From 73f43b527bdb0650ed7c82b36e367616cffaac36 Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Tue, 26 Apr 2011 12:57:24 +0000 Subject: naive first try... seems to run each thread sequentially or not at all --- diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py index 944b9bf..3d5d290 100644 --- a/TurtleArt/talogo.py +++ b/TurtleArt/talogo.py @@ -22,6 +22,7 @@ #THE SOFTWARE. import gtk +import gobject from time import time from operator import isNumberType @@ -425,16 +426,20 @@ class LogoCode: def doevalstep(self): """ evaluate one step """ + self.tw.event.wait() starttime = _millisecond() try: while (_millisecond() - starttime) < 120: try: if self.step is not None: + self.tw.lock.acquire() self.step.next() + self.tw.lock.release() else: return False except StopIteration: # self.tw.turtles.show_all() + self.tw.lock.release() # Just in case. if self.hidden_turtle is not None: self.hidden_turtle.show() self.hidden_turtle = None diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py index 38565e2..5c78269 100644 --- a/TurtleArt/tawindow.py +++ b/TurtleArt/tawindow.py @@ -22,10 +22,13 @@ #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN #THE SOFTWARE. +from threading import Thread, Lock, Event import pygtk pygtk.require('2.0') import gtk import gobject +gtk.gdk.threads_init() + from gettext import gettext as _ try: @@ -225,6 +228,7 @@ class TurtleArtWindow(): else: Turtle(self.turtles, self.default_turtle_name, mycolors.split(',')) self.active_turtle = self.turtles.get_turtle(self.default_turtle_name) + self.active_turtles = [self.active_turtle] self.saving_svg = False self.svg_string = '' @@ -254,6 +258,10 @@ class TurtleArtWindow(): self._init_plugins() self.lc = LogoCode(self) + self.logo_code = [self.lc, LogoCode(self)] + self.lock = Lock() + self.event = Event() + self.event.clear() from tabasics import Palettes p = Palettes(self) @@ -266,6 +274,18 @@ class TurtleArtWindow(): self.saved_pictures = [] self.block_operation = '' + # TODO: allocate these additional LogoCode instances upon + # encountering start blocks... this is a simple kludge just to + # test two threads + # TODO: copy the object list each time a new LogoCode instance + # is created as per above. + self.logo_code.append(LogoCode(self)) + self.active_turtles.append(Turtle(self.turtles, + self.default_turtle_name)) + for lc in self.logo_code: + if lc != self.lc: + lc.oblist = self.lc.oblist + def _get_plugin_home(self): """ Look in the execution directory """ path = os.path.join(self.path, self._PLUGIN_SUBPATH) @@ -423,24 +443,40 @@ class TurtleArtWindow(): if self.running_sugar: self.activity.recenter() + start_blocks = [] # Look for a 'start' block for blk in self.just_blocks(): if find_start_stack(blk): - self.step_time = time - debug_output("running stack starting from %s" % (blk.name), - self.running_sugar) - self._run_stack(blk) - return + this_start_block = find_top_block(blk) + if not this_start_block in start_blocks: + start_blocks.append(this_start_block) + self.step_time = time + debug_output("running stack starting from %s" % ( + this_start_block.name), self.running_sugar) + i = start_blocks.index(this_start_block) + # TODO: ADD one logo_code instance per start block + # gobject.idle_add(self._run_stack, blk, self.logo_code[i]) + self._run_stack_thread(blk, self.logo_code[i]) + # return # If there is no 'start' block, run stacks that aren't 'def action' - for blk in self.just_blocks(): - if find_block_to_run(blk): - self.step_time = time - debug_output("running stack starting from %s" % (blk.name), - self.running_sugar) - self._run_stack(blk) + if len(start_blocks) == 0: + for blk in self.just_blocks(): + if find_block_to_run(blk): + this_top_block = find_top_block(blk) + if not this_top_block in start_blocks: + start_blocks.append(this_top_block) + self.step_time = time + debug_output("running stack starting from %s" % ( + this_top_block.name), self.running_sugar) + self._run_stack(blk) + else: + self.event.set() return + def _run_stack_thread(self, blk, lc): + Thread(target=self._run_stack, args=(blk, lc)).start() + def stop_button(self): """ Stop button """ self.lc.stop_logo() @@ -939,7 +975,8 @@ class TurtleArtWindow(): self._new_macro(blk.name, x + 20, y + 20) else: # You can only have one instance of some blocks - if blk.name in ['start', 'hat1', 'hat2']: + # if blk.name in ['start', 'hat1', 'hat2']: + if blk.name in ['hat1', 'hat2']: if len(self.block_list.get_similar_blocks( 'block', blk.name)) > 0: self.showlabel('dupstack') @@ -1665,8 +1702,7 @@ class TurtleArtWindow(): dx = 20 blk.expand_in_x(dx) else: - self._run_stack(blk) - return + dx = 0 for gblk in group: if gblk != blk: gblk.spr.move_relative((dx * blk.scale, 0)) @@ -1679,8 +1715,7 @@ class TurtleArtWindow(): dy = 20 blk.expand_in_y(dy) else: - self._run_stack(blk) - return + dy = 0 for gblk in group: if gblk != blk: gblk.spr.move_relative((0, dy * blk.scale)) @@ -1864,18 +1899,22 @@ class TurtleArtWindow(): reset_stack_arm(b) gblk.refresh() - def _run_stack(self, blk): + def _run_stack(self, blk, lc=None): """ Run a stack of blocks. """ + print lc if blk is None: return - self.lc.find_value_blocks() # Are there blocks to update? + if lc is None: + lc = self.lc + lc.find_value_blocks() # Are there blocks to update? self._start_plugins() # Let the plugins know we are running. top = find_top_block(blk) - self.lc.run_blocks(top, self.just_blocks(), True) + self.active_turtle = self.active_turtles[self.logo_code.index(lc)] + lc.run_blocks(top, self.just_blocks(), True) if self.interactive_mode: - gobject.idle_add(self.lc.doevalstep) + gobject.idle_add(lc.doevalstep) else: - while self.lc.doevalstep(): + while lc.doevalstep(): pass def _snap_to_dock(self): -- cgit v0.9.1