class Vector3: def __init__(self, x=0, y=0, z=0 ): self._vec = JS('new THREE.Vector3(x,y,z)') @property def x(self): vec = self._vec return JS('vec.x') @x.setter def x(self, value): vec = self._vec JS('vec.x=value') @property def y(self): vec = self._vec return JS('vec.y') @y.setter def y(self, value): vec = self._vec JS('vec.y=value') @property def z(self): vec = self._vec return JS('vec.z') @x.setter def z(self, value): vec = self._vec JS('vec.z=value')
The python_to_pythonjs compiler was modified to support the @property decorator by inserting the right calls for each instance of a class where those properties get used. This requires that the compiler knows what class type each instance is - this becomes a problem for scripts that are later compiled in another pass, because the compiler needs all the information that was introspected during AST traversal. To workaround this problem the introspected data is dumped to a file for each wrapper module and is loaded later when a script calls: from some_module import *
I also added a test server, see this commit, using the Tornado web framework that dynamically converts html files that contain embedded PythonScript. It will process any PythonScript wrappers in the head and cache the AST introspection data so that the embedded PythonScript can properly import and use the wrapper classes in them.
<html><head> <script src="pythonscript.js"></script> <script src="libs/three/three.min.js"></script> <script src="bindings/three.py"></script> <script type="text/python" closure="true"> from three import * def test(): v = Vector3(1, 2, 3) print( v.x ) print( v.y ) print( v.z ) </script> </head> <body> <button onclick="test()">click me</button> </body> </html>