Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | Related Pages | Examples

clientframework.h

00001 /***************************************************************************
00002  * The contents of this file are subject to the Mozilla Public             *
00003  * License Version 1.1 (the "License"); you may not use this file          *
00004  * except in compliance with the License. You may obtain a copy of         *
00005  * the License at http://www.mozilla.org/MPL/                              *
00006  *                                                                         *
00007  * Software distributed under the License is distributed on an "AS         *
00008  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or              *
00009  * implied. See the License for the specific language governing            *
00010  * rights and limitations under the License.                               *
00011  *                                                                         *
00012  * The Original Code is Game Network Framework (GaNeF).                    *
00013  *                                                                         *
00014  * The Initial Developers of the Original Code are                         *
00015  * Lars Langer and Emanuel Greisen                                         *
00016  * Copyright (C) 2005. Lars Langer & Emanuel Greisen                       *
00017  * All Rights Reserved.                                                    *
00018  *                                                                         *
00019  * Contributor(s):                                                         *
00020  *   none yet....                                                          *
00021  *                                                                         *
00022  ***************************************************************************/
00023 #ifndef CLIENTFRAMEWORK_H
00024 #define CLIENTFRAMEWORK_H
00025 
00026 #include <ptypes.h>
00027 
00028 #include <map>
00029 #include <vector>
00030 
00031 #include "../common/framework.h"
00032 #include "../common/frameworkseqnolist.h"
00033 #include "../common/averagetimecalculator.h"
00034 #include "../common/frameworkpacket.h"
00035 #include "clientpacket.h"
00036 #include "clientdatamap.h"
00037 
00038 class ClientData;
00039 
00040 /// @example testclient/testclientframework.h
00041 
00042 /**
00043  * @ingroup Client
00044  * @brief This class is the framework on the client.
00045  * With sender, reciever, pending-ack-list and all client data.
00046  * This is the class you must inherit from on the client side of your game.
00047  *
00048  * @author Lars Langer and Emanuel Greisen
00049  */
00050 class ClientFramework : public Framework<ClientPacket,ipmessage>
00051 {
00052 friend class ClientData;
00053 //friend class ServerData;
00054 
00055 public:
00056    enum ClientState
00057    {
00058       ///Framework initialized, but not started
00059       NOT_STARTED                    = 1000,
00060       ///Handshaking initilized
00061       HANDSHAKING_INIT               = 3001,
00062       ///Handshaking was aborted by the server
00063       HANDSHAKING_ABORTED_BY_SERVER  = 3002,
00064       ///Handshaking was aborted by the server
00065       HANDSHAKING_ABORTED_BY_CLIENT  = 3003,
00066       ///Client and server in agreement - client connected
00067       CONNECTED                      = 4000,
00068       ///Now we are disconnected (but we were connected before)
00069       DISCONNECTED                   = 5000
00070    };
00071 
00072 private:
00073    ClientDataMap * client_data_map;
00074    ipaddress server_host;
00075    int server_port;
00076    int local_port;
00077    FrameworkSeqNoList<ClientPacket,ipmessage> sequencenumbers;
00078    std::map<unsigned int, ClientData *> client_data;
00079    std::map<unsigned int, Plugin<ClientPacket> *> plugins;
00080    std::map<unsigned int, ClientData* (*)(ClientFramework *, ClientPacket *) > constructors;
00081    AverageTimeCalculator<16> avg_rtt;
00082    /// Told by the server, telling us how often we should at least heartbeat.
00083    unsigned int connection_timeout_length;
00084    unsigned int last_reliable_sent_packet_time;
00085    unsigned int last_received_pack;
00086 
00087    bool onConnectCalled;
00088    bool onDisconnectCalled;
00089    unsigned int nextExpectedSequenceNumber;
00090    ClientState state;
00091 
00092 
00093 public:
00094    ClientFramework(int local_port);
00095    ~ClientFramework();
00096 
00097 public:
00098    ///This method starts the listning and receiving sockets of the framework. It also starts the handshaking session between the client framwork and the server
00099    void initServerConnection(const std::string & _server_host, int _server_port);
00100    /// This method will stop both the sender and the receiver if they are started, and clean out the queues.
00101    void terminateServerConnection();
00102    //static ipaddress getHostFromName(const std::string &hostname);
00103 
00104 private:
00105    virtual void registerData(ClientData *data);
00106    bool checkPlugin( unsigned int plug_id );
00107    void handleSystemPacket(ClientPacket * p);
00108    void heartBeat();
00109    void disconnectionCleanup();
00110 
00111 public:
00112    virtual void unregisterData( ClientData *data );
00113    /// This method will return a pointer to a ClientData object (or null if the object does not exist on the client).
00114    ClientData * getDataObject(unsigned int objid);
00115    /// This method will add to the pointer-pointer-table-thingy a missing pointer.
00116    void registerPointer(unsigned int receiver, unsigned int missing, ClientData **ptrptr);
00117    /// This method will deletea pointer from the pointer-pointer-table
00118    bool unregisterPointer(unsigned int receiver, unsigned int objid, ClientData **ptrptr);
00119    /// This method will register a constructor-method with a class-id.
00120    void registerConstructor(unsigned int class_id, ClientData * (*func)(ClientFramework *, ClientPacket *));
00121    /// Will register a plugin in the framework, plugins are used to "unpack" packets created with the same plugin on the server side (example: compression).
00122    void registerPlugin(Plugin<ClientPacket> * plugin);
00123    /// This will handle any incomming packets, along with other keep-alive-stuff.
00124    void keepAlive(unsigned int sleepmillis = 0);
00125    /// This method tests if a packet is in order, and if not buffer the packet
00126    /// for later delivery.
00127    virtual bool isPacketReadyForDelivery(ClientPacket * packet);
00128    /// This method will deliver the packet and return any buffered packets,
00129    /// waiting for this packet.
00130    virtual ClientPacket * deliverPacket(ClientPacket * p);
00131    /// This will return the next sequence number for the outgoing packet, and increment it also.
00132    unsigned int getNextUnreliablePacketSeqNumber(ClientPacket * packet);
00133    /// Called when we want to insert a pending ack into the pendingackist.
00134    virtual void addPendingAck(ClientPacket * packet, bool haslock);
00135    /// This method will be called by the sender when ever it successfully sends a
00136    /// reliable packet to the socket, we will register the time.
00137    virtual void sentReliablePacket(ClientPacket * packet);
00138    /// This method enqueues a packet.
00139    void enqueuePacket(ClientPacket * p, bool sendnow=false);
00140    /// This method will return the current state of the client;
00141    ClientState getState() const { return state; };
00142    /// This method will return a complete list of ClientData objects registered in the framework.
00143    inline const std::map<unsigned int, ClientData *> & getClientDataObjects() const { return client_data; };
00144    /// Just a debug method.
00145    void printPointerPointerMapDebug( ) const { client_data_map->printDebug(); };
00146 
00147 
00148 public:
00149    /// Will be called by the pendingacklist when ever we want to retransmit a packet
00150    virtual void retransmitPacket(FrameworkPacket * packet);
00151 
00152 protected: // These must be implemented in a derived class
00153    /// This method is called just before a connection attempt,
00154    /// you can write any gamespecific data in the packet for the server to read.
00155    virtual void writeHandshakeInitMessage(ClientPacket * fp) = 0;
00156    /// If the server will not let you connect, you can read what ever was written to you.
00157    virtual void onHandshakingDiscontinue(ClientPacket * fp) = 0;
00158    /// If the server will let you connect, then here is the packet from the server,
00159    /// and you can reply in the other packet.
00160    virtual bool onHandshakeDescription(ClientPacket * fp, ClientPacket * reply) = 0;
00161    /// Will be called during "keepAlive(...)" if the client has lost the connection
00162    /// to the server.
00163    virtual void onDisconnect() = 0;
00164    /// Will be called during "keepAlive(...)" if the client has successfully
00165    /// connected to the server.
00166    virtual void onConnect() = 0;
00167    /// This method should add a sequence number to the pluginpacket if it does not already have one.
00168    virtual void addPluginSequenceNumber( ClientPacket * packet);
00169 
00170 public:
00171    unsigned long bytesReceived() const;
00172    unsigned long packetsReceived() const;
00173    unsigned long packetsDelivered() const;
00174    unsigned long getSkippedUnreliablePackets() const;
00175    unsigned long getSkippedReliablePackets() const;
00176    unsigned long bytesSent() const;
00177    unsigned long packetsSent() const;
00178    unsigned long inQueueSize() const;
00179    unsigned long outQueueSize() const;
00180    unsigned long getPendingAckCount() const;
00181    /// Returns total count of packets buffered due to deliver-in-order
00182    unsigned int bufferedPackets() const;
00183 
00184 };
00185 
00186 #endif

Generated on Mon Feb 6 12:24:50 2006 for Ganef by  doxygen 1.4.4