How is network-game started

The following entries are of the format that, first the user behavior is specified, then how to implement it.

User choose 'New with contacts'

  • Add new button 'New with contacts'. Minor work.
  • Related callback, say new_with_contact_cb.

A list of contacts is shown

  • new_with_contact acquires a list of contacts from Telepathy's connection manager.

  • Filter the list, contacts should be online, etc.
  • Add a dialog to display this.

User chooses contact. Press 'OK'

  • If the player is already in a game, which is_changed(), then he is asked whether to save the game, via a popped-up dialog. Save game or not per user's reply. Close current game.

  • Send request (OfferDBusTube) to the selected contact.
  • Pop up dialog showing 'Cancel request'.

User can also drag somebody from Empathy to sudoku

  • Same as the above User chooses contact step.

  • Implement drag-n-drop. This and the above step can use a same method, like connect_to_contact(contact_name, conn_manager, blah). The above step gets arguments from the list-of-contact, and this step gets arguments from drag-n-drop.

  • Priority is to get it working. So I will first implement the easier of alternative solutions and get to the other in the end of summer (if possible).

Initiator waits for reply. Receiver gets a new message in Empathy

  • Empathy can't handle it (e.g. an older sudoku doesn't have the .service file). Then a 'denied' message is reported to the initiator.
  • Sudoku is launched according to the .service file. Something like,

    $ cat /usr/share/dbus-1/services/org.gnome.Empathy.DTubeHandler.GnomeSudoku.service 
    [D-BUS Service]
    Name=org.gnome.Empathy.DTubeHandler.GnomeSudoku
    Exec=/usr/bin/gnome-sudoku
  • Version capability:
    1. Use .service (whether exists) to identify old version sudokus.
    2. Use Tubes' parameters to identify between different kinds of sudokus, if in the future we add other kinds of puzzles (16x16, jigsaw)

Sudoku is launched

  • If receiver doesn't already have sudoku open (i.e. DBus can't find proper tube handler), it will be launched automatically by DBus, by installing a .service file.
    • sudoku will be always launched if it's not running when the offer comes, even though the user may not like to accept it. One possible solution is to add a special option to sudoku, say '--process-tube-offer', which will simply pop up a dialog to let the user make choice and will afterward launch the 'real' sudoku, or not, per the user's decision.
  • When sudoku is launched, it create a tube handler on DBus. So when a tube is offered, the associated callback is called.
  • If multiple sudoku is launched, only the first one can create tube handler. So only it will get the tube offer.
    • And we can also make it that only one sudoku can run at one time. Anyway, several concurrent sudoku tend to conflict (e.g. saving games).
  • The callback will close existing game if one is open.
  • Then the offered DBusTube is accepted and state changes from 'local pending' to 'open'.
  • For the initiator it changes from 'remote pending' to 'open'.

Both players enter new game. Game is initialized

  • Initiator exports its logical puzzle on DBus. Receiver gets the puzzle.
    • Sudoku should be refactored that, we define an interface for sudoku logic, which can receive requests to update the logic and emits signals per the result of the request.
    • On the number boxes, user input (like key_release_even/button_press_event) is sent as request to the logic interfaces.
    • The 9x9 grid listens for signals from the logic, like conflict_error (which instructs the GUI to display red color).
  • (Both games) creates its main_logic object from the puzzle.

  • Bind the main grid on this main_logic.

  • The receiver also exports its main_logic.

  • Both games connect (to DBus) to each other's main_logic, and bind its little side-grid to it. (Or first create a logic-puzzle object from the other's main_logic if necessary).

  • In other words, a player has a logic puzzle, whose signal will be heard by both the player's main-grid, and the other player's side-grid.

In game

  • Say A is the initiator, and B receiver; a is A's shadow, and b is B's.

  • When A changes some fields, the change is applied on the underlying logical puzzle

  • The logic sends a signal.
  • This signal is combined with A's main grid (the GUI), thus causing the main grid to be updated.

  • This signal is also sent to DBus, which is forwarded to A's shadow object a (the logic).

  • The shadow object (which is on B's machine) is updated.

  • The little second grid, which listens on the shadow object, is updated. Thus we realize the target that one player sees the actions of the other.
  • The initiator is like,

       1 class logic_puzzle:
       2     def set_value (self, x, y, value): # user filling a number will first update the logical puzzle
       3         # update logic
       4         self.emit("puzzle-changed", x, y, val, conflicts)
       5 
       6 class number_box:
       7     def key_release_event_cb():
       8         self.logic.set_value(x, y, value)
       9 
      10 class gui_main_grid:
      11     self.logic.connect("puzzle-changed", update_gui)
      12 
      13 class tp_connection (dbus.service.Object):
      14     self.logic.connect("puzzle-changed", value_changed_signal)
      15 
      16     @dbus.service.signal(SUDOKU_INTERFACE)
      17     def value_changed_signal (self, x, y, value):
      18     '''send signal to DBus, which should be received remotely by the other player'''
      19         pass
    
  • The receiver is like,

       1 class gui_shadow_grid:
       2     self.shadow_logic = logic_puzzle()
       3     self.shadow_logic.connect("puzzle-changed", update_gui)
       4 
       5 class tp_connection (dbus.service.Object):
       6     self.connect_to_signal("puzzle-changed", self.shadow_logic.set_value)
    
  • Although the initiator and receiver is specified separately above, they will appear in one game in reality, since sudoku should be either initiator or receiver.
  • This requires some refactoring of the current sudoku code, i.e. the logic_puzzle and gui_main_grid.


Project Home Page

ZhangSen/GSoC2009/StartGame (last edited 2009-05-15 15:17:34 by ZhangSen)