Danbias/Code/Network/NetworkAPI/NetworkClient.cpp

247 lines
4.8 KiB
C++
Raw Normal View History

#ifndef INCLUDE_WINSOCK_LIB
#define INCLUDE_WINSOCK_LIB
#pragma comment(lib, "ws2_32.lib")
#endif
2013-12-10 08:32:08 +01:00
#include "NetworkClient.h"
#include "Translator.h"
#include "CustomNetProtocol.h"
#include "../NetworkDependencies/Connection.h"
#include "../NetworkDependencies/PostBox.h"
#include "../NetworkDependencies/WinsockFunctions.h"
#include "../../Misc/Utilities.h"
#include "../../Misc/Thread/IThreadObject.h"
#include "../../Misc/Thread/OysterThread.h"
2013-12-10 08:32:08 +01:00
using namespace Oyster::Network;
using namespace Oyster::Thread;
using namespace Utility::DynamicMemory;
2013-12-10 08:32:08 +01:00
/*************************************
PrivateData
*************************************/
struct NetworkClient::PrivateData : public IThreadObject
2013-12-10 08:32:08 +01:00
{
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();
Connection* connection;
2013-12-10 08:32:08 +01:00
IPostBox<CustomNetProtocol> *sendPostBox;
RecieverObject recvObj;
NetworkProtocolCallbackType callbackType;
Oyster::Thread::OysterThread thread;
std::mutex recvObjMutex;
std::mutex postBoxMutex;
Translator translator;
2013-12-10 08:32:08 +01:00
};
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);
2013-12-12 09:24:57 +01:00
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();
}
2013-12-10 08:32:08 +01:00
/*************************************
NetworkClient
*************************************/
NetworkClient::NetworkClient()
{
privateData = new PrivateData();
}
NetworkClient::NetworkClient(unsigned int socket)
{
privateData = new PrivateData(socket);
}
2013-12-10 08:32:08 +01:00
NetworkClient::NetworkClient(RecieverObject recvObj, NetworkProtocolCallbackType type)
{
privateData = new PrivateData();
this->privateData->recvObj = recvObj;
}
NetworkClient::NetworkClient(RecieverObject recvObj, NetworkProtocolCallbackType type, unsigned int socket)
{
privateData = new PrivateData(socket);
this->privateData->recvObj = recvObj;
this->privateData->callbackType = type;
2013-12-10 08:32:08 +01:00
}
NetworkClient::~NetworkClient()
{
if(privateData)
{
delete privateData;
privateData = NULL;
}
}
bool NetworkClient::Connect(unsigned short port, const char serverIP[])
{
int result = this->privateData->connection->Connect(port, serverIP);
//Connect has succeeded
if(result == 0)
{
privateData->Start();
return true;
}
2013-12-10 08:32:08 +01:00
2013-12-12 09:24:57 +01:00
privateData->connection->SetBlockingMode(false);
//Connect has failed
return false;
2013-12-10 08:32:08 +01:00
}
void NetworkClient::Disconnect()
{
privateData->connection->Disconnect();
2013-12-10 08:32:08 +01:00
}
bool NetworkClient::IsConnected()
{
return privateData->connection->IsConnected();
2013-12-10 08:32:08 +01:00
}
void NetworkClient::Send(CustomNetProtocol& protocol)
2013-12-10 08:32:08 +01:00
{
this->privateData->Send(protocol);
}
2013-12-10 08:32:08 +01:00
void NetworkClient::SetRecieverObject(RecieverObject recvObj, NetworkProtocolCallbackType type)
{
privateData->recvObjMutex.lock();
privateData->recvObj = recvObj;
privateData->callbackType = type;
privateData->recvObjMutex.unlock();
2013-12-10 08:32:08 +01:00
}