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