Cry Legacy: the Lessening (#5961)

* Generic Cleanup

Removals:

* Unused cvars,member variables and defines
* Windows media center edition support routines
* CSystem - removed debug_GetCallStackRaw/GetRootWindowMessageHandler/
UnloadDLL/ShutdownModuleLibraries

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Fix CryMessageBox return values in Windows build

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove named selection group and a few smaller unused functionalities

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove ObjectManager export functionality + 2 deprecated functions

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove object legacy freeze/hide support from ObjectManager

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove ObjectManager duplicate name dection, as well as object renaming

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove ObjectManager serialization and selection callbacks

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* ObjectManager - remove MoveObjects/HitTestObject/EndEditParams and related members/functions

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove a bunch of unused clone related functionality + misc

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* ObjectManager - misc removals

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* ObjectManager - more removals

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove unused object selection/retrieval in ObjectManager and LoadObjects in ObjectLoader

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* CBaseObject - remove unused material layers mask support

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* More CBaseObject cleanups.

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* CBaseObject - remove SubObj functions and IMouseCreateCallback

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove unused procedural floor management, helper scale and tags.

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* CBaseObject - remove more unused methods.

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Removals in multiple places.

CBaseObject - unused `OBJTYPE_DUMMY` flag removed, member `IsSameClass`
CObjectArchive removed unused methods/members
CObjectManager removed unused `Update` method

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* More removals

IDisplayViewport - HitTestLine/GetGridStep/setHitcontext/
GetConstructionPlane
Unused Cry_Matrix44 template specializations.

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* O3DE.exe Project-Centric "Open Editor" fix (#5852)

* The O3DE.exe Open Editor button now attempts to open the Editor in the
build directory of the project being opened.

If their is no Editor within the build directory of the Project, it uses
the Editor.exe in the current O3DE.exe executable directory if it exists

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Engine .gitignore now ignores the build directory if placed in the
AutomatedTesting project

Previously it was just ignoring a `[Bb]uild` directory if it was
directly within the engine root.
This change matches the behavior of the project templates.

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Renamed the ProjectUtils GetEditorDirectory function to
GetEditorExecutablePath

Added a platform specific implementation for retrieving the path to the
Editor executable in the GetEditorExectuablePath function.

It first attempts to locate the Editor via checking the project build
directory for an Editor executable before falling back to checking the
binary directory of the currently running O3DE executable.

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Correct the MacOS GetEditorExecutablePath to return the Editor path

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Adding missing C++20 std::erase implementations (#5735)

There were already implementations for std::erase_if.
This adds the counterpart AZStd::erase versions

resolves #5734

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* More removals and refactors

`ShowMessage` and `CryMessageBox` return void now
Simplify code in `CSystem::WarningV`
Remove unused `CryGetTicksPerSec`
Remove unused WinBase functionality
Replace `nanosleep` call in WinBase with `std::this_thread::sleep_for`
Remove unused Win32Wrapper routines
Remove unused IFunctorBase.h and IEntityObjectListener.h
Fix VectorAndArray.cpp compilation
Use QMessageBox instead of CryMessageBox in the editor.
Remove empty ArchiveVars platform specific files

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Fix test code.

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove an unused  function

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* CBaseObject and undo description removals.

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* A bunch of removals

* Remove IRenderNode
* Remove editor's KDTree
* Remove StatObjBus, InstanceStatObjEventBus::ReleaseData is redundant (
same functionality in the only available handler is triggered by
`OnCryEditorCloseScene`)
* Remove CExportManager::AddStatObj/AddMeshes/AddMesh,
IExportManager::ExportSingleStatObj
* Remove CIconManager/IIconManager::GetObject
* Remove CBaseObject::IntersectRayMesh
* Remove IIndexedMesh and related structs.
* Unused IUndoObject::GetDescription and all derived implementations.
* Unused CUndoBaseLibrary/CUndoBaseLibraryManager
* Unused Matrix34_tpl typedefs
* Legacy Xml classes cleanup

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove unused `Vec3ToVector3D` helper

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* fix - remove unused static variable

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

Co-authored-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
This commit is contained in:
Artur K
2021-11-29 19:21:06 +01:00
committed by GitHub
parent a3835d8545
commit 56904d1799
115 changed files with 355 additions and 6354 deletions
+12 -512
View File
@@ -53,21 +53,8 @@
#include <mach/mach_host.h>
#endif
#if defined(ANDROID)
#define FIX_FILENAME_CASE 0 // everything is lower case on android
#elif defined(LINUX) || defined(APPLE)
#define FIX_FILENAME_CASE 1
#endif
#include <sys/time.h>
#if !defined(_RELEASE) || defined(_DEBUG)
#include <set>
unsigned int g_EnableMultipleAssert = 0;//set to something else than 0 if to enable already reported asserts
#endif
#if defined(LINUX) || defined(APPLE)
#include <sys/types.h>
#include <unistd.h>
@@ -81,106 +68,11 @@ unsigned int g_EnableMultipleAssert = 0;//set to something else than 0 if to ena
#if AZ_TRAIT_COMPILER_DEFINE_FS_ERRNO_TYPE
typedef int FS_ERRNO_TYPE;
#if AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE
typedef struct stat FS_STAT_TYPE;
#else
typedef struct stat64 FS_STAT_TYPE;
#endif
#include <mutex>
#elif AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE
#error cannot request AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE if AZ_TRAIT_COMPILER_DEFINE_FS_ERRNO_TYPE is zero
#endif
#if AZ_TRAIT_COMPILER_DEFINE_SASSERTDATA_TYPE && (!defined(_RELEASE) || defined(_DEBUG))
struct SAssertData
{
int line;
char fileName[256 - sizeof(int)];
const bool operator==(const SAssertData& crArg) const
{
return crArg.line == line && (strcmp(fileName, crArg.fileName) == 0);
}
const bool operator<(const SAssertData& crArg) const
{
if (line == crArg.line)
{
return strcmp(fileName, crArg.fileName) < 0;
}
else
{
return line < crArg.line;
}
}
SAssertData()
: line(-1){}
SAssertData(const int cLine, const char* cpFile)
: line(cLine)
{
azstrcpy(fileName, AZ_ARRAY_SIZE(fileName), cpFile);
}
SAssertData(const SAssertData& crAssertData)
{
memcpy((void*)this, &crAssertData, sizeof(SAssertData));
}
void operator=(const SAssertData& crAssertData)
{
memcpy((void*)this, &crAssertData, sizeof(SAssertData));
}
};
//#define OUTPUT_ASSERT_TO_FILE
void HandleAssert(const char* cpMessage, const char* cpFunc, const char* cpFile, const int cLine)
{
#if defined(OUTPUT_ASSERT_TO_FILE)
static FILE* pAssertLogFile = nullptr;
if (!pAssertLogFile)
{
azfopen(&pAssertLogFile, "Assert.log", "w+");
}
#endif
bool report = true;
static std::set<SAssertData> assertSet;
SAssertData assertData(cLine, cpFile);
if (!g_EnableMultipleAssert)
{
std::set<SAssertData>::const_iterator it = assertSet.find(assertData);
if (it != assertSet.end())
{
report = false;
}
else
{
assertSet.insert(assertData);
}
}
else
{
assertSet.insert(assertData);
}
if (report)
{
//added function to be able to place a breakpoint here or to print out to other consoles
printf("ASSERT: %s in %s (%s : %d)\n", cpMessage, cpFunc, cpFile, cLine);
#if defined(OUTPUT_ASSERT_TO_FILE)
if (pAssertLogFile)
{
fprintf(pAssertLogFile, "ASSERT: %s in %s (%s : %d)\n", cpMessage, cpFunc, cpFile, cLine);
fflush(pAssertLogFile);
}
#endif
}
}
#endif
bool IsBadReadPtr(void* ptr, unsigned int size)
{
//too complicated to really support it
@@ -232,9 +124,9 @@ char* strupr (char* str)
char* ltoa (long i, char* a, int radix)
{
if (a == NULL)
if (a == nullptr)
{
return NULL;
return nullptr;
}
strcpy (a, "0");
if (i && radix > 1 && radix < 37)
@@ -369,9 +261,9 @@ void _makepath(char* path, const char* drive, const char* dir, const char* filen
char* _ui64toa(unsigned long long value, char* str, int radix)
{
if (str == 0)
if (str == nullptr)
{
return 0;
return nullptr;
}
char buffer[65];
@@ -401,7 +293,7 @@ char* _ui64toa(unsigned long long value, char* str, int radix)
long long _atoi64(const char* str)
{
if (str == 0)
if (str == nullptr)
{
return -1;
}
@@ -550,22 +442,6 @@ void _splitpath(const char* inpath, char* drv, char* dir, char* fname, char* ext
}
}
//////////////////////////////////////////////////////////////////////////
int memicmp(LPCSTR s1, LPCSTR s2, DWORD len)
{
int ret = 0;
while (len--)
{
if ((ret = tolower(*s1) - tolower(*s2)))
{
break;
}
s1++;
s2++;
}
return ret;
}
//-----------------------------------------other stuff-------------------------------------------------------------------
void GlobalMemoryStatus(LPMEMORYSTATUS lpmem)
@@ -697,7 +573,7 @@ static void NormalizeTimeFields(short* FieldToNormalize, short* CarryField, int
*CarryField = (short) (*CarryField + 1);
}
bool TimeFieldsToTime(PTIME_FIELDS tfTimeFields, PLARGE_INTEGER Time)
static bool TimeFieldsToTime(PTIME_FIELDS tfTimeFields, PLARGE_INTEGER Time)
{
#define SECSPERMIN 60
#define MINSPERHOUR 60
@@ -775,119 +651,6 @@ BOOL SystemTimeToFileTime(const SYSTEMTIME* syst, LPFILETIME ft)
return TRUE;
}
void adaptFilenameToLinux(AZStd::string& rAdjustedFilename)
{
//first replace all \\ by /
AZStd::string::size_type loc = 0;
while ((loc = rAdjustedFilename.find("\\", loc)) != AZStd::string::npos)
{
rAdjustedFilename.replace(loc, 1, "/");
}
loc = 0;
//remove /./
while ((loc = rAdjustedFilename.find("/./", loc)) != AZStd::string::npos)
{
rAdjustedFilename.replace(loc, 3, "/");
}
}
void replaceDoublePathFilename(char* szFileName)
{
//replace "\.\" by "\"
AZStd::string s(szFileName);
AZStd::string::size_type loc = 0;
//remove /./
while ((loc = s.find("/./", loc)) != AZStd::string::npos)
{
s.replace(loc, 3, "/");
}
loc = 0;
//remove "\.\"
while ((loc = s.find("\\.\\", loc)) != AZStd::string::npos)
{
s.replace(loc, 3, "\\");
}
azstrcpy((char*)szFileName, AZ_MAX_PATH_LEN, s.c_str());
}
#if FIX_FILENAME_CASE
static bool FixOnePathElement(char* path)
{
if (*path == '\0')
{
return true;
}
if ((path[0] == '/') && (path[1] == '\0'))
{
return true; // root dir always exists.
}
if (strchr(path, '*') || strchr(path, '?'))
{
return true; // wildcard...stop correcting path.
}
struct stat statbuf;
if (stat(path, &statbuf) != -1) // current case exists.
{
return true;
}
char* name = path;
char* ptr = strrchr(path, '/');
if (ptr)
{
name = ptr + 1;
*ptr = '\0';
}
if (*name == '\0') // trailing '/' ?
{
*ptr = '/';
return true;
}
const char* parent;
if (ptr == path)
{
parent = "/";
}
else if (ptr == NULL)
{
parent = ".";
}
else
{
parent = path;
}
DIR* dirp = opendir(parent);
if (ptr)
{
*ptr = '/';
}
if (dirp == NULL)
{
return false;
}
struct dirent* dent;
bool found = false;
while ((dent = readdir(dirp)) != NULL)
{
if (strcasecmp(dent->d_name, name) == 0)
{
azstrcpy(name, AZ_MAX_PATH_LEN, dent->d_name);
found = true;
break;
}
}
closedir(dirp);
return found;
}
#endif
#define Int32x32To64(a, b) ((uint64)((uint64)(a)) * (uint64)((uint64)(b)))
//////////////////////////////////////////////////////////////////////////
@@ -904,24 +667,14 @@ threadID GetCurrentThreadId()
}
#endif
#include <chrono>
#include <thread>
//////////////////////////////////////////////////////////////////////////
DWORD Sleep(DWORD dwMilliseconds)
{
#if defined(LINUX) || defined(APPLE)
timespec req;
timespec rem;
memset(&req, 0, sizeof(req));
memset(&rem, 0, sizeof(rem));
time_t sec = (int)(dwMilliseconds / 1000);
req.tv_sec = sec;
req.tv_nsec = (dwMilliseconds - (sec * 1000)) * 1000000L;
if (nanosleep(&req, &rem) == -1)
{
nanosleep(&rem, 0);
}
std::this_thread::sleep_for(std::chrono::milliseconds(dwMilliseconds));
return 0;
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
#elif defined(AZ_RESTRICTED_PLATFORM)
@@ -960,7 +713,7 @@ DWORD Sleep(DWORD dwMilliseconds)
}
//////////////////////////////////////////////////////////////////////////
DWORD SleepEx(DWORD dwMilliseconds, BOOL bAlertable)
DWORD SleepEx(DWORD dwMilliseconds, BOOL /*bAlertable*/)
{
//TODO: implement
// CRY_ASSERT_MESSAGE(0, "SleepEx not implemented yet");
@@ -1006,7 +759,7 @@ void CrySleep(unsigned int dwMilliseconds)
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
int CryMessageBox(const char* lpText, const char* lpCaption, unsigned int uType)
void CryMessageBox(const char* lpText, const char* lpCaption, [[maybe_unused]] unsigned int uType)
{
#ifdef WIN32
# error WIN32 is defined in WinBase.cpp (it is a non-Windows file)
@@ -1087,63 +840,8 @@ int CryMessageBox(const char* lpText, const char* lpCaption, unsigned int uType)
CFRelease(strText);
}
if (kResult == kCFUserNotificationDefaultResponse)
{
switch (uType & 0xf)
{
case MB_OK:
case MB_OKCANCEL:
default:
return IDOK;
case MB_ABORTRETRYIGNORE:
return IDABORT;
case MB_YESNOCANCEL:
case MB_YESNO:
return IDYES;
case MB_RETRYCANCEL:
return IDRETRY;
case MB_CANCELTRYCONTINUE:
return IDCANCEL;
}
}
else if (kResult == kCFUserNotificationAlternateResponse)
{
switch (uType & 0xf)
{
case MB_OKCANCEL:
case MB_RETRYCANCEL:
return IDCANCEL;
case MB_ABORTRETRYIGNORE:
return IDRETRY;
case MB_YESNOCANCEL:
case MB_YESNO:
return IDNO;
case MB_CANCELTRYCONTINUE:
return IDTRYAGAIN;
default:
assert(false);
return IDCANCEL;
}
}
else if (kResult == kCFUserNotificationOtherResponse)
{
switch (uType & 0xf)
{
case MB_ABORTRETRYIGNORE:
return IDIGNORE;
case MB_YESNOCANCEL:
return IDCANCEL;
case MB_CANCELTRYCONTINUE:
return IDCONTINUE;
default:
assert(false);
return IDCANCEL;
}
}
return 0;
#else
printf("Messagebox: cap: %s text:%s\n", lpCaption ? lpCaption : " ", lpText ? lpText : " ");
return 0;
#endif
}
@@ -1171,21 +869,6 @@ DLL_EXPORT void OutputDebugString(const char* outputString)
// This code does not have a long life span and will be replaced soon
#if defined(APPLE) || defined(LINUX) || defined(DEFINE_LEGACY_CRY_FILE_OPERATIONS)
typedef DIR* FS_DIR_TYPE;
typedef dirent FS_DIRENT_TYPE;
static const FS_ERRNO_TYPE FS_ENOENT = ENOENT;
static const FS_DIR_TYPE FS_DIR_NULL = NULL;
typedef int FS_ERRNO_TYPE;
#if defined(APPLE)
typedef struct stat FS_STAT_TYPE;
#else
typedef struct stat64 FS_STAT_TYPE;
#endif
#include <mutex>
bool CrySetFileAttributes(const char* lpFileName, uint32 dwFileAttributes)
{
//TODO: implement
@@ -1194,190 +877,7 @@ bool CrySetFileAttributes(const char* lpFileName, uint32 dwFileAttributes)
}
ILINE void FS_OPEN(const char* szFileName, int iFlags, int& iFileDesc, mode_t uMode, FS_ERRNO_TYPE& rErr)
{
rErr = ((iFileDesc = open(szFileName, iFlags, uMode)) != -1) ? 0 : errno;
}
ILINE void FS_CLOSE(int iFileDesc, FS_ERRNO_TYPE& rErr)
{
rErr = close(iFileDesc) != -1 ? 0 : errno;
}
ILINE void FS_CLOSE_NOERR(int iFileDesc)
{
close(iFileDesc);
}
ILINE void FS_OPENDIR(const char* szDirName, FS_DIR_TYPE& pDir, FS_ERRNO_TYPE& rErr)
{
rErr = (pDir = opendir(szDirName)) != NULL ? 0 : errno;
}
ILINE void FS_READDIR(FS_DIR_TYPE pDir, FS_DIRENT_TYPE& kEnt, uint64_t& uEntSize, FS_ERRNO_TYPE& rErr)
{
errno = 0; // errno is used to determine if readdir succeeds after
FS_DIRENT_TYPE* pDirent(readdir(pDir));
if (pDirent == NULL)
{
uEntSize = 0;
rErr = (errno == FS_ENOENT) ? 0 : errno;
}
else
{
kEnt = *pDirent;
uEntSize = static_cast<uint64_t>(sizeof(FS_DIRENT_TYPE));
rErr = 0;
}
}
ILINE void FS_STAT(const char* szFileName, FS_STAT_TYPE& kStat, FS_ERRNO_TYPE& rErr)
{
#if defined(APPLE)
rErr = stat(szFileName, &kStat) != -1 ? 0 : errno;
#else
rErr = stat64(szFileName, &kStat) != -1 ? 0 : errno;
#endif
}
ILINE void FS_FSTAT(int iFileDesc, FS_STAT_TYPE& kStat, FS_ERRNO_TYPE& rErr)
{
#if defined(APPLE)
rErr = fstat(iFileDesc, &kStat) != -1 ? 0 : errno;
#else
rErr = fstat64(iFileDesc, &kStat) != -1 ? 0 : errno;
#endif
}
ILINE void FS_CLOSEDIR(FS_DIR_TYPE pDir, FS_ERRNO_TYPE& rErr)
{
errno = 0;
rErr = closedir(pDir) == 0 ? 0 : errno;
}
ILINE void FS_CLOSEDIR_NOERR(FS_DIR_TYPE pDir)
{
closedir(pDir);
}
const bool GetFilenameNoCase
(
const char* file,
char* pAdjustedFilename
)
{
assert(file);
assert(pAdjustedFilename);
azstrcpy(pAdjustedFilename, AZ_MAX_PATH_LEN, file);
// Fix the dirname case.
const int cLen = strlen(file);
for (int i = 0; i < cLen; ++i)
{
if (pAdjustedFilename[i] == '\\')
{
pAdjustedFilename[i] = '/';
}
}
if ((pAdjustedFilename) == (char*)-1)
{
return false;
}
#if !defined(LINUX) && !defined(APPLE) && !defined(DEFINE_SKIP_WILDCARD_CHECK) // fix the parent path anyhow.
char* slash = strrchr(pAdjustedFilename, '/');
char* name = pAdjustedFilename;
if (slash)
{
name = slash + 1;
*slash = 0;
}
// Check for wildcards. We'll always return true if the specified filename is
// a wildcard pattern.
if (strchr(name, '*') || strchr(name, '?'))
{
if (slash)
{
*slash = '/';
}
return true;
}
// Scan for the file.
if (slash)
{
*slash = '/';
}
#endif
#if FIX_FILENAME_CASE
char* path = pAdjustedFilename;
char* sep;
while ((sep = strchr(path, '/')) != NULL)
{
*sep = '\0';
const bool exists = FixOnePathElement(pAdjustedFilename);
*sep = '/';
if (!exists)
{
return false;
}
path = sep + 1;
}
if (!FixOnePathElement(pAdjustedFilename)) // catch last filename.
{
return false;
}
#else
for (char* c = pAdjustedFilename; *c; ++c)
{
*c = tolower(*c);
}
#endif
return true;
}
DWORD GetFileAttributes(LPCWSTR lpFileNameW)
{
AZStd::string lpFileName;
AZStd::to_string(lpFileName, lpFileNameW);
struct stat fileStats;
const int success = stat(lpFileName.c_str(), &fileStats);
if (success == -1)
{
char adjustedFilename[MAX_PATH];
GetFilenameNoCase(lpFileName.c_str(), adjustedFilename);
if (stat(adjustedFilename, &fileStats) == -1)
{
return (DWORD)INVALID_FILE_ATTRIBUTES;
}
}
DWORD ret = 0;
const int acc = (fileStats.st_mode & S_IWRITE);
if (acc != 0)
{
if (S_ISDIR(fileStats.st_mode) != 0)
{
ret |= FILE_ATTRIBUTE_DIRECTORY;
}
}
return (ret == 0) ? FILE_ATTRIBUTE_NORMAL : ret;//return file attribute normal as the default value, must only be set if no other attributes have been found
}
__finddata64_t::~__finddata64_t()
{
if (m_Dir != FS_DIR_NULL)
{
FS_CLOSEDIR_NOERR(m_Dir);
m_Dir = FS_DIR_NULL;
}
}
#endif //defined(APPLE) || defined(LINUX)
#endif // AZ_TRAIT_LEGACY_CRYCOMMON_USE_WINDOWS_STUBS