Modified namespace around Threadsafe queue and IQueue. Added TCP_NODELAY to sockets. Implemented some functionality to gamelogic

This commit is contained in:
Dennis Andersen 2014-01-15 11:03:25 +01:00
parent 54babfc7c7
commit ceac5ce31d
26 changed files with 500 additions and 189 deletions

View File

@ -13,7 +13,7 @@ using namespace GameLogic;
static int gameClientIDCount = 1;
GameClient::GameClient(SmartPointer<LobbyClient> client, Game::PlayerData player, Oyster::Callback::OysterCallback<void, NetworkSession::NetEvent> value)
GameClient::GameClient(SmartPointer<LobbyClient> client, Game::PlayerData* player, Oyster::Callback::OysterCallback<void, NetworkSession::NetEvent> value)
{
this->callbackValue = value;
this->client = client;
@ -28,8 +28,7 @@ GameClient::GameClient(SmartPointer<LobbyClient> client, Game::PlayerData player
GameClient::~GameClient()
{
if(this->client) this->client->Disconnect();
this->player.playerID = 0;
this->player.teamID = 0;
this->player = 0;
this->id = -1;
}
@ -40,13 +39,12 @@ void GameClient::SetCallback(Oyster::Callback::OysterCallback<void, NetworkSessi
GameLogic::Game::PlayerData* GameClient::GetPlayer()
{
return &this->player;
return this->player;
}
GameLogic::Game::PlayerData GameClient::ReleasePlayer()
GameLogic::Game::PlayerData* GameClient::ReleasePlayer()
{
GameLogic::Game::PlayerData temp = this->player;
this->player.playerID = 0;
this->player.teamID = 0;
GameLogic::Game::PlayerData *temp = this->player;
this->player = 0;
return temp;
}
LobbyClient* GameClient::GetClient() const

View File

@ -13,14 +13,15 @@ namespace DanBias
class GameClient: Oyster::Callback::CallbackObject<void, NetworkSession::NetEvent>
{
public:
GameClient(Utility::DynamicMemory::SmartPointer<LobbyClient> client, GameLogic::Game::PlayerData player, Oyster::Callback::OysterCallback<void, NetworkSession::NetEvent> value);
GameClient(Utility::DynamicMemory::SmartPointer<LobbyClient> client, GameLogic::Game::PlayerData* player, Oyster::Callback::OysterCallback<void, NetworkSession::NetEvent> value);
virtual~GameClient();
void SetCallback(Oyster::Callback::OysterCallback<void, NetworkSession::NetEvent> value);
//GameLogic::Player* GetPlayer();
/* */
GameLogic::Game::PlayerData* GetPlayer();
GameLogic::Game::PlayerData ReleasePlayer();
GameLogic::Game::PlayerData* ReleasePlayer();
LobbyClient* GetClient() const;
Utility::DynamicMemory::SmartPointer<LobbyClient> ReleaseClient();
@ -28,7 +29,7 @@ namespace DanBias
private:
//Utility::DynamicMemory::SmartPointer<GameLogic::Player> player;
GameLogic::Game::PlayerData player;
GameLogic::Game::PlayerData* player;
Utility::DynamicMemory::SmartPointer<LobbyClient> client;
Oyster::Callback::OysterCallback<void, NetworkSession::NetEvent> callbackValue;
int id;

View File

@ -12,6 +12,7 @@
#include <PostBox\IPostBox.h>
#include <Thread\OysterThread.h>
#include <Game.h>
#include <Queue.h>
namespace DanBias
{
@ -30,6 +31,19 @@ namespace DanBias
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<LobbyClient>> clients;
};
struct GameSessionEvent
{
union EventData
{
GameLogic::Game::PlayerData* player;
} data;
enum EventType
{
EventType_Player,
EventType_DynamicObject,
} value;
};
public:
GameSession();
virtual~GameSession();
@ -74,6 +88,8 @@ namespace DanBias
void SendToOwner(DanBias::GameClient* obj);
//Do a cleanup on all the private data
void Clean();
//Update game objects if needed
void UpdateGameObjects();
//Private member variables
private:
@ -83,9 +99,9 @@ namespace DanBias
Oyster::Thread::OysterThread worker;
GameLogic::Game gameInstance;
NetworkSession* owner;
Utility::WinTimer timer;
bool isCreated;
bool isRunning;
Utility::Container::Queue<GameSessionEvent> modifiedClient;
private:
friend class AdminInterface;

View File

@ -38,6 +38,10 @@ namespace DanBias
void GameSession::ParseGameplayEvent(Oyster::Network::CustomNetProtocol& p, DanBias::GameClient* c)
{
GameSessionEvent e;
e.data.player = c->GetPlayer();
e.value = GameSessionEvent::EventType_Player;
switch (p[protocol_INDEX_ID].value.netShort)
{
case protocol_Gameplay_PlayerNavigation:
@ -45,22 +49,17 @@ namespace DanBias
Oyster::Math::Float4x4 world = Oyster::Math::Matrix::identity;
if(p[1].value.netBool) //bool bForward;
world.v[3].x = 2;
//c->GetPlayer()->Move(GameLogic::PLAYER_MOVEMENT_FORWARD);
//world.v[3].x = 2;
c->GetPlayer()->Move(GameLogic::PLAYER_MOVEMENT_FORWARD);
if(p[2].value.netBool) //bool bBackward;
world.v[3].x = -2;
//c->GetPlayer()->Move(GameLogic::PLAYER_MOVEMENT_BACKWARD);
//world.v[3].x = -2;
c->GetPlayer()->Move(GameLogic::PLAYER_MOVEMENT_BACKWARD);
if(p[5].value.netBool) //bool bStrafeRight;
world.v[3].y = 2;
//c->GetPlayer()->Move(GameLogic::PLAYER_MOVEMENT_RIGHT);
//world.v[3].y = 2;
c->GetPlayer()->Move(GameLogic::PLAYER_MOVEMENT_RIGHT);
if(p[6].value.netBool) //bool bStrafeLeft;
world.v[3].y = -2;
//c->GetPlayer()->Move(GameLogic::PLAYER_MOVEMENT_LEFT);
Protocol_ObjectPosition res(world, 0);
Send(res.GetProtocol());
//world.v[3].y = -2;
c->GetPlayer()->Move(GameLogic::PLAYER_MOVEMENT_LEFT);
}
break;
case protocol_Gameplay_PlayerMouseMovement:
@ -76,6 +75,8 @@ namespace DanBias
break;
}
this->modifiedClient.Push(e);
}
void GameSession::ParseGeneralEvent(Oyster::Network::CustomNetProtocol& p, DanBias::GameClient* c)

View File

@ -93,7 +93,7 @@ namespace DanBias
{
if(dissconnectClients)
{
for (int i = 0; i < this->clients.Size(); i++)
for (unsigned int i = 0; i < this->clients.Size(); i++)
{
this->clients[i]->GetClient()->Disconnect();
}
@ -143,7 +143,7 @@ namespace DanBias
}
else
{
for (int i = 0; i < this->clients.Size(); i++)
for (unsigned int i = 0; i < this->clients.Size(); i++)
{
if(this->clients[i])
{

View File

@ -19,10 +19,6 @@ namespace DanBias
{
bool GameSession::DoWork( )
{
this->gameInstance.NewFrame();
this->ParseEvents();
if(GetAsyncKeyState(VK_UP))
{
Protocol_General_Status p(Protocol_General_Status::States_ready);
@ -30,8 +26,30 @@ namespace DanBias
Sleep(100);
}
this->ParseEvents();
this->gameInstance.NewFrame();
this->UpdateGameObjects();
return this->isRunning;
}
void GameSession::UpdateGameObjects()
{
while(!this->modifiedClient.IsEmpty())
{
//There is something that needs update
GameSessionEvent e = this->modifiedClient.Pop();
switch (e.value)
{
case GameSessionEvent::EventType_Player:
//e.data.player->GetOrientation();
break;
}
}
}
}//End namespace DanBias

View File

@ -3,24 +3,60 @@
#include "Level.h"
#include <DynamicArray.h>
#include <GID.h>
#include <PhysicsAPI.h>
#include <WinTimer.h>
using namespace GameLogic;
using namespace Utility::DynamicMemory;
using namespace Oyster::Physics;
#define DELTA_TIME 0.01666666666666666666666666666667f
template<typename T>
int InsertObject(DynamicArray<T*>& list, T* obj)
{
for (unsigned int i = 0; i < list.Size(); i++)
{
if(!list[i])
{
list[i] = obj;
return i;
}
}
list.Push(obj);
return list.Size() - 1;
}
template<typename T>
int RemoveObject(DynamicArray<T*>& list, T* obj)
{
for (unsigned int i = 0; i < list.Size(); i++)
{
if(!list[i])
{
list[i] = obj;
return i;
}
}
list.Push(obj);
return list.Size() - 1;
}
struct Game::PrivateData
{
PrivateData()
{
}
{ }
~PrivateData()
{
for (unsigned int i = 0; i < players.Size(); i++)
{
this->players[i]->player = 0;
}
//DynamicArray<SmartPointer<Player>> players;
DynamicArray<SmartPointer<PlayerData>> players;
}
DynamicArray<PlayerData*> players;
SmartPointer<Level> level;
Utility::WinTimer timer;
}myData;
@ -38,27 +74,18 @@ Game::~Game(void)
}
}
void Game::PlayerUseWeapon(int playerID, const WEAPON_FIRE &Usage)
void Game::GetAllPlayerPositions() const
{
}
void Game::GetPlayerPos(int playerID)
Game::PlayerData* Game::CreatePlayer()
{
}
void Game::GetAllPlayerPos()
{
}
Game::PlayerData Game::CreatePlayer()
{
SmartPointer<Player> newPlayer = new Player();
myData->players.Push(newPlayer);
Player *newPlayer = new Player();
PlayerData *newPdata = new PlayerData();
newPdata->player = newPlayer;
int id = InsertObject(this->myData->players, newPdata);
return this->myData->players[id];
}
void Game::CreateTeam()
@ -68,5 +95,24 @@ void Game::CreateTeam()
void Game::NewFrame()
{
double dt = this->myData->timer.getElapsedSeconds();
//60 fps sec is currently staticly
if(dt >= DELTA_TIME)
{
for (int i = 0; i < this->myData->players.Size(); i++)
{
if(this->myData->players[i]->player)
this->myData->players[i]->player->BeginFrame();
}
API::Instance().Update();
for (int i = 0; i < this->myData->players.Size(); i++)
{
if(this->myData->players[i]->player)
this->myData->players[i]->player->EndFrame();
}
this->myData->timer.reset();
}
}

View File

@ -7,76 +7,77 @@
#include "GameLogicDef.h"
#include "GameLogicStates.h"
#include <OysterMath.h>
namespace GameLogic
{
class Player;
class Game
class DANBIAS_GAMELOGIC_DLL Game
{
public:
struct PlayerData
struct DANBIAS_GAMELOGIC_DLL PlayerData
{
private:
friend class Game;
Player *player;
PlayerData();
PlayerData(int playerID,int teamID);
~PlayerData();
public:
int playerID;
int teamID;
PlayerData();
PlayerData(int playerID,int teamID);
~PlayerData()
{
}
/********************************************************
* Moves the chosen player based on input
* @param playerID: ID of the player you want to recieve the message
* @param movement: enum value on what kind of action is to be taken
********************************************************/
void MovePlayer(const PLAYER_MOVEMENT &movement);
};
public:
Game(void);
~Game(void);
void Move(const PLAYER_MOVEMENT &movement);
/********************************************************
* Uses the chosen players weapon based on input
* @param playerID: ID of the player you want to recieve the message
* @param Usage: enum value on what kind of action is to be taken
********************************************************/
void PlayerUseWeapon(int playerID, const WEAPON_FIRE &Usage);
void UseWeapon(int playerID, const WEAPON_FIRE &Usage);
/********************************************************
* Gets a specific players position
* Gets players position
* @param playerID: ID of the player whos position you want
********************************************************/
void GetPlayerPos(int playerID);
Oyster::Math::Float3 GetPosition();
/********************************************************
* Gets players current orientation
* @param playerID: ID of the player whos position you want
********************************************************/
Oyster::Math::Float4x4 GetOrientation();
/********************************************************
* Check player state
* @return The current player state
********************************************************/
PLAYER_STATE GetState() const;
/***/
int GetID() const;
/***/
int GetTeamID() const;
};
public:
Game(void);
~Game(void);
/********************************************************
* Gets the position of all players currently in the game
********************************************************/
void GetAllPlayerPos();
void GetAllPlayerPositions() const;
/********************************************************
* Creates a player and returns PlayerData containing ID of the player
********************************************************/
PlayerData CreatePlayer();
PlayerData* CreatePlayer();
/********************************************************
* Creates a team
@ -88,7 +89,6 @@ namespace GameLogic
********************************************************/
void NewFrame();
private:
struct PrivateData;
PrivateData *myData;

View File

@ -193,6 +193,7 @@
<ClCompile Include="DynamicObject.cpp" />
<ClCompile Include="Game.cpp" />
<ClCompile Include="GameMode.cpp" />
<ClCompile Include="Game_PlayerData.cpp" />
<ClCompile Include="IAttatchment.cpp" />
<ClCompile Include="Level.cpp" />
<ClCompile Include="Object.cpp" />

View File

@ -16,6 +16,8 @@ namespace GameLogic
PLAYER_STATE_JUMPING = 0,
PLAYER_STATE_WALKING = 1,
PLAYER_STATE_IDLE = 2,
PLAYER_STATE_DEAD = 4,
PLAYER_STATE_INVALID = 8,
};
enum OBJECT_TYPE
@ -37,7 +39,7 @@ namespace GameLogic
enum WEAPON_STATE
{
WEAPON_STATE_FIREING = 0,
WEAPON_STATE_FIRING = 0,
WEAPON_STATE_IDLE = 1,
WEAPON_STATE_RELOADING = 2,
};

View File

@ -7,8 +7,40 @@ Game::PlayerData::PlayerData()
{
}
void Game::PlayerData::MovePlayer(const PLAYER_MOVEMENT &movement)
Game::PlayerData::PlayerData(int playerID,int teamID)
{
}
Game::PlayerData::~PlayerData()
{
}
void Game::PlayerData::Move(const PLAYER_MOVEMENT &movement)
{
this->player->Move(movement);
}
void Game::PlayerData::UseWeapon(int playerID, const WEAPON_FIRE &Usage)
{
}
Oyster::Math::Float3 Game::PlayerData::GetPosition()
{
return this->player->GetPosition();
}
Oyster::Math::Float4x4 Game::PlayerData::GetOrientation()
{
return this->player->GetOrientation();
}
PLAYER_STATE Game::PlayerData::GetState() const
{
return this->player->GetState();
}
int Game::PlayerData::GetID() const
{
return this->player->GetID();
}
int Game::PlayerData::GetTeamID() const
{
return this->player->GetTeamID();
}

View File

@ -16,15 +16,13 @@ Object::Object()
//sbDesc.centerPosition =
//poi
ICustomBody* temp = rigidBody = API::Instance().CreateRigidBody(sbDesc).Release();
ICustomBody* rigidBody = API::Instance().CreateRigidBody(sbDesc).Release();
//rigidBody->gameObjectRef = this;
this->objectID = GID();
this->type = OBJECT_TYPE::OBJECT_TYPE_UNKNOWN;
rigidBody->GetState(state);
}
Object::Object(void* collisionFunc, OBJECT_TYPE type)
@ -42,8 +40,6 @@ Object::Object(void* collisionFunc, OBJECT_TYPE type)
this->objectID = GID();
this->type = type;
rigidBody->GetState(state);
}
@ -52,11 +48,11 @@ Object::~Object(void)
}
OBJECT_TYPE Object::GetType()
OBJECT_TYPE Object::GetType() const
{
return this->type;
}
int Object::GetID()
int Object::GetID() const
{
return this->objectID;
}

View File

@ -19,8 +19,8 @@ namespace GameLogic
Object(void* collisionFunc, OBJECT_TYPE type);
~Object(void);
OBJECT_TYPE GetType();
int GetID();
OBJECT_TYPE GetType() const;
int GetID() const;
Oyster::Physics::ICustomBody* GetRigidBody();
@ -29,7 +29,8 @@ namespace GameLogic
int objectID;
protected:
Oyster::Physics::ICustomBody *rigidBody;
Oyster::Physics::ICustomBody::State state;
Oyster::Physics::ICustomBody::State setState;
Oyster::Physics::ICustomBody::State getState;
};

View File

@ -1,49 +1,26 @@
#include "Player.h"
#include "OysterMath.h"
#include "CollisionManager.h"
#include "Weapon.h"
using namespace GameLogic;
using namespace Oyster::Physics;
struct Player::PrivateData
Player::Player()
:Object(CollisionManager::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER)
{
PrivateData()
{
weapon = new Weapon();
life = 100;
teamID = -1;
playerState = PLAYER_STATE::PLAYER_STATE_IDLE;
lookDir = Oyster::Math::Float4(1,0,0,0);
}
~PrivateData()
{
if (weapon)
{
delete weapon;
}
}
int life;
int teamID;
Weapon *weapon;
PLAYER_STATE playerState;
Oyster::Math::Float4 lookDir;
}myData;
Player::Player()
:Object(CollisionManager::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER)
{
myData = new PrivateData();
}
Player::~Player(void)
{
delete myData;
delete weapon;
weapon = NULL;
}
@ -75,36 +52,36 @@ void Player::Move(const PLAYER_MOVEMENT &movement)
void Player::MoveForward()
{
state.ApplyLinearImpulse(myData->lookDir * 100);
setState.ApplyLinearImpulse(this->lookDir * 100);
}
void Player::MoveBackwards()
{
state.ApplyLinearImpulse(-myData->lookDir * 100);
setState.ApplyLinearImpulse(-this->lookDir * 100);
}
void Player::MoveRight()
{
//Do cross product with forward vector and negative gravity vector
Oyster::Math::Float4 r = (-rigidBody->GetGravityNormal()).Cross((Oyster::Math::Float3)myData->lookDir);
state.ApplyLinearImpulse(r * 100);
Oyster::Math::Float4 r = (-rigidBody->GetGravityNormal()).Cross((Oyster::Math::Float3)this->lookDir);
setState.ApplyLinearImpulse(r * 100);
}
void Player::MoveLeft()
{
//Do cross product with forward vector and negative gravity vector
Oyster::Math::Float4 r = -(-rigidBody->GetGravityNormal()).Cross((Oyster::Math::Float3)myData->lookDir);
state.ApplyLinearImpulse(-r * 100);
Oyster::Math::Float4 r = -(-rigidBody->GetGravityNormal()).Cross((Oyster::Math::Float3)this->lookDir);
setState.ApplyLinearImpulse(-r * 100);
}
void Player::UseWeapon(const WEAPON_FIRE &Usage)
{
myData->weapon->Use(Usage);
this->weapon->Use(Usage);
}
void Player::Respawn(Oyster::Math::Float3 spawnPoint)
{
myData->life = 100;
myData->playerState = PLAYER_STATE::PLAYER_STATE_IDLE;
myData->lookDir = Oyster::Math::Float4(1,0,0);
this->life = 100;
this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE;
this->lookDir = Oyster::Math::Float4(1,0,0);
}
void Player::Jump()
@ -114,33 +91,48 @@ void Player::Jump()
bool Player::IsWalking()
{
return (myData->playerState == PLAYER_STATE::PLAYER_STATE_WALKING);
return (this->playerState == PLAYER_STATE::PLAYER_STATE_WALKING);
}
bool Player::IsJumping()
{
return (myData->playerState == PLAYER_STATE::PLAYER_STATE_JUMPING);
return (this->playerState == PLAYER_STATE::PLAYER_STATE_JUMPING);
}
bool Player::IsIdle()
{
return (myData->playerState == PLAYER_STATE::PLAYER_STATE_IDLE);
return (this->playerState == PLAYER_STATE::PLAYER_STATE_IDLE);
}
Oyster::Math::Float3 Player::GetPos()
Oyster::Math::Float3 Player::GetPosition() const
{
return (Oyster::Math::Float3)state.GetCenterPosition();
return (Oyster::Math::Float3)getState.GetCenterPosition();
}
Oyster::Math::Float3 Player::GetLookDir()
Oyster::Math::Float4x4 Player::GetOrientation() const
{
return myData->lookDir.xyz;
return this->getState.GetOrientation();
}
int Player::GetTeamID()
Oyster::Math::Float3 Player::GetLookDir() const
{
return myData->teamID;
return this->lookDir.xyz;
}
int Player::GetTeamID() const
{
return this->teamID;
}
PLAYER_STATE Player::GetState() const
{
return this->playerState;
}
void Player::DamageLife(int damage)
{
myData->life -= damage;
this->life -= damage;
}
void Player::BeginFrame()
{
this->rigidBody->SetState(this->setState);
}
void Player::EndFrame()
{
this->rigidBody->GetState(this->getState);
}

View File

@ -3,13 +3,18 @@
//////////////////////////////////////////////////
#ifndef PLAYER_H
#define PLAYER_H
#include "GameLogicStates.h"
#include "OysterMath.h"
#include "Object.h"
#include "OysterMath.h"
#include "CollisionManager.h"
namespace GameLogic
{
class Weapon;
class Player : public Object
{
@ -45,18 +50,28 @@ namespace GameLogic
bool IsJumping();
bool IsIdle();
Oyster::Math::Float3 GetPos();
Oyster::Math::Float3 GetLookDir();
int GetTeamID();
Oyster::Math::Float3 GetPosition() const;
Oyster::Math::Float3 GetLookDir() const;
Oyster::Math::Float4x4 GetOrientation() const;
int GetTeamID() const;
PLAYER_STATE GetState() const;
void DamageLife(int damage);
private:
//Do frame calculations
void BeginFrame();
void EndFrame();
void Jump();
private:
struct PrivateData;
PrivateData *myData;
void Jump();
private:
int life;
int teamID;
Weapon *weapon;
PLAYER_STATE playerState;
Oyster::Math::Float4 lookDir;
};
}
#endif

View File

@ -54,7 +54,7 @@ void TeamManager::RespawnPlayerRandom(Player *player)
Player *respawnOnThis = myData->teams[teamID]->GetPlayer(0);
player->Respawn(respawnOnThis->GetPos());
player->Respawn(respawnOnThis->GetPosition());
}
void TeamManager::CreateTeam(int teamSize)

View File

@ -68,7 +68,7 @@ void Weapon::Use(const WEAPON_FIRE &fireInput)
********************************************************/
bool Weapon::IsFireing()
{
return (myData->weaponState == WEAPON_STATE::WEAPON_STATE_FIREING);
return (myData->weaponState == WEAPON_STATE::WEAPON_STATE_FIRING);
}
bool Weapon::IsIdle()

View File

@ -1,13 +1,13 @@
#ifndef I_QUEUE_H
#define I_QUEUE_H
#ifndef MISC_I_QUEUE_H
#define MISC_I_QUEUE_H
/////////////////////////////////
// Created by Sam Svensson 2013//
/////////////////////////////////
namespace Oyster
namespace Utility
{
namespace Queue
namespace Container
{
template <typename Type>
class IQueue
@ -20,13 +20,10 @@ namespace Oyster
virtual ~IQueue() {};
virtual void Push( Type item ) = 0;
virtual Type Pop() = 0;
virtual Type Front() = 0;
virtual Type Back() = 0;
virtual int Size() = 0;
virtual bool IsEmpty() = 0;
virtual void Swap( IQueue<Type> &queue ) = 0;
};
}

View File

@ -162,6 +162,7 @@
<ClInclude Include="OysterCallback.h" />
<ClInclude Include="PostBox\IPostBox.h" />
<ClInclude Include="PostBox\PostBox.h" />
<ClInclude Include="Queue.h" />
<ClInclude Include="Resource\OysterResource.h" />
<ClInclude Include="Resource\OResource.h" />
<ClInclude Include="ThreadSafeQueue.h" />

View File

@ -101,5 +101,8 @@
<ClInclude Include="OysterCallback.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Queue.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -24,7 +24,8 @@ namespace Oyster
virtual bool IsEmpty();
private:
Oyster::Queue::ThreadSafeQueue<T> messages;
Utility::Container::ThreadSafeQueue<T> messages;
//Utility::Container::ThreadSafeQueue<T> messages;
};

181
Code/Misc/Queue.h Normal file
View File

@ -0,0 +1,181 @@
#ifndef MISC_QUEUE_H
#define MISC_QUEUE_H
////////////////////////////////////////////
// Created by Sam Svensson 2013
/////////////////////////////////////////////
#include "IQueue.h"
namespace Utility
{
namespace Container
{
template <typename Type>
class Queue : public IQueue<Type>
{
public:
Queue<Type>();
virtual ~Queue<Type>();
virtual void Push( Type item );
virtual Type Pop();
virtual Type Front();
virtual Type Back();
virtual int Size();
virtual bool IsEmpty();
virtual void Swap( IQueue<Type> &queue );
private:
class Node
{
public:
Type item;
Node *next;
Node(Type item){ this->item = item; this->next = NULL; };
~Node() {};
};
Node *front;
Node *back;
int nrOfNodes;
};
//----------------------------------------------
//implemented template functions
//----------------------------------------------
template < typename Type >
Queue<Type>::Queue()
{
this->front = NULL;
this->back = NULL;
this->nrOfNodes = 0;
}
template < typename Type >
Queue<Type>::~Queue()
{
if(!nrOfNodes) return;
if(this->front != NULL)
{
Node *destroyer;
Node *walker = this->front;
for(int i = 0; i < this->nrOfNodes; i++)
{
destroyer = walker;
walker = walker->next;
delete destroyer;
}
this->front = NULL;
this->back = NULL;
}
}
template < typename Type >
void Queue<Type>::Push(Type item)
{
Node *e = new Node(item);
if(this->front != NULL)
{
this->back->next = e;
this->back = e;
}
else
{
this->front = e;
this->back = e;
}
this->nrOfNodes++;
}
template < typename Type >
Type Queue<Type>::Pop()
{
Type item = this->front->item;
Node *destroyer = this->front;
this->front = front->next;
delete destroyer;
this->nrOfNodes--;
if(nrOfNodes == 0)
{
this->front = NULL;
this->back = NULL;
}
return item;
}
template < typename Type >
Type Queue<Type>::Front()
{
Type temp = this->front->item;
return temp;
}
template < typename Type >
Type Queue<Type>::Back()
{
Type temp = this->back->item;
return temp;
}
template < typename Type >
int Queue<Type>::Size()
{
int size = this->nrOfNodes;
return size;
}
template < typename Type >
bool Queue<Type>::IsEmpty()
{
if(nrOfNodes == 0 || this->front == NULL)
{
return true;
}
return false;
}
template < typename Type >
void Queue<Type>::Swap(IQueue<Type> &queue )
{
int prevNrOfNodes = this->nrOfNodes;
int size = queue.Size();
for(int i = 0; i < size; i++)
{
this->Push(queue.Pop());
}
for(int i = 0; i < prevNrOfNodes; i++)
{
queue.Push(this->Pop());
}
}
}
}
#endif

View File

@ -10,11 +10,10 @@
/////////////////////////////////////////////
#include "IQueue.h"
#include "Thread/OysterMutex.h"
namespace Oyster
namespace Utility
{
namespace Queue
namespace Container
{
template <typename Type>
class ThreadSafeQueue : public IQueue<Type>

View File

@ -211,5 +211,14 @@ int Connection::InitiateSocket()
return WSAGetLastError();
}
int flag = 1;
int result = setsockopt(this->socket, /* socket affected */
IPPROTO_TCP, /* set option at TCP level */
TCP_NODELAY, /* name of option */
(char *) &flag, /* the cast is historical cruft */
sizeof(int)); /* length of option value */
if (result < 0)
return -1;
return 0;
}

View File

@ -27,7 +27,7 @@ namespace Oyster
virtual bool IsFull();
private:
Oyster::Queue::ThreadSafeQueue<T> messages;
Utility::Container::ThreadSafeQueue<T> messages;
};

View File

@ -4,6 +4,7 @@
#include <iostream>
using namespace Oyster::Network;
using namespace Oyster::Thread;
using namespace Utility::Container;
using namespace Utility::DynamicMemory;
ThreadedClient::ThreadedClient()