fix simulator

Signed-off-by: 杨亮 <yangliang36@huawei.com>
This commit is contained in:
杨亮 2023-05-28 16:29:18 +08:00
parent 9d70afbf3b
commit 1c60651ca3
10 changed files with 395 additions and 70 deletions

View File

@ -21,6 +21,7 @@ ability_runtime_services_path = "${ability_runtime_path}/services"
ability_runtime_test_path = "${ability_runtime_path}/test"
ace_engine_path = "//foundation/arkui/ace_engine"
arkui_path = "//foundation/arkui"
previewer_path = "//ide/tools/previewer"
bundlefwk_path = "//foundation/bundlemanager/bundle_framework"
bundlefwk_inner_api_path = "${bundlefwk_path}/interfaces/inner_api"

View File

@ -61,7 +61,7 @@ ohos_copy("ability_simulator_copy_application_modules") {
"napi_module/ability_stage_context:ability_stage_context_napi",
"napi_module/application_context:application_context_napi",
"napi_module/caller:caller_napi",
"napi_module/callee:callee_napi",
"napi_module/callee:callee",
"napi_module/context:context_napi",
"napi_module/configuration_constant:configurationconstant_napi",
]
@ -78,9 +78,31 @@ ohos_copy("ability_simulator_copy_application_modules") {
outputs = [ target_path + "/bin/module/application/{{source_file_part}}" ]
}
ohos_copy("ability_simulator_copy_app_ability_modules") {
deps = []
sources = []
napi_modules = [ "napi_module/uiability:uiability" ]
foreach(module, napi_modules) {
deps += [ module ]
out_path = get_label_info(module, "root_out_dir")
out_name = get_label_info(module, "name")
sources += [ out_path + "/ability/simulator/lib" + out_name + dylib_suffix ]
}
target_path = get_label_info(":copy_ability_simulator", "target_out_dir")
outputs = [ target_path + "/bin/module/app/ability/{{source_file_part}}" ]
part_name = "simulator"
subsystem_name = "ability"
}
ohos_copy("copy_ability_simulator") {
deps = [
":ability_simulator_copy_ability_modules",
":ability_simulator_copy_app_ability_modules",
":ability_simulator_copy_application_modules",
]
sources = []
@ -96,9 +118,10 @@ ohos_copy("copy_ability_simulator") {
sources +=
[ out_path + "/ability/simulator/libability_simulator" + dylib_suffix ]
external_deps = [ "napi:ace_napi" ]
out_path = get_label_info("${arkui_path}/napi:ace_napi", "root_out_dir")
sources += [ out_path + "/arkui/napi/libace_napi" + dylib_suffix ]
deps += [ "${ability_base_path}:string_utils" ]
out_path = get_label_info("${ability_base_path}:string_utils", "root_out_dir")
sources +=
[ out_path + "/ability/ability_base/libstring_utils" + dylib_suffix ]
deps += [ "${arkui_path}/napi:ace_napi_ark" ]
out_path = get_label_info("${arkui_path}/napi:ace_napi_ark", "root_out_dir")

View File

@ -18,13 +18,13 @@ import("//foundation/arkui/ace_engine/build/ace_gen_obj.gni")
ts2abc_gen_abc("gen_abc_js_mock") {
js_mock_path =
get_label_info("//third_party/jsframework:gen_snapshot",
get_label_info("${previewer_path}/automock:gen_snapshot_jsmock",
"target_out_dir") + "/dist/jsMockSystemPlugin.js"
src_js = rebase_path(js_mock_path)
dst_file = rebase_path(target_out_dir + "/jsMockSystemPlugin.abc")
in_puts = [ js_mock_path ]
out_puts = [ target_out_dir + "/jsMockSystemPlugin.abc" ]
extra_dependencies = [ "//third_party/jsframework:gen_snapshot" ]
extra_dependencies = [ "${previewer_path}/automock:gen_snapshot_jsmock" ]
}
gen_obj("js_mock_abc") {
@ -68,7 +68,7 @@ ohos_shared_library("ability_simulator") {
sources = [
"${ability_runtime_native_path}/runtime/js_console_log.cpp",
"${ability_runtime_native_path}/runtime/js_module_searcher.cpp",
"${ability_runtime_native_path}/runtime/js_runtime_utils.cpp",
"src/js_runtime_utils.cpp",
"src/js_timer.cpp",
"src/simulator.cpp",
]
@ -80,7 +80,6 @@ ohos_shared_library("ability_simulator") {
deps = [
":gen_obj_src_js_mock_abc",
"${ability_runtime_native_path}/runtime:string_utils",
"${ability_runtime_path}/frameworks/simulator/osal:simulator_osal",
"${arkui_path}/napi:ace_napi_ark",
"${hilog_path}/interfaces/native/innerkits:libhilog_$platform",
@ -89,6 +88,7 @@ ohos_shared_library("ability_simulator") {
]
external_deps = [
"ability_base:string_utils",
"ets_runtime:libark_jsruntime",
"napi:ace_napi",
]

View File

@ -25,6 +25,9 @@ namespace AbilityRuntime {
class Simulator {
public:
struct Options {
std::string bundleName;
std::string moduleName;
std::string modulePath;
};
using TerminateCallback = std::function<void(int64_t)>;
@ -37,9 +40,8 @@ public:
virtual int64_t StartAbility(const std::string& abilitySrcPath, TerminateCallback callback) = 0;
virtual void TerminateAbility(int64_t abilityId) = 0;
virtual int64_t CreateForm(const std::string& formSrcPath, FormUpdateCallback callback) = 0;
virtual void RequestUpdateForm(int64_t formId) = 0;
virtual void DestroyForm(int64_t formId) = 0;
private:
bool RunScript();
};
} // namespace AbilityRuntime
} // namespace OHOS

View File

@ -0,0 +1,263 @@
/*
* Copyright (c) 2021-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "js_runtime_utils.h"
#include "hilog_wrapper.h"
#include "js_runtime.h"
namespace OHOS {
namespace AbilityRuntime {
namespace {
std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
std::unique_ptr<AsyncTask::ExecuteCallback>&& execute, std::unique_ptr<AsyncTask::CompleteCallback>&& complete,
NativeValue** result)
{
if (lastParam == nullptr || lastParam->TypeOf() != NATIVE_FUNCTION) {
NativeDeferred* nativeDeferred = nullptr;
*result = engine.CreatePromise(&nativeDeferred);
return std::make_unique<AsyncTask>(nativeDeferred, std::move(execute), std::move(complete));
} else {
*result = engine.CreateUndefined();
NativeReference* callbackRef = engine.CreateReference(lastParam, 1);
return std::make_unique<AsyncTask>(callbackRef, std::move(execute), std::move(complete));
}
}
} // namespace
// Help Functions
NativeValue* CreateJsError(NativeEngine& engine, int32_t errCode, const std::string& message)
{
return engine.CreateError(CreateJsValue(engine, errCode), CreateJsValue(engine, message));
}
void BindNativeFunction(NativeEngine& engine, NativeObject& object, const char* name,
const char* moduleName, NativeCallback func)
{
std::string fullName(moduleName);
fullName += ".";
fullName += name;
object.SetProperty(name, engine.CreateFunction(fullName.c_str(), fullName.length(), func, nullptr));
}
void BindNativeProperty(NativeObject& object, const char* name, NativeCallback getter)
{
NativePropertyDescriptor property;
property.utf8name = name;
property.name = nullptr;
property.method = nullptr;
property.getter = getter;
property.setter = nullptr;
property.value = nullptr;
property.attributes = napi_default;
property.data = nullptr;
object.DefineProperty(property);
}
void* GetNativePointerFromCallbackInfo(const NativeEngine* engine, NativeCallbackInfo* info, const char* name)
{
if (engine == nullptr || info == nullptr) {
return nullptr;
}
NativeObject* object = ConvertNativeValueTo<NativeObject>(info->thisVar);
if (object != nullptr && name != nullptr) {
object = ConvertNativeValueTo<NativeObject>(object->GetProperty(name));
}
return (object != nullptr) ? object->GetNativePointer() : nullptr;
}
void SetNamedNativePointer(NativeEngine& engine, NativeObject& object, const char* name, void* ptr, NativeFinalize func)
{
NativeValue* value = engine.CreateObject();
NativeObject* newObject = ConvertNativeValueTo<NativeObject>(value);
if (newObject == nullptr) {
return;
}
newObject->SetNativePointer(ptr, func, nullptr);
object.SetProperty(name, value);
}
void* GetNamedNativePointer(NativeEngine& engine, NativeObject& object, const char* name)
{
NativeObject* namedObj = ConvertNativeValueTo<NativeObject>(object.GetProperty(name));
return (namedObj != nullptr) ? namedObj->GetNativePointer() : nullptr;
}
// Async Task
AsyncTask::AsyncTask(NativeDeferred* deferred, std::unique_ptr<AsyncTask::ExecuteCallback>&& execute,
std::unique_ptr<AsyncTask::CompleteCallback>&& complete)
: deferred_(deferred), execute_(std::move(execute)), complete_(std::move(complete))
{}
AsyncTask::AsyncTask(NativeReference* callbackRef, std::unique_ptr<AsyncTask::ExecuteCallback>&& execute,
std::unique_ptr<AsyncTask::CompleteCallback>&& complete)
: callbackRef_(callbackRef), execute_(std::move(execute)), complete_(std::move(complete))
{}
AsyncTask::~AsyncTask() = default;
void AsyncTask::Schedule(const std::string &name, NativeEngine& engine, std::unique_ptr<AsyncTask>&& task)
{
if (task && task->Start(name, engine)) {
task.release();
}
}
void AsyncTask::Resolve(NativeEngine& engine, NativeValue* value)
{
HILOG_DEBUG("AsyncTask::Resolve is called");
if (deferred_) {
deferred_->Resolve(value);
deferred_.reset();
}
if (callbackRef_) {
NativeValue* argv[] = {
CreateJsError(engine, 0),
value,
};
engine.CallFunction(engine.CreateUndefined(), callbackRef_->Get(), argv, ArraySize(argv));
callbackRef_.reset();
}
HILOG_DEBUG("AsyncTask::Resolve is called end.");
}
void AsyncTask::ResolveWithNoError(NativeEngine& engine, NativeValue* value)
{
HILOG_DEBUG("AsyncTask::Resolve is called");
if (deferred_) {
deferred_->Resolve(value);
deferred_.reset();
}
if (callbackRef_) {
NativeValue* argv[] = {
engine.CreateNull(),
value,
};
engine.CallFunction(engine.CreateUndefined(), callbackRef_->Get(), argv, ArraySize(argv));
callbackRef_.reset();
}
HILOG_DEBUG("AsyncTask::Resolve is called end.");
}
void AsyncTask::Reject(NativeEngine& engine, NativeValue* error)
{
if (deferred_) {
deferred_->Reject(error);
deferred_.reset();
}
if (callbackRef_) {
NativeValue* argv[] = {
error,
engine.CreateUndefined(),
};
engine.CallFunction(engine.CreateUndefined(), callbackRef_->Get(), argv, ArraySize(argv));
callbackRef_.reset();
}
}
void AsyncTask::ResolveWithCustomize(NativeEngine& engine, NativeValue* error, NativeValue* value)
{
HILOG_DEBUG("AsyncTask::ResolveWithCustomize is called");
if (deferred_) {
deferred_->Resolve(value);
deferred_.reset();
}
if (callbackRef_) {
NativeValue* argv[] = {
error,
value,
};
engine.CallFunction(engine.CreateUndefined(), callbackRef_->Get(), argv, ArraySize(argv));
callbackRef_.reset();
}
HILOG_DEBUG("AsyncTask::ResolveWithCustomize is called end.");
}
void AsyncTask::RejectWithCustomize(NativeEngine& engine, NativeValue* error, NativeValue* value)
{
HILOG_DEBUG("AsyncTask::RejectWithCustomize is called");
if (deferred_) {
deferred_->Reject(error);
deferred_.reset();
}
if (callbackRef_) {
NativeValue* argv[] = {
error,
value,
};
engine.CallFunction(engine.CreateUndefined(), callbackRef_->Get(), argv, ArraySize(argv));
callbackRef_.reset();
}
HILOG_DEBUG("AsyncTask::RejectWithCustomize is called end.");
}
void AsyncTask::Execute(NativeEngine* engine, void* data)
{
if (engine == nullptr || data == nullptr) {
return;
}
auto me = static_cast<AsyncTask*>(data);
if (me->execute_ && *(me->execute_)) {
(*me->execute_)();
}
}
void AsyncTask::Complete(NativeEngine* engine, int32_t status, void* data)
{
if (engine == nullptr || data == nullptr) {
return;
}
std::unique_ptr<AsyncTask> me(static_cast<AsyncTask*>(data));
if (me->complete_ && *(me->complete_)) {
(*me->complete_)(*engine, *me, status);
}
}
bool AsyncTask::Start(const std::string &name, NativeEngine& engine)
{
work_.reset(engine.CreateAsyncWork(name, Execute, Complete, this));
return work_->Queue();
}
std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
AsyncTask::ExecuteCallback&& execute, AsyncTask::CompleteCallback&& complete, NativeValue** result)
{
return CreateAsyncTaskWithLastParam(engine, lastParam,
std::make_unique<AsyncTask::ExecuteCallback>(std::move(execute)),
std::make_unique<AsyncTask::CompleteCallback>(std::move(complete)), result);
}
std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
AsyncTask::ExecuteCallback&& execute, nullptr_t, NativeValue** result)
{
return CreateAsyncTaskWithLastParam(
engine, lastParam, std::make_unique<AsyncTask::ExecuteCallback>(std::move(execute)), nullptr, result);
}
std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
nullptr_t, AsyncTask::CompleteCallback&& complete, NativeValue** result)
{
return CreateAsyncTaskWithLastParam(
engine, lastParam, nullptr, std::make_unique<AsyncTask::CompleteCallback>(std::move(complete)), result);
}
std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
nullptr_t, nullptr_t, NativeValue** result)
{
return CreateAsyncTaskWithLastParam(engine, lastParam, std::unique_ptr<AsyncTask::ExecuteCallback>(),
std::unique_ptr<AsyncTask::CompleteCallback>(), result);
}
} // namespace AbilityRuntime
} // namespace OHOS

View File

@ -71,8 +71,6 @@ public:
// call js function
ContainerScope containerScope(containerScopeId_);
#endif
HandleScope handleScope(nativeEngine_);
std::vector<NativeValue*> args;
args.reserve(jsArgs_.size());
for (auto arg : jsArgs_) {
@ -172,7 +170,7 @@ NativeValue* StopTimeoutOrInterval(NativeEngine* engine, NativeCallbackInfo* inf
}
}
void InitTimerModule(NativeEngine& engine, NativeObject& globalObject)
void InitTimer(NativeEngine& engine, NativeObject& globalObject)
{
const char *moduleName = "AsJsTimer";
BindNativeFunction(engine, globalObject, "setTimeout", moduleName, StartTimeout);

View File

@ -16,9 +16,9 @@
#include "simulator.h"
#include <condition_variable>
#include <fstream>
#include <functional>
#include <mutex>
#include <sys/prctl.h>
#include <thread>
#include <unordered_map>
@ -40,6 +40,8 @@ constexpr int32_t DEFAULT_ARK_PROPERTIES = -1;
constexpr size_t DEFAULT_GC_THREAD_NUM = 7;
constexpr size_t DEFAULT_LONG_PAUSE_TIME = 40;
constexpr char BUNDLE_INSTALL_PATH[] = "/data/storage/el1/bundle/";
#if defined(WINDOWS_PLATFORM)
constexpr char ARK_DEBUGGER_LIB_PATH[] = "libark_debugger.dll";
#elif defined(MAC_PLATFORM)
@ -82,6 +84,7 @@ private:
void Run();
Options options_;
std::string abilityPath_;
std::thread thread_;
panda::ecmascript::EcmaVM* vm_ = nullptr;
DebuggerTask debuggerTask_;
@ -167,14 +170,6 @@ bool SimulatorImpl::Initialize(const Options& options)
options_ = options;
thread_ = std::thread([&] {
if (nativeEngine_ == nullptr) {
return;
}
if (prctl(PR_SET_NAME, "simulatorInit") < 0) {
HILOG_WARN("Set thread name failed with %{public}d", errno);
}
bool initResult = OnInit();
if (!initResult) {
waiter.NotifyResult(false);
@ -212,8 +207,6 @@ bool SimulatorImpl::Initialize(const Options& options)
void CallObjectMethod(NativeEngine& engine, NativeValue* value, const char *name, NativeValue *const *argv, size_t argc)
{
HandleScope handleScope(engine);
NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
if (obj == nullptr) {
HILOG_ERROR("%{public}s, Failed to get Ability object", __func__);
@ -228,40 +221,55 @@ void CallObjectMethod(NativeEngine& engine, NativeValue* value, const char *name
engine.CallFunction(value, methodOnCreate, argv, argc);
}
bool SimulatorImpl::RunScript()
{
panda::JSNApi::SetBundleName(vm_, options_.bundleName);
panda::JSNApi::SetModuleName(vm_, options_.moduleName);
panda::JSNApi::SetAssetPath(vm_, options_.modulePath);
panda::JSNApi::SetBundle(vm_, false);
panda::Local<panda::ObjectRef> objRef = panda::JSNApi::GetExportObject(vm_, abilityPath_, "default");
if (objRef->IsNull()) {
HILOG_ERROR("Get export object failed");
return false;
}
auto obj = ArkNativeEngine::ArkValueToNativeValue(static_cast<ArkNativeEngine*>(nativeEngine_.get()), objRef);
NativeValue* instanceValue = nativeEngine_->CreateInstance(obj, nullptr, 0);
if (instanceValue == nullptr) {
HILOG_ERROR("Failed to create object instance");
return false;
}
return true;
}
int64_t SimulatorImpl::StartAbility(const std::string& abilitySrcPath, TerminateCallback callback)
{
uv_work_t work;
ResultWaiter<int64_t> waiter;
work.data = new std::function<void()>([abilitySrcPath, this, &waiter] () {
NativeObject* globalObj = ConvertNativeValueTo<NativeObject>(nativeEngine_->GetGlobal());
NativeValue* exports = nativeEngine_->CreateObject();
globalObj->SetProperty("exports", exports);
if (nativeEngine_->RunScriptPath(abilitySrcPath.c_str()) == nullptr) {
HILOG_ERROR("Failed to run script: %{private}s", abilitySrcPath.c_str());
abilityPath_ = BUNDLE_INSTALL_PATH + options_.moduleName + "/" + abilitySrcPath;
work.data = new std::function<void()>([this, &waiter] () {
std::ifstream stream(options_.modulePath, std::ios::ate | std::ios::binary);
if (!stream.is_open()) {
HILOG_ERROR("Failed to open: %{public}s", options_.modulePath.c_str());
waiter.NotifyResult(-1);
return;
}
NativeObject* exportsObj = ConvertNativeValueTo<NativeObject>(globalObj->GetProperty("exports"));
if (exportsObj == nullptr) {
HILOG_ERROR("Failed to get exports objcect: %{private}s", abilitySrcPath.c_str());
size_t len = stream.tellg();
std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(len);
stream.seekg(0);
stream.read(reinterpret_cast<char*>(buffer.get()), len);
stream.close();
if (!nativeEngine_->RunScriptBuffer(abilityPath_, buffer.release(), len, false)) {
HILOG_ERROR("Failed to run script: %{public}s", abilityPath_.c_str());
waiter.NotifyResult(-1);
return;
}
NativeValue* exportObj = exportsObj->GetProperty("default");
if (exportObj == nullptr) {
HILOG_ERROR("Failed to get default objcect: %{private}s", abilitySrcPath.c_str());
waiter.NotifyResult(-1);
return;
}
NativeValue* instanceValue = nativeEngine_->CreateInstance(exportObj, nullptr, 0);
if (instanceValue == nullptr) {
HILOG_ERROR("Failed to create object instance");
if (!RunScript()) {
waiter.NotifyResult(-1);
return;
}
@ -323,19 +331,6 @@ void SimulatorImpl::TerminateAbility(int64_t abilityId)
waiter.WaitForResult();
}
int64_t SimulatorImpl::CreateForm(const std::string& formSrcPath, FormUpdateCallback callback)
{
return -1;
}
void SimulatorImpl::RequestUpdateForm(int64_t formId)
{
}
void SimulatorImpl::DestroyForm(int64_t formId)
{
}
bool SimulatorImpl::OnInit()
{
panda::RuntimeOption pandaOption;
@ -359,8 +354,6 @@ bool SimulatorImpl::OnInit()
auto nativeEngine = std::make_unique<ArkNativeEngine>(vm_, nullptr);
HandleScope handleScope(*nativeEngine);
NativeObject* globalObj = ConvertNativeValueTo<NativeObject>(nativeEngine->GetGlobal());
if (globalObj == nullptr) {
HILOG_ERROR("Failed to get global object");
@ -368,7 +361,7 @@ bool SimulatorImpl::OnInit()
}
InitConsoleLogModule(*nativeEngine, *globalObj);
InitTimerModule(*nativeEngine, *globalObj);
InitTimer(*nativeEngine, *globalObj);
globalObj->SetProperty("group", nativeEngine->CreateObject());

View File

@ -20,7 +20,7 @@ gen_js_src_binary("callee") {
js_source = "${ability_runtime_napi_path}/callee/callee.js"
}
ohos_shared_library("callee_napi") {
ohos_shared_library("callee") {
if (is_mingw) {
defines = [ "WINDOWS_PLATFORM" ]
} else {

View File

@ -0,0 +1,40 @@
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
import("//foundation/ability/ability_runtime/ability_runtime.gni")
import(
"${ability_runtime_path}/frameworks/simulator/build/ability_simulator.gni")
gen_js_src_binary("ability") {
js_source = "${ability_runtime_napi_path}/ability/ability.js"
}
ohos_shared_library("uiability") {
if (is_mingw) {
defines = [ "WINDOWS_PLATFORM" ]
} else {
defines = [ "MAC_PLATFORM" ]
}
defines += [ "ENABLE_ERRCODE" ]
sources = [ "${ability_runtime_napi_path}/ability/ability_module.cpp" ]
deps = [
":gen_obj_src_ability_abc",
":gen_obj_src_ability_js",
]
external_deps = [ "napi:ace_napi" ]
part_name = "simulator"
subsystem_name = "ability"
}

View File

@ -14,24 +14,29 @@
*/
#include <cstdint>
#include <iostream>
#include "simulator.h"
constexpr int32_t MIN_PARAMS = 5;
int32_t main(int32_t argc, const char* argv[])
{
OHOS::AbilityRuntime::Simulator::Options options;
auto simulator = OHOS::AbilityRuntime::Simulator::Create(options);
if (!simulator) {
if (argc < MIN_PARAMS) {
std::cout << "Insufficient parameters." << std::endl;
return 1;
}
std::string abilitySrcPath;
if (argc > 1) {
abilitySrcPath = argv[1];
OHOS::AbilityRuntime::Simulator::Options options {argv[1], argv[2], argv[3]};
auto simulator = OHOS::AbilityRuntime::Simulator::Create(options);
if (!simulator) {
std::cout << "Create Simulator failed." << std::endl;
return 1;
}
std::string abilitySrcPath {argv[4]};
int64_t id = simulator->StartAbility(abilitySrcPath, [](int64_t abilityId) {});
if (id < 0) {
std::cout << "Start Ability failed." << std::endl;
return 1;
}