1 /*
2  * Copyright (c) 2023 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 #ifndef FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_ANIMATABLE_ARITHMETIC_H
17 #define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_ANIMATABLE_ARITHMETIC_H
18 
19 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
20 #include "bridge/declarative_frontend/engine/js_types.h"
21 #include "core/components_ng/animation/animatable_arithmetic.h"
22 
23 namespace OHOS::Ace::Framework {
24 using OHOS::Ace::NG::CustomAnimatableArithmetic;
25 
26 class JSAnimatableArithmetic : public CustomAnimatableArithmetic {
27     DECLARE_ACE_TYPE(JSAnimatableArithmetic, CustomAnimatableArithmetic)
28 public:
29     JSAnimatableArithmetic() = default;
30     ~JSAnimatableArithmetic() override = default;
31 
JSAnimatableArithmetic(const JSRef<JSObject> & jsObject,JSExecutionContext ctx)32     explicit JSAnimatableArithmetic(const JSRef<JSObject>& jsObject, JSExecutionContext ctx)
33         : jsObject_(jsObject), ctx_(ctx)
34     {
35         auto addVal = jsObject_->GetProperty("plus");
36         if (addVal->IsFunction()) {
37             addFunc_ = JSRef<JSFunc>::Cast(addVal);
38         }
39         auto minusVal = jsObject_->GetProperty("subtract");
40         if (minusVal->IsFunction()) {
41             minusFunc_ = JSRef<JSFunc>::Cast(minusVal);
42         }
43         auto multiplyVal = jsObject_->GetProperty("multiply");
44         if (multiplyVal->IsFunction()) {
45             multiplyFunc_ = JSRef<JSFunc>::Cast(multiplyVal);
46         }
47         auto equalsVal = jsObject_->GetProperty("equals");
48         if (equalsVal->IsFunction()) {
49             equalsFunc_ = JSRef<JSFunc>::Cast(equalsVal);
50         }
51     }
52 
Add(const RefPtr<CustomAnimatableArithmetic> & value)53     RefPtr<CustomAnimatableArithmetic> Add(const RefPtr<CustomAnimatableArithmetic>& value) const override
54     {
55         RefPtr<JSAnimatableArithmetic> rhs = AceType::DynamicCast<JSAnimatableArithmetic>(value);
56         if (!rhs) {
57             return {};
58         }
59         JAVASCRIPT_EXECUTION_SCOPE(ctx_);
60         JSRef<JSVal> argv[1] = { rhs->jsObject_ };
61         auto retVal = addFunc_->Call(jsObject_, 1, argv);
62         if (!retVal->IsObject()) {
63             return {};
64         }
65 
66         return MakeRefPtr<JSAnimatableArithmetic>(JSRef<JSObject>::Cast(retVal), ctx_);
67     }
68 
Minus(const RefPtr<CustomAnimatableArithmetic> & value)69     RefPtr<CustomAnimatableArithmetic> Minus(const RefPtr<CustomAnimatableArithmetic>& value) const override
70     {
71         RefPtr<JSAnimatableArithmetic> rhs = AceType::DynamicCast<JSAnimatableArithmetic>(value);
72         if (!rhs) {
73             return {};
74         }
75         JAVASCRIPT_EXECUTION_SCOPE(ctx_);
76         JSRef<JSVal> argv[1] = { rhs->jsObject_ };
77         auto retVal = minusFunc_->Call(jsObject_, 1, argv);
78         if (!retVal->IsObject()) {
79             return {};
80         }
81 
82         return MakeRefPtr<JSAnimatableArithmetic>(JSRef<JSObject>::Cast(retVal), ctx_);
83     }
84 
Multiply(const float scale)85     RefPtr<CustomAnimatableArithmetic> Multiply(const float scale) const override
86     {
87         JAVASCRIPT_EXECUTION_SCOPE(ctx_);
88         JSRef<JSVal> argv[1] = { JSRef<JSVal>::Make(ToJSValue(scale)) };
89         auto retVal = multiplyFunc_->Call(jsObject_, 1, argv);
90         if (!retVal->IsObject()) {
91             return {};
92         }
93 
94         return MakeRefPtr<JSAnimatableArithmetic>(JSRef<JSObject>::Cast(retVal), ctx_);
95     }
96 
IsEqual(const RefPtr<CustomAnimatableArithmetic> & value)97     bool IsEqual(const RefPtr<CustomAnimatableArithmetic>& value) const override
98     {
99         RefPtr<JSAnimatableArithmetic> rhs = AceType::DynamicCast<JSAnimatableArithmetic>(value);
100         if (!rhs) {
101             return false;
102         }
103 
104         JAVASCRIPT_EXECUTION_SCOPE(ctx_);
105         JSRef<JSVal> argv[1] = { rhs->jsObject_ };
106         auto retVal = equalsFunc_->Call(jsObject_, 1, argv);
107         if (!retVal->IsBoolean()) {
108             return false;
109         }
110 
111         return retVal->ToBoolean();
112     }
113 
GetObject()114     JSRef<JSObject> GetObject() const
115     {
116         return jsObject_;
117     }
118 
119 private:
120     JSRef<JSObject> jsObject_;
121     JSExecutionContext ctx_;
122     JSRef<JSFunc> addFunc_;
123     JSRef<JSFunc> minusFunc_;
124     JSRef<JSFunc> multiplyFunc_;
125     JSRef<JSFunc> equalsFunc_;
126 };
127 } // namespace OHOS::Ace::Framework
128 
129 #endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_ANIMATABLE_ARITHMETIC_H
130