/* * RequestManager.h * * Copyright (C) 2008 Matthias Schiffer * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef MAD_COMMON_REQUESTMANAGER_H_ #define MAD_COMMON_REQUESTMANAGER_H_ #include "Request.h" #include #include #include #include namespace Mad { namespace Net { class Packet; } namespace Common { class RequestManager { private: class RequestMap : private std::map { private: // Prevent shallow copy RequestMap(const RequestMap &o); RequestMap& operator=(const RequestMap &o); public: RequestMap() {} ~RequestMap(); bool addRequest(uint16_t id, RequestHandler *info); RequestHandler* findRequest(uint16_t id); bool deleteRequest(uint16_t id); }; class RequestHandlerFactory { protected: RequestHandlerFactory() {} public: virtual RequestHandler* createRequestHandler(Connection *connection, int16_t requestId) = 0; virtual ~RequestHandlerFactory() {} }; template class SpecificRequestHandlerFactory : public RequestHandlerFactory { public: virtual RequestHandler* createRequestHandler(Connection *connection, int16_t requestId) { return new T(connection, requestId); } }; static RequestManager requestManager; std::map requestMaps; bool core; uint16_t lastRequestId; std::map requestHandlerFactories; uint16_t getRequestId() { return lastRequestId+=2; } // Prevent shallow copy RequestManager(const RequestManager &o); RequestManager& operator=(const RequestManager &o); void receiveHandler(Connection *connection, const XmlPacket &packet, uint16_t requestId); RequestMap* getUnusedRequestId(Connection *connection, uint16_t *requestId); bool send(Request *request); RequestManager(); public: static RequestManager* get() { return &requestManager; } bool isCore() const {return core;} void setCore(bool newCore) { core = newCore; if(core) lastRequestId &= ~0x01; else lastRequestId |= 0x01; } void registerConnection(Connection *connection); void unregisterConnection(Connection *connection); template void registerPacketType(const std::string &type) { requestHandlerFactories.insert(std::make_pair(type, new SpecificRequestHandlerFactory())); } void unregisterPacketType(const std::string &type); template bool sendRequest(Connection *connection, Request::slot_type slot) { RequestMap *requestMap; uint16_t requestId; requestMap = getUnusedRequestId(connection, &requestId); if(!requestMap) return false; Request *request = new T(connection, requestId, slot); request->sendRequest(); requestMap->addRequest(requestId, request); return true; } template bool sendRequest(Connection *connection, Request::slot_type slot, T1 t1) { RequestMap *requestMap; uint16_t requestId; requestMap = getUnusedRequestId(connection, &requestId); if(!requestMap) return false; Request *request = new T(connection, requestId, slot, t1); request->sendRequest(); requestMap->addRequest(requestId, request); return true; } template bool sendRequest(Connection *connection, Request::slot_type slot, T1 t1, T2 t2) { RequestMap *requestMap; uint16_t requestId; requestMap = getUnusedRequestId(connection, &requestId); if(!requestMap) return false; Request *request = new T(connection, requestId, slot, t1, t2); request->sendRequest(); requestMap->addRequest(requestId, request); return true; } template bool sendRequest(Connection *connection, Request::slot_type slot, T1 t1, T2 t2, T3 t3) { RequestMap *requestMap; uint16_t requestId; requestMap = getUnusedRequestId(connection, &requestId); if(!requestMap) return false; Request *request = new T(connection, requestId, slot, t1, t2, t3); request->sendRequest(); requestMap->addRequest(requestId, request); return true; } template bool sendRequest(Connection *connection, Request::slot_type slot, T1 t1, T2 t2, T3 t3, T4 t4) { RequestMap *requestMap; uint16_t requestId; requestMap = getUnusedRequestId(connection, &requestId); if(!requestMap) return false; Request *request = new T(connection, requestId, slot, t1, t2, t3, t4); request->sendRequest(); requestMap->addRequest(requestId, request); return true; } virtual ~RequestManager(); }; } } #endif /* MAD_COMMON_REQUESTMANAGER_H_ */