--- a/src/Network/Object.hh Mon Dec 08 16:14:23 2008 +0000
+++ b/src/Network/Object.hh Mon Dec 08 16:23:30 2008 +0000
@@ -7,7 +7,14 @@
#include <map>
+/**
+ * A NetworkObject's ID is a 32-bit integer
+ */
typedef uint32_t NetworkObjectID;
+
+/**
+ * A NetworkObject's message type is a 16-bit integer
+ */
typedef uint16_t NetworkMessageID;
// forward-declare
@@ -15,32 +22,65 @@
class NetworkObject_Client;
class NetworkObject_Server;
+/**
+ * A NetworkObjectController contains a mapping of NetworkObjectID -> NetworkObject, and handles the
+ * messages received on our channel from the NetworkSession.
+ *
+ * Additionally, this provides methods to read/write NetworkObject references from/to a NetworkPacket
+ */
class NetworkObjectController {
friend class NetworkObject;
friend class NetworkObject_Server;
friend class NetworkObject_Client;
private:
+ /**
+ * The NetworkSession that we use
+ */
NetworkSession &session;
+
+ /**
+ * The NetworkChannelID that we use to communicate
+ */
NetworkChannelID channel_id;
-
+
+ /**
+ * Our map of NetworkObjectID -> NetworkObject
+ */
std::map<NetworkObjectID, NetworkObject*> objects;
-
+
CL_Slot slot_message;
protected:
+ /**
+ * Construct a NetworkObjectController to use the given NetworkSession and NetworkChannelID
+ */
NetworkObjectController (NetworkSession &session, NetworkChannelID channel_id);
private:
+ /**
+ * Our NetworkSession::sig_chan_message handler
+ *
+ * Reads the NetworkObjectID and NetworkMessageID from the packet, and then either calls handle_create or
+ * NetworkObject::handle_packet.
+ */
void on_message (NetworkPacketInput &pkt, NetworkNode *node);
protected:
+ /**
+ * Abstract method called by on_message if we recieve a message for an unknown NetworkObjectID
+ *
+ * @param obj_id the unknown NetworkObjectID
+ * @param msg_id the packet's NetworkMessageID
+ * @param pkt the packet itself, with the header read
+ * @param node the node that we got this packet from
+ */
virtual void handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacketInput &pkt, NetworkNode *node) = 0;
public:
/**
* Read an NetworkObjectID from the given packet, and return the corresponding NetworkObject, or NULL if we
- * don't know it
+ * don't know it.
*/
NetworkObject* read_object (NetworkPacketInput &pkt);
@@ -50,94 +90,251 @@
void write_object (NetworkPacketOutput &pkt, NetworkObject *obj);
};
+/**
+ * A NetworkObjectController intended for use with a server.
+ *
+ * This has an id_pool that new NetworkObjectIDs can be generated from, and this doesn't accept unknown
+ * NetworkObjectIDs from clients.
+ */
class NetworkObject_ServerController : public NetworkObjectController {
friend class NetworkObject_Server;
private:
+ /**
+ * The id_pool that we use to generate NetworkObjectIDs for new NetworkObject's
+ */
NetworkObjectID id_pool;
public:
+ /**
+ * @see NetworkObjectController
+ */
NetworkObject_ServerController (NetworkSession &session, NetworkChannelID channel_id);
protected:
+ /**
+ * Get a new NetworkObjectID
+ */
NetworkObjectID getObjectID (void);
-
+
+ /**
+ * Throw an error, as we don't accept unknown NetworkObjects from clients
+ */
virtual void handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacketInput &pkt, NetworkNode *node);
};
+/**
+ * A NetworkObjectController intended for use with a client.
+ *
+ * This provides two ways to handle unknown objects: override handle_create, or use sig_create
+ */
class NetworkObject_ClientController : public NetworkObjectController {
friend class NetworkObject_Client;
- private:
+ protected:
+ /**
+ * The server node, as returned by NetworkSession::connect
+ */
NetworkNode *server;
-
+
+ /**
+ * A mapping of NetworkMessageID -> sig_create, used by the default handle_create
+ */
std::map<NetworkMessageID, CL_Signal_v2<NetworkObject_Client*, NetworkPacketInput&> > _map_sig_create;
public:
+ /**
+ * Construct a NetworkObjectController using the given NetworkNode (as returned by NetworkSession::connect) as
+ * a server.
+ *
+ * @see NetworkObjectController
+ */
NetworkObject_ClientController (NetworkSession &session, NetworkChannelID channel_id, NetworkNode *server);
protected:
+ /**
+ * Handle unknown NetworkObjectIDs by constructing a new NetworkObject_Client and calling sig_create.
+ *
+ * This can be overriden to handle this differently, e.g. to create an instance of a NetworkObject_Client
+ * subclass instead.
+ */
virtual void handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacketInput &pkt, NetworkNode *node);
public:
+ /**
+ * Signal triggered by default handle_create when we get a message for an unknown NetworkObject.
+ * The signal gets the new NetworkObject_Client, and the packet itself.
+ *
+ * @param msg_id the NetworkMessageID to handle creates for
+ */
CL_Signal_v2<NetworkObject_Client*, NetworkPacketInput&>& sig_create (NetworkMessageID msg_id) { return _map_sig_create[msg_id]; }
};
+/**
+ * Base class of NetworkObject_(Client/Server)
+ *
+ * A NetworkObject has an NetworkObjectID, and can handle packets to/from this object
+ */
class NetworkObject {
friend class NetworkObjectController;
friend std::ostream& operator<< (std::ostream &s, const NetworkObject &obj);
protected:
+ /**
+ * This object's object id
+ */
NetworkObjectID obj_id;
protected:
+ /**
+ * Construct a NetworkObject using the given controller and object id
+ *
+ * @param controller the NetworkObjectController (subclass)
+ * @param obj_id our NetworkObjectID
+ */
NetworkObject (NetworkObjectController &controller, NetworkObjectID obj_id);
+ /**
+ * Abstract method to handle packets sent to this object
+ *
+ * @param node the NetworkNode that sent this packet to us
+ * @param msg_id the packet's NetworkMessageID
+ * @param pkt the packet itself, with the headers read
+ */
virtual void handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacketInput &pkt) = 0;
-
+
+ /**
+ * Prepare an outgoing packet, writing the header and the payload
+ *
+ * @param pkt the packet to prepare
+ * @param msg_id the packet's message id
+ * @param payload the packet's payload
+ */
void buildPacket (NetworkPacketOutput &pkt, NetworkMessageID msg_id, const NetworkPacketBuffer &payload);
};
+/**
+ * Formats the object as "<NetworkObject #" <obj_id> ">"
+ */
std::ostream& operator<< (std::ostream &s, const NetworkObject &obj);
+/**
+ * A server-side NetworkObject
+ */
class NetworkObject_Server : public NetworkObject {
friend class NetworkObject_ServerController;
- private:
+ protected:
+ /**
+ * The NetworkObject_ServerController
+ */
NetworkObject_ServerController &controller;
-
+
+ /**
+ * Mapping of NetworkMessageID -> sig_message used for received messages
+ */
std::map<NetworkMessageID, CL_Signal_v2<NetworkNode*, NetworkPacketInput&> > _map_sig_message;
public:
+ /**
+ * @see NetworkObject
+ */
NetworkObject_Server (NetworkObject_ServerController &controller);
protected:
+ /**
+ * Handle an incoming packet by invoking the appopriate sig_message
+ *
+ * @see NetworkObject::handlePacket
+ */
virtual void handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacketInput &pkt);
public:
+ /**
+ * Send a message on this object to the given node
+ *
+ * @param dst the NetworkNode to send the message to
+ * @param msg_id the type of message to send
+ * @param pkt the packet payload
+ * @param reliable Whether to use TCP or UDP
+ */
void send_to (NetworkNode *dst, NetworkMessageID msg_id, const NetworkPacketBuffer &pkt, bool reliable = true);
+
+ /**
+ * Send a message on this object to all nodes on our controller's NetworkSession
+ *
+ * @param msg_id the type of message to send
+ * @param pkt the packet payload
+ * @param reliable Whether to use TCP or UDP
+ */
void send_all (NetworkMessageID msg_id, const NetworkPacketBuffer &pkt, bool reliable = true);
+
+ /**
+ * Send a message on this object to all nodes on our controller's NetworkSession, except the given node
+ *
+ * @param msg_id the type of message to send
+ * @param pkt the packet payload
+ * @param black_sheep the node to *NOT* send the message to
+ * @param reliable Whether to use TCP or UDP
+ */
void send_all_except (NetworkMessageID msg_id, const NetworkPacketBuffer &pkt, NetworkNode *black_sheep, bool reliable = true);
-
+
+ /**
+ * Triggered whenever we receive a message of the given type on this object, giving the node that sent it and the
+ * packet itself
+ *
+ * @param msg_id the NetworkMessageID to handle
+ */
CL_Signal_v2<NetworkNode*, NetworkPacketInput&>& sig_message (NetworkMessageID msg_id) { return _map_sig_message[msg_id]; }
};
+/**
+ * A client-side NetworkObject
+ */
class NetworkObject_Client : public NetworkObject {
friend class NetworkObject_ClientController;
- private:
+ protected:
+ /**
+ * Our NetworkObject_ClientController
+ */
NetworkObject_ClientController &controller;
-
+
+ /**
+ * Our mapping of NetworkMessageID -> sig_message, used to handle received packets
+ */
std::map<NetworkMessageID, CL_Signal_v1<NetworkPacketInput&> > _map_sig_message;
protected:
+ /**
+ * @see NetworkObject
+ */
NetworkObject_Client (NetworkObject_ClientController &controller, NetworkObjectID id);
+ /**
+ * Handle an incoming packet by invoking the appropriate sig_message.
+ *
+ * This assumes that packets only come from the server
+ *
+ * @see NetworkObject::handlePacket
+ */
virtual void handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacketInput &pkt);
public:
+ /**
+ * Send a message on this object to the server
+ *
+ * @param msg_id the type of message to send
+ * @param pkt the packet payload
+ * @param reliable Whether to use TCP or UDP
+ */
void send (NetworkMessageID msg_id, const NetworkPacketBuffer &pkt, bool reliable = true);
+ /**
+ * Triggered whenever we receive a message of the given type on this object from the server.
+ *
+ * @param msg_id the NetworkMessageID to handle
+ */
CL_Signal_v1<NetworkPacketInput&>& sig_message (NetworkMessageID msg_id) { return _map_sig_message[msg_id]; }
};