From beb116e964993459030185391b2da77e4d2a3bce Mon Sep 17 00:00:00 2001 From: Dennis Andersen Date: Thu, 19 Dec 2013 12:32:23 +0100 Subject: [PATCH] Fixed some threafing and stuff --- Code/Game/DanBiasLauncher/Launcher.cpp | 1 + Code/Game/DanBiasServer/DanBiasServer.vcxproj | 18 +- Code/Game/DanBiasServer/GameServer.cpp | 32 +- .../{ => Helpers}/GameSessionManager.cpp | 18 +- .../{ => Helpers}/GameSessionManager.h | 0 .../DanBiasServer/Helpers/ProtocolParser.cpp | 75 ++++ .../DanBiasServer/Helpers/ProtocolParser.h | 27 ++ .../{ => Helpers}/ServerInitReader.h | 2 +- .../ServerObjects/ClientObject.cpp | 5 +- .../ServerObjects/ClientObject.h | 1 + .../ServerObjects/GameSession.cpp | 112 +++-- .../DanBiasServer/ServerObjects/GameSession.h | 21 +- .../ServerObjects/Lobby/GameLobby.cpp | 9 +- .../ServerObjects/Lobby/GameLobby.h | 6 +- .../ServerObjects/Lobby/MainLobby.cpp | 65 ++- .../ServerObjects/Lobby/MainLobby.h | 18 +- .../ServerObjects/NetworkSession.cpp | 19 + .../ServerObjects/NetworkSession.h | 5 +- Code/Game/GameLogic/CollisionManager.cpp | 9 +- Code/Game/GameLogic/CollisionManager.h | 7 +- Code/Game/GameLogic/GameLogic.vcxproj | 1 + Code/Game/GameLogic/Weapon.cpp | 1 + Code/Game/GameProtocols/GameProtocols.h | 2 + Code/Game/GameProtocols/GameProtocols.vcxproj | 1 + Code/Game/GameProtocols/LobbyProtocols.h | 120 +++++ Code/Game/GameProtocols/ObjectProtocols.h | 4 +- .../GameProtocols/ProtocolIdentificationID.h | 46 +- Code/Misc/Thread/OysterThread.h | 31 +- Code/Misc/Thread/OysterThread_Impl.cpp | 416 +++++++++--------- Code/Misc/Utilities-Impl.h | 17 +- Code/Misc/Utilities.h | 4 + Code/Network/NetworkAPI/NetworkServer.cpp | 19 +- Code/Network/NetworkDependencies/Listener.cpp | 3 +- 33 files changed, 758 insertions(+), 357 deletions(-) rename Code/Game/DanBiasServer/{ => Helpers}/GameSessionManager.cpp (64%) rename Code/Game/DanBiasServer/{ => Helpers}/GameSessionManager.h (100%) create mode 100644 Code/Game/DanBiasServer/Helpers/ProtocolParser.cpp create mode 100644 Code/Game/DanBiasServer/Helpers/ProtocolParser.h rename Code/Game/DanBiasServer/{ => Helpers}/ServerInitReader.h (93%) create mode 100644 Code/Game/GameProtocols/LobbyProtocols.h diff --git a/Code/Game/DanBiasLauncher/Launcher.cpp b/Code/Game/DanBiasLauncher/Launcher.cpp index 6b82da2a..994acb11 100644 --- a/Code/Game/DanBiasLauncher/Launcher.cpp +++ b/Code/Game/DanBiasLauncher/Launcher.cpp @@ -30,6 +30,7 @@ int WINAPI WinMain( HINSTANCE hinst, HINSTANCE prevInst, PSTR cmdLine, int cmdSh DanBias::DanBiasGameDesc gameDesc; gameDesc.port = 15151; gameDesc.IP = "193.11.184.196"; + gameDesc.IP = "127.0.0.1"; gameDesc.hinst = hinst; gameDesc.nCmdShow = cmdShow; diff --git a/Code/Game/DanBiasServer/DanBiasServer.vcxproj b/Code/Game/DanBiasServer/DanBiasServer.vcxproj index 5793ef44..8319c2c9 100644 --- a/Code/Game/DanBiasServer/DanBiasServer.vcxproj +++ b/Code/Game/DanBiasServer/DanBiasServer.vcxproj @@ -113,7 +113,7 @@ Windows true - GameLogic_$(PlatformShortName)D.dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName)D.dll + GameLogic_$(PlatformShortName)D.dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName)D.dll;GamePhysics_$(PlatformShortName)D.dll NetworkAPI_$(PlatformShortName)D.lib;WindowManager_$(PlatformShortName)D.lib;GameLogic_$(PlatformShortName)D.lib;%(AdditionalDependencies) @@ -130,7 +130,7 @@ Windows true - GameLogic_$(PlatformShortName)D.dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName)D.dll + GameLogic_$(PlatformShortName)D.dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName)D.dll;GamePhysics_$(PlatformShortName)D.dll NetworkAPI_$(PlatformShortName)D.lib;WindowManager_$(PlatformShortName)D.lib;GameLogic_$(PlatformShortName)D.lib;%(AdditionalDependencies) @@ -151,7 +151,7 @@ true true true - GameLogic_$(PlatformShortName).dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName).dll + GameLogic_$(PlatformShortName).dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName).dll;GamePhysics_$(PlatformShortName).dll NetworkAPI_$(PlatformShortName).lib;WindowManager_$(PlatformShortName).lib;GameLogic_$(PlatformShortName).lib;%(AdditionalDependencies) @@ -172,12 +172,13 @@ true true true - GameLogic_$(PlatformShortName).dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName).dll + GameLogic_$(PlatformShortName).dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName).dll;GamePhysics_$(PlatformShortName).dll NetworkAPI_$(PlatformShortName).lib;WindowManager_$(PlatformShortName).lib;GameLogic_$(PlatformShortName).lib;%(AdditionalDependencies) - + + @@ -186,18 +187,21 @@ + - + - + + + diff --git a/Code/Game/DanBiasServer/GameServer.cpp b/Code/Game/DanBiasServer/GameServer.cpp index 4f4d1c0d..afb6e1b2 100644 --- a/Code/Game/DanBiasServer/GameServer.cpp +++ b/Code/Game/DanBiasServer/GameServer.cpp @@ -2,28 +2,43 @@ // Created by [Dennis Andersen] [2013] ///////////////////////////////////////////////////////////////////// #define NOMINMAX +#include "Test\TEST.h" #include #include #include #include "GameServer.h" #include "Utilities.h" -#include "ServerInitReader.h" -#include +#include "Helpers\ServerInitReader.h" #include #include "ServerObjects\ClientObject.h" +#include "ServerObjects\GameSession.h" + +#include namespace DanBias { using namespace Oyster::Network; - + static GameSession *myTest; + void GameServer::ClientConnectCallback(NetworkClient* client) { - printf("Client connected!\n"); + if(!myTest) + { + myTest = new GameSession(); + Utility::DynamicMemory::SmartPointer c = new ClientObject(client); + DanBias::GameSession::GameSessionDescription desc; + desc.owner = 0; + desc.clients.Push(c); - Utility::DynamicMemory::SmartPointer c = new ClientObject(client); - this->mainLobby->AttachClient(c); + myTest->Run(desc); + } + + //printf("Client connected with socket: %i\n", client->Id()); + // + //Utility::DynamicMemory::SmartPointer c = new ClientObject(client); + //this->mainLobby->AttachClient(c, this->mainLobby->GetPostbox()); } GameServer::GameServer() : initiated(0) @@ -32,8 +47,7 @@ namespace DanBias , maxClients(0) , mainLobby(0) , server(0) - { - } + { } GameServer::~GameServer() { @@ -78,9 +92,9 @@ namespace DanBias } DanBiasServerReturn GameServer::Release() { + delete this->mainLobby; this->server->Shutdown(); delete this->server; - delete this->mainLobby; this->released = true; return DanBiasServerReturn_Sucess; } diff --git a/Code/Game/DanBiasServer/GameSessionManager.cpp b/Code/Game/DanBiasServer/Helpers/GameSessionManager.cpp similarity index 64% rename from Code/Game/DanBiasServer/GameSessionManager.cpp rename to Code/Game/DanBiasServer/Helpers/GameSessionManager.cpp index 9a78cae7..1bcaa652 100644 --- a/Code/Game/DanBiasServer/GameSessionManager.cpp +++ b/Code/Game/DanBiasServer/Helpers/GameSessionManager.cpp @@ -1,6 +1,6 @@ #include "GameSessionManager.h" -#include "ServerObjects\GameSession.h" +#include "..\ServerObjects\GameSession.h" #include "DynamicArray.h" struct GameSessionData @@ -25,30 +25,30 @@ struct GameSessionData return -1; } -} __gameSessionData; +} gameSessionData; void GameSessionManager::AddSession(DanBias::GameSession* session) { - if(__gameSessionData.Existst(session) == -1) + if(gameSessionData.Existst(session) == -1) { - int k = __gameSessionData.freeSpot; + int k = gameSessionData.freeSpot; - if( k == -1) k = __gameSessionData.GetFree(); + if( k == -1) k = gameSessionData.GetFree(); - if(k == -1) __gameSessionData.sessions.Push(session); - else __gameSessionData.sessions[k] = session; + if(k == -1) gameSessionData.sessions.Push(session); + else gameSessionData.sessions[k] = session; } } void GameSessionManager::CloseSession(DanBias::GameSession* session) { - int i = __gameSessionData.Existst(session); + int i = gameSessionData.Existst(session); //Moron check... if(i == -1) return; - //__gameSessionData.sessions[i]->Close(); + //gameSessionData.sessions[i]->Close(); } diff --git a/Code/Game/DanBiasServer/GameSessionManager.h b/Code/Game/DanBiasServer/Helpers/GameSessionManager.h similarity index 100% rename from Code/Game/DanBiasServer/GameSessionManager.h rename to Code/Game/DanBiasServer/Helpers/GameSessionManager.h diff --git a/Code/Game/DanBiasServer/Helpers/ProtocolParser.cpp b/Code/Game/DanBiasServer/Helpers/ProtocolParser.cpp new file mode 100644 index 00000000..b027e54c --- /dev/null +++ b/Code/Game/DanBiasServer/Helpers/ProtocolParser.cpp @@ -0,0 +1,75 @@ +#include "ProtocolParser.h" +using namespace DanBias; + + +void ParseGeneralP(Oyster::Network::CustomNetProtocol& p, const short &f, ProtocolParser::ProtocolData& d) +{ + switch (f) + { + case protocol_General_Disconnect: + + break; + case protocol_General_Ping: + + break; + case protocol_General_Text: + + break; + } +} +void ParseLobbyP(Oyster::Network::CustomNetProtocol& p, const short &f, ProtocolParser::ProtocolData& d) +{ + Oyster::Network::CustomNetProtocol* lp; + d.type = f; + switch (f) + { + case protocol_Lobby_CreateGame: + { + //lp = d.p.createGame.GetProtocol(); + //d.p.createGame (*lp)[0].value; + } + break; + case protocol_Lobby_JoinGame: + { + lp = d.p.createGame.GetProtocol(); + } + break; + case protocol_Lobby_StartGame: + { + lp = d.p.createGame.GetProtocol(); + d.p.startGame.gameId = (*lp)[1].value.netChar; + } + break; + case protocol_Lobby_JoinLobby: + { + lp = d.p.createGame.GetProtocol(); + } + break; + case protocol_Lobby_LeaveLobby: + { + lp = d.p.createGame.GetProtocol(); + } + break; + } +} + + +ProtocolParser::ProtocolData ProtocolParser::ParseProtocol(Oyster::Network::CustomNetProtocol& p) +{ + ProtocolParser::ProtocolData d; + memset(&d, 0, sizeof(ProtocolData)); + + short f = p[0].value.netShort; + + switch (f) + { + case protocol_TypeId_General: + ParseGeneralP(p, f, d); + break; + case protocol_TypeId_Lobby: + ParseLobbyP(p, f, d); + break; + } + + return d; +} \ No newline at end of file diff --git a/Code/Game/DanBiasServer/Helpers/ProtocolParser.h b/Code/Game/DanBiasServer/Helpers/ProtocolParser.h new file mode 100644 index 00000000..c72dac95 --- /dev/null +++ b/Code/Game/DanBiasServer/Helpers/ProtocolParser.h @@ -0,0 +1,27 @@ +#ifndef DANBIASSERVER_PROTOCOLPARSER_H +#define DANBIASSERVER_PROTOCOLPARSER_H + +#include +namespace DanBias +{ + class ProtocolParser + { + public: + union ProtocolCollection + { + struct{ GameLogic::Protocol_LobbyCreateGame createGame; }; + struct{ GameLogic::Protocol_LobbyJoinGame joinGame; }; + struct{ GameLogic::Protocol_LobbyStartGame startGame; }; + struct{ GameLogic::Protocol_LobbyJoinLobby joinLobby; }; + struct{ GameLogic::Protocol_LobbyLeaveLobby leaveLobby; }; + }; + struct ProtocolData + { + short type; + ProtocolCollection p; + }; + public: + static ProtocolData ParseProtocol(Oyster::Network::CustomNetProtocol& p); + }; +} +#endif // !DANBIASSERVER_PROTOCOLPARSER_H diff --git a/Code/Game/DanBiasServer/ServerInitReader.h b/Code/Game/DanBiasServer/Helpers/ServerInitReader.h similarity index 93% rename from Code/Game/DanBiasServer/ServerInitReader.h rename to Code/Game/DanBiasServer/Helpers/ServerInitReader.h index cf7cc4c7..68c28a9a 100644 --- a/Code/Game/DanBiasServer/ServerInitReader.h +++ b/Code/Game/DanBiasServer/Helpers/ServerInitReader.h @@ -10,7 +10,7 @@ namespace DanBias { InitPath_ServerIni, }; - std::string GetInitPath(InitPath file) + static std::string GetInitPath(InitPath file) { std::string type = ""; std::string path = ""; diff --git a/Code/Game/DanBiasServer/ServerObjects/ClientObject.cpp b/Code/Game/DanBiasServer/ServerObjects/ClientObject.cpp index a06bde05..33f8b8c1 100644 --- a/Code/Game/DanBiasServer/ServerObjects/ClientObject.cpp +++ b/Code/Game/DanBiasServer/ServerObjects/ClientObject.cpp @@ -12,7 +12,10 @@ ClientObject::~ClientObject() { this->client->Disconnect(); } - +void ClientObject::SetProtocolCallback(Oyster::Network::ProtocolRecieverObject* object) +{ + this->NetClient_Object()->SetRecieverObject(object, Oyster::Network::NetworkProtocolCallbackType_Object); +} void ClientObject::SetPostbox(Oyster::IPostBox* box) { this->box = box; diff --git a/Code/Game/DanBiasServer/ServerObjects/ClientObject.h b/Code/Game/DanBiasServer/ServerObjects/ClientObject.h index 3ee8c710..bf2dab6a 100644 --- a/Code/Game/DanBiasServer/ServerObjects/ClientObject.h +++ b/Code/Game/DanBiasServer/ServerObjects/ClientObject.h @@ -17,6 +17,7 @@ namespace DanBias virtual~ClientObject(); void SetPostbox(Oyster::IPostBox* box); + void SetProtocolCallback(Oyster::Network::ProtocolRecieverObject* object); GameLogic::Player* Logic_Object(); Oyster::Network::NetworkClient* NetClient_Object(); diff --git a/Code/Game/DanBiasServer/ServerObjects/GameSession.cpp b/Code/Game/DanBiasServer/ServerObjects/GameSession.cpp index 1863d7e4..35ff5972 100644 --- a/Code/Game/DanBiasServer/ServerObjects/GameSession.cpp +++ b/Code/Game/DanBiasServer/ServerObjects/GameSession.cpp @@ -1,8 +1,9 @@ #include -#include "GameSession.h" #include +#include "GameSession.h" #include "ClientObject.h" +#include "..\Helpers\ProtocolParser.h" #define ERIK @@ -10,29 +11,39 @@ using namespace Utility::DynamicMemory; using namespace Oyster::Network; using namespace Oyster; +using namespace Oyster::Thread; namespace DanBias { GameSession::GameSession() { - + this->box = 0; } GameSession::~GameSession() { - + delete this->box; + this->box = 0; } - void GameSession::Run(const GameSessionDescription& desc) + void GameSession::Run(GameSessionDescription& desc) { - + if(this->Init(desc)) + { + if(this->worker.Create(this, true, true) != OYSTER_THREAD_ERROR_SUCCESS) return; + this->worker.SetPriority(OYSTER_THREAD_PRIORITY_1); + } } + void GameSession::Join(Utility::DynamicMemory::SmartPointer client) + { + AttachClient(client, this->box); + } + +////private: overriden NetworkSession functions void GameSession::AttachClient(SmartPointer client, Oyster::IPostBox *box ) { - this->Init(); + NetworkSession::AttachClient(client, box); } - -////private: //overriden NetworkSession functions void GameSession::Close() { @@ -84,64 +95,69 @@ namespace DanBias } ////private: - void GameSession::Init() + bool GameSession::Init(GameSessionDescription& desc) { -#ifdef ERIK - EricLogicInitFunc(); -#else - -#endif + if(desc.clients.Size() == 0) return false; + this->box = new PostBox(); + this->owner = desc.owner; + for (unsigned int i = 0; i < desc.clients.Size(); i++) + { + desc.clients[i]->SetPostbox(this->box); + this->clients.Push(desc.clients[i]); + } + + return true; } void GameSession::Frame() { -#ifdef ERIK - EricLogicFrameFunc(); -#else - -#endif } void GameSession::ParseEvents() { if(this->box && !this->box->IsEmpty()) { NetEvent &e = this->box->Fetch(); - -#ifdef ERIK - EricsLogicTestingProtocalRecieved(e.reciever, e.protocol); -#else + if(e.protocol[0].type != Oyster::Network::NetAttributeType_Short) return; - short f = e.protocol[0].value.netShort; - - switch (f) + ParseProtocol(e.protocol, *e.reciever); + } + } + void GameSession::ParseProtocol(Oyster::Network::CustomNetProtocol& p, DanBias::ClientObject& c) + { + switch (p[0].value.netShort) + { + case protocol_Gamplay_PlayerNavigation: { - default: - - break; + if(p[1].value.netBool) //bool bForward; + c.Logic_Object()->Move(GameLogic::PLAYER_MOVEMENT_FORWARD); + if(p[2].value.netBool) //bool bBackward; + c.Logic_Object()->Move(GameLogic::PLAYER_MOVEMENT_BACKWARD); + if(p[5].value.netBool) //bool bStrafeRight; + c.Logic_Object()->Move(GameLogic::PLAYER_MOVEMENT_RIGHT); + if(p[6].value.netBool) //bool bStrafeLeft; + c.Logic_Object()->Move(GameLogic::PLAYER_MOVEMENT_LEFT); } -#endif + break; + case protocol_Gamplay_PlayerMouseMovement: + + break; + case protocol_Gamplay_PlayerPosition: + + break; + case protocol_Gamplay_CreateObject: + + break; + case protocol_Gamplay_ObjectPosition: + + break; } } - -#pragma region TESTING +#ifdef ERIK //VARIABLES GOES HERE - int i = 0; - GameLogic::Player erik; - - void GameSession::EricLogicInitFunc() - { - - } - void GameSession::EricLogicFrameFunc() - { - - } - void GameSession::EricsLogicTestingProtocalRecieved(ClientObject* reciever, CustomNetProtocol& protocol) - { - - } -#pragma endregion + + +#endif }//End namespace DanBias diff --git a/Code/Game/DanBiasServer/ServerObjects/GameSession.h b/Code/Game/DanBiasServer/ServerObjects/GameSession.h index 33d57b67..dadf2096 100644 --- a/Code/Game/DanBiasServer/ServerObjects/GameSession.h +++ b/Code/Game/DanBiasServer/ServerObjects/GameSession.h @@ -14,19 +14,20 @@ namespace DanBias struct GameSessionDescription { NetworkSession* owner; - + Utility::DynamicMemory::DynamicArray> clients; }; public: GameSession(); virtual~GameSession(); - void Run(const GameSessionDescription& desc); + void Run(GameSessionDescription& desc); - void AttachClient(Utility::DynamicMemory::SmartPointer client, Oyster::IPostBox *box = 0) override; + void Join(Utility::DynamicMemory::SmartPointer client); private: //overriden NetworkSession functions void Close(); + void AttachClient(Utility::DynamicMemory::SmartPointer client, Oyster::IPostBox *box = 0) override; Utility::DynamicMemory::SmartPointer DetachClient(Oyster::Network::NetworkClient* client) override; Utility::DynamicMemory::SmartPointer DetachClient(ClientObject* client) override; Utility::DynamicMemory::SmartPointer DetachClient(short ID) override; @@ -36,27 +37,21 @@ namespace DanBias void CloseSession(NetworkSession* clientDestination) override; private: //overriden Threading functions - void ThreadEntry() override; - void ThreadExit() override; + void ThreadEntry( ) override; + void ThreadExit( ) override; bool DoWork ( ) override; private: - void Init(); + bool Init(GameSessionDescription& desc); void Frame(); void ParseEvents(); + void ParseProtocol(Oyster::Network::CustomNetProtocol& p, DanBias::ClientObject& c); private: NetworkSession* owner; Oyster::IPostBox *box; Oyster::Thread::OysterThread worker; -#pragma region TESTING - void EricLogicInitFunc(); - void EricLogicFrameFunc(); - void EricsLogicTestingProtocalRecieved(ClientObject* reciever, Oyster::Network::CustomNetProtocol& protocol); -#pragma endregion - - };//End GameSession }//End namespace DanBias #endif // !DANBIASSERVER_GAME_SESSION_H \ No newline at end of file diff --git a/Code/Game/DanBiasServer/ServerObjects/Lobby/GameLobby.cpp b/Code/Game/DanBiasServer/ServerObjects/Lobby/GameLobby.cpp index 06efcb96..72833d29 100644 --- a/Code/Game/DanBiasServer/ServerObjects/Lobby/GameLobby.cpp +++ b/Code/Game/DanBiasServer/ServerObjects/Lobby/GameLobby.cpp @@ -3,7 +3,7 @@ namespace DanBias { - GameLobby::GameLobby() + GameLobby::GameLobby(Utility::DynamicMemory::SmartPointer owner) { } @@ -15,4 +15,11 @@ namespace DanBias { } + void GameLobby::Join(Utility::DynamicMemory::SmartPointer client) + { + NetworkSession::AttachClient(client); + } + + void GameLobby::AttachClient(Utility::DynamicMemory::SmartPointer client, Oyster::IPostBox *box) + { } }//End namespace DanBias \ No newline at end of file diff --git a/Code/Game/DanBiasServer/ServerObjects/Lobby/GameLobby.h b/Code/Game/DanBiasServer/ServerObjects/Lobby/GameLobby.h index a328271e..6b6ea383 100644 --- a/Code/Game/DanBiasServer/ServerObjects/Lobby/GameLobby.h +++ b/Code/Game/DanBiasServer/ServerObjects/Lobby/GameLobby.h @@ -8,13 +8,15 @@ namespace DanBias class GameLobby :public NetworkSession { public: - GameLobby(); + GameLobby(Utility::DynamicMemory::SmartPointer owner); virtual~GameLobby(); void Release(); - private: + void Join(Utility::DynamicMemory::SmartPointer client); + private: + void AttachClient(Utility::DynamicMemory::SmartPointer client, Oyster::IPostBox *box = 0) override; }; }//End namespace DanBias diff --git a/Code/Game/DanBiasServer/ServerObjects/Lobby/MainLobby.cpp b/Code/Game/DanBiasServer/ServerObjects/Lobby/MainLobby.cpp index 39e5dad1..f111f5ec 100644 --- a/Code/Game/DanBiasServer/ServerObjects/Lobby/MainLobby.cpp +++ b/Code/Game/DanBiasServer/ServerObjects/Lobby/MainLobby.cpp @@ -1,12 +1,20 @@ + #include "MainLobby.h" +#include "..\..\Helpers\ProtocolParser.h" +#include "..\ClientObject.h" #include #include +using namespace Utility::DynamicMemory; +using namespace Oyster::Network; +using namespace Oyster; + namespace DanBias { MainLobby::MainLobby() + :gameLobby(5) { - this->box = new Oyster::PostBox(); + this->box = new PostBox(); } MainLobby::~MainLobby() { @@ -22,6 +30,10 @@ namespace DanBias { ParseEvents(); } + IPostBox* MainLobby::GetPostbox() + { + return this->box; + } //////// Private void MainLobby::ParseEvents() @@ -30,17 +42,56 @@ namespace DanBias { NetEvent &e = this->box->Fetch(); - if(e.protocol[0].type != Oyster::Network::NetAttributeType_Short) return; + ParseProtocol(e.protocol, *e.reciever); + + } + } + void MainLobby::ParseProtocol(Oyster::Network::CustomNetProtocol& p, DanBias::ClientObject& c) + { + //switch (p[0].value.netChar) + //{ + // case protocol_Lobby_CreateGame: + // { + // GameLogic::Protocol_LobbyCreateGame val(p); + // CreateGame(val, c); + // } + // break; + // case protocol_Lobby_JoinGame: + // { + // + // } + // break; + // case protocol_Lobby_JoinLobby: + // { + // + // } + // break; + // case protocol_Lobby_LeaveLobby: + // { + // + // } + // break; + //} - short f = e.protocol[0].value.netShort; + } - switch (f) + void MainLobby::CreateGame(GameLogic::Protocol_LobbyCreateGame& p, DanBias::ClientObject& c) + { + SmartPointer sc = NetworkSession::FindClient(c); + NetworkSession::DetachClient(&c); + + if(!sc) return; + + for (unsigned int i = 0; i < this->gameLobby.Size(); i++) + { + if(!gameLobby[i]) { - default: - - break; + gameLobby[i] = new GameLobby(sc); + return; } } + + this->gameLobby.Push(new GameLobby(sc)); } }//End namespace DanBias \ No newline at end of file diff --git a/Code/Game/DanBiasServer/ServerObjects/Lobby/MainLobby.h b/Code/Game/DanBiasServer/ServerObjects/Lobby/MainLobby.h index 7269f66d..2c188d5c 100644 --- a/Code/Game/DanBiasServer/ServerObjects/Lobby/MainLobby.h +++ b/Code/Game/DanBiasServer/ServerObjects/Lobby/MainLobby.h @@ -2,6 +2,8 @@ #define DANBIASSERVER_MAINLOBBY_H #include "..\NetworkSession.h" +#include "GameLobby.h" +#include #include namespace DanBias @@ -15,12 +17,20 @@ namespace DanBias void Frame(); - private: - void ParseEvents(); + Oyster::IPostBox* GetPostbox(); private: - Oyster::IPostBox *box; - + void ParseEvents(); + void ParseProtocol(Oyster::Network::CustomNetProtocol& p, DanBias::ClientObject& c); + + void CreateGame(GameLogic::Protocol_LobbyCreateGame& p, DanBias::ClientObject& c); + //void CreateJoin(GameLogic::Protocol_LobbyJoinGame& p, DanBias::ClientObject& c); + + //void ProtocolRecievedCallback(CustomNetProtocol& protocol) override; + + private: + Oyster::IPostBox *box; + Utility::DynamicMemory::DynamicArray> gameLobby; }; }//End namespace DanBias #endif // !DANBIASGAME_GAMELOBBY_H diff --git a/Code/Game/DanBiasServer/ServerObjects/NetworkSession.cpp b/Code/Game/DanBiasServer/ServerObjects/NetworkSession.cpp index 56e019c0..c269f681 100644 --- a/Code/Game/DanBiasServer/ServerObjects/NetworkSession.cpp +++ b/Code/Game/DanBiasServer/ServerObjects/NetworkSession.cpp @@ -158,4 +158,23 @@ namespace DanBias ClientListLock.unlock(); } + Utility::DynamicMemory::SmartPointer NetworkSession::FindClient(int ID) + { + for (unsigned int i = 0; i < this->clients.Size(); i++) + { + if(this->clients[i]->NetClient_Object()->Id() == ID) + return this->clients[i]; + } + return Utility::DynamicMemory::SmartPointer(); + } + Utility::DynamicMemory::SmartPointer NetworkSession::FindClient(ClientObject& obj) + { + for (unsigned int i = 0; i < this->clients.Size(); i++) + { + if(this->clients[i]->NetClient_Object()->Id() == obj.NetClient_Object()->Id()) + return this->clients[i]; + } + return Utility::DynamicMemory::SmartPointer(); + } + }//End namespace DanBias \ No newline at end of file diff --git a/Code/Game/DanBiasServer/ServerObjects/NetworkSession.h b/Code/Game/DanBiasServer/ServerObjects/NetworkSession.h index dd87652a..02c9e28f 100644 --- a/Code/Game/DanBiasServer/ServerObjects/NetworkSession.h +++ b/Code/Game/DanBiasServer/ServerObjects/NetworkSession.h @@ -7,7 +7,7 @@ #pragma warning(disable: 4150) #define NOMINMAX -#include "Utilities.h" +#include #include #include #include @@ -47,6 +47,9 @@ namespace DanBias virtual void CloseSession(NetworkSession* clientDestination); // FindClient(int ID); + Utility::DynamicMemory::SmartPointer FindClient(ClientObject& obj); + protected: Utility::DynamicMemory::DynamicArray> clients; }; diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 3d1af2a1..b4a1e50f 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -9,13 +9,10 @@ using namespace Oyster; namespace GameLogic { - namespace CollisionManager - { - void PlayerVBox(Player &player, DynamicObject &box); - Physics::ICustomBody::SubscriptMessage PlayerCollision(const Oyster::Physics::ICustomBody *rigidBodyPlayer, const Oyster::Physics::ICustomBody *obj) + Physics::ICustomBody::SubscriptMessage CollisionManager::PlayerCollision(const Oyster::Physics::ICustomBody *rigidBodyPlayer, const Oyster::Physics::ICustomBody *obj) { Player *player = ((Player*)(rigidBodyPlayer->gameObjectRef)); Object *realObj = (Object*)obj->gameObjectRef; @@ -38,7 +35,7 @@ namespace GameLogic player.DamageLife(20); } - Physics::ICustomBody::SubscriptMessage BoxCollision(const Oyster::Physics::ICustomBody *rigidBodyBox, const Oyster::Physics::ICustomBody *obj) + Physics::ICustomBody::SubscriptMessage CollisionManager::BoxCollision(const Oyster::Physics::ICustomBody *rigidBodyBox, const Oyster::Physics::ICustomBody *obj) { DynamicObject *box = (DynamicObject*)rigidBodyBox->gameObjectRef; Object *realObj = (Object*)obj->gameObjectRef; @@ -55,5 +52,5 @@ namespace GameLogic return Physics::ICustomBody::SubscriptMessage_none; } - } + } \ No newline at end of file diff --git a/Code/Game/GameLogic/CollisionManager.h b/Code/Game/GameLogic/CollisionManager.h index d19ce8e3..18d482b4 100644 --- a/Code/Game/GameLogic/CollisionManager.h +++ b/Code/Game/GameLogic/CollisionManager.h @@ -7,12 +7,13 @@ namespace GameLogic { - namespace CollisionManager + class CollisionManager { + public: //these are the main collision functions //typedef SubscriptMessage (*EventAction_Collision)( const ICustomBody *proto, const ICustomBody *deuter ); - Oyster::Physics::ICustomBody::SubscriptMessage PlayerCollision(const Oyster::Physics::ICustomBody *rigidBodyPlayer, const Oyster::Physics::ICustomBody *obj); - Oyster::Physics::ICustomBody::SubscriptMessage BoxCollision(const Oyster::Physics::ICustomBody *rigidBodyBox, const Oyster::Physics::ICustomBody *obj); + static Oyster::Physics::ICustomBody::SubscriptMessage PlayerCollision(const Oyster::Physics::ICustomBody *rigidBodyPlayer, const Oyster::Physics::ICustomBody *obj); + static Oyster::Physics::ICustomBody::SubscriptMessage BoxCollision(const Oyster::Physics::ICustomBody *rigidBodyBox, const Oyster::Physics::ICustomBody *obj); //these are the specific collision case functions //void PlayerVBox(Player &player, DynamicObject &box); diff --git a/Code/Game/GameLogic/GameLogic.vcxproj b/Code/Game/GameLogic/GameLogic.vcxproj index 11ba6e82..500f8bbc 100644 --- a/Code/Game/GameLogic/GameLogic.vcxproj +++ b/Code/Game/GameLogic/GameLogic.vcxproj @@ -174,6 +174,7 @@ + diff --git a/Code/Game/GameLogic/Weapon.cpp b/Code/Game/GameLogic/Weapon.cpp index b2359ec7..7f4b3308 100644 --- a/Code/Game/GameLogic/Weapon.cpp +++ b/Code/Game/GameLogic/Weapon.cpp @@ -13,6 +13,7 @@ struct Weapon::PrivateData currentNrOfAttatchments = 0; selectedSocketID = 0; maxNrOfSockets = 0; + attatchmentSockets = 0; } ~PrivateData() diff --git a/Code/Game/GameProtocols/GameProtocols.h b/Code/Game/GameProtocols/GameProtocols.h index be3d59a7..b860f400 100644 --- a/Code/Game/GameProtocols/GameProtocols.h +++ b/Code/Game/GameProtocols/GameProtocols.h @@ -3,6 +3,8 @@ #include "ObjectProtocols.h" #include "PlayerProtocols.h" +#include "LobbyProtocols.h" + #include "TEST_PROTOCOLS.h" diff --git a/Code/Game/GameProtocols/GameProtocols.vcxproj b/Code/Game/GameProtocols/GameProtocols.vcxproj index a06b8aca..16f8ebd3 100644 --- a/Code/Game/GameProtocols/GameProtocols.vcxproj +++ b/Code/Game/GameProtocols/GameProtocols.vcxproj @@ -155,6 +155,7 @@ + diff --git a/Code/Game/GameProtocols/LobbyProtocols.h b/Code/Game/GameProtocols/LobbyProtocols.h new file mode 100644 index 00000000..433aeec2 --- /dev/null +++ b/Code/Game/GameProtocols/LobbyProtocols.h @@ -0,0 +1,120 @@ +////////////////////////////////////////////////////////// +// Created 2013 // +// Dennis Andersen, Linda Andersson // +////////////////////////////////////////////////////////// + +#ifndef GAMELOGIC_LOBBY_PROTOCOLS_H +#define GAMELOGIC_LOBBY_PROTOCOLS_H + +#include +#include "ProtocolIdentificationID.h" + +namespace GameLogic +{ + struct Protocol_LobbyCreateGame :public Oyster::Network::CustomProtocolObject + { + char* mapName; + char gameId; + + Protocol_LobbyCreateGame() + { + this->protocol[0].value = protocol_Lobby_CreateGame; + this->protocol[0].type = Oyster::Network::NetAttributeType_Short; + + this->protocol[1].type = Oyster::Network::NetAttributeType_CharArray; + this->protocol[2].type = Oyster::Network::NetAttributeType_Char; + } + Protocol_LobbyCreateGame(Oyster::Network::CustomNetProtocol& o) + { + mapName = o[1].value.netCharPtr; + gameId = o[2].value.netChar; + } + Oyster::Network::CustomNetProtocol* GetProtocol() override + { + protocol[1].value = mapName; + protocol[2].value = gameId; + return &protocol; + } + + private: + Oyster::Network::CustomNetProtocol protocol; + }; + + struct Protocol_LobbyJoinGame :public Oyster::Network::CustomProtocolObject + { + char gameId; + + Protocol_LobbyJoinGame() + { + this->protocol[0].value = protocol_Lobby_JoinGame; + this->protocol[0].type = Oyster::Network::NetAttributeType_Short; + + this->protocol[1].type = Oyster::Network::NetAttributeType_Char; + } + Oyster::Network::CustomNetProtocol* GetProtocol() override + { + protocol[1].value = gameId; + return &protocol; + } + + private: + Oyster::Network::CustomNetProtocol protocol; + }; + + struct Protocol_LobbyStartGame :public Oyster::Network::CustomProtocolObject + { + char gameId; + + Protocol_LobbyStartGame() + { + this->protocol[0].value = protocol_Lobby_StartGame; + this->protocol[0].type = Oyster::Network::NetAttributeType_Short; + + this->protocol[1].type = Oyster::Network::NetAttributeType_Char; + } + Oyster::Network::CustomNetProtocol* GetProtocol() override + { + protocol[1].value = gameId; + return &protocol; + } + + private: + Oyster::Network::CustomNetProtocol protocol; + }; + + struct Protocol_LobbyJoinLobby :public Oyster::Network::CustomProtocolObject + { + Protocol_LobbyJoinLobby() + { + this->protocol[0].value = protocol_Lobby_JoinLobby; + this->protocol[0].type = Oyster::Network::NetAttributeType_Short; + } + Oyster::Network::CustomNetProtocol* GetProtocol() override + { + return &protocol; + } + + private: + Oyster::Network::CustomNetProtocol protocol; + }; + + struct Protocol_LobbyLeaveLobby :public Oyster::Network::CustomProtocolObject + { + + Protocol_LobbyLeaveLobby() + { + this->protocol[0].value = protocol_Lobby_LeaveLobby; + this->protocol[0].type = Oyster::Network::NetAttributeType_Short; + } + Oyster::Network::CustomNetProtocol* GetProtocol() override + { + return &protocol; + } + + private: + Oyster::Network::CustomNetProtocol protocol; + }; + +} + +#endif // !GAMELOGIC_PLAYER_PROTOCOLS_H diff --git a/Code/Game/GameProtocols/ObjectProtocols.h b/Code/Game/GameProtocols/ObjectProtocols.h index 50dbf530..0c211bbf 100644 --- a/Code/Game/GameProtocols/ObjectProtocols.h +++ b/Code/Game/GameProtocols/ObjectProtocols.h @@ -1,5 +1,5 @@ -#ifndef GAMELOGIC_PLAYER_PROTOCOLS_H -#define GAMELOGIC_PLAYER_PROTOCOLS_H +#ifndef GAMELOGIC_OBJECT_PROTOCOLS_H +#define GAMELOGIC_OBJECT_PROTOCOLS_H #include #include "ProtocolIdentificationID.h" diff --git a/Code/Game/GameProtocols/ProtocolIdentificationID.h b/Code/Game/GameProtocols/ProtocolIdentificationID.h index 8e575502..90664777 100644 --- a/Code/Game/GameProtocols/ProtocolIdentificationID.h +++ b/Code/Game/GameProtocols/ProtocolIdentificationID.h @@ -7,18 +7,48 @@ /* THERE CAN ABSOLUTLEY NOT BE TWO DEFINITIONS WITH THE SAME ID!! */ -#define protocol_Gamplay_PlayerNavigation 0 -#define protocol_Gamplay_PlayerMouseMovement 1 -#define protocol_Gamplay_PlayerPosition 2 -#define protocol_Gamplay_CreateObject 3 -#define protocol_Gamplay_ObjectPosition 4 -#define protocol_Lobby_Msg 100 +/***********************************/ +/********* RESERVERD PROTOCOLS *****/ +/********** [ 0 - 96 ] *********/ +#define protocol_TypeId_Lobby 97 +#define protocol_TypeId_General 98 +#define protocol_TypeId_Gameplay 99 -#define protocol_General_Disconnect 200 -#define protocol_General_Ping 201 +/***********************************/ +/********* GENERAL PROTOCOLS *******/ +/***********[ 200 - 300 ]***********/ +#define protocol_General_Disconnect 100 +#define protocol_General_Ping 101 +#define protocol_General_Text 102 + + +/***********************************/ +/********* LOBBY PROTOCOLS *********/ +/***********[ 100 - 200 ]***********/ +#define protocol_Lobby_CreateGame 200 +#define protocol_Lobby_JoinGame 201 +#define protocol_Lobby_StartGame 202 +#define protocol_Lobby_JoinLobby 203 +#define protocol_Lobby_LeaveLobby 204 +#define protocol_Lobby_CreateGameLobby 205 + + +/***********************************/ +/********* GAMEPLAY PROTOCOLS ******/ +/***********[ 300 - 400 ]***********/ +#define protocol_Gamplay_PlayerNavigation 300 +#define protocol_Gamplay_PlayerMouseMovement 301 +#define protocol_Gamplay_PlayerPosition 302 +#define protocol_Gamplay_CreateObject 303 +#define protocol_Gamplay_ObjectPosition 304 + + +/***********************************/ +/*********** TEST PROTOCOLS ********/ +/***********[ 1000 - x ]************/ #define PROTOCOL_TEST 1000 #endif // !GAMEPROTOCOL_PROTOCOL_DEFINITION_ID_H diff --git a/Code/Misc/Thread/OysterThread.h b/Code/Misc/Thread/OysterThread.h index 51f1cf6e..ec150857 100644 --- a/Code/Misc/Thread/OysterThread.h +++ b/Code/Misc/Thread/OysterThread.h @@ -12,8 +12,16 @@ namespace Oyster { enum OYSTER_THREAD_ERROR { - OYSTER_THREAD_ERROR_FAILED, OYSTER_THREAD_ERROR_SUCCESS, + OYSTER_THREAD_ERROR_ThreadAlreadyCreated, + OYSTER_THREAD_ERROR_ThreadCreationFailed, + OYSTER_THREAD_ERROR_ThreadNotCreated, + OYSTER_THREAD_ERROR_ThreadHasNoWorker, + OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe, + OYSTER_THREAD_ERROR_ThreadCannotBeWaitedOn, + OYSTER_THREAD_ERROR_ThreadIsDead, + + OYSTER_THREAD_ERROR_FAILED, }; enum OYSTER_THREAD_PRIORITY { @@ -34,21 +42,22 @@ namespace Oyster const OysterThread& operator=(const OysterThread& original); virtual~OysterThread(); - OYSTER_THREAD_ERROR Create(IThreadObject* worker, bool start); + OYSTER_THREAD_ERROR Create(IThreadObject* worker, bool start, bool detach = false); OYSTER_THREAD_ERROR Start(); - void Stop(bool wait = false); - void Pause(); - void Pause(int mSec); - void Resume(); + OYSTER_THREAD_ERROR Stop(bool wait = false); + OYSTER_THREAD_ERROR Pause(); + OYSTER_THREAD_ERROR Pause(int mSec); + OYSTER_THREAD_ERROR Resume(); OYSTER_THREAD_ERROR Reset(IThreadObject* worker = 0); - void Terminate(bool wait = false); - void Wait(); - void Wait(int mSec); + OYSTER_THREAD_ERROR Terminate(bool wait = true); + OYSTER_THREAD_ERROR Wait(); + OYSTER_THREAD_ERROR Wait(int mSec); OYSTER_THREAD_ERROR Swap(const OysterThread* other); - bool IsActive(); - void SetPriority(OYSTER_THREAD_PRIORITY priority); + void SetPriority(OYSTER_THREAD_PRIORITY priority); + bool IsActive(); bool IsCreated() const; + }; } } diff --git a/Code/Misc/Thread/OysterThread_Impl.cpp b/Code/Misc/Thread/OysterThread_Impl.cpp index cbc4b8ea..4d820eb1 100644 --- a/Code/Misc/Thread/OysterThread_Impl.cpp +++ b/Code/Misc/Thread/OysterThread_Impl.cpp @@ -3,148 +3,169 @@ ///////////////////////////////////////////////////////////////////// #include "OysterThread.h" -#include "OysterMutex.h" #include "..\Utilities.h" #include #include #include +#include using namespace Oyster::Thread; using namespace Utility::DynamicMemory; -#pragma region Declerations - struct ThreadData; - /** A typical Oyster thread function */ - typedef void (*ThreadFunction)(SmartPointer&); + +#pragma region Declerations enum OYSTER_THREAD_STATE { - OYSTER_THREAD_STATE_RESET, - OYSTER_THREAD_STATE_RUNNING, - OYSTER_THREAD_STATE_PAUSED, - OYSTER_THREAD_STATE_STOPED, + OYSTER_THREAD_STATE_IDLE, + OYSTER_THREAD_STATE_NORMAL, OYSTER_THREAD_STATE_DEAD, }; - struct ThreadData { OYSTER_THREAD_STATE state; // workerThread; // msec; //owner = 0; - this->state = OYSTER_THREAD_STATE_DEAD; - if(this->workerThread) - { - //@todo TODO: Make detatch avalible. - if(this->workerThread->joinable()) - this->workerThread->detach(); - } + //std::timed_mutex threadFunctionLock; + //std::mutex threadWaitFunctionLock; + }; + + /** A typical Oyster thread function */ + typedef void (*ThreadFunction)(ThreadData* w); + + struct RefData + { + bool isCreated; + ThreadData *threadData; + std::thread workerThread; + + RefData() + { + threadData = 0; + isCreated = false; + } + ~RefData() + { + Terminate(true); + delete threadData; + } + OYSTER_THREAD_ERROR Terminate(bool wait) + { + if(!threadData) return OYSTER_THREAD_ERROR_SUCCESS; + + this->threadData->state = OYSTER_THREAD_STATE_DEAD; + + if(wait) + { + if(std::this_thread::get_id() != this->workerThread.get_id()) + if(this->workerThread.joinable()) + this->workerThread.join(); + } + else + { + if(this->workerThread.joinable()) + this->workerThread.detach(); + } + return OYSTER_THREAD_ERROR_SUCCESS; + } + OYSTER_THREAD_ERROR Create(ThreadFunction fnc, IThreadObject* worker, bool start, bool detach) + { + if(this->isCreated ) return OYSTER_THREAD_ERROR_ThreadAlreadyCreated; + + threadData = new ThreadData(); + if(start) + this->threadData->state = OYSTER_THREAD_STATE_NORMAL; + else + this->threadData->state = OYSTER_THREAD_STATE_IDLE; + threadData->owner = worker; + threadData->prio = OYSTER_THREAD_PRIORITY_3; + + workerThread = std::thread(fnc, this->threadData); + + if(detach) + this->workerThread.detach(); + + isCreated = true; + + return OYSTER_THREAD_ERROR_SUCCESS; } - ThreadData(const ThreadData&) - {}; - const ThreadData& operator =(const ThreadData& o) - {}; }; struct OysterThread::PrivateData { - bool isCreated; - SmartPointer threadData; - - PrivateData() - { - isCreated = false; - threadData = new ThreadData(); - threadData->first = true; - threadData->owner = 0; - threadData->workerThread = 0; - threadData->callingThread; - threadData->state = OYSTER_THREAD_STATE_STOPED; - threadData->prio = OYSTER_THREAD_PRIORITY_3; - } - PrivateData(const PrivateData& o) - { - isCreated = o.isCreated; - threadData = o.threadData; - } - const PrivateData& operator=(const PrivateData& o) - { - threadData = o.threadData; - } - ~PrivateData() - { - //if(threadData.Release() == 0) - //{ - // if(this->threadData->workerThread->joinable()) - // { - // this->threadData->workerThread->join(); - // } - //} - } + SmartPointer data; + OYSTER_THREAD_ERROR Create(ThreadFunction fnc, IThreadObject* worker, bool start, bool detach) + { + if(data) return OYSTER_THREAD_ERROR_ThreadAlreadyCreated; + data = new RefData(); + return data->Create(fnc, worker, start, detach); + } + OYSTER_THREAD_ERROR Terminate(bool wait) + { + return data->Terminate(wait); + } + }; + + class ThreadHelp + { + public: + static void CheckPriority(ThreadData* w) + { + switch (w->prio) + { + case Oyster::Thread::OYSTER_THREAD_PRIORITY_1: + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + break; + case Oyster::Thread::OYSTER_THREAD_PRIORITY_2: + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + break; + case Oyster::Thread::OYSTER_THREAD_PRIORITY_3: + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + break; + } + } + static bool DoWork(ThreadData* w) + { + if(w->owner) + return w->owner->DoWork(); + + return true; + } + static void CheckStatus(ThreadData* w) + { + if(w->msec > 0) + std::this_thread::sleep_for(std::chrono::milliseconds(w->msec)); + + while (w->state == OYSTER_THREAD_STATE_IDLE) + std::this_thread::yield(); + } + static void ThreadingFunction(ThreadData* w) + { + CheckStatus(w); + + if(w->owner) w->owner->ThreadEntry(); + + while (w->state == OYSTER_THREAD_STATE_NORMAL) + { + CheckPriority(w); + if(!DoWork(w)) break; + CheckStatus(w); + } + + if(w->owner) w->owner->ThreadExit(); + + w->state = OYSTER_THREAD_STATE_DEAD; + } }; #pragma endregion -static void ThreadingFunction(SmartPointer &origin) -{ - - bool shouldContinue = true; - SmartPointer w = origin; - -theBegining: - - while(w->state == OYSTER_THREAD_STATE_STOPED) std::this_thread::yield(); - - if(w->owner) w->owner->ThreadEntry(); - w->first = false; - while (w->state != OYSTER_THREAD_STATE_STOPED && w->state != OYSTER_THREAD_STATE_DEAD && shouldContinue) - { - switch (w->prio) - { - case Oyster::Thread::OYSTER_THREAD_PRIORITY_2: - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - break; - case Oyster::Thread::OYSTER_THREAD_PRIORITY_3: - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - //std::this_thread::yield(); - break; - } - if(w->owner) - shouldContinue = w->owner->DoWork(); - - if(w->state == OYSTER_THREAD_STATE_RESET) goto theBegining; - else if(w->msec > 0) std::this_thread::sleep_for(std::chrono::milliseconds(w->msec)); - - while (w->state == OYSTER_THREAD_STATE_PAUSED) std::this_thread::yield(); - } - - if(w->state == OYSTER_THREAD_STATE_DEAD) - { - if(w->workerThread->joinable()) - w->workerThread->detach(); - - return; - } - -//theEnd: - - if(w->owner) w->owner->ThreadExit(); - w->state = OYSTER_THREAD_STATE_DEAD; -} - OysterThread::OysterThread() { this->privateData = new PrivateData(); @@ -156,7 +177,8 @@ OysterThread::OysterThread(const OysterThread& original) const OysterThread& OysterThread::operator=(const OysterThread& original) { delete this->privateData; - this->privateData = new PrivateData(*original.privateData); + this->privateData = new PrivateData(); + this->privateData->data = original.privateData->data; return *this; } OysterThread::~OysterThread() @@ -165,133 +187,117 @@ OysterThread::~OysterThread() this->privateData = 0; } -OYSTER_THREAD_ERROR OysterThread::Create(IThreadObject* worker, bool start) +OYSTER_THREAD_ERROR OysterThread::Create(IThreadObject* worker, bool start, bool detach) { - if(!this->privateData) return OYSTER_THREAD_ERROR_FAILED; - if(this->IsCreated()) return OYSTER_THREAD_ERROR_FAILED; - if(this->privateData->threadData->workerThread) return OYSTER_THREAD_ERROR_FAILED; - - this->privateData->threadData->owner = worker; - - ThreadFunction fnc = ThreadingFunction; - - //Maby move this thread creation to a seperate Start() function because std::thread fires the thread when it is created. :( - this->privateData->threadData->workerThread = new std::thread(fnc, this->privateData->threadData); - - if(!this->privateData->threadData->workerThread) - return OYSTER_THREAD_ERROR_FAILED; - - if(start) - { - this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING; - } - - this->privateData->isCreated = true; - return OYSTER_THREAD_ERROR_SUCCESS; + if(!this->privateData) + this->privateData = new PrivateData(); + + return this->privateData->Create(ThreadHelp::ThreadingFunction, worker, start, detach); } OYSTER_THREAD_ERROR OysterThread::Start() { - if(!this->privateData->threadData->owner) - return OYSTER_THREAD_ERROR_FAILED; - if(!this->privateData->threadData->workerThread) - return OYSTER_THREAD_ERROR_FAILED; - if(this->privateData->threadData->state == OYSTER_THREAD_STATE_DEAD) - return OYSTER_THREAD_ERROR_FAILED; + if(!this->privateData->data->threadData->owner) + return OYSTER_THREAD_ERROR_ThreadHasNoWorker; + + if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD) + return OYSTER_THREAD_ERROR_ThreadIsDead; + + this->privateData->data->threadData->state = OYSTER_THREAD_STATE_NORMAL; - this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING; return OYSTER_THREAD_ERROR_SUCCESS; } -void OysterThread::Stop(bool wait) +OYSTER_THREAD_ERROR OysterThread::Stop(bool wait) { - //this->privateData->threadData->mutexLock.LockMutex(); - this->privateData->threadData->state = OYSTER_THREAD_STATE_STOPED; - //this->privateData->threadData->mutexLock.UnlockMutex(); + return this->Terminate(wait); } -void OysterThread::Pause() +OYSTER_THREAD_ERROR OysterThread::Pause() { - //this->privateData->threadData->mutexLock.LockMutex(); - this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED; - //this->privateData->threadData->mutexLock.UnlockMutex(); + this->privateData->data->threadData->state = OYSTER_THREAD_STATE_IDLE; + return OYSTER_THREAD_ERROR_SUCCESS; } -void OysterThread::Pause(int msec) +OYSTER_THREAD_ERROR OysterThread::Pause(int msec) { + this->privateData->data->threadData->msec = msec; + return OYSTER_THREAD_ERROR_SUCCESS; +} +OYSTER_THREAD_ERROR OysterThread::Resume() +{ + if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD) + return OYSTER_THREAD_ERROR_ThreadIsDead; - if(std::this_thread::get_id() == this->privateData->threadData->workerThread->get_id()) - { - this->privateData->threadData->msec = msec; - } - else - { - this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED; - this->privateData->threadData->msec = msec; - } -} -void OysterThread::Resume() -{ -// this->privateData->threadData->mutexLock.LockMutex(); - this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING; -// this->privateData->threadData->mutexLock.UnlockMutex(); + this->privateData->data->threadData->state = OYSTER_THREAD_STATE_NORMAL; + + return OYSTER_THREAD_ERROR_SUCCESS; } OYSTER_THREAD_ERROR OysterThread::Reset(IThreadObject* worker) { -// this->privateData->threadData->mutexLock.LockMutex(); - if(worker) - { - this->privateData->threadData->owner = worker; - } - this->privateData->threadData->callingThread = std::this_thread::get_id(); - this->privateData->threadData->msec = 0; -// this->privateData->threadData->mutexLock.UnlockMutex(); + this->privateData->data->threadData->owner = worker; + + this->privateData->data->threadData->msec = 0; + + return OYSTER_THREAD_ERROR_SUCCESS;; +} +OYSTER_THREAD_ERROR OysterThread::Terminate(bool wait) +{ + //this->privateData->data->threadData->state = OYSTER_THREAD_STATE_DEAD; + // + //if(std::this_thread::get_id() == this->privateData->data->workerThread->get_id()) + // return OYSTER_THREAD_ERROR_SUCCESS; + // + //if(wait) + //{ + // if(this->privateData->data->workerThread->joinable()) + // this->privateData->data->workerThread->detach(); + // + // this->privateData->data->threadData->threadFunctionLock.lock(); + // this->privateData->data->threadData->threadFunctionLock.unlock(); + //} + + return this->privateData->Terminate(wait); + + //return OYSTER_THREAD_ERROR_SUCCESS; +} +OYSTER_THREAD_ERROR OysterThread::Wait() +{ + if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD) + return OYSTER_THREAD_ERROR_ThreadIsDead; + + if( this->privateData->data->workerThread.get_id() == std::this_thread::get_id()) + return OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe; + + //this->privateData->data->threadData->threadFunctionLock.lock(); + //this->privateData->data->threadData->threadFunctionLock.unlock(); return OYSTER_THREAD_ERROR_SUCCESS; } -void OysterThread::Terminate(bool wait) +OYSTER_THREAD_ERROR OysterThread::Wait(int msec) { - this->privateData->threadData->state = OYSTER_THREAD_STATE_DEAD; -} -void OysterThread::Wait() -{ - if(this->privateData->threadData->state == OYSTER_THREAD_STATE_DEAD) - { return; } + if(this->privateData->data->workerThread.get_id() == std::this_thread::get_id()) + return OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe; - if( this->privateData->threadData->workerThread - && - this->privateData->threadData->workerThread->get_id() == std::this_thread::get_id()) - return; + //if(this->privateData->data->threadData->threadFunctionLock.try_lock_for(std::chrono::milliseconds(msec))) + // this->privateData->data->threadData->threadFunctionLock.unlock(); - //if(this->privateData->threadData->state == OYSTER_THREAD_STATE_STOPED) - if(this->privateData->threadData->first) - { return; } - - if(this->privateData->threadData->workerThread) - if(this->privateData->threadData->workerThread->joinable()) - this->privateData->threadData->workerThread->join(); -} -void OysterThread::Wait(int msec) -{ - if(this->privateData->threadData->workerThread->get_id() == std::this_thread::get_id()) return; - - //TODO: Sync with thread. - - //std::this_thread::sleep_for(std::chrono::milliseconds(msec)); + return OYSTER_THREAD_ERROR_SUCCESS; } OYSTER_THREAD_ERROR OysterThread::Swap(const OysterThread* other) { - this->privateData->threadData->workerThread->swap(*other->privateData->threadData->workerThread); + this->privateData->data->workerThread.swap(other->privateData->data->workerThread); return OYSTER_THREAD_ERROR_SUCCESS; } + +void OysterThread::SetPriority(OYSTER_THREAD_PRIORITY priority) +{ + this->privateData->data->threadData->prio = priority; +} bool OysterThread::IsActive() { - if (this->privateData->threadData->state == OYSTER_THREAD_STATE_RUNNING) + if (this->privateData->data->threadData->state == OYSTER_THREAD_STATE_NORMAL) return true; return false; } -void OysterThread::SetPriority(OYSTER_THREAD_PRIORITY priority) -{ - this->privateData->threadData->prio = priority; -} bool OysterThread::IsCreated() const { - return privateData->isCreated; + return privateData->data->isCreated; } diff --git a/Code/Misc/Utilities-Impl.h b/Code/Misc/Utilities-Impl.h index 6567d9eb..6ede28d0 100644 --- a/Code/Misc/Utilities-Impl.h +++ b/Code/Misc/Utilities-Impl.h @@ -282,14 +282,17 @@ namespace Utility { //Call child specific Destroy(); - this->_rc = new ReferenceCount(); + if(p) this->_rc = new ReferenceCount(); } } - else + else if(p) + { this->_rc = new ReferenceCount(); - + } + this->_ptr = p; - this->_rc->Incref(); + + if(p) this->_rc->Incref(); } return *this; } @@ -359,6 +362,12 @@ namespace Utility } return returnVal; } + template int SmartPointer::ReleaseDummy() + { + int val = this->_rc->Decref(); + this->_rc->Incref(); + return val; + } template inline bool SmartPointer::IsValid() const { return (this->_ptr != NULL) ? true : false; diff --git a/Code/Misc/Utilities.h b/Code/Misc/Utilities.h index e427d0b3..ae3124f9 100644 --- a/Code/Misc/Utilities.h +++ b/Code/Misc/Utilities.h @@ -235,6 +235,10 @@ namespace Utility * Releases one reference of the pointer and set value to null, making the current SmartPointer invalid. */ int Release(); + /** + * Only test to release to check reference count. + */ + int ReleaseDummy(); /** Checks if the pointer is valid (not NULL) * Returns true for valid, else false. diff --git a/Code/Network/NetworkAPI/NetworkServer.cpp b/Code/Network/NetworkAPI/NetworkServer.cpp index 5a02d767..404f6efa 100644 --- a/Code/Network/NetworkAPI/NetworkServer.cpp +++ b/Code/Network/NetworkAPI/NetworkServer.cpp @@ -41,7 +41,7 @@ struct NetworkServer::PrivateData : public IThreadObject bool started; //Postbox for new clients - IPostBox *postBox; + PostBox postBox; //Server thread OysterThread thread; @@ -52,7 +52,7 @@ NetworkServer::PrivateData::PrivateData() { listener = 0; started = false; - postBox = new PostBox; + //postBox = new PostBox; } NetworkServer::PrivateData::~PrivateData() @@ -74,7 +74,7 @@ bool NetworkServer::PrivateData::Init(INIT_DESC& initDesc) this->initDesc = initDesc; //Initiate listener - listener = new Listener(postBox); + listener = new Listener(&postBox); if(!((Listener*)listener)->Init(this->initDesc.port, false)) { return false; @@ -120,21 +120,12 @@ void NetworkServer::PrivateData::Stop() void NetworkServer::PrivateData::Shutdown() { - //Stop server main thread - thread.Stop(); - if(listener) { delete listener; listener = NULL; } - if(postBox) - { - delete postBox; - postBox = NULL; - } - started = false; ShutdownWinSock(); @@ -143,9 +134,9 @@ void NetworkServer::PrivateData::Shutdown() //Checks for new clients and sends them to the proc function. void NetworkServer::PrivateData::CheckForNewClient() { - if(postBox->IsFull()) + if(postBox.IsFull()) { - int clientSocketNum = postBox->FetchMessage(); + int clientSocketNum = postBox.FetchMessage(); //Safety check that is probably not needed. if(clientSocketNum == -1) diff --git a/Code/Network/NetworkDependencies/Listener.cpp b/Code/Network/NetworkDependencies/Listener.cpp index 20d4c927..e371ad54 100644 --- a/Code/Network/NetworkDependencies/Listener.cpp +++ b/Code/Network/NetworkDependencies/Listener.cpp @@ -19,7 +19,7 @@ Listener::~Listener() { if(connection) { - this->thread.Terminate(); + this->thread.Terminate(false); delete connection; connection = 0; } @@ -99,6 +99,7 @@ int Listener::Accept() bool Listener::DoWork() { + if(!this->connection) return false; int result = Accept(); if(result == -1)