mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-01-04 02:31:10 -06:00
Linux support. (#54)
* Initial Linux attempt. * Add clang toolchain & make tools compile. * vcpkg as submodule. * First implementation of IO rewrite. (#31) * Fix directory iteration resolving symlinks. * Refactor kernel objects to be lock-free. * Implement guest critical sections using std::atomic. * Make D3D12 support optional. (#33) * Make D3D12 support optional. * Update ShaderRecomp, fix macros. * Replace QueryPerformanceCounter. (#35) * Add Linux home path for GetUserPath(). (#36) * Cross-platform Sleep. (#37) * Add mmap implementations for virtual allocation. (#38) * Cross-platform TLS. (#34) * Cross-platform TLS. * Fix front() to back(), use Mutex. * Fix global variable namings. --------- Co-authored-by: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> * Unicode support. (#39) * Replace CreateDirectoryA with Unicode version. * Cross platform thread implementation. (#41) * Cross-platform thread implementation. * Put set thread name calls behind a Win32 macro. * Cross-platform semaphore implementation. (#43) * xam: use SDL for keyboard input * Cross-platform atomic operations. (#44) * Cross-platform spin lock implementation. * Cross-platform reference counting. * Cross-platform event implementation. (#47) * Compiling and running on Linux. (#49) * Current work trying to get it to compile. * Update vcpkg.json baseline. * vcpkg, memory mapped file. * Bitscan forward. * Fix localtime_s. * FPS patches high res clock. * Rename Window to GameWindow. Fix guest pointers. * GetCurrentThreadID gone. * Code cache pointers, RenderWindow type. * Add Linux stubs. * Refactor Config. * Fix paths. * Add linux-release config. * FS fixes. * Fix Windows compilation errors & unicode converter crash. * Rename physical memory allocation functions to not clash with X11. * Fix NULL character being added on RtlMultiByteToUnicodeN. * Use std::exit. * Add protection to memory on Linux. * Convert majority of dependencies to submodules. (#48) * Convert majority of dependencies to submodules. * Don't compile header-only libraries. * Fix a few incorrect data types. * Fix config directory. * Unicode fixes & sizeof asserts. * Change the exit function to not call static destructors. * Fix files picker. * Add RelWithDebInfo preset for Linux. * Implement OS Restart on Linux. (#50) --------- Co-authored-by: Dario <dariosamo@gmail.com> * Update PowerRecomp. * Add Env Var detection for VCPKG_ROOT, add DLC detection. * Use error code version on DLC directory iterator. * Set D3D12MA::ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED flag. * Linux flatpak. (#51) * Add flatpak support. * Add game install directory override for flatpak. * Flatpak'ing. * Flatpak it some more. * We flat it, we pak it. * Flatpak'd. * The Marvelous Misadventures of Flatpak. * Attempt to change logic of NFD and show error. * Flattenpakken. * Use game install directory instead of current path. * Attempt to fix line endings. * Update io.github.hedge_dev.unleashedrecomp.json * Fix system time query implementation. * Add Present Wait to Vulkan to improve frame pacing and reduce latency. (#53) * Add present wait support to Vulkan. * Default to triple buffering if presentWait is supported. * Bracey fellas. * Update paths.h * SDL2 audio (again). (#52) * Implement SDL2 audio (again). * Call timeBeginPeriod/timeEndPeriod. * Replace miniaudio with SDL mixer. * Queue audio samples in a separate thread. * Enable CMake option override policy & fix compilation error. * Fix compilation error on Linux. * Fix but also trim shared strings. * Wayland support. (#55) * Make channel index a global variable in embedded player. * Fix SDL Audio selection for OGG on Flatpak. * Minor installer wizard fixes. * Fix compilation error. * Yield in model consumer and pipeline compiler threads. * Special case Sleep(0) to yield on Linux. * Add App Id hint. * Correct implementation for auto reset events. (#57) --------- Co-authored-by: Dario <dariosamo@gmail.com> Co-authored-by: Hyper <34012267+hyperbx@users.noreply.github.com>
This commit is contained in:
@@ -2,14 +2,14 @@
|
||||
|
||||
#include "SWA.inl"
|
||||
|
||||
inline static void* __HH_ALLOC(const uint32_t in_Size)
|
||||
inline void* __HH_ALLOC(const uint32_t in_Size)
|
||||
{
|
||||
return GuestToHostFunction<void*>(0x82DFA0B0, in_Size, nullptr, 0, 0);
|
||||
return GuestToHostFunction<void*>(sub_822C0988, in_Size);
|
||||
}
|
||||
|
||||
inline static void __HH_FREE(const void* in_pData)
|
||||
inline void __HH_FREE(const void* in_pData)
|
||||
{
|
||||
GuestToHostFunction<void>(0x82DF9E50, in_pData);
|
||||
GuestToHostFunction<void>(sub_822C0270, in_pData);
|
||||
}
|
||||
|
||||
namespace Hedgehog::Base
|
||||
|
||||
@@ -6,38 +6,16 @@ namespace Hedgehog::Base
|
||||
{
|
||||
struct SStringHolder
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
be<uint16_t> Length;
|
||||
be<uint16_t> RefCount;
|
||||
};
|
||||
|
||||
be<uint32_t> RefCountAndLength;
|
||||
};
|
||||
|
||||
char aStr[1u];
|
||||
be<uint32_t> RefCount;
|
||||
char aStr[];
|
||||
|
||||
static SStringHolder* GetHolder(const char* in_pStr);
|
||||
|
||||
static size_t GetMemorySize(const size_t in_Length);
|
||||
static size_t GetMemorySizeAligned(const size_t in_Length);
|
||||
|
||||
static SStringHolder* Make(const char* in_pStr, const size_t in_Length);
|
||||
|
||||
static SStringHolder* Concat(
|
||||
const char* in_pStrA, const size_t in_LengthA,
|
||||
const char* in_pStrB, const size_t in_LengthB);
|
||||
static SStringHolder* Make(const char* in_pStr);
|
||||
|
||||
void AddRef();
|
||||
void Release();
|
||||
|
||||
bool IsUnique() const;
|
||||
|
||||
bool TryInplaceAssign(const char* in_pStr, const size_t in_Length);
|
||||
bool TryInplaceAppend(const char* in_pStr, const size_t in_Length);
|
||||
bool TryInplacePrepend(const char* in_pStr, const size_t in_Length);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,66 +2,41 @@ namespace Hedgehog::Base
|
||||
{
|
||||
inline SStringHolder* SStringHolder::GetHolder(const char* in_pStr)
|
||||
{
|
||||
return (SStringHolder*)((size_t)in_pStr - sizeof(RefCountAndLength));
|
||||
return (SStringHolder*)((size_t)in_pStr - sizeof(RefCount));
|
||||
}
|
||||
|
||||
inline size_t SStringHolder::GetMemorySize(const size_t in_Length)
|
||||
inline SStringHolder* SStringHolder::Make(const char* in_pStr)
|
||||
{
|
||||
return sizeof(RefCountAndLength) + in_Length;
|
||||
}
|
||||
|
||||
inline size_t SStringHolder::GetMemorySizeAligned(const size_t in_Length)
|
||||
{
|
||||
return (GetMemorySize(in_Length) + 0x10) & ~0x0F;
|
||||
}
|
||||
|
||||
inline SStringHolder* SStringHolder::Make(const char* in_pStr, const size_t in_Length)
|
||||
{
|
||||
const size_t memSize = GetMemorySize(in_Length);
|
||||
const size_t memSizeAligned = GetMemorySizeAligned(in_Length);
|
||||
|
||||
auto pHolder = (SStringHolder*)__HH_ALLOC(memSizeAligned);
|
||||
auto pHolder = (SStringHolder*)__HH_ALLOC(sizeof(RefCount) + strlen(in_pStr) + 1);
|
||||
pHolder->RefCount = 1;
|
||||
pHolder->Length = (uint16_t)in_Length;
|
||||
|
||||
if (in_pStr)
|
||||
memcpy(pHolder->aStr, in_pStr, in_Length);
|
||||
|
||||
memset(&pHolder->aStr[in_Length], 0, memSizeAligned - memSize);
|
||||
|
||||
return pHolder;
|
||||
}
|
||||
|
||||
inline SStringHolder* SStringHolder::Concat(const char* in_pStrA, const size_t in_LengthA, const char* in_pStrB, const size_t in_LengthB)
|
||||
{
|
||||
SStringHolder* pHolder = Make(nullptr, in_LengthA + in_LengthB);
|
||||
|
||||
memcpy(pHolder->aStr, in_pStrA, in_LengthA);
|
||||
memcpy(&pHolder->aStr[in_LengthA], in_pStrB, in_LengthB);
|
||||
|
||||
strcpy(pHolder->aStr, in_pStr);
|
||||
return pHolder;
|
||||
}
|
||||
|
||||
inline void SStringHolder::AddRef()
|
||||
{
|
||||
uint32_t originalValue, incrementedValue;
|
||||
std::atomic_ref refCount(RefCount.value);
|
||||
|
||||
be<uint32_t> original, incremented;
|
||||
do
|
||||
{
|
||||
originalValue = RefCountAndLength.value;
|
||||
incrementedValue = ByteSwap(ByteSwap(originalValue) + 1);
|
||||
} while (InterlockedCompareExchange(reinterpret_cast<LONG*>(&RefCountAndLength), incrementedValue, originalValue) != originalValue);
|
||||
original = RefCount;
|
||||
incremented = original + 1;
|
||||
} while (!refCount.compare_exchange_weak(original.value, incremented.value));
|
||||
}
|
||||
|
||||
inline void SStringHolder::Release()
|
||||
{
|
||||
uint32_t originalValue, decrementedValue;
|
||||
std::atomic_ref refCount(RefCount.value);
|
||||
|
||||
be<uint32_t> original, decremented;
|
||||
do
|
||||
{
|
||||
originalValue = RefCountAndLength.value;
|
||||
decrementedValue = ByteSwap(ByteSwap(originalValue) - 1);
|
||||
} while (InterlockedCompareExchange(reinterpret_cast<LONG*>(&RefCountAndLength), decrementedValue, originalValue) != originalValue);
|
||||
original = RefCount;
|
||||
decremented = original - 1;
|
||||
} while (!refCount.compare_exchange_weak(original.value, decremented.value));
|
||||
|
||||
if ((decrementedValue & 0xFFFF0000) == 0)
|
||||
if (decremented == 0)
|
||||
__HH_FREE(this);
|
||||
}
|
||||
|
||||
@@ -69,66 +44,4 @@ namespace Hedgehog::Base
|
||||
{
|
||||
return RefCount == 1;
|
||||
}
|
||||
|
||||
inline bool SStringHolder::TryInplaceAssign(const char* in_pStr, const size_t in_Length)
|
||||
{
|
||||
if (!IsUnique())
|
||||
return false;
|
||||
|
||||
const size_t memSizeAligned = GetMemorySizeAligned(in_Length);
|
||||
|
||||
if (memSizeAligned > GetMemorySizeAligned(Length))
|
||||
return false;
|
||||
|
||||
if (in_pStr)
|
||||
memcpy(aStr, in_pStr, in_Length);
|
||||
|
||||
memset(&aStr[in_Length], 0, memSizeAligned - GetMemorySize(in_Length));
|
||||
|
||||
Length = (uint16_t)in_Length;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool SStringHolder::TryInplaceAppend(const char* in_pStr, const size_t in_Length)
|
||||
{
|
||||
if (!IsUnique())
|
||||
return false;
|
||||
|
||||
const size_t memSizeAligned = GetMemorySizeAligned(Length + in_Length);
|
||||
|
||||
if (memSizeAligned > GetMemorySizeAligned(Length))
|
||||
return false;
|
||||
|
||||
if (in_pStr)
|
||||
memcpy(&aStr[Length], in_pStr, in_Length);
|
||||
|
||||
memset(&aStr[Length + in_Length], 0, memSizeAligned - GetMemorySize(Length + in_Length));
|
||||
|
||||
Length = (uint16_t)(Length + in_Length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool SStringHolder::TryInplacePrepend(const char* in_pStr, const size_t in_Length)
|
||||
{
|
||||
if (!IsUnique())
|
||||
return false;
|
||||
|
||||
const size_t memSizeAligned = GetMemorySizeAligned(in_Length + Length);
|
||||
|
||||
if (memSizeAligned > GetMemorySizeAligned(Length))
|
||||
return false;
|
||||
|
||||
memmove(&aStr[in_Length], aStr, Length);
|
||||
|
||||
if (in_pStr)
|
||||
memcpy(aStr, in_pStr, in_Length);
|
||||
|
||||
memset(&aStr[in_Length + Length], 0, memSizeAligned - GetMemorySize(in_Length + Length));
|
||||
|
||||
Length = (uint16_t)(in_Length + Length);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,56 +32,6 @@ namespace Hedgehog::Base
|
||||
|
||||
const char* begin() const;
|
||||
const char* end() const;
|
||||
|
||||
CSharedString substr(size_t pos = 0, size_t len = npos) const;
|
||||
|
||||
size_t find(char c, size_t pos = 0) const;
|
||||
size_t find(const char* s, size_t pos = 0) const;
|
||||
size_t rfind(char c, size_t pos = npos) const;
|
||||
|
||||
size_t find_first_of(const char* s, size_t pos = 0) const;
|
||||
size_t find_last_of(const char* s, size_t pos = npos) const;
|
||||
size_t find_first_not_of(const char* s, size_t pos = 0) const;
|
||||
size_t find_last_not_of(const char* s, size_t pos = npos) const;
|
||||
|
||||
size_t find(const CSharedString& str, size_t pos = 0) const;
|
||||
size_t rfind(const CSharedString& str, size_t pos = npos) const;
|
||||
|
||||
size_t find_first_of(const CSharedString& str, size_t pos = 0) const;
|
||||
size_t find_last_of(const CSharedString& str, size_t pos = npos) const;
|
||||
size_t find_first_not_of(const CSharedString& str, size_t pos = 0) const;
|
||||
size_t find_last_not_of(const CSharedString& str, size_t pos = npos) const;
|
||||
|
||||
void assign(const CSharedString& in_rOther);
|
||||
void assign(const char* in_pStr);
|
||||
void assign(CSharedString&& io_rOther);
|
||||
|
||||
void append(const CSharedString& in_rOther);
|
||||
void append(const char* in_pStr);
|
||||
|
||||
void prepend(const CSharedString& in_rOther);
|
||||
void prepend(const char* in_pStr);
|
||||
|
||||
int compare(const CSharedString& in_rOther) const;
|
||||
|
||||
CSharedString& operator=(const CSharedString& in_rOther);
|
||||
CSharedString& operator=(const char* in_pStr);
|
||||
CSharedString& operator=(CSharedString&& io_rOther);
|
||||
CSharedString& operator+=(const CSharedString& in_rOther);
|
||||
CSharedString& operator+=(const char* in_pStr);
|
||||
|
||||
friend CSharedString operator+(const CSharedString& in_rLeft, const CSharedString& in_rRight);
|
||||
friend CSharedString operator+(const CSharedString& in_rLeft, const char* in_pRight);
|
||||
friend CSharedString operator+(const char* in_pLeft, const CSharedString& in_pRight);
|
||||
|
||||
bool operator>(const CSharedString& in_rOther) const;
|
||||
bool operator>=(const CSharedString& in_rOther) const;
|
||||
bool operator<(const CSharedString& in_rOther) const;
|
||||
bool operator<=(const CSharedString& in_rOther) const;
|
||||
bool operator==(const CSharedString& in_rOther) const;
|
||||
bool operator!=(const CSharedString& in_rOther) const;
|
||||
bool operator==(const char* in_pOther) const;
|
||||
bool operator!=(const char* in_pOther) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Hedgehog::Base
|
||||
size_t length;
|
||||
|
||||
if (in_pStr && (length = strlen(in_pStr)) != 0)
|
||||
m_pStr.ptr = g_memory.MapVirtual(SStringHolder::Make(in_pStr, length)->aStr);
|
||||
m_pStr.ptr = g_memory.MapVirtual(SStringHolder::Make(in_pStr)->aStr);
|
||||
}
|
||||
|
||||
inline CSharedString::CSharedString(const CSharedString& in_rOther) : m_pStr(in_rOther.m_pStr)
|
||||
@@ -53,7 +53,7 @@ namespace Hedgehog::Base
|
||||
|
||||
inline size_t CSharedString::size() const
|
||||
{
|
||||
return GetHolder()->Length;
|
||||
return strlen(m_pStr);
|
||||
}
|
||||
|
||||
inline size_t CSharedString::length() const
|
||||
@@ -73,367 +73,6 @@ namespace Hedgehog::Base
|
||||
|
||||
inline const char* CSharedString::end() const
|
||||
{
|
||||
return &m_pStr[GetHolder()->Length];
|
||||
}
|
||||
|
||||
inline CSharedString CSharedString::substr(size_t pos, size_t len) const
|
||||
{
|
||||
if (len == 0)
|
||||
return CSharedString();
|
||||
|
||||
if (len > (GetHolder()->Length - pos))
|
||||
len = GetHolder()->Length - pos;
|
||||
|
||||
if (pos == 0 && len == GetHolder()->Length)
|
||||
return *this;
|
||||
|
||||
return SStringHolder::Make(&m_pStr[pos], len);
|
||||
}
|
||||
|
||||
inline size_t CSharedString::find(char c, size_t pos) const
|
||||
{
|
||||
for (size_t i = pos; i < GetHolder()->Length; i++)
|
||||
{
|
||||
if (m_pStr[i] == c)
|
||||
return i;
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
inline size_t CSharedString::find(const char* s, size_t pos) const
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
for (size_t i = pos; i < GetHolder()->Length - len + 1; i++)
|
||||
{
|
||||
if (strncmp(m_pStr + i, s, len) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
inline size_t CSharedString::rfind(char c, size_t pos) const
|
||||
{
|
||||
if (pos >= GetHolder()->Length)
|
||||
pos = GetHolder()->Length - 1;
|
||||
|
||||
for (size_t i = pos; i != static_cast<size_t>(-1); i--)
|
||||
{
|
||||
if (m_pStr[i] == c)
|
||||
return i;
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
inline size_t CSharedString::find_first_of(const char* s, size_t pos) const
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
for (size_t i = pos; i < GetHolder()->Length; i++)
|
||||
{
|
||||
for (size_t j = 0; j < len; j++)
|
||||
{
|
||||
if (m_pStr[i] == s[j])
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
inline size_t CSharedString::find_last_of(const char* s, size_t pos) const
|
||||
{
|
||||
if (pos >= GetHolder()->Length)
|
||||
pos = GetHolder()->Length - 1;
|
||||
|
||||
size_t len = strlen(s);
|
||||
for (size_t i = pos; i != static_cast<size_t>(-1); i--)
|
||||
{
|
||||
for (size_t j = 0; j < len; j++)
|
||||
{
|
||||
if (m_pStr[i] == s[j])
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
inline size_t CSharedString::find_first_not_of(const char* s, size_t pos) const
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
for (size_t i = pos; i < GetHolder()->Length; i++)
|
||||
{
|
||||
bool found = false;
|
||||
for (size_t j = 0; j < len; j++)
|
||||
{
|
||||
if (m_pStr[i] == s[j])
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return i;
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
inline size_t CSharedString::find_last_not_of(const char* s, size_t pos) const
|
||||
{
|
||||
if (pos >= GetHolder()->Length)
|
||||
pos = GetHolder()->Length - 1;
|
||||
|
||||
size_t len = strlen(s);
|
||||
for (size_t i = pos; i != static_cast<size_t>(-1); i--)
|
||||
{
|
||||
bool found = false;
|
||||
for (size_t j = 0; j < len; j++)
|
||||
{
|
||||
if (m_pStr[i] == s[j])
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return i;
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
inline size_t CSharedString::find(const CSharedString& str, size_t pos) const
|
||||
{
|
||||
return find(str.c_str(), pos);
|
||||
}
|
||||
|
||||
inline size_t CSharedString::find_first_of(const CSharedString& str, size_t pos) const
|
||||
{
|
||||
return find_first_of(str.c_str(), pos);
|
||||
}
|
||||
|
||||
inline size_t CSharedString::find_last_of(const CSharedString& str, size_t pos) const
|
||||
{
|
||||
return find_last_of(str.c_str(), pos);
|
||||
}
|
||||
|
||||
inline size_t CSharedString::find_first_not_of(const CSharedString& str, size_t pos) const
|
||||
{
|
||||
return find_first_not_of(str.c_str(), pos);
|
||||
}
|
||||
|
||||
inline size_t CSharedString::find_last_not_of(const CSharedString& str, size_t pos) const
|
||||
{
|
||||
return find_last_not_of(str.c_str(), pos);
|
||||
}
|
||||
|
||||
inline void CSharedString::assign(const CSharedString& in_rOther)
|
||||
{
|
||||
GetHolder()->Release();
|
||||
m_pStr = in_rOther.m_pStr;
|
||||
GetHolder()->AddRef();
|
||||
}
|
||||
|
||||
inline void CSharedString::assign(const char* in_pStr)
|
||||
{
|
||||
size_t length;
|
||||
|
||||
if (in_pStr && (length = strlen(in_pStr)) != 0)
|
||||
{
|
||||
if (!GetHolder()->TryInplaceAssign(in_pStr, length))
|
||||
{
|
||||
GetHolder()->Release();
|
||||
m_pStr = SStringHolder::Make(in_pStr, length)->aStr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetHolder()->Release();
|
||||
m_pStr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
inline void CSharedString::assign(CSharedString&& io_rOther)
|
||||
{
|
||||
m_pStr = io_rOther.m_pStr;
|
||||
io_rOther.m_pStr = nullptr;
|
||||
}
|
||||
|
||||
inline void CSharedString::append(const CSharedString& in_rOther)
|
||||
{
|
||||
if (!GetHolder()->TryInplaceAppend(in_rOther.GetHolder()->aStr, in_rOther.GetHolder()->Length))
|
||||
{
|
||||
SStringHolder* pHolder = SStringHolder::Concat(
|
||||
GetHolder()->aStr, GetHolder()->Length,
|
||||
in_rOther.GetHolder()->aStr, in_rOther.GetHolder()->Length);
|
||||
|
||||
GetHolder()->Release();
|
||||
m_pStr = pHolder->aStr;
|
||||
}
|
||||
}
|
||||
|
||||
inline void CSharedString::append(const char* in_pStr)
|
||||
{
|
||||
size_t length;
|
||||
|
||||
if (in_pStr && (length = strlen(in_pStr)) != 0)
|
||||
{
|
||||
if (!GetHolder()->TryInplaceAppend(in_pStr, length))
|
||||
{
|
||||
SStringHolder* pHolder = SStringHolder::Concat(
|
||||
GetHolder()->aStr, GetHolder()->Length, in_pStr, length);
|
||||
|
||||
GetHolder()->Release();
|
||||
m_pStr = pHolder->aStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void CSharedString::prepend(const CSharedString& in_rOther)
|
||||
{
|
||||
if (!GetHolder()->TryInplacePrepend(in_rOther.GetHolder()->aStr, in_rOther.GetHolder()->Length))
|
||||
{
|
||||
SStringHolder* pHolder = SStringHolder::Concat(
|
||||
in_rOther.GetHolder()->aStr, in_rOther.GetHolder()->Length,
|
||||
GetHolder()->aStr, GetHolder()->Length);
|
||||
|
||||
GetHolder()->Release();
|
||||
m_pStr = pHolder->aStr;
|
||||
}
|
||||
}
|
||||
|
||||
inline void CSharedString::prepend(const char* in_pStr)
|
||||
{
|
||||
size_t length;
|
||||
|
||||
if (in_pStr && (length = strlen(in_pStr)) != 0)
|
||||
{
|
||||
if (!GetHolder()->TryInplacePrepend(in_pStr, length))
|
||||
{
|
||||
SStringHolder* pHolder = SStringHolder::Concat(
|
||||
in_pStr, length, GetHolder()->aStr, GetHolder()->Length);
|
||||
|
||||
GetHolder()->Release();
|
||||
m_pStr = pHolder->aStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline int CSharedString::compare(const CSharedString& in_rOther) const
|
||||
{
|
||||
// TODO: DO NOT PASS BY REFERENCE.
|
||||
return GuestToHostFunction<int>(0x82DFB028, this, &in_rOther);
|
||||
}
|
||||
|
||||
inline CSharedString& CSharedString::operator=(const CSharedString& in_rOther)
|
||||
{
|
||||
assign(in_rOther);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CSharedString& CSharedString::operator=(const char* in_pStr)
|
||||
{
|
||||
assign(in_pStr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CSharedString& CSharedString::operator=(CSharedString&& io_rOther)
|
||||
{
|
||||
assign(std::move(io_rOther));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CSharedString& CSharedString::operator+=(const CSharedString& in_rOther)
|
||||
{
|
||||
append(in_rOther);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CSharedString& CSharedString::operator+=(const char* in_pStr)
|
||||
{
|
||||
append(in_pStr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CSharedString operator+(const CSharedString& in_rLeft, const CSharedString& in_rRight)
|
||||
{
|
||||
return SStringHolder::Concat(
|
||||
in_rLeft.GetHolder()->aStr, in_rLeft.GetHolder()->Length,
|
||||
in_rRight.GetHolder()->aStr, in_rRight.GetHolder()->Length);
|
||||
}
|
||||
|
||||
inline CSharedString operator+(const CSharedString& in_rLeft, const char* in_pRight)
|
||||
{
|
||||
size_t length;
|
||||
|
||||
if (in_pRight && (length = strlen(in_pRight)) != 0)
|
||||
{
|
||||
return SStringHolder::Concat(
|
||||
in_rLeft.GetHolder()->aStr, in_rLeft.GetHolder()->Length, in_pRight, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
return in_rLeft;
|
||||
}
|
||||
}
|
||||
|
||||
inline CSharedString operator+(const char* in_pLeft, const CSharedString& in_pRight)
|
||||
{
|
||||
size_t length;
|
||||
|
||||
if (in_pLeft && (length = strlen(in_pLeft)) != 0)
|
||||
{
|
||||
return SStringHolder::Concat(
|
||||
in_pLeft, length, in_pRight.GetHolder()->aStr, in_pRight.GetHolder()->Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
return in_pRight;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool CSharedString::operator>(const CSharedString& in_rOther) const
|
||||
{
|
||||
return compare(in_rOther) > 0;
|
||||
}
|
||||
|
||||
inline bool CSharedString::operator>=(const CSharedString& in_rOther) const
|
||||
{
|
||||
return compare(in_rOther) >= 0;
|
||||
}
|
||||
|
||||
inline bool CSharedString::operator<(const CSharedString& in_rOther) const
|
||||
{
|
||||
return compare(in_rOther) < 0;
|
||||
}
|
||||
|
||||
inline bool CSharedString::operator<=(const CSharedString& in_rOther) const
|
||||
{
|
||||
return compare(in_rOther) <= 0;
|
||||
}
|
||||
|
||||
inline bool CSharedString::operator==(const CSharedString& in_rOther) const
|
||||
{
|
||||
return compare(in_rOther) == 0;
|
||||
}
|
||||
|
||||
inline bool CSharedString::operator!=(const CSharedString& in_rOther) const
|
||||
{
|
||||
return !(*this == in_rOther);
|
||||
}
|
||||
|
||||
inline bool CSharedString::operator==(const char* in_pOther) const
|
||||
{
|
||||
return strcmp(c_str(), in_pOther) == 0;
|
||||
}
|
||||
|
||||
inline bool CSharedString::operator!=(const char* in_pOther) const
|
||||
{
|
||||
return !(*this == in_pOther);
|
||||
return &m_pStr[size()];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,22 +28,26 @@ namespace boost
|
||||
|
||||
void add_ref()
|
||||
{
|
||||
std::atomic_ref useCount(use_count_.value);
|
||||
|
||||
be<uint32_t> original, incremented;
|
||||
do
|
||||
{
|
||||
original = use_count_;
|
||||
incremented = original + 1;
|
||||
} while (InterlockedCompareExchange((unsigned long*)&use_count_, incremented.value, original.value) != original.value);
|
||||
} while (!useCount.compare_exchange_weak(original.value, incremented.value));
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
std::atomic_ref useCount(use_count_.value);
|
||||
|
||||
be<uint32_t> original, decremented;
|
||||
do
|
||||
{
|
||||
original = use_count_;
|
||||
decremented = original - 1;
|
||||
} while (InterlockedCompareExchange((unsigned long*)&use_count_, decremented.value, original.value) != original.value);
|
||||
} while (!useCount.compare_exchange_weak(original.value, decremented.value));
|
||||
|
||||
if (decremented == 0)
|
||||
{
|
||||
@@ -54,12 +58,14 @@ namespace boost
|
||||
|
||||
void weak_release()
|
||||
{
|
||||
std::atomic_ref weakCount(weak_count_.value);
|
||||
|
||||
be<uint32_t> original, decremented;
|
||||
do
|
||||
{
|
||||
original = weak_count_;
|
||||
decremented = original - 1;
|
||||
} while (InterlockedCompareExchange((unsigned long*)&weak_count_, decremented.value, original.value) != original.value);
|
||||
} while (!weakCount.compare_exchange_weak(original.value, decremented.value));
|
||||
|
||||
if (decremented == 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user