Merge branch 'MiscBranch' of https://github.com/dean11/Danbias into Network
This commit is contained in:
commit
14eee7d2da
|
@ -152,7 +152,7 @@ OResource* OResource::ByteLoader(const wchar_t filename[], ResourceType type, OR
|
||||||
|
|
||||||
if(!old)
|
if(!old)
|
||||||
{
|
{
|
||||||
resource = new OResource((OHRESOURCE)data, type, (sizeof(char) * sOut.size()), sizeof(char), filename);
|
resource = new OResource((OHRESOURCE&)data, type, (sizeof(char) * sOut.size()), sizeof(char), filename);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,34 +12,49 @@ using namespace Oyster::Resource;
|
||||||
|
|
||||||
OResource* OResource::CustomLoader(const wchar_t filename[], CustomLoadFunction fnc)
|
OResource* OResource::CustomLoader(const wchar_t filename[], CustomLoadFunction fnc)
|
||||||
{
|
{
|
||||||
const CustomData &data = fnc(filename);
|
CustomData data;
|
||||||
|
memset(&data, 0, sizeof(CustomData));
|
||||||
|
|
||||||
if(!data.loadedData) return 0;
|
fnc(filename, data);
|
||||||
if(!data.resourceUnloadFnc) return 0;
|
|
||||||
|
if(!data.loadedData)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!data.resourceUnloadFnc)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/** For some wierd reason that i don't understand when trying to send data.loadedData directly as a
|
||||||
|
* parameter to OResource constructor, the value is changed when it arrives in the constructor.
|
||||||
|
* Doing it like this, storing in a temporary variable, the value stays correct. (What the fuck! I must be overloking something...)*/
|
||||||
|
//OHRESOURCE temp = data.loadedData;
|
||||||
|
OResource *resource = new OResource(data.loadedData, ResourceType_UNKNOWN, 0, 0, filename);
|
||||||
|
|
||||||
OResource *resource = new OResource((OHRESOURCE)data.loadedData, ResourceType_UNKNOWN, 0, 0, filename);
|
|
||||||
|
|
||||||
resource->customData = new CustomResourceData();
|
resource->customData = new CustomResourceData();
|
||||||
resource->customData->unloadingFunction = data.resourceUnloadFnc;
|
resource->customData->unloadingFunction = data.resourceUnloadFnc;
|
||||||
resource->resourceData = (OHRESOURCE)data.loadedData;
|
|
||||||
resource->customData->loadingFunction = fnc;
|
resource->customData->loadingFunction = fnc;
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
void OResource::CustomUnloader()
|
void OResource::CustomUnloader()
|
||||||
{
|
{
|
||||||
this->customData->unloadingFunction((void*)this->resourceData);
|
this->customData->unloadingFunction(this->resourceData);
|
||||||
}
|
}
|
||||||
OResource* OResource::CustomReloader()
|
OResource* OResource::CustomReloader()
|
||||||
{
|
{
|
||||||
CustomUnloader();
|
CustomUnloader();
|
||||||
|
|
||||||
const CustomData &data = this->customData->loadingFunction(this->resourceFilename.c_str());
|
CustomData data;
|
||||||
|
memset(&data, 0, sizeof(CustomData));
|
||||||
|
|
||||||
|
this->customData->loadingFunction(this->resourceFilename.c_str(), data);
|
||||||
this->resourceData = (OHRESOURCE)data.loadedData;
|
this->resourceData = (OHRESOURCE)data.loadedData;
|
||||||
|
|
||||||
if(data.resourceUnloadFnc)
|
if(data.resourceUnloadFnc)
|
||||||
|
{
|
||||||
this->customData->unloadingFunction = data.resourceUnloadFnc;
|
this->customData->unloadingFunction = data.resourceUnloadFnc;
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,17 +7,19 @@
|
||||||
using namespace Oyster::Resource;
|
using namespace Oyster::Resource;
|
||||||
|
|
||||||
OResource::OResource(OHRESOURCE handle, ResourceType type, size_t resourceSize, size_t elementSize, ::std::wstring filename)
|
OResource::OResource(OHRESOURCE handle, ResourceType type, size_t resourceSize, size_t elementSize, ::std::wstring filename)
|
||||||
: resourceData (handle)
|
: resourceFilename (filename)
|
||||||
, resourceFilename (filename)
|
|
||||||
, resourceSize (resourceSize)
|
, resourceSize (resourceSize)
|
||||||
, resourceElementSize (elementSize)
|
, resourceElementSize (elementSize)
|
||||||
, resourceType (type)
|
, resourceType (type)
|
||||||
, customData (0)
|
, customData (0)
|
||||||
{
|
{
|
||||||
|
resourceData = handle;
|
||||||
}
|
}
|
||||||
OResource::~OResource()
|
OResource::~OResource()
|
||||||
{}
|
{
|
||||||
|
delete this->customData;
|
||||||
|
this->customData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
OResource* OResource::Load (const wchar_t filename[], ResourceType type)
|
OResource* OResource::Load (const wchar_t filename[], ResourceType type)
|
||||||
|
|
|
@ -27,19 +27,33 @@ namespace Oyster
|
||||||
virtual~ OResource();
|
virtual~ OResource();
|
||||||
|
|
||||||
inline ResourceType GetResourceType() const
|
inline ResourceType GetResourceType() const
|
||||||
{ return this->resourceType; }
|
{
|
||||||
|
return this->resourceType;
|
||||||
|
}
|
||||||
inline const wchar_t* GetResourceFilename() const
|
inline const wchar_t* GetResourceFilename() const
|
||||||
{ return this->resourceFilename.c_str(); }
|
{
|
||||||
|
return this->resourceFilename.c_str();
|
||||||
|
}
|
||||||
inline OHRESOURCE GetResourceHandle() const
|
inline OHRESOURCE GetResourceHandle() const
|
||||||
{ return this->resourceData; }
|
{
|
||||||
|
return this->resourceData;
|
||||||
|
}
|
||||||
inline unsigned long long GetResourceSize() const
|
inline unsigned long long GetResourceSize() const
|
||||||
{ return this->resourceSize; }
|
{
|
||||||
|
return this->resourceSize;
|
||||||
|
}
|
||||||
inline unsigned long long GetResourceElementSize() const
|
inline unsigned long long GetResourceElementSize() const
|
||||||
{ return this->resourceElementSize; }
|
{
|
||||||
|
return this->resourceElementSize;
|
||||||
|
}
|
||||||
inline unsigned int GetResourceID() const
|
inline unsigned int GetResourceID() const
|
||||||
{ return this->resourceID; }
|
{
|
||||||
inline void SetResourceID(unsigned int id)
|
return this->resourceID;
|
||||||
{ this->resourceID = id; }
|
}
|
||||||
|
inline void SetResourceID(int id)
|
||||||
|
{
|
||||||
|
this->resourceID = id;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static OResource* Load (const wchar_t filename[], ResourceType type);
|
static OResource* Load (const wchar_t filename[], ResourceType type);
|
||||||
|
@ -63,7 +77,7 @@ namespace Oyster
|
||||||
size_t resourceSize;
|
size_t resourceSize;
|
||||||
size_t resourceElementSize;
|
size_t resourceElementSize;
|
||||||
::std::wstring resourceFilename;
|
::std::wstring resourceFilename;
|
||||||
unsigned int resourceID;
|
int resourceID;
|
||||||
|
|
||||||
CustomResourceData *customData;
|
CustomResourceData *customData;
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,7 +43,7 @@ OHRESOURCE OysterResource::LoadResource(const wchar_t* filename, ResourceType ty
|
||||||
|
|
||||||
return resourceData->GetResourceHandle();
|
return resourceData->GetResourceHandle();
|
||||||
}
|
}
|
||||||
OHRESOURCE OysterResource::LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc, unsigned int CustomId)
|
OHRESOURCE OysterResource::LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc, int CustomId)
|
||||||
{
|
{
|
||||||
if(!filename) return 0;
|
if(!filename) return 0;
|
||||||
if(!loadFnc) return 0;
|
if(!loadFnc) return 0;
|
||||||
|
@ -67,14 +67,14 @@ OHRESOURCE OysterResource::LoadResource(const wchar_t filename[], CustomLoadFunc
|
||||||
return (OHRESOURCE)resourceData->GetResourceHandle();
|
return (OHRESOURCE)resourceData->GetResourceHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
OHRESOURCE ReloadResource(const wchar_t filename[])
|
OHRESOURCE OysterResource::ReloadResource(const wchar_t filename[])
|
||||||
{
|
{
|
||||||
OResource *resourceData = resourcePrivate.FindResource(filename);
|
OResource *resourceData = resourcePrivate.FindResource(filename);
|
||||||
if(!resourceData) return 0; //The resource has not been loaded
|
if(!resourceData) return 0; //The resource has not been loaded
|
||||||
|
|
||||||
return OResource::Reload(resourceData)->GetResourceHandle();
|
return OResource::Reload(resourceData)->GetResourceHandle();
|
||||||
}
|
}
|
||||||
OHRESOURCE ReloadResource(OHRESOURCE resource)
|
OHRESOURCE OysterResource::ReloadResource(OHRESOURCE resource)
|
||||||
{
|
{
|
||||||
OResource *resourceData = resourcePrivate.FindResource(resource);
|
OResource *resourceData = resourcePrivate.FindResource(resource);
|
||||||
if(!resourceData) return 0; //The resource has not been loaded
|
if(!resourceData) return 0; //The resource has not been loaded
|
||||||
|
@ -89,12 +89,13 @@ void OysterResource::Clean()
|
||||||
|
|
||||||
for (i; i != last; i++)
|
for (i; i != last; i++)
|
||||||
{
|
{
|
||||||
if(OResource::Release(i->second))
|
//Remove all the references
|
||||||
{
|
while (!OResource::Release(i->second));
|
||||||
const wchar_t* temp = i->second->GetResourceFilename();
|
|
||||||
delete resourcePrivate.resources[temp];
|
const wchar_t* temp = i->second->GetResourceFilename();
|
||||||
resourcePrivate.resources.erase(temp);
|
delete resourcePrivate.resources[temp];
|
||||||
}
|
resourcePrivate.resources.erase(temp);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void OysterResource::ReleaseResource(const OHRESOURCE& resourceData)
|
void OysterResource::ReleaseResource(const OHRESOURCE& resourceData)
|
||||||
|
@ -110,6 +111,19 @@ void OysterResource::ReleaseResource(const OHRESOURCE& resourceData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void OysterResource::ReleaseResource(const wchar_t filename[])
|
||||||
|
{
|
||||||
|
OResource* t = resourcePrivate.FindResource(filename);
|
||||||
|
if(t)
|
||||||
|
{
|
||||||
|
if(OResource::Release(t))
|
||||||
|
{
|
||||||
|
const wchar_t* temp = t->GetResourceFilename();
|
||||||
|
delete resourcePrivate.resources[temp];
|
||||||
|
resourcePrivate.resources.erase(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OysterResource::SetResourceId (const OHRESOURCE& resourceData, unsigned int id)
|
void OysterResource::SetResourceId (const OHRESOURCE& resourceData, unsigned int id)
|
||||||
{
|
{
|
||||||
|
@ -117,13 +131,27 @@ void OysterResource::SetResourceId (const OHRESOURCE& resourceData, unsigned int
|
||||||
|
|
||||||
if(t) t->SetResourceID(id);
|
if(t) t->SetResourceID(id);
|
||||||
}
|
}
|
||||||
|
void OysterResource::SetResourceId(const wchar_t c[], unsigned int id)
|
||||||
|
{
|
||||||
|
OResource* t = resourcePrivate.FindResource(c);
|
||||||
|
|
||||||
|
if(t) t->SetResourceID(id);
|
||||||
|
}
|
||||||
ResourceType OysterResource::GetResourceType (const OHRESOURCE& resourceData)
|
ResourceType OysterResource::GetResourceType (const OHRESOURCE& resourceData)
|
||||||
{
|
{
|
||||||
OResource* t = resourcePrivate.FindResource(resourceData);
|
OResource* t = resourcePrivate.FindResource(resourceData);
|
||||||
|
|
||||||
if(t) return t->GetResourceType();
|
if(t) return t->GetResourceType();
|
||||||
|
|
||||||
return ResourceType_UNKNOWN;
|
return ResourceType_INVALID;
|
||||||
|
}
|
||||||
|
ResourceType OysterResource::GetResourceType (const wchar_t c[])
|
||||||
|
{
|
||||||
|
OResource* t = resourcePrivate.FindResource(c);
|
||||||
|
|
||||||
|
if(t) return t->GetResourceType();
|
||||||
|
|
||||||
|
return ResourceType_INVALID;
|
||||||
}
|
}
|
||||||
const wchar_t* OysterResource::GetResourceFilename (const OHRESOURCE& resourceData)
|
const wchar_t* OysterResource::GetResourceFilename (const OHRESOURCE& resourceData)
|
||||||
{
|
{
|
||||||
|
@ -133,7 +161,15 @@ const wchar_t* OysterResource::GetResourceFilename (const OHRESOURCE& resourceDa
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
unsigned int OysterResource::GetResourceId (const OHRESOURCE& resourceData)
|
OHRESOURCE OysterResource::GetResourceHandle(const wchar_t filename[])
|
||||||
|
{
|
||||||
|
OResource* t = resourcePrivate.FindResource(filename);
|
||||||
|
|
||||||
|
if(t) return t->GetResourceHandle();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int OysterResource::GetResourceId (const OHRESOURCE& resourceData)
|
||||||
{
|
{
|
||||||
OResource* t = resourcePrivate.FindResource(resourceData);
|
OResource* t = resourcePrivate.FindResource(resourceData);
|
||||||
|
|
||||||
|
@ -141,7 +177,14 @@ unsigned int OysterResource::GetResourceId (const OHRESOURCE& resourceData)
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
int OysterResource::GetResourceId(const wchar_t c[])
|
||||||
|
{
|
||||||
|
OResource* t = resourcePrivate.FindResource(c);
|
||||||
|
|
||||||
|
if(t) return t->GetResourceID();
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
OResource* ResourcePrivate::FindResource(const OHRESOURCE& h) const
|
OResource* ResourcePrivate::FindResource(const OHRESOURCE& h) const
|
||||||
|
|
|
@ -12,11 +12,11 @@ namespace Oyster
|
||||||
{
|
{
|
||||||
struct CustomData;
|
struct CustomData;
|
||||||
/** A Resource handle representing various resources */
|
/** A Resource handle representing various resources */
|
||||||
typedef unsigned long OHRESOURCE;
|
typedef void* OHRESOURCE;
|
||||||
/** Typedef on a fuction required for custom unloading */
|
/** Typedef on a fuction required for custom unloading */
|
||||||
typedef void(*CustomUnloadFunction)(void* loadedData);
|
typedef void(*CustomUnloadFunction)(void* loadedData);
|
||||||
/** Typedef on a fuction required for custom loading */
|
/** Typedef on a fuction required for custom loading */
|
||||||
typedef const CustomData&(*CustomLoadFunction)(const wchar_t filename[]);
|
typedef void(*CustomLoadFunction)(const wchar_t filename[], CustomData& outData);
|
||||||
|
|
||||||
/** An enum class representing all avalible resources that is supported. */
|
/** An enum class representing all avalible resources that is supported. */
|
||||||
enum ResourceType
|
enum ResourceType
|
||||||
|
@ -31,15 +31,14 @@ namespace Oyster
|
||||||
ResourceType_COUNT, /**< Not used. */
|
ResourceType_COUNT, /**< Not used. */
|
||||||
|
|
||||||
ResourceType_UNKNOWN = -1, /**< Handle can be interpeted as void* */
|
ResourceType_UNKNOWN = -1, /**< Handle can be interpeted as void* */
|
||||||
|
ResourceType_INVALID = -2, /**< Invalid or non existing resource */
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A struct to return when doing a custom resource Load
|
/** A struct to fill when doing a custom resource Load. */
|
||||||
* By loading this way you are handing over the ownership to the resource loaded.
|
|
||||||
*/
|
|
||||||
struct CustomData
|
struct CustomData
|
||||||
{
|
{
|
||||||
void* loadedData; ///<! The loaded resource interpeted as a void*.
|
void* loadedData; //<! The loaded resource interpeted as a void*.
|
||||||
CustomUnloadFunction resourceUnloadFnc; ///<! The function that will be used to free the resource when needed.
|
CustomUnloadFunction resourceUnloadFnc; //<! The function that will be used to free the resource when needed.
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A resource handler interface to interact with when loading resources.
|
/** A resource handler interface to interact with when loading resources.
|
||||||
|
@ -64,7 +63,7 @@ namespace Oyster
|
||||||
* @param loadFnc If set, this gives you the right to do custom resource loading if your recource type is not supported.
|
* @param loadFnc If set, this gives you the right to do custom resource loading if your recource type is not supported.
|
||||||
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
|
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
|
||||||
*/
|
*/
|
||||||
static OHRESOURCE LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc = 0, unsigned int CustomId = 0);
|
static OHRESOURCE LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc = 0, int CustomId = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reload a resource
|
* Reload a resource
|
||||||
|
@ -93,29 +92,63 @@ namespace Oyster
|
||||||
*/
|
*/
|
||||||
static void ReleaseResource(const OHRESOURCE& resource);
|
static void ReleaseResource(const OHRESOURCE& resource);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release a reference to the resource handle
|
||||||
|
* @param resource The resource filename to release reference.
|
||||||
|
* @return Nothing
|
||||||
|
*/
|
||||||
|
static void ReleaseResource(const wchar_t filename[]);
|
||||||
|
|
||||||
/** Set a user defined ID
|
/** Set a user defined ID
|
||||||
* @param resource A handle to accociate the id with.
|
* @param resource A handle to accociate the id with.
|
||||||
* @param id A user defined identifier that the resource handler does not touch.
|
* @param id A user defined identifier that the resource handler does not touch.
|
||||||
*/
|
*/
|
||||||
static void SetResourceId(const OHRESOURCE& resource, unsigned int id);
|
static void SetResourceId(const OHRESOURCE& resource, unsigned int id);
|
||||||
|
|
||||||
|
/** Set a user defined ID
|
||||||
|
* If the resource is not loaded the id will not be set.
|
||||||
|
* @param resource A filename to accociate the id with.
|
||||||
|
* @param id A user defined identifier that the resource handler does not touch.
|
||||||
|
*/
|
||||||
|
static void SetResourceId(const wchar_t filename[], unsigned int id);
|
||||||
|
|
||||||
/** Get a resource type given a OHRESOURCE handle
|
/** Get a resource type given a OHRESOURCE handle
|
||||||
* @param resource The handle to check
|
* @param resource The handle to check
|
||||||
* @return Returns the resource type of the handle
|
* @return Returns the resource type of the handle
|
||||||
*/
|
*/
|
||||||
static ResourceType GetResourceType(const OHRESOURCE& resource);
|
static ResourceType GetResourceType(const OHRESOURCE& resource);
|
||||||
|
|
||||||
|
/** Get a resource type given a filename
|
||||||
|
* If the resource is not loaded the id will not be set.
|
||||||
|
* @param resource The filename to check
|
||||||
|
* @return Returns the resource type of the handle
|
||||||
|
*/
|
||||||
|
static ResourceType GetResourceType (const wchar_t filename[]);
|
||||||
|
|
||||||
/** Get a resource filename given a OHRESOURCE handle
|
/** Get a resource filename given a OHRESOURCE handle
|
||||||
* @param resource The handle to check
|
* @param resource The handle to check
|
||||||
* @return Returns the accociated filename
|
* @return Returns the accociated filename
|
||||||
*/
|
*/
|
||||||
static const wchar_t* GetResourceFilename(const OHRESOURCE& resource);
|
static const wchar_t* GetResourceFilename(const OHRESOURCE& resource);
|
||||||
|
|
||||||
|
/** Get a resource handle given a filename
|
||||||
|
* If the resource is not loaded function returns 0.
|
||||||
|
* @param resource The filename to check
|
||||||
|
* @return Returns the accociated handle
|
||||||
|
*/
|
||||||
|
static OHRESOURCE GetResourceHandle(const wchar_t filename[]);
|
||||||
|
|
||||||
/** Get a user defined ID accociated with a handle
|
/** Get a user defined ID accociated with a handle
|
||||||
* @param resource The handle to check
|
* @param resource The handle to check
|
||||||
* @return Returns the accociated ID
|
* @return Returns the accociated ID
|
||||||
*/
|
*/
|
||||||
static unsigned int GetResourceId(const OHRESOURCE& resource);
|
static int GetResourceId(const OHRESOURCE& resource);
|
||||||
|
|
||||||
|
/** Get a user defined ID accociated with a filename
|
||||||
|
* @param resource The filename to check
|
||||||
|
* @return Returns the accociated ID
|
||||||
|
*/
|
||||||
|
static int GetResourceId(const wchar_t filename[]);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,9 +63,4 @@ void OysterMutex::UnlockMutex()
|
||||||
bool OysterMutex::IsTaken()
|
bool OysterMutex::IsTaken()
|
||||||
{
|
{
|
||||||
return !this->mutex.try_lock();
|
return !this->mutex.try_lock();
|
||||||
}
|
|
||||||
void OysterMutex::Reset()
|
|
||||||
{
|
|
||||||
if(!this->mutex.try_lock())
|
|
||||||
this->mutex.unlock();
|
|
||||||
}
|
}
|
|
@ -20,8 +20,6 @@ public:
|
||||||
void UnlockMutex();
|
void UnlockMutex();
|
||||||
/** Returns true if mutex is taken */
|
/** Returns true if mutex is taken */
|
||||||
bool IsTaken();
|
bool IsTaken();
|
||||||
/** This function resets resource locking */
|
|
||||||
void Reset();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#define MISC_OYSTER_THREAD_H
|
#define MISC_OYSTER_THREAD_H
|
||||||
|
|
||||||
#include "IThreadObject.h"
|
#include "IThreadObject.h"
|
||||||
|
|
||||||
namespace Oyster
|
namespace Oyster
|
||||||
{
|
{
|
||||||
namespace Thread
|
namespace Thread
|
||||||
|
@ -23,11 +22,10 @@ namespace Oyster
|
||||||
struct PrivateData;
|
struct PrivateData;
|
||||||
PrivateData *privateData;
|
PrivateData *privateData;
|
||||||
|
|
||||||
OysterThread(const OysterThread& original);
|
|
||||||
const OysterThread& operator=(const OysterThread& original);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OysterThread();
|
OysterThread();
|
||||||
|
OysterThread(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);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "..\Utilities.h"
|
#include "..\Utilities.h"
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
using namespace Oyster::Thread;
|
using namespace Oyster::Thread;
|
||||||
using namespace Utility::DynamicMemory::SmartPointer;
|
using namespace Utility::DynamicMemory::SmartPointer;
|
||||||
|
@ -24,24 +25,23 @@ using namespace Utility::DynamicMemory::SmartPointer;
|
||||||
OYSTER_THREAD_STATE_RUNNING,
|
OYSTER_THREAD_STATE_RUNNING,
|
||||||
OYSTER_THREAD_STATE_PAUSED,
|
OYSTER_THREAD_STATE_PAUSED,
|
||||||
OYSTER_THREAD_STATE_STOPED,
|
OYSTER_THREAD_STATE_STOPED,
|
||||||
OYSTER_THREAD_STATE_TERMINATED,
|
|
||||||
OYSTER_THREAD_STATE_DEAD,
|
OYSTER_THREAD_STATE_DEAD,
|
||||||
};
|
};
|
||||||
|
|
||||||
//TODO: Add a threadStartPackage struct that contains all the necasary data to fire of a thread
|
|
||||||
struct ThreadData
|
struct ThreadData
|
||||||
{
|
{
|
||||||
OYSTER_THREAD_STATE state; //<! The current thread state.
|
std::atomic<OYSTER_THREAD_STATE> state; //<! The current thread state.
|
||||||
StdSmartPointer<std::thread> workerThread; //<! The worker thread.
|
//OYSTER_THREAD_STATE state; //<! The current thread state.
|
||||||
std::thread::id callingThread; //<! The owner thread.
|
StdSmartPointer<std::thread> workerThread; //<! The worker thread.
|
||||||
IThreadObject *owner; //<! The owner of the thread as IThread.
|
std::thread::id callingThread; //<! The owner thread.
|
||||||
int msec; //<! A timer in miliseconds.
|
IThreadObject *owner; //<! The owner of the thread as IThread.
|
||||||
OysterMutex mutexLock; //<! The lock, locking the member variabls.
|
std::atomic<int> msec; //<! A timer in miliseconds.
|
||||||
|
//OysterMutex mutexLock; //<! The lock, locking the member variabls.
|
||||||
|
|
||||||
ThreadData() {}
|
ThreadData() {}
|
||||||
|
~ThreadData() {}
|
||||||
private:
|
ThreadData(const ThreadData&) {};
|
||||||
ThreadData(const ThreadData&){};
|
|
||||||
};
|
};
|
||||||
struct OysterThread::PrivateData
|
struct OysterThread::PrivateData
|
||||||
{
|
{
|
||||||
|
@ -55,6 +55,10 @@ using namespace Utility::DynamicMemory::SmartPointer;
|
||||||
threadData->callingThread;
|
threadData->callingThread;
|
||||||
threadData->state = OYSTER_THREAD_STATE_STOPED;
|
threadData->state = OYSTER_THREAD_STATE_STOPED;
|
||||||
}
|
}
|
||||||
|
PrivateData(const PrivateData& o)
|
||||||
|
{
|
||||||
|
threadData = o.threadData;
|
||||||
|
}
|
||||||
~PrivateData()
|
~PrivateData()
|
||||||
{
|
{
|
||||||
//@todo TODO: Make detatch avalible.
|
//@todo TODO: Make detatch avalible.
|
||||||
|
@ -70,35 +74,46 @@ using namespace Utility::DynamicMemory::SmartPointer;
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
|
||||||
|
int tempId = 0;
|
||||||
|
std::vector<int> IDS;
|
||||||
static void ThreadingFunction(StdSmartPointer<ThreadData> &origin)
|
static void ThreadingFunction(StdSmartPointer<ThreadData> &origin)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool shouldContinue;
|
bool shouldContinue;
|
||||||
StdSmartPointer<ThreadData> w = origin;
|
StdSmartPointer<ThreadData> w = origin;
|
||||||
|
|
||||||
theBegining:
|
theBegining:
|
||||||
|
|
||||||
while(w->state == OYSTER_THREAD_STATE_STOPED);
|
while(w->state == OYSTER_THREAD_STATE_STOPED)
|
||||||
w->mutexLock.LockMutex();
|
{
|
||||||
w->owner->ThreadEntry();
|
std::this_thread::yield();
|
||||||
w->mutexLock.UnlockMutex();
|
}
|
||||||
|
|
||||||
|
// 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)
|
while (w->state != OYSTER_THREAD_STATE_STOPED && w->state != OYSTER_THREAD_STATE_DEAD)
|
||||||
{
|
{
|
||||||
|
// w->mutexLock.LockMutex();
|
||||||
w->mutexLock.LockMutex();
|
|
||||||
{
|
{
|
||||||
shouldContinue = w->owner->DoWork();
|
if(w->owner)
|
||||||
|
{
|
||||||
|
shouldContinue = w->owner->DoWork();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
w->mutexLock.UnlockMutex();
|
// w->mutexLock.UnlockMutex();
|
||||||
|
|
||||||
if(!shouldContinue)
|
if(!shouldContinue)
|
||||||
{
|
{
|
||||||
goto theEnd;
|
goto theEnd;
|
||||||
}
|
}
|
||||||
if(w->state == OYSTER_THREAD_STATE_TERMINATED)
|
if(w->state == OYSTER_THREAD_STATE_DEAD)
|
||||||
{
|
{
|
||||||
return;
|
goto theEnd;
|
||||||
}
|
}
|
||||||
else if(w->state == OYSTER_THREAD_STATE_RESET)
|
else if(w->state == OYSTER_THREAD_STATE_RESET)
|
||||||
{
|
{
|
||||||
|
@ -109,19 +124,26 @@ theBegining:
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(w->msec));
|
std::this_thread::sleep_for(std::chrono::milliseconds(w->msec));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (w->state == OYSTER_THREAD_STATE_PAUSED);
|
while (w->state == OYSTER_THREAD_STATE_PAUSED)
|
||||||
|
{
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(w->state == OYSTER_THREAD_STATE_DEAD)
|
if(w->state == OYSTER_THREAD_STATE_DEAD)
|
||||||
{
|
{
|
||||||
|
w->workerThread->detach();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
theEnd:
|
theEnd:
|
||||||
|
|
||||||
w->mutexLock.LockMutex();
|
// w->mutexLock.LockMutex();
|
||||||
w->owner->ThreadExit();
|
if(w->owner)
|
||||||
w->mutexLock.UnlockMutex();
|
{
|
||||||
|
w->owner->ThreadExit();
|
||||||
|
}
|
||||||
|
// w->mutexLock.UnlockMutex();
|
||||||
|
|
||||||
w->state = OYSTER_THREAD_STATE_DEAD;
|
w->state = OYSTER_THREAD_STATE_DEAD;
|
||||||
}
|
}
|
||||||
|
@ -130,6 +152,14 @@ OysterThread::OysterThread()
|
||||||
{
|
{
|
||||||
this->privateData = new PrivateData();
|
this->privateData = new PrivateData();
|
||||||
}
|
}
|
||||||
|
OysterThread::OysterThread(const OysterThread& original)
|
||||||
|
{
|
||||||
|
this->privateData = new PrivateData(*original.privateData);
|
||||||
|
}
|
||||||
|
const OysterThread& OysterThread::operator=(const OysterThread& original)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
OysterThread::~OysterThread()
|
OysterThread::~OysterThread()
|
||||||
{
|
{
|
||||||
delete this->privateData;
|
delete this->privateData;
|
||||||
|
@ -153,30 +183,33 @@ OYSTER_THREAD_ERROR OysterThread::Create(IThreadObject* worker, bool start)
|
||||||
|
|
||||||
if(start)
|
if(start)
|
||||||
{
|
{
|
||||||
//@todo TODO: No need to lock since the other thread end is only reading this value. Worst case scenario is n lost cycles.
|
|
||||||
this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING;
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING;
|
||||||
}
|
}
|
||||||
return OYSTER_THREAD_ERROR_SUCCESS;
|
return OYSTER_THREAD_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
OYSTER_THREAD_ERROR OysterThread::Start()
|
OYSTER_THREAD_ERROR OysterThread::Start()
|
||||||
{
|
{
|
||||||
|
if(!this->privateData->threadData->owner)
|
||||||
|
return OYSTER_THREAD_ERROR_FAILED;
|
||||||
if(!this->privateData->threadData->workerThread)
|
if(!this->privateData->threadData->workerThread)
|
||||||
return OYSTER_THREAD_ERROR_FAILED;
|
return OYSTER_THREAD_ERROR_FAILED;
|
||||||
|
if(this->privateData->threadData->state == OYSTER_THREAD_STATE_DEAD)
|
||||||
|
return OYSTER_THREAD_ERROR_FAILED;
|
||||||
|
|
||||||
this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING;
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING;
|
||||||
return OYSTER_THREAD_ERROR_SUCCESS;
|
return OYSTER_THREAD_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
void OysterThread::Stop()
|
void OysterThread::Stop()
|
||||||
{
|
{
|
||||||
this->privateData->threadData->mutexLock.LockMutex();
|
//this->privateData->threadData->mutexLock.LockMutex();
|
||||||
this->privateData->threadData->state = OYSTER_THREAD_STATE_STOPED;
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_STOPED;
|
||||||
this->privateData->threadData->mutexLock.UnlockMutex();
|
//this->privateData->threadData->mutexLock.UnlockMutex();
|
||||||
}
|
}
|
||||||
void OysterThread::Pause()
|
void OysterThread::Pause()
|
||||||
{
|
{
|
||||||
this->privateData->threadData->mutexLock.LockMutex();
|
//this->privateData->threadData->mutexLock.LockMutex();
|
||||||
this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED;
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED;
|
||||||
this->privateData->threadData->mutexLock.UnlockMutex();
|
//this->privateData->threadData->mutexLock.UnlockMutex();
|
||||||
}
|
}
|
||||||
void OysterThread::Pause(int msec)
|
void OysterThread::Pause(int msec)
|
||||||
{
|
{
|
||||||
|
@ -187,39 +220,34 @@ void OysterThread::Pause(int msec)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->privateData->threadData->mutexLock.LockMutex();
|
//this->privateData->threadData->mutexLock.LockMutex();
|
||||||
this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED;
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED;
|
||||||
this->privateData->threadData->msec = msec;
|
this->privateData->threadData->msec = msec;
|
||||||
this->privateData->threadData->mutexLock.UnlockMutex();
|
//this->privateData->threadData->mutexLock.UnlockMutex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void OysterThread::Resume()
|
void OysterThread::Resume()
|
||||||
{
|
{
|
||||||
this->privateData->threadData->mutexLock.LockMutex();
|
// this->privateData->threadData->mutexLock.LockMutex();
|
||||||
this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING;
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING;
|
||||||
this->privateData->threadData->mutexLock.UnlockMutex();
|
// 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->threadData->mutexLock.LockMutex();
|
||||||
if(worker)
|
if(worker)
|
||||||
{
|
{
|
||||||
this->privateData->threadData->owner = worker;
|
this->privateData->threadData->owner = worker;
|
||||||
}
|
}
|
||||||
this->privateData->threadData->callingThread = std::this_thread::get_id();
|
this->privateData->threadData->callingThread = std::this_thread::get_id();
|
||||||
this->privateData->threadData->msec = 0;
|
this->privateData->threadData->msec = 0;
|
||||||
this->privateData->threadData->mutexLock.UnlockMutex();
|
// this->privateData->threadData->mutexLock.UnlockMutex();
|
||||||
|
|
||||||
return OYSTER_THREAD_ERROR_SUCCESS;
|
return OYSTER_THREAD_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
void OysterThread::Terminate()
|
void OysterThread::Terminate()
|
||||||
{
|
{
|
||||||
delete this->privateData->threadData->workerThread;
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_DEAD;
|
||||||
this->privateData->threadData->mutexLock.Reset();
|
|
||||||
this->privateData->threadData->workerThread = 0;
|
|
||||||
this->privateData->threadData->callingThread = std::thread::id();
|
|
||||||
this->privateData->threadData->msec = 0;
|
|
||||||
this->privateData->threadData->state = OYSTER_THREAD_STATE_STOPED;
|
|
||||||
}
|
}
|
||||||
void OysterThread::Wait()
|
void OysterThread::Wait()
|
||||||
{
|
{
|
||||||
|
@ -250,4 +278,4 @@ bool OysterThread::IsActive()
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,8 +165,7 @@ namespace Utility
|
||||||
|
|
||||||
namespace SmartPointer
|
namespace SmartPointer
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T> void StdSmartPointer<T>::Destroy()
|
||||||
void StdSmartPointer<T>::Destroy()
|
|
||||||
{
|
{
|
||||||
delete this->_rc;
|
delete this->_rc;
|
||||||
this->_rc = NULL;
|
this->_rc = NULL;
|
||||||
|
@ -200,7 +199,7 @@ namespace Utility
|
||||||
if (this != &p)
|
if (this != &p)
|
||||||
{
|
{
|
||||||
//Last to go?
|
//Last to go?
|
||||||
if(this->_rc && this->_rc->Release() == 0)
|
if(this->_rc && this->_rc->Decref() == 0)
|
||||||
{
|
{
|
||||||
//Call child specific
|
//Call child specific
|
||||||
Destroy();
|
Destroy();
|
||||||
|
@ -208,7 +207,7 @@ namespace Utility
|
||||||
|
|
||||||
this->_ptr = p._ptr;
|
this->_ptr = p._ptr;
|
||||||
this->_rc = p._rc;
|
this->_rc = p._rc;
|
||||||
this->_rc->Add();
|
this->_rc->Incref();
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -254,16 +253,14 @@ namespace Utility
|
||||||
{
|
{
|
||||||
return this->_ptr;
|
return this->_ptr;
|
||||||
}
|
}
|
||||||
|
template<typename T> inline StdSmartPointer<T>::operator bool()
|
||||||
/**
|
{
|
||||||
* Returns the connected pointer */
|
return (this->_ptr != 0);
|
||||||
|
}
|
||||||
template<typename T> inline T* StdSmartPointer<T>::Get()
|
template<typename T> inline T* StdSmartPointer<T>::Get()
|
||||||
{
|
{
|
||||||
return this->_ptr;
|
return this->_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if the pointer is valid (not NULL)
|
|
||||||
Returns true for valid, else false. */
|
|
||||||
template<typename T> inline bool StdSmartPointer<T>::IsValid()
|
template<typename T> inline bool StdSmartPointer<T>::IsValid()
|
||||||
{
|
{
|
||||||
return (this->_ptr != NULL) ? true : false;
|
return (this->_ptr != NULL) ? true : false;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
namespace Utility
|
namespace Utility
|
||||||
{
|
{
|
||||||
|
@ -110,12 +111,12 @@ namespace Utility
|
||||||
struct ReferenceCount
|
struct ReferenceCount
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int count;
|
std::atomic<int> count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ReferenceCount() :count(0) { }
|
ReferenceCount() :count(0) { }
|
||||||
ReferenceCount(const ReferenceCount& o) { count = o.count; }
|
ReferenceCount(const ReferenceCount& o) { count.store(o.count); }
|
||||||
inline const ReferenceCount& operator=(const ReferenceCount& o) { count = o.count; return *this;}
|
inline const ReferenceCount& operator=(const ReferenceCount& o) { count.store(o.count); return *this;}
|
||||||
inline void Incref() { this->count++; }
|
inline void Incref() { this->count++; }
|
||||||
inline void Incref(int c) { this->count += c; }
|
inline void Incref(int c) { this->count += c; }
|
||||||
inline int Decref() { return --this->count;}
|
inline int Decref() { return --this->count;}
|
||||||
|
@ -151,6 +152,7 @@ namespace Utility
|
||||||
T& operator* ();
|
T& operator* ();
|
||||||
T* operator-> ();
|
T* operator-> ();
|
||||||
operator T* ();
|
operator T* ();
|
||||||
|
operator bool();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the connected pointer */
|
* Returns the connected pointer */
|
||||||
|
|
Loading…
Reference in New Issue