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
25void* GeometryJS::GetInstanceImpl(uint32_t id)
26{
27    if (id == GeometryJS::ID) {
28        return this;
29    }
30    return NodeImpl::GetInstanceImpl(id);
31}
32void 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}
52void 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
69GeometryJS::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}
87GeometryJS::~GeometryJS()
88{
89    LOG_F("GeometryJS -- ");
90}
91
92napi_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}