• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <string>
17 #include <sstream>
18 #include <algorithm>
19 #include <chrono>
20 #include <iomanip>
21 #include <unordered_map>
22 
23 #define KOALA_INTEROP_MODULE ArkUINativeModule
24 #include "common-interop.h"
25 #include "interop-logging.h"
26 
27 #include "arkoala_api_generated.h"
28 #include "Serializers.h"
29 
30 const OH_AnyAPI* GetAnyImpl(int kind, int version, std::string* result = nullptr);
31 
GetArkUIBasicNodeAPI()32 const GENERATED_ArkUIBasicNodeAPI* GetArkUIBasicNodeAPI() {
33     return reinterpret_cast<const GENERATED_ArkUIBasicNodeAPI*>(
34         GetAnyImpl(static_cast<int>(GENERATED_Ark_APIVariantKind::GENERATED_BASIC),
35         GENERATED_ARKUI_BASIC_NODE_API_VERSION, nullptr));
36 }
37 
GetArkUIExtendedNodeAPI()38 const GENERATED_ArkUIExtendedNodeAPI* GetArkUIExtendedNodeAPI() {
39     return reinterpret_cast<const GENERATED_ArkUIExtendedNodeAPI*>(
40         GetAnyImpl(static_cast<int>(GENERATED_Ark_APIVariantKind::GENERATED_EXTENDED),
41         GENERATED_ARKUI_EXTENDED_NODE_API_VERSION, nullptr));
42 }
43 
44 CustomDeserializer* DeserializerBase::customDeserializers = nullptr;
45 
46 // TODO: Remove all this.
disposeNode(KNativePointer * ptr)47 void disposeNode(KNativePointer* ptr) {
48     GetArkUIBasicNodeAPI()->disposeNode((Ark_NodeHandle)ptr);
49 }
impl_GetNodeFinalizer()50 KNativePointer impl_GetNodeFinalizer() {
51     return fnPtr<KNativePointer>(disposeNode);
52 }
KOALA_INTEROP_DIRECT_0(GetNodeFinalizer,KNativePointer)53 KOALA_INTEROP_DIRECT_0(GetNodeFinalizer, KNativePointer)
54 
55 // custom methods
56 void impl_ShowCrash(const KStringPtr& messagePtr) {
57     GetArkUIExtendedNodeAPI()->showCrash(messagePtr.c_str());
58 }
KOALA_INTEROP_V1(ShowCrash,KStringPtr)59 KOALA_INTEROP_V1(ShowCrash, KStringPtr)
60 
61 Ark_Int32 impl_LayoutNode(KVMContext vmContext, Ark_NativePointer nodePtr, KFloatArray data) {
62     return GetArkUIExtendedNodeAPI()->layoutNode((Ark_VMContext)vmContext, (Ark_NodeHandle)nodePtr, (Ark_Float32(*)[2])data);
63 }
64 KOALA_INTEROP_CTX_2(LayoutNode, Ark_Int32, Ark_NativePointer, KFloatArray)
65 
66 struct PerfInfo {
67     int64_t start;
68     int64_t end;
69     int64_t cost;
70     std::string perf_name;
PrintPerfInfo71     void Print(std::stringstream& result, float counterSelf = 0.0) {
72         result << "Perf trace_name(" << perf_name <<  ") cost " << (cost / 1000.0 - counterSelf) << " us.";
73     }
74 };
75 
76 class Performance {
77   public:
PrintAvgs(std::stringstream & result)78     void PrintAvgs(std::stringstream& result) {
79         for (const auto& [name, perfs] : perfs_) {
80             if (name == "perf_counter_self_cost") continue;
81             float totalCost = 0;
82             for (const auto& perf : perfs) {
83                 totalCost += perf.cost / 1000.0 - self_cost_;
84             }
85             auto avg = totalCost / perfs.size();
86             result << "Perf trace_name(" << name << ") " << perfs.size() << " call avg cost " << avg << " us.";
87         }
88     }
PrintTotals(std::stringstream & result)89     void PrintTotals(std::stringstream& result) {
90         for (const auto& [name, perfs] : perfs_) {
91             float totalCost = 0;
92             for (const auto& perf : perfs) {
93                 totalCost += perf.cost / 1000.0 - self_cost_;
94             }
95             result << "Perf trace_name(" << name << ") " << perfs.size() << " call total cost " << totalCost << " us.";
96         }
97     }
PrintPeak(std::stringstream & result)98     void PrintPeak(std::stringstream& result) {
99         for(auto &kv : perfs_) {
100             std::sort(kv.second.begin(), kv.second.end(), [](const PerfInfo &perf1, const PerfInfo &perf2) {
101                 return perf1.cost > perf2.cost;
102             });
103             auto maxCost = kv.second.front().cost / 1000.0 - self_cost_;
104             auto minCost = kv.second.back().cost / 1000.0 - self_cost_;
105             result << "Perf trace_name(" << kv.first << ") " << " maxCost = " << maxCost << " us, ";
106             result << "minCost = " << minCost << " us.";
107         }
108     }
PrintDetails(std::stringstream & result)109     void PrintDetails(std::stringstream& result) {
110         for (const auto& [name, perfs] : perfs_) {
111             for (auto perf : perfs) {
112                 perf.Print(result);
113             }
114         }
115     }
FinishOne()116     void FinishOne() {
117         perfs_[current_.perf_name].emplace_back(current_);
118     }
CalcSelfCost()119     void CalcSelfCost() {
120         float totalCost = 0.0;
121         auto it = perfs_.find("perf_counter_self_cost");
122         if (it == perfs_.end()) {
123             self_cost_ = totalCost;
124             return;
125         }
126         for (const auto& perf : it->second) {
127             totalCost += perf.cost / 1000.0;
128         }
129         self_cost_ = totalCost / it->second.size();
130     }
Clean()131     void Clean() {
132         perfs_.clear();
133     }
GetCurrent()134     PerfInfo* GetCurrent() { return &current_; }
GetInstance()135     static Performance* GetInstance() {
136         static Performance perf;
137         return &perf;
138     }
139 private:
140     std::unordered_map<std::string, std::vector<PerfInfo>> perfs_;
141     PerfInfo current_;
142     float self_cost_;
143 };
144 
impl_StartPerf(const KStringPtr & traceName)145 void impl_StartPerf(const KStringPtr& traceName) {
146     PerfInfo* perf = Performance::GetInstance()->GetCurrent();
147     perf->perf_name = traceName.c_str();
148     auto now = std::chrono::high_resolution_clock::now();
149     perf->start = std::chrono::time_point_cast<std::chrono::nanoseconds>(now).time_since_epoch().count();
150 }
KOALA_INTEROP_V1(StartPerf,KStringPtr)151 KOALA_INTEROP_V1(StartPerf, KStringPtr)
152 
153 void impl_EndPerf(const KStringPtr& traceName) {
154     auto now = std::chrono::high_resolution_clock::now();
155     PerfInfo* perf = Performance::GetInstance()->GetCurrent();
156     perf->end = std::chrono::time_point_cast<std::chrono::nanoseconds>(now).time_since_epoch().count();
157     perf->cost = perf->end - perf->start;
158     Performance::GetInstance()->FinishOne();
159 }
160 KOALA_INTEROP_V1(EndPerf, KStringPtr)
161 
162 enum DumpOptions {
163     TOTAL = 0,
164     AVERAGE = 1,
165     PEAK = 2,
166     DETAILS = 3,
167     CLEAR = 4
168 };
169 
impl_DumpPerf(KInt options)170 KNativePointer impl_DumpPerf(KInt options) {
171     std::stringstream result;
172     result << std::fixed << std::setprecision(3);
173     auto perf = Performance::GetInstance();
174     perf->CalcSelfCost();
175     switch (options) {
176         case TOTAL:
177             perf->PrintTotals(result);
178             break;
179         case AVERAGE:
180             perf->PrintAvgs(result);
181             break;
182         case PEAK:
183             perf->PrintPeak(result);
184             break;
185         case DETAILS:
186             perf->PrintDetails(result);
187             break;
188         case CLEAR:
189             perf->Clean();
190             break;
191         default:
192             break;
193     }
194     return new std::string(result.str());
195 }
KOALA_INTEROP_1(DumpPerf,KNativePointer,KInt)196 KOALA_INTEROP_1(DumpPerf, KNativePointer, KInt)
197 // custom API methods
198 
199 Ark_NativePointer impl_CreateNode(Ark_Int32 type, Ark_Int32 id, Ark_Int32 flags)
200 {
201     GENERATED_Ark_NodeType typeCast = GENERATED_Ark_NodeType(type);
202     return GetArkUIBasicNodeAPI()->createNode(typeCast, id, flags);
203 }
KOALA_INTEROP_DIRECT_3(CreateNode,Ark_NativePointer,Ark_Int32,Ark_Int32,Ark_Int32)204 KOALA_INTEROP_DIRECT_3(CreateNode, Ark_NativePointer, Ark_Int32, Ark_Int32, Ark_Int32)
205 
206 Ark_NativePointer impl_GetNodeByViewStack()
207 {
208     return GetArkUIBasicNodeAPI()->getNodeByViewStack();
209 }
KOALA_INTEROP_DIRECT_0(GetNodeByViewStack,Ark_NativePointer)210 KOALA_INTEROP_DIRECT_0(GetNodeByViewStack, Ark_NativePointer)
211 
212 void impl_DisposeNode(Ark_NativePointer nodePtr)
213 {
214     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
215     GetArkUIBasicNodeAPI()->disposeNode(nodePtrCast);
216 }
KOALA_INTEROP_DIRECT_V1(DisposeNode,Ark_NativePointer)217 KOALA_INTEROP_DIRECT_V1(DisposeNode, Ark_NativePointer)
218 
219 void impl_DumpTreeNode(Ark_NativePointer nodePtr)
220 {
221     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
222     GetArkUIBasicNodeAPI()->dumpTreeNode(nodePtrCast);
223 }
KOALA_INTEROP_DIRECT_V1(DumpTreeNode,Ark_NativePointer)224 KOALA_INTEROP_DIRECT_V1(DumpTreeNode, Ark_NativePointer)
225 
226 void impl_RemoveChild(Ark_NativePointer parent, Ark_NativePointer child)
227 {
228     Ark_NodeHandle parentCast = (Ark_NodeHandle) parent;
229     Ark_NodeHandle childCast = (Ark_NodeHandle) child;
230     GetArkUIBasicNodeAPI()->removeChild(parentCast, childCast);
231     GetArkUIBasicNodeAPI()->markDirty(parentCast, GENERATED_ARKUI_DIRTY_FLAG_MEASURE_BY_CHILD_REQUEST);
232 }
KOALA_INTEROP_DIRECT_V2(RemoveChild,Ark_NativePointer,Ark_NativePointer)233 KOALA_INTEROP_DIRECT_V2(RemoveChild, Ark_NativePointer, Ark_NativePointer)
234 
235 Ark_Int32 impl_InsertChildAfter(Ark_NativePointer parent, Ark_NativePointer child, Ark_NativePointer sibling)
236 {
237     Ark_NodeHandle parentCast = (Ark_NodeHandle) parent;
238     Ark_NodeHandle childCast = (Ark_NodeHandle) child;
239     Ark_NodeHandle siblingCast = (Ark_NodeHandle) sibling;
240     auto result = GetArkUIBasicNodeAPI()->insertChildAfter(parentCast, childCast, siblingCast);
241     GetArkUIBasicNodeAPI()->markDirty(parentCast, GENERATED_ARKUI_DIRTY_FLAG_MEASURE_BY_CHILD_REQUEST);
242     return result;
243 }
KOALA_INTEROP_DIRECT_3(InsertChildAfter,Ark_Int32,Ark_NativePointer,Ark_NativePointer,Ark_NativePointer)244 KOALA_INTEROP_DIRECT_3(InsertChildAfter, Ark_Int32, Ark_NativePointer, Ark_NativePointer, Ark_NativePointer)
245 
246 Ark_Int32 impl_AddChild(Ark_NativePointer parent, Ark_NativePointer child)
247 {
248     Ark_NodeHandle parentCast = (Ark_NodeHandle) parent;
249     Ark_NodeHandle childCast = (Ark_NodeHandle) child;
250     auto result = GetArkUIBasicNodeAPI()->addChild(parentCast, childCast);
251     GetArkUIBasicNodeAPI()->markDirty(parentCast, GENERATED_ARKUI_DIRTY_FLAG_MEASURE_BY_CHILD_REQUEST);
252     return result;
253 }
KOALA_INTEROP_DIRECT_2(AddChild,Ark_Int32,Ark_NativePointer,Ark_NativePointer)254 KOALA_INTEROP_DIRECT_2(AddChild, Ark_Int32, Ark_NativePointer, Ark_NativePointer)
255 
256 Ark_Int32 impl_InsertChildBefore(Ark_NativePointer parent, Ark_NativePointer child, Ark_NativePointer sibling)
257 {
258     Ark_NodeHandle parentCast = (Ark_NodeHandle) parent;
259     Ark_NodeHandle childCast = (Ark_NodeHandle) child;
260     Ark_NodeHandle siblingCast = (Ark_NodeHandle) sibling;
261     auto result = GetArkUIBasicNodeAPI()->insertChildBefore(parentCast, childCast, siblingCast);
262     GetArkUIBasicNodeAPI()->markDirty(parentCast, GENERATED_ARKUI_DIRTY_FLAG_MEASURE_BY_CHILD_REQUEST);
263     return result;
264 }
KOALA_INTEROP_DIRECT_3(InsertChildBefore,Ark_Int32,Ark_NativePointer,Ark_NativePointer,Ark_NativePointer)265 KOALA_INTEROP_DIRECT_3(InsertChildBefore, Ark_Int32, Ark_NativePointer, Ark_NativePointer, Ark_NativePointer)
266 
267 Ark_Int32 impl_InsertChildAt(Ark_NativePointer parent, Ark_NativePointer child, Ark_Int32 position)
268 {
269     Ark_NodeHandle parentCast = (Ark_NodeHandle) parent;
270     Ark_NodeHandle childCast = (Ark_NodeHandle) child;
271     auto result = GetArkUIBasicNodeAPI()->insertChildAt(parentCast, childCast, position);
272     GetArkUIBasicNodeAPI()->markDirty(parentCast, GENERATED_ARKUI_DIRTY_FLAG_MEASURE_BY_CHILD_REQUEST);
273     return result;
274 }
KOALA_INTEROP_DIRECT_3(InsertChildAt,Ark_Int32,Ark_NativePointer,Ark_NativePointer,Ark_Int32)275 KOALA_INTEROP_DIRECT_3(InsertChildAt, Ark_Int32, Ark_NativePointer, Ark_NativePointer, Ark_Int32)
276 
277 void impl_ApplyModifierFinish(Ark_NativePointer nodePtr)
278 {
279     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
280     GetArkUIBasicNodeAPI()->applyModifierFinish(nodePtrCast);
281 }
KOALA_INTEROP_DIRECT_V1(ApplyModifierFinish,Ark_NativePointer)282 KOALA_INTEROP_DIRECT_V1(ApplyModifierFinish, Ark_NativePointer)
283 
284 void impl_MarkDirty(Ark_NativePointer nodePtr, KUInt dirtyFlag)
285 {
286     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
287     Ark_UInt32 dirtyFlagCast = (Ark_UInt32) dirtyFlag;
288     GetArkUIBasicNodeAPI()->markDirty(nodePtrCast, dirtyFlagCast);
289 }
KOALA_INTEROP_V2(MarkDirty,Ark_NativePointer,KUInt)290 KOALA_INTEROP_V2(MarkDirty, Ark_NativePointer, KUInt)
291 
292 KBoolean impl_IsBuilderNode(Ark_NativePointer nodePtr)
293 {
294     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
295     return GetArkUIBasicNodeAPI()->isBuilderNode(nodePtrCast);
296 }
KOALA_INTEROP_DIRECT_1(IsBuilderNode,KBoolean,Ark_NativePointer)297 KOALA_INTEROP_DIRECT_1(IsBuilderNode, KBoolean, Ark_NativePointer)
298 
299 Ark_Float32 impl_ConvertLengthMetricsUnit(Ark_Float32 value, Ark_Int32 originUnit, Ark_Int32 targetUnit)
300 {
301     return GetArkUIBasicNodeAPI()->convertLengthMetricsUnit(value, originUnit, targetUnit);
302 }
KOALA_INTEROP_DIRECT_3(ConvertLengthMetricsUnit,Ark_Float32,Ark_Float32,Ark_Int32,Ark_Int32)303 KOALA_INTEROP_DIRECT_3(ConvertLengthMetricsUnit, Ark_Float32, Ark_Float32, Ark_Int32, Ark_Int32)
304 
305 void impl_MeasureLayoutAndDraw(KVMContext vmContext, Ark_NativePointer nodePtr)
306 {
307     Ark_VMContext vmContextCast = (Ark_VMContext) vmContext;
308     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
309     GetArkUIExtendedNodeAPI()->measureLayoutAndDraw(vmContextCast, nodePtrCast);
310 }
KOALA_INTEROP_CTX_V1(MeasureLayoutAndDraw,Ark_NativePointer)311 KOALA_INTEROP_CTX_V1(MeasureLayoutAndDraw, Ark_NativePointer)
312 
313 Ark_Int32 impl_MeasureNode(KVMContext vmContext, Ark_NativePointer nodePtr, KFloatArray data)
314 {
315     Ark_VMContext vmContextCast = (Ark_VMContext) vmContext;
316     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
317     Ark_Float32* dataCast = (Ark_Float32*) data;
318     return GetArkUIExtendedNodeAPI()->measureNode(vmContextCast, nodePtrCast, dataCast);
319 }
KOALA_INTEROP_CTX_2(MeasureNode,Ark_Int32,Ark_NativePointer,KFloatArray)320 KOALA_INTEROP_CTX_2(MeasureNode, Ark_Int32, Ark_NativePointer, KFloatArray)
321 
322 Ark_Int32 impl_DrawNode(KVMContext vmContext, Ark_NativePointer nodePtr, KFloatArray data)
323 {
324     Ark_VMContext vmContextCast = (Ark_VMContext) vmContext;
325     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
326     Ark_Float32* dataCast = (Ark_Float32*) data;
327     return GetArkUIExtendedNodeAPI()->drawNode(vmContextCast, nodePtrCast, dataCast);
328 }
KOALA_INTEROP_CTX_2(DrawNode,Ark_Int32,Ark_NativePointer,KFloatArray)329 KOALA_INTEROP_CTX_2(DrawNode, Ark_Int32, Ark_NativePointer, KFloatArray)
330 
331 Ark_Int32 impl_IndexerChecker(KVMContext vmContext, Ark_NativePointer nodePtr)
332 {
333     Ark_VMContext vmContextCast = (Ark_VMContext) vmContext;
334     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
335     return GetArkUIExtendedNodeAPI()->indexerChecker(vmContextCast, nodePtrCast);
336 }
KOALA_INTEROP_CTX_1(IndexerChecker,Ark_Int32,Ark_NativePointer)337 KOALA_INTEROP_CTX_1(IndexerChecker, Ark_Int32, Ark_NativePointer)
338 
339 void impl_SetLazyItemIndexer(KVMContext vmContext, Ark_NativePointer nodePtr, Ark_Int32 indexerId)
340 {
341     Ark_VMContext vmContextCast = (Ark_VMContext) vmContext;
342     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
343     GetArkUIExtendedNodeAPI()->setLazyItemIndexer(vmContextCast, nodePtrCast, indexerId);
344 }
KOALA_INTEROP_CTX_V2(SetLazyItemIndexer,Ark_NativePointer,Ark_Int32)345 KOALA_INTEROP_CTX_V2(SetLazyItemIndexer, Ark_NativePointer, Ark_Int32)
346 
347 void impl_SetCustomCallback(KVMContext vmContext, Ark_NativePointer nodePtr, Ark_Int32 updaterId)
348 {
349     Ark_VMContext vmContextCast = (Ark_VMContext) vmContext;
350     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
351     GetArkUIExtendedNodeAPI()->setCustomCallback(vmContextCast, nodePtrCast, updaterId);
352 }
KOALA_INTEROP_CTX_V2(SetCustomCallback,Ark_NativePointer,Ark_Int32)353 KOALA_INTEROP_CTX_V2(SetCustomCallback, Ark_NativePointer, Ark_Int32)
354 
355 void impl_SetMeasureWidth(Ark_NativePointer nodePtr, Ark_Int32 value)
356 {
357     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
358     GetArkUIExtendedNodeAPI()->setMeasureWidth(nodePtrCast, value);
359 }
KOALA_INTEROP_DIRECT_V2(SetMeasureWidth,Ark_NativePointer,Ark_Int32)360 KOALA_INTEROP_DIRECT_V2(SetMeasureWidth, Ark_NativePointer, Ark_Int32)
361 
362 Ark_Int32 impl_GetMeasureWidth(Ark_NativePointer nodePtr)
363 {
364     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
365     return GetArkUIExtendedNodeAPI()->getMeasureWidth(nodePtrCast);
366 }
KOALA_INTEROP_DIRECT_1(GetMeasureWidth,Ark_Int32,Ark_NativePointer)367 KOALA_INTEROP_DIRECT_1(GetMeasureWidth, Ark_Int32, Ark_NativePointer)
368 
369 void impl_SetMeasureHeight(Ark_NativePointer nodePtr, Ark_Int32 value)
370 {
371     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
372     GetArkUIExtendedNodeAPI()->setMeasureHeight(nodePtrCast, value);
373 }
KOALA_INTEROP_DIRECT_V2(SetMeasureHeight,Ark_NativePointer,Ark_Int32)374 KOALA_INTEROP_DIRECT_V2(SetMeasureHeight, Ark_NativePointer, Ark_Int32)
375 
376 Ark_Int32 impl_GetMeasureHeight(Ark_NativePointer nodePtr)
377 {
378     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
379     return GetArkUIExtendedNodeAPI()->getMeasureHeight(nodePtrCast);
380 }
KOALA_INTEROP_DIRECT_1(GetMeasureHeight,Ark_Int32,Ark_NativePointer)381 KOALA_INTEROP_DIRECT_1(GetMeasureHeight, Ark_Int32, Ark_NativePointer)
382 
383 void impl_SetX(Ark_NativePointer nodePtr, Ark_Int32 value)
384 {
385     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
386     GetArkUIExtendedNodeAPI()->setX(nodePtrCast, value);
387 }
KOALA_INTEROP_DIRECT_V2(SetX,Ark_NativePointer,Ark_Int32)388 KOALA_INTEROP_DIRECT_V2(SetX, Ark_NativePointer, Ark_Int32)
389 
390 Ark_Int32 impl_GetX(Ark_NativePointer nodePtr)
391 {
392     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
393     return GetArkUIExtendedNodeAPI()->getX(nodePtrCast);
394 }
KOALA_INTEROP_DIRECT_1(GetX,Ark_Int32,Ark_NativePointer)395 KOALA_INTEROP_DIRECT_1(GetX, Ark_Int32, Ark_NativePointer)
396 
397 void impl_SetY(Ark_NativePointer nodePtr, Ark_Int32 value)
398 {
399     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
400     GetArkUIExtendedNodeAPI()->setY(nodePtrCast, value);
401 }
KOALA_INTEROP_DIRECT_V2(SetY,Ark_NativePointer,Ark_Int32)402 KOALA_INTEROP_DIRECT_V2(SetY, Ark_NativePointer, Ark_Int32)
403 
404 Ark_Int32 impl_GetY(Ark_NativePointer nodePtr)
405 {
406     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
407     return GetArkUIExtendedNodeAPI()->getY(nodePtrCast);
408 }
KOALA_INTEROP_DIRECT_1(GetY,Ark_Int32,Ark_NativePointer)409 KOALA_INTEROP_DIRECT_1(GetY, Ark_Int32, Ark_NativePointer)
410 
411 void impl_SetAlignment(Ark_NativePointer nodePtr, Ark_Int32 value)
412 {
413     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
414     GetArkUIExtendedNodeAPI()->setAlignment(nodePtrCast, value);
415 }
KOALA_INTEROP_DIRECT_V2(SetAlignment,Ark_NativePointer,Ark_Int32)416 KOALA_INTEROP_DIRECT_V2(SetAlignment, Ark_NativePointer, Ark_Int32)
417 
418 Ark_Int32 impl_GetAlignment(Ark_NativePointer nodePtr)
419 {
420     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
421     return GetArkUIExtendedNodeAPI()->getAlignment(nodePtrCast);
422 }
KOALA_INTEROP_DIRECT_1(GetAlignment,Ark_Int32,Ark_NativePointer)423 KOALA_INTEROP_DIRECT_1(GetAlignment, Ark_Int32, Ark_NativePointer)
424 
425 void impl_SetRangeUpdater(Ark_NativePointer nodePtr, Ark_Int32 updaterId)
426 {
427     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
428     GetArkUIExtendedNodeAPI()->setRangeUpdater(nodePtrCast, updaterId);
429 }
KOALA_INTEROP_DIRECT_V2(SetRangeUpdater,Ark_NativePointer,Ark_Int32)430 KOALA_INTEROP_DIRECT_V2(SetRangeUpdater, Ark_NativePointer, Ark_Int32)
431 
432 void impl_SetChildTotalCount(Ark_NativePointer nodePtr, Ark_Int32 totalCount)
433 {
434     Ark_NodeHandle nodePtrCast = (Ark_NodeHandle) nodePtr;
435     GetArkUIExtendedNodeAPI()->setChildTotalCount(nodePtrCast, totalCount);
436 }
437 KOALA_INTEROP_DIRECT_V2(SetChildTotalCount, Ark_NativePointer, Ark_Int32)
438 
439 static const std::string PAGE_SUFFIX = "GeneratedEntry";
isPageClass(const std::string & className)440 [[maybe_unused]] static bool isPageClass(const std::string& className)
441 {
442     return (PAGE_SUFFIX.size() < className.size()) && std::equal(PAGE_SUFFIX.rbegin(), PAGE_SUFFIX.rend(), className.rbegin());
443 }
444 
impl_LoadUserView(KVMContext vm,const KStringPtr & viewClass,const KStringPtr & viewParams)445 KVMObjectHandle impl_LoadUserView(KVMContext vm, const KStringPtr& viewClass, const KStringPtr& viewParams) {
446 #ifdef KOALA_USE_JAVA_VM
447     JNIEnv* env = reinterpret_cast<JNIEnv*>(vm);
448     std:: string className(viewClass.c_str());
449     std::replace(className.begin(), className.end(), '.', '/');
450     jclass viewClassClass = env->FindClass(className.c_str());
451     if (!viewClassClass) {
452         LOGE("Cannot find user class %" LOG_PUBLIC "s", viewClass.c_str());
453         if (env->ExceptionCheck()) {
454             env->ExceptionDescribe();
455             env->ExceptionClear();
456         }
457         return nullptr;
458     }
459     jmethodID viewClassCtor = env->GetMethodID(viewClassClass, "<init>", "(Ljava/lang/String;)V");
460     if (!viewClassCtor) {
461         LOGE("Cannot find user class ctor");
462         if (env->ExceptionCheck()) {
463             env->ExceptionDescribe();
464             env->ExceptionClear();
465         }
466         return nullptr;
467     }
468     jobject result = env->NewObject(viewClassClass, viewClassCtor, env->NewStringUTF(viewParams.c_str()));
469     if (!result) {
470         LOGE("Cannot instantiate user class");
471         if (env->ExceptionCheck()) {
472             env->ExceptionDescribe();
473             env->ExceptionClear();
474         }
475         return nullptr;
476     }
477     return (KVMObjectHandle)result;
478 #elif KOALA_ETS_NAPI
479     EtsEnv* env = reinterpret_cast<EtsEnv*>(vm);
480     std:: string className(viewClass.c_str());
481     // TODO: hack, fix it!
482     if (className == "ViewLoaderApp") {
483         className = "Page.App";
484     } else if (className == "EtsHarness") {
485         className = "@koalaui.ets-harness.build.unmemoized.build.Page.EtsHarness";
486     } else if (isPageClass(className)) {
487         className = "@koalaui.user.build.unmemoized.build.generated." + className;
488     } else {
489         className = "@koalaui.user.build.unmemoized.src.Page." + className;
490     }
491     std::replace(className.begin(), className.end(), '.', '/');
492     ets_class viewClassClass = env->FindClass(className.c_str());
493     if (!viewClassClass) {
494         fprintf(stderr, "Cannot find user class %s\n", viewClass.c_str());
495         if (env->ErrorCheck()) {
496             env->ErrorDescribe();
497             env->ErrorClear();
498         }
499         return nullptr;
500     }
501     ets_method viewClassCtor = env->Getp_method(viewClassClass, "<ctor>", "Lstd/core/String;:V");
502     if (!viewClassCtor) {
503         fprintf(stderr, "Cannot find user class ctor\n");
504         if (env->ErrorCheck()) {
505             env->ErrorDescribe();
506             env->ErrorClear();
507         }
508         return nullptr;
509     }
510     ets_object result = env->NewObject(viewClassClass, viewClassCtor, env->NewStringUTF(viewParams.c_str()));
511     if (!result) {
512         fprintf(stderr, "Cannot instantiate user class\n");
513         if (env->ErrorCheck()) {
514             env->ErrorDescribe();
515             env->ErrorClear();
516         }
517         return nullptr;
518     }
519     return (KVMObjectHandle)result;
520 #elif KOALA_ANI
521     ani_env* env = reinterpret_cast<ani_env*>(vm);
522     std::string className(viewClass.c_str());
523     // TODO: hack, fix it!
524     if (className == "UserApp") {
525         className = "L@koalaui.arkts-arkui.Application.UserView;";
526     } if (className == "EtsHarness") {
527         className = "L@koalaui.ets-harness.build.unmemoized.build.Page.EtsHarness";
528     } else if (isPageClass(className)) {
529         className = "L@koalaui.user.build.unmemoized.build.generated." + className + ";";
530     } else {
531         className = "L@koalaui.user.build.unmemoized.src.Page." + className + ";";
532     }
533     std::replace(className.begin(), className.end(), '.', '/');
534     ani_class viewClassClass = nullptr;
535     env->FindClass(className.c_str(), &viewClassClass);
536     if (!viewClassClass) {
537         LOGE("Cannot find user class %" LOG_PUBLIC "s\n", viewClass.c_str());
538         ani_boolean hasError = false;
539         env->ExistUnhandledError(&hasError);
540         if (hasError) {
541             env->DescribeError();
542             env->ResetError();
543         }
544         return nullptr;
545     }
546     ani_method viewClassCtor = nullptr;
547     env->Class_FindMethod(viewClassClass, "<ctor>", "Lstd/core/String;:V", &viewClassCtor);
548     if (!viewClassCtor) {
549         LOGE("Cannot find user class ctor");
550         ani_boolean hasError = false;
551         env->ExistUnhandledError(&hasError);
552         if (hasError) {
553             env->DescribeError();
554             env->ResetError();
555         }
556         return nullptr;
557     }
558     ani_object result = nullptr;
559     ani_string params = nullptr;
560     env->String_NewUTF8(viewParams.c_str(), viewParams.length(), &params);
561     env->Object_New(viewClassClass, viewClassCtor, &result, params);
562     if (!result) {
563         LOGE("Cannot instantiate user class");
564         ani_boolean hasError = false;
565         env->ExistUnhandledError(&hasError);
566         if (hasError) {
567             env->DescribeError();
568             env->ResetError();
569         }
570         return nullptr;
571     }
572     return (KVMObjectHandle)result;
573 #else
574     LOGE("LoadUserView() is not implemented yet");
575     return nullptr;
576 #endif
577 }
578 KOALA_INTEROP_CTX_2(LoadUserView, KVMObjectHandle, KStringPtr, KStringPtr)
579