• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 #include "common-interop.h"
17 #include "common-redrawer.h"
18 
19 #include "ark-interop.h"
20 #include "oh_sk_log.h"
21 
22 #include "platform-api.h"
23 
24 static napi_ref gPlatformApiRef = nullptr;
25 
Node_skoala_setPlatformAPI(const Napi::CallbackInfo & info)26 Napi::Value Node_skoala_setPlatformAPI(const Napi::CallbackInfo& info) {
27     if (static_cast<size_t>(0) >= info.Length()) {
28         Napi::Error::New(info.Env(), "No such element")
29                 .ThrowAsJavaScriptException();
30         return info.Env().Undefined();
31     }
32     if (info[0].IsNull()) {
33         return info.Env().Undefined();
34     }
35 
36     napi_value platformApi = (napi_value)info[0];
37     napi_create_reference(info.Env(), platformApi, 1, &gPlatformApiRef);
38 
39     return info.Env().Undefined();
40 }
MAKE_INTEROP_NODE_EXPORT(skoala_setPlatformAPI)41 MAKE_INTEROP_NODE_EXPORT(skoala_setPlatformAPI)
42 
43 Napi::Value Node_skoala_createRedrawerPeer(const Napi::CallbackInfo& info) {
44     if (static_cast<size_t>(0) >= info.Length()) {
45         Napi::Error::New(info.Env(), "No such element")
46                 .ThrowAsJavaScriptException();
47         return info.Env().Undefined();
48     }
49     if (info[0].IsNull()) {
50         return info.Env().Undefined();
51     }
52     napi_value redrawer = (napi_value)info[0];
53 
54     napi_value platformApi = nullptr;
55     napi_get_reference_value(info.Env(), gPlatformApiRef, &platformApi);
56 
57     auto* peer = reinterpret_cast<RedrawerPeer *>(GetPeerFactory()(reinterpret_cast<void*>(&const_cast<Napi::CallbackInfo&>(info)),
58         GetEngine(), platformApi, redrawer, Engine::RuntimeKind::JS));
59     Napi::Value result = makePointer(info, peer);
60     peer->callOnInitEnv(info);
61     return result;
62 }
MAKE_INTEROP_NODE_EXPORT(skoala_createRedrawerPeer)63 MAKE_INTEROP_NODE_EXPORT(skoala_createRedrawerPeer)
64 
65 Napi::Value Node_skoala_checkEvents(const Napi::CallbackInfo& info) {
66     if (static_cast<size_t>(0) >= info.Length()) {
67         Napi::Error::New(info.Env(), "No such element")
68                 .ThrowAsJavaScriptException();
69         return info.Env().Undefined();
70     }
71     if (info[0].IsNull()) {
72         return info.Env().Undefined();
73     }
74     RedrawerData* data = reinterpret_cast<RedrawerData*>(getPointer(info, 0));
75     return makeBoolean(info, data->peer->checkEvents(data->peer->engine, reinterpret_cast<void*>(&const_cast<Napi::CallbackInfo&>(info))));
76 }
MAKE_INTEROP_NODE_EXPORT(skoala_checkEvents)77 MAKE_INTEROP_NODE_EXPORT(skoala_checkEvents)
78 
79 Napi::Value Node_skoala_drawPicture(const Napi::CallbackInfo& info) {
80     if (static_cast<size_t>(3) >= info.Length()) {
81         Napi::Error::New(info.Env(), "No such element")
82                 .ThrowAsJavaScriptException();
83         return info.Env().Undefined();
84     }
85 
86     SkPicture* picture = reinterpret_cast<SkPicture*>(getPointer(info, 0));
87     RedrawerData* data = reinterpret_cast<RedrawerData*>(getPointer(info, 1));
88     Napi::Function completer = Napi::Function(info.Env(), (napi_value)info[2]);
89     KBoolean sync = getBoolean(info, 3);
90 
91     performDrawOperation(completer, data, picture, sync);
92 
93     return info.Env().Undefined();
94 }
MAKE_INTEROP_NODE_EXPORT(skoala_drawPicture)95 MAKE_INTEROP_NODE_EXPORT(skoala_drawPicture)
96 
97 void doDisposeCallback(KNativePointer cb) {
98     NodeCallback* callback = reinterpret_cast<NodeCallback*>(cb);
99     delete callback;
100 }
101 
callCallback(KNativePointer cb)102 napi_value callCallback(KNativePointer cb) {
103     NodeCallback* callback = reinterpret_cast<NodeCallback*>(cb);
104     return callback->callCallback();
105 }
106 
getEnv(KNativePointer cb)107 Napi::Env getEnv(KNativePointer cb) {
108     NodeCallback* callback = reinterpret_cast<NodeCallback*>(cb);
109     return callback->getEnv();
110 }
111 
doCallBooleanCallback(KNativePointer cb)112 KBoolean doCallBooleanCallback(KNativePointer cb) {
113     napi_value value = callCallback(cb);
114     Napi::Env env = getEnv(cb);
115 
116     return getBoolean(env, Napi::Value(env, value));
117 }
118 
doCallIntCallback(KNativePointer cb)119 KInt doCallIntCallback(KNativePointer cb) {
120     napi_value value = callCallback(cb);
121     Napi::Env env = getEnv(cb);
122 
123     return getInt32(env, Napi::Value(env, value));
124 }
125 
doCallNativePointerCallback(KNativePointer cb)126 KNativePointer doCallNativePointerCallback(KNativePointer cb) {
127     napi_value value = callCallback(cb);
128     Napi::Env env = getEnv(cb);
129 
130     return getPointer(env, Napi::Value(env, value));
131 }
132 
doCallVoidCallback(KNativePointer cb)133 void doCallVoidCallback(KNativePointer cb) {
134     callCallback(cb);
135 }
136 
Node_skoala_registerCallback(const Napi::CallbackInfo & info)137 Napi::Value Node_skoala_registerCallback(const Napi::CallbackInfo& info) {
138     static std::once_flag flag;
139     std::call_once(flag, []() {
140         initCallbacks(
141             &doCallBooleanCallback,
142             &doCallIntCallback,
143             &doCallNativePointerCallback,
144             &doCallVoidCallback,
145             &doDisposeCallback);
146     });
147 
148     if (static_cast<size_t>(1) >= info.Length()) {
149         Napi::Error::New(info.Env(), "No such element").ThrowAsJavaScriptException();
150         return info.Env().Undefined();
151     }
152 
153     Napi::Value arg0 = info[0];
154 
155     if (arg0.IsNull() || arg0.IsUndefined() || !arg0.IsFunction()) {
156         Napi::Error::New(info.Env(), "Wrong callback").ThrowAsJavaScriptException();
157         return info.Env().Undefined();
158     }
159 
160     Napi::Value arg1 = info[1];
161     if (!arg0.IsObject()) {
162         Napi::Error::New(info.Env(), "Not an object").ThrowAsJavaScriptException();
163         return info.Env().Undefined();
164     }
165     NodeCallback* callback = new NodeCallback(info, arg1, arg0);
166 
167     return makePointer(info, callback);
168 }
MAKE_INTEROP_NODE_EXPORT(skoala_registerCallback)169 MAKE_INTEROP_NODE_EXPORT(skoala_registerCallback)
170 
171 static inline void OnAsyncWorkExecute(napi_env env, void* asyncworker) {}
OnAsyncWorkComplete(napi_env env,napi_status status,void * asyncworker)172 static inline void OnAsyncWorkComplete(napi_env env,
173                                        napi_status status,
174                                        void* asyncworker) {
175     napi_value platformApi = nullptr;
176     napi_value runCallback = nullptr;
177     napi_get_reference_value(env, gPlatformApiRef, &platformApi);
178     napi_get_named_property(env, platformApi, "run", &runCallback);
179     Napi::Function cb = Napi::Function(env, runCallback);
180     cb.Call(runCallback, {});
181 }
182 static napi_async_work gWork = nullptr;
Node_skoala_enqueue_run(const Napi::CallbackInfo & info)183 Napi::Value Node_skoala_enqueue_run(const Napi::CallbackInfo& info) {
184     const char* resource_name = "generic";
185     napi_env env = info.Env();
186     const Napi::Object resource = Napi::Object::New(env);
187     napi_value resource_id;
188     napi_status status = napi_create_string_latin1(
189         env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
190     NAPI_THROW_IF_FAILED_VOID(env, status);
191 
192     // napi_async_work work;
193     if (gWork != nullptr) {
194         napi_delete_async_work(env, gWork);
195         gWork = nullptr;
196     }
197     status = napi_create_async_work(env, resource, resource_id, OnAsyncWorkExecute,
198                                     OnAsyncWorkComplete, nullptr, &gWork);
199     NAPI_THROW_IF_FAILED_VOID(env, status);
200     status = napi_queue_async_work(env, gWork);
201     NAPI_THROW_IF_FAILED_VOID(env, status);
202 
203     return info.Env().Undefined();
204 }
205 MAKE_INTEROP_NODE_EXPORT(skoala_enqueue_run)
206