src/Network/Object.cc
author terom
Tue, 09 Dec 2008 04:40:05 +0000
changeset 367 5114fbb7ec03
parent 337 ecde18d07879
child 431 c6d7272a164b
permissions -rw-r--r--
fix more optimized-assert errors

#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);
}