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 "MeshResourceJS.h"
17
18 #include <scene/interface/intf_create_mesh.h>
19 #include <scene/interface/intf_mesh_resource.h>
20 #include <scene/interface/intf_scene.h>
21
22 #include "SceneJS.h"
23
MeshResourceJS(napi_env e,napi_callback_info i)24 MeshResourceJS::MeshResourceJS(napi_env e, napi_callback_info i)
25 : BaseObject(e, i), SceneResourceImpl(SceneResourceType::MESH_RESOURCE)
26 {
27 NapiApi::FunctionContext<NapiApi::Object, NapiApi::Object> ctx(e, i);
28 // As long as our native object is a dummy interface without a backing implementation, we're only concerned about
29 // arg validity and not about native object existence.
30 if (!ctx) {
31 LOG_E("Cannot finish creating a mesh resource: Invalid args given");
32 assert(false);
33 return;
34 }
35
36 scene_ = ctx.Arg<0>().valueOrDefault();
37 // Add the dispose hook to scene so that the MeshResourceJS is disposed when scene is disposed.
38 if (const auto sceneJS = scene_.GetObject().GetJsWrapper<SceneJS>()) {
39 sceneJS->DisposeHook(reinterpret_cast<uintptr_t>(&scene_), ctx.This());
40 }
41
42 auto resourceParams = NapiApi::Object { ctx.Arg<1>() };
43 if (auto nameParam = resourceParams.Get<BASE_NS::string>("name"); nameParam.IsDefined()) {
44 ctx.This().Set("name", nameParam);
45 }
46
47 GeometryDefinition::GeometryDefinition* geomDef {};
48 napi_get_value_external(e, resourceParams.Get("GeometryDefinition"), (void**)&geomDef);
49 geometryDefinition_.reset(geomDef);
50 }
51
Init(napi_env env,napi_value exports)52 void MeshResourceJS::Init(napi_env env, napi_value exports)
53 {
54 BASE_NS::vector<napi_property_descriptor> node_props;
55 SceneResourceImpl::GetPropertyDescs(node_props);
56
57 #define NAPI_API_JS_NAME MeshResource
58 DeclareClass();
59 #undef NAPI_API_JS_NAME
60 }
61
GetInstanceImpl(uint32_t id)62 void* MeshResourceJS::GetInstanceImpl(uint32_t id)
63 {
64 return (id == MeshResourceJS::ID) ? this : SceneResourceImpl::GetInstanceImpl(id);
65 }
66
CreateMesh()67 SCENE_NS::IMesh::Ptr MeshResourceJS::CreateMesh()
68 {
69 auto scene = scene_.GetObject().GetNative<SCENE_NS::IScene>();
70 if (!scene || !geometryDefinition_) {
71 return {};
72 }
73
74 const auto meshCreator = scene->CreateObject<SCENE_NS::ICreateMesh>(SCENE_NS::ClassId::MeshCreator).GetResult();
75 // Name and material aren't set here. Name is set in the constructor. Material needs to be manually set later.
76 auto meshConfig = SCENE_NS::MeshConfig {};
77 return geometryDefinition_->CreateMesh(meshCreator, meshConfig);
78 }
79
DisposeNative(void * scene)80 void MeshResourceJS::DisposeNative(void* scene)
81 {
82 if (disposed_) {
83 return;
84 }
85 disposed_ = true;
86 if (auto node = interface_pointer_cast<SCENE_NS::IMeshResource>(GetNativeObject())) {
87 UnsetNativeObject();
88 }
89 geometryDefinition_.reset();
90
91 if (auto* sceneJS = static_cast<SceneJS*>(scene)) {
92 sceneJS->ReleaseDispose(reinterpret_cast<uintptr_t>(&scene_));
93 }
94
95 scene_.Reset();
96 }
97
Finalize(napi_env env)98 void MeshResourceJS::Finalize(napi_env env)
99 {
100 DisposeNative(scene_.GetObject().GetJsWrapper<SceneJS>());
101 BaseObject::Finalize(env);
102 }
103