1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef OHOS_ROSEN_NAPI_ASYNC_WORK_H 17 #define OHOS_ROSEN_NAPI_ASYNC_WORK_H 18 19 #include <functional> 20 #include <memory> 21 #include <string> 22 #include "refbase.h" 23 24 #include "napi/native_api.h" 25 #include "napi/native_common.h" 26 #include "napi/native_node_api.h" 27 #include "utils/text_log.h" 28 29 namespace OHOS::Rosen { 30 #define MAX_LOG_SIZE 1024 31 /* check condition related to argc/argv, return and logging. */ 32 #define NAPI_CHECK_ARGS(context, condition, specifyStatus, code, retValue, fmt, ...) \ 33 do { \ 34 if (!(condition)) { \ 35 (context)->status = specifyStatus; \ 36 (context)->errCode = static_cast<int32_t>(code); \ 37 char buffer[MAX_LOG_SIZE] = {0}; \ 38 int res = snprintf_s(buffer, MAX_LOG_SIZE, MAX_LOG_SIZE - 1, fmt, ##__VA_ARGS__); \ 39 if (res < 0) { \ 40 TEXT_LOGE("Snprintf err, errcode %{public}d", res); \ 41 retValue; \ 42 } \ 43 (context)->errMessage = std::string(buffer); \ 44 TEXT_LOGE("Test (" #condition ") failed: %{public}s", buffer); \ 45 retValue; \ 46 } \ 47 } while (0) 48 49 #define NAPI_CHECK_STATUS_RETURN_VOID(context, message, code) \ 50 do { \ 51 if ((context)->status != napi_ok) { \ 52 (context)->errMessage = std::string(message); \ 53 (context)->errCode = code; \ 54 TEXT_LOGE("test (context->status == napi_ok) failed: " message); \ 55 return; \ 56 } \ 57 } while (0) 58 59 using NapiCbInfoParser = std::function<void(size_t argc, napi_value* argv)>; 60 using NapiAsyncExecute = std::function<void(void)>; 61 using NapiAsyncComplete = std::function<void(napi_value&)>; 62 63 struct ContextBase : RefBase { 64 virtual ~ContextBase(); 65 void GetCbInfo(napi_env env, napi_callback_info info, NapiCbInfoParser parser = NapiCbInfoParser(), 66 bool sync = false); 67 68 napi_env env = nullptr; 69 napi_value output = nullptr; 70 napi_status status = napi_invalid_arg; 71 std::string errMessage; 72 int32_t errCode = -1; 73 napi_value self = nullptr; 74 void* native = nullptr; 75 76 private: 77 napi_deferred deferred = nullptr; 78 napi_async_work work = nullptr; 79 napi_ref callbackRef = nullptr; 80 napi_ref selfRef = nullptr; 81 82 NapiAsyncExecute execute = nullptr; 83 NapiAsyncComplete complete = nullptr; 84 85 static constexpr size_t ARGC_MAX = 6; 86 87 friend class NapiAsyncWork; 88 }; 89 90 class NapiAsyncWork { 91 public: 92 static napi_value Enqueue(napi_env env, sptr<ContextBase> contextBase, const std::string& name, 93 NapiAsyncExecute execute = NapiAsyncExecute(), 94 NapiAsyncComplete complete = NapiAsyncComplete()); 95 96 private: 97 enum { 98 /* AsyncCallback / Promise output result index */ 99 RESULT_ERROR = 0, 100 RESULT_DATA = 1, 101 RESULT_ALL = 2 102 }; 103 static void GenerateOutput(sptr<ContextBase> ctxt); 104 }; 105 } // namespace OHOS::Rosen 106 #endif // OHOS_ROSEN_NAPI_ASYNC_WORK_H