mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
...
This commit is contained in:
parent
778a70e90f
commit
979b7f4a67
@ -114,17 +114,36 @@ 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){ \
|
||||
C99Struct& s = CAST(C99Struct&, args[0]); \
|
||||
if(s.size != sizeof(T)) vm->ValueError("size mismatch"); \
|
||||
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){ \
|
||||
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
|
@ -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");
|
||||
|
@ -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: ...
|
||||
|
||||
|
@ -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: ...
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
11
src/cffi.cpp
11
src/cffi.cpp
@ -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));
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user