On Thu, Jul 17, 2008 at 09:46:16AM +0200, David M. Kaplan wrote:
> I don't think the blocking code will be that hard to maintain.  It
> basically just depends on events, callback functions and time.sleep.  If
> those are cross-platform, then it shouldn't be a problem.  But only time
> will tell.  My ability and desire to test on multiple platforms is
> limited - I use ubuntu/gnome-gtk/linux 100%.

In addition to your patch you can put start/stop_event_loop 
methods into the the canvas.  That way backends can specialize 
their implementation so they don't need a busy loop while waiting
for the event.

Then you can replace the termination notice in BlockingInput:

-            self.done = True
+            self.fig.canvas.stop_event_loop()

and move the busy loop to the backend:

         # wait for n clicks
-        counter = 0
-        while not self.done:
-            self.fig.canvas.flush_events()
-            time.sleep(0.01)
- 
-            # check for a timeout
-            counter += 1
-            if timeout > 0 and counter > timeout/0.01:
-                print "ginput timeout";
-                break;
+        self.fig.canvas.start_event_loop(timeout=timeout)


In backend_bases.py I have a generic interactive version 
based on sleep:

class FigureCanvasBase:
    ...
    def start_event_loop(self, timeout=0):
        """
        Run the event loop.

        This call blocks until an event callback triggers
        stop_event_loop() or the timeout interval is exceeded.
        """
        if timeout == 0: timeout = npy.inf
        timestep = 0.01
        counter = 0
        self._looping = True
        while self._looping and counter*timestep < timeout:
            self.flush_events()
            time.sleep(timestep)
            counter += 1

    def stop_event_loop(self):
        """
        Stop the event loop.

        The function which started the event loop can now run to completion.
        """
        self._looping = False


In the wx canvas this is specialized as:

class FigureCanvasWx(FigureCanvasBase, wx.Panel):
    ...
    def start_event_loop(self, timeout=0):
        """
        Run the event loop.

        This call blocks until an event callback triggers
        stop_event_loop() or the timeout interval is exceeded.
        """
        root = self.GetTopLevelParent()
        bind(root, wx.EVT_CLOSE, self.stop_event_loop)

        id = wx.NewId()
        timer = wx.Timer(self, id=id)
        if timeout > 0:
            timer.Start(timeout*1000, oneShot=True)
            bind(self, wx.EVT_TIMER, self.stop_event_loop, id=id)
        self._event_loop.Run()
        timer.Stop()

    def stop_event_loop(self, event=None):
        """
        Stop the event loop.

        The function which started the event loop can now run to completion.
        """
        if self._event_loop.IsRunning(): 
            self._event_loop.Exit()

# Event binding code changed after version 2.5
if wx.VERSION_STRING >= '2.5':
    def bind(actor,event,action,**kw):
        actor.Bind(event,action,**kw)
else:
    def bind(actor,event,action,id=None):
        if id is not None:
            event(actor, id, action)
        else:
            event(actor,action)


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to