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#include "ShaderJS.h"
168bf80f4bSopenharmony_ci
178bf80f4bSopenharmony_ci#include <scene_plugin/api/material_uid.h>
188bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_ecs_object.h>
198bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_mesh.h>
208bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_scene.h>
218bf80f4bSopenharmony_ci
228bf80f4bSopenharmony_ci#include "MaterialJS.h"
238bf80f4bSopenharmony_ci#include "SceneJS.h"
248bf80f4bSopenharmony_ci#include "Vec2Proxy.h"
258bf80f4bSopenharmony_ci#include "Vec3Proxy.h"
268bf80f4bSopenharmony_ci#include "Vec4Proxy.h"
278bf80f4bSopenharmony_ci
288bf80f4bSopenharmony_ciusing IntfPtr = META_NS::SharedPtrIInterface;
298bf80f4bSopenharmony_ciusing IntfWeakPtr = META_NS::WeakPtrIInterface;
308bf80f4bSopenharmony_ci
318bf80f4bSopenharmony_citemplate<typename type>
328bf80f4bSopenharmony_ciclass TypeProxy : public Proxy {
338bf80f4bSopenharmony_ci    META_NS::IProperty::Ptr prop_;
348bf80f4bSopenharmony_ci    BASE_NS::string name_;
358bf80f4bSopenharmony_ci
368bf80f4bSopenharmony_cipublic:
378bf80f4bSopenharmony_ci    explicit TypeProxy(META_NS::IProperty::Ptr prop) : prop_(prop), name_(prop_->GetName()) {}
388bf80f4bSopenharmony_ci    ~TypeProxy()
398bf80f4bSopenharmony_ci    {
408bf80f4bSopenharmony_ci        prop_.reset();
418bf80f4bSopenharmony_ci    }
428bf80f4bSopenharmony_ci
438bf80f4bSopenharmony_ci    napi_value Get(NapiApi::FunctionContext<> ctx)
448bf80f4bSopenharmony_ci    {
458bf80f4bSopenharmony_ci        META_NS::Property<type> p(prop_);
468bf80f4bSopenharmony_ci        return NapiApi::Value<type>(ctx, p->GetValue());
478bf80f4bSopenharmony_ci    }
488bf80f4bSopenharmony_ci    napi_value Set(NapiApi::FunctionContext<type> ctx)
498bf80f4bSopenharmony_ci    {
508bf80f4bSopenharmony_ci        type val = ctx.template Arg<0>();
518bf80f4bSopenharmony_ci        META_NS::Property<type> p(prop_);
528bf80f4bSopenharmony_ci        p->SetValue(val);
538bf80f4bSopenharmony_ci        return ctx.GetUndefined();
548bf80f4bSopenharmony_ci    }
558bf80f4bSopenharmony_ci    void insertProp(BASE_NS::vector<napi_property_descriptor>& props)
568bf80f4bSopenharmony_ci    {
578bf80f4bSopenharmony_ci        props.push_back(napi_property_descriptor { name_.c_str(), nullptr, nullptr,
588bf80f4bSopenharmony_ci            [](napi_env e, napi_callback_info i) -> napi_value {
598bf80f4bSopenharmony_ci                NapiApi::FunctionContext<> info(e, i);
608bf80f4bSopenharmony_ci                auto me_ = (TypeProxy<type>*)info.GetData();
618bf80f4bSopenharmony_ci                return me_->Get(info);
628bf80f4bSopenharmony_ci            },
638bf80f4bSopenharmony_ci            [](napi_env e, napi_callback_info i) -> napi_value {
648bf80f4bSopenharmony_ci                NapiApi::FunctionContext<type> info(e, i);
658bf80f4bSopenharmony_ci                auto me_ = (TypeProxy<type>*)info.GetData();
668bf80f4bSopenharmony_ci                return me_->Set(info);
678bf80f4bSopenharmony_ci            },
688bf80f4bSopenharmony_ci            nullptr, napi_default_jsproperty, (void*)this });
698bf80f4bSopenharmony_ci    }
708bf80f4bSopenharmony_ci};
718bf80f4bSopenharmony_ci
728bf80f4bSopenharmony_ciclass BitmapProxy : public Proxy {
738bf80f4bSopenharmony_ci    NapiApi::StrongRef scene_;
748bf80f4bSopenharmony_ci    META_NS::IProperty::Ptr prop_;
758bf80f4bSopenharmony_ci    BASE_NS::string name_;
768bf80f4bSopenharmony_ci
778bf80f4bSopenharmony_cipublic:
788bf80f4bSopenharmony_ci    BitmapProxy(NapiApi::Object scene, META_NS::IProperty::Ptr prop, BASE_NS::string_view prefix = "") : prop_(prop)
798bf80f4bSopenharmony_ci    {
808bf80f4bSopenharmony_ci        scene_ = scene;
818bf80f4bSopenharmony_ci        if (!prefix.empty()) {
828bf80f4bSopenharmony_ci            name_ = prefix;
838bf80f4bSopenharmony_ci            name_ += "_";
848bf80f4bSopenharmony_ci        }
858bf80f4bSopenharmony_ci        name_ += prop->GetName();
868bf80f4bSopenharmony_ci    }
878bf80f4bSopenharmony_ci    ~BitmapProxy()
888bf80f4bSopenharmony_ci    {
898bf80f4bSopenharmony_ci        prop_.reset();
908bf80f4bSopenharmony_ci    }
918bf80f4bSopenharmony_ci
928bf80f4bSopenharmony_ci    napi_value Get(NapiApi::FunctionContext<> ctx)
938bf80f4bSopenharmony_ci    {
948bf80f4bSopenharmony_ci        META_NS::Property<SCENE_NS::IBitmap::Ptr> p(prop_);
958bf80f4bSopenharmony_ci        // return NapiApi::Value<type>(ctx, p->GetValue());
968bf80f4bSopenharmony_ci        auto obj = p->GetValue();
978bf80f4bSopenharmony_ci        if (auto cached = FetchJsObj(obj)) {
988bf80f4bSopenharmony_ci            return cached;
998bf80f4bSopenharmony_ci        }
1008bf80f4bSopenharmony_ci
1018bf80f4bSopenharmony_ci        if (obj) {
1028bf80f4bSopenharmony_ci            // okay.. there is a native bitmap set.. but no js wrapper yet.
1038bf80f4bSopenharmony_ci
1048bf80f4bSopenharmony_ci            // create the jsobject if we don't have one.
1058bf80f4bSopenharmony_ci            NapiApi::Object parms(ctx);
1068bf80f4bSopenharmony_ci            napi_value args[] = {
1078bf80f4bSopenharmony_ci                scene_.GetValue(), // scene..
1088bf80f4bSopenharmony_ci                parms              // params.
1098bf80f4bSopenharmony_ci            };
1108bf80f4bSopenharmony_ci            MakeNativeObjectParam(ctx, obj, BASE_NS::countof(args), args);
1118bf80f4bSopenharmony_ci
1128bf80f4bSopenharmony_ci            auto size = obj->Size()->GetValue();
1138bf80f4bSopenharmony_ci            auto uri = obj->Uri()->GetValue();
1148bf80f4bSopenharmony_ci            auto name = interface_cast<META_NS::INamed>(obj)->Name()->GetValue();
1158bf80f4bSopenharmony_ci            parms.Set("uri", uri);
1168bf80f4bSopenharmony_ci            NapiApi::Object imageJS(GetJSConstructor(ctx, "Image"), BASE_NS::countof(args), args);
1178bf80f4bSopenharmony_ci            return imageJS;
1188bf80f4bSopenharmony_ci        }
1198bf80f4bSopenharmony_ci        return ctx.GetNull();
1208bf80f4bSopenharmony_ci    }
1218bf80f4bSopenharmony_ci    napi_value Set(NapiApi::FunctionContext<NapiApi::Object> ctx)
1228bf80f4bSopenharmony_ci    {
1238bf80f4bSopenharmony_ci        NapiApi::Object val = ctx.Arg<0>();
1248bf80f4bSopenharmony_ci        auto bitmap = GetNativeMeta<SCENE_NS::IBitmap>(val);
1258bf80f4bSopenharmony_ci        if (bitmap) {
1268bf80f4bSopenharmony_ci            META_NS::Property<SCENE_NS::IBitmap::Ptr> p(prop_);
1278bf80f4bSopenharmony_ci            p->SetValue(bitmap);
1288bf80f4bSopenharmony_ci        }
1298bf80f4bSopenharmony_ci        return ctx.GetUndefined();
1308bf80f4bSopenharmony_ci    }
1318bf80f4bSopenharmony_ci    void insertProp(BASE_NS::vector<napi_property_descriptor>& props)
1328bf80f4bSopenharmony_ci    {
1338bf80f4bSopenharmony_ci        props.push_back(napi_property_descriptor { name_.c_str(), nullptr, nullptr,
1348bf80f4bSopenharmony_ci            [](napi_env e, napi_callback_info i) -> napi_value {
1358bf80f4bSopenharmony_ci                NapiApi::FunctionContext<> info(e, i);
1368bf80f4bSopenharmony_ci                auto me_ = (BitmapProxy*)info.GetData();
1378bf80f4bSopenharmony_ci                return me_->Get(info);
1388bf80f4bSopenharmony_ci            },
1398bf80f4bSopenharmony_ci            [](napi_env e, napi_callback_info i) -> napi_value {
1408bf80f4bSopenharmony_ci                NapiApi::FunctionContext<NapiApi::Object> info(e, i);
1418bf80f4bSopenharmony_ci                auto me_ = (BitmapProxy*)info.GetData();
1428bf80f4bSopenharmony_ci                return me_->Set(info);
1438bf80f4bSopenharmony_ci            },
1448bf80f4bSopenharmony_ci            nullptr, napi_default_jsproperty, (void*)this });
1458bf80f4bSopenharmony_ci    }
1468bf80f4bSopenharmony_ci};
1478bf80f4bSopenharmony_ci
1488bf80f4bSopenharmony_citemplate<typename proxType>
1498bf80f4bSopenharmony_ciclass PropProxy : public Proxy {
1508bf80f4bSopenharmony_ci    BASE_NS::shared_ptr<proxType> proxy_;
1518bf80f4bSopenharmony_ci    BASE_NS::string name_;
1528bf80f4bSopenharmony_ci
1538bf80f4bSopenharmony_cipublic:
1548bf80f4bSopenharmony_ci    PropProxy(napi_env e, META_NS::IProperty::Ptr prop, BASE_NS::string_view prefix = "")
1558bf80f4bSopenharmony_ci    {
1568bf80f4bSopenharmony_ci        proxy_.reset(new proxType(e, prop));
1578bf80f4bSopenharmony_ci        if (!prefix.empty()) {
1588bf80f4bSopenharmony_ci            name_ = prefix;
1598bf80f4bSopenharmony_ci            name_ += "_";
1608bf80f4bSopenharmony_ci        }
1618bf80f4bSopenharmony_ci        name_ += prop->GetName();
1628bf80f4bSopenharmony_ci    }
1638bf80f4bSopenharmony_ci    ~PropProxy()
1648bf80f4bSopenharmony_ci    {
1658bf80f4bSopenharmony_ci        proxy_.reset();
1668bf80f4bSopenharmony_ci    }
1678bf80f4bSopenharmony_ci    napi_value Get(NapiApi::FunctionContext<> ctx)
1688bf80f4bSopenharmony_ci    {
1698bf80f4bSopenharmony_ci        return proxy_->Value();
1708bf80f4bSopenharmony_ci    }
1718bf80f4bSopenharmony_ci
1728bf80f4bSopenharmony_ci    napi_value Set(NapiApi::FunctionContext<NapiApi::Object> ctx)
1738bf80f4bSopenharmony_ci    {
1748bf80f4bSopenharmony_ci        NapiApi::Object val = ctx.Arg<0>();
1758bf80f4bSopenharmony_ci        proxy_->SetValue(val);
1768bf80f4bSopenharmony_ci        return ctx.GetUndefined();
1778bf80f4bSopenharmony_ci    }
1788bf80f4bSopenharmony_ci
1798bf80f4bSopenharmony_ci    void insertProp(BASE_NS::vector<napi_property_descriptor>& props)
1808bf80f4bSopenharmony_ci    {
1818bf80f4bSopenharmony_ci        props.push_back(napi_property_descriptor { name_.c_str(), nullptr, nullptr,
1828bf80f4bSopenharmony_ci            [](napi_env e, napi_callback_info i) -> napi_value {
1838bf80f4bSopenharmony_ci                NapiApi::FunctionContext<> info(e, i);
1848bf80f4bSopenharmony_ci                auto me_ = (PropProxy<proxType>*)info.GetData();
1858bf80f4bSopenharmony_ci                return me_->Get(info);
1868bf80f4bSopenharmony_ci            },
1878bf80f4bSopenharmony_ci            [](napi_env e, napi_callback_info i) -> napi_value {
1888bf80f4bSopenharmony_ci                NapiApi::FunctionContext<NapiApi::Object> info(e, i);
1898bf80f4bSopenharmony_ci                auto me_ = (PropProxy<proxType>*)info.GetData();
1908bf80f4bSopenharmony_ci                return me_->Set(info);
1918bf80f4bSopenharmony_ci            },
1928bf80f4bSopenharmony_ci            nullptr, napi_default_jsproperty, (void*)this });
1938bf80f4bSopenharmony_ci    }
1948bf80f4bSopenharmony_ci};
1958bf80f4bSopenharmony_ci
1968bf80f4bSopenharmony_civoid ShaderJS::Init(napi_env env, napi_value exports)
1978bf80f4bSopenharmony_ci{
1988bf80f4bSopenharmony_ci    using namespace NapiApi;
1998bf80f4bSopenharmony_ci    BASE_NS::vector<napi_property_descriptor> node_props;
2008bf80f4bSopenharmony_ci
2018bf80f4bSopenharmony_ci    SceneResourceImpl::GetPropertyDescs(node_props);
2028bf80f4bSopenharmony_ci
2038bf80f4bSopenharmony_ci    napi_value func;
2048bf80f4bSopenharmony_ci    auto status = napi_define_class(env, "Shader", NAPI_AUTO_LENGTH, BaseObject::ctor<ShaderJS>(), nullptr,
2058bf80f4bSopenharmony_ci        node_props.size(), node_props.data(), &func);
2068bf80f4bSopenharmony_ci
2078bf80f4bSopenharmony_ci    NapiApi::MyInstanceState* mis;
2088bf80f4bSopenharmony_ci    napi_get_instance_data(env, (void**)&mis);
2098bf80f4bSopenharmony_ci    mis->StoreCtor("Shader", func);
2108bf80f4bSopenharmony_ci}
2118bf80f4bSopenharmony_ci
2128bf80f4bSopenharmony_ciShaderJS::ShaderJS(napi_env e, napi_callback_info i)
2138bf80f4bSopenharmony_ci    : BaseObject<ShaderJS>(e, i), SceneResourceImpl(SceneResourceImpl::SHADER)
2148bf80f4bSopenharmony_ci{
2158bf80f4bSopenharmony_ci    NapiApi::FunctionContext<NapiApi::Object, NapiApi::Object> fromJs(e, i);
2168bf80f4bSopenharmony_ci    NapiApi::Object meJs(e, fromJs.This());
2178bf80f4bSopenharmony_ci
2188bf80f4bSopenharmony_ci    NapiApi::Object scene = fromJs.Arg<0>(); // access to owning scene...
2198bf80f4bSopenharmony_ci    NapiApi::Object args = fromJs.Arg<1>();  // other args
2208bf80f4bSopenharmony_ci    scene_ = { scene };
2218bf80f4bSopenharmony_ci    if (!GetNativeMeta<SCENE_NS::IScene>(scene_.GetObject())) {
2228bf80f4bSopenharmony_ci        CORE_LOG_F("INVALID SCENE!");
2238bf80f4bSopenharmony_ci    }
2248bf80f4bSopenharmony_ci
2258bf80f4bSopenharmony_ci    auto* tro = scene.Native<TrueRootObject>();
2268bf80f4bSopenharmony_ci    auto* sceneJS = ((SceneJS*)tro->GetInstanceImpl(SceneJS::ID));
2278bf80f4bSopenharmony_ci    sceneJS->DisposeHook((uintptr_t)&scene_, meJs);
2288bf80f4bSopenharmony_ci
2298bf80f4bSopenharmony_ci    // check if we got the NativeObject as parameter. (meta object created when bound to material..)
2308bf80f4bSopenharmony_ci    auto metaobj = GetNativeObjectParam<META_NS::IMetadata>(args);
2318bf80f4bSopenharmony_ci
2328bf80f4bSopenharmony_ci    StoreJsObj(interface_pointer_cast<META_NS::IObject>(metaobj), meJs);
2338bf80f4bSopenharmony_ci
2348bf80f4bSopenharmony_ci    // check if it's a SCENE_NS::IShader (can only be set on instances created createShader, these are the "template"
2358bf80f4bSopenharmony_ci    // shaders.)
2368bf80f4bSopenharmony_ci    auto shader = interface_pointer_cast<SCENE_NS::IShader>(metaobj);
2378bf80f4bSopenharmony_ci    if (shader) {
2388bf80f4bSopenharmony_ci        // we should not be bound to a material then.. this is a place holder object.
2398bf80f4bSopenharmony_ci        SetNativeObject(interface_pointer_cast<META_NS::IObject>(shader), true);
2408bf80f4bSopenharmony_ci    } else {
2418bf80f4bSopenharmony_ci        // should be bound to a material..
2428bf80f4bSopenharmony_ci        // so the shader should be stored as a parameter..
2438bf80f4bSopenharmony_ci        SetNativeObject(interface_pointer_cast<META_NS::IObject>(metaobj), true);
2448bf80f4bSopenharmony_ci        shader = interface_pointer_cast<SCENE_NS::IShader>(metaobj->GetPropertyByName<IntfPtr>("shader")->GetValue());
2458bf80f4bSopenharmony_ci    }
2468bf80f4bSopenharmony_ci
2478bf80f4bSopenharmony_ci    NapiApi::Object material = args.Get<NapiApi::Object>("Material"); // see if we SHOULD be bound to a material.
2488bf80f4bSopenharmony_ci    if (material) {
2498bf80f4bSopenharmony_ci        BindToMaterial(meJs, material);
2508bf80f4bSopenharmony_ci    }
2518bf80f4bSopenharmony_ci
2528bf80f4bSopenharmony_ci    BASE_NS::string name;
2538bf80f4bSopenharmony_ci    if (auto prm = args.Get<BASE_NS::string>("name")) {
2548bf80f4bSopenharmony_ci        name = prm;
2558bf80f4bSopenharmony_ci    } else {
2568bf80f4bSopenharmony_ci        if (auto named = interface_cast<META_NS::INamed>(metaobj)) {
2578bf80f4bSopenharmony_ci            name = named->Name()->GetValue();
2588bf80f4bSopenharmony_ci        }
2598bf80f4bSopenharmony_ci    }
2608bf80f4bSopenharmony_ci    meJs.Set("name", name);
2618bf80f4bSopenharmony_ci}
2628bf80f4bSopenharmony_ci
2638bf80f4bSopenharmony_civoid ShaderJS::BindToMaterial(NapiApi::Object meJs, NapiApi::Object material)
2648bf80f4bSopenharmony_ci{
2658bf80f4bSopenharmony_ci    auto metaobj = GetNativeMeta<META_NS::IMetadata>(meJs);
2668bf80f4bSopenharmony_ci    auto shader = interface_pointer_cast<SCENE_NS::IShader>(
2678bf80f4bSopenharmony_ci        metaobj->GetPropertyByName<IntfPtr>("shader")->GetValue());
2688bf80f4bSopenharmony_ci
2698bf80f4bSopenharmony_ci    napi_env e = meJs.GetEnv();
2708bf80f4bSopenharmony_ci    // inputs are actually owned (and used) by the material.
2718bf80f4bSopenharmony_ci    // create the input object
2728bf80f4bSopenharmony_ci    NapiApi::Object inputs(e);
2738bf80f4bSopenharmony_ci
2748bf80f4bSopenharmony_ci    auto* tro = material.Native<TrueRootObject>();
2758bf80f4bSopenharmony_ci    auto mat = interface_pointer_cast<SCENE_NS::IMaterial>(tro->GetNativeObject());
2768bf80f4bSopenharmony_ci
2778bf80f4bSopenharmony_ci    BASE_NS::vector<napi_property_descriptor> inputProps;
2788bf80f4bSopenharmony_ci
2798bf80f4bSopenharmony_ci    META_NS::IMetadata::Ptr customProperties;
2808bf80f4bSopenharmony_ci    BASE_NS::vector<SCENE_NS::ITextureInfo::Ptr> Textures;
2818bf80f4bSopenharmony_ci
2828bf80f4bSopenharmony_ci    ExecSyncTask([mat, &customProperties, &Textures]() {
2838bf80f4bSopenharmony_ci        Textures = mat->Inputs()->GetValue();
2848bf80f4bSopenharmony_ci        customProperties = interface_pointer_cast<META_NS::IMetadata>(mat->CustomProperties()->GetValue());
2858bf80f4bSopenharmony_ci        return META_NS::IAny::Ptr {};
2868bf80f4bSopenharmony_ci    });
2878bf80f4bSopenharmony_ci    if (!Textures.empty()) {
2888bf80f4bSopenharmony_ci        int index = 0;
2898bf80f4bSopenharmony_ci        for (auto t : Textures) {
2908bf80f4bSopenharmony_ci            BASE_NS::string name;
2918bf80f4bSopenharmony_ci            auto nn = interface_cast<META_NS::INamed>(t);
2928bf80f4bSopenharmony_ci            if (nn) {
2938bf80f4bSopenharmony_ci                name = nn->Name()->GetValue();
2948bf80f4bSopenharmony_ci            } else {
2958bf80f4bSopenharmony_ci                name = "TextureInfo_" + BASE_NS::to_string(index);
2968bf80f4bSopenharmony_ci            }
2978bf80f4bSopenharmony_ci            BASE_NS::shared_ptr<Proxy> proxt;
2988bf80f4bSopenharmony_ci            // factor
2998bf80f4bSopenharmony_ci            proxt = BASE_NS::shared_ptr { new PropProxy<Vec4Proxy>(e, t->Factor(), name) };
3008bf80f4bSopenharmony_ci            if (proxt) {
3018bf80f4bSopenharmony_ci                proxies_.push_back(proxt);
3028bf80f4bSopenharmony_ci                proxt->insertProp(inputProps);
3038bf80f4bSopenharmony_ci            }
3048bf80f4bSopenharmony_ci            proxt = BASE_NS::shared_ptr { new BitmapProxy(scene_.GetObject(), t->Image(), name) };
3058bf80f4bSopenharmony_ci            if (proxt) {
3068bf80f4bSopenharmony_ci                proxies_.push_back(proxt);
3078bf80f4bSopenharmony_ci                proxt->insertProp(inputProps);
3088bf80f4bSopenharmony_ci            }
3098bf80f4bSopenharmony_ci
3108bf80f4bSopenharmony_ci            index++;
3118bf80f4bSopenharmony_ci        }
3128bf80f4bSopenharmony_ci    }
3138bf80f4bSopenharmony_ci    if (customProperties) {
3148bf80f4bSopenharmony_ci        for (auto t : customProperties->GetAllProperties()) {
3158bf80f4bSopenharmony_ci            auto name = t->GetName();
3168bf80f4bSopenharmony_ci            auto type = t->GetTypeId();
3178bf80f4bSopenharmony_ci            auto tst = type.ToString();
3188bf80f4bSopenharmony_ci            BASE_NS::shared_ptr<Proxy> proxt;
3198bf80f4bSopenharmony_ci            if (type == META_NS::UidFromType<float>()) {
3208bf80f4bSopenharmony_ci                proxt = BASE_NS::shared_ptr { new TypeProxy<float>(t) };
3218bf80f4bSopenharmony_ci            }
3228bf80f4bSopenharmony_ci            if (type == META_NS::UidFromType<int32_t>()) {
3238bf80f4bSopenharmony_ci                proxt = BASE_NS::shared_ptr { new TypeProxy<int32_t>(t) };
3248bf80f4bSopenharmony_ci            }
3258bf80f4bSopenharmony_ci            if (type == META_NS::UidFromType<uint32_t>()) {
3268bf80f4bSopenharmony_ci                proxt = BASE_NS::shared_ptr { new TypeProxy<uint32_t>(t) };
3278bf80f4bSopenharmony_ci            }
3288bf80f4bSopenharmony_ci            if (type == META_NS::UidFromType<BASE_NS::Math::Vec2>()) {
3298bf80f4bSopenharmony_ci                proxt = BASE_NS::shared_ptr { new PropProxy<Vec2Proxy>(e, t) };
3308bf80f4bSopenharmony_ci            }
3318bf80f4bSopenharmony_ci            if (type == META_NS::UidFromType<BASE_NS::Math::Vec3>()) {
3328bf80f4bSopenharmony_ci                proxt = BASE_NS::shared_ptr { new PropProxy<Vec3Proxy>(e, t) };
3338bf80f4bSopenharmony_ci            }
3348bf80f4bSopenharmony_ci            if (type == META_NS::UidFromType<BASE_NS::Math::Vec4>()) {
3358bf80f4bSopenharmony_ci                proxt = BASE_NS::shared_ptr { new PropProxy<Vec4Proxy>(e, t) };
3368bf80f4bSopenharmony_ci            }
3378bf80f4bSopenharmony_ci            if (proxt) {
3388bf80f4bSopenharmony_ci                proxies_.push_back(proxt);
3398bf80f4bSopenharmony_ci                proxt->insertProp(inputProps);
3408bf80f4bSopenharmony_ci            }
3418bf80f4bSopenharmony_ci        }
3428bf80f4bSopenharmony_ci    }
3438bf80f4bSopenharmony_ci    if (!inputProps.empty()) {
3448bf80f4bSopenharmony_ci        napi_define_properties(e, inputs, inputProps.size(), inputProps.data());
3458bf80f4bSopenharmony_ci    }
3468bf80f4bSopenharmony_ci
3478bf80f4bSopenharmony_ci    inputs_ = { e, inputs };
3488bf80f4bSopenharmony_ci    meJs.Set("inputs", inputs_.GetValue());
3498bf80f4bSopenharmony_ci}
3508bf80f4bSopenharmony_ci
3518bf80f4bSopenharmony_ciShaderJS::~ShaderJS()
3528bf80f4bSopenharmony_ci{
3538bf80f4bSopenharmony_ci    DisposeNative();
3548bf80f4bSopenharmony_ci}
3558bf80f4bSopenharmony_ci
3568bf80f4bSopenharmony_civoid* ShaderJS::GetInstanceImpl(uint32_t id)
3578bf80f4bSopenharmony_ci{
3588bf80f4bSopenharmony_ci    if (id == ShaderJS::ID) {
3598bf80f4bSopenharmony_ci        return this;
3608bf80f4bSopenharmony_ci    }
3618bf80f4bSopenharmony_ci    return SceneResourceImpl::GetInstanceImpl(id);
3628bf80f4bSopenharmony_ci}
3638bf80f4bSopenharmony_ci
3648bf80f4bSopenharmony_civoid ShaderJS::DisposeNative()
3658bf80f4bSopenharmony_ci{
3668bf80f4bSopenharmony_ci    if (!disposed_) {
3678bf80f4bSopenharmony_ci        disposed_ = true;
3688bf80f4bSopenharmony_ci        SetNativeObject(nullptr, false);
3698bf80f4bSopenharmony_ci        SetNativeObject(nullptr, true);
3708bf80f4bSopenharmony_ci        NapiApi::Object obj = scene_.GetObject();
3718bf80f4bSopenharmony_ci        if (obj) {
3728bf80f4bSopenharmony_ci            auto* tro = obj.Native<TrueRootObject>();
3738bf80f4bSopenharmony_ci
3748bf80f4bSopenharmony_ci            if (tro) {
3758bf80f4bSopenharmony_ci                SceneJS* sceneJS = ((SceneJS*)tro->GetInstanceImpl(SceneJS::ID));
3768bf80f4bSopenharmony_ci                sceneJS->ReleaseDispose((uintptr_t)&scene_);
3778bf80f4bSopenharmony_ci            }
3788bf80f4bSopenharmony_ci        }
3798bf80f4bSopenharmony_ci        proxies_.clear();
3808bf80f4bSopenharmony_ci        inputs_.Reset();
3818bf80f4bSopenharmony_ci        scene_.Reset();
3828bf80f4bSopenharmony_ci    }
3838bf80f4bSopenharmony_ci}
3848bf80f4bSopenharmony_civoid ShaderJS::Finalize(napi_env env)
3858bf80f4bSopenharmony_ci{
3868bf80f4bSopenharmony_ci    DisposeNative();
3878bf80f4bSopenharmony_ci    BaseObject<ShaderJS>::Finalize(env);
3888bf80f4bSopenharmony_ci}
389