From e18f61790c1d4f369ed8bb33a67e9da148450126 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sat, 22 Jul 2023 12:38:50 +0800 Subject: [PATCH] ... --- include/pocketpy/bindings.h | 54 +++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/include/pocketpy/bindings.h b/include/pocketpy/bindings.h index 2398a026..52060267 100644 --- a/include/pocketpy/bindings.h +++ b/include/pocketpy/bindings.h @@ -4,6 +4,14 @@ namespace pkpy{ +template +struct OpaquePointer{ + T* ptr; + OpaquePointer(T* ptr): ptr(ptr){} + + T* operator->(){ return ptr; } +}; + struct NativeProxyFuncCBase { virtual PyObject* operator()(VM* vm, ArgsView args) = 0; }; @@ -34,13 +42,13 @@ struct NativeProxyFuncC final: NativeProxyFuncCBase { template struct NativeProxyMethodC final: NativeProxyFuncCBase { - static constexpr int N = sizeof...(Params) + 1; + static constexpr int N = sizeof...(Params); using _Fp = Ret(T::*)(Params...); _Fp func; NativeProxyMethodC(_Fp func) : func(func) {} PyObject* operator()(VM* vm, ArgsView args) override { - PK_ASSERT(args.size() == N); + PK_ASSERT(args.size() == N+1); return call(vm, args, std::make_index_sequence()); } @@ -57,6 +65,33 @@ struct NativeProxyMethodC final: NativeProxyFuncCBase { } }; +template +struct NativeProxyOpaqueMethodC final: NativeProxyFuncCBase { + static_assert(std::is_base_of_v, _OpaqueT>); + static constexpr int N = sizeof...(Params); + using _Fp = Ret(T::*)(Params...); + _Fp func; + NativeProxyOpaqueMethodC(_Fp func) : func(func) {} + + PyObject* operator()(VM* vm, ArgsView args) override { + PK_ASSERT(args.size() == N+1); + return call(vm, args, std::make_index_sequence()); + } + + template + PyObject* call(VM* vm, ArgsView args, std::index_sequence){ + OpaquePointer& _opa_self = py_cast<_OpaqueT&>(vm, args[0]); + T& self = *_opa_self.ptr; + if constexpr(std::is_void_v<__Ret>){ + (self.*func)(py_cast(vm, args[Is+1])...); + return vm->None; + }else{ + __Ret ret = (self.*func)(py_cast(vm, args[Is+1])...); + return VAR(std::move(ret)); + } + } +}; + inline PyObject* proxy_wrapper(VM* vm, ArgsView args){ NativeProxyFuncCBase* pf = lambda_get_userdata(args.begin()); return (*pf)(vm, args); @@ -73,16 +108,13 @@ void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){ auto proxy = new NativeProxyMethodC(func); vm->bind(obj, sig, proxy_wrapper, proxy); } + +template +void _bind_opaque(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){ + auto proxy = new NativeProxyOpaqueMethodC<_OpaqueT, Ret, T, Params...>(func); + vm->bind(obj, sig, proxy_wrapper, proxy); +} /*****************************************************************/ - -template -struct OpaquePointer{ - T* ptr; - OpaquePointer(T* ptr): ptr(ptr){} - - T* operator->(){ return ptr; } -}; - #define PK_REGISTER_FIELD(T, NAME) \ type->attr().set(#NAME, vm->property( \ [](VM* vm, ArgsView args){ \