This commit is contained in:
blueloveTH 2023-09-27 07:46:25 +08:00
parent 39706325dd
commit 778a70e90f
8 changed files with 54 additions and 6 deletions

View File

@ -113,4 +113,18 @@ void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){
return VAR(self.REF().FGET()); \
});
#define PY_STRUCT_LIKE_OBJECT(T) \
static_assert(std::is_trivially_copyable<T>::value); \
vm->bind_func<1>(type, "__from_struct__", [](VM* vm, ArgsView args){ \
C99Struct& s = CAST(C99Struct&, args[0]); \
if(s.size != sizeof(T)) vm->ValueError("size mismatch"); \
PyObject* obj = vm->heap.gcnew<T>(T::_type(vm)); \
memcpy(&_CAST(T&, obj), s.p, sizeof(T)); \
return obj; \
}); \
vm->bind_method<0>(type, "__to_struct__", [](VM* vm, ArgsView args){ \
T& self = _CAST(T&, args[0]); \
return VAR_T(C99Struct, &self, sizeof(T)); \
});
} // namespace pkpy

View File

@ -1,6 +1,6 @@
#pragma once
#include "cffi.h"
#include "bindings.h"
namespace pkpy{

View File

@ -192,6 +192,9 @@ const StrName __package__ = StrName::get("__package__");
const StrName __path__ = StrName::get("__path__");
const StrName __class__ = StrName::get("__class__");
const StrName __to_struct__ = StrName::get("__to_struct__");
const StrName __from_struct__ = StrName::get("__from_struct__");
const StrName pk_id_add = StrName::get("add");
const StrName pk_id_set = StrName::get("set");
const StrName pk_id_eval = StrName::get("eval");

View File

@ -399,10 +399,14 @@ public:
return _all_types[t.index].obj;
}
Type _tp(PyObject* obj){
if(is_int(obj)) return tp_int;
if(is_float(obj)) return tp_float;
return obj->type;
}
PyObject* _t(PyObject* obj){
if(is_int(obj)) return _t(tp_int);
if(is_float(obj)) return _t(tp_float);
return _all_types[obj->type].obj;
return _all_types[_tp(obj).index].obj;
}
struct ImportContext{

View File

@ -127,3 +127,6 @@ class array(struct):
def __getitem__(self, index: int) -> struct: ...
def __setitem__(self, index: int, value: struct) -> None: ...
def __len__(self) -> int: ...
def to_struct(obj) -> struct: ...
def from_struct(T: type, obj: struct): ...

View File

@ -1,4 +1,5 @@
#include "pocketpy/cffi.h"
#include "pocketpy/str.h"
namespace pkpy{
@ -136,7 +137,7 @@ namespace pkpy{
vm->bind_method<0>(type, "copy", [](VM* vm, ArgsView args){
const C99Struct& self = _CAST(C99Struct&, args[0]);
return VAR_T(C99Struct, self);
return vm->heap.gcnew<C99Struct>(vm->_tp(args[0]), self);
});
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
@ -233,6 +234,15 @@ void add_module_c(VM* vm){
return vm->None;
});
vm->bind_func<1>(mod, "to_struct", [](VM* vm, ArgsView args){
return vm->call_method(args[0], __to_struct__);
});
vm->bind_func<2>(mod, "from_struct", [](VM* vm, ArgsView args){
PyObject* f = vm->getattr(args[0], __from_struct__);
return vm->call(f, args[1]);
});
VoidP::register_class(vm, mod);
C99Struct::register_class(vm, mod);
mod->attr().set("NULL", VAR_T(VoidP, nullptr));

View File

@ -48,6 +48,8 @@ namespace pkpy{
void PyVec2::_register(VM* vm, PyObject* mod, PyObject* type){
PY_STRUCT_LIKE_OBJECT(PyVec2)
vm->bind_constructor<3>(type, [](VM* vm, ArgsView args){
float x = CAST_F(args[1]);
float y = CAST_F(args[2]);
@ -112,6 +114,8 @@ namespace pkpy{
}
void PyVec3::_register(VM* vm, PyObject* mod, PyObject* type){
PY_STRUCT_LIKE_OBJECT(PyVec3)
vm->bind_constructor<4>(type, [](VM* vm, ArgsView args){
float x = CAST_F(args[1]);
float y = CAST_F(args[2]);
@ -154,6 +158,8 @@ namespace pkpy{
}
void PyVec4::_register(VM* vm, PyObject* mod, PyObject* type){
PY_STRUCT_LIKE_OBJECT(PyVec4)
vm->bind_constructor<1+4>(type, [](VM* vm, ArgsView args){
float x = CAST_F(args[1]);
float y = CAST_F(args[2]);
@ -204,6 +210,8 @@ namespace pkpy{
#undef BIND_VEC_FUNCTION_1
void PyMat3x3::_register(VM* vm, PyObject* mod, PyObject* type){
PY_STRUCT_LIKE_OBJECT(PyMat3x3)
vm->bind_constructor<-1>(type, [](VM* vm, ArgsView args){
if(args.size() == 1+0) return VAR_T(PyMat3x3, Mat3x3::zeros());
if(args.size() == 1+9){

View File

@ -471,3 +471,9 @@ test_mat_copy = test_mat.copy()
test_mat_copy = test_mat.copy()
test_vec2_copy = test_vec2.copy()
temp_vec2 = test_mat_copy.transform_vector(test_vec2_copy)
import c
a = vec2(1, 2)
b = c.to_struct(a)
assert b.size() == 8
assert c.from_struct(vec2, b) == a