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 "SceneResourceImpl.h"
17
18 #include "BaseObjectJS.h"
19 #include "SceneJS.h"
20
SceneResourceImpl(SceneResourceType type)21 SceneResourceImpl::SceneResourceImpl(SceneResourceType type) : type_(type)
22 {
23 LOG_V("SceneResourceImpl ++");
24 }
~SceneResourceImpl()25 SceneResourceImpl::~SceneResourceImpl()
26 {
27 LOG_V("SceneResourceImpl --");
28 }
29
RegisterEnums(NapiApi::Object exports)30 void SceneResourceImpl::RegisterEnums(NapiApi::Object exports)
31 {
32 napi_value v;
33 NapiApi::Object SceneResourceType(exports.GetEnv());
34
35 #define DECL_ENUM(enu, x) \
36 { \
37 napi_create_uint32(enu.GetEnv(), SceneResourceType::x, &v); \
38 enu.Set(#x, v); \
39 }
40 DECL_ENUM(SceneResourceType, UNKNOWN);
41 DECL_ENUM(SceneResourceType, NODE);
42 DECL_ENUM(SceneResourceType, ENVIRONMENT);
43 DECL_ENUM(SceneResourceType, MATERIAL);
44 DECL_ENUM(SceneResourceType, MESH);
45 DECL_ENUM(SceneResourceType, ANIMATION);
46 DECL_ENUM(SceneResourceType, SHADER);
47 DECL_ENUM(SceneResourceType, IMAGE);
48 DECL_ENUM(SceneResourceType, MESH_RESOURCE);
49 #undef DECL_ENUM
50
51 exports.Set("SceneResourceType", SceneResourceType);
52 }
53
GetPropertyDescs(BASE_NS::vector<napi_property_descriptor> & props)54 void SceneResourceImpl::GetPropertyDescs(BASE_NS::vector<napi_property_descriptor>& props)
55 {
56 props.push_back(
57 TROGetSetProperty<BASE_NS::string, SceneResourceImpl, &SceneResourceImpl::GetName, &SceneResourceImpl::SetName>(
58 "name"));
59 props.push_back(TROGetProperty<NapiApi::Object, SceneResourceImpl, &SceneResourceImpl::GetUri>("uri"));
60 props.push_back(
61 TROGetProperty<BASE_NS::string, SceneResourceImpl, &SceneResourceImpl::GetObjectType>("resourceType"));
62 props.push_back(
63 MakeTROMethod<NapiApi::FunctionContext<>, SceneResourceImpl, &SceneResourceImpl::Dispose>("destroy"));
64 }
65
GetInstanceImpl(uint32_t id)66 void* SceneResourceImpl::GetInstanceImpl(uint32_t id)
67 {
68 if (id == SceneResourceImpl::ID)
69 return this;
70 return nullptr;
71 }
validateSceneRef()72 bool SceneResourceImpl::validateSceneRef()
73 {
74 if (scene_.GetObject()) {
75 // scene reference still valid.
76 // so resource should still be valid.
77 return true;
78 }
79 // scene reference lost, so the resource should be disposed
80 LOG_V("Scene reference lost.");
81 return false;
82 }
83
Dispose(NapiApi::FunctionContext<> & ctx)84 napi_value SceneResourceImpl::Dispose(NapiApi::FunctionContext<>& ctx)
85 {
86 // Dispose of the native object. (makes the js object invalid)
87 if (TrueRootObject* instance = GetThisRootObject(ctx)) {
88 // see if we have "scenejs" as ext (prefer one given as argument)
89 napi_status stat;
90 SceneJS* ptr { nullptr };
91 NapiApi::FunctionContext<NapiApi::Object> args(ctx);
92 if (args) {
93 if (NapiApi::Object obj = args.Arg<0>()) {
94 if (napi_value ext = obj.Get("SceneJS")) {
95 stat = napi_get_value_external(ctx.GetEnv(), ext, (void**)&ptr);
96 }
97 }
98 }
99 if (!ptr) {
100 NapiApi::Object obj = scene_.GetObject();
101 if (obj) {
102 auto* tro = obj.Native<TrueRootObject>();
103 if (tro) {
104 ptr = static_cast<SceneJS*>(tro->GetInstanceImpl(SceneJS::ID));
105 }
106 }
107 }
108 instance->DisposeNative(ptr);
109 }
110 scene_.Reset();
111 uri_.Reset();
112 return ctx.GetUndefined();
113 }
114
GetObjectType(NapiApi::FunctionContext<> & ctx)115 napi_value SceneResourceImpl::GetObjectType(NapiApi::FunctionContext<>& ctx)
116 {
117 if (!validateSceneRef()) {
118 return ctx.GetUndefined();
119 }
120
121 return ctx.GetNumber(type_);
122 }
123
GetName(NapiApi::FunctionContext<> & ctx)124 napi_value SceneResourceImpl::GetName(NapiApi::FunctionContext<>& ctx)
125 {
126 if (!validateSceneRef()) {
127 return ctx.GetUndefined();
128 }
129
130 BASE_NS::string name;
131 if (auto named = interface_pointer_cast<META_NS::INamed>(GetThisNativeObject(ctx))) {
132 name = named->Name()->GetValue();
133 } else if (auto node = interface_pointer_cast<META_NS::IObject>(GetThisNativeObject(ctx))) {
134 name = node->GetName();
135 }
136 return ctx.GetString(name);
137 }
SetName(NapiApi::FunctionContext<BASE_NS::string> & ctx)138 void SceneResourceImpl::SetName(NapiApi::FunctionContext<BASE_NS::string>& ctx)
139 {
140 if (!validateSceneRef()) {
141 return;
142 }
143 BASE_NS::string name = ctx.Arg<0>();
144 if (auto named = interface_pointer_cast<META_NS::INamed>(GetThisNativeObject(ctx))) {
145 named->Name()->SetValue(name);
146 } else {
147 LOG_E("renaming resource not implemented, trying to name (%d) to '%s'", type_, name.c_str());
148 }
149 }
SetUri(NapiApi::StrongRef uri)150 void SceneResourceImpl::SetUri(NapiApi::StrongRef uri)
151 {
152 if (!validateSceneRef()) {
153 return;
154 }
155 uri_ = BASE_NS::move(uri);
156 }
GetUri(NapiApi::FunctionContext<> & ctx)157 napi_value SceneResourceImpl::GetUri(NapiApi::FunctionContext<>& ctx)
158 {
159 if (!validateSceneRef()) {
160 return ctx.GetUndefined();
161 }
162 return uri_.GetValue();
163 }
164