[gnome-games/sudoku-tube] Have bi-directional communication



commit 16b9416909fa2de075422f24e11811bc5e60b32f
Author: Zhang Sen <zh jesse gmail com>
Date:   Wed Jul 29 10:43:37 2009 +0800

    Have bi-directional communication

 gnome-sudoku/src/lib/main.py       |   51 ++++++++++++++++++++++++++++++++---
 gnome-sudoku/src/lib/model.py      |    4 ++-
 gnome-sudoku/src/lib/networking.py |   31 +++++++++++++++-------
 gnome-sudoku/src/lib/sudoku.py     |    2 +-
 gnome-sudoku/src/lib/view.py       |    4 ++-
 5 files changed, 74 insertions(+), 18 deletions(-)
---
diff --git a/gnome-sudoku/src/lib/main.py b/gnome-sudoku/src/lib/main.py
index 9df6230..61c895c 100644
--- a/gnome-sudoku/src/lib/main.py
+++ b/gnome-sudoku/src/lib/main.py
@@ -55,6 +55,7 @@ class UI (gconf_wrapper.GConfWrapper):
                      }
     _tube_service = 'org.gnome.Sudoku'
     _view_obj_path = "/SideView"
+    _virgin_puzzle_obj_path = "/virgin_puzzle"
 
     def __init__ (self):
         gconf_wrapper.GConfWrapper.__init__(self,
@@ -81,8 +82,13 @@ class UI (gconf_wrapper.GConfWrapper):
         # generate puzzles while our use is working...
         self._run_background_generator()
 
-    def _auto_open_game(self):
-        game = self._auto_load_saved() or self._auto_load_new()
+    def _auto_open_game(self, check_saved=True):
+        game = None
+        if check_saved:
+            game = self._auto_load_saved()
+        if not game:
+            game = self._auto_load_new()
+
         if game:
             self._open_game(*game)
             self._post_open_setup()
@@ -246,7 +252,7 @@ class UI (gconf_wrapper.GConfWrapper):
         side_grid_container.add(self._side_grid_vew)
 
     def _setup_side_view(self):
-        self._side_grid_vew = view.SudokuView(group_size=9)
+        self._side_grid_vew = view.SudokuNumberGrid(group_size=9)
         for x in range(9):
             for y in range(9):
                 self._side_grid_vew.set_readonly_appearance(x, y, True)
@@ -411,12 +417,46 @@ class UI (gconf_wrapper.GConfWrapper):
 
     def _tube_received_cb(self, bus):
         """Called when we receive a tube"""
-        self._tube_open_cb(bus, is_initiator=False)
+        self._bus = bus
+        virgin_puzzle = bus.get_object(object_path=self._virgin_puzzle_obj_path)
+        virgin_puzzle.get_puzzle(
+                dbus_interface="org.gnome.Sudoku.view",
+                reply_handler=self._got_remote_puzzle_cb,
+                error_handler=self._error_cb)
+
+    def _got_remote_puzzle_cb(self, puzzle):
+        logger.info("got puzzle: %s; type: %s" % (puzzle, type(puzzle)))
+        puzzle = str(puzzle)
+        assert len(puzzle) == 81
+        self._close_current_game()
+        self._open_game(game_selector.NewOrSavedGameSelector.NEW_GAME, puzzle)
+        self._init_side_view_display(puzzle)
+        self._tube_open_cb(self._bus, is_initiator=False)
+
+    def _error_cb(self, exception):
+        print 'error', exception
 
     def _tube_offered_cb(self, bus):
         """Called when the peer accepts our tube"""
+        self._close_current_game()
+        # use this flag to ensure we are in a new game, and self._puzzle is a
+        # string. FIXME
+        self._auto_open_game(check_saved=False)
+
+        puzzle = self._puzzle.replace(" ", "") # delete all spaces
+        print 'exporting', puzzle
+        virgin_puzzle = networking.VirginGameString(bus,
+                self._virgin_puzzle_obj_path, puzzle)
+        self._init_side_view_display(puzzle)
         self._tube_open_cb(bus, is_initiator=True)
 
+    def _init_side_view_display(self, puzzle):
+        for x in range(9):
+            for y in range(9):
+                val = int(puzzle[9 * y + x])
+                if val:
+                    self._side_grid_vew.set_value(x, y, val)
+
     def _tube_open_cb(self, bus, is_initiator):
         receiver_view = self._view_obj_path + "/receiver"
         initiator_view = self._view_obj_path + "/initiator"
@@ -429,7 +469,6 @@ class UI (gconf_wrapper.GConfWrapper):
         proxy_of_side_view = networking.SideViewProxy(bus, our_obj_path,
                  self._side_grid_vew)
         logger.info("exported side-view on dbus")
-        self._side_grid_vew.show()
 
         # Then fetch our peer's side-grid-view
         remote_view_proxy = bus.get_object(object_path=peer_obj_path)
@@ -439,6 +478,8 @@ class UI (gconf_wrapper.GConfWrapper):
         view_handler = networking.RemoteViewHandler(remote_view_proxy)
         view_handler.connect_to_model(self._main_model)
 
+        self._side_grid_vew.show()
+
     def _close_current_game (self):
         """Close current running game
 
diff --git a/gnome-sudoku/src/lib/model.py b/gnome-sudoku/src/lib/model.py
index 82dc8fb..515b684 100644
--- a/gnome-sudoku/src/lib/model.py
+++ b/gnome-sudoku/src/lib/model.py
@@ -216,7 +216,9 @@ class SudokuModel:
 
     def _setup_virgin_grid(self, virgin):
         """both grid and initial_grid should be str"""
-        self._virgin_grid = [int(c) for c in virgin.split()]
+        virgin = virgin.replace(" ", "")
+        assert len(virgin) == self.group_size ** 2
+        self._virgin_grid = [int(c) for c in virgin]
         self.grid = sudoku.InteractiveSudoku(virgin, group_size=self.group_size)
 
     def _setup_initial_grid(self, initial_grid):
diff --git a/gnome-sudoku/src/lib/networking.py b/gnome-sudoku/src/lib/networking.py
index e7de6cd..c0d58ef 100644
--- a/gnome-sudoku/src/lib/networking.py
+++ b/gnome-sudoku/src/lib/networking.py
@@ -8,6 +8,21 @@ logger = logging.getLogger("main.network")
 
 view_interface = "org.gnome.Sudoku.view"
 
+class VirginGameString(dbus.service.Object):
+    """Receiver use this to get the game
+    """
+
+    def __init__(self, bus, obj_path, puzzle):
+        """puzzle should be a string
+        """
+        dbus.service.Object.__init__(self, bus, obj_path)
+        self._puzzle = puzzle
+
+    @dbus.service.method(dbus_interface=view_interface,
+            in_signature="", out_signature="s")
+    def get_puzzle(self):
+        return self._puzzle
+
 class SideViewProxy(dbus.service.Object):
     """A dbus object, which exports a sudoku game's side-view on dbus
     """
@@ -51,23 +66,19 @@ class RemoteViewHandler:
             if value is None:
                 pass
             elif value == 0:
-                self._remote_proxy.set_empty(x, y)
+                self._remote_proxy.set_empty(x, y,
+                        reply_handler=self._handle_reply,
+                        error_handler=self._handle_error)
             else:
-                self._remote_proxy.set_invisible(x, y)
+                self._remote_proxy.set_invisible(x, y,
+                        reply_handler=self._handle_reply,
+                        error_handler=self._handle_error)
 
     def puzzle_finished_cb(self):
         self._remote_proxy.puzzle_finished_cb()
 
     def connect_to_model(self, model):
         model.add_observer(self)
-        for x in range(9):
-            for y in range(9):
-                val = model.get_virgin_value(x, y)
-                if val:
-                    self._remote_proxy.set_value(x,y, val,
-                            dbus_interface=view_interface,
-                            reply_handler=self._handle_reply,
-                            error_handler=self._handle_error)
 
     def _handle_reply(*args):
         pass
diff --git a/gnome-sudoku/src/lib/sudoku.py b/gnome-sudoku/src/lib/sudoku.py
index 2488134..d8cabea 100644
--- a/gnome-sudoku/src/lib/sudoku.py
+++ b/gnome-sudoku/src/lib/sudoku.py
@@ -131,7 +131,7 @@ class SudokuGrid:
         self.col_coords = _calc_col_coords(group_size)
         if grid:
             if type(grid) == str:
-                g = re.split("\s+", grid)
+                g = grid.replace(" ", "")
                 side = int(math.sqrt(len(g)))
                 grid = []
                 for row in range(side):
diff --git a/gnome-sudoku/src/lib/view.py b/gnome-sudoku/src/lib/view.py
index ee40add..7cac5a0 100644
--- a/gnome-sudoku/src/lib/view.py
+++ b/gnome-sudoku/src/lib/view.py
@@ -202,6 +202,8 @@ class SudokuNumberGrid (gtk.AspectFrame):
     def get_focus(self):
         return self.table.get_focus_child()
 
+    def set_value(self, x, y, value):
+        self.__entries__[(x, y)].set_value(value)
 
 class SudokuView(SudokuNumberGrid, gobject.GObject):
 
@@ -274,7 +276,7 @@ class SudokuView(SudokuNumberGrid, gobject.GObject):
             tid = self._tracker.get_tracker_by_coord(x, y)
             if tid is not None:
                 self._tracker.remove_from_tracker(tid, x, y)
-        self.__entries__[(x, y)].set_value(value)
+        SudokuNumberGrid.set_value(self, x, y, value)
 
     def _refresh_color(self, x, y, conflict, is_new_value):
         """Set the color according to several rules, conflict/tracker, etc



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]