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 "ImageJS.h"
17
18 #include <scene_plugin/interface/intf_scene.h>
19 #include "SceneJS.h"
20
21 using namespace SCENE_NS;
22
Init(napi_env env,napi_value exports)23 void ImageJS::Init(napi_env env, napi_value exports)
24 {
25 using namespace NapiApi;
26 // clang-format off
27 BASE_NS::vector<napi_property_descriptor> props;
28 SceneResourceImpl::GetPropertyDescs(props);
29 props.emplace_back(GetProperty<uint32_t, ImageJS, &ImageJS::GetWidth>("width"));
30 props.emplace_back(GetProperty<uint32_t, ImageJS, &ImageJS::GetHeight>("height"));
31
32 // clang-format on
33
34 napi_value func;
35 auto status = napi_define_class(
36 env, "Image", NAPI_AUTO_LENGTH, BaseObject::ctor<ImageJS>(), nullptr, props.size(), props.data(), &func);
37
38 NapiApi::MyInstanceState* mis;
39 napi_get_instance_data(env, (void**)&mis);
40 mis->StoreCtor("Image", func);
41 }
42
DisposeNative()43 void ImageJS::DisposeNative()
44 {
45 if (!disposed_) {
46 disposed_ = true;
47 LOG_F("ImageJS::DisposeNative");
48 NapiApi::Object obj = scene_.GetObject();
49 auto* tro = obj.Native<TrueRootObject>();
50 SceneJS* sceneJS;
51 if (tro) {
52 sceneJS = ((SceneJS*)tro->GetInstanceImpl(SceneJS::ID));
53 sceneJS->ReleaseDispose((uintptr_t)&scene_);
54 }
55 // reset the native object refs
56 if (auto bitmap = interface_pointer_cast<IBitmap>(GetNativeObject())) {
57 SetNativeObject(nullptr, false);
58 SetNativeObject(nullptr, true);
59 if (obj) {
60 BASE_NS::string uri = FetchResourceOrUri(obj.GetEnv(), uriRef_.GetObject());
61 ExecSyncTask([uri, sceneJS]() -> META_NS::IAny::Ptr {
62 sceneJS->StoreBitmap(uri, nullptr);
63 return {};
64 });
65 }
66 } else {
67 SetNativeObject(nullptr, false);
68 }
69 scene_.Reset();
70 }
71 }
GetInstanceImpl(uint32_t id)72 void* ImageJS::GetInstanceImpl(uint32_t id)
73 {
74 if (id == ImageJS::ID) {
75 return this;
76 }
77 return SceneResourceImpl::GetInstanceImpl(id);
78 }
Finalize(napi_env env)79 void ImageJS::Finalize(napi_env env)
80 {
81 DisposeNative();
82 BaseObject<ImageJS>::Finalize(env);
83 }
84
ImageJS(napi_env e,napi_callback_info i)85 ImageJS::ImageJS(napi_env e, napi_callback_info i)
86 : BaseObject<ImageJS>(e, i), SceneResourceImpl(SceneResourceType::IMAGE)
87 {
88 NapiApi::FunctionContext<NapiApi::Object, NapiApi::Object> fromJs(e, i);
89 NapiApi::Object meJs(e, fromJs.This());
90 NapiApi::Object scene = fromJs.Arg<0>(); // access to owning scene...
91 scene_ = { scene };
92 if (!GetNativeMeta<SCENE_NS::IScene>(scene_.GetObject())) {
93 CORE_LOG_F("INVALID SCENE!");
94 }
95
96 auto* tro = scene.Native<TrueRootObject>();
97 auto* sceneJS = ((SceneJS*)tro->GetInstanceImpl(SceneJS::ID));
98 NapiApi::Object args = fromJs.Arg<1>();
99
100 SCENE_NS::IBitmap::Ptr bitmap;
101
102 // check if we got the NativeObject as parameter.
103 bitmap = GetNativeObjectParam<SCENE_NS::IBitmap>(args);
104
105 if (auto prm = args.Get("uri")) {
106 uriRef_ = { e, prm };
107 BASE_NS::string uri = FetchResourceOrUri(e, prm);
108 if (!uri.empty()) {
109 SetUri(uriRef_);
110 }
111 if (!bitmap) {
112 // if we did not receive it already...
113 bitmap = sceneJS->FetchBitmap(uri);
114 }
115 }
116 sceneJS->DisposeHook((uintptr_t)&scene_, meJs);
117 auto obj = interface_pointer_cast<META_NS::IObject>(bitmap);
118 SetNativeObject(obj, false);
119 StoreJsObj(obj, meJs);
120
121 BASE_NS::string name;
122 if (auto prm = args.Get<BASE_NS::string>("name")) {
123 name = prm;
124 } else {
125 if (auto named = interface_cast<META_NS::INamed>(obj)) {
126 name = named->Name()->GetValue();
127 }
128 }
129 meJs.Set("name", name);
130 }
131
~ImageJS()132 ImageJS::~ImageJS()
133 {
134 DisposeNative();
135 }
136
GetWidth(NapiApi::FunctionContext<> & ctx)137 napi_value ImageJS::GetWidth(NapiApi::FunctionContext<>& ctx)
138 {
139 uint32_t width = 0;
140 if (auto env = interface_cast<IBitmap>(GetNativeObject())) {
141 ExecSyncTask([env, &width]() {
142 width = env->Size()->GetValue().x;
143 return META_NS::IAny::Ptr {};
144 });
145 }
146 napi_value value;
147 napi_create_uint32(ctx, width, &value);
148 return value;
149 }
150
GetHeight(NapiApi::FunctionContext<> & ctx)151 napi_value ImageJS::GetHeight(NapiApi::FunctionContext<>& ctx)
152 {
153 uint32_t height = 0;
154 if (auto env = interface_cast<IBitmap>(GetNativeObject())) {
155 ExecSyncTask([env, &height]() {
156 height = env->Size()->GetValue().y;
157 return META_NS::IAny::Ptr {};
158 });
159 }
160 napi_value value;
161 napi_create_uint32(ctx, height, &value);
162 return value;
163 }
164