blueloveTH пре 2 година
родитељ
комит
979b7f4a67
9 измењених фајлова са 56 додато и 83 уклоњено
  1. 25 6
      include/pocketpy/bindings.h
  2. 0 3
      include/pocketpy/str.h
  3. 15 2
      include/typings/c.pyi
  4. 5 12
      include/typings/linalg.pyi
  5. 2 2
      python/c.py
  6. 1 10
      src/cffi.cpp
  7. 0 41
      src/linalg.cpp
  8. 4 3
      tests/80_linalg.py
  9. 4 4
      tests/99_cffi_2.py

+ 25 - 6
include/pocketpy/bindings.h

@@ -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

+ 0 - 3
include/pocketpy/str.h

@@ -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");

+ 15 - 2
include/typings/c.pyi

@@ -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: ...
+

+ 5 - 12
include/typings/linalg.pyi

@@ -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: ...
 

+ 2 - 2
python/c.py

@@ -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)
 

+ 1 - 10
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));

+ 0 - 41
src/linalg.cpp

@@ -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());

+ 4 - 3
tests/80_linalg.py

@@ -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

+ 4 - 4
tests/99_cffi_2.py

@@ -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