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> 21std::unordered_map<int, IFunctionBinding*> JSClassImpl<T, ImplDetail>::functions_; 22template<typename T, template<typename> typename ImplDetail> 23int JSClassImpl<T, ImplDetail>::nextFreeId_ = 0; 24template<typename T, template<typename> typename ImplDetail> 25std::string JSClassImpl<T, ImplDetail>::jsName; 26 27template<typename C, template<typename> typename ImplDetail> 28void JSClassImpl<C, ImplDetail>::Declare(const char* name) 29{ 30 jsName = name; 31 ImplDetail<C>::Declare(name); 32} 33 34template<typename C, template<typename> typename ImplDetail> 35template<typename R, typename... Args> 36void JSClassImpl<C, ImplDetail>::Method(const char* name, R (C::*func)(Args...), MethodOptions options) 37{ 38 functions_.emplace(nextFreeId_, new FunctionBinding(name, options, func)); 39 ImplDetail<C>::Method(name, func, nextFreeId_++); 40} 41 42template<typename C, template<typename> typename ImplDetail> 43template<typename Base, typename R, typename... Args> 44void JSClassImpl<C, ImplDetail>::Method(const char* name, R (Base::*func)(Args...), MethodOptions options) 45{ 46 static_assert(std::is_base_of_v<Base, C>, "Trying to bind an unrelated method!"); 47 functions_.emplace(nextFreeId_, new FunctionBinding(name, options, func)); 48 ImplDetail<C>::Method(name, func, nextFreeId_++); 49} 50 51template<typename C, template<typename> typename ImplDetail> 52template<typename R, typename... Args> 53void JSClassImpl<C, ImplDetail>::StaticMethod(const char* name, R (C::*func)(Args...), MethodOptions options) 54{ 55 functions_.emplace(nextFreeId, new FunctionBinding(name, options, func)); 56 ImplDetail<C>::StaticMethod(name, func, nextFreeId++); 57} 58 59template<typename C, template<typename> typename ImplDetail> 60template<typename Base, typename R, typename... Args> 61void JSClassImpl<C, ImplDetail>::StaticMethod(const char* name, R (Base::*func)(Args...), MethodOptions options) 62{ 63 static_assert(std::is_base_of_v<Base, C>, "Trying to bind an unrelated method!"); 64 functions_.emplace(nextFreeId, new FunctionBinding(name, options, func)); 65 ImplDetail<C>::StaticMethod(name, func, nextFreeId++); 66} 67 68template<typename C, template<typename> typename ImplDetail> 69template<typename T> 70void JSClassImpl<C, ImplDetail>::CustomMethod( 71 const char* name, typename ImplDetail<C>::template MemberFunctionCallback<T> callback) 72{ 73 static_assert(std::is_base_of_v<T, C>, "Trying to bind an unrelated method!"); 74 functions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, callback)); 75 ImplDetail<C>::CustomMethod(name, callback, nextFreeId_++); 76} 77 78template<typename C, template<typename> typename ImplDetail> 79void JSClassImpl<C, ImplDetail>::CustomMethod(const char* name, typename ImplDetail<C>::FunctionCallback callback) 80{ 81 ImplDetail<C>::CustomMethod(name, callback); 82} 83 84template<typename C, template<typename> typename ImplDetail> 85template<typename T> 86void JSClassImpl<C, ImplDetail>::CustomProperty( 87 const char* name, typename ImplDetail<C>::template MemberFunctionGetCallback<T> getter, 88 typename ImplDetail<C>::template MemberFunctionSetCallback<T> setter) 89{ 90 int getFuncId; 91 int setFuncId; 92 static_assert(std::is_base_of_v<T, C>, "Trying to bind an unrelated method!"); 93 getFunctions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, getter)); 94 setFunctions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, setter)); 95 functions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, getter)); 96 getFuncId = nextFreeId_++; 97 functions_.emplace(nextFreeId_, new FunctionBinding(name, MethodOptions::NONE, setter)); 98 setFuncId = nextFreeId_++; 99 ImplDetail<C>::CustomProperty(name, getter, getFuncId, setFuncId); 100} 101 102template<typename C, template<typename> typename ImplDetail> 103void JSClassImpl<C, ImplDetail>::CustomProperty(const char* name, typename ImplDetail<C>::FunctionGetCallback getter, 104 typename ImplDetail<C>::FunctionSetCallback setter) 105{ 106 ImplDetail<C>::CustomProperty(name, getter, setter); 107} 108 109template<typename C, template<typename> typename ImplDetail> 110template<typename T> 111void JSClassImpl<C, ImplDetail>::StaticMethod( 112 const char* name, typename ImplDetail<C>::template MemberFunctionCallback<T> callback) 113{ 114 static_assert(std::is_base_of_v<T, C>, "Trying to bind an unrelated method!"); 115 functions_.emplace(nextFreeId, new FunctionBinding(name, MethodOptions::NONE, callback)); 116 ImplDetail<C>::StaticMethod(name, callback, nextFreeId++); 117} 118 119template<typename C, template<typename> typename ImplDetail> 120void JSClassImpl<C, ImplDetail>::StaticMethod(const char* name, typename ImplDetail<C>::FunctionCallback callback) 121{ 122 ImplDetail<C>::StaticMethod(name, callback); 123} 124 125template<typename C, template<typename> typename ImplDetail> 126template<typename T> 127void JSClassImpl<C, ImplDetail>::StaticConstant(const char* name, T value) 128{ 129 ImplDetail<C>::StaticConstant(name, value); 130} 131 132template<typename C, template<typename> typename ImplDetail> 133void JSClassImpl<C, ImplDetail>::Bind( 134 typename ImplDetail<C>::BindingTarget bindTarget, typename ImplDetail<C>::FunctionCallback ctor) 135{ 136 ImplDetail<C>::Bind(bindTarget, ctor); 137} 138 139template<typename C, template<typename> typename ImplDetail> 140template<typename... Args> 141void JSClassImpl<C, ImplDetail>::Bind(typename ImplDetail<C>::BindingTarget bindTarget) 142{ 143 ImplDetail<C>::template Bind<Args...>(bindTarget); 144} 145 146template<typename C, template<typename> typename ImplDetail> 147template<typename Base> 148void JSClassImpl<C, ImplDetail>::Inherit() 149{ 150 static_assert(std::is_base_of_v<Base, C>, "Calling Inherit() on unrelated classes!"); 151 ImplDetail<C>::template Inherit<Base>(); 152} 153 154template<typename C, template<typename> typename ImplDetail> 155template<typename Base> 156void JSClassImpl<C, ImplDetail>::InheritAndBind( 157 typename ImplDetail<C>::BindingTarget bindTarget, ImplDetail<C>::JSFunctionCallback ctor, 158 ImplDetail<C>::JSDestructorCallback dtor, ImplDetail<C>::JSGCMarkCallback gcMark) 159{ 160 static_assert(std::is_base_of_v<Base, C>, "Calling Inherit() on unrelated classes!"); 161 ImplDetail<C>::template InheritAndBind<Base>(bindTarget, ctor, dtor, gcMark); 162} 163 164template<typename C, template<typename> typename ImplDetail> 165IFunctionBinding* JSClassImpl<C, ImplDetail>::GetFunctionBinding(int id) 166{ 167 return functions_[id]; 168} 169 170template<typename C, template<typename> typename ImplDetail> 171const char* JSClassImpl<C, ImplDetail>::JSName() 172{ 173 return jsName.c_str(); 174} 175 176}; // namespace OHOS::Ace::Framework 177