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

Gonzalo Odiard gonzalo at laptop.org
Mon Sep 17 09:08:36 EDT 2012


Hi Ariel,
This patch mix many changes, not only what the title say.
Please prepare a patch only with the code needed to implement this,
and I will review it.
If you want propose other changes, send it in different patches.
Thanks

Gonzalo

On Fri, Sep 14, 2012 at 12:31 PM, Ariel Calzada <ariel.calzada at gmail.com>wrote:

> 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sugarlabs.org/archive/sugar-devel/attachments/20120917/47f46788/attachment-0001.html>


More information about the Sugar-devel mailing list