/* * 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 #include namespace Mad { namespace Net { class Packet; } namespace Common { class RequestManager : boost::noncopyable { private: friend class RequestHandler; class RequestMap : private boost::noncopyable { private: typedef std::map > IdMap; typedef std::map > HandlerMap; std::map connectionMap; HandlerMap handlerMap; public: void registerConnection(Connection *connection) { connectionMap.insert(std::make_pair(connection, IdMap())); } void unregisterConnection(Connection *connection); bool isConnectionRegistered(Connection *connection) const { return connectionMap.count(connection); } bool addRequest(Connection *con, boost::uint16_t id, boost::shared_ptr info); boost::shared_ptr findRequest(Connection *con, boost::uint16_t id); void deleteRequest(Connection *con, boost::uint16_t id); std::pair getRequestInfo(const RequestHandler *requestHandler); }; class RequestHandlerFactory { protected: RequestHandlerFactory() {} public: virtual boost::shared_ptr createRequestHandler() = 0; virtual ~RequestHandlerFactory() {} }; template class SpecificRequestHandlerFactory : public RequestHandlerFactory { public: virtual boost::shared_ptr createRequestHandler() { return boost::shared_ptr(new T()); } }; static RequestManager requestManager; boost::shared_mutex mutex; RequestMap requestMap; bool server; boost::uint16_t lastRequestId; std::map > requestHandlerFactories; boost::uint16_t _getRequestId() { return lastRequestId+=2; } void receiveHandler(Connection *connection, boost::shared_ptr packet, boost::uint16_t requestId); void handleRequestFinished(Connection *con, boost::uint16_t requestId) { boost::lock_guard lock(mutex); requestMap.deleteRequest(con, requestId); } boost::uint16_t _getUnusedRequestId(Connection *connection); bool send(Request *request); RequestManager(); public: static RequestManager* get() { return &requestManager; } bool isServer() { boost::shared_lock lock(mutex); return server; } void setServer(bool newServer) { boost::lock_guard lock(mutex); server = newServer; if(server) lastRequestId &= ~0x01; else lastRequestId |= 0x01; } void registerConnection(Connection *connection); void unregisterConnection(Connection *connection) { boost::lock_guard lock(mutex); requestMap.unregisterConnection(connection); } template void registerPacketType(const std::string &type) { boost::lock_guard lock(mutex); requestHandlerFactories.insert(std::make_pair(type, boost::shared_ptr >(new SpecificRequestHandlerFactory()))); } void unregisterPacketType(const std::string &type) { boost::lock_guard lock(mutex); requestHandlerFactories.erase(type); } bool sendRequest(Connection *connection, boost::shared_ptr request); }; } } #endif /* MAD_COMMON_REQUESTMANAGER_H_ */