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