This commit is contained in:
blueloveTH 2023-09-27 10:28:39 +08:00
parent 778a70e90f
commit 979b7f4a67
9 changed files with 56 additions and 83 deletions

View File

@ -115,16 +115,35 @@ void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){
#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){ \
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){ \
vm->bind_method<0>(type, "to_struct", [](VM* vm, ArgsView args){ \
T& self = _CAST(T&, args[0]); \
return VAR_T(C99Struct, &self, sizeof(T)); \
});
}); \
vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){ \
T& self = _CAST(T&, args[0]); \
return VAR_T(VoidP, &self); \
}); \
vm->bind_method<0>(type, "copy", [](VM* vm, ArgsView args){ \
T& self = _CAST(T&, args[0]); \
return VAR_T(T, self); \
}); \
vm->bind_method<0>(type, "sizeof", [](VM* vm, ArgsView args){ \
return VAR(sizeof(T)); \
}); \
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ \
T& self = _CAST(T&, _0); \
if(!vm->isinstance(_1, T::_type(vm))){ \
return vm->NotImplemented; \
} \
T& other = _CAST(T&, _1); \
return VAR(self == other); \
}); \
} // namespace pkpy

View File

@ -192,9 +192,6 @@ 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

@ -128,5 +128,18 @@ class array(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): ...
from typing import Generic, TypeVar
T = TypeVar('T')
class _struct_like(Generic[T]):
def to_struct(self) -> struct: ...
@classmethod
def from_struct(cls, s: struct) -> T: ...
def addr(self) -> void_p: ...
def sizeof(self) -> int: ...
def copy(self) -> T: ...
def __eq__(self, other: T) -> bool: ...
def __ne__(self, other: T) -> bool: ...

View File

@ -1,12 +1,11 @@
from typing import overload
from c import float_p
from c import _struct_like
class vec2:
class vec2(_struct_like['vec2']):
x: float
y: float
def __init__(self, x: float, y: float) -> None: ...
def copy(self) -> vec2: ...
def __add__(self, other: vec2) -> vec2: ...
def __sub__(self, other: vec2) -> vec2: ...
def __mul__(self, other: float) -> vec2: ...
@ -18,15 +17,13 @@ class vec2:
def normalize(self) -> vec2: ...
def rotate(self, radians: float) -> vec2: ...
def rotate_(self, radians: float) -> None: ...
def addr(self) -> float_p: ...
class vec3:
class vec3(_struct_like['vec3']):
x: float
y: float
z: float
def __init__(self, x: float, y: float, z: float) -> None: ...
def copy(self) -> vec3: ...
def __add__(self, other: vec3) -> vec3: ...
def __sub__(self, other: vec3) -> vec3: ...
def __mul__(self, other: float) -> vec3: ...
@ -36,16 +33,14 @@ class vec3:
def length(self) -> float: ...
def length_squared(self) -> float: ...
def normalize(self) -> vec3: ...
def addr(self) -> float_p: ...
class vec4:
class vec4(_struct_like['vec4']):
x: float
y: float
z: float
w: float
def __init__(self, x: float, y: float, z: float, w: float) -> None: ...
def copy(self) -> vec4: ...
def __add__(self, other: vec4) -> vec4: ...
def __sub__(self, other: vec4) -> vec4: ...
def __mul__(self, other: float) -> vec4: ...
@ -54,9 +49,8 @@ class vec4:
def length(self) -> float: ...
def length_squared(self) -> float: ...
def normalize(self) -> vec4: ...
def addr(self) -> float_p: ...
class mat3x3:
class mat3x3(_struct_like['mat3x3']):
_11: float
_12: float
_13: float
@ -78,7 +72,6 @@ class mat3x3:
def set_ones(self) -> None: ...
def set_identity(self) -> None: ...
def copy(self) -> mat3x3: ...
def determinant(self) -> float: ...
def transpose(self) -> mat3x3: ...

View File

@ -18,8 +18,8 @@ class array(struct):
def __setitem__(self, index: int, value: struct) -> None:
if index < 0 or index >= self.item_count:
raise IndexError("array index out of range")
if value.size() != self.item_size:
raise ValueError(f"array item size mismatch: {value.size()} != {self.item_size}")
if value.sizeof() != self.item_size:
raise ValueError(f"array item size mismatch: {value.sizeof()} != {self.item_size}")
p = self.addr() + self.item_size * index
p.write_struct(value)

View File

@ -130,7 +130,7 @@ namespace pkpy{
return VAR_T(VoidP, self.p);
});
vm->bind_method<0>(type, "size", [](VM* vm, ArgsView args){
vm->bind_method<0>(type, "sizeof", [](VM* vm, ArgsView args){
C99Struct& self = _CAST(C99Struct&, args[0]);
return VAR(self.size);
});
@ -234,15 +234,6 @@ 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

@ -2,12 +2,6 @@
namespace pkpy{
#define BIND_VEC_ADDR(D) \
vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){ \
PyVec##D& self = _CAST(PyVec##D&, args[0]); \
return VAR_T(VoidP, &self.x); \
});
#define BIND_VEC_VEC_OP(D, name, op) \
vm->bind_method<1>(type, #name, [](VM* vm, ArgsView args){ \
PyVec##D& self = _CAST(PyVec##D&, args[0]); \
@ -68,11 +62,6 @@ namespace pkpy{
return VAR(ss.str());
});
vm->bind_method<0>(type, "copy", [](VM* vm, ArgsView args){
PyVec2& self = _CAST(PyVec2&, args[0]);
return VAR_T(PyVec2, self);
});
vm->bind_method<1>(type, "rotate", [](VM* vm, ArgsView args){
Vec2 self = _CAST(PyVec2&, args[0]);
float radian = CAST(f64, args[1]);
@ -97,13 +86,11 @@ namespace pkpy{
return vm->None;
});
BIND_VEC_ADDR(2)
BIND_VEC_VEC_OP(2, __add__, +)
BIND_VEC_VEC_OP(2, __sub__, -)
BIND_VEC_FLOAT_OP(2, __mul__, *)
BIND_VEC_FLOAT_OP(2, __rmul__, *)
BIND_VEC_FLOAT_OP(2, __truediv__, /)
BIND_VEC_VEC_OP(2, __eq__, ==)
BIND_VEC_FIELD(2, x)
BIND_VEC_FIELD(2, y)
BIND_VEC_FUNCTION_1(2, dot)
@ -135,18 +122,11 @@ namespace pkpy{
return VAR(ss.str());
});
vm->bind_method<0>(type, "copy", [](VM* vm, ArgsView args){
PyVec3& self = _CAST(PyVec3&, args[0]);
return VAR_T(PyVec3, self);
});
BIND_VEC_ADDR(3)
BIND_VEC_VEC_OP(3, __add__, +)
BIND_VEC_VEC_OP(3, __sub__, -)
BIND_VEC_FLOAT_OP(3, __mul__, *)
BIND_VEC_FLOAT_OP(3, __rmul__, *)
BIND_VEC_FLOAT_OP(3, __truediv__, /)
BIND_VEC_VEC_OP(3, __eq__, ==)
BIND_VEC_FIELD(3, x)
BIND_VEC_FIELD(3, y)
BIND_VEC_FIELD(3, z)
@ -180,18 +160,11 @@ namespace pkpy{
return VAR(ss.str());
});
vm->bind_method<0>(type, "copy", [](VM* vm, ArgsView args){
PyVec4& self = _CAST(PyVec4&, args[0]);
return VAR_T(PyVec4, self);
});
BIND_VEC_ADDR(4)
BIND_VEC_VEC_OP(4, __add__, +)
BIND_VEC_VEC_OP(4, __sub__, -)
BIND_VEC_FLOAT_OP(4, __mul__, *)
BIND_VEC_FLOAT_OP(4, __rmul__, *)
BIND_VEC_FLOAT_OP(4, __truediv__, /)
BIND_VEC_VEC_OP(4, __eq__, ==)
BIND_VEC_FIELD(4, x)
BIND_VEC_FIELD(4, y)
BIND_VEC_FIELD(4, z)
@ -266,11 +239,6 @@ namespace pkpy{
return VAR(ss.str());
});
vm->bind_method<0>(type, "copy", [](VM* vm, ArgsView args){
PyMat3x3& self = _CAST(PyMat3x3&, args[0]);
return VAR_T(PyMat3x3, self);
});
vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj, PyObject* index){
PyMat3x3& self = _CAST(PyMat3x3&, obj);
Tuple& t = CAST(Tuple&, index);
@ -369,15 +337,6 @@ namespace pkpy{
return vm->NotImplemented;
});
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
PyMat3x3& self = _CAST(PyMat3x3&, _0);
if(is_non_tagged_type(_1, PyMat3x3::_type(vm))){
PyMat3x3& other = _CAST(PyMat3x3&, _1);
return VAR(self == other);
}
return vm->NotImplemented;
});
vm->bind_method<0>(type, "determinant", [](VM* vm, ArgsView args){
PyMat3x3& self = _CAST(PyMat3x3&, args[0]);
return VAR(self.determinant());

View File

@ -474,6 +474,7 @@ 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
b = a.to_struct()
assert a.sizeof() == 8
assert b.sizeof() == 8
assert vec2.from_struct(b) == a

View File

@ -9,7 +9,7 @@ c_void_1.write_bytes(c_void_1.read_bytes(5))
# ------------------------------------------------
c_void_1 = c.malloc(32)
my_struct2 = c_void_1.read_struct(32)
assert my_struct2.size() == 32
assert my_struct2.sizeof() == 32
data_bytes = bytes([1,2,3])
my_struct4 = c.struct(data_bytes)
@ -27,15 +27,15 @@ except TypeError:
pass
# ------------------------------------------------
my_struct1 = c.struct(16)
assert my_struct1.size() == 16
assert my_struct1.sizeof() == 16
# 对 c.struct 的 copy 方法的测试不完全
assert my_struct1.copy().size() == 16
assert my_struct1.copy().sizeof() == 16
data_bytes = bytes([1,2,3])
my_struct4 = c.struct(data_bytes)
assert my_struct4.addr().read_bytes(
my_struct4.size()
my_struct4.sizeof()
) == data_bytes