This commit is contained in:
blueloveTH 2023-07-22 12:38:50 +08:00
parent 5f058efec5
commit e18f61790c

View File

@ -4,6 +4,14 @@
namespace pkpy{ namespace pkpy{
template<typename T>
struct OpaquePointer{
T* ptr;
OpaquePointer(T* ptr): ptr(ptr){}
T* operator->(){ return ptr; }
};
struct NativeProxyFuncCBase { struct NativeProxyFuncCBase {
virtual PyObject* operator()(VM* vm, ArgsView args) = 0; virtual PyObject* operator()(VM* vm, ArgsView args) = 0;
}; };
@ -34,13 +42,13 @@ struct NativeProxyFuncC final: NativeProxyFuncCBase {
template<typename Ret, typename T, typename... Params> template<typename Ret, typename T, typename... Params>
struct NativeProxyMethodC final: NativeProxyFuncCBase { struct NativeProxyMethodC final: NativeProxyFuncCBase {
static constexpr int N = sizeof...(Params) + 1; static constexpr int N = sizeof...(Params);
using _Fp = Ret(T::*)(Params...); using _Fp = Ret(T::*)(Params...);
_Fp func; _Fp func;
NativeProxyMethodC(_Fp func) : func(func) {} NativeProxyMethodC(_Fp func) : func(func) {}
PyObject* operator()(VM* vm, ArgsView args) override { PyObject* operator()(VM* vm, ArgsView args) override {
PK_ASSERT(args.size() == N); PK_ASSERT(args.size() == N+1);
return call<Ret>(vm, args, std::make_index_sequence<N>()); return call<Ret>(vm, args, std::make_index_sequence<N>());
} }
@ -57,6 +65,33 @@ struct NativeProxyMethodC final: NativeProxyFuncCBase {
} }
}; };
template<typename _OpaqueT, typename Ret, typename T, typename... Params>
struct NativeProxyOpaqueMethodC final: NativeProxyFuncCBase {
static_assert(std::is_base_of_v<OpaquePointer<T>, _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<Ret>(vm, args, std::make_index_sequence<N>());
}
template<typename __Ret, size_t... Is>
PyObject* call(VM* vm, ArgsView args, std::index_sequence<Is...>){
OpaquePointer<T>& _opa_self = py_cast<_OpaqueT&>(vm, args[0]);
T& self = *_opa_self.ptr;
if constexpr(std::is_void_v<__Ret>){
(self.*func)(py_cast<Params>(vm, args[Is+1])...);
return vm->None;
}else{
__Ret ret = (self.*func)(py_cast<Params>(vm, args[Is+1])...);
return VAR(std::move(ret));
}
}
};
inline PyObject* proxy_wrapper(VM* vm, ArgsView args){ inline PyObject* proxy_wrapper(VM* vm, ArgsView args){
NativeProxyFuncCBase* pf = lambda_get_userdata<NativeProxyFuncCBase*>(args.begin()); NativeProxyFuncCBase* pf = lambda_get_userdata<NativeProxyFuncCBase*>(args.begin());
return (*pf)(vm, args); 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<Ret, T, Params...>(func); auto proxy = new NativeProxyMethodC<Ret, T, Params...>(func);
vm->bind(obj, sig, proxy_wrapper, proxy); vm->bind(obj, sig, proxy_wrapper, proxy);
} }
template<typename _OpaqueT, typename Ret, typename T, typename... Params>
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<typename T>
struct OpaquePointer{
T* ptr;
OpaquePointer(T* ptr): ptr(ptr){}
T* operator->(){ return ptr; }
};
#define PK_REGISTER_FIELD(T, NAME) \ #define PK_REGISTER_FIELD(T, NAME) \
type->attr().set(#NAME, vm->property( \ type->attr().set(#NAME, vm->property( \
[](VM* vm, ArgsView args){ \ [](VM* vm, ArgsView args){ \