/* * 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 "SceneResourceImpl.h" #include "BaseObjectJS.h" #include "SceneJS.h" #include SceneResourceImpl::SceneResourceImpl(SceneResourceType type) : type_(type) { LOG_V("SceneResourceImpl ++"); } SceneResourceImpl::~SceneResourceImpl() { LOG_V("SceneResourceImpl --"); } void SceneResourceImpl::RegisterEnums(NapiApi::Object exports) { napi_value v; NapiApi::Object SceneResourceType(exports.GetEnv()); #define DECL_ENUM(enu, x) \ { \ napi_create_uint32(enu.GetEnv(), SceneResourceType::x, &v); \ enu.Set(#x, v); \ } DECL_ENUM(SceneResourceType, UNKNOWN); DECL_ENUM(SceneResourceType, NODE); DECL_ENUM(SceneResourceType, ENVIRONMENT); DECL_ENUM(SceneResourceType, MATERIAL); DECL_ENUM(SceneResourceType, MESH); DECL_ENUM(SceneResourceType, ANIMATION); DECL_ENUM(SceneResourceType, SHADER); DECL_ENUM(SceneResourceType, IMAGE); DECL_ENUM(SceneResourceType, MESH_RESOURCE); #undef DECL_ENUM exports.Set("SceneResourceType", SceneResourceType); } void SceneResourceImpl::GetPropertyDescs(BASE_NS::vector& props) { props.push_back( TROGetSetProperty( "name")); props.push_back(TROGetProperty("uri")); props.push_back( TROGetProperty("resourceType")); props.push_back( MakeTROMethod, SceneResourceImpl, &SceneResourceImpl::Dispose>("destroy")); } void* SceneResourceImpl::GetInstanceImpl(uint32_t id) { if (id == SceneResourceImpl::ID) return this; return nullptr; } bool SceneResourceImpl::validateSceneRef() { if (scene_.GetObject()) { // scene reference still valid. // so resource should still be valid. return true; } // scene reference lost, so the resource should be disposed LOG_V("Scene reference lost."); return false; } napi_value SceneResourceImpl::Dispose(NapiApi::FunctionContext<>& ctx) { // Dispose of the native object. (makes the js object invalid) if (TrueRootObject* instance = ctx.This().GetRoot()) { // see if we have "scenejs" as ext (prefer one given as argument) napi_status stat; SceneJS* ptr { nullptr }; NapiApi::FunctionContext args(ctx); if (args) { if (NapiApi::Object obj = args.Arg<0>()) { if (napi_value ext = obj.Get("SceneJS")) { stat = napi_get_value_external(ctx.GetEnv(), ext, (void**)&ptr); } } } if (!ptr) { ptr = scene_.GetObject().GetJsWrapper(); } instance->DisposeNative(ptr); } scene_.Reset(); uri_.Reset(); return ctx.GetUndefined(); } napi_value SceneResourceImpl::GetObjectType(NapiApi::FunctionContext<>& ctx) { if (!validateSceneRef()) { return ctx.GetUndefined(); } uint32_t type = -1; // return -1 if the resource does not exist anymore if (ctx.This().GetNative()) { type = type_; } return ctx.GetNumber(type); } napi_value SceneResourceImpl::GetName(NapiApi::FunctionContext<>& ctx) { if (!validateSceneRef()) { return ctx.GetUndefined(); } BASE_NS::string name; auto native = ctx.This().GetNative(); if (auto named = interface_cast(native)) { name = META_NS::GetValue(named->Name()); } else if (native) { name = native->GetName(); } if (name.empty()) { name = name_; // Use cached if we didn't get anything from underlying object } return ctx.GetString(name); } void SceneResourceImpl::SetName(NapiApi::FunctionContext& ctx) { if (!validateSceneRef()) { return; } BASE_NS::string name = ctx.Arg<0>(); auto object = ctx.This(); auto native = object.GetNative(); if (auto named = interface_cast(native)) { META_NS::SetValue(named->Name(), name); } else if (auto objectname = interface_cast(native)) { objectname->SetName(name); } else { // Object does not support naming, store name locally name_ = name; } } void SceneResourceImpl::SetUri(NapiApi::StrongRef uri) { if (!validateSceneRef()) { return; } uri_ = BASE_NS::move(uri); } napi_value SceneResourceImpl::GetUri(NapiApi::FunctionContext<>& ctx) { if (!validateSceneRef()) { return ctx.GetUndefined(); } return uri_.GetValue(); }