• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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#include "bindings_implementation.h"
17
18namespace OHOS::Ace::Framework {
19
20template<typename T, template<typename> typename ImplDetail>
21thread_local std::unordered_map<int, std::unique_ptr<IFunctionBinding>> JSClassImpl<T, ImplDetail>::functions_;
22template<typename T, template<typename> typename ImplDetail>
23thread_local std::unordered_map<int, std::unique_ptr<IFunctionBinding>> JSClassImpl<T, ImplDetail>::getFunctions_;
24template<typename T, template<typename> typename ImplDetail>
25thread_local std::unordered_map<int, std::unique_ptr<IFunctionBinding>> JSClassImpl<T, ImplDetail>::setFunctions_;
26template<typename T, template<typename> typename ImplDetail>
27thread_local int JSClassImpl<T, ImplDetail>::nextFreeId_ = 0;
28template<typename T, template<typename> typename ImplDetail>
29thread_local std::string JSClassImpl<T, ImplDetail>::jsName;
30
31template<typename C, template<typename> typename ImplDetail>
32void JSClassImpl<C, ImplDetail>::Declare(const char* name)
33{
34    jsName = name;
35    ImplDetail<C>::Declare(name);
36}
37
38template<typename C, template<typename> typename ImplDetail>
39template<typename Base, typename R, typename... Args>
40void JSClassImpl<C, ImplDetail>::Method(const char* name, R (Base::*func)(Args...), MethodOptions options)
41{
42    static_assert(std::is_base_of_v<Base, C>, "Trying to bind an unrelated method!");
43    functions_.emplace(nextFreeId_, new FunctionBinding(name, options, func));
44    ImplDetail<C>::Method(name, func, nextFreeId_++);
45}
46
47template<typename C, template<typename> typename ImplDetail>
48template<typename R, typename... Args>
49void JSClassImpl<C, ImplDetail>::StaticMethod(const char* name, R (*func)(Args...), MethodOptions options)
50{
51    functions_.emplace(nextFreeId_, new StaticFunctionBinding(name, options, func));
52    ImplDetail<C>::StaticMethod(name, func, nextFreeId_++);
53}
54
55template<typename C, template<typename> typename ImplDetail>
56void JSClassImpl<C, ImplDetail>::StaticMethod(const char* name, JSFunctionCallback func)
57{
58    functions_.emplace(nextFreeId_, new StaticFunctionBinding(name, MethodOptions::NONE, func));
59    ImplDetail<C>::StaticMethod(name, func, nextFreeId_++);
60}
61
62template<typename C, template<typename> typename ImplDetail>
63template<typename T>
64void JSClassImpl<C, ImplDetail>::CustomMethod(const char* name, MemberFunctionCallback<T> callback)
65{
66    static_assert(std::is_base_of_v<T, C>, "Trying to bind an unrelated method!");
67    functions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, callback));
68    ImplDetail<C>::CustomMethod(name, callback, nextFreeId_++);
69}
70
71template<typename C, template<typename> typename ImplDetail>
72void JSClassImpl<C, ImplDetail>::CustomMethod(const char* name, FunctionCallback callback)
73{
74    ImplDetail<C>::CustomMethod(name, callback);
75}
76
77template<typename C, template<typename> typename ImplDetail>
78template<typename T>
79void JSClassImpl<C, ImplDetail>::CustomMethod(const char* name, JSMemberFunctionCallback<T> callback)
80{
81    functions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, callback));
82    ImplDetail<C>::CustomMethod(name, callback, nextFreeId_++);
83}
84
85template<typename C, template<typename> typename ImplDetail>
86template<typename T>
87void JSClassImpl<C, ImplDetail>::CustomProperty(const char* name, MemberFunctionGetCallback<T> getter,
88    MemberFunctionSetCallback<T> setter)
89{
90    int getFuncId;
91    int setFuncId;
92    getFunctions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, getter));
93    setFunctions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, setter));
94
95    static_assert(std::is_base_of_v<T, C>, "Trying to bind an unrelated method!");
96    functions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, getter));
97    getFuncId = nextFreeId_++;
98    functions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, setter));
99    setFuncId = nextFreeId_++;
100
101
102    ImplDetail<C>::CustomProperty(name, getter, getFuncId, setFuncId);
103}
104
105template<typename C, template<typename> typename ImplDetail>
106void JSClassImpl<C, ImplDetail>::CustomProperty(const char* name, FunctionGetCallback getter,
107    FunctionSetCallback setter)
108{
109    ImplDetail<C>::CustomProperty(name, getter, setter);
110}
111
112template<typename C, template<typename> typename ImplDetail>
113template<typename T>
114void JSClassImpl<C, ImplDetail>::CustomProperty(const char* name, JSMemberFunctionCallback<T> getter,
115    JSMemberFunctionCallback<T> setter)
116{
117    int getFuncId;
118    int setFuncId;
119    getFunctions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, getter));
120    setFunctions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, setter));
121    functions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, getter));
122    getFuncId = nextFreeId_++;
123    functions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, setter));
124    setFuncId = nextFreeId_++;
125
126    ImplDetail<C>::CustomProperty(name, getter, getFuncId, setFuncId);
127}
128
129template<typename C, template<typename> typename ImplDetail>
130void JSClassImpl<C, ImplDetail>::CustomStaticMethod(const char* name, FunctionCallback callback)
131{
132    ImplDetail<C>::CustomStaticMethod(name, callback);
133}
134
135template<typename C, template<typename> typename ImplDetail>
136void JSClassImpl<C, ImplDetail>::ExoticGetter(ExoticGetterCallback callback)
137{
138    ImplDetail<C>::ExoticGetter(callback);
139}
140
141template<typename C, template<typename> typename ImplDetail>
142void JSClassImpl<C, ImplDetail>::ExoticSetter(ExoticSetterCallback callback)
143{
144    ImplDetail<C>::ExoticSetter(callback);
145}
146
147template<typename C, template<typename> typename ImplDetail>
148void JSClassImpl<C, ImplDetail>::ExoticHasProperty(ExoticHasPropertyCallback callback)
149{
150    ImplDetail<C>::ExoticHasProperty(callback);
151}
152
153template<typename C, template<typename> typename ImplDetail>
154template<typename T>
155void JSClassImpl<C, ImplDetail>::StaticConstant(const char* name, T value)
156{
157    ImplDetail<C>::StaticConstant(name, value);
158}
159
160template<typename C, template<typename> typename ImplDetail>
161void JSClassImpl<C, ImplDetail>::Bind(BindingTarget bindTarget, FunctionCallback ctor)
162{
163    ImplDetail<C>::Bind(bindTarget, ctor);
164}
165
166template<typename C, template<typename> typename ImplDetail>
167void JSClassImpl<C, ImplDetail>::Bind(
168    BindingTarget bindTarget, JSFunctionCallback ctor, JSDestructorCallback<C> dtor, JSGCMarkCallback<C> gcMark)
169{
170    ImplDetail<C>::Bind(bindTarget, ctor, dtor, gcMark);
171}
172
173template<typename C, template<typename> typename ImplDetail>
174template<typename... Args>
175void JSClassImpl<C, ImplDetail>::Bind(
176    BindingTarget bindTarget, JSDestructorCallback<C> dtor, JSGCMarkCallback<C> gcMark)
177{
178    ImplDetail<C>::template Bind<Args...>(bindTarget, dtor, gcMark);
179}
180
181template<typename C, template<typename> typename ImplDetail>
182template<typename Base>
183void JSClassImpl<C, ImplDetail>::Inherit()
184{
185    static_assert(std::is_base_of_v<Base, C>, "Calling Inherit() on unrelated classes!");
186    ImplDetail<C>::template Inherit<Base>();
187}
188
189template<typename C, template<typename> typename ImplDetail>
190IFunctionBinding* JSClassImpl<C, ImplDetail>::GetFunctionBinding(int id)
191{
192    return functions_[id].get();
193}
194
195template<typename C, template<typename> typename ImplDetail>
196IFunctionBinding* JSClassImpl<C, ImplDetail>::GetGetFunctionBinding(int id)
197{
198    return getFunctions_[id].get();
199}
200
201template<typename C, template<typename> typename ImplDetail>
202IFunctionBinding* JSClassImpl<C, ImplDetail>::GetSetFunctionBinding(int id)
203{
204    return setFunctions_[id].get();
205}
206
207template<typename C, template<typename> typename ImplDetail>
208const char* JSClassImpl<C, ImplDetail>::JSName()
209{
210    return jsName.c_str();
211}
212
213template<typename C, template<typename> typename ImplDetail>
214JSRef<JSObject> JSClassImpl<C, ImplDetail>::NewInstance()
215{
216    return JSRef<JSObject>::Make(ImplDetail<C>::NewInstance());
217}
218
219}; // namespace OHOS::Ace::Framework
220