18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci
168bf80f4bSopenharmony_ci#include "ImageJS.h"
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_scene.h>
198bf80f4bSopenharmony_ci#include "SceneJS.h"
208bf80f4bSopenharmony_ci
218bf80f4bSopenharmony_ciusing namespace SCENE_NS;
228bf80f4bSopenharmony_ci
238bf80f4bSopenharmony_civoid ImageJS::Init(napi_env env, napi_value exports)
248bf80f4bSopenharmony_ci{
258bf80f4bSopenharmony_ci    using namespace NapiApi;
268bf80f4bSopenharmony_ci    // clang-format off
278bf80f4bSopenharmony_ci    BASE_NS::vector<napi_property_descriptor> props;
288bf80f4bSopenharmony_ci    SceneResourceImpl::GetPropertyDescs(props);
298bf80f4bSopenharmony_ci    props.emplace_back(GetProperty<uint32_t, ImageJS, &ImageJS::GetWidth>("width"));
308bf80f4bSopenharmony_ci    props.emplace_back(GetProperty<uint32_t, ImageJS, &ImageJS::GetHeight>("height"));
318bf80f4bSopenharmony_ci
328bf80f4bSopenharmony_ci    // clang-format on
338bf80f4bSopenharmony_ci
348bf80f4bSopenharmony_ci    napi_value func;
358bf80f4bSopenharmony_ci    auto status = napi_define_class(
368bf80f4bSopenharmony_ci        env, "Image", NAPI_AUTO_LENGTH, BaseObject::ctor<ImageJS>(), nullptr, props.size(), props.data(), &func);
378bf80f4bSopenharmony_ci
388bf80f4bSopenharmony_ci    NapiApi::MyInstanceState* mis;
398bf80f4bSopenharmony_ci    napi_get_instance_data(env, (void**)&mis);
408bf80f4bSopenharmony_ci    mis->StoreCtor("Image", func);
418bf80f4bSopenharmony_ci}
428bf80f4bSopenharmony_ci
438bf80f4bSopenharmony_civoid ImageJS::DisposeNative()
448bf80f4bSopenharmony_ci{
458bf80f4bSopenharmony_ci    if (!disposed_) {
468bf80f4bSopenharmony_ci        disposed_ = true;
478bf80f4bSopenharmony_ci        LOG_F("ImageJS::DisposeNative");
488bf80f4bSopenharmony_ci        NapiApi::Object obj = scene_.GetObject();
498bf80f4bSopenharmony_ci        auto* tro = obj.Native<TrueRootObject>();
508bf80f4bSopenharmony_ci        SceneJS* sceneJS;
518bf80f4bSopenharmony_ci        if (tro) {
528bf80f4bSopenharmony_ci            sceneJS = ((SceneJS*)tro->GetInstanceImpl(SceneJS::ID));
538bf80f4bSopenharmony_ci            sceneJS->ReleaseDispose((uintptr_t)&scene_);
548bf80f4bSopenharmony_ci        }
558bf80f4bSopenharmony_ci        // reset the native object refs
568bf80f4bSopenharmony_ci        if (auto bitmap = interface_pointer_cast<IBitmap>(GetNativeObject())) {
578bf80f4bSopenharmony_ci            SetNativeObject(nullptr, false);
588bf80f4bSopenharmony_ci            SetNativeObject(nullptr, true);
598bf80f4bSopenharmony_ci            if (obj) {
608bf80f4bSopenharmony_ci                BASE_NS::string uri = FetchResourceOrUri(obj.GetEnv(), uriRef_.GetObject());
618bf80f4bSopenharmony_ci                ExecSyncTask([uri, sceneJS]() -> META_NS::IAny::Ptr {
628bf80f4bSopenharmony_ci                    sceneJS->StoreBitmap(uri, nullptr);
638bf80f4bSopenharmony_ci                    return {};
648bf80f4bSopenharmony_ci                });
658bf80f4bSopenharmony_ci            }
668bf80f4bSopenharmony_ci        } else {
678bf80f4bSopenharmony_ci            SetNativeObject(nullptr, false);
688bf80f4bSopenharmony_ci        }
698bf80f4bSopenharmony_ci        scene_.Reset();
708bf80f4bSopenharmony_ci    }
718bf80f4bSopenharmony_ci}
728bf80f4bSopenharmony_civoid* ImageJS::GetInstanceImpl(uint32_t id)
738bf80f4bSopenharmony_ci{
748bf80f4bSopenharmony_ci    if (id == ImageJS::ID) {
758bf80f4bSopenharmony_ci        return this;
768bf80f4bSopenharmony_ci    }
778bf80f4bSopenharmony_ci    return SceneResourceImpl::GetInstanceImpl(id);
788bf80f4bSopenharmony_ci}
798bf80f4bSopenharmony_civoid ImageJS::Finalize(napi_env env)
808bf80f4bSopenharmony_ci{
818bf80f4bSopenharmony_ci    DisposeNative();
828bf80f4bSopenharmony_ci    BaseObject<ImageJS>::Finalize(env);
838bf80f4bSopenharmony_ci}
848bf80f4bSopenharmony_ci
858bf80f4bSopenharmony_ciImageJS::ImageJS(napi_env e, napi_callback_info i)
868bf80f4bSopenharmony_ci    : BaseObject<ImageJS>(e, i), SceneResourceImpl(SceneResourceType::IMAGE)
878bf80f4bSopenharmony_ci{
888bf80f4bSopenharmony_ci    NapiApi::FunctionContext<NapiApi::Object, NapiApi::Object> fromJs(e, i);
898bf80f4bSopenharmony_ci    NapiApi::Object meJs(e, fromJs.This());
908bf80f4bSopenharmony_ci    NapiApi::Object scene = fromJs.Arg<0>(); // access to owning scene...
918bf80f4bSopenharmony_ci    scene_ = { scene };
928bf80f4bSopenharmony_ci    if (!GetNativeMeta<SCENE_NS::IScene>(scene_.GetObject())) {
938bf80f4bSopenharmony_ci        CORE_LOG_F("INVALID SCENE!");
948bf80f4bSopenharmony_ci    }
958bf80f4bSopenharmony_ci
968bf80f4bSopenharmony_ci    auto* tro = scene.Native<TrueRootObject>();
978bf80f4bSopenharmony_ci    auto* sceneJS = ((SceneJS*)tro->GetInstanceImpl(SceneJS::ID));
988bf80f4bSopenharmony_ci    NapiApi::Object args = fromJs.Arg<1>();
998bf80f4bSopenharmony_ci
1008bf80f4bSopenharmony_ci    SCENE_NS::IBitmap::Ptr bitmap;
1018bf80f4bSopenharmony_ci
1028bf80f4bSopenharmony_ci    // check if we got the NativeObject as parameter.
1038bf80f4bSopenharmony_ci    bitmap = GetNativeObjectParam<SCENE_NS::IBitmap>(args);
1048bf80f4bSopenharmony_ci
1058bf80f4bSopenharmony_ci    if (auto prm = args.Get("uri")) {
1068bf80f4bSopenharmony_ci        uriRef_ = { e, prm };
1078bf80f4bSopenharmony_ci        BASE_NS::string uri = FetchResourceOrUri(e, prm);
1088bf80f4bSopenharmony_ci        if (!uri.empty()) {
1098bf80f4bSopenharmony_ci            SetUri(uriRef_);
1108bf80f4bSopenharmony_ci        }
1118bf80f4bSopenharmony_ci        if (!bitmap) {
1128bf80f4bSopenharmony_ci            // if we did not receive it already...
1138bf80f4bSopenharmony_ci            bitmap = sceneJS->FetchBitmap(uri);
1148bf80f4bSopenharmony_ci        }
1158bf80f4bSopenharmony_ci    }
1168bf80f4bSopenharmony_ci    sceneJS->DisposeHook((uintptr_t)&scene_, meJs);
1178bf80f4bSopenharmony_ci    auto obj = interface_pointer_cast<META_NS::IObject>(bitmap);
1188bf80f4bSopenharmony_ci    SetNativeObject(obj, false);
1198bf80f4bSopenharmony_ci    StoreJsObj(obj, meJs);
1208bf80f4bSopenharmony_ci
1218bf80f4bSopenharmony_ci    BASE_NS::string name;
1228bf80f4bSopenharmony_ci    if (auto prm = args.Get<BASE_NS::string>("name")) {
1238bf80f4bSopenharmony_ci        name = prm;
1248bf80f4bSopenharmony_ci    } else {
1258bf80f4bSopenharmony_ci        if (auto named = interface_cast<META_NS::INamed>(obj)) {
1268bf80f4bSopenharmony_ci            name = named->Name()->GetValue();
1278bf80f4bSopenharmony_ci        }
1288bf80f4bSopenharmony_ci    }
1298bf80f4bSopenharmony_ci    meJs.Set("name", name);
1308bf80f4bSopenharmony_ci}
1318bf80f4bSopenharmony_ci
1328bf80f4bSopenharmony_ciImageJS::~ImageJS()
1338bf80f4bSopenharmony_ci{
1348bf80f4bSopenharmony_ci    DisposeNative();
1358bf80f4bSopenharmony_ci}
1368bf80f4bSopenharmony_ci
1378bf80f4bSopenharmony_cinapi_value ImageJS::GetWidth(NapiApi::FunctionContext<>& ctx)
1388bf80f4bSopenharmony_ci{
1398bf80f4bSopenharmony_ci    uint32_t width = 0;
1408bf80f4bSopenharmony_ci    if (auto env = interface_cast<IBitmap>(GetNativeObject())) {
1418bf80f4bSopenharmony_ci        ExecSyncTask([env, &width]() {
1428bf80f4bSopenharmony_ci            width = env->Size()->GetValue().x;
1438bf80f4bSopenharmony_ci            return META_NS::IAny::Ptr {};
1448bf80f4bSopenharmony_ci        });
1458bf80f4bSopenharmony_ci    }
1468bf80f4bSopenharmony_ci    napi_value value;
1478bf80f4bSopenharmony_ci    napi_create_uint32(ctx, width, &value);
1488bf80f4bSopenharmony_ci    return value;
1498bf80f4bSopenharmony_ci}
1508bf80f4bSopenharmony_ci
1518bf80f4bSopenharmony_cinapi_value ImageJS::GetHeight(NapiApi::FunctionContext<>& ctx)
1528bf80f4bSopenharmony_ci{
1538bf80f4bSopenharmony_ci    uint32_t height = 0;
1548bf80f4bSopenharmony_ci    if (auto env = interface_cast<IBitmap>(GetNativeObject())) {
1558bf80f4bSopenharmony_ci        ExecSyncTask([env, &height]() {
1568bf80f4bSopenharmony_ci            height = env->Size()->GetValue().y;
1578bf80f4bSopenharmony_ci            return META_NS::IAny::Ptr {};
1588bf80f4bSopenharmony_ci        });
1598bf80f4bSopenharmony_ci    }
1608bf80f4bSopenharmony_ci    napi_value value;
1618bf80f4bSopenharmony_ci    napi_create_uint32(ctx, height, &value);
1628bf80f4bSopenharmony_ci    return value;
1638bf80f4bSopenharmony_ci}
164