Permalink
Browse files

made global variable scope an option: python_to_pythonjs.py --global-…

…variable-scope

the new default is not to have variable scope, this is normal python style.
  • Loading branch information...
hartsantler committed Oct 9, 2013
1 parent 4f74b2b commit 9ba79e1109b482fd88317e87229c31cebaad0d34
Showing with 118 additions and 52 deletions.
  1. +11 −4 bindings/three.py
  2. +21 −0 pythonscript/python_to_pythonjs.py
  3. +30 −23 tests/server.py
  4. +32 −0 tests/test_multiple_inheritance.html
  5. +24 −25 tests/threejs_helloworld.html
View
@@ -387,7 +387,8 @@ def setClearColor(self, red=1.0, green=1.0, blue=1.0, alpha=1.0):
c = clr._color
JS('renderer.setClearColor( c, alpha)')
def getDomElement(self):
@property
def domElement(self):
renderer = self._renderer
return JS('renderer.domElement')
@@ -427,9 +428,15 @@ def loadTextureCube( urls ):
ImageUtils = _ImageUtils()
class MeshBasicMaterial:
def __init__(self):
self._object = JS('new THREE.MeshBasicMaterial( {color:0xff0000, wireframe:true} )')
class _Material:
pass
class MeshBasicMaterial( _Material ):
def __init__(self, color=None, wireframe=False):
if not color: color = Color()
elif isinstance(color, dict):
color = Color(red=color['red'], green=color['green'], blue=color['blue'])
self._object = JS('new THREE.MeshBasicMaterial( {color:color, wireframe:wireframe} )')
class CubeGeometry:
def __init__(self, width, height, length):
@@ -13,6 +13,7 @@
from ast import FunctionDef
from ast import BinOp
from ast import Pass
from ast import Global
from ast import parse
from ast import NodeVisitor
@@ -34,6 +35,11 @@ def log(txt):
_log_file.flush()
GLOBAL_VARIABLE_SCOPE = False ## Python style
if '--global-variable-scope' in sys.argv: ## JavaScript style
GLOBAL_VARIABLE_SCOPE = True
log('not using python style variable scope')
class Writer(object):
def __init__(self):
@@ -699,6 +705,21 @@ def visit_FunctionDef(self, node):
writer.write('def %s(args, kwargs):' % node.name)
writer.push()
## the user will almost always want to use Python-style variable scope,
## this is kept here as an option to be sure we are compatible with the
## old-style code in runtime/pythonpythonjs.py and runtime/builtins.py
if not GLOBAL_VARIABLE_SCOPE:
local_vars = set()
global_vars = set()
for n in node.body:
if isinstance(n, Assign) and isinstance(n.targets[0], Name): ## assignment to local
local_vars.add( n.targets[0].id )
elif isinstance(n, Global):
global_vars.update( n.names )
if local_vars:
a = ','.join( local_vars-global_vars )
writer.write('var(%s)' %a)
if len(node.args.defaults) or len(node.args.args) or node.args.vararg or node.args.kwarg:
# new pythonjs' python function arguments handling
# create the structure representing the functions arguments
View
@@ -28,17 +28,19 @@
)
REGENERATE_RUNTIME = '--regenerate-runtime' in sys.argv
def python_to_pythonjs( src, module=None ):
def python_to_pythonjs( src, module=None, global_variable_scope=False ):
cmdheader = '#!%s' %PATHS['module_cache']
if module:
assert '.' not in module
cmdheader += ';' + module
cmdheader += '\n'
cmd = ['python2', os.path.join( PATHS['pythonscript'], 'python_to_pythonjs.py')]
if global_variable_scope: cmd.append('--global-variable-scope')
p = subprocess.Popen(
['python2', os.path.join( PATHS['pythonscript'], 'python_to_pythonjs.py')],
cmd,
stdin = subprocess.PIPE,
stdout = subprocess.PIPE
)
@@ -68,8 +70,8 @@ def pythonjs_to_javascript( src, closure_compiler=False ):
return a
def python_to_javascript( src, module=None, closure_compiler=False, debug=False ):
a = python_to_pythonjs( src, module=module )
def python_to_javascript( src, module=None, closure_compiler=False, debug=False, global_variable_scope=False ):
a = python_to_pythonjs( src, module=module, global_variable_scope=global_variable_scope )
if debug: print( a )
return pythonjs_to_javascript( a, closure_compiler=closure_compiler )
@@ -146,11 +148,15 @@ def convert_python_html_document( data ):
def regenerate_runtime():
print('regenerating pythonscript runtime...')
global REGENERATE_RUNTIME
REGENERATE_RUNTIME = False
a = '// PythonScript Runtime - regenerated on: %s' %datetime.datetime.now().ctime()
b = pythonjs_to_javascript( open(PATHS['runtime_pythonjs'],'rb').read().decode('utf-8') )
c = python_to_javascript( open(PATHS['runtime_builtins'],'rb').read().decode('utf-8') )
b = pythonjs_to_javascript(
open(PATHS['runtime_pythonjs'],'rb').read().decode('utf-8'),
global_variable_scope = True ## because we are not sure if the old code is compatible with the new style
)
c = python_to_javascript(
open(PATHS['runtime_builtins'],'rb').read().decode('utf-8'),
global_variable_scope = True
)
src = '\n'.join( [a,b.strip(),c.strip()] )
file = open( PATHS['runtime'], 'wb')
file.write( src.encode('utf-8') )
@@ -163,10 +169,7 @@ def get(self, path=None):
if not path:
self.write( get_main_page() )
elif path == 'pythonscript.js':
if REGENERATE_RUNTIME:
data = regenerate_runtime()
else:
data = open( PATHS['runtime'], 'rb').read()
data = open( PATHS['runtime'], 'rb').read()
self.set_header("Content-Type", "text/javascript; charset=utf-8")
self.set_header("Content-Length", len(data))
self.write(data)
@@ -238,13 +241,17 @@ def get(self, path=None):
assert os.path.isdir( PATHS['pythonscript'] )
assert os.path.isdir( PATHS['bindings'] )
app = tornado.web.Application(
Handlers,
#cookie_secret = 'some random text',
#login_url = '/login',
#xsrf_cookies = False,
)
app.listen( 8080 )
tornado.ioloop.IOLoop.instance().start()
if '--regenerate-runtime' in sys.argv:
data = regenerate_runtime()
print(data)
else:
print('running server on localhost:8080')
app = tornado.web.Application(
Handlers,
#cookie_secret = 'some random text',
#login_url = '/login',
#xsrf_cookies = False,
)
app.listen( 8080 )
tornado.ioloop.IOLoop.instance().start()
@@ -0,0 +1,32 @@
<html>
<head>
<script src="pythonscript.js"></script>
<script type="text/python" closure="false">
class A:
def foo(self):
print 'foo'
class B:
def bar(self):
print 'bar'
class C( A, B ):
def call_foo_bar(self):
self.foo()
self.bar()
def test():
c = C()
c.foo()
c.bar()
c.call_foo_bar()
</script>
</head>
<body>
<button onclick="test()">click me</button>
</body>
</html>
@@ -3,46 +3,45 @@
<script src="pythonscript.js"></script>
<script src="libs/three/three.min.js"></script>
<script src="bindings/three.py"></script>
</head>
<body>
<script type="text/python" closure="false">
from three import *
div = document.createElement( 'div' )
document.body.appendChild(div)
def test():
global ren, scn, cam, mesh
width = 640; height = 320
scn = Scene()
cam = PerspectiveCamera( 45, width, height, 0.01, 10000)
cam.position.z = 100
cam.position.x = 5
div = document.createElement( 'div' )
document.body.appendChild(div)
#scn.add( cam )
width = 640; height = 320
scn = Scene()
cam = PerspectiveCamera( 45, width/height, 0.01, 10000)
cam.position.z = 100
cam.position.x = 5
#ren = WebGLRenderer()
ren = CanvasRenderer()
ren.setSize( width, height )
ren.setClearColor( red=0.1, green=0.8, blue=0.5 )
ren = CanvasRenderer()
ren.setSize( width, height )
ren.setClearColor( red=0.1, green=0.8, blue=0.5 )
element = ren.getDomElement()
div.appendChild( element )
div.appendChild( ren.domElement )
geo = CubeGeometry( 10, 10, 10 )
mat = MeshBasicMaterial()
mesh = Mesh( geo, mat )
print 'mesh scale', mesh.scale.x, mesh.scale.y, mesh.scale.z
scn.add( mesh )
geo = CubeGeometry( 10, 10, 10 )
mat = MeshBasicMaterial()
mesh = Mesh( geo, mat )
scn.add( mesh )
def animate():
JS('requestAnimationFrame( animate )')
#scn.updateMatrixWorld()
animate()
def animate():
requestAnimationFrame( animate )
mesh.rotation.x = mesh.rotation.x + 0.01
mesh.rotation.y = mesh.rotation.y + 0.02
ren.render( scn, cam )
</script>
<button onclick="animate()">click me</button>
</head>
<body>
<button onclick="test()">click me</button>
</body>
</html>

0 comments on commit 9ba79e1

Please sign in to comment.