This commit is contained in:
blueloveTH 2023-06-24 01:19:34 +08:00
parent 65d20a384a
commit 970b66f228
3 changed files with 32 additions and 11 deletions

View File

@ -50,7 +50,7 @@ public class PyVector2Type: PyTypeObject{
public override System.Type type => typeof(Vector2); public override System.Type type => typeof(Vector2);
[PythonBinding] [PythonBinding]
public static object __add__(VM vm, Vector2 self, object other){ public object __add__(Vector2 self, object other){
// If the other object is not a Vector2, return NotImplemented // If the other object is not a Vector2, return NotImplemented
if(!(other is Vector2)) return VM.NotImplemented; if(!(other is Vector2)) return VM.NotImplemented;
// Otherwise, return the result of addition // Otherwise, return the result of addition
@ -59,7 +59,7 @@ public class PyVector2Type: PyTypeObject{
} }
``` ```
This is easy to understand, right? This is easy to understand.
Let's see another example, `__mul__`, it is used to implement the `*` operator in Python. Let's see another example, `__mul__`, it is used to implement the `*` operator in Python.
`Vector2` object in C# can be multiplied with a `float` object in Python. `Vector2` object in C# can be multiplied with a `float` object in Python.
The following code shows this usage. The following code shows this usage.
@ -82,20 +82,19 @@ public class PyVector2Type: PyTypeObject{
// ... // ...
[PythonBinding] [PythonBinding]
public static object __mul__(VM vm, Vector2 self, object other){ public object __mul__(Vector2 self, object other){
if(!(other is float)) return VM.NotImplemented; if(!(other is float)) return VM.NotImplemented;
return self * (float)other; return self * (float)other;
} }
[PythonBinding] [PythonBinding]
public static object __rmul__(VM vm, Vector2 self, object other){ public object __rmul__(Vector2 self, object other){
if(!(other is float)) return VM.NotImplemented; if(!(other is float)) return VM.NotImplemented;
return self * (float)other; return self * (float)other;
} }
} }
``` ```
Finally, let's implement the constructor of `Vector2`. Finally, let's implement the constructor of `Vector2`.
`__new__` magic method must be defined. `__new__` magic method must be defined.
@ -105,7 +104,7 @@ public class PyVector2Type: PyTypeObject{
public override System.Type type => typeof(Vector2); public override System.Type type => typeof(Vector2);
[PythonBinding] [PythonBinding]
public static object __new__(VM vm, PyTypeObject cls, params object[] args){ public object __new__(PyTypeObject cls, params object[] args){
if(args.Length == 0) return new Vector2(); if(args.Length == 0) return new Vector2();
if(args.Length == 2){ if(args.Length == 2){
float x = vm.PyCast<float>(args[0]); float x = vm.PyCast<float>(args[0]);
@ -137,21 +136,20 @@ public class PyVector2Type: PyTypeObject{
public override System.Type type => typeof(Vector2); public override System.Type type => typeof(Vector2);
[PythonBinding(BindingType.Getter)] [PythonBinding(BindingType.Getter)]
public static object x(VM vm, Vector2 self) => self.x; public object x(Vector2 self) => self.x;
[PythonBinding(BindingType.Setter)] [PythonBinding(BindingType.Setter)]
public static void x(VM vm, Vector2 self, object value) => self.x = vm.PyCast<float>(value); public void x(Vector2 self, object value) => self.x = vm.PyCast<float>(value);
[PythonBinding(BindingType.Getter)] [PythonBinding(BindingType.Getter)]
public static object y(VM vm, Vector2 self) => self.y; public object y(Vector2 self) => self.y;
[PythonBinding(BindingType.Setter)] [PythonBinding(BindingType.Setter)]
public static void y(VM vm, Vector2 self, object value) => self.y = vm.PyCast<float>(value); public void y(Vector2 self, object value) => self.y = vm.PyCast<float>(value);
} }
``` ```
Once you have done all the above, you must register the type to the VM. Once you have done all the above, you must register the type to the VM.
And set the returned object into a module.
Here we set it into `builtins` module, so that it can be accessed from anywhere. Here we set it into `builtins` module, so that it can be accessed from anywhere.
```csharp ```csharp

View File

@ -66,6 +66,7 @@ which means passing arguments between C# and Python is extremely easy and intuit
| Python Type | C# Type | | Python Type | C# Type |
| ----------- | ------- | | ----------- | ------- |
| `None` | `PocketPy.NoneType` | | `None` | `PocketPy.NoneType` |
| `object` | `System.Object` |
| `bool` | `System.Boolean` | | `bool` | `System.Boolean` |
| `int` | `System.Int32` | | `int` | `System.Int32` |
| `float` | `System.Single` | | `float` | `System.Single` |
@ -75,6 +76,11 @@ which means passing arguments between C# and Python is extremely easy and intuit
| `dict` | `System.Collections.Generic.Dictionary<PocketPy.PyDictKey, object>` | | `dict` | `System.Collections.Generic.Dictionary<PocketPy.PyDictKey, object>` |
| ... | ... | | ... | ... |
### Python Console in Editor
PocketPython provides a Python console in Unity editor,
which allows you to do quick debugging and testing.
### Lua Style API ### Lua Style API
PocketPython also provides a Lua style API for C# in `LuaBindings` class. PocketPython also provides a Lua style API for C# in `LuaBindings` class.

View File

@ -30,6 +30,10 @@ The `VM` class provides a sandboxed Python environment and a set of APIs for int
Compile and execute Python source code in the given module. It is equivalent to `Exec(Compile(source, filename, mode), mod)`. Compile and execute Python source code in the given module. It is equivalent to `Exec(Compile(source, filename, mode), mod)`.
+ `object Eval(string source, PyModule mod = null)`
Evaluate an expression in the given module.
+ `object Call(object callable, object[] args, Dictionary<string, object> kwargs)` + `object Call(object callable, object[] args, Dictionary<string, object> kwargs)`
Call a Python callable object with the given arguments and keyword arguments. It is equivalent to `callable(*args, **kwargs)` in Python. Call a Python callable object with the given arguments and keyword arguments. It is equivalent to `callable(*args, **kwargs)` in Python.
@ -78,6 +82,19 @@ The `VM` class provides a sandboxed Python environment and a set of APIs for int
### Type Conversion ### Type Conversion
+ `T PyCast<T>(object obj)`
Convert a Python object to a C# object. It is equivalent to `obj as T` in C#.
Raise `TypeError` if the conversion fails.
+ `bool IsInstance(object obj, PyTypeObject type)`
Check if a Python object is an instance of the given type. It is equivalent to `isinstance(obj, type)` in Python.
+ `void CheckType<T>(object t)`
Check if `t is T`. Raise `TypeError` if the check fails.
+ `bool PyEquals(object lhs, object rhs)` + `bool PyEquals(object lhs, object rhs)`
Check if two Python objects are equal. It is equivalent to `lhs == rhs` in Python. This is different from `==` or `object.ReferenceEquals` in C#. You should always use this method to compare Python objects. Check if two Python objects are equal. It is equivalent to `lhs == rhs` in Python. This is different from `==` or `object.ReferenceEquals` in C#. You should always use this method to compare Python objects.