Fixed some threafing and stuff

This commit is contained in:
Dennis Andersen 2013-12-19 12:32:23 +01:00
parent 92b3525587
commit beb116e964
33 changed files with 758 additions and 357 deletions

View File

@ -30,6 +30,7 @@ int WINAPI WinMain( HINSTANCE hinst, HINSTANCE prevInst, PSTR cmdLine, int cmdSh
DanBias::DanBiasGameDesc gameDesc; DanBias::DanBiasGameDesc gameDesc;
gameDesc.port = 15151; gameDesc.port = 15151;
gameDesc.IP = "193.11.184.196"; gameDesc.IP = "193.11.184.196";
gameDesc.IP = "127.0.0.1";
gameDesc.hinst = hinst; gameDesc.hinst = hinst;
gameDesc.nCmdShow = cmdShow; gameDesc.nCmdShow = cmdShow;

View File

@ -113,7 +113,7 @@
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<DelayLoadDLLs>GameLogic_$(PlatformShortName)D.dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName)D.dll</DelayLoadDLLs> <DelayLoadDLLs>GameLogic_$(PlatformShortName)D.dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName)D.dll;GamePhysics_$(PlatformShortName)D.dll</DelayLoadDLLs>
<AdditionalDependencies>NetworkAPI_$(PlatformShortName)D.lib;WindowManager_$(PlatformShortName)D.lib;GameLogic_$(PlatformShortName)D.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>NetworkAPI_$(PlatformShortName)D.lib;WindowManager_$(PlatformShortName)D.lib;GameLogic_$(PlatformShortName)D.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -130,7 +130,7 @@
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<DelayLoadDLLs>GameLogic_$(PlatformShortName)D.dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName)D.dll</DelayLoadDLLs> <DelayLoadDLLs>GameLogic_$(PlatformShortName)D.dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName)D.dll;GamePhysics_$(PlatformShortName)D.dll</DelayLoadDLLs>
<AdditionalDependencies>NetworkAPI_$(PlatformShortName)D.lib;WindowManager_$(PlatformShortName)D.lib;GameLogic_$(PlatformShortName)D.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>NetworkAPI_$(PlatformShortName)D.lib;WindowManager_$(PlatformShortName)D.lib;GameLogic_$(PlatformShortName)D.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -151,7 +151,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<DelayLoadDLLs>GameLogic_$(PlatformShortName).dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName).dll</DelayLoadDLLs> <DelayLoadDLLs>GameLogic_$(PlatformShortName).dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName).dll;GamePhysics_$(PlatformShortName).dll</DelayLoadDLLs>
<AdditionalDependencies>NetworkAPI_$(PlatformShortName).lib;WindowManager_$(PlatformShortName).lib;GameLogic_$(PlatformShortName).lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>NetworkAPI_$(PlatformShortName).lib;WindowManager_$(PlatformShortName).lib;GameLogic_$(PlatformShortName).lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -172,12 +172,13 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<DelayLoadDLLs>GameLogic_$(PlatformShortName).dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName).dll</DelayLoadDLLs> <DelayLoadDLLs>GameLogic_$(PlatformShortName).dll;%(DelayLoadDLLs);NetworkAPI_$(PlatformShortName).dll;GamePhysics_$(PlatformShortName).dll</DelayLoadDLLs>
<AdditionalDependencies>NetworkAPI_$(PlatformShortName).lib;WindowManager_$(PlatformShortName).lib;GameLogic_$(PlatformShortName).lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>NetworkAPI_$(PlatformShortName).lib;WindowManager_$(PlatformShortName).lib;GameLogic_$(PlatformShortName).lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="GameSessionManager.cpp" /> <ClCompile Include="Helpers\GameSessionManager.cpp" />
<ClCompile Include="Helpers\ProtocolParser.cpp" />
<ClCompile Include="Include\DanBiasServerAPI.cpp" /> <ClCompile Include="Include\DanBiasServerAPI.cpp" />
<ClCompile Include="DLLMain.cpp" /> <ClCompile Include="DLLMain.cpp" />
<ClCompile Include="GameServer.cpp" /> <ClCompile Include="GameServer.cpp" />
@ -186,18 +187,21 @@
<ClCompile Include="ServerObjects\GameSession.cpp" /> <ClCompile Include="ServerObjects\GameSession.cpp" />
<ClCompile Include="ServerObjects\Lobby\MainLobby.cpp" /> <ClCompile Include="ServerObjects\Lobby\MainLobby.cpp" />
<ClCompile Include="ServerObjects\NetworkSession.cpp" /> <ClCompile Include="ServerObjects\NetworkSession.cpp" />
<ClCompile Include="Test\TEST.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Event\EventManager.h" /> <ClInclude Include="Event\EventManager.h" />
<ClInclude Include="GameServer.h" /> <ClInclude Include="GameServer.h" />
<ClInclude Include="GameSessionManager.h" /> <ClInclude Include="Helpers\GameSessionManager.h" />
<ClInclude Include="Include\DanBiasServerAPI.h" /> <ClInclude Include="Include\DanBiasServerAPI.h" />
<ClInclude Include="ServerInitReader.h" /> <ClInclude Include="Helpers\ServerInitReader.h" />
<ClInclude Include="ServerObjects\ClientObject.h" /> <ClInclude Include="ServerObjects\ClientObject.h" />
<ClInclude Include="ServerObjects\GameSession.h" /> <ClInclude Include="ServerObjects\GameSession.h" />
<ClInclude Include="ServerObjects\Lobby\GameLobby.h" /> <ClInclude Include="ServerObjects\Lobby\GameLobby.h" />
<ClInclude Include="ServerObjects\Lobby\MainLobby.h" /> <ClInclude Include="ServerObjects\Lobby\MainLobby.h" />
<ClInclude Include="ServerObjects\NetworkSession.h" /> <ClInclude Include="ServerObjects\NetworkSession.h" />
<ClInclude Include="Helpers\ProtocolParser.h" />
<ClInclude Include="Test\TEST.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\GamePhysics\GamePhysics.vcxproj"> <ProjectReference Include="..\..\GamePhysics\GamePhysics.vcxproj">

View File

@ -2,28 +2,43 @@
// Created by [Dennis Andersen] [2013] // Created by [Dennis Andersen] [2013]
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#define NOMINMAX #define NOMINMAX
#include "Test\TEST.h"
#include <Windows.h> #include <Windows.h>
#include <WindowShell.h> #include <WindowShell.h>
#include <iostream> #include <iostream>
#include "GameServer.h" #include "GameServer.h"
#include "Utilities.h" #include "Utilities.h"
#include "ServerInitReader.h" #include "Helpers\ServerInitReader.h"
#include <TEST_PROTOCOLS.h>
#include <Thread\OysterThread.h> #include <Thread\OysterThread.h>
#include "ServerObjects\ClientObject.h" #include "ServerObjects\ClientObject.h"
#include "ServerObjects\GameSession.h"
#include <CollisionManager.h>
namespace DanBias namespace DanBias
{ {
using namespace Oyster::Network; using namespace Oyster::Network;
static GameSession *myTest;
void GameServer::ClientConnectCallback(NetworkClient* client) void GameServer::ClientConnectCallback(NetworkClient* client)
{ {
printf("Client connected!\n"); if(!myTest)
{
myTest = new GameSession();
Utility::DynamicMemory::SmartPointer<ClientObject> c = new ClientObject(client);
DanBias::GameSession::GameSessionDescription desc;
desc.owner = 0;
desc.clients.Push(c);
Utility::DynamicMemory::SmartPointer<ClientObject> c = new ClientObject(client); myTest->Run(desc);
this->mainLobby->AttachClient(c); }
//printf("Client connected with socket: %i\n", client->Id());
//
//Utility::DynamicMemory::SmartPointer<ClientObject> c = new ClientObject(client);
//this->mainLobby->AttachClient(c, this->mainLobby->GetPostbox());
} }
GameServer::GameServer() GameServer::GameServer()
: initiated(0) : initiated(0)
@ -32,8 +47,7 @@ namespace DanBias
, maxClients(0) , maxClients(0)
, mainLobby(0) , mainLobby(0)
, server(0) , server(0)
{ { }
}
GameServer::~GameServer() GameServer::~GameServer()
{ {
@ -78,9 +92,9 @@ namespace DanBias
} }
DanBiasServerReturn GameServer::Release() DanBiasServerReturn GameServer::Release()
{ {
delete this->mainLobby;
this->server->Shutdown(); this->server->Shutdown();
delete this->server; delete this->server;
delete this->mainLobby;
this->released = true; this->released = true;
return DanBiasServerReturn_Sucess; return DanBiasServerReturn_Sucess;
} }

View File

@ -1,6 +1,6 @@
#include "GameSessionManager.h" #include "GameSessionManager.h"
#include "ServerObjects\GameSession.h" #include "..\ServerObjects\GameSession.h"
#include "DynamicArray.h" #include "DynamicArray.h"
struct GameSessionData struct GameSessionData
@ -25,30 +25,30 @@ struct GameSessionData
return -1; return -1;
} }
} __gameSessionData; } gameSessionData;
void GameSessionManager::AddSession(DanBias::GameSession* session) 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); if(k == -1) gameSessionData.sessions.Push(session);
else __gameSessionData.sessions[k] = session; else gameSessionData.sessions[k] = session;
} }
} }
void GameSessionManager::CloseSession(DanBias::GameSession* session) void GameSessionManager::CloseSession(DanBias::GameSession* session)
{ {
int i = __gameSessionData.Existst(session); int i = gameSessionData.Existst(session);
//Moron check... //Moron check...
if(i == -1) return; if(i == -1) return;
//__gameSessionData.sessions[i]->Close(); //gameSessionData.sessions[i]->Close();
} }

View File

@ -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;
}

View File

@ -0,0 +1,27 @@
#ifndef DANBIASSERVER_PROTOCOLPARSER_H
#define DANBIASSERVER_PROTOCOLPARSER_H
#include <GameProtocols.h>
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

View File

@ -10,7 +10,7 @@ namespace DanBias
{ {
InitPath_ServerIni, InitPath_ServerIni,
}; };
std::string GetInitPath(InitPath file) static std::string GetInitPath(InitPath file)
{ {
std::string type = ""; std::string type = "";
std::string path = ""; std::string path = "";

View File

@ -12,7 +12,10 @@ ClientObject::~ClientObject()
{ {
this->client->Disconnect(); this->client->Disconnect();
} }
void ClientObject::SetProtocolCallback(Oyster::Network::ProtocolRecieverObject* object)
{
this->NetClient_Object()->SetRecieverObject(object, Oyster::Network::NetworkProtocolCallbackType_Object);
}
void ClientObject::SetPostbox(Oyster::IPostBox<NetworkSession::NetEvent>* box) void ClientObject::SetPostbox(Oyster::IPostBox<NetworkSession::NetEvent>* box)
{ {
this->box = box; this->box = box;

View File

@ -17,6 +17,7 @@ namespace DanBias
virtual~ClientObject(); virtual~ClientObject();
void SetPostbox(Oyster::IPostBox<NetworkSession::NetEvent>* box); void SetPostbox(Oyster::IPostBox<NetworkSession::NetEvent>* box);
void SetProtocolCallback(Oyster::Network::ProtocolRecieverObject* object);
GameLogic::Player* Logic_Object(); GameLogic::Player* Logic_Object();
Oyster::Network::NetworkClient* NetClient_Object(); Oyster::Network::NetworkClient* NetClient_Object();

View File

@ -1,8 +1,9 @@
#include <GameProtocols.h> #include <GameProtocols.h>
#include "GameSession.h"
#include <PostBox\PostBox.h> #include <PostBox\PostBox.h>
#include "GameSession.h"
#include "ClientObject.h" #include "ClientObject.h"
#include "..\Helpers\ProtocolParser.h"
#define ERIK #define ERIK
@ -10,29 +11,39 @@
using namespace Utility::DynamicMemory; using namespace Utility::DynamicMemory;
using namespace Oyster::Network; using namespace Oyster::Network;
using namespace Oyster; using namespace Oyster;
using namespace Oyster::Thread;
namespace DanBias namespace DanBias
{ {
GameSession::GameSession() GameSession::GameSession()
{ {
this->box = 0;
} }
GameSession::~GameSession() 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<ClientObject> client)
{
AttachClient(client, this->box);
}
////private: overriden NetworkSession functions
void GameSession::AttachClient(SmartPointer<ClientObject> client, Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box ) void GameSession::AttachClient(SmartPointer<ClientObject> client, Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box )
{ {
this->Init(); NetworkSession::AttachClient(client, box);
} }
////private: //overriden NetworkSession functions
void GameSession::Close() void GameSession::Close()
{ {
@ -84,21 +95,21 @@ namespace DanBias
} }
////private: ////private:
void GameSession::Init() bool GameSession::Init(GameSessionDescription& desc)
{ {
#ifdef ERIK if(desc.clients.Size() == 0) return false;
EricLogicInitFunc(); this->box = new PostBox<NetEvent>();
#else 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]);
}
#endif return true;
} }
void GameSession::Frame() void GameSession::Frame()
{ {
#ifdef ERIK
EricLogicFrameFunc();
#else
#endif
} }
void GameSession::ParseEvents() void GameSession::ParseEvents()
{ {
@ -106,42 +117,47 @@ namespace DanBias
{ {
NetEvent &e = this->box->Fetch(); NetEvent &e = this->box->Fetch();
#ifdef ERIK
EricsLogicTestingProtocalRecieved(e.reciever, e.protocol);
#else
if(e.protocol[0].type != Oyster::Network::NetAttributeType_Short) return; if(e.protocol[0].type != Oyster::Network::NetAttributeType_Short) return;
short f = e.protocol[0].value.netShort; ParseProtocol(e.protocol, *e.reciever);
}
switch (f) }
void GameSession::ParseProtocol(Oyster::Network::CustomNetProtocol& p, DanBias::ClientObject& c)
{
switch (p[0].value.netShort)
{
case protocol_Gamplay_PlayerNavigation:
{ {
default: if(p[1].value.netBool) //bool bForward;
c.Logic_Object()->Move(GameLogic::PLAYER_MOVEMENT_FORWARD);
break; 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;
} }
} }
#ifdef ERIK
#pragma region TESTING
//VARIABLES GOES HERE //VARIABLES GOES HERE
int i = 0;
GameLogic::Player erik;
void GameSession::EricLogicInitFunc()
{
} #endif
void GameSession::EricLogicFrameFunc()
{
}
void GameSession::EricsLogicTestingProtocalRecieved(ClientObject* reciever, CustomNetProtocol& protocol)
{
}
#pragma endregion
}//End namespace DanBias }//End namespace DanBias

View File

@ -14,19 +14,20 @@ namespace DanBias
struct GameSessionDescription struct GameSessionDescription
{ {
NetworkSession* owner; NetworkSession* owner;
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<ClientObject>> clients;
}; };
public: public:
GameSession(); GameSession();
virtual~GameSession(); virtual~GameSession();
void Run(const GameSessionDescription& desc); void Run(GameSessionDescription& desc);
void AttachClient(Utility::DynamicMemory::SmartPointer<ClientObject> client, Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box = 0) override; void Join(Utility::DynamicMemory::SmartPointer<ClientObject> client);
private: //overriden NetworkSession functions private: //overriden NetworkSession functions
void Close(); void Close();
void AttachClient(Utility::DynamicMemory::SmartPointer<ClientObject> client, Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box = 0) override;
Utility::DynamicMemory::SmartPointer<ClientObject> DetachClient(Oyster::Network::NetworkClient* client) override; Utility::DynamicMemory::SmartPointer<ClientObject> DetachClient(Oyster::Network::NetworkClient* client) override;
Utility::DynamicMemory::SmartPointer<ClientObject> DetachClient(ClientObject* client) override; Utility::DynamicMemory::SmartPointer<ClientObject> DetachClient(ClientObject* client) override;
Utility::DynamicMemory::SmartPointer<ClientObject> DetachClient(short ID) override; Utility::DynamicMemory::SmartPointer<ClientObject> DetachClient(short ID) override;
@ -36,27 +37,21 @@ namespace DanBias
void CloseSession(NetworkSession* clientDestination) override; void CloseSession(NetworkSession* clientDestination) override;
private: //overriden Threading functions private: //overriden Threading functions
void ThreadEntry() override; void ThreadEntry( ) override;
void ThreadExit() override; void ThreadExit( ) override;
bool DoWork ( ) override; bool DoWork ( ) override;
private: private:
void Init(); bool Init(GameSessionDescription& desc);
void Frame(); void Frame();
void ParseEvents(); void ParseEvents();
void ParseProtocol(Oyster::Network::CustomNetProtocol& p, DanBias::ClientObject& c);
private: private:
NetworkSession* owner; NetworkSession* owner;
Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box; Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box;
Oyster::Thread::OysterThread worker; Oyster::Thread::OysterThread worker;
#pragma region TESTING
void EricLogicInitFunc();
void EricLogicFrameFunc();
void EricsLogicTestingProtocalRecieved(ClientObject* reciever, Oyster::Network::CustomNetProtocol& protocol);
#pragma endregion
};//End GameSession };//End GameSession
}//End namespace DanBias }//End namespace DanBias
#endif // !DANBIASSERVER_GAME_SESSION_H #endif // !DANBIASSERVER_GAME_SESSION_H

View File

@ -3,7 +3,7 @@
namespace DanBias namespace DanBias
{ {
GameLobby::GameLobby() GameLobby::GameLobby(Utility::DynamicMemory::SmartPointer<ClientObject> owner)
{ {
} }
@ -15,4 +15,11 @@ namespace DanBias
{ {
} }
void GameLobby::Join(Utility::DynamicMemory::SmartPointer<ClientObject> client)
{
NetworkSession::AttachClient(client);
}
void GameLobby::AttachClient(Utility::DynamicMemory::SmartPointer<ClientObject> client, Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box)
{ }
}//End namespace DanBias }//End namespace DanBias

View File

@ -8,13 +8,15 @@ namespace DanBias
class GameLobby :public NetworkSession class GameLobby :public NetworkSession
{ {
public: public:
GameLobby(); GameLobby(Utility::DynamicMemory::SmartPointer<ClientObject> owner);
virtual~GameLobby(); virtual~GameLobby();
void Release(); void Release();
private: void Join(Utility::DynamicMemory::SmartPointer<ClientObject> client);
private:
void AttachClient(Utility::DynamicMemory::SmartPointer<ClientObject> client, Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box = 0) override;
}; };
}//End namespace DanBias }//End namespace DanBias

View File

@ -1,12 +1,20 @@
#include "MainLobby.h" #include "MainLobby.h"
#include "..\..\Helpers\ProtocolParser.h"
#include "..\ClientObject.h"
#include <PlayerProtocols.h> #include <PlayerProtocols.h>
#include <PostBox\PostBox.h> #include <PostBox\PostBox.h>
using namespace Utility::DynamicMemory;
using namespace Oyster::Network;
using namespace Oyster;
namespace DanBias namespace DanBias
{ {
MainLobby::MainLobby() MainLobby::MainLobby()
:gameLobby(5)
{ {
this->box = new Oyster::PostBox<DanBias::NetworkSession::NetEvent>(); this->box = new PostBox<DanBias::NetworkSession::NetEvent>();
} }
MainLobby::~MainLobby() MainLobby::~MainLobby()
{ {
@ -22,6 +30,10 @@ namespace DanBias
{ {
ParseEvents(); ParseEvents();
} }
IPostBox<NetworkSession::NetEvent>* MainLobby::GetPostbox()
{
return this->box;
}
//////// Private //////// Private
void MainLobby::ParseEvents() void MainLobby::ParseEvents()
@ -30,17 +42,56 @@ namespace DanBias
{ {
NetEvent &e = this->box->Fetch(); NetEvent &e = this->box->Fetch();
if(e.protocol[0].type != Oyster::Network::NetAttributeType_Short) return; ParseProtocol(e.protocol, *e.reciever);
short f = e.protocol[0].value.netShort; }
}
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;
//}
switch (f) }
void MainLobby::CreateGame(GameLogic::Protocol_LobbyCreateGame& p, DanBias::ClientObject& c)
{
SmartPointer<ClientObject> sc = NetworkSession::FindClient(c);
NetworkSession::DetachClient(&c);
if(!sc) return;
for (unsigned int i = 0; i < this->gameLobby.Size(); i++)
{
if(!gameLobby[i])
{ {
default: gameLobby[i] = new GameLobby(sc);
return;
break;
} }
} }
this->gameLobby.Push(new GameLobby(sc));
} }
}//End namespace DanBias }//End namespace DanBias

View File

@ -2,6 +2,8 @@
#define DANBIASSERVER_MAINLOBBY_H #define DANBIASSERVER_MAINLOBBY_H
#include "..\NetworkSession.h" #include "..\NetworkSession.h"
#include "GameLobby.h"
#include <GameProtocols.h>
#include <PostBox\IPostBox.h> #include <PostBox\IPostBox.h>
namespace DanBias namespace DanBias
@ -15,12 +17,20 @@ namespace DanBias
void Frame(); void Frame();
Oyster::IPostBox<NetworkSession::NetEvent>* GetPostbox();
private: private:
void ParseEvents(); 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: private:
Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box; Oyster::IPostBox<NetworkSession::NetEvent> *box;
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<GameLobby>> gameLobby;
}; };
}//End namespace DanBias }//End namespace DanBias
#endif // !DANBIASGAME_GAMELOBBY_H #endif // !DANBIASGAME_GAMELOBBY_H

View File

@ -158,4 +158,23 @@ namespace DanBias
ClientListLock.unlock(); ClientListLock.unlock();
} }
Utility::DynamicMemory::SmartPointer<ClientObject> 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<ClientObject>();
}
Utility::DynamicMemory::SmartPointer<ClientObject> 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<ClientObject>();
}
}//End namespace DanBias }//End namespace DanBias

View File

@ -7,7 +7,7 @@
#pragma warning(disable: 4150) #pragma warning(disable: 4150)
#define NOMINMAX #define NOMINMAX
#include "Utilities.h" #include <Utilities.h>
#include <DynamicArray.h> #include <DynamicArray.h>
#include <PostBox\IPostBox.h> #include <PostBox\IPostBox.h>
#include <CustomNetProtocol.h> #include <CustomNetProtocol.h>
@ -47,6 +47,9 @@ namespace DanBias
virtual void CloseSession(NetworkSession* clientDestination); //<! Closes the session and sends the clients to given sesison. If session is null, clients is kicked from server. virtual void CloseSession(NetworkSession* clientDestination); //<! Closes the session and sends the clients to given sesison. If session is null, clients is kicked from server.
Utility::DynamicMemory::SmartPointer<ClientObject> FindClient(int ID);
Utility::DynamicMemory::SmartPointer<ClientObject> FindClient(ClientObject& obj);
protected: protected:
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<ClientObject>> clients; Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<ClientObject>> clients;
}; };

View File

@ -9,13 +9,10 @@ using namespace Oyster;
namespace GameLogic namespace GameLogic
{ {
namespace CollisionManager
{
void PlayerVBox(Player &player, DynamicObject &box); 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)); Player *player = ((Player*)(rigidBodyPlayer->gameObjectRef));
Object *realObj = (Object*)obj->gameObjectRef; Object *realObj = (Object*)obj->gameObjectRef;
@ -38,7 +35,7 @@ namespace GameLogic
player.DamageLife(20); 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; DynamicObject *box = (DynamicObject*)rigidBodyBox->gameObjectRef;
Object *realObj = (Object*)obj->gameObjectRef; Object *realObj = (Object*)obj->gameObjectRef;
@ -55,5 +52,5 @@ namespace GameLogic
return Physics::ICustomBody::SubscriptMessage_none; return Physics::ICustomBody::SubscriptMessage_none;
} }
}
} }

View File

@ -7,12 +7,13 @@
namespace GameLogic namespace GameLogic
{ {
namespace CollisionManager class CollisionManager
{ {
public:
//these are the main collision functions //these are the main collision functions
//typedef SubscriptMessage (*EventAction_Collision)( const ICustomBody *proto, const ICustomBody *deuter ); //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); static 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 BoxCollision(const Oyster::Physics::ICustomBody *rigidBodyBox, const Oyster::Physics::ICustomBody *obj);
//these are the specific collision case functions //these are the specific collision case functions
//void PlayerVBox(Player &player, DynamicObject &box); //void PlayerVBox(Player &player, DynamicObject &box);

View File

@ -174,6 +174,7 @@
<ClInclude Include="CollisionManager.h" /> <ClInclude Include="CollisionManager.h" />
<ClInclude Include="DynamicObject.h" /> <ClInclude Include="DynamicObject.h" />
<ClInclude Include="GameLogicDef.h" /> <ClInclude Include="GameLogicDef.h" />
<ClInclude Include="GameLogicStates.h" />
<ClInclude Include="GameMode.h" /> <ClInclude Include="GameMode.h" />
<ClInclude Include="IAttatchment.h" /> <ClInclude Include="IAttatchment.h" />
<ClInclude Include="Level.h" /> <ClInclude Include="Level.h" />

View File

@ -13,6 +13,7 @@ struct Weapon::PrivateData
currentNrOfAttatchments = 0; currentNrOfAttatchments = 0;
selectedSocketID = 0; selectedSocketID = 0;
maxNrOfSockets = 0; maxNrOfSockets = 0;
attatchmentSockets = 0;
} }
~PrivateData() ~PrivateData()

View File

@ -3,6 +3,8 @@
#include "ObjectProtocols.h" #include "ObjectProtocols.h"
#include "PlayerProtocols.h" #include "PlayerProtocols.h"
#include "LobbyProtocols.h"
#include "TEST_PROTOCOLS.h" #include "TEST_PROTOCOLS.h"

View File

@ -155,6 +155,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="GameProtocols.h" /> <ClInclude Include="GameProtocols.h" />
<ClInclude Include="LobbyProtocols.h" />
<ClInclude Include="ObjectProtocols.h" /> <ClInclude Include="ObjectProtocols.h" />
<ClInclude Include="PlayerProtocols.h" /> <ClInclude Include="PlayerProtocols.h" />
<ClInclude Include="ProtocolIdentificationID.h" /> <ClInclude Include="ProtocolIdentificationID.h" />

View File

@ -0,0 +1,120 @@
//////////////////////////////////////////////////////////
// Created 2013 //
// Dennis Andersen, Linda Andersson //
//////////////////////////////////////////////////////////
#ifndef GAMELOGIC_LOBBY_PROTOCOLS_H
#define GAMELOGIC_LOBBY_PROTOCOLS_H
#include <CustomNetProtocol.h>
#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

View File

@ -1,5 +1,5 @@
#ifndef GAMELOGIC_PLAYER_PROTOCOLS_H #ifndef GAMELOGIC_OBJECT_PROTOCOLS_H
#define GAMELOGIC_PLAYER_PROTOCOLS_H #define GAMELOGIC_OBJECT_PROTOCOLS_H
#include <CustomNetProtocol.h> #include <CustomNetProtocol.h>
#include "ProtocolIdentificationID.h" #include "ProtocolIdentificationID.h"

View File

@ -7,18 +7,48 @@
/* THERE CAN ABSOLUTLEY NOT BE TWO DEFINITIONS WITH THE SAME ID!! */ /* 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 #define PROTOCOL_TEST 1000
#endif // !GAMEPROTOCOL_PROTOCOL_DEFINITION_ID_H #endif // !GAMEPROTOCOL_PROTOCOL_DEFINITION_ID_H

View File

@ -12,8 +12,16 @@ namespace Oyster
{ {
enum OYSTER_THREAD_ERROR enum OYSTER_THREAD_ERROR
{ {
OYSTER_THREAD_ERROR_FAILED,
OYSTER_THREAD_ERROR_SUCCESS, 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 enum OYSTER_THREAD_PRIORITY
{ {
@ -34,21 +42,22 @@ namespace Oyster
const OysterThread& operator=(const OysterThread& original); const OysterThread& operator=(const OysterThread& original);
virtual~OysterThread(); 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(); OYSTER_THREAD_ERROR Start();
void Stop(bool wait = false); OYSTER_THREAD_ERROR Stop(bool wait = false);
void Pause(); OYSTER_THREAD_ERROR Pause();
void Pause(int mSec); OYSTER_THREAD_ERROR Pause(int mSec);
void Resume(); OYSTER_THREAD_ERROR Resume();
OYSTER_THREAD_ERROR Reset(IThreadObject* worker = 0); OYSTER_THREAD_ERROR Reset(IThreadObject* worker = 0);
void Terminate(bool wait = false); OYSTER_THREAD_ERROR Terminate(bool wait = true);
void Wait(); OYSTER_THREAD_ERROR Wait();
void Wait(int mSec); OYSTER_THREAD_ERROR Wait(int mSec);
OYSTER_THREAD_ERROR Swap(const OysterThread* other); 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; bool IsCreated() const;
}; };
} }
} }

View File

@ -3,148 +3,169 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#include "OysterThread.h" #include "OysterThread.h"
#include "OysterMutex.h"
#include "..\Utilities.h" #include "..\Utilities.h"
#include <thread> #include <thread>
#include <assert.h> #include <assert.h>
#include <atomic> #include <atomic>
#include <future>
using namespace Oyster::Thread; using namespace Oyster::Thread;
using namespace Utility::DynamicMemory; using namespace Utility::DynamicMemory;
#pragma region Declerations
struct ThreadData;
/** A typical Oyster thread function */ #pragma region Declerations
typedef void (*ThreadFunction)(SmartPointer<ThreadData>&);
enum OYSTER_THREAD_STATE enum OYSTER_THREAD_STATE
{ {
OYSTER_THREAD_STATE_RESET, OYSTER_THREAD_STATE_IDLE,
OYSTER_THREAD_STATE_RUNNING, OYSTER_THREAD_STATE_NORMAL,
OYSTER_THREAD_STATE_PAUSED,
OYSTER_THREAD_STATE_STOPED,
OYSTER_THREAD_STATE_DEAD, OYSTER_THREAD_STATE_DEAD,
}; };
struct ThreadData struct ThreadData
{ {
OYSTER_THREAD_STATE state; //<! The current thread state. OYSTER_THREAD_STATE state; //<! The current thread state.
OYSTER_THREAD_PRIORITY prio; //<! The thread priority OYSTER_THREAD_PRIORITY prio; //<! The thread priority
SmartPointer<std::thread> workerThread; //<! The worker thread. IThreadObject *owner; //<! The worker.
std::thread::id callingThread; //<! The owner thread.
IThreadObject *owner; //<! The owner of the thread as IThread.
std::atomic<int> msec; //<! A timer in miliseconds. std::atomic<int> msec; //<! A timer in miliseconds.
bool first;
ThreadData() {} //std::timed_mutex threadFunctionLock;
~ThreadData() //std::mutex threadWaitFunctionLock;
};
/** A typical Oyster thread function */
typedef void (*ThreadFunction)(ThreadData* w);
struct RefData
{
bool isCreated;
ThreadData *threadData;
std::thread workerThread;
RefData()
{ {
this->owner = 0; threadData = 0;
this->state = OYSTER_THREAD_STATE_DEAD; isCreated = false;
}
if(this->workerThread) ~RefData()
{ {
//@todo TODO: Make detatch avalible. Terminate(true);
if(this->workerThread->joinable()) delete threadData;
this->workerThread->detach(); }
} 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 struct OysterThread::PrivateData
{ {
bool isCreated; SmartPointer<RefData> data;
SmartPointer<ThreadData> threadData;
PrivateData() OYSTER_THREAD_ERROR Create(ThreadFunction fnc, IThreadObject* worker, bool start, bool detach)
{ {
isCreated = false; if(data) return OYSTER_THREAD_ERROR_ThreadAlreadyCreated;
threadData = new ThreadData(); data = new RefData();
threadData->first = true; return data->Create(fnc, worker, start, detach);
threadData->owner = 0;
threadData->workerThread = 0;
threadData->callingThread;
threadData->state = OYSTER_THREAD_STATE_STOPED;
threadData->prio = OYSTER_THREAD_PRIORITY_3;
} }
PrivateData(const PrivateData& o) OYSTER_THREAD_ERROR Terminate(bool wait)
{ {
isCreated = o.isCreated; return data->Terminate(wait);
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();
// }
//}
} }
};
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 #pragma endregion
static void ThreadingFunction(SmartPointer<ThreadData> &origin)
{
bool shouldContinue = true;
SmartPointer<ThreadData> 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() OysterThread::OysterThread()
{ {
this->privateData = new PrivateData(); this->privateData = new PrivateData();
@ -156,7 +177,8 @@ OysterThread::OysterThread(const OysterThread& original)
const OysterThread& OysterThread::operator=(const OysterThread& original) const OysterThread& OysterThread::operator=(const OysterThread& original)
{ {
delete this->privateData; delete this->privateData;
this->privateData = new PrivateData(*original.privateData); this->privateData = new PrivateData();
this->privateData->data = original.privateData->data;
return *this; return *this;
} }
OysterThread::~OysterThread() OysterThread::~OysterThread()
@ -165,133 +187,117 @@ OysterThread::~OysterThread()
this->privateData = 0; 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->privateData)
if(this->IsCreated()) return OYSTER_THREAD_ERROR_FAILED; this->privateData = new PrivateData();
if(this->privateData->threadData->workerThread) return OYSTER_THREAD_ERROR_FAILED;
this->privateData->threadData->owner = worker; return this->privateData->Create(ThreadHelp::ThreadingFunction, worker, start, detach);
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;
} }
OYSTER_THREAD_ERROR OysterThread::Start() OYSTER_THREAD_ERROR OysterThread::Start()
{ {
if(!this->privateData->threadData->owner) if(!this->privateData->data->threadData->owner)
return OYSTER_THREAD_ERROR_FAILED; return OYSTER_THREAD_ERROR_ThreadHasNoWorker;
if(!this->privateData->threadData->workerThread)
return OYSTER_THREAD_ERROR_FAILED; if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD)
if(this->privateData->threadData->state == OYSTER_THREAD_STATE_DEAD) return OYSTER_THREAD_ERROR_ThreadIsDead;
return OYSTER_THREAD_ERROR_FAILED;
this->privateData->data->threadData->state = OYSTER_THREAD_STATE_NORMAL;
this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING;
return OYSTER_THREAD_ERROR_SUCCESS; return OYSTER_THREAD_ERROR_SUCCESS;
} }
void OysterThread::Stop(bool wait) OYSTER_THREAD_ERROR OysterThread::Stop(bool wait)
{ {
//this->privateData->threadData->mutexLock.LockMutex(); return this->Terminate(wait);
this->privateData->threadData->state = OYSTER_THREAD_STATE_STOPED;
//this->privateData->threadData->mutexLock.UnlockMutex();
} }
void OysterThread::Pause() OYSTER_THREAD_ERROR OysterThread::Pause()
{ {
//this->privateData->threadData->mutexLock.LockMutex(); this->privateData->data->threadData->state = OYSTER_THREAD_STATE_IDLE;
this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED; return OYSTER_THREAD_ERROR_SUCCESS;
//this->privateData->threadData->mutexLock.UnlockMutex();
} }
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->data->threadData->state = OYSTER_THREAD_STATE_NORMAL;
{
this->privateData->threadData->msec = msec; return OYSTER_THREAD_ERROR_SUCCESS;
}
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();
} }
OYSTER_THREAD_ERROR OysterThread::Reset(IThreadObject* worker) OYSTER_THREAD_ERROR OysterThread::Reset(IThreadObject* worker)
{ {
// this->privateData->threadData->mutexLock.LockMutex(); this->privateData->data->threadData->owner = worker;
if(worker)
{ this->privateData->data->threadData->msec = 0;
this->privateData->threadData->owner = worker;
} return OYSTER_THREAD_ERROR_SUCCESS;;
this->privateData->threadData->callingThread = std::this_thread::get_id(); }
this->privateData->threadData->msec = 0; OYSTER_THREAD_ERROR OysterThread::Terminate(bool wait)
// this->privateData->threadData->mutexLock.UnlockMutex(); {
//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; 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; if(this->privateData->data->workerThread.get_id() == std::this_thread::get_id())
} return OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe;
void OysterThread::Wait()
{
if(this->privateData->threadData->state == OYSTER_THREAD_STATE_DEAD)
{ return; }
if( this->privateData->threadData->workerThread //if(this->privateData->data->threadData->threadFunctionLock.try_lock_for(std::chrono::milliseconds(msec)))
&& // this->privateData->data->threadData->threadFunctionLock.unlock();
this->privateData->threadData->workerThread->get_id() == std::this_thread::get_id())
return;
//if(this->privateData->threadData->state == OYSTER_THREAD_STATE_STOPED) return OYSTER_THREAD_ERROR_SUCCESS;
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));
} }
OYSTER_THREAD_ERROR OysterThread::Swap(const OysterThread* other) 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; return OYSTER_THREAD_ERROR_SUCCESS;
} }
void OysterThread::SetPriority(OYSTER_THREAD_PRIORITY priority)
{
this->privateData->data->threadData->prio = priority;
}
bool OysterThread::IsActive() 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 true;
return false; return false;
} }
void OysterThread::SetPriority(OYSTER_THREAD_PRIORITY priority)
{
this->privateData->threadData->prio = priority;
}
bool OysterThread::IsCreated() const bool OysterThread::IsCreated() const
{ {
return privateData->isCreated; return privateData->data->isCreated;
} }

View File

@ -282,14 +282,17 @@ namespace Utility
{ {
//Call child specific //Call child specific
Destroy(); Destroy();
this->_rc = new ReferenceCount(); if(p) this->_rc = new ReferenceCount();
} }
} }
else else if(p)
{
this->_rc = new ReferenceCount(); this->_rc = new ReferenceCount();
}
this->_ptr = p; this->_ptr = p;
this->_rc->Incref();
if(p) this->_rc->Incref();
} }
return *this; return *this;
} }
@ -359,6 +362,12 @@ namespace Utility
} }
return returnVal; return returnVal;
} }
template<typename T> int SmartPointer<T>::ReleaseDummy()
{
int val = this->_rc->Decref();
this->_rc->Incref();
return val;
}
template<typename T> inline bool SmartPointer<T>::IsValid() const template<typename T> inline bool SmartPointer<T>::IsValid() const
{ {
return (this->_ptr != NULL) ? true : false; return (this->_ptr != NULL) ? true : false;

View File

@ -235,6 +235,10 @@ namespace Utility
* Releases one reference of the pointer and set value to null, making the current SmartPointer invalid. * Releases one reference of the pointer and set value to null, making the current SmartPointer invalid.
*/ */
int Release(); int Release();
/**
* Only test to release to check reference count.
*/
int ReleaseDummy();
/** Checks if the pointer is valid (not NULL) /** Checks if the pointer is valid (not NULL)
* Returns true for valid, else false. * Returns true for valid, else false.

View File

@ -41,7 +41,7 @@ struct NetworkServer::PrivateData : public IThreadObject
bool started; bool started;
//Postbox for new clients //Postbox for new clients
IPostBox<int> *postBox; PostBox<int> postBox;
//Server thread //Server thread
OysterThread thread; OysterThread thread;
@ -52,7 +52,7 @@ NetworkServer::PrivateData::PrivateData()
{ {
listener = 0; listener = 0;
started = false; started = false;
postBox = new PostBox<int>; //postBox = new PostBox<int>;
} }
NetworkServer::PrivateData::~PrivateData() NetworkServer::PrivateData::~PrivateData()
@ -74,7 +74,7 @@ bool NetworkServer::PrivateData::Init(INIT_DESC& initDesc)
this->initDesc = initDesc; this->initDesc = initDesc;
//Initiate listener //Initiate listener
listener = new Listener(postBox); listener = new Listener(&postBox);
if(!((Listener*)listener)->Init(this->initDesc.port, false)) if(!((Listener*)listener)->Init(this->initDesc.port, false))
{ {
return false; return false;
@ -120,21 +120,12 @@ void NetworkServer::PrivateData::Stop()
void NetworkServer::PrivateData::Shutdown() void NetworkServer::PrivateData::Shutdown()
{ {
//Stop server main thread
thread.Stop();
if(listener) if(listener)
{ {
delete listener; delete listener;
listener = NULL; listener = NULL;
} }
if(postBox)
{
delete postBox;
postBox = NULL;
}
started = false; started = false;
ShutdownWinSock(); ShutdownWinSock();
@ -143,9 +134,9 @@ void NetworkServer::PrivateData::Shutdown()
//Checks for new clients and sends them to the proc function. //Checks for new clients and sends them to the proc function.
void NetworkServer::PrivateData::CheckForNewClient() 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. //Safety check that is probably not needed.
if(clientSocketNum == -1) if(clientSocketNum == -1)

View File

@ -19,7 +19,7 @@ Listener::~Listener()
{ {
if(connection) if(connection)
{ {
this->thread.Terminate(); this->thread.Terminate(false);
delete connection; delete connection;
connection = 0; connection = 0;
} }
@ -99,6 +99,7 @@ int Listener::Accept()
bool Listener::DoWork() bool Listener::DoWork()
{ {
if(!this->connection) return false;
int result = Accept(); int result = Accept();
if(result == -1) if(result == -1)