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 "NodeJS.h"
17
18 #include <scene/interface/intf_node.h>
19 #include <scene/interface/intf_scene.h>
20
21 #include "SceneJS.h"
Init(napi_env env,napi_value exports)22 void NodeJS::Init(napi_env env, napi_value exports)
23 {
24 BASE_NS::vector<napi_property_descriptor> node_props;
25 NodeImpl::GetPropertyDescs(node_props);
26
27 napi_value func;
28 auto status = napi_define_class(env, "Node", NAPI_AUTO_LENGTH, BaseObject::ctor<NodeJS>(), nullptr,
29 node_props.size(), node_props.data(), &func);
30
31 NapiApi::MyInstanceState* mis;
32 GetInstanceData(env, (void**)&mis);
33 mis->StoreCtor("Node", func);
34 }
35
NodeJS(napi_env e,napi_callback_info i)36 NodeJS::NodeJS(napi_env e, napi_callback_info i) : BaseObject<NodeJS>(e, i), NodeImpl(NodeImpl::NODE)
37 {
38 LOG_V("NodeJS ++");
39
40 NapiApi::FunctionContext<NapiApi::Object, NapiApi::Object> fromJs(e, i);
41 if (!fromJs) {
42 // no arguments. so internal create.
43 // expecting caller to finish initialization
44 return;
45 }
46
47 {
48 // add the dispose hook to scene. (so that the geometry node is disposed when scene is disposed)
49 NapiApi::Object meJs(fromJs.This());
50 NapiApi::Object scene = fromJs.Arg<0>();
51 if (auto sceneJS = GetJsWrapper<SceneJS>(scene)) {
52 sceneJS->StrongDisposeHook(reinterpret_cast<uintptr_t>(&scene_), meJs);
53 }
54 }
55
56 // java script call.. with arguments
57 scene_ = fromJs.Arg<0>().valueOrDefault();
58 auto scn = GetNativeMeta<SCENE_NS::IScene>(scene_.GetObject());
59 if (scn == nullptr) {
60 // hmm..
61 LOG_F("Invalid scene for NodeJS!");
62 return;
63 }
64 NapiApi::Object args = fromJs.Arg<1>();
65
66 auto obj = GetNativeObjectParam<META_NS::IObject>(args);
67 if (obj) {
68 StoreJsObj(obj, fromJs.This());
69 return;
70 }
71
72 // collect parameters
73 NapiApi::Value<BASE_NS::string> name;
74 NapiApi::Value<BASE_NS::string> path;
75 if (auto prm = args.Get("name")) {
76 name = NapiApi::Value<BASE_NS::string>(e, prm);
77 }
78 if (auto prm = args.Get("path")) {
79 path = NapiApi::Value<BASE_NS::string>(e, prm);
80 }
81
82 BASE_NS::string nodePath;
83
84 if (path.IsDefined()) {
85 // create using path
86 nodePath = path.valueOrDefault("");
87 } else if (name.IsDefined()) {
88 // use the name as path (creates under root)
89 nodePath = name.valueOrDefault("");
90 }
91
92 // Create actual node object.
93 SCENE_NS::INode::Ptr node = scn->CreateNode(nodePath).GetResult();
94
95 SetNativeObject(interface_pointer_cast<META_NS::IObject>(node), false);
96 node.reset();
97 NapiApi::Object meJs(fromJs.This());
98 StoreJsObj(GetNativeObject(), meJs);
99
100 if (name.IsDefined()) {
101 // set the name of the object. if we were given one
102 meJs.Set("name", name);
103 }
104 }
~NodeJS()105 NodeJS::~NodeJS()
106 {
107 LOG_V("NodeJS --");
108 }
GetInstanceImpl(uint32_t id)109 void* NodeJS::GetInstanceImpl(uint32_t id)
110 {
111 if (id == NodeJS::ID)
112 return this;
113 return NodeImpl::GetInstanceImpl(id);
114 }
115
DisposeNative(void * sc)116 void NodeJS::DisposeNative(void* sc)
117 {
118 if (!disposed_) {
119 LOG_V("NodeJS::DisposeNative");
120 disposed_ = true;
121
122 if (auto* sceneJS = static_cast<SceneJS*>(sc)) {
123 sceneJS->ReleaseStrongDispose(reinterpret_cast<uintptr_t>(&scene_));
124 }
125
126 scene_.Reset();
127 }
128 }
Finalize(napi_env env)129 void NodeJS::Finalize(napi_env env)
130 {
131 DisposeNative(GetJsWrapper<SceneJS>(scene_.GetObject()));
132 BaseObject::Finalize(env);
133 }