[Sugar-devel] [PATCH] MEMORIZE patch for saving game state after exit and restoring last game state when the game is opened.

Ariel Calzada ariel.calzada at gmail.com
Fri Sep 14 11:31:41 EDT 2012


From: Ariel Calzada <ariel at activitycentral.com>

---
 activity.py            |   88 +++++++++++++++++++++++++++++++++++++++++-------
 activity/activity.info |    2 +-
 cardlist.py            |    3 +-
 createtoolbar.py       |    3 +-
 game.py                |   13 +++++--
 memorizetoolbar.py     |    5 +--
 model.py               |   12 ++++++-
 7 files changed, 105 insertions(+), 21 deletions(-)

diff --git a/activity.py b/activity.py
index 1fdf8ac..f967976 100644
--- a/activity.py
+++ b/activity.py
@@ -35,9 +35,17 @@ import gtk
 import telepathy
 import telepathy.client
 
-from sugar.activity.widgets import ActivityToolbarButton
-from sugar.activity.widgets import StopButton
-from sugar.graphics.toolbarbox import ToolbarBox
+# Toolbars
+try:
+    from sugar.graphics.toolbarbox import ToolbarBox
+    _have_toolbox = True
+except ImportError:
+    _have_toolbox = False
+
+if _have_toolbox:
+    from sugar.activity.widgets import ActivityToolbarButton
+    from sugar.activity.widgets import StopButton
+
 from sugar.graphics.toggletoolbutton import ToggleToolButton
 from sugar.activity.activity import Activity
 from sugar.presence import presenceservice
@@ -53,6 +61,7 @@ import createtoolbar
 import cardlist
 import createcardpanel
 import face
+import time
 
 SERVICE = 'org.laptop.Memorize'
 IFACE = SERVICE
@@ -79,8 +88,33 @@ class MemorizeActivity(Activity):
         toolbar_box = ToolbarBox()
         self.set_toolbar_box(toolbar_box)
 
-        self.activity_button = ActivityToolbarButton(self)
-        toolbar_box.toolbar.insert(self.activity_button, -1)
+        if _have_toolbox:
+            toolbar_box = ToolbarBox()
+
+            # Activity toolbar
+            activity_button = ActivityToolbarButton(self)
+            toolbar_box.toolbar.insert(activity_button, 0)
+            activity_button.show()
+
+            self.set_toolbar_box(toolbar_box)
+            toolbar_box.show()
+
+            # Save toolbar as attribute
+            self._toolbar = toolbar_box.toolbar
+
+        else:
+            # Use pre-0.86 toolbar design
+            games_toolbar = gtk.Toolbar()
+            toolbar_box = activity.ActivityToolbox(self)
+
+            self.set_toolbox(toolbar_box)
+            toolbar_box.add_toolbar(_('Game'), games_toolbar)
+            toolbar_box.show()
+
+            toolbar_box.set_current_toolbar(1)
+
+            # Save toolbar as attribute
+            self._toolbar = games_toolbar
 
         self._memorizeToolbarBuilder = \
                 memorizetoolbar.MemorizeToolbarBuilder(self)
@@ -95,18 +129,19 @@ class MemorizeActivity(Activity):
         self._createToolbarBuilder = \
             createtoolbar.CreateToolbarBuilder(self)
 
-        separator = gtk.SeparatorToolItem()
-        separator.set_expand(True)
-        separator.set_draw(False)
-        separator.set_size_request(0, -1)
-        toolbar_box.toolbar.insert(separator, -1)
+        if _have_toolbox:
+            separator = gtk.SeparatorToolItem()
+            separator.set_expand(True)
+            separator.set_draw(False)
+            separator.set_size_request(0, -1)
+            self._toolbar.insert(separator, -1)
 
-        toolbar_box.toolbar.insert(StopButton(self), -1)
+            self._toolbar.insert(StopButton(self), -1)
 
         # Play game mode
         self.table = cardtable.CardTable()
         self.scoreboard = scoreboard.Scoreboard()
-        self.cardlist = cardlist.CardList()
+        self.cardlist = cardlist.CardList(self)
         self.createcardpanel = createcardpanel.CreateCardPanel()
         self.cardlist.connect('pair-selected',
                 self.createcardpanel.pair_selected)
@@ -124,7 +159,7 @@ class MemorizeActivity(Activity):
                 self.createcardpanel.clean)
         self._createToolbarBuilder.connect('create_equal_pairs',
                 self.change_equal_pairs)
-        self.game = game.MemorizeGame()
+        self.game = game.MemorizeGame(self)
 
         self._edit_button.connect('toggled', self._change_mode_bt)
 
@@ -207,6 +242,7 @@ class MemorizeActivity(Activity):
             self.game.add_buddy(self.owner)
         else:
             self.game.add_buddy(self.owner)
+
         self.show_all()
 
     def _change_mode_bt(self, button):
@@ -228,12 +264,17 @@ class MemorizeActivity(Activity):
                               self.metadata['title'], color)
 
     def write_file(self, file_path):
+        # Wait for graphics events finish
+        self.flush_events()
         logging.debug('WRITE_FILE is_demo %s', self.game.model.is_demo)
+        # We want to save the game-image for demo games too !!!
+        """
         if self.game.model.is_demo:
             # if is a demo game only want keep the metadata
             self._jobject.set_file_path(None)
             raise NotImplementedError
             return
+        """
         if self.cardlist.pair_list_modified:
             self.cardlist.update_model(self.game.model)
 
@@ -282,6 +323,13 @@ class MemorizeActivity(Activity):
         game_zip.close()
         self.metadata['mime_type'] = 'application/x-memorize-project'
 
+        # Store the game image as a string - that is simpler instead of
+        # having to deal with the dbus-converted list.
+        # When reading back, we use "eval" to convert the string into
+        # the correct type ("list" in this case).
+        self.metadata['saved_game_data_image'] = str(self.game.model.grid)
+        self.metadata['size'] = int(self.game.model.data['size'])
+
     def _complete_close(self):
         self._remove_temp_files()
         Activity._complete_close(self)
@@ -447,3 +495,17 @@ class MemorizeActivity(Activity):
 
     def _cleanup_cb(self, data=None):
         self.game.audio.stop()
+
+    def getToolbarBox(self):
+        """ Get toolbar box
+        """
+        return self._toolbar
+
+    def flush_events(self):
+        """ Wait for graphics events finish
+        """
+        gtk.gdk.threads_enter()
+        while gtk.events_pending():
+            gtk.main_iteration(True)
+        gtk.gdk.flush()
+        gtk.gdk.threads_leave()
diff --git a/activity/activity.info b/activity/activity.info
index b68f210..fde320e 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -3,7 +3,7 @@ name = Memorize
 bundle_id = org.laptop.Memorize
 exec = sugar-activity activity.MemorizeActivity
 icon = activity-memorize
-activity_version = 41
+activity_version = 41.3
 show_launcher = yes
 mime_types = application/x-memorize-project;
 license = GPLv2+
diff --git a/cardlist.py b/cardlist.py
index 6bc781c..65e44f1 100644
--- a/cardlist.py
+++ b/cardlist.py
@@ -40,8 +40,9 @@ class CardList(gtk.EventBox):
         'update-create-toolbar': (SIGNAL_RUN_FIRST, None, 3 * [TYPE_PYOBJECT]),
     }
 
-    def __init__(self):
+    def __init__(self, activity_instance):
         gtk.EventBox.__init__(self)
+        self._activity_instance = activity_instance
         self.pairs = []
         self.current_pair = None
         self.current_game_key = None
diff --git a/createtoolbar.py b/createtoolbar.py
index 49feaf7..91394f8 100644
--- a/createtoolbar.py
+++ b/createtoolbar.py
@@ -40,7 +40,8 @@ class CreateToolbarBuilder(gobject.GObject):
     def __init__(self, activity):
         gobject.GObject.__init__(self)
         self.activity = activity
-        self.toolbar = self.activity.get_toolbar_box().toolbar
+        #self.toolbar = self.activity.get_toolbar_box().toolbar
+        self.toolbar = self.activity.getToolbarBox()
 
         self._equal_pairs = ToggleToolButton('pair-non-equals')
         self._equal_pairs.set_tooltip(_('Match different tiles'))
diff --git a/game.py b/game.py
index 5217f7c..ff90b48 100644
--- a/game.py
+++ b/game.py
@@ -57,7 +57,7 @@ class MemorizeGame(GObject):
         'change-turn': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
         }
 
-    def __init__(self):
+    def __init__(self, activity_instance):
         gobject.GObject.__init__(self)
         self.myself = None
         self.players_score = {}
@@ -70,7 +70,7 @@ class MemorizeGame(GObject):
         self.messenger = None
         self.sentitive = True
 
-        self.model = Model()
+        self.model = Model(activity_instance=activity_instance)
         self.flip_block = False
         self._flop_cards = None
 
@@ -109,6 +109,15 @@ class MemorizeGame(GObject):
         self.change_turn()
         self.model.data['running'] = 'False'
 
+        # Card 'state' is an aawesome field.
+        # Its takes on the following values ::
+        #
+        # 0                              ==>    for flopped cards.
+        #
+        # 1                              ==>    for flipped unmatched cards
+        #                                       (can be a maximum of 1 such card).
+        #
+        # <stroke_color>, <fill_color>   ==>    for flipped matched cards
         for card in self.model.grid:
             if card['state'] == '1':
                 self.emit('flip-card', self.model.grid.index(card), False)
diff --git a/memorizetoolbar.py b/memorizetoolbar.py
index c7e4366..cc28e52 100644
--- a/memorizetoolbar.py
+++ b/memorizetoolbar.py
@@ -52,7 +52,8 @@ class MemorizeToolbarBuilder(gobject.GObject):
     def __init__(self, activity):
         gobject.GObject.__init__(self)
         self.activity = activity
-        self.toolbar = self.activity.get_toolbar_box().toolbar
+        #self.toolbar = self.activity.get_toolbar_box().toolbar
+        self.toolbar = self.activity.getToolbarBox()
         self.jobject = None
 
         # Change demo games button
@@ -126,7 +127,7 @@ class MemorizeToolbarBuilder(gobject.GObject):
         self.emit('game_changed', game_file, game_size, 'demo', title, None)
 
     def update_toolbar(self, widget, data, grid):
-        size = data.get('size')
+        size = str(data.get('size'))
         self._size_combo.combo.handler_block(self.size_handle_id)
         size_index = self._sizes.index(size + ' X ' + size)
         self._size_combo.combo.set_active(int(size_index))
diff --git a/model.py b/model.py
index 2567ed2..16239c4 100644
--- a/model.py
+++ b/model.py
@@ -100,11 +100,13 @@ class Model(object):
     information.
     '''
 
-    def __init__(self, game_path=None):
+    def __init__(self, game_path=None, activity_instance=None):
         tmp_root = join(environ['SUGAR_ACTIVITY_ROOT'], 'instance')
         self.temp_folder = tempfile.mkdtemp(dir=tmp_root)
         chmod(self.temp_folder, 0777)
+        self._saved_game_loaded = False
 
+        self._activity_instance = activity_instance
         self.data = {}
 
         if game_path is None:
@@ -366,6 +368,14 @@ class Model(object):
             temp1.extend(temp2)
             random.shuffle(temp1)
         self.grid = temp1
+
+        if not self._saved_game_loaded:
+            if self._activity_instance is not None:
+                if 'saved_game_data_image' in self._activity_instance.metadata.keys():
+                    self.grid = eval(self._activity_instance.metadata['saved_game_data_image'])
+                    self.data['size'] = int(self._activity_instance.metadata['size'])
+                    self._saved_game_loaded = True
+
         _logger.debug('Defgrid: grid( size=%s ): %s'
                       % (self.data['size'], self.grid))
         _logger.debug('Defgrid: data: %s', self.data)
-- 
1.7.9.5



More information about the Sugar-devel mailing list