add bind_field<>

This commit is contained in:
blueloveTH 2024-05-04 12:34:57 +08:00
parent cc68c0dcc8
commit dd5a5e096f
3 changed files with 44 additions and 20 deletions

View File

@ -142,14 +142,9 @@ public:
stack_no_copy<ArgsView> s_view;
} _c;
PyObject* None;
PyObject* True;
PyObject* False;
PyObject* NotImplemented; // unused
PyObject* Ellipsis;
PyObject* builtins; // builtins module
PyObject* StopIteration;
PyObject* _main; // __main__ module
PyObject *None, *True, *False, *NotImplemented;
PyObject *StopIteration, *Ellipsis;
PyObject *builtins, *_main;
// typeid -> Type
std::map<const std::type_index, Type> _cxx_typeid_map;
@ -311,6 +306,8 @@ public:
PyObject* bind(PyObject*, const char*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT);
PyObject* bind(PyObject*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT);
PyObject* bind_property(PyObject*, const char*, NativeFuncC fget, NativeFuncC fset=nullptr);
template<typename T, typename F, bool ReadOnly=false>
PyObject* bind_field(PyObject*, const char*, F T::*);
template<int ARGC, typename __T>
PyObject* bind_constructor(__T&& type, NativeFuncC fn) {
@ -585,4 +582,32 @@ PyObject* VM::bind_func(PyObject* obj, StrName name, NativeFuncC fn, UserData us
return nf;
}
template<typename T, typename F, bool ReadOnly>
PyObject* VM::bind_field(PyObject* obj, const char* name, F T::*field){
static_assert(!std::is_reference_v<F>);
std::string_view name_sv(name); int pos = name_sv.find(':');
if(pos > 0) name_sv = name_sv.substr(0, pos);
auto fget = [](VM* vm, ArgsView args) -> PyObject*{
T& self = PK_OBJ_GET(T, args[0]);
F T::*field = lambda_get_userdata<F T::*>(args.begin());
return VAR(self.*field);
};
PyObject* _0 = heap.gcnew<NativeFunc>(tp_native_func, fget, 1, false);
PK_OBJ_GET(NativeFunc, _0).set_userdata(field);
PyObject* _1 = vm->None;
if constexpr (!ReadOnly){
auto fset = [](VM* vm, ArgsView args){
T& self = PK_OBJ_GET(T, args[0]);
F T::*field = lambda_get_userdata<F T::*>(args.begin());
self.*field = py_cast<F>(vm, args[1]);
return vm->None;
};
_1 = heap.gcnew<NativeFunc>(tp_native_func, fset, 2, false);
PK_OBJ_GET(NativeFunc, _1).set_userdata(field);
}
PyObject* prop = VAR(Property(_0, _1));
obj->attr().set(StrName(name_sv), prop);
return prop;
}
} // namespace pkpy

View File

@ -327,15 +327,15 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
self.m[i][j] = CAST_F(value);
});
PY_FIELD(Mat3x3, "_11", _11)
PY_FIELD(Mat3x3, "_12", _12)
PY_FIELD(Mat3x3, "_13", _13)
PY_FIELD(Mat3x3, "_21", _21)
PY_FIELD(Mat3x3, "_22", _22)
PY_FIELD(Mat3x3, "_23", _23)
PY_FIELD(Mat3x3, "_31", _31)
PY_FIELD(Mat3x3, "_32", _32)
PY_FIELD(Mat3x3, "_33", _33)
vm->bind_field(type, "_11", &Mat3x3::_11);
vm->bind_field(type, "_12", &Mat3x3::_12);
vm->bind_field(type, "_13", &Mat3x3::_13);
vm->bind_field(type, "_21", &Mat3x3::_21);
vm->bind_field(type, "_22", &Mat3x3::_22);
vm->bind_field(type, "_23", &Mat3x3::_23);
vm->bind_field(type, "_31", &Mat3x3::_31);
vm->bind_field(type, "_32", &Mat3x3::_32);
vm->bind_field(type, "_33", &Mat3x3::_33);
vm->bind__add__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
Mat3x3& self = _CAST(Mat3x3&, _0);

View File

@ -1257,12 +1257,11 @@ PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Native
}
PyObject* VM::bind_property(PyObject* obj, const char* name, NativeFuncC fget, NativeFuncC fset){
std::string_view name_sv(name); int pos = name_sv.find(':');
if(pos > 0) name_sv = name_sv.substr(0, pos);
PyObject* _0 = heap.gcnew<NativeFunc>(tp_native_func, fget, 1, false);
PyObject* _1 = vm->None;
if(fset != nullptr) _1 = heap.gcnew<NativeFunc>(tp_native_func, fset, 2, false);
std::string_view name_sv(name);
int pos = name_sv.find(':');
if(pos > 0) name_sv = name_sv.substr(0, pos);
PyObject* prop = VAR(Property(_0, _1));
obj->attr().set(StrName(name_sv), prop);
return prop;