Fixed some craches and stuff

This commit is contained in:
dean11 2013-12-13 23:47:16 +01:00
parent 4617523f8b
commit 8b1c2b91e8
33 changed files with 446 additions and 351 deletions

Binary file not shown.

Binary file not shown.

View File

@ -104,7 +104,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>DANBIAS_CLIENT;DANBIAS_GAME_DLL_EXPORT;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>DANBIAS_GAME_DLL_EXPORT;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)Game/GameProtocols;$(SolutionDir)OysterMath;$(SolutionDir)Input;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
@ -121,7 +121,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>DANBIAS_CLIENT;DANBIAS_GAME_DLL_EXPORT;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>DANBIAS_GAME_DLL_EXPORT;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)GameProtocols;$(SolutionDir)OysterMath;$(SolutionDir)Input;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc;$(SolutionDir)OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
@ -140,7 +140,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>DANBIAS_CLIENT;DANBIAS_GAME_DLL_EXPORT;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>DANBIAS_GAME_DLL_EXPORT;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)GameProtocols;$(SolutionDir)OysterMath;$(SolutionDir)Input;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc;$(SolutionDir)OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
@ -161,7 +161,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>DANBIAS_CLIENT;DANBIAS_GAME_DLL_EXPORT;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>DANBIAS_GAME_DLL_EXPORT;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)GameProtocols;$(SolutionDir)OysterMath;$(SolutionDir)Input;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc;$(SolutionDir)OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>

View File

@ -71,32 +71,32 @@
<OutDir>$(SolutionDir)..\Bin\Executable\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
<IncludePath>$(SolutionDir)..\External\Include\;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir)..\DLL\;$(LibraryPath)</LibraryPath>
<IncludePath>$(SolutionDir)..\External\Include\;C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir)..\DLL\;C:\Program Files %28x86%29\Visual Leak Detector\lib\Win32;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)..\Bin\Executable\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
<IncludePath>$(SolutionDir)..\External\Include\;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir)..\DLL\;$(LibraryPath)</LibraryPath>
<IncludePath>$(SolutionDir)..\External\Include\;C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir)..\DLL\;C:\Program Files %28x86%29\Visual Leak Detector\lib\Win64;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)..\Bin\Executable\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
<IncludePath>$(SolutionDir)..\External\Include\;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir)..\DLL\;$(LibraryPath)</LibraryPath>
<IncludePath>$(SolutionDir)..\External\Include\;C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir)..\DLL\;C:\Program Files %28x86%29\Visual Leak Detector\lib\Win32;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)..\Bin\Executable\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
<IncludePath>$(SolutionDir)..\External\Include\;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir)..\DLL\;$(LibraryPath)</LibraryPath>
<IncludePath>$(SolutionDir)..\External\Include\;C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir)..\DLL\;C:\Program Files %28x86%29\Visual Leak Detector\lib\Win64;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>

View File

@ -3,7 +3,7 @@
/////////////////////////////////////////////////
#define NOMINMAX
#include <Windows.h>
#include <vld.h>
#include "DanBiasServerAPI.h"
//#include "DanBiasGame.h"

View File

@ -10,17 +10,19 @@
#include "ServerInitReader.h"
#include <TEST_PROTOCOLS.h>
#include <Thread\OysterThread.h>
#include "ServerObjects\ClientObject.h"
namespace DanBias
{
using namespace Oyster::Network;
void GameServer::ClientConnectCallback(NetworkClient client)
void GameServer::ClientConnectCallback(NetworkClient& client)
{
printf("Client connected!\n");
this->mainLobby->AttachClient(Utility::DynamicMemory::SmartPointer<NetworkClient>(new NetworkClient(client)));
Utility::DynamicMemory::SmartPointer<ClientObject> c = new ClientObject(client);
this->mainLobby->AttachClient(c);
}
GameServer::GameServer()
: initiated(0)
@ -64,13 +66,11 @@ namespace DanBias
if(!this->server->Start()) return DanBiasServerReturn_Error;
this->running = true;
while (this->running)
while (true)
{
if(!WindowShell::Frame())
break;
if(!WindowShell::Frame()) break;
this->mainLobby->Frame();
}
return DanBiasServerReturn_Sucess;

View File

@ -4,8 +4,6 @@
#ifndef DANBIASSERVER_GAME_SERVER_H
#define DANBIASSERVER_GAME_SERVER_H
#include <vld.h>
#include "Include\DanBiasServerAPI.h"
#include "ServerObjects\Lobby\MainLobby.h"
#include <NetworkServer.h>
@ -25,7 +23,7 @@ namespace DanBias
private:
//static void ClientConnectCallbackFunction(Oyster::Network::NetworkClient& connectedClient);
void ClientConnectCallback(Oyster::Network::NetworkClient client) override;
void ClientConnectCallback(Oyster::Network::NetworkClient& client) override;
bool initiated;
bool running;

View File

@ -4,6 +4,8 @@
#ifndef DANBIAS_SERVER_DANBIAS_SERVER_H
#define DANBIAS_SERVER_DANBIAS_SERVER_H
#include <vld.h>
#define DANBIAS_SERVER
#ifdef DANBIAS_SERVER_DLL_EXPORT

View File

@ -2,11 +2,29 @@
using namespace DanBias;
ClientObject::ClientObject()
ClientObject::ClientObject(const Oyster::Network::NetworkClient& client)
{
this->client = client;
this->client.SetRecieverObject(this, Oyster::Network::NetworkProtocolCallbackType_Object);
this->box = 0;
}
ClientObject::~ClientObject()
{
this->client.Disconnect();
}
void ClientObject::SetPostbox(Oyster::PostBox<NetworkSession::ClientEvent>* box)
{
this->box = box;
}
void ClientObject::ProtocolRecievedCallback(Oyster::Network::CustomNetProtocol& protocol)
{
if(!this->box) return;
NetworkSession::ClientEvent _event;
_event.protocol = protocol;
_event.reciever = this;
this->box->Post(_event);
}

View File

@ -1,18 +1,27 @@
#ifndef DANBIASSERVER_CLIENT_OBJECT_H
#define DANBIASSERVER_CLIENT_OBJECT_H
#include "NetworkSession.h"
#include "NetworkClient.h"
#include <PostBox\PostBox.h>
namespace DanBias
{
class ClientObject
class ClientObject :public Oyster::Network::ProtocolRecieverObject
{
public:
ClientObject();
ClientObject(const Oyster::Network::NetworkClient& client);
~ClientObject();
void SetPostbox(Oyster::PostBox<NetworkSession::ClientEvent>* box);
private:
void ProtocolRecievedCallback(Oyster::Network::CustomNetProtocol& protocol) override;
private:
Oyster::Network::NetworkClient client;
Oyster::IPostBox<DanBias::NetworkSession::ClientEvent>* box;
};
}//End namespace DanBias

View File

@ -1,5 +1,5 @@
#ifndef DANBIASSERVER_GAME_LOBBY_H
#define DANBIASSERVER_GAME_LOBBY_H
#ifndef DANBIASSERVER_GAMELOBBY_H
#define DANBIASSERVER_GAMELOBBY_H
#include "..\NetworkSession.h"

View File

@ -13,6 +13,14 @@ namespace DanBias
}
void MainLobby::Release()
{
this->clients.clear();
}
void MainLobby::Frame()
{
if(!this->box.IsEmpty())
{
}
}
}//End namespace DanBias

View File

@ -1,5 +1,5 @@
#ifndef DANBIASGAME_GAMELOBBY_H
#define DANBIASGAME_GAMELOBBY_H
#ifndef DANBIASSERVER_MAINLOBBY_H
#define DANBIASSERVER_MAINLOBBY_H
#include "..\NetworkSession.h"
#include <thread>
@ -14,6 +14,8 @@ namespace DanBias
~MainLobby();
void Release();
void Frame();
private:

View File

@ -1,3 +1,4 @@
#include "ClientObject.h"
#include "NetworkSession.h"
#include <mutex>
@ -12,11 +13,20 @@ namespace DanBias
}
void NetworkSession::AttachClient(Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> client)
void NetworkSession::AttachClient(Utility::DynamicMemory::SmartPointer<ClientObject> client)
{
for (unsigned int i = 0; i < this->clients.size(); i++)
{
if(!this->clients[i])
{
this->clients[i] = client;
//this->clients[i]->SetPostbox(&this->box);
return;
}
}
this->clients.push_back(client);
}
void NetworkSession::DetachClient(Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> client)
void NetworkSession::DetachClient(Utility::DynamicMemory::SmartPointer<ClientObject> client)
{
}
@ -25,7 +35,7 @@ namespace DanBias
}
void NetworkSession::Kick(Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> client)
void NetworkSession::Kick(Utility::DynamicMemory::SmartPointer<ClientObject> client)
{
}
@ -33,9 +43,4 @@ namespace DanBias
{
}
Oyster::Network::NetworkClient* NetworkSession::operator[](int Identification)
{
return 0;
}
}//End namespace DanBias

View File

@ -2,24 +2,34 @@
#define DANBIASSERVER_NETWORK_SESSION_H
#include "Utilities.h"
#include "ClientObject.h"
#include <PostBox\PostBox.h>
#include <PlayerProtocols.h>
#include <vector>
namespace DanBias
{
class ClientObject;
class NetworkSession
{
public:
struct ClientEvent
{
ClientObject* reciever;
Oyster::Network::CustomNetProtocol protocol;
ClientEvent() { reciever = 0; }
~ClientEvent() { }
};
public:
NetworkSession();
~NetworkSession();
void AttachClient(Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> client);
void AttachClient(Utility::DynamicMemory::SmartPointer<ClientObject> client);
void DetachClient(Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> client);
void DetachClient(Utility::DynamicMemory::SmartPointer<ClientObject> client);
void DetachClient(short ID);
void Kick(Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> client);
void Kick(Utility::DynamicMemory::SmartPointer<ClientObject> client);
void Kick();
void Send(Oyster::Network::CustomNetProtocol& protocol);
@ -28,10 +38,8 @@ namespace DanBias
//TODO: Do more lobby features
protected:
Oyster::Network::NetworkClient* operator[](int Identification);
private:
std::vector<Utility::DynamicMemory::SmartPointer<ClientObject>> clients;
Oyster::PostBox<DanBias::NetworkSession::ClientEvent> box;
};
}//End namespace DanBias
#endif // !DANBIASSERVER_NETWORK_SESSION_H

View File

@ -157,6 +157,8 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="IQueue.h" />
<ClInclude Include="PostBox\IPostBox.h" />
<ClInclude Include="PostBox\PostBox.h" />
<ClInclude Include="Resource\OysterResource.h" />
<ClInclude Include="Resource\OResource.h" />
<ClInclude Include="ThreadSafeQueue.h" />

View File

@ -86,5 +86,11 @@
<ClInclude Include="ThreadSafeQueue.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PostBox\PostBox.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PostBox\IPostBox.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,22 @@
#ifndef NETWORK_DEPENDENCIES_I_POST_BOX_H
#define NETWORK_DEPENDENCIES_I_POST_BOX_H
/////////////////////////////////////
// Created by Pontus Fransson 2013 //
/////////////////////////////////////
namespace Oyster
{
template <class T>
class IPostBox
{
public:
virtual ~IPostBox() {}
virtual void Post(T message) = 0;
virtual T Fetch() = 0;
virtual bool IsEmpty() = 0;
};
}
#endif

View File

@ -0,0 +1,61 @@
#ifndef NETWORK_DEPENDENCIES_POST_BOX_H
#define NETWORK_DEPENDENCIES_POST_BOX_H
/////////////////////////////////////
// Created by Pontus Fransson 2013 //
/////////////////////////////////////
#include "IPostBox.h"
#include "../ThreadSafeQueue.h"
namespace Oyster
{
//With this class you can post items to it and then fetch them somewhere else.
//It is thread safe beacause of the ThreadSafeQueue.
template <class T>
class PostBox : public IPostBox<T>
{
public:
PostBox();
virtual ~PostBox();
virtual void Post(T message);
virtual T Fetch();
virtual bool IsEmpty();
private:
Oyster::Queue::ThreadSafeQueue<T> messages;
};
//Implementation of PostBox
template <class T>
PostBox<T>::PostBox()
{
}
template <class T>
PostBox<T>::~PostBox()
{
}
template <class T>
void PostBox<T>::Post(T message)
{
messages.Push(message);
}
template <class T>
T PostBox<T>::Fetch()
{
return messages.Pop();
}
template <class T>
bool PostBox<T>::IsEmpty()
{
return !messages.IsEmpty();
}
}
#endif

View File

@ -26,7 +26,9 @@ namespace Oyster
*/
virtual void ThreadExit() { }
/**
* This function is required to get threading working.
* This function is required to get threading working.
* Note that this function is NOT thread safe.
* OBS! Do not highjack the looping.
*/
virtual bool DoWork ( ) = 0;
};

View File

@ -15,6 +15,12 @@ namespace Oyster
OYSTER_THREAD_ERROR_FAILED,
OYSTER_THREAD_ERROR_SUCCESS,
};
enum OYSTER_THREAD_PRIORITY
{
OYSTER_THREAD_PRIORITY_1, //!< High
OYSTER_THREAD_PRIORITY_2, //!< Medium
OYSTER_THREAD_PRIORITY_3, //!< Low
};
class OysterThread
{
@ -30,16 +36,17 @@ namespace Oyster
OYSTER_THREAD_ERROR Create(IThreadObject* worker, bool start);
OYSTER_THREAD_ERROR Start();
void Stop();
void Stop(bool wait = false);
void Pause();
void Pause(int mSec);
void Resume();
OYSTER_THREAD_ERROR Reset(IThreadObject* worker = 0);
void Terminate();
void Terminate(bool wait = false);
void Wait();
void Wait(int mSec);
OYSTER_THREAD_ERROR Swap(const OysterThread* other);
bool IsActive();
void SetPriority(OYSTER_THREAD_PRIORITY priority);
};
}
}

View File

@ -31,17 +31,27 @@ using namespace Utility::DynamicMemory;
struct ThreadData
{
std::atomic<OYSTER_THREAD_STATE> state; //<! The current thread state.
OYSTER_THREAD_STATE state; //<! The current thread state.
OYSTER_THREAD_PRIORITY prio; //<! The thread priority
SmartPointer<std::thread> workerThread; //<! The worker thread.
std::thread::id callingThread; //<! The owner thread.
IThreadObject *owner; //<! The owner of the thread as IThread.
std::atomic<int> msec; //<! A timer in miliseconds.
//OysterMutex mutexLock; //<! The lock, locking the member variabls.
//OYSTER_THREAD_STATE state; //<! The current thread state.
bool first;
ThreadData() {}
~ThreadData() {}
~ThreadData()
{
this->owner = 0;
this->state = OYSTER_THREAD_STATE_DEAD;
if(this->workerThread)
{
//@todo TODO: Make detatch avalible.
if(this->workerThread->joinable())
this->workerThread->detach();
}
}
ThreadData(const ThreadData&)
{};
const ThreadData& operator =(const ThreadData& o)
@ -52,12 +62,14 @@ using namespace Utility::DynamicMemory;
SmartPointer<ThreadData> threadData;
PrivateData()
:threadData(new ThreadData())
{
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)
{
@ -69,13 +81,7 @@ using namespace Utility::DynamicMemory;
}
~PrivateData()
{
//@todo TODO: Make detatch avalible.
//if(!this->threadData->workerThread->joinable())
this->threadData->workerThread->detach();
this->threadData->owner = 0;
this->threadData->state = OYSTER_THREAD_STATE_DEAD;
threadData.Release();
}
};
@ -86,72 +92,44 @@ using namespace Utility::DynamicMemory;
static void ThreadingFunction(SmartPointer<ThreadData> &origin)
{
bool shouldContinue;
bool shouldContinue = true;
SmartPointer<ThreadData> w = origin;
theBegining:
while(w->state == OYSTER_THREAD_STATE_STOPED)
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)
{
std::this_thread::yield();
}
// w->mutexLock.LockMutex();
if(w->owner)
{
w->owner->ThreadEntry();
}
// w->mutexLock.UnlockMutex();
while (w->state != OYSTER_THREAD_STATE_STOPED && w->state != OYSTER_THREAD_STATE_DEAD)
{
// w->mutexLock.LockMutex();
switch (w->prio)
{
if(w->owner)
{
shouldContinue = w->owner->DoWork();
}
}
// w->mutexLock.UnlockMutex();
if(!shouldContinue)
{
goto theEnd;
}
if(w->state == OYSTER_THREAD_STATE_DEAD)
{
goto theEnd;
}
else 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();
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::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)
{
w->workerThread->detach();
if(w->workerThread->joinable()) w->workerThread->detach();
return;
}
theEnd:
// w->mutexLock.LockMutex();
if(w->owner)
{
w->owner->ThreadExit();
}
// w->mutexLock.UnlockMutex();
if(w->owner) w->owner->ThreadExit();
w->state = OYSTER_THREAD_STATE_DEAD;
}
@ -208,7 +186,7 @@ OYSTER_THREAD_ERROR OysterThread::Start()
this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING;
return OYSTER_THREAD_ERROR_SUCCESS;
}
void OysterThread::Stop()
void OysterThread::Stop(bool wait)
{
//this->privateData->threadData->mutexLock.LockMutex();
this->privateData->threadData->state = OYSTER_THREAD_STATE_STOPED;
@ -229,10 +207,8 @@ void OysterThread::Pause(int msec)
}
else
{
//this->privateData->threadData->mutexLock.LockMutex();
this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED;
this->privateData->threadData->msec = msec;
//this->privateData->threadData->mutexLock.UnlockMutex();
}
}
void OysterThread::Resume()
@ -254,26 +230,35 @@ OYSTER_THREAD_ERROR OysterThread::Reset(IThreadObject* worker)
return OYSTER_THREAD_ERROR_SUCCESS;
}
void OysterThread::Terminate()
void OysterThread::Terminate(bool wait)
{
this->privateData->threadData->state = OYSTER_THREAD_STATE_DEAD;
}
void OysterThread::Wait()
{
if(this->privateData->threadData->state == OYSTER_THREAD_STATE_DEAD)
{
return;
}
{ return; }
if(this->privateData->threadData->workerThread->get_id() == std::this_thread::get_id()) return;
if( this->privateData->threadData->workerThread
&&
this->privateData->threadData->workerThread->get_id() == std::this_thread::get_id())
return;
this->privateData->threadData->workerThread->join();
//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;
std::this_thread::sleep_for(std::chrono::milliseconds(msec));
//TODO: Sync with thread.
//std::this_thread::sleep_for(std::chrono::milliseconds(msec));
}
OYSTER_THREAD_ERROR OysterThread::Swap(const OysterThread* other)
{
@ -287,4 +272,8 @@ bool OysterThread::IsActive()
return false;
}
void OysterThread::SetPriority(OYSTER_THREAD_PRIORITY priority)
{
this->privateData->threadData->prio = priority;
}

View File

@ -5,6 +5,7 @@
#define NETWORK_CUSTOM_NETWORK_PROTOCOL_H
#include <string>
#include <vld.h>
#ifdef CUSTOM_NET_PROTOCOL_EXPORT
#define NET_PROTOCOL_EXPORT __declspec(dllexport)

View File

@ -30,7 +30,7 @@ namespace Oyster
typedef void(*ProtocolRecieverFunction)(CustomNetProtocol& protocol);
struct ClientConnectedObject
{
virtual void ClientConnectCallback(NetworkClient client) = 0;
virtual void ClientConnectCallback(NetworkClient& client) = 0;
};
struct ProtocolRecieverObject
{

View File

@ -23,28 +23,13 @@ using namespace Utility::DynamicMemory;
/*************************************
PrivateData
*************************************/
struct NetworkClient::PrivateData : public IThreadObject
struct ClientDataContainer
{
PrivateData();
PrivateData(unsigned int socket);
~PrivateData();
void Start();
void Send(CustomNetProtocol& protocol); //Is called from the outside to add messages to send.
//Called on from the thread
int Send();
int Recv();
bool DoWork();
SmartPointer<Connection> connection;
Connection connection;
SmartPointer<IPostBox<CustomNetProtocol>> sendPostBox;
SmartPointer<RecieverObject> recvObj;
RecieverObject recvObj;
NetworkProtocolCallbackType callbackType;
Oyster::Thread::OysterThread thread;
@ -52,123 +37,113 @@ struct NetworkClient::PrivateData : public IThreadObject
std::mutex postBoxMutex;
Translator translator;
ClientDataContainer(IThreadObject* o)
{
InitWinSock();
callbackType = NetworkProtocolCallbackType_Unknown;
sendPostBox = new PostBox<CustomNetProtocol>();
connection.SetBlockingMode(false);
}
ClientDataContainer(IThreadObject* o, unsigned int socket )
:connection(socket)
{
InitWinSock();
callbackType = NetworkProtocolCallbackType_Unknown;
sendPostBox = new PostBox<CustomNetProtocol>();
connection.SetBlockingMode(false);
}
~ClientDataContainer()
{
thread.Stop();
thread.Wait();
connection.Disconnect();
callbackType = NetworkProtocolCallbackType_Unknown;
ShutdownWinSock();
}
};
struct NetworkClient::PrivateData : public IThreadObject
{
Utility::DynamicMemory::SmartPointer<ClientDataContainer> data;
PrivateData() { this->data = new ClientDataContainer(this); }
PrivateData(unsigned int socket) { this->data = new ClientDataContainer(this, socket); }
~PrivateData() { }
bool DoWork()
{
if(!this->data)return true;
if(!this->data->connection.IsConnected()) return true;
Send();
Recv();
return true;
}
void Send(CustomNetProtocol* protocol)
{
if(!data) return;
this->data->postBoxMutex.lock();
this->data->sendPostBox->PostMessage(*protocol);
this->data->postBoxMutex.unlock();
}
int Send()
{
int errorCode = 0;
if(!data) return -1;
this->data->postBoxMutex.lock();
if(this->data->sendPostBox->IsFull())
{
SmartPointer<OysterByte> temp = new OysterByte();
this->data->translator.Pack(temp, this->data->sendPostBox->FetchMessage());
errorCode = this->data->connection.Send(temp);
}
this->data->postBoxMutex.unlock();
return errorCode;
}
int Recv()
{
int errorCode = -1;
if(this->data->callbackType == NetworkProtocolCallbackType_Function)
{
OysterByte temp = OysterByte();
errorCode = this->data->connection.Recieve(temp);
if(errorCode == 0)
{
CustomNetProtocol protocol;
bool ok = this->data->translator.Unpack(protocol, temp);
//Check if the protocol was unpacked correctly
if(ok)
{
this->data->recvObjMutex.lock();
if(this->data->callbackType == NetworkProtocolCallbackType_Function)
{
this->data->recvObj.protocolRecieverFnc(protocol);
}
else if(this->data->callbackType == NetworkProtocolCallbackType_Object)
{
this->data->recvObj.protocolRecievedObject->ProtocolRecievedCallback(protocol);
}
this->data->recvObjMutex.unlock();
}
}
}
return errorCode;
}
};
NetworkClient::PrivateData::PrivateData()
{
InitWinSock();
callbackType = NetworkProtocolCallbackType_Unknown;
connection = new Connection();
sendPostBox = new PostBox<CustomNetProtocol>;
this->thread.Create(this, false);
Start();
}
NetworkClient::PrivateData::PrivateData(unsigned int socket)
{
InitWinSock();
callbackType = NetworkProtocolCallbackType_Unknown;
connection = new Connection(socket);
sendPostBox = new PostBox<CustomNetProtocol>;
this->thread.Create(this, false);
connection->SetBlockingMode(false);
Start();
}
NetworkClient::PrivateData::~PrivateData()
{
thread.Stop();
/*if(connection)
{
delete connection;
connection = NULL;
}*/
/*if(sendPostBox)
{
delete sendPostBox;
sendPostBox = NULL;
}*/
callbackType = NetworkProtocolCallbackType_Unknown;
ShutdownWinSock();
}
bool NetworkClient::PrivateData::DoWork()
{
Send();
Recv();
return true;
}
void NetworkClient::PrivateData::Send(CustomNetProtocol& protocol)
{
postBoxMutex.lock();
sendPostBox->PostMessage(protocol);
postBoxMutex.unlock();
}
int NetworkClient::PrivateData::Send()
{
int errorCode = 0;
postBoxMutex.lock();
if(sendPostBox->IsFull())
{
SmartPointer<OysterByte> temp = new OysterByte();
this->translator.Pack(temp, sendPostBox->FetchMessage());
errorCode = this->connection->Send(temp);
}
postBoxMutex.unlock();
return errorCode;
}
int NetworkClient::PrivateData::Recv()
{
int errorCode = -1;
SmartPointer<OysterByte> temp = new OysterByte;
errorCode = this->connection->Recieve(temp);
if(errorCode == 0)
{
CustomNetProtocol protocol;
bool ok = translator.Unpack(protocol, temp);
//Check if the protocol was unpacked correctly
if(ok)
{
recvObjMutex.lock();
if(callbackType == NetworkProtocolCallbackType_Function)
{
recvObj->protocolRecieverFnc(protocol);
}
else if(callbackType == NetworkProtocolCallbackType_Object)
{
recvObj->protocolRecievedObject->ProtocolRecievedCallback(protocol);
}
recvObjMutex.unlock();
}
}
return errorCode;
}
void NetworkClient::PrivateData::Start()
{
this->thread.Start();
}
/*************************************
NetworkClient
@ -187,28 +162,25 @@ NetworkClient::NetworkClient(unsigned int socket)
NetworkClient::NetworkClient(RecieverObject recvObj, NetworkProtocolCallbackType type)
{
privateData = new PrivateData();
this->privateData->recvObj = SmartPointer<RecieverObject>(&recvObj);;
this->privateData->data->recvObj = SmartPointer<RecieverObject>(&recvObj);;
}
NetworkClient::NetworkClient(RecieverObject recvObj, NetworkProtocolCallbackType type, unsigned int socket)
{
privateData = new PrivateData(socket);
this->privateData->recvObj = SmartPointer<RecieverObject>(&recvObj);
this->privateData->callbackType = type;
this->privateData->data->recvObj = SmartPointer<RecieverObject>(&recvObj);
this->privateData->data->callbackType = type;
}
NetworkClient::NetworkClient(const NetworkClient& obj)
{
this->privateData = new PrivateData();
this->privateData = obj.privateData;
this->privateData = new PrivateData(*obj.privateData);
}
NetworkClient& NetworkClient::operator =(const NetworkClient& obj)
{
delete privateData;
this->privateData = new PrivateData();
this->privateData = obj.privateData;
this->privateData = new PrivateData(*obj.privateData);
return *this;
}
@ -223,16 +195,16 @@ NetworkClient::~NetworkClient()
bool NetworkClient::Connect(unsigned short port, const char serverIP[])
{
int result = this->privateData->connection->Connect(port, serverIP);
int result = this->privateData->data->connection.Connect(port, serverIP);
//Connect has succeeded
if(result == 0)
{
privateData->Start();
privateData->data->thread.Start();
return true;
}
privateData->connection->SetBlockingMode(false);
privateData->data->connection.SetBlockingMode(false);
//Connect has failed
return false;
@ -240,23 +212,25 @@ bool NetworkClient::Connect(unsigned short port, const char serverIP[])
void NetworkClient::Disconnect()
{
privateData->connection->Disconnect();
privateData->data->connection.Disconnect();
}
bool NetworkClient::IsConnected()
{
return privateData->connection->IsConnected();
return privateData->data->connection.IsConnected();
}
void NetworkClient::Send(CustomProtocolObject& protocol)
{
this->privateData->Send(*protocol.GetProtocol());
this->privateData->Send(protocol.GetProtocol());
}
void NetworkClient::SetRecieverObject(RecieverObject recvObj, NetworkProtocolCallbackType type)
{
privateData->recvObjMutex.lock();
privateData->recvObj = SmartPointer<RecieverObject>(&recvObj);
privateData->callbackType = type;
privateData->recvObjMutex.unlock();
if (type == NetworkProtocolCallbackType_Unknown) return;
privateData->data->recvObjMutex.lock();
privateData->data->recvObj = recvObj;
privateData->data->callbackType = type;
privateData->data->recvObjMutex.unlock();
}

View File

@ -12,6 +12,7 @@
#endif
#include "NetworkCallbackHelper.h"
#include <vld.h>
namespace Oyster
{

View File

@ -13,6 +13,7 @@
#include "NetworkClient.h"
#include "NetworkCallbackHelper.h"
#include <vld.h>
namespace Oyster
{

View File

@ -17,28 +17,6 @@ using namespace std;
struct MyCastingStruct
{
std::map<int, NetAttributeContainer> attributes;
/*MyCastingStruct()
{ }
~MyCastingStruct()
{
for (auto i = attributes.begin(); i != attributes.end(); i++)
{
RemoveAttribute(i->first);
}
}
void RemoveAttribute(int ID)
{
auto i = attributes.find(ID);
if(i == attributes.end()) return;
switch (i->second.type)
{
case NetAttributeType_CharArray:
delete [] i->second.value.netCharPtr;
break;
}
}*/
};
// TODO: Check if the package has been packed correctly.
@ -51,13 +29,13 @@ struct Translator::PrivateData
}
//Packages a header with a size(int) and a string of characters(char)
void PackHeader(SmartPointer<OysterByte> &bytes, CustomNetProtocol& protocol)
void PackHeader(OysterByte &bytes, CustomNetProtocol& protocol)
{
auto it = ((MyCastingStruct*)protocol.privateData)->attributes.begin();
auto end = ((MyCastingStruct*)protocol.privateData)->attributes.end();
size = 4; //size(int)
bytes->AddSize(4);
bytes.AddSize(4);
message.SetSize(size);
@ -67,18 +45,18 @@ struct Translator::PrivateData
headerString.push_back(it->second.type);
}
message.PackShort(size, *bytes);
message.PackShort(size, bytes);
for(int i = 0; i < (int)headerString.size(); i++)
{
message.PackChar(headerString.at(i), *bytes);
message.PackChar(headerString.at(i), bytes);
size++;
}
message.SetSize(bytes);
}
void PackMessage(SmartPointer<OysterByte> &bytes, CustomNetProtocol& protocol)
void PackMessage(OysterByte &bytes, CustomNetProtocol& protocol)
{
auto it = ((MyCastingStruct*)protocol.privateData)->attributes.begin();
auto end = ((MyCastingStruct*)protocol.privateData)->attributes.end();
@ -88,40 +66,40 @@ struct Translator::PrivateData
switch((int)headerString.at(i))
{
case NetAttributeType_Bool:
message.PackBool(it->second.value.netBool, *bytes);
message.PackBool(it->second.value.netBool, bytes);
break;
case NetAttributeType_Char:
message.PackChar(it->second.value.netChar, *bytes);
message.PackChar(it->second.value.netChar, bytes);
break;
case NetAttributeType_UnsignedChar:
message.PackUnsignedChar(it->second.value.netUChar, *bytes);
message.PackUnsignedChar(it->second.value.netUChar, bytes);
break;
case NetAttributeType_Short:
message.PackShort(it->second.value.netShort, *bytes);
message.PackShort(it->second.value.netShort, bytes);
break;
case NetAttributeType_UnsignedShort:
message.PackUnsignedShort(it->second.value.netUShort, *bytes);
message.PackUnsignedShort(it->second.value.netUShort, bytes);
break;
case NetAttributeType_Int:
message.PackInt(it->second.value.netInt, *bytes);
message.PackInt(it->second.value.netInt, bytes);
break;
case NetAttributeType_UnsignedInt:
message.PackUnsignedInt(it->second.value.netUInt, *bytes);
message.PackUnsignedInt(it->second.value.netUInt, bytes);
break;
case NetAttributeType_Int64:
message.PackInt64(it->second.value.netInt64, *bytes);
message.PackInt64(it->second.value.netInt64, bytes);
break;
case NetAttributeType_UnsignedInt64:
message.PackUnsignedInt64(it->second.value.netUInt64, *bytes);
message.PackUnsignedInt64(it->second.value.netUInt64, bytes);
break;
case NetAttributeType_Float:
message.PackFloat(it->second.value.netFloat, *bytes);
message.PackFloat(it->second.value.netFloat, bytes);
break;
case NetAttributeType_Double:
message.PackDouble(it->second.value.netDouble, *bytes);
message.PackDouble(it->second.value.netDouble, bytes);
break;
case NetAttributeType_CharArray:
message.PackStr(it->second.value.netCharPtr, *bytes);
message.PackStr(it->second.value.netCharPtr, bytes);
break;
default:
numberOfUnknownTypes++;
@ -132,27 +110,27 @@ struct Translator::PrivateData
message.SetSize(bytes);
}
bool UnpackHeader(CustomNetProtocol& protocol, SmartPointer<OysterByte> &bytes)
bool UnpackHeader(CustomNetProtocol& protocol, OysterByte &bytes)
{
message.SetSize(0);
int packageSize = message.UnpackInt(*bytes);
if(packageSize != bytes->GetSize())
int packageSize = message.UnpackInt(bytes);
if(packageSize != bytes.GetSize())
{
return false;
}
short numberOfTypes = message.UnpackShort(*bytes);
short numberOfTypes = message.UnpackShort(bytes);
for(int i = 0; i < numberOfTypes; i++)
{
char temp = message.UnpackChar(*bytes);
char temp = message.UnpackChar(bytes);
headerString.push_back(temp);
}
return true;
}
void UnpackMessage(CustomNetProtocol& protocol, SmartPointer<OysterByte> &bytes)
void UnpackMessage(CustomNetProtocol& protocol, OysterByte &bytes)
{
for(int i = 0; i < (int)headerString.size(); i++)
{
@ -160,40 +138,40 @@ struct Translator::PrivateData
switch(protocol[i].type)
{
case NetAttributeType_Bool:
protocol[i].value.netBool = message.UnpackBool(*bytes);
protocol[i].value.netBool = message.UnpackBool(bytes);
break;
case NetAttributeType_Char:
protocol[i].value.netChar = message.UnpackChar(*bytes);
protocol[i].value.netChar = message.UnpackChar(bytes);
break;
case NetAttributeType_UnsignedChar:
protocol[i].value.netUChar = message.UnpackUnsignedChar(*bytes);
protocol[i].value.netUChar = message.UnpackUnsignedChar(bytes);
break;
case NetAttributeType_Short:
protocol[i].value.netShort = message.UnpackShort(*bytes);
protocol[i].value.netShort = message.UnpackShort(bytes);
break;
case NetAttributeType_UnsignedShort:
protocol[i].value.netUShort = message.UnpackUnsignedShort(*bytes);
protocol[i].value.netUShort = message.UnpackUnsignedShort(bytes);
break;
case NetAttributeType_Int:
protocol[i].value.netInt = message.UnpackInt(*bytes);
protocol[i].value.netInt = message.UnpackInt(bytes);
break;
case NetAttributeType_UnsignedInt:
protocol[i].value.netUInt = message.UnpackUnsignedInt(*bytes);
protocol[i].value.netUInt = message.UnpackUnsignedInt(bytes);
break;
case NetAttributeType_Int64:
protocol[i].value.netInt64 = message.UnpackInt64(*bytes);
protocol[i].value.netInt64 = message.UnpackInt64(bytes);
break;
case NetAttributeType_UnsignedInt64:
protocol[i].value.netUInt64 = message.UnpackUnsignedInt64(*bytes);
protocol[i].value.netUInt64 = message.UnpackUnsignedInt64(bytes);
break;
case NetAttributeType_Float:
protocol[i].value.netFloat = message.UnpackFloat(*bytes);
protocol[i].value.netFloat = message.UnpackFloat(bytes);
break;
case NetAttributeType_Double:
protocol[i].value.netDouble = message.UnpackDouble(*bytes);
protocol[i].value.netDouble = message.UnpackDouble(bytes);
break;
case NetAttributeType_CharArray:
protocol[i].value.netCharPtr = message.UnpackCStr(*bytes);
protocol[i].value.netCharPtr = message.UnpackCStr(bytes);
break;
default:
numberOfUnknownTypes++;
@ -233,7 +211,7 @@ const Translator& Translator::operator=(const Translator& obj)
return *this;
}
void Translator::Pack(SmartPointer<OysterByte> &bytes, CustomNetProtocol& protocol)
void Translator::Pack(OysterByte &bytes, CustomNetProtocol& protocol)
{
privateData->headerString.clear();
@ -241,7 +219,7 @@ void Translator::Pack(SmartPointer<OysterByte> &bytes, CustomNetProtocol& protoc
privateData->PackMessage(bytes, protocol);
}
bool Translator::Unpack(CustomNetProtocol& protocol, SmartPointer<OysterByte> &bytes)
bool Translator::Unpack(CustomNetProtocol& protocol, OysterByte &bytes)
{
if(!privateData->UnpackHeader(protocol, bytes))
{

View File

@ -51,10 +51,10 @@ namespace Oyster
Translator(const Translator& obj);
const Translator& operator=(const Translator& obj);
void Pack(Utility::DynamicMemory::SmartPointer<OysterByte> &bytes, CustomNetProtocol& protocol);
void Pack(OysterByte &bytes, CustomNetProtocol& protocol);
//Returns false if it discovers any faulty stuff with the package.
bool Unpack(CustomNetProtocol& protocol, Utility::DynamicMemory::SmartPointer<OysterByte> &bytes);
bool Unpack(CustomNetProtocol& protocol, OysterByte &bytes);
private:
struct PrivateData;

View File

@ -9,7 +9,7 @@ using namespace Oyster::Network;
Connection::Connection()
{
this->socket = 0;
this->socket = -1;
bool stillSending = false;
bool closed = true;
}
@ -104,11 +104,11 @@ int Connection::Disconnect()
return 0;
}
int Connection::Send(Utility::DynamicMemory::SmartPointer<OysterByte> &bytes)
int Connection::Send(OysterByte &bytes)
{
int nBytes;
nBytes = send(this->socket, *bytes, bytes->GetSize(), 0);
nBytes = send(this->socket, bytes, bytes.GetSize(), 0);
if(nBytes == SOCKET_ERROR)
{
return WSAGetLastError();
@ -117,20 +117,20 @@ int Connection::Send(Utility::DynamicMemory::SmartPointer<OysterByte> &bytes)
return 0;
}
int Connection::Recieve(Utility::DynamicMemory::SmartPointer<OysterByte> &bytes)
int Connection::Recieve(OysterByte &bytes)
{
int nBytes;
bytes->Resize(1000);
nBytes = recv(this->socket, *bytes, 1000, 0);
bytes.Resize(1000);
nBytes = recv(this->socket, bytes, 1000, 0);
if(nBytes == SOCKET_ERROR)
{
bytes->SetSize(0);
bytes.SetSize(0);
return WSAGetLastError();
}
else
{
bytes->SetSize(nBytes);
bytes.SetSize(nBytes);
}
return 0;

View File

@ -23,8 +23,8 @@ namespace Oyster
virtual int InitiateServer( unsigned short port );
virtual int InitiateClient();
virtual int Send( Utility::DynamicMemory::SmartPointer<OysterByte> &bytes );
virtual int Recieve( Utility::DynamicMemory::SmartPointer<OysterByte> &bytes );
virtual int Send( OysterByte &bytes );
virtual int Recieve( OysterByte &bytes );
virtual int Disconnect();
virtual int Connect( unsigned short port , const char serverName[] );

View File

@ -19,8 +19,8 @@ namespace Oyster
//sends and recieve functions with bytearrays,
//will send to the users connection via socket
virtual int Send( Utility::DynamicMemory::SmartPointer<OysterByte> &bytes ) = 0;
virtual int Recieve( Utility::DynamicMemory::SmartPointer<OysterByte> &bytes) = 0;
virtual int Send( OysterByte &bytes ) = 0;
virtual int Recieve( OysterByte &bytes) = 0;
//initiates sockets and address for server and client
virtual int InitiateServer( unsigned short port ) { return false; };

View File

@ -34,7 +34,8 @@ int main()
ThreadedClient* client = new ThreadedClient;
//Connect to server
errorCode = client->Connect(15151, "193.11.186.101");
//errorCode = client->Connect(15151, "193.11.186.101");
errorCode = client->Connect(15151, "127.0.0.1");
if(errorCode != 0)
{