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