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 "GeometryJS.h"
17 
18 #include <meta/api/make_callback.h>
19 #include <meta/interface/intf_task_queue.h>
20 #include <meta/interface/intf_task_queue_registry.h>
21 #include <scene_plugin/api/camera_uid.h>
22 #include <scene_plugin/interface/intf_camera.h>
23 #include <scene_plugin/interface/intf_scene.h>
24 
GetInstanceImpl(uint32_t id)25 void* GeometryJS::GetInstanceImpl(uint32_t id)
26 {
27     if (id == GeometryJS::ID) {
28         return this;
29     }
30     return NodeImpl::GetInstanceImpl(id);
31 }
DisposeNative()32 void GeometryJS::DisposeNative()
33 {
34     // do nothing for now..
35     CORE_LOG_F("GeometryJS::DisposeNative");
36     if (auto node = interface_pointer_cast<SCENE_NS::INode>(GetNativeObject())) {
37         // reset the native object refs
38         SetNativeObject(nullptr, false);
39         SetNativeObject(nullptr, true);
40 
41         ExecSyncTask([nod = BASE_NS::move(node)]() mutable {
42             auto scene = nod->GetScene();
43             if (scene == nullptr) {
44                 return META_NS::IAny::Ptr {};
45             }
46             scene->ReleaseNode(nod);
47             return META_NS::IAny::Ptr {};
48         });
49     }
50     scene_.Reset();
51 }
Init(napi_env env,napi_value exports)52 void GeometryJS::Init(napi_env env, napi_value exports)
53 {
54     BASE_NS::vector<napi_property_descriptor> node_props;
55     NodeImpl::GetPropertyDescs(node_props);
56 
57     using namespace NapiApi;
58     node_props.push_back(GetProperty<Object, GeometryJS, &GeometryJS::GetMesh>("mesh"));
59 
60     napi_value func;
61     auto status = napi_define_class(env, "Geometry", NAPI_AUTO_LENGTH, BaseObject::ctor<GeometryJS>(), nullptr,
62         node_props.size(), node_props.data(), &func);
63 
64     NapiApi::MyInstanceState* mis;
65     napi_get_instance_data(env, (void**)&mis);
66     mis->StoreCtor("Geometry", func);
67 }
68 
GeometryJS(napi_env e,napi_callback_info i)69 GeometryJS::GeometryJS(napi_env e, napi_callback_info i) : BaseObject<GeometryJS>(e, i), NodeImpl(NodeImpl::GEOMETRY)
70 {
71     LOG_F("GeometryJS ++ ");
72     NapiApi::FunctionContext<NapiApi::Object, NapiApi::Object> fromJs(e, i);
73     // java script call.. with arguments
74     if (!fromJs) {
75         // okay internal create. we will receive the object after.
76         return;
77     }
78     scene_ = fromJs.Arg<0>().valueOrDefault();
79     // Creating new object...  (so we must have scene etc)
80     auto scn = GetNativeMeta<SCENE_NS::IScene>(scene_.GetObject());
81     if (scn == nullptr) {
82         CORE_LOG_F("Invalid scene for GeometryJS!");
83         return;
84     }
85     // missing actual creation of geometry node. (refer to camerajs etc)
86 }
~GeometryJS()87 GeometryJS::~GeometryJS()
88 {
89     LOG_F("GeometryJS -- ");
90 }
91 
GetMesh(NapiApi::FunctionContext<> & ctx)92 napi_value GeometryJS::GetMesh(NapiApi::FunctionContext<>& ctx)
93 {
94     META_NS::IObject::Ptr mesh;
95     if (auto geom = interface_pointer_cast<SCENE_NS::INode>(GetNativeObject())) {
96         ExecSyncTask([geom, &mesh]() {
97             mesh = interface_pointer_cast<META_NS::IObject>(geom->Mesh()->GetValue());
98             return META_NS::IAny::Ptr {};
99         });
100     }
101 
102     if (!mesh) {
103         // no parent.
104         napi_value res;
105         napi_get_null(ctx, &res);
106         return res;
107     }
108 
109     if (auto cached = FetchJsObj(mesh)) {
110         // always return the same js object.
111         return cached;
112     }
113     // create new js object for the native node.
114     NapiApi::Object argJS(ctx);
115     napi_value args[] = { scene_.GetValue(), argJS };
116 
117     return CreateFromNativeInstance(ctx, mesh, false /*these are owned by the scene*/, BASE_NS::countof(args), args);
118 }