[gnome-chess/chess-telepathy-networking-support-664946-communicate: 9/10] Communicate over tubes: correction::Export ChessPlayer objects on DBus::Abstract out constructor_hel



commit d8ab26d0d06ba8ba78356c2013f90d44a4c3921a
Author: Chandni Verma <chandniverma2112 gmail com>
Date:   Fri Dec 28 08:48:08 2012 +0530

    Communicate over tubes: correction::Export ChessPlayer objects on DBus::Abstract out constructor_helper and add contructor ChessState.with_players

 src/Makefile.am                          |    1 +
 src/chess-game.vala                      |   90 ++++++++++++++++++---------
 src/gnome-chess-handler-application.vala |  100 +++++++++++++++++++++++++++---
 src/test-chess-game.vala                 |    4 +-
 4 files changed, 155 insertions(+), 40 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 8102394..ce6bd3a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -64,6 +64,7 @@ test_chess_game_LDADD = \
 	$(TEST_LIBS)
 test_chess_game_VALAFLAGS = \
     --pkg gobject-2.0 \
+    --pkg gio-2.0 \
     --pkg posix
 
 test_chess_pgn_SOURCES = \
diff --git a/src/chess-game.vala b/src/chess-game.vala
index 2f0f8c9..146054a 100644
--- a/src/chess-game.vala
+++ b/src/chess-game.vala
@@ -4,34 +4,34 @@ public enum Color
     BLACK
 }
 
+/* Client interface for RemoteChessPlayer on DBusConnection */
 [DBus (name = "org.gnome.Chess.ChessPlayer")]
+public interface RemoteChessPlayerIface : Object {
+    public signal bool do_move_remote (string move, bool apply);
+    public abstract bool resign () throws GLib.IOError;
+    public abstract bool claim_draw () throws GLib.IOError;
+}
+
+/* This is exported as server by offerer and accepter */
 public class ChessPlayer : Object
 {
-    [DBus (visible = false)]
-    public Color color;
-    [DBus (visible = false)]
+    public Color color {get; construct;}
     public signal void start_turn ();
     public signal bool do_move (string move, bool apply);
-    [DBus (visible = false)]
     public signal void do_undo ();
-    [DBus (visible = false)]
     public signal bool do_resign ();
-    [DBus (visible = false)]
     public signal bool do_claim_draw ();
 
-    [DBus (visible = false)]
     public ChessPlayer (Color color)
     {
-        this.color = color;
+        Object (color : color);
     }
 
-    [DBus (visible = false)]
     public bool move (string move, bool apply = true)
     {
         return do_move (move, apply);
     }
 
-    [DBus (visible = false)]
     public bool move_with_coords (int r0, int f0, int r1, int f1,
         bool apply = true, PieceType promotion_type = PieceType.QUEEN)
     {
@@ -58,7 +58,6 @@ public class ChessPlayer : Object
         return do_move (move, apply);
     }
 
-    [DBus (visible = false)]
     public void undo ()
     {
         do_undo ();
@@ -75,6 +74,16 @@ public class ChessPlayer : Object
     }
 }
 
+/* This gets exported on DBusConnection */
+[DBus (name = "org.gnome.Chess.ChessPlayer")]
+public class RemoteChessPlayer : ChessPlayer, RemoteChessPlayerIface
+{
+    public RemoteChessPlayer (Color color)
+    {
+        base (color);
+    }
+}
+
 public enum PieceType
 {
     PAWN,
@@ -301,24 +310,19 @@ public class ChessState
     {
     }
 
-    public ChessState.with_players (ChessPlayer white, ChessPlayer black, string fen)
-    {
-        players[Color.WHITE] = white;
-        players[Color.BLACK] = black;
-
-        constructor_helper (fen);
-    }
-
-    public ChessState (string fen)
+    public ChessState (ChessPlayer? white, ChessPlayer? black, string fen)
     {
-        players[Color.WHITE] = new ChessPlayer (Color.WHITE);
-        players[Color.BLACK] = new ChessPlayer (Color.BLACK);
-
-        constructor_helper (fen);
-    }
+        if (white != null && black != null)
+        {
+            players[Color.WHITE] = white;
+            players[Color.BLACK] = black;
+        }
+        else
+        {
+            players[Color.WHITE] = new ChessPlayer (Color.WHITE);
+            players[Color.BLACK] = new ChessPlayer (Color.BLACK);
+        }
 
-    private void constructor_helper (string fen)
-    {
         for (int i = 0; i < 64; i++)
             board[i] = null;
 
@@ -1227,6 +1231,9 @@ public class ChessGame : Object
     public ChessResult result;
     public ChessRule rule;
     public List<ChessState> move_stack;
+    /* For setting remote players to be used */
+    private ChessPlayer _white;
+    private ChessPlayer _black;
     
     private int hold_count = 0;
 
@@ -1246,10 +1253,18 @@ public class ChessGame : Object
     public ChessPlayer white
     {
         get { return current_state.players[Color.WHITE]; }
+        set
+        {
+          _white = value;
+        }
     }
     public ChessPlayer black
     {
         get { return current_state.players[Color.BLACK]; }
+        set
+        {
+          _black = value;
+        }
     }
     public ChessPlayer current_player
     {
@@ -1271,10 +1286,13 @@ public class ChessGame : Object
         }
     }
 
-    public ChessGame (string fen = STANDARD_SETUP, string[]? moves = null)
+    public ChessGame (string fen = STANDARD_SETUP, string[]? moves = null, ChessPlayer? white = null, ChessPlayer? black = null)
     {
+        Object (white : white, black : black);
         is_started = false;
-        move_stack.prepend (new ChessState (fen));
+
+        ChessState first_state = new ChessState (white, black, fen);
+        move_stack.prepend (first_state);
         result = ChessResult.IN_PROGRESS;
 
         if (moves != null)
@@ -1294,6 +1312,12 @@ public class ChessGame : Object
         black.do_undo.connect (undo_cb);
         black.do_resign.connect (resign_cb);
         black.do_claim_draw.connect (claim_draw_cb);
+        /* Connect to remote player's moves */
+        if (white is RemoteChessPlayerIface && black is RemoteChessPlayerIface)
+        {
+            (white as RemoteChessPlayerIface).do_move_remote.connect (remote_move_cb);
+            (black as RemoteChessPlayerIface).do_move_remote.connect (remote_move_cb);
+        }
     }
 
     private bool move_cb (ChessPlayer player, string move, bool apply)
@@ -1304,6 +1328,14 @@ public class ChessGame : Object
         return do_move (player, move, apply);
     }
 
+    private bool remote_move_cb (RemoteChessPlayerIface player, string move, bool apply)
+    {
+        if (!is_started)
+            return false;
+
+        return do_move ((ChessPlayer) player, move, apply);
+    }
+
     private bool do_move (ChessPlayer player, string? move, bool apply)
     {
         if (player != current_player)
diff --git a/src/gnome-chess-handler-application.vala b/src/gnome-chess-handler-application.vala
index e8a58d8..52680af 100644
--- a/src/gnome-chess-handler-application.vala
+++ b/src/gnome-chess-handler-application.vala
@@ -537,9 +537,53 @@ public class HandlerApplication : Application
         chess_view.queue_draw ();
     }
 
-    private void create_and_add_game (TelepathyGLib.DBusTubeChannel tube,
+    private void fetch_players (DBusConnection conn,
+        TelepathyGLib.DBusTubeChannel tube,
         Gtk.TreeIter channel_iter)
     {
+        RemoteChessPlayer white, black;
+        white = black = null;
+
+        /* Asynchronously fetch player objects from connection. Create game once both are in hand */
+
+        conn.get_proxy<RemoteChessPlayerIface>.begin (TelepathyGLib.CLIENT_BUS_NAME_BASE + "Gnome.Chess", "/org/freedesktop/Telepathy/Client/Gnome/Chess/ChessPlayer/White", DBusProxyFlags.DO_NOT_AUTO_START, null,
+            (obj, res)=>{
+
+                try {
+                    white = (RemoteChessPlayer) conn.get_proxy<RemoteChessPlayerIface>.end (res);
+
+                    if (white != null && black != null)
+                        create_and_add_game (tube, channel_iter, white, black);
+                }
+                catch (IOError e)
+                {
+                   debug ("couldn't fetch the white player: %s\n", e.message);
+                }
+              }
+            );
+
+        conn.get_proxy<RemoteChessPlayerIface>.begin (TelepathyGLib.CLIENT_BUS_NAME_BASE + "Gnome.Chess", "/org/freedesktop/Telepathy/Client/Gnome/Chess/ChessPlayer/Black", DBusProxyFlags.DO_NOT_AUTO_START, null,
+            (obj, res)=>{
+
+                try {
+                    black = (RemoteChessPlayer) conn.get_proxy<RemoteChessPlayerIface>.end (res);
+
+                    if (white != null && black != null)
+                        create_and_add_game (tube, channel_iter, white, black);
+                }
+                catch (IOError e)
+                {
+                   debug ("couldn't fetch the black player: %s\n", e.message);
+                }
+              }
+            );
+    }
+
+    private void create_and_add_game (TelepathyGLib.DBusTubeChannel tube,
+        Gtk.TreeIter channel_iter,
+        RemoteChessPlayerIface white,
+        RemoteChessPlayerIface black)
+    {
         /* Create a new game with the offered parameters */
         Variant tube_params = tube.dup_parameters_vardict ();
         bool offerer_white, our_color_white;
@@ -580,7 +624,8 @@ public class HandlerApplication : Application
             else
                 warning ("Chess game has SetUp tag but no FEN tag");
         }
-        var game = new ChessGame (fen, moves);
+
+        var game = new ChessGame (fen, moves, (ChessPlayer) white, (ChessPlayer) black);
         (game as Object).set_data<PGNGame> ("pgn-game", pgn_game);
         (game as Object).set_data<string> ("channel-path-string", channels.get_string_from_iter (channel_iter));
         /* Associate history_model for access in scene_changed_cb */
@@ -669,7 +714,8 @@ public class HandlerApplication : Application
 
     private void register_objects (DBusConnection connection,
         TelepathyGLib.DBusTubeChannel tube,
-        Gtk.TreeIter channel_iter)
+        Gtk.TreeIter channel_iter,
+        string side)
     {
         debug ("Registering objects over dbus connection");
 
@@ -677,12 +723,43 @@ public class HandlerApplication : Application
         channels  get (channel_iter, ChannelsColumn.CHESS_GAME, out game);
 
         Variant tube_params = tube.dup_parameters_vardict ();
-        bool play_as_white = (tube_params.lookup_value ("offerer-white", VariantType.BOOLEAN)).get_boolean ();
+        bool offerer_white = (tube_params.lookup_value ("offerer-white", VariantType.BOOLEAN)).get_boolean ();
+
+        bool play_as_white;
         ChessPlayer my_player;
-        my_player = play_as_white ? game.white : game.black;
+        if (side == "offerer")
+        {
+            if (offerer_white)
+            {
+                my_player = game.white;
+                play_as_white = true;
+            }
+            else
+            {
+                my_player = game.black;
+                play_as_white = false;
+            }
+        }
+        else
+        {
+            if (offerer_white)
+            {
+                my_player = game.black;
+                play_as_white = false;
+            }
+            else
+            {
+                my_player = game.white;
+                play_as_white = true;
+            }
+        }
 
         try {
-            connection.register_object<ChessPlayer> ("/org/freedesktop/Telepathy/Client/Gnome/Chess/ChessPlayer", my_player);
+            if (play_as_white)
+                connection.register_object<RemoteChessPlayer> ("/org/freedesktop/Telepathy/Client/Gnome/Chess/ChessPlayer/White", (RemoteChessPlayer) my_player);
+            else
+                connection.register_object<RemoteChessPlayer> ("/org/freedesktop/Telepathy/Client/Gnome/Chess/ChessPlayer/Black", (RemoteChessPlayer) my_player);
+
             debug ("ChessPlayer registered successfully");
         } catch (IOError e) {
             debug ("Could not register ChessPlayer object");
@@ -736,8 +813,10 @@ public class HandlerApplication : Application
                             TelepathyGLib.Channel).target_contact.identifier);
                     }
                 );
-                create_and_add_game (tube, channel_iter);
-                register_objects (connection, tube, channel_iter);
+
+                /* First load player objects. Then wait on them for creating ChessGame */
+                register_objects (connection, tube, channel_iter, "offerer");
+                fetch_players (connection, tube, channel_iter);
 
                 /* Now we can display the game */
                 channels  set (channel_iter, ChannelsColumn.CHANNEL_APPROVED, true);
@@ -788,7 +867,10 @@ public class HandlerApplication : Application
                             TelepathyGLib.Channel).target_contact.identifier);
                     }
                 );
-                create_and_add_game (tube, channel_iter);
+
+                /* First load player objects. Then wait on them for creating ChessGame */
+                register_objects (connection, tube, channel_iter, "accepter");
+                fetch_players (connection, tube, channel_iter);
 
                 /* We can now display the game */
                 channels  set (channel_iter, ChannelsColumn.CHANNEL_APPROVED, true);
diff --git a/src/test-chess-game.vala b/src/test-chess-game.vala
index 1e68ae0..9ae18e1 100644
--- a/src/test-chess-game.vala
+++ b/src/test-chess-game.vala
@@ -7,7 +7,7 @@ class GlChess
                                         ChessResult result = ChessResult.IN_PROGRESS,
                                         ChessRule rule = ChessRule.CHECKMATE)
     {
-        ChessState state = new ChessState (fen);
+        ChessState state = new ChessState (null, null, fen);
         test_count++;
         if (!state.move (move))
         {
@@ -44,7 +44,7 @@ class GlChess
 
     private static void test_bad_move (string fen, string move)
     {
-        ChessState state = new ChessState (fen);
+        ChessState state = new ChessState (null, null, fen);
         test_count++;
         if (state.move (move, false))
         {



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