[gnome-games/sudoku-tube] Close network game when the peer closes



commit fb2e760d5cc06485799ae25a8c62c689ec561b79
Author: Zhang Sen <zh jesse gmail com>
Date:   Sun Aug 2 10:16:16 2009 +0800

    Close network game when the peer closes

 gnome-sudoku/src/lib/main.py         |   46 +++++++++++++++++++++++----------
 gnome-sudoku/src/lib/tp_tube.py      |    8 +----
 gnome-sudoku/src/lib/tube_handler.py |   16 +++++++----
 gnome-sudoku/src/lib/view.py         |   15 +++++++++++
 4 files changed, 59 insertions(+), 26 deletions(-)
---
diff --git a/gnome-sudoku/src/lib/main.py b/gnome-sudoku/src/lib/main.py
index 61c895c..7d0388b 100644
--- a/gnome-sudoku/src/lib/main.py
+++ b/gnome-sudoku/src/lib/main.py
@@ -66,10 +66,13 @@ class UI (gconf_wrapper.GConfWrapper):
         self._main_model = None
         self._main_grid_vew = None
         self._history_manager = None
+        self._tube = None
+
         self.setup_gui()
 
         self.tube_handler = tube_handler.TubeHandler(self._tube_service,
-                callback=self._tube_received_cb)
+                tube_received_cb=self._tube_received_cb,
+                tube_closed_cb=self._tube_closed_cb)
 
         self.timer = timer.ActiveTimer(self.w)
         self.won = False
@@ -248,15 +251,10 @@ class UI (gconf_wrapper.GConfWrapper):
         self._tracker_ui.hide()
         tracker_ui_container.pack_start(self._tracker_ui)
 
-        self._setup_side_view()
+        self._side_grid_vew = view.SudokuSideView(group_size=9)
+        self._side_grid_vew.hide()
         side_grid_container.add(self._side_grid_vew)
 
-    def _setup_side_view(self):
-        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)
-        self._side_grid_vew.hide()
 
     def setup_color (self):
         # setup background colors
@@ -408,16 +406,19 @@ class UI (gconf_wrapper.GConfWrapper):
     def _new_with_contact_cb(self, action):
         choice = contact_selector.contact_selector_run(self.w)
         if choice:
-            logger.info("selected: %s\nconnection: %s\nhandle: %d" % (
-                    choice[2].alias, choice[0].service_name, choice[1]))
-            tp_tube.offer_tube(choice[0], choice[1], self._tube_service,
-                    self._tube_offered_cb)
+            conn, handle, contact = choice
+            logger.info("selected: %s\n  connection: %s\n  handle: %d" % (
+                    contact.alias, conn.service_name, handle))
+            tp_tube.offer_tube(conn, handle, self._tube_service,
+                    tube_offered_cb=self._tube_offered_cb,
+                    tube_closed_cb=self._tube_closed_cb)
         else:
             logger.info("None selected")
 
-    def _tube_received_cb(self, bus):
+    def _tube_received_cb(self, bus, tube):
         """Called when we receive a tube"""
         self._bus = bus
+        self._tube = tube
         virgin_puzzle = bus.get_object(object_path=self._virgin_puzzle_obj_path)
         virgin_puzzle.get_puzzle(
                 dbus_interface="org.gnome.Sudoku.view",
@@ -436,9 +437,10 @@ class UI (gconf_wrapper.GConfWrapper):
     def _error_cb(self, exception):
         print 'error', exception
 
-    def _tube_offered_cb(self, bus):
+    def _tube_offered_cb(self, bus, tube):
         """Called when the peer accepts our tube"""
         self._close_current_game()
+        self._tube = tube
         # 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)
@@ -511,8 +513,24 @@ class UI (gconf_wrapper.GConfWrapper):
         self.gconf['width'] = event.width
         self.gconf['height'] = event.height
 
+    def _tube_closed_cb(self):
+        logger.info("tube has been closed")
+        self._side_grid_vew.reset()
+        self._side_grid_vew.hide()
+        self._tube = None
+
+    def _stop_network_game(self):
+        logger.info("close tube-channel")
+        self._tube[tp_tube.CHANNEL_INTERFACE].Close()
+        self._side_grid_vew.reset()
+        self._side_grid_vew.hide()
+        self._tube = None
+
     def quit_cb (self, *args):
         self.w.hide()
+        if self._tube:
+            self._stop_network_game()
+
         if self._should_save():
             self._save_game()
         # make sure we really go away before doing our saving --
diff --git a/gnome-sudoku/src/lib/tp_tube.py b/gnome-sudoku/src/lib/tp_tube.py
index 83b8868..557008a 100644
--- a/gnome-sudoku/src/lib/tp_tube.py
+++ b/gnome-sudoku/src/lib/tp_tube.py
@@ -19,16 +19,12 @@ import telepathy.errors
 logger = logging.getLogger("main.tp_tube")
 
 
-def tube_closed_cb():
-    logger.info("tube closed")
-
-
-def offer_tube(conn, handle, tube_service, tube_open_cb):
+def offer_tube(conn, handle, tube_service, tube_offered_cb, tube_closed_cb):
     def tube_state_changed_cb(state):
         if state == TUBE_CHANNEL_STATE_OPEN:
             logger.info("Tube state changed ->open")
             tube_conn = dbus.connection.Connection(address)
-            tube_open_cb(bus=tube_conn)
+            tube_offered_cb(bus=tube_conn, tube=chan)
         elif state == TUBE_CHANNEL_STATE_REMOTE_PENDING:
             logger.info("Tube state changed ->remote-pending")
         else:
diff --git a/gnome-sudoku/src/lib/tube_handler.py b/gnome-sudoku/src/lib/tube_handler.py
index d5850bf..e39996d 100644
--- a/gnome-sudoku/src/lib/tube_handler.py
+++ b/gnome-sudoku/src/lib/tube_handler.py
@@ -12,6 +12,7 @@ from telepathy.constants import (
         TUBE_STATE_OPEN,
         SOCKET_ACCESS_CONTROL_CREDENTIALS)
 from telepathy.interfaces import (
+        CHANNEL_INTERFACE,
         CHANNEL_INTERFACE_TUBE,
         CHANNEL_TYPE_DBUS_TUBE)
 
@@ -31,9 +32,10 @@ def _build_object_path(bus_name):
 class TubeHandler(dbus.service.Object):
     """Listen to coming tube and emit a signal for it"""
 
-    def __init__(self, service_name, callback):
+    def __init__(self, service_name, tube_received_cb, tube_closed_cb):
         logger.info("creating TubeHandler")
-        self._tube_received_cb = callback
+        self._tube_received_cb = tube_received_cb
+        self._tube_closed_cb = tube_closed_cb
 
         bus_name = _build_bus_name(service_name)
         obj_path = _build_object_path(bus_name)
@@ -51,18 +53,20 @@ class TubeHandler(dbus.service.Object):
         """Called when we are offered a tube"""
         logger.info("Tube received on %s" % channel)
         conn = Connection(bus_name, connection)
-        chan = Channel(bus_name, channel)
+        self._tube_chan = Channel(bus_name, channel)
 
-        self.address = chan[CHANNEL_TYPE_DBUS_TUBE].Accept(
+        self.address = self._tube_chan[CHANNEL_TYPE_DBUS_TUBE].Accept(
                 SOCKET_ACCESS_CONTROL_CREDENTIALS)
-        chan[CHANNEL_INTERFACE_TUBE].connect_to_signal(
+        self._tube_chan[CHANNEL_INTERFACE_TUBE].connect_to_signal(
                 'TubeChannelStateChanged', self._tube_state_changed_cb)
+        self._tube_chan[CHANNEL_INTERFACE].connect_to_signal(
+                'Closed', self._tube_closed_cb)
 
     def _tube_state_changed_cb(self, state):
         if state == TUBE_STATE_OPEN:
             logger.info("Tube state changed ->open")
             tube_conn = dbus.connection.Connection(self.address)
 
-            self._tube_received_cb(tube_conn)
+            self._tube_received_cb(tube_conn, self._tube_chan)
         else:
             logger.info("Tube state changed ->%s" % state)
diff --git a/gnome-sudoku/src/lib/view.py b/gnome-sudoku/src/lib/view.py
index 7cac5a0..a081fa3 100644
--- a/gnome-sudoku/src/lib/view.py
+++ b/gnome-sudoku/src/lib/view.py
@@ -205,6 +205,9 @@ class SudokuNumberGrid (gtk.AspectFrame):
     def set_value(self, x, y, value):
         self.__entries__[(x, y)].set_value(value)
 
+    def reset(self):
+        pass
+
 class SudokuView(SudokuNumberGrid, gobject.GObject):
 
     # some signals to give notice about change of the View
@@ -419,3 +422,15 @@ class SudokuView(SudokuNumberGrid, gobject.GObject):
 
     def get_trackers_tracking(self):
         return self._tracker.get_trackers_tracking()
+
+class SudokuSideView(SudokuNumberGrid):
+    def __init__(self, group_size):
+        SudokuNumberGrid.__init__(self, group_size)
+        for x in range(self.group_size):
+            for y in range(self.group_size):
+                self.set_readonly_appearance(x, y, True)
+
+    def reset(self):
+        for x in range(self.group_size):
+            for y in range(self.group_size):
+                self.set_value(x, y, 0)



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