@@ -135,6 +135,7 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe
135135 self ._use_threading = False
136136 self ._use_sleep = False
137137 self ._webworker_functions = dict ()
138+ self ._with_webworker = False
138139
139140 self ._source = source .splitlines ()
140141 self ._classes = dict () ## class name : [method names]
@@ -1672,7 +1673,9 @@ def visit_Call(self, node):
16721673
16731674 name = self .visit (node .func )
16741675 if self ._use_threading and isinstance (node .func , ast .Attribute ) and isinstance (node .func .value , Name ) and node .func .value .id == 'threading' :
1675- if node .func .attr == 'start_new_thread' :
1676+ if node .func .attr == 'start_new_thread' or node .func .attr == '_start_new_thread' :
1677+ return '__start_new_thread( %s, %s )' % (self .visit (node .args [0 ]), self .visit (node .args [1 ]))
1678+ elif node .func .attr == 'start_webworker' :
16761679 return '__start_new_thread( %s, %s )' % (self .visit (node .args [0 ]), self .visit (node .args [1 ]))
16771680 else :
16781681 raise SyntaxError (node .func .attr )
@@ -2120,7 +2123,6 @@ def visit_FunctionDef(self, node):
21202123 log ('function: %s' % node .name )
21212124
21222125 is_worker_entry = False
2123- threaded = False
21242126 property_decorator = None
21252127 decorators = []
21262128 with_js_decorators = []
@@ -2130,6 +2132,11 @@ def visit_FunctionDef(self, node):
21302132 fastdef = False
21312133 javascript = False
21322134 inline = False
2135+ threaded = self ._with_webworker
2136+ jsfile = None
2137+
2138+
2139+ ## deprecated?
21332140 self ._cached_property = None
21342141 self ._func_typedefs = {}
21352142
@@ -2147,25 +2154,6 @@ def visit_FunctionDef(self, node):
21472154 threaded = True
21482155 assert len (decorator .args ) == 1
21492156 jsfile = decorator .args [0 ].s
2150- writer_main .write ('%s = "%s"' % (node .name , jsfile ))
2151- self ._webworker_functions [ node .name ] = jsfile
2152-
2153- writer = get_webworker_writer ( jsfile )
2154- if writer .output .len == 0 :
2155- is_worker_entry = True
2156- ## TODO: two-way list and dict sync
2157- writer .write ('__wargs__ = []' )
2158- writer .write ('def onmessage(e):' )
2159- writer .push ()
2160- writer .write ( 'print("worker got message from parent")' )
2161- writer .write ( 'print(e.data)' )
2162- writer .write ( 'if e.data.type=="execute": %s.apply(self, e.data.args); self.postMessage({"type":"terminate"})' % node .name )
2163- writer .write ( 'elif e.data.type=="append": __wargs__[ e.data.argindex ].push( e.data.value )' )
2164-
2165- writer .write ( 'print(__wargs__)' )
2166-
2167- writer .pull ()
2168- writer .write ('self.onmessage = onmessage' )
21692157
21702158
21712159 elif self ._with_dart :
@@ -2230,6 +2218,30 @@ def visit_FunctionDef(self, node):
22302218 else :
22312219 decorators .append ( decorator )
22322220
2221+
2222+ if threaded :
2223+ if not jsfile : jsfile = 'worker.js'
2224+ writer_main .write ('%s = "%s"' % (node .name , jsfile ))
2225+ self ._webworker_functions [ node .name ] = jsfile
2226+
2227+ writer = get_webworker_writer ( jsfile )
2228+ if writer .output .len == 0 :
2229+ is_worker_entry = True
2230+ ## TODO: two-way list and dict sync
2231+ writer .write ('__wargs__ = []' )
2232+ writer .write ('def onmessage(e):' )
2233+ writer .push ()
2234+ writer .write ( 'print("worker got message from parent")' )
2235+ writer .write ( 'print(e.data)' )
2236+ writer .write ( 'if e.data.type=="execute": %s.apply(self, e.data.args); self.postMessage({"type":"terminate"})' % node .name )
2237+ writer .write ( 'elif e.data.type=="append": __wargs__[ e.data.argindex ].push( e.data.value )' )
2238+
2239+ writer .write ( 'print(__wargs__)' )
2240+
2241+ writer .pull ()
2242+ writer .write ('self.onmessage = onmessage' )
2243+
2244+
22332245 if self ._with_dart :
22342246 ## dart supports optional positional params [x=1, y=2], or optional named {x:1, y:2}
22352247 ## but not both at the same time.
@@ -2435,8 +2447,7 @@ def visit_FunctionDef(self, node):
24352447 ## if sleep() is called or a new webworker is started, the following function body must be wrapped in
24362448 ## a closure callback and called later by setTimeout
24372449 timeouts = []
2438- continues = []
2439- after_while = False
2450+ #continues = []
24402451 for b in node .body :
24412452
24422453 if self ._use_threading and isinstance (b , ast .Assign ) and isinstance (b .value , ast .Call ):
@@ -2447,12 +2458,16 @@ def visit_FunctionDef(self, node):
24472458 writer .write ('def __callback%s():' % len (timeouts ))
24482459 writer .push ()
24492460 ## workerjs for nodejs requires at least 100ms to initalize onmessage/postMessage
2450- timeouts .append (100 )
2461+ timeouts .append (0.2 )
2462+ continue
2463+ elif b .value .func .attr == 'start_webworker' :
2464+ self .visit (b )
2465+ writer .write ('__run__ = True' )
2466+ writer .write ('def __callback%s():' % len (timeouts ))
2467+ writer .push ()
2468+ ## workerjs for nodejs requires at least 100ms to initalize onmessage/postMessage
2469+ timeouts .append (0.2 )
24512470 continue
2452-
2453- elif after_while :
2454- after_while = False
2455-
24562471
24572472 elif self ._use_sleep :
24582473 c = b
@@ -2474,16 +2489,6 @@ def visit_FunctionDef(self, node):
24742489 if isinstance (bb , ast .Call ) and isinstance (bb .func , ast .Name ) and bb .func .id == 'sleep' :
24752490 has_sleep = float (self .visit (bb .args [0 ]))
24762491
2477- #timeouts.append( self.visit(bb.args[0]) )
2478- #continues.append( 'if %s: __run__ = True' %self.visit(b.test)) ## recursive
2479- #continues.append( 'else: __run__ = False')
2480- continue
2481-
2482- else :
2483- #e = self.visit(bb)
2484- #if e: writer.write( e )
2485- pass
2486-
24872492 if has_sleep > 0.0 :
24882493
24892494 #writer.write('__run_while__ = True')
@@ -2505,18 +2510,20 @@ def visit_FunctionDef(self, node):
25052510 writer .write ( 'if %s: __run_while__ = True' % self .visit (b .test ))
25062511 writer .write ( 'else: __run_while__ = False' )
25072512
2508- writer .write ('if __run_while__: setTimeout(__while, %s)' % has_sleep )
2509- writer .write ('elif __continue__: setTimeout(__callback%s, 50 )' % len (timeouts ))
2513+ writer .write ('if __run_while__: setTimeout(__while, %s)' % ( has_sleep ) )
2514+ writer .write ('elif __continue__: setTimeout(__callback%s, 0 )' % len (timeouts ))
25102515
25112516 writer .pull ()
25122517
2513- writer .write ('setTimeout(__while, 1 )' )
2518+ writer .write ('setTimeout(__while, 0 )' )
25142519 writer .write ('__run__ = True' )
25152520 writer .write ('def __callback%s():' % len (timeouts ))
25162521 writer .push ()
25172522 timeouts .append (None )
25182523 continue
25192524
2525+ else :
2526+ self .visit (b )
25202527
25212528 continue
25222529
@@ -2526,19 +2533,13 @@ def visit_FunctionDef(self, node):
25262533
25272534 i = len (timeouts )- 1
25282535 while timeouts :
2529- j = i
2530- #if continues:
2531- # continue_else = continues.pop()
2532- # loop_if = continues.pop()
2533- # writer.write( loop_if )
2534- # writer.write( continue_else )
2535- # j -= 1
2536-
25372536 writer .pull ()
25382537 ms = timeouts .pop ()
25392538 if ms is not None :
2540- writer .write ('if __run__: setTimeout(__callback%s, %s)' % (j , ms ))
2541- writer .write ('elif __continue__: setTimeout(__callback%s, %s)' % (j + 1 , ms ))
2539+ ms = float (ms )
2540+ ms *= 1000
2541+ writer .write ('if __run__: setTimeout(__callback%s, %s)' % (i , ms ))
2542+ writer .write ('elif __continue__: setTimeout(__callback%s, %s)' % (i + 1 , ms ))
25422543 i -= 1
25432544
25442545 if self ._return_type : ## check if a return type was caught
@@ -2905,7 +2906,14 @@ def visit_While(self, node):
29052906 writer .pull ()
29062907
29072908 def visit_With (self , node ):
2908- if isinstance ( node .context_expr , Name ) and node .context_expr .id == 'inline' :
2909+ if isinstance ( node .context_expr , Name ) and node .context_expr .id == 'webworker' :
2910+ self ._with_webworker = True
2911+ for b in node .body :
2912+ a = self .visit (b )
2913+ if a : writer .write (a )
2914+ self ._with_webworker = False
2915+
2916+ elif isinstance ( node .context_expr , Name ) and node .context_expr .id == 'inline' :
29092917 writer .write ('with inline:' )
29102918 writer .push ()
29112919 for b in node .body :
0 commit comments