mirror of
https://github.com/openharmony/js_api_module.git
synced 2026-07-16 07:14:27 -04:00
1956f2e85d
Related Issue https://gitee.com/openharmony/manifest/issues/I5HDQT Description Switch component name from ts_js_lang_library to ets_utils for js_api_module,js_util_module,js_sys_module,js_worker_module Signed-off-by: lengchangjing <lengchangjing@huawei.com>
188 lines
6.6 KiB
C++
188 lines
6.6 KiB
C++
/*
|
|
* Copyright (c) 2022 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 "timer.h"
|
|
|
|
#include "utils/log.h"
|
|
|
|
namespace CompilerRuntime::WorkerModule::Plugin {
|
|
uint32_t Timer::timeCallbackId = 0;
|
|
std::map<uint32_t, TimerCallbackInfo*> Timer::timerTable;
|
|
std::mutex Timer::timeLock;
|
|
|
|
TimerCallbackInfo::~TimerCallbackInfo()
|
|
{
|
|
Helper::NapiHelper::DeleteReference(env_, callback_);
|
|
for (size_t idx = 0; idx < argc_; idx++) {
|
|
Helper::NapiHelper::DeleteReference(env_, argv_[idx]);
|
|
}
|
|
Helper::CloseHelp::DeletePointer(argv_, true);
|
|
|
|
uv_timer_stop(&timeReq_);
|
|
uv_close(reinterpret_cast<uv_handle_t*>(&timeReq_), nullptr);
|
|
}
|
|
|
|
bool Timer::RegisterTime(napi_env env)
|
|
{
|
|
if (env == nullptr) {
|
|
return false;
|
|
}
|
|
napi_property_descriptor properties[] = {
|
|
DECLARE_NAPI_FUNCTION("setTimeout", SetTimeout),
|
|
DECLARE_NAPI_FUNCTION("setInterval", SetInterval),
|
|
DECLARE_NAPI_FUNCTION("clearTimeout", ClearTimer),
|
|
DECLARE_NAPI_FUNCTION("clearInterval", ClearTimer)
|
|
};
|
|
napi_value globalObj = Helper::NapiHelper::GetGlobalObject(env);
|
|
napi_status status = napi_define_properties(env, globalObj, sizeof(properties) / sizeof(properties[0]), properties);
|
|
return status == napi_ok;
|
|
}
|
|
|
|
napi_value Timer::SetTimeout(napi_env env, napi_callback_info cbinfo)
|
|
{
|
|
return Timer::SetTimeoutInner(env, cbinfo, false);
|
|
}
|
|
|
|
napi_value Timer::SetInterval(napi_env env, napi_callback_info cbinfo)
|
|
{
|
|
return Timer::SetTimeoutInner(env, cbinfo, true);
|
|
}
|
|
|
|
napi_value Timer::ClearTimer(napi_env env, napi_callback_info cbinfo)
|
|
{
|
|
// 1. check args
|
|
size_t argc = Helper::NapiHelper::GetCallbackInfoArgc(env, cbinfo);
|
|
if (argc <= 0) {
|
|
HILOG_WARN("first arg should be number");
|
|
return nullptr;
|
|
}
|
|
napi_value* argv = new napi_value[argc];
|
|
Helper::ObjectScope<napi_value> scope(argv, true);
|
|
napi_value thisVar = nullptr;
|
|
napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr);
|
|
|
|
uint32_t tId;
|
|
napi_status status = napi_get_value_uint32(env, argv[0], &tId);
|
|
if (status != napi_ok) {
|
|
HILOG_WARN("handler should be number");
|
|
return nullptr;
|
|
}
|
|
auto iter = timerTable.find(tId);
|
|
if (iter == timerTable.end()) {
|
|
HILOG_INFO("handler not in table");
|
|
return nullptr;
|
|
}
|
|
TimerCallbackInfo* callbackInfo = iter->second;
|
|
timerTable.erase(tId);
|
|
Helper::CloseHelp::DeletePointer(callbackInfo, false);
|
|
return Helper::NapiHelper::GetUndefinedValue(env);
|
|
}
|
|
|
|
void Timer::TimerCallback(uv_timer_t* handle)
|
|
{
|
|
TimerCallbackInfo* callbackInfo = Helper::DereferenceHelp::DereferenceOf(&TimerCallbackInfo::timeReq_, handle);
|
|
if (callbackInfo == nullptr) {
|
|
return;
|
|
}
|
|
napi_value callback = Helper::NapiHelper::GetReferenceValue(callbackInfo->env_, callbackInfo->callback_);
|
|
napi_value undefinedValue = Helper::NapiHelper::GetUndefinedValue(callbackInfo->env_);
|
|
napi_value callbackResult = nullptr;
|
|
napi_value* callbackArgv = new napi_value[callbackInfo->argc_];
|
|
Helper::ObjectScope<napi_value> scope(callbackArgv, true);
|
|
for (size_t idx = 0; idx < callbackInfo->argc_; idx++) {
|
|
callbackArgv[idx] = Helper::NapiHelper::GetReferenceValue(callbackInfo->env_, callbackInfo->argv_[idx]);
|
|
}
|
|
napi_call_function(callbackInfo->env_, undefinedValue, callback,
|
|
callbackInfo->argc_, callbackArgv, &callbackResult);
|
|
if (callbackResult == nullptr) {
|
|
HILOG_WARN("call callback error");
|
|
return;
|
|
}
|
|
if (!callbackInfo->repeat_) {
|
|
timerTable.erase(callbackInfo->tId_);
|
|
Helper::CloseHelp::DeletePointer(callbackInfo, false);
|
|
} else {
|
|
uv_timer_again(handle);
|
|
}
|
|
}
|
|
|
|
napi_value Timer::SetTimeoutInner(napi_env env, napi_callback_info cbinfo, bool repeat)
|
|
{
|
|
// 1. check args
|
|
size_t argc = Helper::NapiHelper::GetCallbackInfoArgc(env, cbinfo);
|
|
if (argc <= 0) {
|
|
napi_throw_error(env, nullptr, "callback must be a function. received undefined");
|
|
return nullptr;
|
|
}
|
|
napi_value* argv = new napi_value[argc];
|
|
Helper::ObjectScope<napi_value> scope(argv, true);
|
|
napi_value thisVar = nullptr;
|
|
napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr);
|
|
if (!Helper::NapiHelper::IsCallable(env, argv[0])) {
|
|
napi_throw_error(env, nullptr, "callback must be a function.");
|
|
return nullptr;
|
|
}
|
|
uint32_t timeout = 0;
|
|
if (argc > 1) {
|
|
napi_status status = napi_get_value_uint32(env, argv[1], &timeout);
|
|
if (status != napi_ok) {
|
|
HILOG_WARN("timeout should be number");
|
|
timeout = 0;
|
|
}
|
|
}
|
|
// 2. get callback args
|
|
size_t callbackArgc = argc >= 2 ? argc - 2 : 0; // 2 include callback and timeout
|
|
napi_ref* callbackArgv = nullptr;
|
|
if (callbackArgc > 0) {
|
|
callbackArgv = new napi_ref[callbackArgc];
|
|
for (size_t idx = 0; idx < callbackArgc; idx++) {
|
|
callbackArgv[idx] =
|
|
Helper::NapiHelper::CreateReference(env, argv[idx + 2], 1); // 2 include callback and timeout
|
|
}
|
|
}
|
|
|
|
// 3. generate time callback id;
|
|
uint32_t tId = 0;
|
|
{
|
|
std::lock_guard<std::mutex> lock(timeLock);
|
|
tId = timeCallbackId++;
|
|
}
|
|
// 4. generate time callback info
|
|
napi_ref callbackRef = Helper::NapiHelper::CreateReference(env, argv[0], 1);
|
|
TimerCallbackInfo* callbackInfo =
|
|
new TimerCallbackInfo(env, tId, timeout, callbackRef, repeat, callbackArgc, callbackArgv);
|
|
// 5. push callback info into timerTable
|
|
timerTable[tId] = callbackInfo;
|
|
|
|
// 6. start timer
|
|
uv_timer_start(&callbackInfo->timeReq_, TimerCallback, timeout, timeout > 0 ? timeout : 1);
|
|
return Helper::NapiHelper::CreateUint32(env, tId);
|
|
}
|
|
|
|
void Timer::ClearEnvironmentTimer(napi_env env)
|
|
{
|
|
auto iter = timerTable.begin();
|
|
while (iter != timerTable.end()) {
|
|
TimerCallbackInfo* callbackInfo = iter->second;
|
|
if (callbackInfo->env_ == env) {
|
|
iter = timerTable.erase(iter);
|
|
Helper::CloseHelp::DeletePointer(callbackInfo, false);
|
|
} else {
|
|
iter++;
|
|
}
|
|
}
|
|
}
|
|
} // namespace CompilerRuntime::WorkerModule::Plugin
|