diff --git a/Code/Misc/Resource/Loaders/CustomLoader.cpp.orig b/Code/Misc/Resource/Loaders/CustomLoader.cpp.orig new file mode 100644 index 00000000..15dea599 --- /dev/null +++ b/Code/Misc/Resource/Loaders/CustomLoader.cpp.orig @@ -0,0 +1,65 @@ + +#include "..\OResource.h" +#include "..\..\Utilities.h" + +#include + +using namespace Oyster::Resource; + + +OResource* OResource::CustomLoader(const wchar_t filename[], CustomLoadFunction fnc) +{ +<<<<<<< HEAD + const CustomData &data = fnc(); +======= + CustomData data; + memset(&data, 0, sizeof(CustomData)); + + fnc(filename, data); + + 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); +>>>>>>> origin/MiscBranch + + resource->customData = new CustomResourceData(); + resource->customData->unloadingFunction = data.resourceUnloadFnc; + resource->customData->loadingFunction = fnc; + + return resource; +} +void OResource::CustomUnloader() +{ + this->customData->unloadingFunction(this->resourceData); +} +OResource* OResource::CustomReloader() +{ + CustomUnloader(); + +<<<<<<< HEAD + const CustomData &data = this->customData->loadingFunction(); +======= + CustomData data; + memset(&data, 0, sizeof(CustomData)); + + this->customData->loadingFunction(this->resourceFilename.c_str(), data); +>>>>>>> origin/MiscBranch + this->resourceData = (OHRESOURCE)data.loadedData; + + if(data.resourceUnloadFnc) + { + this->customData->unloadingFunction = data.resourceUnloadFnc; + } + return this; +} + diff --git a/Code/Misc/Resource/OResourceHandler.cpp.orig b/Code/Misc/Resource/OResourceHandler.cpp.orig new file mode 100644 index 00000000..923ab706 --- /dev/null +++ b/Code/Misc/Resource/OResourceHandler.cpp.orig @@ -0,0 +1,258 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// + + +#include "OysterResource.h" +#include "OResource.h" +#include +#include + +using namespace Oyster::Resource; + +class ResourcePrivate +{ +public: + + std::map resources; + + OResource* FindResource(const OHRESOURCE& h) const; + OResource* FindResource(const wchar_t c[]) const; + void SaveResource(OResource* r, bool addNew = true); + +} resourcePrivate; + + +OHRESOURCE OysterResource::LoadResource(const wchar_t* filename, ResourceType type, int customID, bool force) +{ + if(!filename) return 0; + + OResource *resourceData = resourcePrivate.FindResource(filename); + + if(resourceData) + { + if(force) + { + return OysterResource::ReloadResource(filename); + } + else + { + //Add new reference + resourcePrivate.SaveResource(resourceData, false); + return resourceData->GetResourceHandle(); + } + } + else + { + resourceData = OResource::Load(filename, type); + if(resourceData) + { + resourceData->SetResourceID(customID); + resourcePrivate.SaveResource(resourceData); + } + } + + return resourceData->GetResourceHandle(); +} +OHRESOURCE OysterResource::LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc, int customId, bool force) +{ + if(!filename) + { + return 0; + } + if(!loadFnc) + { + return 0; + } + + OResource *resourceData = resourcePrivate.FindResource(filename); + if(resourceData) + { + if(force) + { + return OysterResource::ReloadResource(filename); + } + else + { + //Add new reference + resourcePrivate.SaveResource(resourceData, false); + return resourceData->GetResourceHandle(); + } + } + else + { + resourceData = OResource::Load(filename, loadFnc); + if(resourceData) + { + resourceData->SetResourceID(customId); + resourcePrivate.SaveResource(resourceData); + } + } +<<<<<<< HEAD + + resourceData = OResource::Load(filename, loadFnc); + + if(!resourceData) return 0; + + if(resourceData) resourceData->SetResourceID(CustomId); + resourcePrivate.SaveResource(resourceData); +======= +>>>>>>> origin/MiscBranch + + return (OHRESOURCE)resourceData->GetResourceHandle(); +} + +OHRESOURCE OysterResource::ReloadResource(const wchar_t filename[]) +{ + OResource *resourceData = resourcePrivate.FindResource(filename); + if(!resourceData) return 0; //The resource has not been loaded + + return OResource::Reload(resourceData)->GetResourceHandle(); +} +OHRESOURCE OysterResource::ReloadResource(OHRESOURCE resource) +{ + OResource *resourceData = resourcePrivate.FindResource(resource); + if(!resourceData) return 0; //The resource has not been loaded + + return OResource::Reload(resourceData)->GetResourceHandle(); +} + +void OysterResource::Clean() +{ + auto i = resourcePrivate.resources.begin(); + auto last = resourcePrivate.resources.end(); + + for (i; i != last; i++) + { + //Remove all the references + while (!OResource::Release(i->second)); + + const wchar_t* temp = i->second->GetResourceFilename(); + delete resourcePrivate.resources[temp]; + resourcePrivate.resources.erase(temp); + + } +} +void OysterResource::ReleaseResource(const OHRESOURCE& resourceData) +{ + OResource* t = resourcePrivate.FindResource(resourceData); + if(t) + { + if(OResource::Release(t)) + { + const wchar_t* temp = t->GetResourceFilename(); + delete resourcePrivate.resources[temp]; + resourcePrivate.resources.erase(temp); + } + } +} +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) +{ + OResource* t = resourcePrivate.FindResource(resourceData); + + 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) +{ + OResource* t = resourcePrivate.FindResource(resourceData); + + if(t) return t->GetResourceType(); + + 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) +{ + OResource* t = resourcePrivate.FindResource(resourceData); + + if(t) return t->GetResourceFilename(); + + return 0; +} +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); + + if(t) return t->GetResourceID(); + + 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 +{ + for (auto i = this->resources.begin(); i != this->resources.end() ; i++) + { + if(i->second->GetResourceHandle() == h) + { + return i->second; + } + } + return 0; +} +OResource* ResourcePrivate::FindResource(const wchar_t c[]) const +{ + std::wstring temp = c; + auto t = this->resources.find(c); + if(t == this->resources.end()) return 0; + + return t->second; +} +void ResourcePrivate::SaveResource( OResource* r, bool addNew ) +{ + if(!r) return; + + if(addNew) + { + this->resources[r->GetResourceFilename()] = r; + } + + r->resourceRef.Incref(); +} + + + + diff --git a/Code/Misc/Resource/OysterResource.h.orig b/Code/Misc/Resource/OysterResource.h.orig new file mode 100644 index 00000000..906b77fb --- /dev/null +++ b/Code/Misc/Resource/OysterResource.h.orig @@ -0,0 +1,164 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// + +#ifndef MISC_OYSTER_RESOURCE_H +#define MISC_OYSTER_RESOURCE_H + + +namespace Oyster +{ + namespace Resource + { + struct CustomData; + /** A Resource handle representing various resources */ +<<<<<<< HEAD + typedef unsigned long OHRESOURCE; + typedef void(*CustomUnloadFunction)(void*); + typedef const CustomData&(*CustomLoadFunction)(); +======= + typedef void* OHRESOURCE; + /** Typedef on a fuction required for custom unloading */ + typedef void(*CustomUnloadFunction)(void* loadedData); + /** Typedef on a fuction required for custom loading */ + typedef void(*CustomLoadFunction)(const wchar_t filename[], CustomData& outData); +>>>>>>> origin/MiscBranch + + /** An enum class representing all avalible resources that is supported. */ + enum ResourceType + { + //Byte + ResourceType_Byte_Raw, /**< Handle can be interpeted as char[] or char* */ + ResourceType_Byte_ANSI, /**< Handle can be interpeted as char[] or char* */ + ResourceType_Byte_UTF8, /**< Handle can be interpeted as char[] or char* */ + ResourceType_Byte_UNICODE, /**< Handle can be interpeted as char[] or char* */ + ResourceType_Byte_UTF16LE, /**< Handle can be interpeted as char[] or char* */ + + ResourceType_COUNT, /**< Handle can be interpeted as ? */ + + ResourceType_UNKNOWN = -1, /**< Handle can be interpeted as void* */ + ResourceType_INVALID = -2, /**< Invalid or non existing resource */ + }; + + /** A struct to fill when doing a custom resource Load. */ + struct CustomData + { + void* loadedData; // +#include +#include + +using namespace Oyster::Thread; + + +OysterMutex::OysterMutex() +{} + +OysterMutex::OysterMutex(bool initialOwnership) +{ + if(initialOwnership) + { + this->mutex.lock(); + this->id = std::this_thread::get_id(); + } +} +OysterMutex::~OysterMutex() +{ +} +void OysterMutex::LockMutex() +{ + if(std::this_thread::get_id() == this->id) return; + + this->mutex.lock(); + + this->id = std::this_thread::get_id(); +} +void OysterMutex::LockMutex(unsigned int msec) +{ + if(std::this_thread::get_id() == this->id) return; + + auto start = std::chrono::high_resolution_clock::now(); + auto end = start + std::chrono::milliseconds(msec); + + do + { + if(this->mutex.try_lock()) + { + this->mutex.lock(); + this->id = std::this_thread::get_id(); + return; + } + } while (std::chrono::high_resolution_clock::now() < end); + + this->mutex.lock(); +} +void OysterMutex::UnlockMutex() +{ + //Let the owner unlock + if(std::this_thread::get_id() != this->id) return; + + this->mutex.unlock(); + this->id = std::thread::id(); + +} +bool OysterMutex::IsTaken() +{ + return !this->mutex.try_lock(); +} \ No newline at end of file diff --git a/Code/Misc/Thread/OysterMutex.h.orig b/Code/Misc/Thread/OysterMutex.h.orig new file mode 100644 index 00000000..d9f29d95 --- /dev/null +++ b/Code/Misc/Thread/OysterMutex.h.orig @@ -0,0 +1,37 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// + +#ifndef MISC_OYSTER_MUTEX_H +#define MISC_OYSTER_MUTEX_H + +#include +#include +#include + +namespace Oyster +{ + namespace Thread + { + class OysterMutex + { + public: + OysterMutex(); + OysterMutex(bool initialOwnership); + virtual~OysterMutex(); + void LockMutex(); + void LockMutex(unsigned int timeSpan); + void UnlockMutex(); + /** Returns true if mutex is taken */ + bool IsTaken(); + + private: + std::mutex mutex; + std::thread::id id; + + OysterMutex(const OysterMutex&); + }; + } +} + +#endif // !MISC_OYSTER_MUTEX_H diff --git a/Code/Misc/Thread/OysterThread.h.orig b/Code/Misc/Thread/OysterThread.h.orig new file mode 100644 index 00000000..05a9f8ad --- /dev/null +++ b/Code/Misc/Thread/OysterThread.h.orig @@ -0,0 +1,47 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// + +#ifndef MISC_OYSTER_THREAD_H +#define MISC_OYSTER_THREAD_H + +#include "IThreadObject.h" +namespace Oyster +{ + namespace Thread + { + enum OYSTER_THREAD_ERROR + { + OYSTER_THREAD_ERROR_FAILED, + OYSTER_THREAD_ERROR_SUCCESS, + }; + + class OysterThread + { + private: + struct PrivateData; + PrivateData *privateData; + + public: + OysterThread(); + OysterThread(const OysterThread& original); + const OysterThread& operator=(const OysterThread& original); + virtual~OysterThread(); + + OYSTER_THREAD_ERROR Create(IThreadObject* worker, bool start); + OYSTER_THREAD_ERROR Start(); + void Stop(); + void Pause(); + void Pause(int mSec); + void Resume(); + OYSTER_THREAD_ERROR Reset(IThreadObject* worker = 0); + void Terminate(); + void Wait(); + void Wait(int mSec); + OYSTER_THREAD_ERROR Swap(const OysterThread* other); + bool IsActive(); + }; + } +} + +#endif // !MISC_OYSTER_THREAD_H diff --git a/Code/Misc/Thread/OysterThread_Impl.cpp.orig b/Code/Misc/Thread/OysterThread_Impl.cpp.orig new file mode 100644 index 00000000..46b889fe --- /dev/null +++ b/Code/Misc/Thread/OysterThread_Impl.cpp.orig @@ -0,0 +1,281 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// + +#include "OysterThread.h" +#include "OysterMutex.h" +#include "..\Utilities.h" +#include +#include +#include + +using namespace Oyster::Thread; +using namespace Utility::DynamicMemory::SmartPointer; + + +#pragma region Declerations + + struct ThreadData; + /** A typical Oyster thread function */ + typedef void (*ThreadFunction)(StdSmartPointer&); + + enum OYSTER_THREAD_STATE + { + OYSTER_THREAD_STATE_RESET, + OYSTER_THREAD_STATE_RUNNING, + OYSTER_THREAD_STATE_PAUSED, + OYSTER_THREAD_STATE_STOPED, + OYSTER_THREAD_STATE_DEAD, + }; + + + struct ThreadData + { + std::atomic state; // workerThread; // msec; // threadData; + + PrivateData() + :threadData(new ThreadData()) + { + threadData->owner = 0; + threadData->workerThread = 0; + threadData->callingThread; + threadData->state = OYSTER_THREAD_STATE_STOPED; + } + PrivateData(const PrivateData& o) + { + threadData = o.threadData; + } + ~PrivateData() + { + //@todo TODO: Make detatch avalible. + this->threadData->workerThread->detach(); + + this->threadData->owner = 0; + + this->threadData->state = OYSTER_THREAD_STATE_DEAD; + } + + }; + +#pragma endregion + + +int tempId = 0; +std::vector IDS; +static void ThreadingFunction(StdSmartPointer &origin) +{ + + bool shouldContinue; + StdSmartPointer w = origin; + +theBegining: + + while(w->state == OYSTER_THREAD_STATE_STOPED) + { + 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(); + { + 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(); + } + } + + if(w->state == OYSTER_THREAD_STATE_DEAD) + { + w->workerThread->detach(); + return; + } + +theEnd: + +// w->mutexLock.LockMutex(); + if(w->owner) + { + w->owner->ThreadExit(); + } +// w->mutexLock.UnlockMutex(); + + w->state = OYSTER_THREAD_STATE_DEAD; +} + +OysterThread::OysterThread() +{ + 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() +{ + delete this->privateData; + this->privateData = 0; +} + +OYSTER_THREAD_ERROR OysterThread::Create(IThreadObject* worker, bool start) +{ + if(!this->privateData) return OYSTER_THREAD_ERROR_FAILED; + if(this->privateData->threadData->workerThread) return OYSTER_THREAD_ERROR_FAILED; + + this->privateData->threadData->owner = worker; + + ThreadFunction fnc = ThreadingFunction; + + //Maby move this thread creation to a seperate Start() function because std::thread fires the thread when it is created. :( + this->privateData->threadData->workerThread = new std::thread(fnc, this->privateData->threadData); + + if(!this->privateData->threadData->workerThread) + return OYSTER_THREAD_ERROR_FAILED; + + if(start) + { + this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING; + } + return OYSTER_THREAD_ERROR_SUCCESS; +} +OYSTER_THREAD_ERROR OysterThread::Start() +{ + if(!this->privateData->threadData->owner) + return OYSTER_THREAD_ERROR_FAILED; + if(!this->privateData->threadData->workerThread) + 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; + return OYSTER_THREAD_ERROR_SUCCESS; +} +void OysterThread::Stop() +{ + //this->privateData->threadData->mutexLock.LockMutex(); + this->privateData->threadData->state = OYSTER_THREAD_STATE_STOPED; + //this->privateData->threadData->mutexLock.UnlockMutex(); +} +void OysterThread::Pause() +{ + //this->privateData->threadData->mutexLock.LockMutex(); + this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED; + //this->privateData->threadData->mutexLock.UnlockMutex(); +} +void OysterThread::Pause(int msec) +{ + + if(std::this_thread::get_id() == this->privateData->threadData->workerThread->get_id()) + { + this->privateData->threadData->msec = 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() +{ +// this->privateData->threadData->mutexLock.LockMutex(); + this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING; +// this->privateData->threadData->mutexLock.UnlockMutex(); +} +OYSTER_THREAD_ERROR OysterThread::Reset(IThreadObject* worker) +{ +// this->privateData->threadData->mutexLock.LockMutex(); + if(worker) + { + this->privateData->threadData->owner = worker; + } + this->privateData->threadData->callingThread = std::this_thread::get_id(); + this->privateData->threadData->msec = 0; +// this->privateData->threadData->mutexLock.UnlockMutex(); + + return OYSTER_THREAD_ERROR_SUCCESS; +} +void OysterThread::Terminate() +{ + this->privateData->threadData->state = OYSTER_THREAD_STATE_DEAD; +} +void OysterThread::Wait() +{ + if(this->privateData->threadData->state == OYSTER_THREAD_STATE_DEAD) + { + return; + } + + if(this->privateData->threadData->workerThread->get_id() == std::this_thread::get_id()) return; + + 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)); +} +OYSTER_THREAD_ERROR OysterThread::Swap(const OysterThread* other) +{ + this->privateData->threadData->workerThread->swap(*other->privateData->threadData->workerThread); + return OYSTER_THREAD_ERROR_SUCCESS; +} +bool OysterThread::IsActive() +{ + if (this->privateData->threadData->state == OYSTER_THREAD_STATE_RUNNING) + return true; + + return false; +} + diff --git a/Code/Misc/Utilities-InlineImpl.h.orig b/Code/Misc/Utilities-InlineImpl.h.orig new file mode 100644 index 00000000..107ea730 --- /dev/null +++ b/Code/Misc/Utilities-InlineImpl.h.orig @@ -0,0 +1,315 @@ +///////////////////////////////////////////////////////////////////// +// Inline and template implementations for +// the Utility Collection of Miscellanious Handy Functions +// © Dan Andersson 2013 +///////////////////////////////////////////////////////////////////// + +#ifndef UTILITIES_INLINE_IMPL_H +#define UTILITIES_INLINE_IMPL_H + +#include "Utilities.h" + +namespace Utility +{ + namespace DynamicMemory + { + template + inline void SafeDeleteInstance( Type *dynamicInstance ) + { + if( dynamicInstance ) + { + delete dynamicInstance; + } + } + + template + void SafeDeleteArray( Type dynamicArray[] ) + { + if( dynamicArray ) + { + delete [] dynamicArray; + } + } + + template + UniquePointer::UniquePointer( Type *assignedInstance ) + { + this->ownedInstance = assignedInstance; + } + + template + UniquePointer::UniquePointer( const UniquePointer &donor ) + { + this->ownedInstance = donor.ownedInstance; + donor.ownedInstance = NULL; + + } + + template + UniquePointer::~UniquePointer() + { + SafeDeleteInstance( this->ownedInstance ); + } + + template + UniquePointer & UniquePointer::operator = ( Type *assignedInstance ) + { + SafeDeleteInstance( this->ownedInstance ); + this->ownedInstance = assignedInstance; + return *this; + } + + template + UniquePointer & UniquePointer::operator = ( const UniquePointer &donor ) + { + SafeDeleteInstance( this->ownedInstance ); + this->ownedInstance = donor.ownedInstance; + donor.ownedInstance = NULL; + return *this; + } + + template + UniquePointer::operator Type* () + { + return this->ownedInstance; + } + + template + UniquePointer::operator const Type* () const + { + return this->ownedInstance; + } + + template + Type * UniquePointer::operator -> () + { + return this->ownedInstance; + } + + template + const Type * UniquePointer::operator -> () const + { + return this->ownedInstance; + } + + template + UniquePointer::operator bool() const + { + return this->ownedInstance != NULL; + } + + template + bool UniquePointer::operator == ( Type *stray ) const + { + return this->ownedInstance == stray; + } + + template + bool UniquePointer::operator != ( Type *stray ) const + { + return this->ownedInstance != stray; + } + + template + Type* UniquePointer::Release() + { + Type *copy = this->ownedInstance; + this->ownedInstance = NULL; + return copy; + } + + template + inline bool UniquePointer::HaveOwnership() const + { + return this->operator bool(); + } + + template + UniqueArray::UniqueArray( Type assignedArray[] ) + { + this->ownedArray = assignedArray; + } + + template + UniqueArray::UniqueArray( const UniqueArray &donor ) + { + this->ownedArray = donor.ownedArray; + donor.ownedArray = NULL; + + } + + template + UniqueArray::~UniqueArray() + { + SafeDeleteArray( this->ownedArray ); + } + + template + UniqueArray & UniqueArray::operator = ( Type assignedArray[] ) + { + SafeDeleteArray( this->ownedArray ); + this->ownedArray = assignedArray; + } + + template + UniqueArray & UniqueArray::operator = ( const UniqueArray &donor ) + { + SafeDeleteArray( this->ownedArray ); + this->ownedArray = donor.ownedInstance; + donor.owned = NULL; + } + + template template + Type & UniqueArray::operator [] ( Index i ) + { + return this->ownedArray[i]; + } + + template template + const Type & UniqueArray::operator [] ( Index i ) const + { + return this->ownedArray[i]; + } + + template + UniqueArray::operator bool () const + { + return this->ownedArray != NULL; + } + + template + bool UniqueArray::operator == ( Type *stray ) const + { + return this->ownedArray == stray; + } + + template + bool UniqueArray::operator != ( Type *stray ) const + { + return this->ownedArray != stray; + } + + template + Type* UniqueArray::Release() + { + Type *copy = this->ownedArray; + this->ownedArray = NULL; + return copy; + } + + template + inline bool UniqueArray::HaveOwnership() const + { + return this->operator bool(); + } +<<<<<<< HEAD +======= + + namespace SmartPointer + { + template void StdSmartPointer::Destroy() + { + delete this->_rc; + this->_rc = NULL; + delete this->_ptr; + this->_ptr = NULL; + } + template StdSmartPointer::StdSmartPointer() + :_rc(0), _ptr(0) + { } + template StdSmartPointer::StdSmartPointer(T* p) + :_ptr(p) + { + this->_rc = new ReferenceCount(); + this->_rc->Incref(); + } + template StdSmartPointer::StdSmartPointer(const StdSmartPointer& d) + :_ptr(d._ptr), _rc(d._rc) + { + if(this->_rc) + this->_rc->Incref(); + } + template StdSmartPointer::~StdSmartPointer() + { + if (this->_rc && this->_rc->Decref() == 0) + { + Destroy(); + } + } + template StdSmartPointer& StdSmartPointer::operator= (const StdSmartPointer& p) + { + if (this != &p) + { + //Last to go? + if(this->_rc && this->_rc->Decref() == 0) + { + //Call child specific + Destroy(); + } + + this->_ptr = p._ptr; + this->_rc = p._rc; + this->_rc->Incref(); + } + return *this; + } + template StdSmartPointer& StdSmartPointer::operator= (T* p) + { + if (this->_ptr != p) + { + //Last to go? + if(this->_rc) + { + if(this->_rc->Decref() == 0) + { + //Call child specific + Destroy(); + this->_rc = new ReferenceCount(); + } + } + else + this->_rc = new ReferenceCount(); + + this->_ptr = p; + this->_rc->Incref(); + } + return *this; + } + template inline bool StdSmartPointer::operator== (const StdSmartPointer& d) + { + return d._ptr == this->_ptr; + } + template inline bool StdSmartPointer::operator== (const T& p) + { + return &p == this->_ptr; + } + template inline T& StdSmartPointer::operator* () + { + return *this->_ptr; + } + template inline T* StdSmartPointer::operator-> () + { + return this->_ptr; + } + template inline StdSmartPointer::operator T* () + { + return this->_ptr; + } + template inline StdSmartPointer::operator bool() + { + return (this->_ptr != 0); + } + template inline T* StdSmartPointer::Get() + { + return this->_ptr; + } + template inline bool StdSmartPointer::IsValid() + { + return (this->_ptr != NULL) ? true : false; + } + } +>>>>>>> origin/MiscBranch + } +} + +#endif \ No newline at end of file diff --git a/Code/Misc/Utilities.h.orig b/Code/Misc/Utilities.h.orig new file mode 100644 index 00000000..55c4820f --- /dev/null +++ b/Code/Misc/Utilities.h.orig @@ -0,0 +1,347 @@ +//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//! +// Utility Collection of Miscellanious Handy Functions +// © Dan Andersson 2013 +//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//! + +#ifndef UTILITIES_H +#define UTILITIES_H + +#include +#include +#include +#include +#include +#include + +namespace Utility +{ + namespace DynamicMemory + { + //! If dynamicInstance is not NULL, then delete + template void SafeDeleteInstance( Type *dynamicInstance ); + + //! If dynamicArray is not NULL, then delete [] + template void SafeDeleteArray( Type dynamicArray[] ); + + //! Wrapper to safely transfer dynamic ownership/responsibility + template struct UniquePointer + { + public: + //! Assigns assignedInstance ownership to this UniquePonter, old owned instance will be deleted. + //! If NULL is assigned is equivalent with clearing all responsibilities from this UniquePointer. + UniquePointer( Type *assignedInstance = NULL ); + + //! Transfers assignedInstance ownership from donor to this UniquePonter, old owned instance will be deleted. + //! If donor had nothing, is equivalent with clearing all responsibilities from this UniquePointer. + UniquePointer( const UniquePointer &donor ); + + //! Will auto delete assigned dynamic instance. + ~UniquePointer(); + + //! Assigns assignedInstance ownership to this UniquePonter, old owned instance will be deleted. + //! If NULL is assigned is equivalent with clearing all responsibilities from this UniquePointer. + UniquePointer & operator = ( Type *assignedInstance ); + + //! Transfers assignedInstance ownership from donor to this UniquePonter, old owned instance will be deleted. + //! If donor had nothing, is equivalent with clearing all responsibilities from this UniquePointer. + UniquePointer & operator = ( const UniquePointer &donor ); + + //! Access the assigned dynamic instance. Will crash if nothing there + operator Type* (); + + //! Access the assigned dynamic instance. Will crash if nothing there + operator const Type* () const; + + //! Access members of the assigned dynamic instance. Will crash if nothing there + Type * operator -> (); + + //! Access members of the assigned dynamic instance. Will crash if nothing there + const Type * operator -> () const; + + //! If true, this UniquePointer have a current ownership/responsibility of a dynamic instance. + operator bool () const; + + //! @return true if this ownedInstance matches with stray + bool operator == ( Type *stray ) const; + + //! @return false if this ownedInstance matches with stray + bool operator != ( Type *stray ) const; + + //! This UniquePointer drops all claims of ownership/responsibility and returns the dynamic instance. Now it is your responsibility to delete. + Type* Release(); + + //! (inline) If true, this UniquePointer have a current ownership/responsibility of a dynamic instance. + bool HaveOwnership() const; + + private: + mutable Type *ownedInstance; + }; + + template + struct UniqueArray + { //! Wrapper to safely transfer dynamic ownership/responsibility + public: + //! Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted. + //! If NULL is assigned is equivalent with clearing all responsibilities from this UniqueArray. + UniqueArray( Type assignedArray[] = NULL ); + + //! Transfers assignedInstance ownership from donor to this UniquePonter, old owned array will be deleted. + //! If donor had nothing, is equivalent with clearing all responsibilities from this UniqueArray. + UniqueArray( const UniqueArray &donor ); + + //! Will auto delete assigned dynamic array. + ~UniqueArray(); + + //! Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted. + //! If NULL is assigned is equivalent with clearing all responsibilities from this UniqueArray. + UniqueArray & operator = ( Type assignedArray[] ); + + //! Transfers assignedInstance ownership from donor to this UniquePonter, old owned array will be deleted. + //! If donor had nothing, is equivalent with clearing all responsibilities from this UniqueArray. + UniqueArray & operator = ( const UniqueArray &donor ); + + //! Accesses the instance at index i of this UniqeArray's owned dynamic array. + //! Will crash if out-of-bound or there is no assigned array. + template Type & operator [] ( Index i ); + + //! Accesses the instance at index i of this UniqeArray's owned dynamic array. + //! Will crash if out-of-bound or there is no assigned array. + template const Type & operator [] ( Index i ) const; + + //! If true, this UniqueArray have a current ownership/responsibility of a dynamic instance. + operator bool () const; + + //! @return true if this ownedInstance matches with stray + bool operator == ( Type *stray ) const; + + //! @return false if this ownedInstance matches with stray + bool operator != ( Type *stray ) const; + + //! This UniqueArray drops all claims of ownership/responsibility and returns the dynamic array. Now it is your responsibility to delete. + Type* Release(); + + //! (inline) If true, this UniqueArray have a current ownership/responsibility of a dynamic array. + bool HaveOwnership() const; + + private: + mutable Type *ownedArray; + }; + + struct RefCount + { + private: + std::atomic count; + + public: +<<<<<<< HEAD + RefCount() :count(0) { } + RefCount(const RefCount& o) { count = o.count; } + const RefCount& operator=(const RefCount& o) { count = o.count; return *this;} + void Incref() { this->count++; } + void Incref(int c) { this->count += c; } + int Decref() { return --this->count;} + void Reset() { this->count = 0; } + }; +======= + ReferenceCount() :count(0) { } + ReferenceCount(const ReferenceCount& o) { count.store(o.count); } + inline const ReferenceCount& operator=(const ReferenceCount& o) { count.store(o.count); return *this;} + inline void Incref() { this->count++; } + inline void Incref(int c) { this->count += c; } + inline int Decref() { return --this->count;} + inline void Reset() { this->count = 0; } + }; + + namespace SmartPointer + { + //! Smart pointer for a regular object. + /** + * Regular objects, objects that is deleted normaly (ie not COM objects, or array pointers) + * can use this class to easy the use of dynamic memory + */ + template + struct StdSmartPointer + { + private: + ReferenceCount *_rc; + T *_ptr; + + /** Destroys the pointer and returns the memory allocated. */ + void Destroy(); + + public: + StdSmartPointer(); + StdSmartPointer(T* p); + StdSmartPointer(const StdSmartPointer& d); + virtual~StdSmartPointer(); + StdSmartPointer& operator= (const StdSmartPointer& p); + StdSmartPointer& operator= (T* p); + bool operator== (const StdSmartPointer& d); + bool operator== (const T& p); + T& operator* (); + T* operator-> (); + operator T* (); + operator bool(); + + /** + * Returns the connected pointer */ + T* Get(); + + /** Checks if the pointer is valid (not NULL) + Returns true for valid, else false. */ + bool IsValid(); + }; + } + + +>>>>>>> origin/MiscBranch + } + + namespace String + { + // string + + ::std::vector<::std::string> & Split( ::std::vector<::std::string> &output, const ::std::string &str, char delim, ::std::string::size_type offset = 0 ); + ::std::vector<::std::string> & Split( ::std::vector<::std::string> &output, const ::std::string &str, const ::std::string &delim, ::std::string::size_type offset = 0 ); + ::std::vector<::std::string> & Split( ::std::vector<::std::string> &output, const ::std::string &str, const ::std::vector<::std::string> &delim, ::std::string::size_type offset = 0 ); + ::std::string Trim( const ::std::string &str ); + ::std::string & ToLowerCase( ::std::string &output, const ::std::string &str ); + ::std::string & ToLowerCase( ::std::string &str ); + ::std::string & ToUpperCase( ::std::string &output, const ::std::string &str ); + ::std::string & ToUpperCase( ::std::string &str ); + ::std::string & ExtractDirPath( ::std::string &output, const ::std::string &file, char dirDelimeter ); + ::std::string & ExtractDirPath( ::std::string &output, const ::std::string &file, const ::std::string &dirDelimeter ); + ::std::string & ReplaceCharacters( ::std::string &str, char characterToReplace, char newCharacter, const ::std::string::size_type &offset = 0, const ::std::string::size_type &end = ::std::string::npos ); + + // wstring + + ::std::vector<::std::wstring> & Split( ::std::vector<::std::wstring> &output, const ::std::wstring &str, char delim, ::std::wstring::size_type offset = 0 ); + ::std::vector<::std::wstring> & Split( ::std::vector<::std::wstring> &output, const ::std::wstring &str, const ::std::wstring &delim, ::std::wstring::size_type offset = 0 ); + ::std::vector<::std::wstring> & Split( ::std::vector<::std::wstring> &output, const ::std::wstring &str, const ::std::vector<::std::wstring> &delim, ::std::wstring::size_type offset = 0 ); + ::std::wstring & wToLowerCase( ::std::wstring &output, const ::std::wstring &str ); + ::std::wstring & wToLowerCase( ::std::wstring &str ); + + //To wstring + + ::std::wstring & StringToWstring( const ::std::string &str, ::std::wstring &wstr ); + ::std::string & WStringToString( const ::std::wstring &wstr, ::std::string &str ); + } + + namespace Stream + { + float* ReadFloats( float *output, ::std::istream &input, unsigned int numFloats ); + } + + namespace StaticArray + { + template + inline unsigned int NumElementsOf( const ScalarType(&)[num] ) + { return num; } + + template + inline ScalarType & FirstElementOf( ScalarType (&arr)[num] ) + { return arr[0]; } + + template + inline ScalarType & LastElementOf( ScalarType (&arr)[num] ) + { return arr[num-1]; } + } + + namespace Element + { + template + inline void Swap( ScalarType &elementA, ScalarType &elementB, ScalarType &swapSpace ) + { swapSpace = elementA; elementA = elementB; elementB = swapSpace; } + + template + inline void Swap( ScalarType &elementA, ScalarType &elementB ) + { ScalarType swapSpace; Swap( elementA, elementB, swapSpace ); } + } + + namespace Value + { + using ::std::numeric_limits; + + template + inline ValueType Abs( const ValueType &value ) + { return value < 0 ? value * -1 : value; } + + template + inline ValueType Max( const ValueType &valueA, const ValueType &valueB ) + { return valueA > valueB ? valueA : valueB; } + + template + inline ValueType Min( const ValueType &valueA, const ValueType &valueB ) + { return valueA < valueB ? valueA : valueB; } + + template + inline ValueType Average( const ValueType &valueA, const ValueType &valueB ) + { return (valueA + valueB) * 0.5f; } + + template + inline ValueType AverageWithDelta( const ValueType &origin, const ValueType &delta ) + { return origin + (delta * 0.5f); } + + template + inline ValueType Radian( const ValueType °ree ) + { return degree * (3.1415926535897932384626433832795f / 180.0f); } + + template + inline ValueType Degree( const ValueType &radian ) + { return radian * (180.0f / 3.1415926535897932384626433832795f); } + + // SPECIALIZATIONS //!//!//!//!//!//!//!//!//!//!//!//!//!//! + + template<> inline char Average( const char &valueA, const char &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline unsigned char Average( const unsigned char &valueA, const unsigned char &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline int Average( const int &valueA, const int &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline unsigned int Average( const unsigned int &valueA, const unsigned int &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline long Average( const long &valueA, const long &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline unsigned long Average( const unsigned long &valueA, const unsigned long &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline long long Average( const long long &valueA, const long long &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline unsigned long long Average( const unsigned long long &valueA, const unsigned long long &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline char AverageWithDelta( const char &origin, const char &delta ) + { return origin + (delta >> 1); } + + template<> inline unsigned char AverageWithDelta( const unsigned char &origin, const unsigned char &delta ) + { return origin + (delta >> 1); } + + template<> inline int AverageWithDelta( const int &origin, const int &delta ) + { return origin + (delta >> 1); } + + template<> inline unsigned int AverageWithDelta( const unsigned int &origin, const unsigned int &delta ) + { return origin + (delta >> 1); } + + template<> inline long AverageWithDelta( const long &origin, const long &delta ) + { return origin + (delta >> 1); } + + template<> inline unsigned long AverageWithDelta( const unsigned long &origin, const unsigned long &delta ) + { return origin + (delta >> 1); } + + template<> inline long long AverageWithDelta( const long long &origin, const long long &delta ) + { return origin + (delta >> 1); } + + template<> inline unsigned long long AverageWithDelta( const unsigned long long &origin, const unsigned long long &delta ) + { return origin + (delta >> 1); } + } +} + +#include "Utilities-InlineImpl.h" + +#endif \ No newline at end of file