Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/olpcgames/_gtkmain.py
diff options
context:
space:
mode:
authorManuel Kaufmann <humitos@gmail.com>2012-03-27 13:15:10 (GMT)
committer Rafael Ortiz <rafael@activitycentral.com>2012-03-28 18:05:22 (GMT)
commit335ad73456ba3ec8f56811abddcaca4650199db1 (patch)
treedb788baba57c7656c9bdb73eb9003a70dc87d59a /olpcgames/_gtkmain.py
parent6deeb3f569e6c9a1c02a32a011b7a96a58fa8443 (diff)
Save and restore state of the game
Ability to 'save' (when the user closes the Activity) and 'restore' (when the user launch it from the Journal or the Home without holding Alt) the state of the game. For this ability I had to upgrade 'olpcgames' to 1.6 because 'olpcgames.FILE_READ_REQUEST' and 'olpcgames.FILE_WRITE_REQUEST' events are added in that version and those events are needed for this. The data is saved (as JSON, with json module) in the 'event.metadata["state"]' and the timestamp state is saved in 'event.filename'. This commit solves ticket #2393: * http://bugs.sugarlabs.org/ticket/2393 Signed-off-by: Manuel Kaufmann <humitos@gmail.com> Signed-off-by: Rafael Ortiz <rafael@activitycentral.com>
Diffstat (limited to 'olpcgames/_gtkmain.py')
-rw-r--r--olpcgames/_gtkmain.py70
1 files changed, 70 insertions, 0 deletions
diff --git a/olpcgames/_gtkmain.py b/olpcgames/_gtkmain.py
new file mode 100644
index 0000000..33a6a83
--- /dev/null
+++ b/olpcgames/_gtkmain.py
@@ -0,0 +1,70 @@
+"""Support for GObject mainloop-requiring libraries when not inside GTK
+
+INITIALIZED -- whether we have a running gobject loop yet...
+LOOP_TRACKER -- if present, the manual gtk event loop used to
+ support gobject-based code running in a non-Gobject event loop
+
+Holder -- objects which can be held as attributes to keep the mainloop running
+"""
+import threading, logging
+log = logging.getLogger( 'olpcgames._gtkmain' )
+##log.setLevel( logging.DEBUG )
+
+INITIALIZED = False
+LOOP_TRACKER = None
+
+class _TrackLoop( object ):
+ """Tracks the number of open loops and stops when finished"""
+ count = 0
+ _mainloop = None
+ def increment( self ):
+ log.info( 'Increment from %s', self.count )
+ self.count += 1 # XXX race condition here?
+ if self.count == 1:
+ log.info( 'Creating GObject mainloop')
+ self.t_loop = threading.Thread(target=self.loop)
+ self.t_loop.setDaemon( True )
+ self.t_loop.start()
+ def decrement( self ):
+ log.info( 'Decrement from %s', self.count )
+ self.count -= 1
+ def loop( self ):
+ """Little thread loop that replicates the gtk mainloop"""
+ import gtk
+ while self.count >= 1:
+ log.debug( 'GTK loop restarting' )
+ while gtk.events_pending():
+ gtk.main_iteration()
+ log.debug( 'GTK loop exiting' )
+ try:
+ del self.t_loop
+ except AttributeError, err:
+ pass
+
+class Holder():
+ """Object which, while held, keeps the gtk mainloop running"""
+ def __init__( self ):
+ log.info( 'Beginning hold on GTK mainloop with Holder object' )
+ startGTK()
+ def __del__( self ):
+ log.info( 'Releasing hold on GTK mainloop with Holder object' )
+ stopGTK()
+
+def startGTK( ):
+ """GTK support is required here, process..."""
+ if not INITIALIZED:
+ init()
+ if LOOP_TRACKER:
+ LOOP_TRACKER.increment()
+def stopGTK( ):
+ """GTK support is no longer required, release"""
+ if LOOP_TRACKER:
+ LOOP_TRACKER.decrement()
+def init( ):
+ """Create a gobject mainloop in a sub-thread (you don't need to call this normally)"""
+ global INITIALIZED, LOOP_TRACKER
+ if not INITIALIZED:
+ if not LOOP_TRACKER:
+ LOOP_TRACKER = _TrackLoop()
+ INITIALIZED = True
+ return LOOP_TRACKER