#include <cassert>
#include "Object.hh"
/*
* NetworkObject_Controller
*/
NetworkObjectController::NetworkObjectController (NetworkSession &session, NetworkChannelID channel_id) :
session(session), channel_id(channel_id) {
// setup signals
slot_message = session.sig_chan_message(channel_id).connect(this, &NetworkObjectController::on_message);
}
void NetworkObjectController::on_message (NetworkPacketInput &pkt, NetworkNode *node) {
uint32_t obj_id = pkt.read_uint32();
uint16_t msg_id = pkt.read_uint16();
// lookup object
NetworkObject *obj = objects[obj_id];
if (obj) {
obj->handle_packet(node, msg_id, pkt);
} else {
handle_create(obj_id, msg_id, pkt, node);
}
}
NetworkObject* NetworkObjectController::read_object (NetworkPacketInput &pkt) {
uint32_t obj_id = pkt.read_uint32();
// lookup object
NetworkObject *obj = obj_id ? objects[obj_id] : NULL;
// return
return obj;
}
void NetworkObjectController::write_object (NetworkPacketOutput &pkt, NetworkObject *obj) {
pkt.write_uint32(obj ? obj->obj_id : 0);
}
/*
* NetworkObject_ServerController
*/
NetworkObject_ServerController::NetworkObject_ServerController (NetworkSession &session, NetworkChannelID channel_id) :
NetworkObjectController(session, channel_id), id_pool(0) {
}
NetworkObjectID NetworkObject_ServerController::getObjectID (void) {
return ++id_pool;
}
void NetworkObject_ServerController::handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacketInput &pkt, NetworkNode *node) {
(void) obj_id;
(void) msg_id;
(void) pkt;
(void) node;
// XXX: fail
throw CL_Error("clients cannot create objects");
}
/*
* NetworkObject_ClientController *
*/
NetworkObject_ClientController::NetworkObject_ClientController (NetworkSession &session, NetworkChannelID channel_id, NetworkNode *server) :
NetworkObjectController(session, channel_id), server(server) {
}
void NetworkObject_ClientController::handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacketInput &pkt, NetworkNode *node) {
// we only communicate with the server
if (node != server)
assert(false);
// create new object
NetworkObject_Client *obj = new NetworkObject_Client(*this, obj_id);
// signal
// XXX: this leaks if it's not handled
_map_sig_create[msg_id](obj, pkt);
}
/*
* NetworkObject
*/
NetworkObject::NetworkObject (NetworkObjectController &controller, NetworkObjectID obj_id) :
controller(controller), obj_id(obj_id) {
assert(obj_id);
controller.objects[obj_id] = this;
}
NetworkObject::~NetworkObject (void) {
controller.objects.erase(obj_id);
}
void NetworkObject::buildPacket (NetworkPacketOutput &pkt, NetworkMessageID msg_id, const NetworkPacketBuffer &payload) {
pkt.write_uint32(obj_id);
pkt.write_uint16(msg_id);
pkt.write_packet(payload);
}
std::ostream& operator<< (std::ostream &s, const NetworkObject &obj) {
return s << "<NetworkObject #" << obj.obj_id << ">";
}
/*
* NetworkObject_Server
*/
NetworkObject_Server::NetworkObject_Server (NetworkObject_ServerController &controller) :
NetworkObject(controller, controller.getObjectID()), controller(controller) {
}
void NetworkObject_Server::handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacketInput &pkt) {
_map_sig_message[msg_id](node, pkt);
}
void NetworkObject_Server::send_to (NetworkNode *dst, NetworkMessageID msg_id, const NetworkPacketBuffer &pkt, bool reliable) {
NetworkPacket pkt_out;
buildPacket(pkt_out, msg_id, pkt);
dst->send(controller.channel_id, pkt_out, reliable);
}
void NetworkObject_Server::send_all (NetworkMessageID msg_id, const NetworkPacketBuffer &pkt, bool reliable) {
send_all_except(msg_id, pkt, NULL, reliable);
}
void NetworkObject_Server::send_all_except (NetworkMessageID msg_id, const NetworkPacketBuffer &pkt, NetworkNode *black_sheep, bool reliable) {
NetworkPacket pkt_out;
buildPacket(pkt_out, msg_id, pkt);
controller.session.send_all_except(controller.channel_id, pkt_out, black_sheep, reliable);
}
/*
* NetworkObject_Client
*/
NetworkObject_Client::NetworkObject_Client (NetworkObject_ClientController &controller, NetworkObjectID id) :
NetworkObject(controller, id), controller(controller) {
// nothing
}
void NetworkObject_Client::handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacketInput &pkt) {
if (node != controller.server)
assert(false);
_map_sig_message[msg_id](pkt);
}
void NetworkObject_Client::send (NetworkMessageID msg_id, const NetworkPacketBuffer &pkt, bool reliable) {
NetworkPacket pkt_out;
buildPacket(pkt_out, msg_id, pkt);
controller.server->send(controller.channel_id, pkt_out, reliable);
}