ovccclient-client.vala 4.87 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* 
 * 
 * Copyright (C) 2009-2011 Colomban Wendling <ban@herbesfolles.org>
 *                         Jonathan Michalon <studios.chalmion@no-log.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

21
using OVCC;
22

23
[CCode (cprefix = "OVCCClient", lower_case_cprefix = "ovccclient_")]
24 25
namespace OVCCClient
{
26 27 28
  /**
   * The domain for client errors
   */
29 30
  public errordomain ClientError
  {
31 32 33
    /**
     * The client is already connected to a server
     */
34
    ALREADY_BOUND,
35 36 37
    /**
     * An unknown error occurred
     */
38 39 40
    FAILED
  }

41
  /**
42 43
   * A class representing a client that can connect to a server.
   * Frontends should connect to the signals to know when player should play.
44
   */
45 46
  public class Client : Object
  {
47 48 49
    /**
     * The server this client is bound to, or null if none
     */
50
    public Server server {get; private set; default = null;}
51 52 53
    /**
     * The player this client represents
     */
Jonathan Michalon's avatar
Jonathan Michalon committed
54
    public Player player {get; private set;}
55 56 57
    /**
     * The game on which this client is, or null if none
     */
58
    public Game   game   {get; private set; default = null;}
59 60
    
    private SigQueue sigqueue = new SigQueue ();
61

62 63 64 65 66
    /**
     * A signal emitted when the client should place a tile
     * 
     * @param t The tile to place
     */
67
    public signal void place_tile (Tile t);
68 69 70
    /**
     * A signal emitted when the client should place a pawn
     * 
71
     * @param pos The position where to place the pawn
72
     */
73
    public signal void place_pawn (Position pos);
74

75
    
76
    public Client ()
77
    {
78
      Object ();
79 80
    }

81 82 83
    /**
     * Connects to a server
     * 
84
     * @param s The {@link Server} to connect to
85
     * @param cancellable a Cancellable object or null
86 87
     * @return Whether connection was successful
     */
88 89
    public async bool bind_to (Server       s,
                               Cancellable? cancellable = null)
90
      throws Error
91
    {
92
      if (server != null) {
93
        throw new ClientError.ALREADY_BOUND ("This client is already bound to a server");
94 95 96
      }

      server = s;
97
      debug ("Trying to connect to server...");
98
      yield server.connect_to (cancellable); /* may throw a rejection */
99
      debug ("Connected");
100

101
      return true;
102 103
    }

104 105 106 107 108 109
    /**
     * Disconnects from the server
     * 
     * @return Whether disconnection was perfectly successful (this is not
     *         necessarily important to know)
     */
110
    public bool leave ()
111
      throws ServerError
112
    {
113
      sigqueue.remove_all ();
114 115 116 117

      if (game != null) {
        game.abort ();
      }
118
      if (server.is_connected ()) {
119 120
        server.disconnect_from ();
      }
121 122
      /* destroy server */
      server = null;
123
      game   = null;
124
      player = null;
125

126
      return true;
127
    }
128

129 130 131 132
    /**
     * Logins on the server
     * 
     * @param nick The nick with which log in
133
     * @param password The password with which log in
134
     * @param cancellable a Cancellable object or null
135 136
     * @return whether login succeeded
     */
137
    public async bool login (string       nick,
138
                             string       password = "",
139 140
                             Cancellable? cancellable = null)
      throws ServerError, IOError
141
    {
142
      yield server.login_to (nick, password, cancellable);
Jonathan Michalon's avatar
Jonathan Michalon committed
143

144 145 146 147 148
      player = new Player (nick);

      return true;
    }

149
    /**
150
     * Joins a game asynchronously
151
     * 
152
     * @param index The index of the game to join, -1 means any open game
153
     * @param cancellable a Cancellable object or null
154
     * @return The joined Game
155
     */
156 157
    public async Game join_game (int           index,
                                 Cancellable?  cancellable = null)
158
      throws ServerError, IOError
159
    {
160
      game = yield server.join_game (index, player, cancellable);
161

162
      sigqueue.add (game, game.notify["current-player"].connect (() => {
163
        debug ("Current player changed to \"%s\"", game.current_player.nick);
164
        if (game.current_player == player) {
165 166 167 168
          Idle.add (() => {
            this.place_tile (game.current_tile);
            return false;
          });
169 170 171 172 173
        }
      }));

      sigqueue.add (game.board, game.board.tile_added.connect ((t, p) => {
        if (game.current_player == player) {
174 175 176 177
          Idle.add (() => {
            this.place_pawn (p);
            return false;
          });
178 179
        }
      }));
Jonathan Michalon's avatar
Jonathan Michalon committed
180

181 182
      return game;
    }
183 184
  }
}