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