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#include "Vec4Proxy.h"
16Vec4Proxy::Vec4Proxy(napi_env env, META_NS::Property<BASE_NS::Math::Vec4> prop) : PropertyProxy(prop)
17{
18    name_ = prop->GetName();
19    // Construct a "Lume::Vec4" instance
20    Create(env, "Vec4");
21    // hook to the objects members (set custom get/set)
22    Hook("x");
23    Hook("y");
24    Hook("z");
25    Hook("w");
26    SyncGet();
27}
28Vec4Proxy::~Vec4Proxy()
29{
30}
31void Vec4Proxy::UpdateLocalValues()
32{
33    // executed in javascript thread (locks handled outside)
34    value = META_NS::Property<BASE_NS::Math::Vec4>(prop_)->GetValue();
35}
36void Vec4Proxy::UpdateRemoteValues()
37{
38    // executed in engine thread (locks handled outside)
39    META_NS::Property<BASE_NS::Math::Vec4>(prop_)->SetValue(value);
40}
41void Vec4Proxy::SetValue(const BASE_NS::Math::Vec4& v)
42{
43    // currently executed in engine thread, hence the locks.
44    duh.Lock();
45    if (value != v) {
46        value = v;
47        ScheduleUpdate();
48    }
49    duh.Unlock();
50}
51void Vec4Proxy::SetValue(NapiApi::FunctionContext<>& cb, BASE_NS::string_view memb)
52{
53    // should be executed in the javascript thread.
54    NapiApi::FunctionContext<float> info(cb.GetEnv(), cb.GetInfo());
55    float val = info.Arg<0>();
56    duh.Lock();
57    if ((memb == "x") && (val != value.x)) {
58        value.x = val;
59        ScheduleUpdate();
60    } else if ((memb == "y") && (val != value.y)) {
61        value.y = val;
62        ScheduleUpdate();
63    } else if ((memb == "z") && (val != value.z)) {
64        value.z = val;
65        ScheduleUpdate();
66    } else if ((memb == "w") && (val != value.w)) {
67        value.w = val;
68        ScheduleUpdate();
69    }
70    duh.Unlock();
71}
72napi_value Vec4Proxy::GetValue(NapiApi::FunctionContext<>& cb, BASE_NS::string_view memb)
73{
74    // should be executed in the javascript thread.
75    float res;
76    duh.Lock();
77    if (memb == "x") {
78        res = value.x;
79    } else if (memb == "y") {
80        res = value.y;
81    } else if (memb == "z") {
82        res = value.z;
83    } else if (memb == "w") {
84        res = value.w;
85    } else {
86        // invalid member?
87        duh.Unlock();
88        return {};
89    }
90    duh.Unlock();
91    napi_value value;
92    napi_status status = napi_create_double(cb.GetEnv(), res, &value);
93    return value;
94}
95
96bool Vec4Proxy::SetValue(NapiApi::Object obj)
97{
98    auto x = obj.Get<float>("x");
99    auto y = obj.Get<float>("y");
100    auto z = obj.Get<float>("z");
101    auto w = obj.Get<float>("w");
102    if (x.IsValid() && y.IsValid() && z.IsValid() && w.IsValid()) {
103        BASE_NS::Math::Vec4 v { x, y, z, w };
104        SetValue(v);
105        return true;
106    }
107    return false;
108}
109