diff --git a/src/karts/controller/local_player_controller.cpp b/src/karts/controller/local_player_controller.cpp index f5132bcec..27ef87122 100644 --- a/src/karts/controller/local_player_controller.cpp +++ b/src/karts/controller/local_player_controller.cpp @@ -161,7 +161,7 @@ bool LocalPlayerController::action(PlayerAction action, int value, NetworkConfig::get()->isClient() && !RewindManager::get()->isRewinding() ) { - GameProtocol::getInstance() + GameProtocol::lock() ->controllerAction(m_kart->getWorldKartId(), action, value, m_steer_val_l, m_steer_val_r); diff --git a/src/modes/world_status.cpp b/src/modes/world_status.cpp index 71e43add8..0659771d1 100644 --- a/src/modes/world_status.cpp +++ b/src/modes/world_status.cpp @@ -262,8 +262,7 @@ void WorldStatus::updateTime(const float dt) if (!m_server_is_ready) return; m_phase = READY_PHASE; - Protocol *p = LobbyProtocol::get(); - ClientLobby *cl = dynamic_cast(p); + auto cl = LobbyProtocol::get(); if (cl) cl->startingRaceNow(); return; // Don't increase time diff --git a/src/network/network_console.cpp b/src/network/network_console.cpp index 9f673ed81..3b419766a 100644 --- a/src/network/network_console.cpp +++ b/src/network/network_console.cpp @@ -78,23 +78,19 @@ void* NetworkConsole::mainLoop(void* data) } else if (str == "start" && NetworkConfig::get()->isServer()) { - ServerLobby* protocol = - dynamic_cast(LobbyProtocol::get()); - protocol->signalRaceStartToClients(); + auto sl = LobbyProtocol::get(); + sl->signalRaceStartToClients(); } else if (str == "selection" && NetworkConfig::get()->isServer()) { - ServerLobby* protocol = - dynamic_cast(LobbyProtocol::get()); - protocol->startSelection(); + auto sl = LobbyProtocol::get(); + sl->startSelection(); } else if (str == "select" && NetworkConfig::get()->isClient()) { std::string str2; getline(std::cin, str2); - ServerLobby* protocol = - dynamic_cast(LobbyProtocol::get()); - ClientLobby* clrp = dynamic_cast(protocol); + auto clrp = LobbyProtocol::get(); std::vector players = STKHost::get()->getMyPlayerProfiles(); // For now send a vote for each local player @@ -109,9 +105,7 @@ void* NetworkConsole::mainLoop(void* data) std::cout << "Vote for ? (track/laps/reversed/major/minor/race#) :"; std::string str2; getline(std::cin, str2); - LobbyProtocol* protocol = LobbyProtocol::get(); - ClientLobby* clrp = - dynamic_cast(protocol); + auto clrp = LobbyProtocol::get(); std::vector players = STKHost::get()->getMyPlayerProfiles(); if (str2 == "track") @@ -164,14 +158,13 @@ void* NetworkConsole::mainLoop(void* data) } } // while !stop - Protocol *p = new StopServer(); + auto p = std::make_shared(); + p->requestStart(); while(p->getState() != PROTOCOL_STATE_TERMINATED) { StkTime::sleep(1); } - delete p; - main_loop->abort(); return NULL; diff --git a/src/network/protocol.cpp b/src/network/protocol.cpp index 29d54192e..0f9a7a068 100644 --- a/src/network/protocol.cpp +++ b/src/network/protocol.cpp @@ -79,7 +79,7 @@ bool Protocol::checkDataSize(Event* event, unsigned int minimum_size) */ void Protocol::requestStart() { - ProtocolManager::lock()->requestStart(this); + ProtocolManager::lock()->requestStart(shared_from_this()); } // requestStart // ---------------------------------------------------------------------------- @@ -87,7 +87,7 @@ void Protocol::requestStart() */ void Protocol::requestPause() { - ProtocolManager::lock()->requestPause(this); + ProtocolManager::lock()->requestPause(shared_from_this()); } // requestPause // ---------------------------------------------------------------------------- @@ -95,7 +95,7 @@ void Protocol::requestPause() */ void Protocol::requestUnpause() { - ProtocolManager::lock()->requestUnpause(this); + ProtocolManager::lock()->requestUnpause(shared_from_this()); } // requestUnpause // ---------------------------------------------------------------------------- @@ -103,7 +103,7 @@ void Protocol::requestUnpause() */ void Protocol::requestTerminate() { - ProtocolManager::lock()->requestTerminate(this); + ProtocolManager::lock()->requestTerminate(shared_from_this()); } // requestTerminate // ---------------------------------------------------------------------------- diff --git a/src/network/protocol.hpp b/src/network/protocol.hpp index f962cfe2c..0f3d0794e 100644 --- a/src/network/protocol.hpp +++ b/src/network/protocol.hpp @@ -27,6 +27,7 @@ #include "utils/no_copy.hpp" #include "utils/types.hpp" +#include #include class Event; @@ -90,7 +91,8 @@ public: * to make any network job. * \ingroup network */ -class Protocol : public NoCopy +class Protocol : public std::enable_shared_from_this, + public NoCopy { LEAK_CHECK() protected: diff --git a/src/network/protocol_manager.cpp b/src/network/protocol_manager.cpp index f1b2c025b..507415222 100644 --- a/src/network/protocol_manager.cpp +++ b/src/network/protocol_manager.cpp @@ -99,8 +99,6 @@ ProtocolManager::~ProtocolManager() // ---------------------------------------------------------------------------- void ProtocolManager::OneProtocolType::abort() { - for (unsigned int i = 0; i < m_protocols.getData().size(); i++) - delete m_protocols.getData()[i]; m_protocols.getData().clear(); } // OneProtocolType::abort @@ -143,7 +141,7 @@ void ProtocolManager::propagateEvent(Event* event) * \param protocol : A pointer to the protocol to start * \return The unique id of the protocol that is being started. */ -void ProtocolManager::requestStart(Protocol* protocol) +void ProtocolManager::requestStart(std::shared_ptr protocol) { // create the request ProtocolRequest req(PROTOCOL_REQUEST_START, protocol); @@ -159,7 +157,7 @@ void ProtocolManager::requestStart(Protocol* protocol) * thread-safe. * \param protocol : A pointer to the protocol to pause */ -void ProtocolManager::requestPause(Protocol* protocol) +void ProtocolManager::requestPause(std::shared_ptr protocol) { if (!protocol) return; @@ -177,12 +175,12 @@ void ProtocolManager::requestPause(Protocol* protocol) * thread-safe. * \param protocol : A pointer to the protocol to unpause */ -void ProtocolManager::requestUnpause(Protocol* protocol) +void ProtocolManager::requestUnpause(std::shared_ptr protocol) { if (!protocol) return; // create the request - ProtocolRequest req(PROTOCOL_REQUEST_UNPAUSE, protocol);; + ProtocolRequest req(PROTOCOL_REQUEST_UNPAUSE, protocol); // add it to the request stack m_requests.lock(); m_requests.getData().push_back(req); @@ -195,7 +193,7 @@ void ProtocolManager::requestUnpause(Protocol* protocol) * thread-safe. * \param protocol : A pointer to the protocol that is finished */ -void ProtocolManager::requestTerminate(Protocol* protocol) +void ProtocolManager::requestTerminate(std::shared_ptr protocol) { if (!protocol) return; @@ -222,7 +220,7 @@ void ProtocolManager::requestTerminate(Protocol* protocol) * Add the protocol info to the m_protocols vector. * \param protocol : ProtocolInfo to start. */ -void ProtocolManager::startProtocol(Protocol *protocol) +void ProtocolManager::startProtocol(std::shared_ptr protocol) { assert(std::this_thread::get_id() == m_asynchronous_update_thread.get_id()); OneProtocolType &opt = m_all_protocols[protocol->getProtocolType()]; @@ -242,7 +240,7 @@ void ProtocolManager::startProtocol(Protocol *protocol) * Pauses a protocol and tells it that it's being paused. * \param protocol : Protocol to pause. */ -void ProtocolManager::pauseProtocol(Protocol *protocol) +void ProtocolManager::pauseProtocol(std::shared_ptr protocol) { assert(std::this_thread::get_id() == m_asynchronous_update_thread.get_id()); assert(protocol->getState() == PROTOCOL_STATE_RUNNING); @@ -259,7 +257,7 @@ void ProtocolManager::pauseProtocol(Protocol *protocol) * Unpauses a protocol and notifies it. * \param protocol : Protocol to unpause. */ -void ProtocolManager::unpauseProtocol(Protocol *protocol) +void ProtocolManager::unpauseProtocol(std::shared_ptr protocol) { assert(std::this_thread::get_id() == m_asynchronous_update_thread.get_id()); assert(protocol->getState() == PROTOCOL_STATE_PAUSED); @@ -274,10 +272,9 @@ void ProtocolManager::unpauseProtocol(Protocol *protocol) * Note that the protocol is not deleted. * \param p The protocol to be removed. */ -void ProtocolManager::OneProtocolType::removeProtocol(Protocol *p) +void ProtocolManager::OneProtocolType::removeProtocol(std::shared_ptr p) { - std::vector::iterator i = - std::find(m_protocols.getData().begin(), + auto i = std::find(m_protocols.getData().begin(), m_protocols.getData().end(), p); if (i == m_protocols.getData().end()) { @@ -296,7 +293,7 @@ void ProtocolManager::OneProtocolType::removeProtocol(Protocol *p) * Remove a protocol from the protocols vector. * \param protocol : Protocol concerned. */ -void ProtocolManager::terminateProtocol(Protocol *protocol) +void ProtocolManager::terminateProtocol(std::shared_ptr protocol) { assert(std::this_thread::get_id() == m_asynchronous_update_thread.get_id()); @@ -551,7 +548,7 @@ void ProtocolManager::asynchronousUpdate() * \param type : The type of the protocol. * \return The protocol that matches the given type. */ -Protocol* ProtocolManager::getProtocol(ProtocolType type) +std::shared_ptr ProtocolManager::getProtocol(ProtocolType type) { OneProtocolType &opt = m_all_protocols[type]; if (opt.isEmpty()) return NULL; diff --git a/src/network/protocol_manager.hpp b/src/network/protocol_manager.hpp index ed1834ea5..9712c3453 100644 --- a/src/network/protocol_manager.hpp +++ b/src/network/protocol_manager.hpp @@ -67,10 +67,10 @@ public: ProtocolRequestType m_type; /** The concerned protocol information. */ - Protocol *m_protocol; + std::shared_ptr m_protocol; public: - ProtocolRequest(ProtocolRequestType type, Protocol *protocol) + ProtocolRequest(ProtocolRequestType type, std::shared_ptr protocol) { m_type = type; m_protocol = protocol; @@ -80,7 +80,7 @@ public: ProtocolRequestType getType() const { return m_type; } // ------------------------------------------------------------------------ /** Returns the protocol for this request. */ - Protocol *getProtocol() { return m_protocol; } + std::shared_ptr getProtocol() { return m_protocol; } }; // class ProtocolRequest; // ============================================================================ @@ -144,9 +144,9 @@ private: class OneProtocolType { private: - Synchronised< std::vector > m_protocols; + Synchronised< std::vector > > m_protocols; public: - void removeProtocol(Protocol *p); + void removeProtocol(std::shared_ptr p); void requestTerminateAll(); bool notifyEvent(Event *event); void update(float dt, bool async); @@ -154,7 +154,8 @@ private: // -------------------------------------------------------------------- /** Returns the first protocol of a given type. It is assumed that * there is a protocol of that type. */ - Protocol *getFirstProtocol() { return m_protocols.getData()[0]; } + std::shared_ptr getFirstProtocol() + { return m_protocols.getData()[0]; } // -------------------------------------------------------------------- /** Returns if this protocol class handles connect events. Protocols * of the same class either all handle a connect event, or none, so @@ -180,7 +181,7 @@ private: /** Locks access to this list of all protocols of a certain type. */ void unlock() { m_protocols.unlock(); } // -------------------------------------------------------------------- - void addProtocol(Protocol *p) + void addProtocol(std::shared_ptr p) { m_protocols.getData().push_back(p); } // addProtocol @@ -222,11 +223,11 @@ private: bool sendEvent(Event* event); - virtual void startProtocol(Protocol *protocol); - virtual void terminateProtocol(Protocol *protocol); + virtual void startProtocol(std::shared_ptr protocol); + virtual void terminateProtocol(std::shared_ptr protocol); virtual void asynchronousUpdate(); - virtual void pauseProtocol(Protocol *protocol); - virtual void unpauseProtocol(Protocol *protocol); + virtual void pauseProtocol(std::shared_ptr protocol); + virtual void unpauseProtocol(std::shared_ptr protocol); public: // =========================================== @@ -235,11 +236,11 @@ public: virtual ~ProtocolManager(); void abort(); void propagateEvent(Event* event); - Protocol* getProtocol(ProtocolType type); - void requestStart(Protocol* protocol); - void requestPause(Protocol* protocol); - void requestUnpause(Protocol* protocol); - void requestTerminate(Protocol* protocol); + std::shared_ptr getProtocol(ProtocolType type); + void requestStart(std::shared_ptr protocol); + void requestPause(std::shared_ptr protocol); + void requestUnpause(std::shared_ptr protocol); + void requestTerminate(std::shared_ptr protocol); void findAndTerminate(ProtocolType type); void update(float dt); // ------------------------------------------------------------------------ diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index d0ec62168..d01e987d2 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -357,8 +357,7 @@ void ClientLobby::update(float dt) screen->push(); m_state = SELECTING_KARTS; - Protocol *p = new LatencyProtocol(); - p->requestStart(); + std::make_shared()->requestStart(); Log::info("LobbyProtocol", "LatencyProtocol started."); } break; @@ -370,7 +369,7 @@ void ClientLobby::update(float dt) break; case DONE: m_state = EXITING; - ProtocolManager::lock()->requestTerminate(this); + ProtocolManager::lock()->requestTerminate(shared_from_this()); break; case EXITING: break; diff --git a/src/network/protocols/connect_to_peer.cpp b/src/network/protocols/connect_to_peer.cpp index 70b505e16..6157a9dc3 100644 --- a/src/network/protocols/connect_to_peer.cpp +++ b/src/network/protocols/connect_to_peer.cpp @@ -40,7 +40,6 @@ ConnectToPeer::ConnectToPeer(uint32_t peer_id) : Protocol(PROTOCOL_CONNECTION) m_peer_address.clear(); m_peer_id = peer_id; m_state = NONE; - m_current_protocol = NULL; m_is_lan = false; setHandleConnections(true); } // ConnectToPeer(peer_id) @@ -56,7 +55,6 @@ ConnectToPeer::ConnectToPeer(const TransportAddress &address) // We don't need to find the peer address, so we can start // with the state when we found the peer address. m_state = RECEIVED_PEER_ADDRESS; - m_current_protocol = NULL; m_is_lan = true; setHandleConnections(true); } // ConnectToPeers(TransportAddress) @@ -99,7 +97,7 @@ void ConnectToPeer::asynchronousUpdate() { case NONE: { - m_current_protocol = new GetPeerAddress(m_peer_id, this); + m_current_protocol = std::make_shared(m_peer_id, this); m_current_protocol->requestStart(); // Pause this protocol till we receive an answer @@ -118,8 +116,7 @@ void ConnectToPeer::asynchronousUpdate() m_state = DONE; break; } - delete m_current_protocol; - m_current_protocol = 0; + m_current_protocol = nullptr; // Now we know the peer address. If it's a non-local host, start // the Ping protocol to keep the port available. We can't rely on @@ -130,7 +127,7 @@ void ConnectToPeer::asynchronousUpdate() NetworkConfig::get()->getMyAddress().getIP() ) || NetworkConfig::m_disable_lan ) { - m_current_protocol = new PingProtocol(m_peer_address, + m_current_protocol = std::make_shared(m_peer_address, /*time-between-ping*/2.0); ProtocolManager::lock()->requestStart(m_current_protocol); m_state = CONNECTING; @@ -202,7 +199,7 @@ void ConnectToPeer::asynchronousUpdate() { // Kill the ping protocol because we're connected m_current_protocol->requestTerminate(); - m_current_protocol = NULL; + m_current_protocol = nullptr; } m_state = DONE; break; diff --git a/src/network/protocols/connect_to_peer.hpp b/src/network/protocols/connect_to_peer.hpp index 6f5532fcf..87854b88c 100644 --- a/src/network/protocols/connect_to_peer.hpp +++ b/src/network/protocols/connect_to_peer.hpp @@ -34,7 +34,7 @@ protected: uint32_t m_peer_id; /** Pointer to the protocol which is monitored for state changes. */ - Protocol *m_current_protocol; + std::shared_ptr m_current_protocol; /** True if this is a LAN connection. */ bool m_is_lan; diff --git a/src/network/protocols/connect_to_server.cpp b/src/network/protocols/connect_to_server.cpp index 5095d7ed1..c950939be 100644 --- a/src/network/protocols/connect_to_server.cpp +++ b/src/network/protocols/connect_to_server.cpp @@ -82,7 +82,7 @@ ConnectToServer::~ConnectToServer() void ConnectToServer::setup() { Log::info("ConnectToServer", "SETUP"); - m_current_protocol = NULL; + m_current_protocol = nullptr; // In case of LAN we already have the server's and our ip address, // so we can immediately start requesting a connection. m_state = NetworkConfig::get()->isLAN() ? GOT_SERVER_ADDRESS : NONE; @@ -108,7 +108,7 @@ void ConnectToServer::asynchronousUpdate() Log::info("ConnectToServer", "Protocol starting"); // This protocol will write the public address of this // instance to STKHost. - m_current_protocol = new GetPublicAddress(this); + m_current_protocol = std::make_shared(this); m_current_protocol->requestStart(); // This protocol will be unpaused in the callback from // GetPublicAddress @@ -118,8 +118,8 @@ void ConnectToServer::asynchronousUpdate() } case GETTING_SELF_ADDRESS: { - delete m_current_protocol; // delete GetPublicAddress - m_current_protocol = NULL; + // drop GetPublicAddress + m_current_protocol = nullptr; registerWithSTKServer(); // Register us with STK server @@ -139,8 +139,7 @@ void ConnectToServer::asynchronousUpdate() case GOT_SERVER_ADDRESS: { assert(!m_quick_join); - delete m_current_protocol; - m_current_protocol = NULL; + m_current_protocol = nullptr; Log::info("ConnectToServer", "Server's address known"); // we're in the same lan (same public ip address) !! @@ -151,7 +150,7 @@ void ConnectToServer::asynchronousUpdate() "Server appears to be in the same LAN."); } m_state = REQUESTING_CONNECTION; - m_current_protocol = new RequestConnection(m_server_id); + m_current_protocol = std::make_shared(m_server_id); m_current_protocol->requestStart(); break; } @@ -160,8 +159,7 @@ void ConnectToServer::asynchronousUpdate() if (!m_current_protocol || m_current_protocol->getState() == PROTOCOL_STATE_TERMINATED) { - delete m_current_protocol; - m_current_protocol = NULL; + m_current_protocol = nullptr; // Server knows we want to connect Log::info("ConnectToServer", "Connection request made"); if (m_server_address.getIP() == 0 || @@ -171,7 +169,7 @@ void ConnectToServer::asynchronousUpdate() m_state = HIDING_ADDRESS; Log::error("ConnectToServer", "Server address is %s", m_server_address.toString().c_str()); - m_current_protocol = new HidePublicAddress(); + m_current_protocol = std::make_shared(); m_current_protocol->requestStart(); return; } @@ -187,7 +185,7 @@ void ConnectToServer::asynchronousUpdate() else { m_state = CONNECTING; - m_current_protocol = new PingProtocol(m_server_address, 2.0); + m_current_protocol = std::make_shared(m_server_address, 2.0); m_current_protocol->requestStart(); } } @@ -212,12 +210,11 @@ void ConnectToServer::asynchronousUpdate() // Kill the ping protocol because we're connected m_current_protocol->requestTerminate(); } - delete m_current_protocol; - m_current_protocol = NULL; + m_current_protocol = nullptr; // LAN networking does not use the stk server tables. if(NetworkConfig::get()->isWAN()) { - m_current_protocol = new HidePublicAddress(); + m_current_protocol = std::make_shared(); m_current_protocol->requestStart(); } m_state = HIDING_ADDRESS; @@ -230,18 +227,16 @@ void ConnectToServer::asynchronousUpdate() { if(m_current_protocol) { - delete m_current_protocol; - m_current_protocol = NULL; + m_current_protocol = nullptr; Log::info("ConnectToServer", "Address hidden"); } m_state = DONE; // lobby room protocol if we're connected only if(STKHost::get()->getPeers()[0]->isConnected()) { - ClientLobby *p = - LobbyProtocol::create(); - p->setAddress(m_server_address); - p->requestStart(); + auto cl = LobbyProtocol::create(); + cl->setAddress(m_server_address); + cl->requestStart(); } } break; diff --git a/src/network/protocols/connect_to_server.hpp b/src/network/protocols/connect_to_server.hpp index e69a8e370..42690fef0 100644 --- a/src/network/protocols/connect_to_server.hpp +++ b/src/network/protocols/connect_to_server.hpp @@ -32,7 +32,7 @@ private: uint32_t m_host_id; /** Protocol currently being monitored. */ - Protocol *m_current_protocol; + std::shared_ptr m_current_protocol; bool m_quick_join; /** State for finite state machine. */ diff --git a/src/network/protocols/game_protocol.cpp b/src/network/protocols/game_protocol.cpp index a4aeaa028..c642e9882 100644 --- a/src/network/protocols/game_protocol.cpp +++ b/src/network/protocols/game_protocol.cpp @@ -32,6 +32,21 @@ #include "network/stk_peer.hpp" #include "utils/log.hpp" +// ============================================================================ +std::weak_ptr GameProtocol::m_game_protocol; +// ============================================================================ +std::shared_ptr GameProtocol::createInstance() +{ + if (!emptyInstance()) + { + Log::fatal("GameProtocol", "Create only 1 instance of GameProtocol!"); + return NULL; + } + auto gm = std::make_shared(); + m_game_protocol = gm; + return gm; +} // createInstance + //----------------------------------------------------------------------------- /** Constructor. Allocates the buffer for events to send to the server. */ GameProtocol::GameProtocol() diff --git a/src/network/protocols/game_protocol.hpp b/src/network/protocols/game_protocol.hpp index 5f211764f..831f5016f 100644 --- a/src/network/protocols/game_protocol.hpp +++ b/src/network/protocols/game_protocol.hpp @@ -34,7 +34,6 @@ class STKPeer; class GameProtocol : public Protocol , public EventRewinder - , public Singleton { private: @@ -69,6 +68,7 @@ private: void handleControllerAction(Event *event); void handleState(Event *event); void handleAdjustTime(Event *event); + static std::weak_ptr m_game_protocol; public: GameProtocol(); virtual ~GameProtocol(); @@ -90,6 +90,18 @@ public: // ------------------------------------------------------------------------ virtual void asynchronousUpdate() OVERRIDE {} // ------------------------------------------------------------------------ + static std::shared_ptr createInstance(); + // ------------------------------------------------------------------------ + static bool emptyInstance() + { + return m_game_protocol.expired(); + } // emptyInstance + // ------------------------------------------------------------------------ + static std::shared_ptr lock() + { + return m_game_protocol.lock(); + } // lock + }; // class GameProtocol #endif // GAME_PROTOCOL_HPP diff --git a/src/network/protocols/lobby_protocol.cpp b/src/network/protocols/lobby_protocol.cpp index 4b4f489b0..e1f7a444c 100644 --- a/src/network/protocols/lobby_protocol.cpp +++ b/src/network/protocols/lobby_protocol.cpp @@ -33,7 +33,7 @@ #include "race/race_manager.hpp" #include "states_screens/state_manager.hpp" -LobbyProtocol *LobbyProtocol::m_lobby = NULL; +std::weak_ptr LobbyProtocol::m_lobby; LobbyProtocol::LobbyProtocol(CallbackObject* callback_object) : Protocol(PROTOCOL_LOBBY_ROOM, callback_object) @@ -125,8 +125,8 @@ void LobbyProtocol::loadWorld() // Load the actual world. m_game_setup->getRaceConfig()->loadWorld(); World::getWorld()->setNetworkWorld(true); - GameProtocol::getInstance()->requestStart(); - (new GameEventsProtocol())->requestStart(); + GameProtocol::createInstance()->requestStart(); + std::make_shared()->requestStart(); } // loadWorld diff --git a/src/network/protocols/lobby_protocol.hpp b/src/network/protocols/lobby_protocol.hpp index 8b00cbb7f..52f31bf27 100644 --- a/src/network/protocols/lobby_protocol.hpp +++ b/src/network/protocols/lobby_protocol.hpp @@ -63,28 +63,33 @@ public: }; protected: - static LobbyProtocol *m_lobby; + static std::weak_ptr m_lobby; /** The game setup. */ GameSetup* m_game_setup; - public: /** Creates either a client or server lobby protocol as a singleton. */ - template static S* create() + template static std::shared_ptr create() { - assert(m_lobby == NULL); - m_lobby = new S(); - return dynamic_cast(m_lobby); + assert(m_lobby.expired()); + auto ret = std::make_shared(); + m_lobby = ret; + return std::dynamic_pointer_cast(ret); } // create // ------------------------------------------------------------------------ /** Returns the singleton client or server lobby protocol. */ - static LobbyProtocol *get() + template static std::shared_ptr get() { - assert(m_lobby); - return m_lobby; + if (std::shared_ptr lp = m_lobby.lock()) + { + std::shared_ptr new_type = std::dynamic_pointer_cast(lp); + if (new_type) + return new_type; + } + return nullptr; } // get // ------------------------------------------------------------------------ diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 3ae85c425..62ec55406 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -115,7 +115,7 @@ void ServerLobby::setup() m_state = NetworkConfig::get()->isLAN() ? ACCEPTING_CLIENTS : INIT_WAN; m_selection_enabled = false; - m_current_protocol = NULL; + m_current_protocol = nullptr; Log::info("ServerLobby", "Starting the protocol."); // Initialise the data structures to detect if all clients and @@ -202,7 +202,7 @@ void ServerLobby::update(float dt) { case INIT_WAN: // Start the protocol to find the public ip address. - m_current_protocol = new GetPublicAddress(this); + m_current_protocol = std::make_shared(this); m_current_protocol->requestStart(); m_state = GETTING_PUBLIC_ADDRESS; // The callback from GetPublicAddress will wake this protocol up @@ -212,7 +212,7 @@ void ServerLobby::update(float dt) { Log::debug("ServerLobby", "Public address known."); // Free GetPublicAddress protocol - delete m_current_protocol; + m_current_protocol = nullptr; // Register this server with the STK server. This will block // this thread, but there is no need for the protocol manager @@ -420,8 +420,7 @@ void ServerLobby::startSelection(const Event *event) m_state = SELECTING; WaitingForOthersScreen::getInstance()->push(); - Protocol *p = new LatencyProtocol(); - p->requestStart(); + std::make_shared()->requestStart(); Log::info("LobbyProtocol", "LatencyProtocol started."); } // startSelection @@ -468,8 +467,7 @@ void ServerLobby::checkIncomingConnectionRequests() users_xml->getNode(i)->get("id", &id); Log::debug("ServerLobby", "User with id %d wants to connect.", id); - Protocol *p = new ConnectToPeer(id); - p->requestStart(); + std::make_shared(id)->requestStart(); } delete request; } // checkIncomingConnectionRequests diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index 744aefae3..fd58f2bb7 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -54,7 +54,7 @@ private: * seconds), which is the real time at which the server should start. */ double m_server_delay; - Protocol *m_current_protocol; + std::shared_ptr m_current_protocol; bool m_selection_enabled; /** Counts how many players are ready to go on. */ diff --git a/src/network/race_event_manager.cpp b/src/network/race_event_manager.cpp index 6af40c6c0..20c79c0ef 100644 --- a/src/network/race_event_manager.cpp +++ b/src/network/race_event_manager.cpp @@ -73,7 +73,7 @@ bool RaceEventManager::isRaceOver() // ---------------------------------------------------------------------------- void RaceEventManager::kartFinishedRace(AbstractKart *kart, float time) { - GameEventsProtocol* protocol = static_cast( + auto protocol = std::static_pointer_cast( ProtocolManager::lock()->getProtocol(PROTOCOL_GAME_EVENTS)); protocol->kartFinishedRace(kart, time); } // kartFinishedRace @@ -89,7 +89,7 @@ void RaceEventManager::collectedItem(Item *item, AbstractKart *kart) // this is only called in the server assert(NetworkConfig::get()->isServer()); - GameEventsProtocol* protocol = static_cast( + auto protocol = std::static_pointer_cast( ProtocolManager::lock()->getProtocol(PROTOCOL_GAME_EVENTS)); protocol->collectedItem(item,kart); } // collectedItem diff --git a/src/network/rewind_manager.cpp b/src/network/rewind_manager.cpp index 4aa876812..2468c2562 100755 --- a/src/network/rewind_manager.cpp +++ b/src/network/rewind_manager.cpp @@ -191,7 +191,7 @@ void RewindManager::update(float dt) PROFILER_PUSH_CPU_MARKER("RewindManager - save state", 0x20, 0x7F, 0x20); // Save state - GameProtocol::getInstance()->startNewState(); + GameProtocol::lock()->startNewState(); AllRewinder::const_iterator rewinder; for(rewinder=m_all_rewinder.begin(); rewinder!=m_all_rewinder.end(); ++rewinder) { @@ -202,14 +202,14 @@ void RewindManager::update(float dt) // Add to the previously created container m_rewind_queue.addLocalState(*rewinder, buffer, /*confirmed*/true, World::getWorld()->getTime()); - GameProtocol::getInstance()->addState(buffer); + GameProtocol::lock()->addState(buffer); } // size >= 0 else delete buffer; // NULL or 0 byte buffer } PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("RewindManager - send state", 0x20, 0x7F, 0x40); - GameProtocol::getInstance()->sendState(); + GameProtocol::lock()->sendState(); PROFILER_POP_CPU_MARKER(); m_last_saved_state = time; } // update diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp index 3bf92ed4f..d2719bade 100644 --- a/src/network/stk_host.cpp +++ b/src/network/stk_host.cpp @@ -257,8 +257,7 @@ STKHost::STKHost(uint32_t server_id, uint32_t host_id) "an ENet client host."); } - Protocol *connect = new ConnectToServer(server_id, host_id); - connect->requestStart(); + std::make_shared(server_id, host_id)->requestStart(); } // STKHost // ---------------------------------------------------------------------------- @@ -288,8 +287,7 @@ STKHost::STKHost(const irr::core::stringw &server_name) } startListening(); - Protocol *p = LobbyProtocol::create(); - ProtocolManager::lock()->requestStart(p); + ProtocolManager::lock()->requestStart(LobbyProtocol::create()); } // STKHost(server_name) @@ -608,8 +606,7 @@ void STKHost::handleDirectSocketRequest() { // In case of a LAN connection, we only allow connections from // a LAN address (192.168*, ..., and 127.*). - Protocol *c = new ConnectToPeer(sender); - c->requestStart(); + std::make_shared(sender)->requestStart(); } else Log::info("STKHost", "Received unknown command '%s'", diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index 2daeb829e..0501ce06f 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -562,7 +562,7 @@ void RaceManager::startNextRace() // the world has been setup if(NetworkConfig::get()->isNetworking()) { - LobbyProtocol *lobby = LobbyProtocol::get(); + auto lobby = LobbyProtocol::get(); assert(lobby); lobby->finishedLoadingWorld(); } diff --git a/src/states_screens/network_kart_selection.cpp b/src/states_screens/network_kart_selection.cpp index 559e165f2..2769fac66 100644 --- a/src/states_screens/network_kart_selection.cpp +++ b/src/states_screens/network_kart_selection.cpp @@ -144,9 +144,7 @@ void NetworkKartSelectionScreen::playerConfirm(const int playerID) } if(playerID == PLAYER_ID_GAME_MASTER) // self { - - LobbyProtocol* protocol = LobbyProtocol::get(); - ClientLobby *clrp = dynamic_cast(protocol); + auto clrp = LobbyProtocol::get(); assert(clrp); // FIXME SPLITSCREEN: we need to supply the global player id of the // player selecting the kart here. For now ... just vote the same kart @@ -196,10 +194,7 @@ void NetworkKartSelectionScreen::playerSelected(uint8_t player_id, // to the server. if(STKHost::get()->isAuthorisedToControl()) { - Protocol* protocol = ProtocolManager::lock() - ->getProtocol(PROTOCOL_LOBBY_ROOM); - ClientLobby* clrp = - dynamic_cast(protocol); + auto clrp = LobbyProtocol::get(); assert(clrp); // FIXME: for now we submit a vote from the authorised user // for the various modes based on the settings in the race manager. @@ -214,7 +209,7 @@ void NetworkKartSelectionScreen::playerSelected(uint8_t player_id, clrp->voteMinor(id, race_manager->getMinorMode()); clrp->voteReversed(id, race_manager->getReverseTrack()); clrp->voteRaceCount(id, 1); - clrp->voteLaps(id, 3); + clrp->voteLaps(id, 1); } //WaitingForOthersScreen::getInstance()->push(); //return; @@ -228,10 +223,8 @@ bool NetworkKartSelectionScreen::onEscapePressed() // then remove the lobby screen (you left the server) StateManager::get()->popMenu(); ServerSelection::getInstance()->refresh(); - Protocol *lobby = LobbyProtocol::get(); // notify the server that we left - ClientLobby* clrp = - dynamic_cast(lobby); + auto clrp = LobbyProtocol::get(); if (clrp) clrp->leave(); return true; // remove the screen diff --git a/src/states_screens/networking_lobby.cpp b/src/states_screens/networking_lobby.cpp index 2a3a68b84..62d751d9f 100644 --- a/src/states_screens/networking_lobby.cpp +++ b/src/states_screens/networking_lobby.cpp @@ -162,8 +162,7 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, { if(NetworkConfig::get()->isServer()) { - Protocol *p = LobbyProtocol::get(); - ServerLobby* slrp = dynamic_cast(p); + auto slrp = LobbyProtocol::get(); slrp->startSelection(); } else // client @@ -198,10 +197,9 @@ void NetworkingLobby::tearDown() bool NetworkingLobby::onEscapePressed() { // notify the server that we left - ClientLobby* protocol = - dynamic_cast(LobbyProtocol::get()); - if (protocol) - protocol->leave(); + auto clrp = LobbyProtocol::get(); + if (clrp) + clrp->leave(); STKHost::get()->shutdown(); return true; // close the screen } // onEscapePressed diff --git a/src/states_screens/online_profile_servers.cpp b/src/states_screens/online_profile_servers.cpp index d7ca56184..1e9a9c355 100644 --- a/src/states_screens/online_profile_servers.cpp +++ b/src/states_screens/online_profile_servers.cpp @@ -149,7 +149,7 @@ void OnlineProfileServers::doQuickPlay() { delete join_request; NetworkingLobby::getInstance()->push(); - ConnectToServer *cts = new ConnectToServer(server->getServerId(), + auto cts = std::make_shared(server->getServerId(), server->getHostId()); ProtocolManager::lock()->requestStart(cts); } diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 8df14e439..20830e17a 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -348,9 +348,7 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget, if (name == "middle") // Continue button (return to server lobby) { // Signal to the server that this client is back in the lobby now. - Protocol* protocol = LobbyProtocol::get(); - ClientLobby* clrp = - dynamic_cast(protocol); + auto clrp = LobbyProtocol::get(); if(clrp) clrp->doneWithResults(); backToLobby(); diff --git a/src/states_screens/tracks_screen.cpp b/src/states_screens/tracks_screen.cpp index cb207ac37..259cec128 100644 --- a/src/states_screens/tracks_screen.cpp +++ b/src/states_screens/tracks_screen.cpp @@ -89,10 +89,9 @@ void TracksScreen::eventCallback(Widget* widget, const std::string& name, { if(STKHost::existHost()) { - Protocol* protocol = LobbyProtocol::get(); - ClientLobby* clrp = - dynamic_cast(protocol); - assert(clrp); // server never shows the track screen. + auto clrp = LobbyProtocol::get(); + // server never shows the track screen. + assert(clrp); // FIXME SPLITSCREEN: we need to supply the global player id of the // player selecting the track here. For now ... just vote the same // track for each local player. @@ -200,11 +199,10 @@ void TracksScreen::buildTrackList() // First build a list of all tracks to be displayed // (e.g. exclude arenas, ...) bool is_network = (STKHost::existHost()); - ClientLobby* clrp = NULL; + std::shared_ptr clrp; if (is_network) { - Protocol* protocol = LobbyProtocol::get(); - clrp = dynamic_cast(protocol); + clrp = LobbyProtocol::get(); assert(clrp); } PtrVector tracks;