1 /*
2  * Copyright (c) 2021 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_VIEW_JS_VIEW_COMMON_DEF_H
17 #define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_VIEW_COMMON_DEF_H
18 
19 #include <functional>
20 #include <vector>
21 
22 #include "base/memory/ace_type.h"
23 #include "base/utils/noncopyable.h"
24 #include "bridge/declarative_frontend/engine/functions/js_function.h"
25 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
26 #include "bridge/declarative_frontend/engine/js_types.h"
27 
28 #define ACE_DEFINE_DEFAULT_FUNCTIONS(name)                        \
29 public:                                                           \
30     JsEventCallback() = delete;                                   \
31     ~JsEventCallback() = default;                                 \
32     JsEventCallback(const JsEventCallback&) = default;            \
33     JsEventCallback& operator=(const JsEventCallback&) = default; \
34     JsEventCallback(JsEventCallback&&) = default;                 \
35     JsEventCallback& operator=(JsEventCallback&&) = default
36 
37 namespace OHOS::Ace::Framework {
38 
39 template<class T>
40 JSRef<JSVal> ConvertToJSValue(T&& value);
41 
42 template<class... Args>
43 std::vector<JSRef<JSVal>> ConvertToJSValues(Args... args);
44 
45 template<class T>
46 bool ConvertFromJSValue(const JSRef<JSVal>& jsValue, T& result);
47 
48 template<class T, size_t N>
49 bool ConvertFromJSValue(const JSRef<JSVal>& jsValue, const T (&enumValues)[N], T& result);
50 
51 template<class T>
52 T FastConvertFromJSValue(const JSRef<JSVal>& jsValue);
53 
54 template<class F>
55 class JsEventCallback;
56 
57 template<class R, class... Args>
58 class JsEventCallback<R(Args...)> final {
59     ACE_DEFINE_DEFAULT_FUNCTIONS(JsEventCallback);
60 
61 public:
62     using ParamCollector = std::function<std::vector<JSRef<JSVal>>(Args...)>;
63     using ResultConvertor = std::function<R(const JSRef<JSVal>&)>;
64 
65     JsEventCallback(const JSExecutionContext& context, const JSRef<JSFunc>& jsFunction,
66         ParamCollector paramCollector = &ConvertToJSValues<Args...>,
67         ResultConvertor resultConvertor = &FastConvertFromJSValue<R>)
68         : context_(context), function_(jsFunction), paramCollector_(std::move(paramCollector)),
69           resultConvertor_(std::move(resultConvertor))
70     {}
71 
operator()72     R operator()(Args... args)
73     {
74         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context_, NULL);
75         std::vector<JSRef<JSVal>> params = paramCollector_(args...);
76         return resultConvertor_(function_->Call(JSRef<JSObject>(), params.size(), params.data()));
77     }
78 
79 private:
80     JSExecutionContext context_;
81     JSRef<JSFunc> function_;
82     ParamCollector paramCollector_;
83     ResultConvertor resultConvertor_;
84 };
85 
86 template<class R>
87 class JsEventCallback<R()> final {
88     ACE_DEFINE_DEFAULT_FUNCTIONS(JsEventCallback);
89 
90 public:
91     using ResultConvertor = std::function<R(const JSRef<JSVal>&)>;
92 
93     JsEventCallback(const JSExecutionContext& context, const JSRef<JSFunc>& jsFunction,
94         ResultConvertor resultConvertor = &FastConvertFromJSValue<R>)
95         : context_(context), function_(jsFunction), resultConvertor_(std::move(resultConvertor))
96     {}
97 
operator()98     R operator()()
99     {
100         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context_, NULL);
101         return resultConvertor_(function_->Call(JSRef<JSObject>()));
102     }
103 
104 private:
105     JSExecutionContext context_;
106     JSRef<JSFunc> function_;
107     ResultConvertor resultConvertor_;
108 };
109 
110 template<class... Args>
111 class JsEventCallback<void(Args...)> final {
112     ACE_DEFINE_DEFAULT_FUNCTIONS(JsEventCallback);
113 
114 public:
115     using ParamCollector = std::function<std::vector<JSRef<JSVal>>(Args...)>;
116 
117     JsEventCallback(const JSExecutionContext& context, const JSRef<JSFunc>& jsFunction,
118         ParamCollector paramCollector = &ConvertToJSValues<Args...>)
119         : context_(context), function_(jsFunction), paramCollector_(std::move(paramCollector))
120     {}
121 
operator()122     void operator()(Args... args)
123     {
124         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context_);
125         std::vector<JSRef<JSVal>> params = paramCollector_(args...);
126         function_->Call(JSRef<JSObject>(), params.size(), params.data());
127     }
128 
129 private:
130     JSExecutionContext context_;
131     JSRef<JSFunc> function_;
132     ParamCollector paramCollector_;
133 };
134 
135 template<>
136 class JsEventCallback<void()> final {
137     ACE_DEFINE_DEFAULT_FUNCTIONS(JsEventCallback);
138 
139 public:
JsEventCallback(const JSExecutionContext & context,const JSRef<JSFunc> & jsFunction)140     JsEventCallback(const JSExecutionContext& context, const JSRef<JSFunc>& jsFunction)
141         : context_(context), function_(jsFunction)
142     {}
143 
operator()144     void operator()()
145     {
146         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context_);
147         function_->Call(JSRef<JSObject>());
148     }
149 
150 private:
151     JSExecutionContext context_;
152     JSRef<JSFunc> function_;
153 };
154 
155 template<class C, class V, class T, size_t N>
156 void JSViewSetProperty(void (C::*setMethod)(V), int32_t param, const T (&enumValues)[N], T defValue);
157 
158 template<class C, class V, class T>
159 void JSViewSetProperty(void (C::*setMethod)(V), T&& param);
160 
161 template<class C, class F>
162 bool JSViewBindEvent(
163     void (C::*setMethod)(std::function<F>&&), const JSExecutionContext& context, const JSRef<JSVal>& jsValue);
164 
165 template<class C, class F>
166 bool JSViewBindEvent(void (C::*setMethod)(std::function<F>&&), const JSCallbackInfo& args);
167 
168 } // namespace OHOS::Ace::Framework
169 
170 #include "js_view_common_def.inl"
171 
172 #undef ACE_DEFINE_DEFAULT_FUNCTIONS
173 
174 #endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_VIEW_COMMON_DEF_H
175