1 /*
2 * Copyright (C) 2025 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 "DisposeContainer.h"
17
DisposeHook(uintptr_t token,NapiApi::Object obj)18 void DisposeContainer::DisposeHook(uintptr_t token, NapiApi::Object obj)
19 {
20 disposables_[token] = { obj };
21 }
22
ReleaseDispose(uintptr_t token)23 void DisposeContainer::ReleaseDispose(uintptr_t token)
24 {
25 auto it = disposables_.find(token);
26 if (it != disposables_.end()) {
27 it->second.Reset();
28 disposables_.erase(it->first);
29 }
30 }
31
StrongDisposeHook(uintptr_t token,NapiApi::Object obj)32 void DisposeContainer::StrongDisposeHook(uintptr_t token, NapiApi::Object obj)
33 {
34 strongDisposables_[token] = NapiApi::StrongRef(obj);
35 }
36
ReleaseStrongDispose(uintptr_t token)37 void DisposeContainer::ReleaseStrongDispose(uintptr_t token)
38 {
39 auto it = strongDisposables_.find(token);
40 if (it != strongDisposables_.end()) {
41 it->second.Reset();
42 strongDisposables_.erase(it->first);
43 }
44 }
45
DisposeAll(napi_env e)46 void DisposeContainer::DisposeAll(napi_env e)
47 {
48 NapiApi::Object scen(e);
49 napi_value tmp;
50 napi_create_external(
51 e, static_cast<void*>(this),
52 [](napi_env env, void* data, void* finalize_hint) {
53 // do nothing.
54 },
55 nullptr, &tmp);
56 scen.Set("SceneJS", tmp);
57 napi_value scene = scen.ToNapiValue();
58
59 // dispose all cameras/env/etcs.
60 while (!strongDisposables_.empty()) {
61 auto it = strongDisposables_.begin();
62 auto token = it->first;
63 auto env = it->second.GetObject();
64 if (env) {
65 auto size = strongDisposables_.size();
66 NapiApi::Function func = env.Get<NapiApi::Function>("destroy");
67 if (func) {
68 func.Invoke(env, 1, &scene);
69 }
70
71 if (size == strongDisposables_.size()) {
72 LOG_E("Dispose function didn't dispose.");
73 strongDisposables_.erase(strongDisposables_.begin());
74 }
75 } else {
76 strongDisposables_.erase(strongDisposables_.begin());
77 }
78 }
79
80 // dispose
81 while (!disposables_.empty()) {
82 auto env = disposables_.begin()->second.GetObject();
83 if (env) {
84 auto size = disposables_.size();
85 NapiApi::Function func = env.Get<NapiApi::Function>("destroy");
86 if (func) {
87 func.Invoke(env, 1, &scene);
88 }
89 if (size == disposables_.size()) {
90 LOG_E("Weak ref dispose function didn't dispose.");
91 disposables_.erase(disposables_.begin());
92 }
93 } else {
94 disposables_.erase(disposables_.begin());
95 }
96 }
97 }
98
99