/* * Copyright (C) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "MeshResourceJS.h" #include #include #include #include "SceneJS.h" MeshResourceJS::MeshResourceJS(napi_env e, napi_callback_info i) : BaseObject(e, i), SceneResourceImpl(SceneResourceType::MESH_RESOURCE) { NapiApi::FunctionContext ctx(e, i); // As long as our native object is a dummy interface without a backing implementation, we're only concerned about // arg validity and not about native object existence. if (!ctx) { LOG_E("Cannot finish creating a mesh resource: Invalid args given"); assert(false); return; } scene_ = ctx.Arg<0>().valueOrDefault(); // Add the dispose hook to scene so that the MeshResourceJS is disposed when scene is disposed. if (const auto sceneJS = scene_.GetObject().GetJsWrapper()) { sceneJS->DisposeHook(reinterpret_cast(&scene_), ctx.This()); } auto resourceParams = NapiApi::Object { ctx.Arg<1>() }; if (auto nameParam = resourceParams.Get("name"); nameParam.IsDefined()) { ctx.This().Set("name", nameParam); } GeometryDefinition::GeometryDefinition* geomDef {}; napi_get_value_external(e, resourceParams.Get("GeometryDefinition"), (void**)&geomDef); geometryDefinition_.reset(geomDef); } void MeshResourceJS::Init(napi_env env, napi_value exports) { BASE_NS::vector node_props; SceneResourceImpl::GetPropertyDescs(node_props); #define NAPI_API_JS_NAME MeshResource DeclareClass(); #undef NAPI_API_JS_NAME } void* MeshResourceJS::GetInstanceImpl(uint32_t id) { return (id == MeshResourceJS::ID) ? this : SceneResourceImpl::GetInstanceImpl(id); } SCENE_NS::IMesh::Ptr MeshResourceJS::CreateMesh() { auto scene = scene_.GetObject().GetNative(); if (!scene || !geometryDefinition_) { return {}; } const auto meshCreator = scene->CreateObject(SCENE_NS::ClassId::MeshCreator).GetResult(); // Name and material aren't set here. Name is set in the constructor. Material needs to be manually set later. auto meshConfig = SCENE_NS::MeshConfig {}; return geometryDefinition_->CreateMesh(meshCreator, meshConfig); } void MeshResourceJS::DisposeNative(void* scene) { if (disposed_) { return; } disposed_ = true; if (auto node = interface_pointer_cast(GetNativeObject())) { UnsetNativeObject(); } geometryDefinition_.reset(); if (auto* sceneJS = static_cast(scene)) { sceneJS->ReleaseDispose(reinterpret_cast(&scene_)); } scene_.Reset(); } void MeshResourceJS::Finalize(napi_env env) { DisposeNative(scene_.GetObject().GetJsWrapper()); BaseObject::Finalize(env); }