GameLogic - Added alot of functionality to Game related parts

This commit is contained in:
Dennis Andersen 2013-12-18 13:07:10 +01:00
parent e9c5a49778
commit 8721224d7c
24 changed files with 712 additions and 58 deletions

View File

@ -177,6 +177,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="GameSessionManager.cpp" />
<ClCompile Include="Include\DanBiasServerAPI.cpp" />
<ClCompile Include="DLLMain.cpp" />
<ClCompile Include="GameServer.cpp" />
@ -189,6 +190,7 @@
<ItemGroup>
<ClInclude Include="Event\EventManager.h" />
<ClInclude Include="GameServer.h" />
<ClInclude Include="GameSessionManager.h" />
<ClInclude Include="Include\DanBiasServerAPI.h" />
<ClInclude Include="ServerInitReader.h" />
<ClInclude Include="ServerObjects\ClientObject.h" />

View File

@ -54,6 +54,7 @@ namespace DanBias
if(!this->server->Init(serverDesc)) return DanBiasServerReturn_Error;
if(!WindowShell::CreateConsoleWindow()) return DanBiasServerReturn_Error;
if(!WindowShell::CreateWin(WindowShell::WINDOW_INIT_DESC())) return DanBiasServerReturn_Error;
this->initiated = true;
return DanBiasServerReturn_Sucess;

View File

@ -15,7 +15,7 @@ namespace DanBias
{
public:
GameServer();
~GameServer();
virtual~GameServer();
DanBiasServerReturn Create();
DanBiasServerReturn Run();

View File

@ -0,0 +1,57 @@
#include "GameSessionManager.h"
#include "ServerObjects\GameSession.h"
#include "DynamicArray.h"
struct GameSessionData
{
Utility::DynamicMemory::DynamicArray<DanBias::GameSession*> sessions;
int freeSpot;
int Existst(DanBias::GameSession* s)
{
for (unsigned int i = 0; i < sessions.Size(); i++)
{
if(!sessions[i] && freeSpot == -1) freeSpot = i;
if(sessions[i] == s) return i;
}
return -1;
}
int GetFree()
{
for (unsigned int i = 0; i < sessions.Size(); i++)
if(!sessions[i])
return i;
return -1;
}
} __gameSessionData;
void GameSessionManager::AddSession(DanBias::GameSession* session)
{
if(__gameSessionData.Existst(session) == -1)
{
int k = __gameSessionData.freeSpot;
if( k == -1) k = __gameSessionData.GetFree();
if(k == -1) __gameSessionData.sessions.Push(session);
else __gameSessionData.sessions[k] = session;
}
}
void GameSessionManager::CloseSession(DanBias::GameSession* session)
{
int i = __gameSessionData.Existst(session);
//Moron check...
if(i == -1) return;
//__gameSessionData.sessions[i]->Close();
}

View File

@ -0,0 +1,16 @@
#ifndef DANBIASSERVER_GAME_SEESION_MANAGER_H
#define DANBIASSERVER_GAME_SEESION_MANAGER_H
namespace DanBias
{
class GameSession;
}
class GameSessionManager
{
public:
static void AddSession(DanBias::GameSession* session);
static void CloseSession(DanBias::GameSession* session);
};
#endif // !DANBIASSERVER_GAME_SEESION_MANAGER_H

View File

@ -14,13 +14,14 @@ namespace DanBias
{
public:
ClientObject(Oyster::Network::NetworkClient* client);
~ClientObject();
virtual~ClientObject();
void SetPostbox(Oyster::IPostBox<NetworkSession::NetEvent>* box);
GameLogic::Player* Logic_Object();
Oyster::Network::NetworkClient* NetClient_Object();
private:
/** This method is NOT threadsafe. */
virtual void ProtocolRecievedCallback(Oyster::Network::CustomNetProtocol& protocol) override;

View File

@ -1,9 +1,147 @@
#include <GameProtocols.h>
#include "GameSession.h"
#include <PostBox\PostBox.h>
#include "ClientObject.h"
#define ERIK
using namespace Utility::DynamicMemory;
using namespace Oyster::Network;
using namespace Oyster;
namespace DanBias
{
GameSession::GameSession()
{
}
GameSession::~GameSession()
{
}
void GameSession::Run(const GameSessionDescription& desc)
{
}
void GameSession::AttachClient(SmartPointer<ClientObject> client, Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box )
{
this->Init();
}
////private: //overriden NetworkSession functions
void GameSession::Close()
{
}
SmartPointer<ClientObject> GameSession::DetachClient(NetworkClient* client)
{
return SmartPointer<ClientObject>();
}
SmartPointer<ClientObject> GameSession::DetachClient(ClientObject* client)
{
return SmartPointer<ClientObject>();
}
SmartPointer<ClientObject> GameSession::DetachClient(short ID)
{
return SmartPointer<ClientObject>();
}
void GameSession::Send(::CustomNetProtocol& protocol)
{
}
void GameSession::Send(CustomNetProtocol& protocol, int ID)
{
}
void GameSession::SetPostbox(IPostBox<NetworkSession::NetEvent> *box)
{
}
void GameSession::CloseSession(NetworkSession* clientDestination)
{
}
////private: //overriden Threading functions
void GameSession::ThreadEntry()
{
}
void GameSession::ThreadExit()
{
}
bool GameSession::DoWork ( )
{
this->ParseEvents();
this->Frame();
return true;
}
////private:
void GameSession::Init()
{
#ifdef ERIK
EricLogicInitFunc();
#else
#endif
}
void GameSession::Frame()
{
#ifdef ERIK
EricLogicFrameFunc();
#else
#endif
}
void GameSession::ParseEvents()
{
if(this->box && !this->box->IsEmpty())
{
NetEvent &e = this->box->Fetch();
#ifdef ERIK
EricsLogicTestingProtocalRecieved(e.reciever, e.protocol);
#else
if(e.protocol[0].type != Oyster::Network::NetAttributeType_Short) return;
short f = e.protocol[0].value.netShort;
switch (f)
{
default:
break;
}
#endif
}
}
}//End namespace DanBias
#pragma region TESTING
//VARIABLES GOES HERE
int i = 0;
GameLogic::Player erik;
void GameSession::EricLogicInitFunc()
{
}
void GameSession::EricLogicFrameFunc()
{
}
void GameSession::EricsLogicTestingProtocalRecieved(ClientObject* reciever, CustomNetProtocol& protocol)
{
}
#pragma endregion
}//End namespace DanBias

View File

@ -2,16 +2,59 @@
#define DANBIASSERVER_GAME_SESSION_H
#include "NetworkSession.h"
#include <PostBox\IPostBox.h>
#include <Thread\OysterThread.h>
namespace DanBias
{
class GameSession :public NetworkSession
class ClientObject;
class GameSession :private NetworkSession, public Oyster::Thread::IThreadObject
{
public:
struct GameSessionDescription
{
NetworkSession* owner;
};
public:
GameSession();
~GameSession();
virtual~GameSession();
void Run(const GameSessionDescription& desc);
void AttachClient(Utility::DynamicMemory::SmartPointer<ClientObject> client, Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box = 0) override;
private: //overriden NetworkSession functions
void Close();
Utility::DynamicMemory::SmartPointer<ClientObject> DetachClient(Oyster::Network::NetworkClient* client) override;
Utility::DynamicMemory::SmartPointer<ClientObject> DetachClient(ClientObject* client) override;
Utility::DynamicMemory::SmartPointer<ClientObject> DetachClient(short ID) override;
void Send(Oyster::Network::CustomNetProtocol& protocol) override;
void Send(Oyster::Network::CustomNetProtocol& protocol, int ID) override;
void SetPostbox(Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box) override;
void CloseSession(NetworkSession* clientDestination) override;
private: //overriden Threading functions
void ThreadEntry() override;
void ThreadExit() override;
bool DoWork ( ) override;
private:
void Init();
void Frame();
void ParseEvents();
private:
NetworkSession* owner;
Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box;
Oyster::Thread::OysterThread worker;
#pragma region TESTING
void EricLogicInitFunc();
void EricLogicFrameFunc();
void EricsLogicTestingProtocalRecieved(ClientObject* reciever, Oyster::Network::CustomNetProtocol& protocol);
#pragma endregion
};//End GameSession

View File

@ -9,7 +9,8 @@ namespace DanBias
{
public:
GameLobby();
~GameLobby();
virtual~GameLobby();
void Release();
private:

View File

@ -1,19 +1,21 @@
#include "MainLobby.h"
#include <PlayerProtocols.h>
#include <PostBox\PostBox.h>
namespace DanBias
{
MainLobby::MainLobby()
{
this->box = new Oyster::PostBox<DanBias::NetworkSession::NetEvent>();
}
MainLobby::~MainLobby()
{
delete this->box;
this->box = 0;
}
void MainLobby::Release()
{
this->DetachClient();
this->CloseSession(0);
}
void MainLobby::Frame()
@ -24,7 +26,7 @@ namespace DanBias
//////// Private
void MainLobby::ParseEvents()
{
if(!this->box->IsEmpty())
if(this->box && !this->box->IsEmpty())
{
NetEvent &e = this->box->Fetch();

View File

@ -2,6 +2,7 @@
#define DANBIASSERVER_MAINLOBBY_H
#include "..\NetworkSession.h"
#include <PostBox\IPostBox.h>
namespace DanBias
{
@ -9,7 +10,7 @@ namespace DanBias
{
public:
MainLobby();
~MainLobby();
virtual~MainLobby();
void Release();
void Frame();
@ -18,7 +19,8 @@ namespace DanBias
void ParseEvents();
private:
//NetworkSession *
Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box;
};
}//End namespace DanBias
#endif // !DANBIASGAME_GAMELOBBY_H

View File

@ -8,20 +8,27 @@ static std::mutex ClientListLock;
namespace DanBias
{
NetworkSession::NetworkSession()
{ }
NetworkSession::NetworkSession(const NetworkSession& orig)
{
this->clients = orig.clients;
}
const NetworkSession& NetworkSession::operator=(const NetworkSession& orig)
{
this->clients = orig.clients;
return *this;
}
NetworkSession::~NetworkSession()
{
this->clients.Clear();
}
void NetworkSession::AttachClient(Utility::DynamicMemory::SmartPointer<ClientObject> client)
void NetworkSession::AttachClient(Utility::DynamicMemory::SmartPointer<ClientObject> client, Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box)
{
ClientListLock.lock();
int k = -1;
for (unsigned int i = 0; (k == -1) && i < this->clients.size(); i++)
for (unsigned int i = 0; (k == -1) && i < this->clients.Size(); i++)
{
if(!this->clients[i])
k = i;
@ -29,81 +36,126 @@ namespace DanBias
if(k == -1)
{
this->clients.push_back(client);
this->clients[this->clients.size() - 1]->SetPostbox(this->box);
this->clients.Push(client);
this->clients[this->clients.Size() - 1]->SetPostbox(box);
}
else
{
this->clients[k]->SetPostbox(this->box);
this->clients[k] = client;
this->clients[k]->SetPostbox(box);
}
ClientListLock.unlock();
}
void NetworkSession::DetachClient(Oyster::Network::NetworkClient* client)
Utility::DynamicMemory::SmartPointer<ClientObject> NetworkSession::DetachClient(Oyster::Network::NetworkClient* client)
{
Utility::DynamicMemory::SmartPointer<ClientObject> val;
ClientListLock.lock();
for (unsigned int i = 0; i < this->clients.size(); i++)
for (unsigned int i = 0; i < this->clients.Size(); i++)
{
if(this->clients[0]->NetClient_Object()->Id() == client->Id())
{
val = this->clients[i];
this->clients[i] = 0;
}
}
ClientListLock.unlock();
return val;
}
void NetworkSession::DetachClient(ClientObject* client)
Utility::DynamicMemory::SmartPointer<ClientObject> NetworkSession::DetachClient(ClientObject* client)
{
Utility::DynamicMemory::SmartPointer<ClientObject> val;
ClientListLock.lock();
for (unsigned int i = 0; i < this->clients.size(); i++)
for (unsigned int i = 0; i < this->clients.Size(); i++)
{
if(this->clients[0]->NetClient_Object()->Id() == client->NetClient_Object()->Id())
{
val = this->clients[i];
this->clients[i] = 0;
}
}
ClientListLock.unlock();
return val;
}
void NetworkSession::DetachClient(short ID)
Utility::DynamicMemory::SmartPointer<ClientObject> NetworkSession::DetachClient(short ID)
{
Utility::DynamicMemory::SmartPointer<ClientObject> val;
ClientListLock.lock();
for (unsigned int i = 0; i < this->clients.size(); i++)
for (unsigned int i = 0; i < this->clients.Size(); i++)
{
if(this->clients[0]->NetClient_Object()->Id() == ID)
{
val = this->clients[i];
this->clients[i] = 0;
}
}
ClientListLock.unlock();
}
void NetworkSession::DetachClient()
{
ClientListLock.lock();
for (unsigned int i = 0; i < this->clients.size(); i++)
{
this->clients[i] = 0;
}
ClientListLock.unlock();
return val;
}
void NetworkSession::Kick()
void NetworkSession::Send(Oyster::Network::CustomNetProtocol& protocol)
{
ClientListLock.lock();
for (unsigned int i = 0; i < this->clients.size(); i++)
for (unsigned int i = 0; i < this->clients.Size(); i++)
{
this->clients[i]->NetClient_Object()->Send(&protocol);
}
}
void NetworkSession::Send(Oyster::Network::CustomNetProtocol& protocol, int ID)
{
for (unsigned int i = 0; i < this->clients.Size(); i++)
{
if(this->clients[i]->NetClient_Object()->Id() == ID)
{
this->clients[i]->NetClient_Object()->Disconnect();
this->clients[i] = 0;
this->clients[i]->NetClient_Object()->Send(&protocol);
break;
}
ClientListLock.unlock();
}
}
void NetworkSession::SetPostbox(Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box)
{
this->box = box;
for (unsigned int i = 0; i < this->clients.Size(); i++)
{
this->clients[i]->SetPostbox(box);
}
}
void NetworkSession::CloseSession(NetworkSession * owner)
{
ClientListLock.lock();
if(!owner)
{
for (unsigned int i = 0; i < this->clients.Size(); i++)
{
this->clients[i]->NetClient_Object()->Disconnect();
}
}
else
{
for (unsigned int i = 0; i < this->clients.Size(); i++)
{
owner->AttachClient(this->clients[i]);
}
}
this->clients.Clear();
ClientListLock.unlock();
}
}//End namespace DanBias

View File

@ -4,13 +4,17 @@
#ifndef DANBIASSERVER_NETWORK_SESSION_H
#define DANBIASSERVER_NETWORK_SESSION_H
#pragma warning(disable: 4150)
#define NOMINMAX
#include "Utilities.h"
#include <DynamicArray.h>
#include <PostBox\IPostBox.h>
#include <CustomNetProtocol.h>
#include <NetworkClient.h>
#include <vector>
namespace DanBias
{
class ClientObject;
@ -25,26 +29,26 @@ namespace DanBias
public:
NetworkSession();
~NetworkSession();
NetworkSession(const NetworkSession& orig);
const NetworkSession& operator=(const NetworkSession& orig);
virtual~NetworkSession();
void AttachClient(Utility::DynamicMemory::SmartPointer<ClientObject> client);
virtual void AttachClient(Utility::DynamicMemory::SmartPointer<ClientObject> client, Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box = 0);
void DetachClient(Oyster::Network::NetworkClient* client);
void DetachClient(ClientObject* client);
void DetachClient(short ID);
void DetachClient();
virtual Utility::DynamicMemory::SmartPointer<ClientObject> DetachClient(Oyster::Network::NetworkClient* client);
virtual Utility::DynamicMemory::SmartPointer<ClientObject> DetachClient(ClientObject* client);
virtual Utility::DynamicMemory::SmartPointer<ClientObject> DetachClient(short ID);
void Kick();
void Send(Oyster::Network::CustomNetProtocol& protocol);
void Send(Oyster::Network::CustomNetProtocol& protocol, int ID);
virtual void Send(Oyster::Network::CustomNetProtocol& protocol);
virtual void Send(Oyster::Network::CustomNetProtocol& protocol, int ID);
//TODO: Do more lobby features
void SetPostbox(Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box);
virtual void SetPostbox(Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box);
virtual void CloseSession(NetworkSession* clientDestination); //<! Closes the session and sends the clients to given sesison. If session is null, clients is kicked from server.
protected:
std::vector<Utility::DynamicMemory::SmartPointer<ClientObject>> clients;
Oyster::IPostBox<DanBias::NetworkSession::NetEvent> *box;
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<ClientObject>> clients;
};
}//End namespace DanBias
#endif // !DANBIASSERVER_NETWORK_SESSION_H

View File

@ -8,7 +8,6 @@
namespace GameLogic
{
class GameMode
{
public:

View File

@ -56,4 +56,6 @@ bool Team::AddPlayer(Player *player)
myData->players[myData->nrOfPlayers] = player;
myData->nrOfPlayers++;
}
return true;
}

View File

@ -0,0 +1,9 @@
#ifndef GAMEPROTOCOLS_GAMEPROTOCOLS_H
#define GAMEPROTOCOLS_GAMEPROTOCOLS_H
#include "ObjectProtocols.h"
#include "PlayerProtocols.h"
#include "TEST_PROTOCOLS.h"
#endif // !GAMEPROTOCOLS_GAMEPROTOCOLS_H

View File

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

215
Code/Misc/DynamicArray.h Normal file
View File

@ -0,0 +1,215 @@
//////////////////////////////
// Dennis Andersen 2013 //
//////////////////////////////
#ifndef MISC_DYNAMIC_ARRAY_H
#define MISC_DYNAMIC_ARRAY_H
namespace Utility
{
namespace DynamicMemory
{
template <typename T>
class DynamicArray
{
public:
DynamicArray();
DynamicArray(unsigned int capacity);
DynamicArray(const DynamicArray& orig);
const DynamicArray& operator=(const DynamicArray& orig);
virtual~DynamicArray();
T& operator[](unsigned int index);
const T& operator[](unsigned int index) const;
void Push(const T& value);
void Push(unsigned int index, const T& value);
T& PopFront();
T& PopBack();
T& Pop(unsigned int index);
void Remove(unsigned int index);
void Remove(unsigned int first, unsigned int last);
void Clear();
void Expand(int elements = 0);
unsigned int Size() const;
unsigned int Capacity() const;
private:
T* data;
int size;
int capacity;
};
#pragma region Implementation
template <typename T> DynamicArray<T>::DynamicArray()
: data(0)
, size(0)
, capacity(0)
{ }
template <typename T> DynamicArray<T>::DynamicArray(unsigned int capacity)
: size(capacity)
, capacity(capacity)
, data(new T[capacity])
{ }
template <typename T> DynamicArray<T>::DynamicArray(const DynamicArray& orig)
: capacity(orig.capacity)
, size(orig.size)
{
this->data = new T[orig.capacity];
for (int i = 0; i < orig.size; i++)
{
this->data[i] = orig.data[i];
}
}
template <typename T> const DynamicArray<T>& DynamicArray<T>::operator=(const DynamicArray& orig)
{
if(this->data)
{
delete [] this->data;
}
this->capacity = orig.capacity;
this->size = orig.size;
if(orig.capacity > 0)
{
this->data = new T[orig.capacity];
for (int i = 0; i < orig.size; i++)
{
this->data[i] = orig.data[i];
}
}
return *this;
}
template <typename T> DynamicArray<T>::~DynamicArray()
{
Clear();
}
template <typename T> T& DynamicArray<T>::operator[](unsigned int index)
{
assert((int)index < this->size);
return this->data[index];
}
template <typename T> const T& DynamicArray<T>::operator[](unsigned int index) const
{
assert(index < this->size);
return this->data[index];
}
template <typename T> void DynamicArray<T>::Push(const T& value)
{
Expand(1);
this->data[this->size] = value;
this->size ++;
}
template <typename T> void DynamicArray<T>::Push(unsigned int index, const T& value)
{
int newElem = 1;
if((int)index >= this->size)
newElem = (index + 1) - this->size;
Expand(newElem);
this->data[index] = value;
this->size += newElem;
}
template <typename T> T& DynamicArray<T>::PopFront()
{
return Pop(0);
}
template <typename T> T& DynamicArray<T>::PopBack()
{
return Pop(this->size-1);
}
template <typename T> T& DynamicArray<T>::Pop(unsigned int index)
{
assert((int)index < this->size);
T* temp = new T[this->capacity];
for (int i = 0; i < this->size; i++)
{
if(i != index) temp[i] = this->data[i];
}
delete [] this->data;
this->data = temp;
this->size--;
return this->data[index];
}
template <typename T> void DynamicArray<T>::Remove(unsigned int index)
{
assert(index > this->size);
T* temp = new T[this->capacity - 1];
for (int i = 0; i < this->size; i++)
{
if(i != index) temp[i] = this->data[i];
}
delete [] this->data;
this->data = temp;
this->size--;
}
template <typename T> void DynamicArray<T>::Clear()
{
delete [] this->data;
this->data = 0;
this->size = 0;
this->capacity = 0;
}
template <typename T> void DynamicArray<T>::Expand(int elements)
{
int newSize = this->size + elements;
if(newSize >= this->capacity)
{
T* temp = new T[newSize];
for (int i = 0; i < this->size; i++)
{
temp[i] = this->data[i];
}
this->capacity = newSize;
delete [] this->data;
this->data = temp;
}
}
template <typename T> unsigned int DynamicArray<T>::Size() const
{
return (unsigned int)this->size;
}
template <typename T> unsigned int DynamicArray<T>::Capacity() const
{
return (unsigned int)this->capacity;
}
#pragma endregion
}
}
#endif

29
Code/Misc/GID.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef GID_H
#define GID_H
#include <vector>
/**
* This class only purpos is to generate a uniqe global id, nothing else..
*/
class GID
{
private:
int id;
int usft() { static int ID = 0; return ID++; }
public:
GID::GID() { this->id = usft(); }
GID::~GID() { }
GID(const GID& o) { this->id = usft(); }
const GID& operator=(const GID& o) { this->id = usft(); return *this; }
operator int() const { return this->id; }
bool operator == (const GID& object) const { return (this->id == object.id); }
bool operator == (const int& id) const { return (this->id == id); }
int get() const { return this->id; }
};
#endif

View File

@ -156,7 +156,10 @@
<ClCompile Include="WinTimer.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="DynamicArray.h" />
<ClInclude Include="GID.h" />
<ClInclude Include="IQueue.h" />
<ClInclude Include="OysterCallback.h" />
<ClInclude Include="PostBox\IPostBox.h" />
<ClInclude Include="PostBox\PostBox.h" />
<ClInclude Include="Resource\OysterResource.h" />

View File

@ -92,5 +92,14 @@
<ClInclude Include="PostBox\IPostBox.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DynamicArray.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GID.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="OysterCallback.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,47 @@
//////////////////////////////
// Dennis Andersen 2013 //
//////////////////////////////
#ifndef MISC_OYSTER_CALLBACK_H
#define MISC_OYSTER_CALLBACK_H
#include "PostBox\IPostBox.h"
namespace Oyster
{
namespace Callback
{
template <typename ReturnVal = void, typename ParamVal = void>
struct CallbackFunction
{
typedef ReturnVal (*FNC)(ParamVal);
};
template <typename ReturnVal = void, typename ParamVal = void>
struct CallbackObject
{
virtual ReturnVal ObjectCallback(ParamVal) = 0;
};
enum CallbackType
{
CallbackType_PostBox,
CallbackType_Function,
CallbackType_Object,
};
template <typename ReturnVal = void, typename ParamVal = void>
union OysterCallback
{
IPostBox<ParamVal>* callbackPostBox;
CallbackObject<ReturnVal, ParamVal> *callbackObject;
typename CallbackFunction<ReturnVal, ParamVal>::FNC callbackFunction;
OysterCallback() { memset(this, 0, sizeof(OysterCallback)); }
OysterCallback(IPostBox<ReturnVal>* postbox) { callbackPostBox = postbox; }
OysterCallback(CallbackObject<ReturnVal, ParamVal>* obj) { callbackObject = obj; }
OysterCallback(typename CallbackFunction<ReturnVal, ParamVal>::FNC function) { callbackFunction = function; }
};
}
}
#endif

View File

@ -217,6 +217,24 @@ bool WindowShell::CreateConsoleWindow(bool redirectStdOut, const wchar_t* title)
return true;
}
unsigned int WindowShell::GetWidth()
{
if(!__windowShellData.hWnd) return -1;
RECT rect;
GetWindowRect(__windowShellData.hWnd, &rect);
return (rect.right - rect.left);
}
unsigned int WindowShell::GetHeight()
{
if(!__windowShellData.hWnd) return -1;
RECT rect;
GetWindowRect(__windowShellData.hWnd, &rect);
return (rect.bottom - rect.top);
}
bool WindowShell::Frame()
{
MSG msg = {0};

View File

@ -55,6 +55,9 @@ public:
static bool CreateWin (WINDOW_INIT_DESC&);
static bool CreateConsoleWindow (bool redirectStdOut = true, const wchar_t* title = L"Debug Output");
static unsigned int GetWidth();
static unsigned int GetHeight();
/** Procces window messages if avalible. If the return value was false, the window was destroyed. */
static bool Frame ();
};