Merge branch 'development' into cmake/warn_virtual

Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>

# Conflicts:
#	Code/Legacy/CryCommon/IConsole.h
#	Code/Legacy/CrySystem/LocalizedStringManager.h
#	Code/Legacy/CrySystem/XConsole.h
#	Code/Legacy/CrySystem/XConsoleVariable.h
#	Code/Legacy/CrySystem/XML/XmlUtils.cpp
#	cmake/Platform/Common/Clang/Configurations_clang.cmake
This commit is contained in:
Esteban Papp
2021-09-07 18:42:40 -07:00
228 changed files with 1196 additions and 16357 deletions
@@ -81,7 +81,6 @@
#include <Cry_Camera.h>
#include <smartptr.h>
#include <Range.h>
#include <CrySizer.h>
#include <StlUtils.h>
-18
View File
@@ -122,24 +122,6 @@ public:
void CompressInput(const uint8* const pInput, const size_t numBytes, uint8* const pOutput, size_t* const outputSize);
size_t UncompressInput(const uint8* const pInput, const size_t numBytes, uint8* const pOutput, const size_t maxOutputSize);
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
if (m_Counts != NULL)
{
pSizer->AddObject(m_Counts, sizeof(uint32), MAX_NUM_SYMBOLS);
}
if (m_TreeNodes != NULL)
{
pSizer->AddObject(m_TreeNodes, sizeof(HuffmanTreeNode), MAX_NUM_NODES);
}
if (m_Codes != NULL)
{
pSizer->AddObject(m_Codes, sizeof(HuffmanSymbolCode), MAX_NUM_CODES);
}
}
private:
void ScaleCountsAndUpdateNodes();
int BuildTree();
@@ -37,12 +37,6 @@ namespace LegacyLevelSystem
{
static constexpr const char* ArchiveExtension = ".pak";
void CLevelInfo::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(m_levelName);
pSizer->AddObject(m_levelPath);
}
//////////////////////////////////////////////////////////////////////////
bool CLevelInfo::OpenLevelPak()
{
@@ -824,17 +818,7 @@ void CLevelSystem::LogLoadingTime()
sChain = " (Chained)";
}
AZStd::string text;
text.format("Game Level Load Time: [%s] Level %s loaded in %.2f seconds%s", vers, m_lastLevelName.c_str(), m_fLastLevelLoadTime, sChain);
gEnv->pLog->Log(text.c_str());
}
void CLevelSystem::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(m_levelInfos);
pSizer->AddObject(m_levelsFolder);
pSizer->AddObject(m_listeners);
gEnv->pLog->Log("Game Level Load Time: [%s] Level %s loaded in %.2f seconds%s", vers, m_lastLevelName.c_str(), m_fLastLevelLoadTime, sChain);
}
//////////////////////////////////////////////////////////////////////////
@@ -31,8 +31,6 @@ public:
// ~ILevelInfo
void GetMemoryUsage(ICrySizer*) const;
private:
bool ReadInfo();
@@ -114,8 +112,6 @@ public:
// ~ILevelSystem
void GetMemoryUsage(ICrySizer* s) const;
private:
float GetLastLevelLoadTime() { return m_fLastLevelLoadTime; }
@@ -468,10 +468,7 @@ namespace LegacyLevelSystem
sChain = " (Chained)";
}
AZStd::string text;
text.format(
"Game Level Load Time: [%s] Level %s loaded in %.2f seconds%s", vers, m_lastLevelName.c_str(), m_fLastLevelLoadTime, sChain);
gEnv->pLog->Log(text.c_str());
gEnv->pLog->Log("Game Level Load Time: [%s] Level %s loaded in %.2f seconds%s", vers, m_lastLevelName.c_str(), m_fLastLevelLoadTime, sChain);
}
//////////////////////////////////////////////////////////////////////////
@@ -802,16 +802,6 @@ bool CLocalizedStringsManager::ReleaseLocalizationDataByTag(
m_pLanguage->m_vLocalizedStrings.clear();
m_pLanguage->m_vLocalizedStrings = newVec;
}
/*LARGE_INTEGER liEnd, liFreq;
QueryPerformanceCounter(&liEnd);
QueryPerformanceFrequency(&liFreq);
CTimeValue lockTime = CTimeValue((liEnd.QuadPart - liStart.QuadPart) * CTimeValue::TIMEVALUE_PRECISION / liFreq.QuadPart);
if (m_cvarLocalizationDebug >= 2)
{
CryLog("<Localization> ReleaseLocalizationDataByTag %s lock time %fMS", sTag, lockTime.GetMilliSeconds());
}*/
}
if (m_cvarLocalizationDebug >= 2)
@@ -2418,16 +2408,6 @@ void CLocalizedStringsManager::FormatStringMessage(AZStd::string& outString, con
}
//////////////////////////////////////////////////////////////////////////
int CLocalizedStringsManager::GetMemoryUsage(ICrySizer* pSizer)
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(m_languages);
pSizer->AddObject(m_prototypeEvents);
pSizer->AddObject(m_characterNameSet);
pSizer->AddObject(m_pLanguage);
return 0;
}
#if defined (WIN32) || defined(WIN64)
namespace
@@ -89,8 +89,6 @@ public:
void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam) override;
// ~ISystemEventManager
int GetMemoryUsage(ICrySizer* pSizer);
void GetLoadedTags(TLocalizationTagVec& tagVec);
void FreeLocalizationData();
@@ -113,17 +111,6 @@ private:
AZStd::string sOriginalCharacterName; // english character name speaking via XML asset
unsigned int nRow; // Number of row in XML file
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(sKey);
pSizer->AddObject(sOriginalActorLine);
pSizer->AddObject(sUtf8TranslatedActorLine);
pSizer->AddObject(sOriginalText);
pSizer->AddObject(sOriginalCharacterName);
}
};
struct SLanguage;
@@ -194,28 +181,6 @@ private:
};
AZStd::string GetTranslatedText(const SLanguage* pLanguage) const;
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(sCharacterName);
if ((flags & IS_COMPRESSED) == 0 && TranslatedText.psUtf8Uncompressed != nullptr) //Number of bytes stored for compressed text is unknown, which throws this GetMemoryUsage off
{
pSizer->AddObject(*TranslatedText.psUtf8Uncompressed);
}
pSizer->AddObject(sPrototypeSoundEvent);
pSizer->AddObject(SoundMoods);
pSizer->AddObject(EventParameters);
if (pEditorExtension != nullptr)
{
pEditorExtension->GetMemoryUsage(pSizer);
}
}
};
//Keys as CRC32. Strings previously, but these proved too large
@@ -230,15 +195,6 @@ private:
StringsKeyMap m_keysMap;
TLocalizedStringEntries m_vLocalizedStrings;
THuffmanCoders m_vEncoders;
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(sLanguage);
pSizer->AddObject(m_vLocalizedStrings);
pSizer->AddObject(m_keysMap);
pSizer->AddObject(m_vEncoders);
}
};
struct SFileInfo
+2 -2
View File
@@ -593,11 +593,11 @@ void CLog::LogPlus(const char* szFormat, ...)
if (bfile)
{
LogToFilePlus(szTemp);
LogToFilePlus("%s", szTemp);
}
if (bconsole)
{
LogToConsolePlus(szTemp);
LogToConsolePlus("%s", szTemp);
}
}
+7 -12
View File
@@ -11,6 +11,13 @@
#include <ILog.h>
#include <MultiThread_Containers.h>
#include <list>
#include <AzCore/std/string/fixed_string.h>
#include <AzCore/IO/SystemFile.h>
struct IConsole;
struct ICVar;
struct ISystem;
//////////////////////////////////////////////////////////////////////
#if defined(ANDROID) || defined(AZ_PLATFORM_MAC)
@@ -105,7 +112,6 @@ private: // -------------------------------------------------------------------
ELogType logType;
bool bAdd;
Destination destination;
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {}
};
void CheckAndPruneBackupLogs() const;
@@ -193,17 +199,6 @@ private: // -------------------------------------------------------------------
#endif
public: // -------------------------------------------------------------------
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(m_pLogVerbosity);
pSizer->AddObject(m_pLogWriteToFile);
pSizer->AddObject(m_pLogWriteToFileVerbosity);
pSizer->AddObject(m_pLogVerbosityOverridesWriteToFile);
pSizer->AddObject(m_pLogSpamDelay);
pSizer->AddObject(m_threadSafeMsgQueue);
}
// checks the verbosity of the message and returns NULL if the message must NOT be
// logged, or the pointer to the part of the message that should be logged
const char* CheckAgainstVerbosity(const char* pText, bool& logtofile, bool& logtoconsole, const uint8 DefaultVerbosity = 2);
-4
View File
@@ -125,7 +125,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#include "Log.h"
#include "XML/xml.h"
#include "XML/ReadWriteXMLSink.h"
#include "LocalizedStringManager.h"
#include "XML/XmlUtils.h"
@@ -340,9 +339,6 @@ CSystem::~CSystem()
//////////////////////////////////////////////////////////////////////////
void CSystem::Release()
{
//Disconnect the render bus
AZ::RenderNotificationsBus::Handler::BusDisconnect();
delete this;
}
+5 -75
View File
@@ -18,19 +18,22 @@
#include "CmdLine.h"
#include <AzFramework/Archive/ArchiveVars.h>
#include "RenderBus.h"
#include <LoadScreenBus.h>
#include <AzCore/Module/DynamicModuleHandle.h>
#include <AzCore/Math/Crc.h>
#include <list>
#include <map>
namespace AzFramework
{
class MissingAssetLogger;
}
struct IConsoleCmdArgs;
struct ICVar;
struct IFFont;
class CWatchdogThread;
#if defined(AZ_RESTRICTED_PLATFORM)
@@ -48,48 +51,11 @@ class CWatchdogThread;
#if defined(WIN32) || defined(LINUX) || defined(APPLE)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_ALLOW_CREATE_BACKUP_LOG_FILE 1
#endif
#if defined(WIN32) || (defined(LINUX) && !defined(ANDROID)) || defined(MAC)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_DEFINE_DETECT_PROCESSOR 1
#endif
//////////////////////////////////////////////////////////////////////////
#if defined(WIN32) || defined(APPLE) || defined(LINUX)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_DO_PREASSERT 1
#endif
#if defined(MAC) || (defined(LINUX) && !defined(ANDROID))
#define AZ_LEGACY_CRYSYSTEM_TRAIT_ASM_VOLATILE_CPUID 1
#endif
#if (defined(WIN32) && !defined(WIN64)) || (defined(LINUX) && !defined(ANDROID) && !defined(LINUX64))
#define AZ_LEGACY_CRYSYSTEM_TRAIT_HAS64BITEXT 1
#endif
#if defined(WIN32) || (defined(LINUX) && !defined(ANDROID)) || defined(MAC)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_HTSUPPORTED 1
#endif
#if defined(WIN32) || (defined(LINUX) && !defined(ANDROID)) || defined(MAC)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_HASCPUID 1
#endif
#if defined(WIN32)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_HASAFFINITYMASK 1
#endif
#if defined(LINUX) || defined(APPLE)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_CRYPAK_POSIX 1
#endif
#if defined(WIN64)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_USE_BIT64 1
#endif
#if defined(WIN32)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_USE_PACKED_PEHEADER 1
#endif
#if defined(WIN32) || defined(LINUX)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_USE_RENDERMEMORY_INFO 1
#endif
#if defined(WIN32)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_USE_HANDLER_SYNC_AFFINITY 1
#endif
#if defined(LINUX) || defined(APPLE)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_FORWARD_EXCEPTION_POINTERS 1
@@ -105,18 +71,6 @@ class CWatchdogThread;
#define AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_APPEND_MODULENAME 1
#endif
#if !(defined(ANDROID) || defined(IOS) || defined(LINUX))
#define AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO 1
#endif
#if 1
#define AZ_LEGACY_CRYSYSTEM_TRAIT_JOBMANAGER_SIXWORKERTHREADS 0
#endif
#if defined(WIN32)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_MEMADDRESSRANGE_WINDOWS_STYLE 1
#endif
#if 1
#define AZ_LEGACY_CRYSYSTEM_TRAIT_USE_EXCLUDEUPDATE_ON_CONSOLE 0
#endif
@@ -127,31 +81,8 @@ class CWatchdogThread;
#define AZ_LEGACY_CRYSYSTEM_TRAIT_CAPTURESTACK 1
#endif
#if !defined(LINUX) && !defined(APPLE)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_SYSTEMCFG_MODULENAME 1
#endif
#if defined(WIN32) || defined(WIN64)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_THREADINFO_WINDOWS_STYLE 1
#endif
#if defined(WIN32)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_THREADTASK_EXCEPTIONS 1
#endif
//////////////////////////////////////////////////////////////////////////
#if defined(APPLE) || defined(LINUX)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_FACTORY_REGISTRY_USE_PRINTF_FOR_FATAL 1
#endif
#if defined(LINUX) || defined(APPLE)
#define AZ_LEGACY_CRYSYSTEM_TRAIT_USE_FTELL_NOT_FTELLI64 1
#endif
#endif
#if defined(USE_UNIXCONSOLE) || defined(USE_ANDROIDCONSOLE) || defined(USE_WINDOWSCONSOLE) || defined(USE_IOSCONSOLE) || defined(USE_NULLCONSOLE)
#define USE_DEDICATED_SERVER_CONSOLE
#endif
#if defined(LINUX)
@@ -269,7 +200,6 @@ class CSystem
, public ILoadConfigurationEntrySink
, public ISystemEventListener
, public IWindowMessageHandler
, public AZ::RenderNotificationsBus::Handler
, public CrySystemRequestBus::Handler
{
public:
+10 -113
View File
@@ -22,8 +22,6 @@
#include <AzCore/Utils/Utils.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include "SystemCFG.h"
#if defined(AZ_RESTRICTED_PLATFORM)
#undef AZ_RESTRICTED_SECTION
#define SYSTEMCFG_CPP_SECTION_1 1
@@ -180,7 +178,7 @@ void CSystem::LogVersion()
strftime(s, 128, "%d %b %y (%H %M %S)", today);
#endif
[[maybe_unused]] const SFileVersion& ver = GetFileVersion();
const SFileVersion& ver = GetFileVersion();
CryLogAlways("BackupNameAttachment=\" Build(%d) %s\" -- used by backup system\n", ver.v[0], s); // read by CreateBackupFile()
@@ -190,7 +188,7 @@ void CSystem::LogVersion()
#else
strftime(s, 128, "Log Started at %c", today);
#endif
CryLogAlways(s);
CryLogAlways("%s", s);
CryLogAlways("Built on " __DATE__ " " __TIME__);
@@ -251,122 +249,21 @@ void CSystem::LogVersion()
//////////////////////////////////////////////////////////////////////////
void CSystem::LogBuildInfo()
{
[[maybe_unused]] auto projectName = AZ::Utils::GetProjectName();
auto projectName = AZ::Utils::GetProjectName();
CryLogAlways("GameName: %s", projectName.c_str());
CryLogAlways("BuildTime: " __DATE__ " " __TIME__);
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
class CCVarSaveDump
: public ICVarDumpSink
{
public:
CCVarSaveDump(FILE* pFile)
{
m_pFile = pFile;
}
virtual void OnElementFound(ICVar* pCVar)
{
if (!pCVar)
{
return;
}
int nFlags = pCVar->GetFlags();
if (((nFlags & VF_DUMPTODISK) && (nFlags & VF_MODIFIED)) || (nFlags & VF_WASINCONFIG))
{
AZStd::string szValue = pCVar->GetString();
int pos;
pos = 1;
for (;; )
{
pos = static_cast<int>(szValue.find_first_of("\\", pos));
if (pos == AZStd::string::npos)
{
break;
}
szValue.replace(pos, 1, "\\\\", 2);
pos += 2;
}
// replace " with \"
pos = 1;
for (;; )
{
pos = static_cast<int>(szValue.find_first_of("\"", pos));
if (pos == AZStd::string::npos)
{
break;
}
szValue.replace(pos, 1, "\\\"", 2);
pos += 2;
}
AZStd::string szLine = pCVar->GetName();
if (pCVar->GetType() == CVAR_STRING)
{
szLine += " = \"" + szValue + "\"\r\n";
}
else
{
szLine += " = " + szValue + "\r\n";
}
if (pCVar->GetFlags() & VF_WARNING_NOTUSED)
{
fputs("-- REMARK: the following was not assigned to a console variable\r\n", m_pFile);
}
fputs(szLine.c_str(), m_pFile);
}
}
private: // --------------------------------------------------------
FILE* m_pFile; //
};
//////////////////////////////////////////////////////////////////////////
void CSystem::SaveConfiguration()
{
}
//////////////////////////////////////////////////////////////////////////
// system cfg
//////////////////////////////////////////////////////////////////////////
CSystemConfiguration::CSystemConfiguration(const AZStd::string& strSysConfigFilePath, CSystem* pSystem, ILoadConfigurationEntrySink* pSink, bool warnIfMissing)
: m_strSysConfigFilePath(strSysConfigFilePath)
, m_bError(false)
, m_pSink(pSink)
, m_warnIfMissing(warnIfMissing)
static bool ParseSystemConfig(const AZStd::string& strSysConfigFilePath, ILoadConfigurationEntrySink* pSink, bool warnIfMissing)
{
assert(pSink);
m_pSystem = pSystem;
m_bError = !ParseSystemConfig();
}
//////////////////////////////////////////////////////////////////////////
CSystemConfiguration::~CSystemConfiguration()
{
}
//////////////////////////////////////////////////////////////////////////
bool CSystemConfiguration::ParseSystemConfig()
{
AZStd::string filename = m_strSysConfigFilePath;
AZStd::string filename = strSysConfigFilePath;
if (strlen(PathUtil::GetExt(filename.c_str())) == 0)
{
filename = PathUtil::ReplaceExtension(filename, "cfg");
@@ -384,7 +281,7 @@ bool CSystemConfiguration::ParseSystemConfig()
// if the file is missing and its already prefixed with an alias, there is no need to look any further.
if (!(file.Open(filename.c_str(), "rb", flags)))
{
if (m_warnIfMissing)
if (warnIfMissing)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Config file %s not found!", filename.c_str());
}
@@ -403,7 +300,7 @@ bool CSystemConfiguration::ParseSystemConfig()
!(file.Open((AZStd::string("@assets@/config/spec/") + filename).c_str(), "rb", flags))
)
{
if (m_warnIfMissing)
if (warnIfMissing)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Config file %s not found!", filename.c_str());
}
@@ -518,7 +415,7 @@ bool CSystemConfiguration::ParseSystemConfig()
AZ::StringFunc::Replace(strValue, "\\\\", "\\");
AZ::StringFunc::Replace(strValue, "\\\"", "\"");
m_pSink->OnLoadConfigurationEntry(strKey.c_str(), strValue.c_str(), strGroup.c_str());
pSink->OnLoadConfigurationEntry(strKey.c_str(), strValue.c_str(), strGroup.c_str());
}
}
}
@@ -532,7 +429,7 @@ bool CSystemConfiguration::ParseSystemConfig()
CryLog("Loading Config file %s (%s)", filename.c_str(), filenameLog.c_str());
m_pSink->OnLoadConfigurationEntry_End();
pSink->OnLoadConfigurationEntry_End();
return true;
}
@@ -574,7 +471,7 @@ void CSystem::LoadConfiguration(const char* sFilename, ILoadConfigurationEntrySi
pSink = this;
}
CSystemConfiguration tempConfig(sFilename, this, pSink, warnIfMissing);
ParseSystemConfig(sFilename, pSink, warnIfMissing);
}
}
-44
View File
@@ -1,44 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_CRYSYSTEM_SYSTEMCFG_H
#define CRYINCLUDE_CRYSYSTEM_SYSTEMCFG_H
#pragma once
#include <math.h>
#include <map>
typedef AZStd::string SysConfigKey;
typedef AZStd::string SysConfigValue;
//////////////////////////////////////////////////////////////////////////
class CSystemConfiguration
{
public:
CSystemConfiguration(const AZStd::string& strSysConfigFilePath, CSystem* pSystem, ILoadConfigurationEntrySink* pSink, bool warnIfMissing = true);
~CSystemConfiguration();
bool IsError() const { return m_bError; }
private: // ----------------------------------------
// Returns:
// success
bool ParseSystemConfig();
CSystem* m_pSystem;
AZStd::string m_strSysConfigFilePath;
bool m_bError;
ILoadConfigurationEntrySink* m_pSink; // never 0
bool m_warnIfMissing;
};
#endif // CRYINCLUDE_CRYSYSTEM_SYSTEMCFG_H
-92
View File
@@ -516,95 +516,6 @@ void CSystem::ShutdownModuleLibraries()
#endif // !defined(AZ_MONOLITHIC_BUILD)
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
#if defined(WIN32) || defined(WIN64)
AZStd::wstring GetErrorStringUnsupportedGPU(const char* gpuName, unsigned int gpuVendorId, unsigned int gpuDeviceId)
{
const size_t fullLangID = (size_t) GetKeyboardLayout(0);
const size_t primLangID = fullLangID & 0x3FF;
const wchar_t* pFmt = L"Unsupported video card detected! Continuing to run might lead to unexpected results or crashes. "
L"Please check the manual for further information on hardware requirements.\n\n\"%S\" [vendor id = 0x%.4x, device id = 0x%.4x]";
switch (primLangID)
{
case 0x04: // Chinese
{
static const wchar_t fmt[] = {0x5075, 0x6E2C, 0x5230, 0x4E0D, 0x652F, 0x63F4, 0x7684, 0x986F, 0x793A, 0x5361, 0xFF01, 0x7E7C, 0x7E8C, 0x57F7, 0x884C, 0x53EF, 0x80FD, 0x5C0E, 0x81F4, 0x7121, 0x6CD5, 0x9810, 0x671F, 0x7684, 0x7D50, 0x679C, 0x6216, 0x7576, 0x6A5F, 0x3002, 0x8ACB, 0x6AA2, 0x67E5, 0x8AAA, 0x660E, 0x66F8, 0x4E0A, 0x7684, 0x786C, 0x9AD4, 0x9700, 0x6C42, 0x4EE5, 0x53D6, 0x5F97, 0x66F4, 0x591A, 0x76F8, 0x95DC, 0x8CC7, 0x8A0A, 0x3002, 0x000A, 0x000A, 0x0022, 0x0025, 0x0053, 0x0022, 0x0020, 0x005B, 0x5EE0, 0x5546, 0x7DE8, 0x865F, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x002C, 0x0020, 0x88DD, 0x7F6E, 0x7DE8, 0x865F, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x005D, 0};
pFmt = fmt;
break;
}
case 0x05: // Czech
{
static const wchar_t fmt[] = {0x0042, 0x0079, 0x006C, 0x0061, 0x0020, 0x0064, 0x0065, 0x0074, 0x0065, 0x006B, 0x006F, 0x0076, 0x00E1, 0x006E, 0x0061, 0x0020, 0x0067, 0x0072, 0x0061, 0x0066, 0x0069, 0x0063, 0x006B, 0x00E1, 0x0020, 0x006B, 0x0061, 0x0072, 0x0074, 0x0061, 0x002C, 0x0020, 0x006B, 0x0074, 0x0065, 0x0072, 0x00E1, 0x0020, 0x006E, 0x0065, 0x006E, 0x00ED, 0x0020, 0x0070, 0x006F, 0x0064, 0x0070, 0x006F, 0x0072, 0x006F, 0x0076, 0x00E1, 0x006E, 0x0061, 0x002E, 0x0020, 0x0050, 0x006F, 0x006B, 0x0072, 0x0061, 0x010D, 0x006F, 0x0076, 0x00E1, 0x006E, 0x00ED, 0x0020, 0x006D, 0x016F, 0x017E, 0x0065, 0x0020, 0x0076, 0x00E9, 0x0073, 0x0074, 0x0020, 0x006B, 0x0065, 0x0020, 0x006B, 0x0072, 0x0069, 0x0074, 0x0069, 0x0063, 0x006B, 0x00FD, 0x006D, 0x0020, 0x0063, 0x0068, 0x0079, 0x0062, 0x00E1, 0x006D, 0x0020, 0x006E, 0x0065, 0x0062, 0x006F, 0x0020, 0x006E, 0x0065, 0x0073, 0x0074, 0x0061, 0x0062, 0x0069, 0x006C, 0x0069, 0x0074, 0x011B, 0x0020, 0x0073, 0x0079, 0x0073, 0x0074, 0x00E9, 0x006D, 0x0075, 0x002E, 0x0020, 0x0050, 0x0159, 0x0065, 0x010D, 0x0074, 0x011B, 0x0074, 0x0065, 0x0020, 0x0073, 0x0069, 0x0020, 0x0070, 0x0072, 0x006F, 0x0073, 0x00ED, 0x006D, 0x0020, 0x0075, 0x017E, 0x0069, 0x0076, 0x0061, 0x0074, 0x0065, 0x006C, 0x0073, 0x006B, 0x006F, 0x0075, 0x0020, 0x0070, 0x0159, 0x00ED, 0x0072, 0x0075, 0x010D, 0x006B, 0x0075, 0x0020, 0x0070, 0x0072, 0x006F, 0x0020, 0x0070, 0x006F, 0x0064, 0x0072, 0x006F, 0x0062, 0x006E, 0x00E9, 0x0020, 0x0069, 0x006E, 0x0066, 0x006F, 0x0072, 0x006D, 0x0061, 0x0063, 0x0065, 0x0020, 0x006F, 0x0020, 0x0073, 0x0079, 0x0073, 0x0074, 0x00E9, 0x006D, 0x006F, 0x0076, 0x00FD, 0x0063, 0x0068, 0x0020, 0x0070, 0x006F, 0x017E, 0x0061, 0x0064, 0x0061, 0x0076, 0x0063, 0x00ED, 0x0063, 0x0068, 0x002E, 0x000A, 0x000A, 0x0022, 0x0025, 0x0053, 0x0022, 0x0020, 0x005B, 0x0076, 0x0065, 0x006E, 0x0064, 0x006F, 0x0072, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x002C, 0x0020, 0x0064, 0x0065, 0x0076, 0x0069, 0x0063, 0x0065, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x005D, 0};
pFmt = fmt;
break;
}
case 0x07: // German
{
static const wchar_t fmt[] = {0x004E, 0x0069, 0x0063, 0x0068, 0x0074, 0x002D, 0x0075, 0x006E, 0x0074, 0x0065, 0x0072, 0x0073, 0x0074, 0x00FC, 0x0074, 0x007A, 0x0074, 0x0065, 0x0020, 0x0056, 0x0069, 0x0064, 0x0065, 0x006F, 0x006B, 0x0061, 0x0072, 0x0074, 0x0065, 0x0020, 0x0067, 0x0065, 0x0066, 0x0075, 0x006E, 0x0064, 0x0065, 0x006E, 0x0021, 0x0020, 0x0046, 0x006F, 0x0072, 0x0074, 0x0066, 0x0061, 0x0068, 0x0072, 0x0065, 0x006E, 0x0020, 0x006B, 0x0061, 0x006E, 0x006E, 0x0020, 0x007A, 0x0075, 0x0020, 0x0075, 0x006E, 0x0065, 0x0072, 0x0077, 0x0061, 0x0072, 0x0074, 0x0065, 0x0074, 0x0065, 0x006E, 0x0020, 0x0045, 0x0072, 0x0067, 0x0065, 0x0062, 0x006E, 0x0069, 0x0073, 0x0073, 0x0065, 0x006E, 0x0020, 0x006F, 0x0064, 0x0065, 0x0072, 0x0020, 0x0041, 0x0062, 0x0073, 0x0074, 0x00FC, 0x0072, 0x007A, 0x0065, 0x006E, 0x0020, 0x0066, 0x00FC, 0x0068, 0x0072, 0x0065, 0x006E, 0x002E, 0x0020, 0x0042, 0x0069, 0x0074, 0x0074, 0x0065, 0x0020, 0x006C, 0x0069, 0x0065, 0x0073, 0x0020, 0x0064, 0x0061, 0x0073, 0x0020, 0x004D, 0x0061, 0x006E, 0x0075, 0x0061, 0x006C, 0x0020, 0x0066, 0x00FC, 0x0072, 0x0020, 0x0077, 0x0065, 0x0069, 0x0074, 0x0065, 0x0072, 0x0065, 0x0020, 0x0049, 0x006E, 0x0066, 0x006F, 0x0072, 0x006D, 0x0061, 0x0074, 0x0069, 0x006F, 0x006E, 0x0065, 0x006E, 0x0020, 0x007A, 0x0075, 0x0020, 0x0048, 0x0061, 0x0072, 0x0064, 0x0077, 0x0061, 0x0072, 0x0065, 0x002D, 0x0041, 0x006E, 0x0066, 0x006F, 0x0072, 0x0064, 0x0065, 0x0072, 0x0075, 0x006E, 0x0067, 0x0065, 0x006E, 0x002E, 0x000A, 0x000A, 0x0022, 0x0025, 0x0053, 0x0022, 0x0020, 0x005B, 0x0076, 0x0065, 0x006E, 0x0064, 0x006F, 0x0072, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x002C, 0x0020, 0x0064, 0x0065, 0x0076, 0x0069, 0x0063, 0x0065, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x005D, 0};
pFmt = fmt;
break;
}
case 0x0a: // Spanish
{
static const wchar_t fmt[] = {0x0053, 0x0065, 0x0020, 0x0068, 0x0061, 0x0020, 0x0064, 0x0065, 0x0074, 0x0065, 0x0063, 0x0074, 0x0061, 0x0064, 0x006F, 0x0020, 0x0075, 0x006E, 0x0061, 0x0020, 0x0074, 0x0061, 0x0072, 0x006A, 0x0065, 0x0074, 0x0061, 0x0020, 0x0067, 0x0072, 0x00E1, 0x0066, 0x0069, 0x0063, 0x0061, 0x0020, 0x006E, 0x006F, 0x0020, 0x0063, 0x006F, 0x006D, 0x0070, 0x0061, 0x0074, 0x0069, 0x0062, 0x006C, 0x0065, 0x002E, 0x0020, 0x0053, 0x0069, 0x0020, 0x0073, 0x0069, 0x0067, 0x0075, 0x0065, 0x0073, 0x0020, 0x0065, 0x006A, 0x0065, 0x0063, 0x0075, 0x0074, 0x0061, 0x006E, 0x0064, 0x006F, 0x0020, 0x0065, 0x006C, 0x0020, 0x006A, 0x0075, 0x0065, 0x0067, 0x006F, 0x002C, 0x0020, 0x0065, 0x0073, 0x0020, 0x0070, 0x006F, 0x0073, 0x0069, 0x0062, 0x006C, 0x0065, 0x0020, 0x0071, 0x0075, 0x0065, 0x0020, 0x0073, 0x0065, 0x0020, 0x0070, 0x0072, 0x006F, 0x0064, 0x0075, 0x007A, 0x0063, 0x0061, 0x006E, 0x0020, 0x0065, 0x0066, 0x0065, 0x0063, 0x0074, 0x006F, 0x0073, 0x0020, 0x0069, 0x006E, 0x0065, 0x0073, 0x0070, 0x0065, 0x0072, 0x0061, 0x0064, 0x006F, 0x0073, 0x0020, 0x006F, 0x0020, 0x0071, 0x0075, 0x0065, 0x0020, 0x0065, 0x006C, 0x0020, 0x0070, 0x0072, 0x006F, 0x0067, 0x0072, 0x0061, 0x006D, 0x0061, 0x0020, 0x0064, 0x0065, 0x006A, 0x0065, 0x0020, 0x0064, 0x0065, 0x0020, 0x0066, 0x0075, 0x006E, 0x0063, 0x0069, 0x006F, 0x006E, 0x0061, 0x0072, 0x002E, 0x0020, 0x0050, 0x006F, 0x0072, 0x0020, 0x0066, 0x0061, 0x0076, 0x006F, 0x0072, 0x002C, 0x0020, 0x0063, 0x006F, 0x006D, 0x0070, 0x0072, 0x0075, 0x0065, 0x0062, 0x0061, 0x0020, 0x0065, 0x006C, 0x0020, 0x006D, 0x0061, 0x006E, 0x0075, 0x0061, 0x006C, 0x0020, 0x0070, 0x0061, 0x0072, 0x0061, 0x0020, 0x006F, 0x0062, 0x0074, 0x0065, 0x006E, 0x0065, 0x0072, 0x0020, 0x006D, 0x00E1, 0x0073, 0x0020, 0x0069, 0x006E, 0x0066, 0x006F, 0x0072, 0x006D, 0x0061, 0x0063, 0x0069, 0x00F3, 0x006E, 0x0020, 0x0061, 0x0063, 0x0065, 0x0072, 0x0063, 0x0061, 0x0020, 0x0064, 0x0065, 0x0020, 0x006C, 0x006F, 0x0073, 0x0020, 0x0072, 0x0065, 0x0071, 0x0075, 0x0069, 0x0073, 0x0069, 0x0074, 0x006F, 0x0073, 0x0020, 0x0064, 0x0065, 0x006C, 0x0020, 0x0073, 0x0069, 0x0073, 0x0074, 0x0065, 0x006D, 0x0061, 0x002E, 0x000A, 0x000A, 0x0022, 0x0025, 0x0053, 0x0022, 0x0020, 0x005B, 0x0076, 0x0065, 0x006E, 0x0064, 0x006F, 0x0072, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x002C, 0x0020, 0x0064, 0x0065, 0x0076, 0x0069, 0x0063, 0x0065, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x005D, 0};
pFmt = fmt;
break;
}
case 0x0c: // French
{
static const wchar_t fmt[] = {0x0041, 0x0074, 0x0074, 0x0065, 0x006E, 0x0074, 0x0069, 0x006F, 0x006E, 0x002C, 0x0020, 0x006C, 0x0061, 0x0020, 0x0063, 0x0061, 0x0072, 0x0074, 0x0065, 0x0020, 0x0076, 0x0069, 0x0064, 0x00E9, 0x006F, 0x0020, 0x0064, 0x00E9, 0x0074, 0x0065, 0x0063, 0x0074, 0x00E9, 0x0065, 0x0020, 0x006E, 0x2019, 0x0065, 0x0073, 0x0074, 0x0020, 0x0070, 0x0061, 0x0073, 0x0020, 0x0073, 0x0075, 0x0070, 0x0070, 0x006F, 0x0072, 0x0074, 0x00E9, 0x0065, 0x0020, 0x0021, 0x0020, 0x0050, 0x006F, 0x0075, 0x0072, 0x0073, 0x0075, 0x0069, 0x0076, 0x0072, 0x0065, 0x0020, 0x006C, 0x2019, 0x0061, 0x0070, 0x0070, 0x006C, 0x0069, 0x0063, 0x0061, 0x0074, 0x0069, 0x006F, 0x006E, 0x0020, 0x0070, 0x006F, 0x0075, 0x0072, 0x0072, 0x0061, 0x0069, 0x0074, 0x0020, 0x0065, 0x006E, 0x0067, 0x0065, 0x006E, 0x0064, 0x0072, 0x0065, 0x0072, 0x0020, 0x0064, 0x0065, 0x0073, 0x0020, 0x0069, 0x006E, 0x0073, 0x0074, 0x0061, 0x0062, 0x0069, 0x006C, 0x0069, 0x0074, 0x00E9, 0x0073, 0x0020, 0x006F, 0x0075, 0x0020, 0x0064, 0x0065, 0x0073, 0x0020, 0x0063, 0x0072, 0x0061, 0x0073, 0x0068, 0x0073, 0x002E, 0x0020, 0x0056, 0x0065, 0x0075, 0x0069, 0x006C, 0x006C, 0x0065, 0x007A, 0x0020, 0x0076, 0x006F, 0x0075, 0x0073, 0x0020, 0x0072, 0x0065, 0x0070, 0x006F, 0x0072, 0x0074, 0x0065, 0x0072, 0x0020, 0x0061, 0x0075, 0x0020, 0x006D, 0x0061, 0x006E, 0x0075, 0x0065, 0x006C, 0x0020, 0x0070, 0x006F, 0x0075, 0x0072, 0x0020, 0x0070, 0x006C, 0x0075, 0x0073, 0x0020, 0x0064, 0x2019, 0x0069, 0x006E, 0x0066, 0x006F, 0x0072, 0x006D, 0x0061, 0x0074, 0x0069, 0x006F, 0x006E, 0x0073, 0x0020, 0x0073, 0x0075, 0x0072, 0x0020, 0x006C, 0x0065, 0x0073, 0x0020, 0x0070, 0x0072, 0x00E9, 0x002D, 0x0072, 0x0065, 0x0071, 0x0075, 0x0069, 0x0073, 0x0020, 0x006D, 0x0061, 0x0074, 0x00E9, 0x0072, 0x0069, 0x0065, 0x006C, 0x002E, 0x000A, 0x000A, 0x0022, 0x0025, 0x0053, 0x0022, 0x0020, 0x005B, 0x0076, 0x0065, 0x006E, 0x0064, 0x006F, 0x0072, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x002C, 0x0020, 0x0064, 0x0065, 0x0076, 0x0069, 0x0063, 0x0065, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x005D, 0};
pFmt = fmt;
break;
}
case 0x10: // Italian
{
static const wchar_t fmt[] = {0x00C8, 0x0020, 0x0073, 0x0074, 0x0061, 0x0074, 0x0061, 0x0020, 0x0072, 0x0069, 0x006C, 0x0065, 0x0076, 0x0061, 0x0074, 0x0061, 0x0020, 0x0075, 0x006E, 0x0061, 0x0020, 0x0073, 0x0063, 0x0068, 0x0065, 0x0064, 0x0061, 0x0020, 0x0067, 0x0072, 0x0061, 0x0066, 0x0069, 0x0063, 0x0061, 0x0020, 0x006E, 0x006F, 0x006E, 0x0020, 0x0073, 0x0075, 0x0070, 0x0070, 0x006F, 0x0072, 0x0074, 0x0061, 0x0074, 0x0061, 0x0021, 0x0020, 0x0053, 0x0065, 0x0020, 0x0073, 0x0069, 0x0020, 0x0063, 0x006F, 0x006E, 0x0074, 0x0069, 0x006E, 0x0075, 0x0061, 0x002C, 0x0020, 0x0073, 0x0069, 0x0020, 0x0070, 0x006F, 0x0074, 0x0072, 0x0065, 0x0062, 0x0062, 0x0065, 0x0072, 0x006F, 0x0020, 0x0076, 0x0065, 0x0072, 0x0069, 0x0066, 0x0069, 0x0063, 0x0061, 0x0072, 0x0065, 0x0020, 0x0072, 0x0069, 0x0073, 0x0075, 0x006C, 0x0074, 0x0061, 0x0074, 0x0069, 0x0020, 0x0069, 0x006E, 0x0061, 0x0074, 0x0074, 0x0065, 0x0073, 0x0069, 0x0020, 0x006F, 0x0020, 0x0063, 0x0072, 0x0061, 0x0073, 0x0068, 0x002E, 0x0020, 0x0043, 0x006F, 0x006E, 0x0073, 0x0075, 0x006C, 0x0074, 0x0061, 0x0020, 0x0069, 0x006C, 0x0020, 0x006D, 0x0061, 0x006E, 0x0075, 0x0061, 0x006C, 0x0065, 0x0020, 0x0070, 0x0065, 0x0072, 0x0020, 0x0075, 0x006C, 0x0074, 0x0065, 0x0072, 0x0069, 0x006F, 0x0072, 0x0069, 0x0020, 0x0069, 0x006E, 0x0066, 0x006F, 0x0072, 0x006D, 0x0061, 0x007A, 0x0069, 0x006F, 0x006E, 0x0069, 0x0020, 0x0073, 0x0075, 0x0069, 0x0020, 0x0072, 0x0065, 0x0071, 0x0075, 0x0069, 0x0073, 0x0069, 0x0074, 0x0069, 0x0020, 0x0064, 0x0069, 0x0020, 0x0073, 0x0069, 0x0073, 0x0074, 0x0065, 0x006D, 0x0061, 0x002E, 0x000A, 0x000A, 0x0022, 0x0025, 0x0053, 0x0022, 0x0020, 0x005B, 0x0076, 0x0065, 0x006E, 0x0064, 0x006F, 0x0072, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x002C, 0x0020, 0x0064, 0x0065, 0x0076, 0x0069, 0x0063, 0x0065, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x005D, 0};
pFmt = fmt;
break;
}
case 0x11: // Japanese
{
static const wchar_t fmt[] = {0x30B5, 0x30DD, 0x30FC, 0x30C8, 0x3055, 0x308C, 0x3066, 0x3044, 0x306A, 0x3044, 0x30D3, 0x30C7, 0x30AA, 0x30AB, 0x30FC, 0x30C9, 0x304C, 0x691C, 0x51FA, 0x3055, 0x308C, 0x307E, 0x3057, 0x305F, 0xFF01, 0x0020, 0x3053, 0x306E, 0x307E, 0x307E, 0x7D9A, 0x3051, 0x308B, 0x3068, 0x4E88, 0x671F, 0x3057, 0x306A, 0x3044, 0x7D50, 0x679C, 0x3084, 0x30AF, 0x30E9, 0x30C3, 0x30B7, 0x30E5, 0x306E, 0x6050, 0x308C, 0x304C, 0x3042, 0x308A, 0x307E, 0x3059, 0x3002, 0x0020, 0x30DE, 0x30CB, 0x30E5, 0x30A2, 0x30EB, 0x306E, 0x5FC5, 0x8981, 0x52D5, 0x4F5C, 0x74B0, 0x5883, 0x3092, 0x3054, 0x78BA, 0x8A8D, 0x304F, 0x3060, 0x3055, 0x3044, 0x3002, 0x000A, 0x000A, 0x0022, 0x0025, 0x0053, 0x0022, 0x0020, 0x005B, 0x30D9, 0x30F3, 0x30C0, 0x30FC, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x002C, 0x0020, 0x30C7, 0x30D0, 0x30A4, 0x30B9, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x005D, 0};
pFmt = fmt;
break;
}
case 0x15: // Polish
{
static const wchar_t fmt[] = {0x0057, 0x0079, 0x006B, 0x0072, 0x0079, 0x0074, 0x006F, 0x0020, 0x006E, 0x0069, 0x0065, 0x006F, 0x0062, 0x0073, 0x0142, 0x0075, 0x0067, 0x0069, 0x0077, 0x0061, 0x006E, 0x0105, 0x0020, 0x006B, 0x0061, 0x0072, 0x0074, 0x0119, 0x0020, 0x0067, 0x0072, 0x0061, 0x0066, 0x0069, 0x0063, 0x007A, 0x006E, 0x0105, 0x0021, 0x0020, 0x0044, 0x0061, 0x006C, 0x0073, 0x007A, 0x0065, 0x0020, 0x006B, 0x006F, 0x0072, 0x007A, 0x0079, 0x0073, 0x0074, 0x0061, 0x006E, 0x0069, 0x0065, 0x0020, 0x007A, 0x0020, 0x0070, 0x0072, 0x006F, 0x0064, 0x0075, 0x006B, 0x0074, 0x0075, 0x0020, 0x006D, 0x006F, 0x017C, 0x0065, 0x0020, 0x0073, 0x0070, 0x006F, 0x0077, 0x006F, 0x0064, 0x006F, 0x0077, 0x0061, 0x0107, 0x0020, 0x006E, 0x0069, 0x0065, 0x0070, 0x006F, 0x017C, 0x0105, 0x0064, 0x0061, 0x006E, 0x0065, 0x0020, 0x007A, 0x0061, 0x0063, 0x0068, 0x006F, 0x0077, 0x0061, 0x006E, 0x0069, 0x0065, 0x0020, 0x006C, 0x0075, 0x0062, 0x0020, 0x0077, 0x0073, 0x0074, 0x0072, 0x007A, 0x0079, 0x006D, 0x0061, 0x006E, 0x0069, 0x0065, 0x0020, 0x0070, 0x0072, 0x006F, 0x0067, 0x0072, 0x0061, 0x006D, 0x0075, 0x002E, 0x0020, 0x0041, 0x0062, 0x0079, 0x0020, 0x0075, 0x007A, 0x0079, 0x0073, 0x006B, 0x0061, 0x0107, 0x0020, 0x0077, 0x0069, 0x0119, 0x0063, 0x0065, 0x006A, 0x0020, 0x0069, 0x006E, 0x0066, 0x006F, 0x0072, 0x006D, 0x0061, 0x0063, 0x006A, 0x0069, 0x002C, 0x0020, 0x0073, 0x006B, 0x006F, 0x006E, 0x0073, 0x0075, 0x006C, 0x0074, 0x0075, 0x006A, 0x0020, 0x0073, 0x0069, 0x0119, 0x0020, 0x007A, 0x0020, 0x0069, 0x006E, 0x0073, 0x0074, 0x0072, 0x0075, 0x006B, 0x0063, 0x006A, 0x0105, 0x0020, 0x006F, 0x0062, 0x0073, 0x0142, 0x0075, 0x0067, 0x0069, 0x002E, 0x000A, 0x000A, 0x0022, 0x0025, 0x0053, 0x0022, 0x0020, 0x005B, 0x0076, 0x0065, 0x006E, 0x0064, 0x006F, 0x0072, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x002C, 0x0020, 0x0064, 0x0065, 0x0076, 0x0069, 0x0063, 0x0065, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x005D, 0};
pFmt = fmt;
break;
}
case 0x19: // Russian
{
static const wchar_t fmt[] = {0x0412, 0x0430, 0x0448, 0x0430, 0x0020, 0x0432, 0x0438, 0x0434, 0x0435, 0x043E, 0x0020, 0x043A, 0x0430, 0x0440, 0x0442, 0x0430, 0x0020, 0x043D, 0x0435, 0x0020, 0x043F, 0x043E, 0x0434, 0x0434, 0x0435, 0x0440, 0x0436, 0x0438, 0x0432, 0x0430, 0x0435, 0x0442, 0x0441, 0x044F, 0x0021, 0x0020, 0x042D, 0x0442, 0x043E, 0x0020, 0x043C, 0x043E, 0x0436, 0x0435, 0x0442, 0x0020, 0x043F, 0x0440, 0x0438, 0x0432, 0x0435, 0x0441, 0x0442, 0x0438, 0x0020, 0x043A, 0x0020, 0x043D, 0x0435, 0x043F, 0x0440, 0x0435, 0x0434, 0x0441, 0x043A, 0x0430, 0x0437, 0x0443, 0x0435, 0x043C, 0x043E, 0x043C, 0x0443, 0x0020, 0x043F, 0x043E, 0x0432, 0x0435, 0x0434, 0x0435, 0x043D, 0x0438, 0x044E, 0x0020, 0x0438, 0x0020, 0x0437, 0x0430, 0x0432, 0x0438, 0x0441, 0x0430, 0x043D, 0x0438, 0x044E, 0x0020, 0x0438, 0x0433, 0x0440, 0x044B, 0x002E, 0x0020, 0x0414, 0x043B, 0x044F, 0x0020, 0x043F, 0x043E, 0x043B, 0x0443, 0x0447, 0x0435, 0x043D, 0x0438, 0x044F, 0x0020, 0x0438, 0x043D, 0x0444, 0x043E, 0x0440, 0x043C, 0x0430, 0x0446, 0x0438, 0x0438, 0x0020, 0x043E, 0x0020, 0x0441, 0x0438, 0x0441, 0x0442, 0x0435, 0x043C, 0x043D, 0x044B, 0x0445, 0x0020, 0x0442, 0x0440, 0x0435, 0x0431, 0x043E, 0x0432, 0x0430, 0x043D, 0x0438, 0x044F, 0x0445, 0x0020, 0x043E, 0x0431, 0x0440, 0x0430, 0x0442, 0x0438, 0x0442, 0x0435, 0x0441, 0x044C, 0x0020, 0x043A, 0x0020, 0x0440, 0x0443, 0x043A, 0x043E, 0x0432, 0x043E, 0x0434, 0x0441, 0x0442, 0x0432, 0x0443, 0x0020, 0x043F, 0x043E, 0x043B, 0x044C, 0x0437, 0x043E, 0x0432, 0x0430, 0x0442, 0x0435, 0x043B, 0x044F, 0x002E, 0x000A, 0x000A, 0x0022, 0x0025, 0x0053, 0x0022, 0x0020, 0x005B, 0x0076, 0x0065, 0x006E, 0x0064, 0x006F, 0x0072, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x002C, 0x0020, 0x0064, 0x0065, 0x0076, 0x0069, 0x0063, 0x0065, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x005D, 0};
pFmt = fmt;
break;
}
case 0x1f: // Turkish
{
static const wchar_t fmt[] = {0x0044, 0x0065, 0x0073, 0x0074, 0x0065, 0x006B, 0x006C, 0x0065, 0x006E, 0x006D, 0x0065, 0x0079, 0x0065, 0x006E, 0x0020, 0x0062, 0x0069, 0x0072, 0x0020, 0x0065, 0x006B, 0x0072, 0x0061, 0x006E, 0x0020, 0x006B, 0x0061, 0x0072, 0x0074, 0x0131, 0x0020, 0x0061, 0x006C, 0x0067, 0x0131, 0x006C, 0x0061, 0x006E, 0x0064, 0x0131, 0x0021, 0x0020, 0x0044, 0x0065, 0x0076, 0x0061, 0x006D, 0x0020, 0x0065, 0x0074, 0x006D, 0x0065, 0x006B, 0x0020, 0x0062, 0x0065, 0x006B, 0x006C, 0x0065, 0x006E, 0x006D, 0x0065, 0x0064, 0x0069, 0x006B, 0x0020, 0x0073, 0x006F, 0x006E, 0x0075, 0x00E7, 0x006C, 0x0061, 0x0072, 0x0061, 0x0020, 0x0076, 0x0065, 0x0020, 0x00E7, 0x00F6, 0x006B, 0x006D, 0x0065, 0x006C, 0x0065, 0x0072, 0x0065, 0x0020, 0x0079, 0x006F, 0x006C, 0x0020, 0x0061, 0x00E7, 0x0061, 0x0062, 0x0069, 0x006C, 0x0069, 0x0072, 0x002E, 0x0020, 0x0044, 0x006F, 0x006E, 0x0061, 0x006E, 0x0131, 0x006D, 0x0020, 0x0067, 0x0065, 0x0072, 0x0065, 0x006B, 0x006C, 0x0069, 0x006C, 0x0069, 0x006B, 0x006C, 0x0065, 0x0072, 0x0069, 0x0020, 0x0069, 0x00E7, 0x0069, 0x006E, 0x0020, 0x006C, 0x00FC, 0x0074, 0x0066, 0x0065, 0x006E, 0x0020, 0x0072, 0x0065, 0x0068, 0x0062, 0x0065, 0x0072, 0x0069, 0x006E, 0x0069, 0x007A, 0x0065, 0x0020, 0x0062, 0x0061, 0x015F, 0x0076, 0x0075, 0x0072, 0x0075, 0x006E, 0x002E, 0x000A, 0x000A, 0x0022, 0x0025, 0x0053, 0x0022, 0x0020, 0x005B, 0x0076, 0x0065, 0x006E, 0x0064, 0x006F, 0x0072, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x002C, 0x0020, 0x0064, 0x0065, 0x0076, 0x0069, 0x0063, 0x0065, 0x0020, 0x0069, 0x0064, 0x0020, 0x003D, 0x0020, 0x0030, 0x0078, 0x0025, 0x002E, 0x0034, 0x0078, 0x005D, 0};
pFmt = fmt;
break;
}
case 0x09: // English
default:
break;
}
wchar_t msg[1024];
msg[0] = L'\0';
msg[sizeof(msg) / sizeof(msg[0]) - 1] = L'\0';
azsnwprintf(msg, sizeof(msg) / sizeof(msg[0]) - 1, pFmt, gpuName, gpuVendorId, gpuDeviceId);
return msg;
}
#endif
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
bool CSystem::InitConsole()
@@ -1598,9 +1509,6 @@ AZ_POP_DISABLE_WARNING
LoadConfiguration("client.cfg", &CVarsClientConfigSink);
}
//Connect to the render bus
AZ::RenderNotificationsBus::Handler::BusConnect();
// Send out EBus event
EBUS_EVENT(CrySystemEventBus, OnCrySystemInitialized, *this, startupParams);
-14
View File
@@ -534,20 +534,6 @@ void CView::SetFrameAdditiveCameraAngles(const Ang3& addFrameAngles)
m_frameAdditiveAngles = addFrameAngles;
}
void CView::GetMemoryUsage(ICrySizer* s) const
{
s->AddObject(this, sizeof(*this));
s->AddObject(m_shakes);
}
//void CView::Serialize(TSerialize ser)
//{
// if (ser.IsReading())
// {
// ResetShaking();
// }
//}
void CView::PostSerialize()
{
}
-4
View File
@@ -81,8 +81,6 @@ public:
ID = shakeID;
}
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const { /*nothing*/}
};
@@ -111,8 +109,6 @@ public:
CCamera& GetCamera() override { return m_camera; }
const CCamera& GetCamera() const override { return m_camera; }
void GetMemoryUsage(ICrySizer* s) const;
protected:
void ProcessShakeNormal(SShake* pShake, float frameTime);
@@ -610,24 +610,6 @@ void CViewSystem::DebugDraw()
}
//////////////////////////////////////////////////////////////////////////
void CViewSystem::GetMemoryUsage(ICrySizer* s) const
{
SIZER_SUBCOMPONENT_NAME(s, "ViewSystem");
s->Add(*this);
s->AddContainer(m_views);
}
//void CViewSystem::Serialize(TSerialize ser)
//{
// TViewMap::iterator iter = m_views.begin();
// TViewMap::iterator iterEnd = m_views.end();
// while (iter != iterEnd)
// {
// iter->second->Serialize(ser);
// ++iter;
// }
//}
void CViewSystem::PostSerialize()
{
TViewMap::iterator iter = m_views.begin();
@@ -105,8 +105,6 @@ public:
return stl::find_and_erase(m_listeners, pListener);
}
void GetMemoryUsage(ICrySizer* s) const;
void ClearAllViews();
private:
+15 -83
View File
@@ -32,6 +32,19 @@
#include <LyShine/Bus/UiCursorBus.h>
//#define DEFENCE_CVAR_HASH_LOGGING
// s should point to a buffer at least 65 chars long
inline void BitsAlpha64(uint64 n, char* s)
{
for (int i = 0; n != 0; n >>= 1, i++)
{
if (n & 1)
{
*s++ = i < 32 ? static_cast<char>(i + 'z' - 31) : static_cast<char>(i + 'Z' - 63);
}
}
*s++ = '\0';
}
static inline void AssertName([[maybe_unused]] const char* szName)
{
#ifdef _DEBUG
@@ -376,12 +389,12 @@ void CXConsole::LogChangeMessage(const char* name, const bool isConst, const boo
if (allowChange)
{
gEnv->pLog->LogWarning(logMessage.c_str());
gEnv->pLog->LogWarning("%s", logMessage.c_str());
gEnv->pLog->LogWarning("Modifying marked variables will not be allowed in Release mode!");
}
else
{
gEnv->pLog->LogError(logMessage.c_str());
gEnv->pLog->LogError("%s", logMessage.c_str());
}
}
@@ -567,35 +580,6 @@ ICVar* CXConsole::Register(const char* sName, int* src, int iValue, int nFlags,
}
//////////////////////////////////////////////////////////////////////////
ICVar* CXConsole::RegisterCVarGroup(const char* szName, const char* szFileName)
{
AssertName(szName);
assert(szFileName);
// suppress cvars not starting with sys_spec_ as
// cheaters might create cvars before we created ours
if (_strnicmp(szName, "sys_spec_", 9) != 0)
{
return 0;
}
ICVar* pCVar = stl::find_in_map(m_mapVariables, szName, NULL);
if (pCVar)
{
AZ_Error("System", false, "CVar groups should only be registered once");
return pCVar;
}
CXConsoleVariableCVarGroup* pCVarGroup = new CXConsoleVariableCVarGroup(this, szName, szFileName, VF_COPYNAME);
pCVar = pCVarGroup;
RegisterVar(pCVar, CXConsoleVariableCVarGroup::OnCVarChangeFunc);
return pCVar;
}
//////////////////////////////////////////////////////////////////////////
ICVar* CXConsole::Register(const char* sName, float* src, float fValue, int nFlags, const char* help, ConsoleVarFunc pChangeFunc, bool allowModify)
{
@@ -620,7 +604,6 @@ ICVar* CXConsole::Register(const char* sName, float* src, float fValue, int nFla
return pCVar;
}
//////////////////////////////////////////////////////////////////////////
ICVar* CXConsole::Register(const char* sName, const char** src, const char* defaultValue, int nFlags, const char* help, ConsoleVarFunc pChangeFunc, bool allowModify)
{
@@ -644,7 +627,6 @@ ICVar* CXConsole::Register(const char* sName, const char** src, const char* defa
return pCVar;
}
//////////////////////////////////////////////////////////////////////////
ICVar* CXConsole::RegisterString(const char* sName, const char* sValue, int nFlags, const char* help, ConsoleVarFunc pChangeFunc)
{
@@ -705,30 +687,6 @@ ICVar* CXConsole::RegisterInt(const char* sName, int iValue, int nFlags, const c
return pCVar;
}
//////////////////////////////////////////////////////////////////////////
ICVar* CXConsole::RegisterInt64(const char* sName, int64 iValue, int nFlags, const char* help, ConsoleVarFunc pChangeFunc)
{
AssertName(sName);
ICVar* pCVar = stl::find_in_map(m_mapVariables, sName, NULL);
if (pCVar)
{
gEnv->pLog->Log("[CVARS]: [DUPLICATE] CXConsole::RegisterInt64(): variable [%s] is already registered", pCVar->GetName());
#if LOG_CVAR_INFRACTIONS_CALLSTACK
gEnv->pSystem->debug_LogCallStack();
#endif // LOG_CVAR_INFRACTIONS_CALLSTACK
return pCVar;
}
pCVar = new CXConsoleVariableInt64(this, sName, iValue, nFlags, help);
RegisterVar(pCVar, pChangeFunc);
return pCVar;
}
//////////////////////////////////////////////////////////////////////////
void CXConsole::UnregisterVariable(const char* sVarName, [[maybe_unused]] bool bDelete)
{
@@ -2891,20 +2849,6 @@ int CXConsole::GetNumVisibleVars()
return numVars;
}
void CXConsole::AddCVarsToHash(ConsoleVariablesVector::const_iterator begin, ConsoleVariablesVector::const_iterator end, CCrc32& runningNameCrc32, CCrc32& runningNameValueCrc32)
{
for (ConsoleVariablesVector::const_iterator it = begin; it <= end; ++it)
{
// add name & variable to string. We add both since adding only the value could cause
// many collisions with variables all having value 0 or all 1.
AZStd::string hashStr = it->first;
runningNameCrc32.Add(hashStr.c_str(), hashStr.length());
hashStr += it->second->GetDataProbeString();
runningNameValueCrc32.Add(hashStr.c_str(), hashStr.length());
}
}
//////////////////////////////////////////////////////////////////////////
size_t CXConsole::GetSortedVars(AZStd::vector<AZStd::string_view>& pszArray, const char* szPrefix)
{
@@ -3089,18 +3033,6 @@ inline size_t sizeOf (const char* sz)
return sz ? strlen(sz) + 1 : 0;
}
//////////////////////////////////////////////////////////////////////////
void CXConsole::GetMemoryUsage (class ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(m_sInputBuffer);
pSizer->AddObject(m_sPrevTab);
pSizer->AddObject(m_dqConsoleBuffer);
pSizer->AddObject(m_dqHistory);
pSizer->AddObject(m_mapCommands);
pSizer->AddObject(m_mapBinds);
}
//////////////////////////////////////////////////////////////////////////
void CXConsole::ConsoleLogInputResponse(const char* format, ...)
{
+14 -26
View File
@@ -13,8 +13,8 @@
#pragma once
#include <IConsole.h>
#include <CryCrc32.h>
#include "Timer.h"
#include <CryCommon/StlUtils.h>
#include <AzFramework/Components/ConsoleBus.h>
#include <AzFramework/CommandLine/CommandRegistrationBus.h>
@@ -22,10 +22,12 @@
#include <AzFramework/Input/Events/InputChannelEventListener.h>
#include <AzFramework/Input/Events/InputTextEventListener.h>
#include <list>
#include <map>
//forward declaration
struct INetwork;
class CSystem;
struct IFFont;
#define MAX_HISTORY_ENTRIES 50
#define LINE_BORDER 10
@@ -53,12 +55,6 @@ struct CConsoleCommand
: m_func(nullptr)
, m_nFlags(0) {}
size_t sizeofThis () const {return sizeof(*this) + m_sName.capacity() + 1 + m_sCommand.capacity() + 1; }
void GetMemoryUsage (class ICrySizer* pSizer) const
{
pSizer->AddObject(m_sName);
pSizer->AddObject(m_sCommand);
pSizer->AddObject(m_sHelp);
}
};
//////////////////////////////////////////////////////////////////////////
@@ -139,14 +135,12 @@ public:
void Release() override;
void Init(ISystem* pSystem) override;
ICVar* RegisterString(const char* sName, const char* sValue, int nFlags, const char* help = "", ConsoleVarFunc pChangeFunc = nullptr) override;
ICVar* RegisterInt(const char* sName, int iValue, int nFlags, const char* help = "", ConsoleVarFunc pChangeFunc = nullptr) override;
ICVar* RegisterInt64(const char* sName, int64 iValue, int nFlags, const char* help = "", ConsoleVarFunc pChangeFunc = nullptr) override;
ICVar* RegisterFloat(const char* sName, float fValue, int nFlags, const char* help = "", ConsoleVarFunc pChangeFunc = nullptr) override;
ICVar* Register(const char* name, float* src, float defaultvalue, int flags = 0, const char* help = "", ConsoleVarFunc pChangeFunc = nullptr, bool allowModify = true) override;
ICVar* Register(const char* name, int* src, int defaultvalue, int flags = 0, const char* help = "", ConsoleVarFunc pChangeFunc = nullptr, bool allowModify = true) override;
ICVar* Register(const char* name, const char** src, const char* defaultvalue, int flags = 0, const char* help = "", ConsoleVarFunc pChangeFunc = nullptr, bool allowModify = true) override;
ICVar* Register(ICVar* pVar) override { RegisterVar(pVar); return pVar; }
ICVar* RegisterString(const char* sName, const char* sValue, int nFlags, const char* help = "", ConsoleVarFunc pChangeFunc = 0) override;
ICVar* RegisterInt(const char* sName, int iValue, int nFlags, const char* help = "", ConsoleVarFunc pChangeFunc = 0) override;
ICVar* RegisterFloat(const char* sName, float fValue, int nFlags, const char* help = "", ConsoleVarFunc pChangeFunc = 0) override;
ICVar* Register(const char* name, float* src, float defaultvalue, int flags = 0, const char* help = "", ConsoleVarFunc pChangeFunc = 0, bool allowModify = true) override;
ICVar* Register(const char* name, int* src, int defaultvalue, int flags = 0, const char* help = "", ConsoleVarFunc pChangeFunc = 0, bool allowModify = true) override;
ICVar* Register(const char* name, const char** src, const char* defaultvalue, int flags = 0, const char* help = "", ConsoleVarFunc pChangeFunc = 0, bool allowModify = true) override;
void UnregisterVariable(const char* sVarName, bool bDelete = false) override;
void SetScrollMax(int value) override;
@@ -171,8 +165,8 @@ public:
void Clear() override;
void Update() override;
void Draw() override;
bool AddCommand(const char* sCommand, ConsoleCommandFunc func, int nFlags = 0, const char* sHelp = nullptr) override;
bool AddCommand(const char* sName, const char* sScriptFunc, int nFlags = 0, const char* sHelp = nullptr) override;
bool AddCommand(const char* sCommand, ConsoleCommandFunc func, int nFlags = 0, const char* sHelp = NULL) override;
bool AddCommand(const char* sName, const char* sScriptFunc, int nFlags = 0, const char* sHelp = NULL) override;
void RemoveCommand(const char* sName) override;
void ExecuteString(const char* command, bool bSilentMode, bool bDeferExecution = false) override;
void ExecuteConsoleCommand(const char* command) override;
@@ -181,15 +175,14 @@ public:
bool IsOpened() override;
int GetNumVars() override;
int GetNumVisibleVars() override;
size_t GetSortedVars(AZStd::vector<AZStd::string_view>& pszArray, const char* szPrefix = nullptr) override;
virtual void FindVar(const char* substr);
size_t GetSortedVars(AZStd::vector<AZStd::string_view>& pszArray, const char* szPrefix = 0) override;
void FindVar(const char* substr);
const char* AutoComplete(const char* substr) override;
const char* AutoCompletePrev(const char* substr) override;
const char* ProcessCompletion(const char* szInputBuffer) override;
void RegisterAutoComplete(const char* sVarOrCommand, IConsoleArgumentAutoComplete* pArgAutoComplete) override;
void UnRegisterAutoComplete(const char* sVarOrCommand) override;
void ResetAutoCompletion() override;
void GetMemoryUsage (ICrySizer* pSizer) const override;
void ResetProgressBar(int nProgressRange) override;
void TickProgressBar() override;
void SetLoadingImage(const char* szFilename) override;
@@ -222,10 +215,6 @@ public:
//////////////////////////////////////////////////////////////////////////
// Returns
// 0 if the operation failed
ICVar* RegisterCVarGroup(const char* sName, const char* szFileName);
void SetProcessingGroup(bool isGroup) { m_bIsProcessingGroup = isGroup; }
bool GetIsProcessingGroup() const { return m_bIsProcessingGroup; }
@@ -290,7 +279,6 @@ private: // ----------------------------------------------------------
void AddCheckedCVar(ConsoleVariablesVector& vector, const ConsoleVariablesVector::value_type& value);
void RemoveCheckedCVar(ConsoleVariablesVector& vector, const ConsoleVariablesVector::value_type& value);
static void AddCVarsToHash(ConsoleVariablesVector::const_iterator begin, ConsoleVariablesVector::const_iterator end, CCrc32& runningNameCrc32, CCrc32& runningNameValueCrc32);
static bool CVarNameLess(const std::pair<const char*, ICVar*>& lhs, const std::pair<const char*, ICVar*>& rhs);
void PostLine(const char* lineOfText, size_t len);
+355 -489
View File
@@ -6,10 +6,8 @@
*
*/
// Description : implementation of the CXConsoleVariable class.
#include "CrySystem_precompiled.h"
#include "XConsole.h"
#include "XConsoleVariable.h"
@@ -19,6 +17,87 @@
#include <algorithm>
namespace
{
using stack_string = AZStd::fixed_string<512>;
uint64 AlphaBit64(char c)
{
return (c >= 'a' && c <= 'z' ? 1U << (c - 'z' + 31) : 0) |
(c >= 'A' && c <= 'Z' ? 1LL << (c - 'Z' + 63) : 0);
}
int64 TextToInt64(const char* s, int64 nCurrent, bool bBitfield)
{
int64 nValue = 0;
if (s)
{
char* e;
if (bBitfield)
{
// Bit manipulation.
if (*s == '^')
// Bit number
#if defined(_MSC_VER)
{
nValue = 1LL << _strtoi64(++s, &e, 10);
}
#else
{
nValue = 1LL << strtoll(++s, &e, 10);
}
#endif
else
// Full number
#if defined(_MSC_VER)
{
nValue = _strtoi64(s, &e, 10);
}
#else
{
nValue = strtoll(s, &e, 10);
}
#endif
// Check letter codes.
for (; (*e >= 'a' && *e <= 'z') || (*e >= 'A' && *e <= 'Z'); e++)
{
nValue |= AlphaBit64(*e);
}
if (*e == '+')
{
nValue = nCurrent | nValue;
}
else if (*e == '-')
{
nValue = nCurrent & ~nValue;
}
else if (*e == '^')
{
nValue = nCurrent ^ nValue;
}
}
else
#if defined(_MSC_VER)
{
nValue = _strtoi64(s, &e, 10);
}
#else
{
nValue = strtoll(s, &e, 10);
}
#endif
}
return nValue;
}
int TextToInt(const char* s, int nCurrent, bool bBitfield)
{
return (int)TextToInt64(s, nCurrent, bBitfield);
}
} // namespace
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
@@ -53,7 +132,6 @@ CXConsoleVariableBase::CXConsoleVariableBase(CXConsole* pConsole, const char* sN
}
}
//////////////////////////////////////////////////////////////////////////
CXConsoleVariableBase::~CXConsoleVariableBase()
{
@@ -78,10 +156,8 @@ void CXConsoleVariableBase::ForceSet(const char* s)
m_nFlags |= oldFlags;
}
//////////////////////////////////////////////////////////////////////////
void CXConsoleVariableBase::ClearFlags (int flags)
void CXConsoleVariableBase::ClearFlags(int flags)
{
m_nFlags &= ~flags;
}
@@ -121,7 +197,7 @@ void CXConsoleVariableBase::SetOnChangeCallback(ConsoleVarFunc pChangeFunc)
m_pChangeFunc = pChangeFunc;
}
uint64 CXConsoleVariableBase::AddOnChangeFunctor(const SFunctor& pChangeFunctor)
uint64 CXConsoleVariableBase::AddOnChangeFunctor(const AZStd::function<void()>& pChangeFunctor)
{
static int uniqueIdGenerator = 0;
int newId = uniqueIdGenerator++;
@@ -144,7 +220,7 @@ void CXConsoleVariableBase::CallOnChangeFunctions()
const size_t nTotal(m_changeFunctors.size());
for (size_t nCount = 0; nCount < nTotal; ++nCount)
{
m_changeFunctors[nCount].second.Call();
m_changeFunctors[nCount].second();
}
}
@@ -168,535 +244,325 @@ bool CXConsoleVariableBase::HasCustomLimits()
return m_hasCustomLimits;
}
void CXConsoleVariableCVarGroup::OnLoadConfigurationEntry(const char* szKey, const char* szValue, const char* szGroup)
const char* CXConsoleVariableBase::GetDataProbeString() const
{
assert(szGroup);
assert(szKey);
assert(szValue);
bool bCheckIfInDefault = false;
SCVarGroup* pGrp = 0;
if (azstricmp(szGroup, "default") == 0) // needs to be before the other groups
if (gEnv->IsDedicated() && m_pDataProbeString)
{
pGrp = &m_CVarGroupDefault;
// if(azstricmp(GetName(),szKey)==0)
if (*szKey == 0)
{
m_sDefaultValue = szValue;
int iGrpValue = atoi(szValue);
// if default state is not part of the mentioned states generate this state, so GetIRealVal() can return this state as well
if (m_CVarGroupStates.find(iGrpValue) == m_CVarGroupStates.end())
{
m_CVarGroupStates[iGrpValue] = new SCVarGroup;
}
return;
}
}
else
{
int iGrp;
if (azsscanf(szGroup, "%d", &iGrp) == 1)
{
if (m_CVarGroupStates.find(iGrp) == m_CVarGroupStates.end())
{
m_CVarGroupStates[iGrp] = new SCVarGroup;
}
pGrp = m_CVarGroupStates[iGrp];
}
else
{
gEnv->pLog->LogError("[CVARS]: [MISSING] [%s] is not a registered console variable group", szGroup);
#if LOG_CVAR_INFRACTIONS_CALLSTACK
gEnv->pSystem->debug_LogCallStack();
#endif // LOG_CVAR_INFRACTIONS_CALLSTACK
return;
}
if (*szKey == 0)
{
assert(0); // =%d only expected in default section
return;
}
}
if (pGrp)
{
if (pGrp->m_KeyValuePair.find(szKey) != pGrp->m_KeyValuePair.end())
{
gEnv->pLog->LogError("[CVARS]: [DUPLICATE] [%s] specified multiple times in console variable group [%s] = [%s]", szKey, GetName(), szGroup);
bCheckIfInDefault = true;
}
pGrp->m_KeyValuePair[szKey] = szValue;
if (bCheckIfInDefault)
{
if (m_CVarGroupDefault.m_KeyValuePair.find(szKey) == m_CVarGroupDefault.m_KeyValuePair.end())
{
gEnv->pLog->LogError("[CVARS]: [MISSING] [%s] specified in console variable group [%s] = [%s], but missing from default group", szKey, GetName(), szGroup);
}
}
return m_pDataProbeString;
}
return GetOwnDataProbeString();
}
void CXConsoleVariableCVarGroup::OnLoadConfigurationEntry_End()
void CXConsoleVariableString::Set(const char* s)
{
if (!m_sDefaultValue.empty())
{
gEnv->pConsole->LoadConfigVar(GetName(), m_sDefaultValue.c_str());
m_sDefaultValue.clear();
}
}
CXConsoleVariableCVarGroup::CXConsoleVariableCVarGroup(CXConsole* pConsole, const char* sName, const char* szFileName, int nFlags)
: CXConsoleVariableInt(pConsole, sName, 0, nFlags, 0)
{
gEnv->pSystem->LoadConfiguration(szFileName, this);
}
AZStd::string CXConsoleVariableCVarGroup::GetDetailedInfo() const
{
AZStd::string sRet = GetName();
sRet += " [";
{
TCVarGroupStateMap::const_iterator it, end = m_CVarGroupStates.end();
for (it = m_CVarGroupStates.begin(); it != end; ++it)
{
if (it != m_CVarGroupStates.begin())
{
sRet += "/";
}
char szNum[10];
azsprintf(szNum, "%d", it->first);
sRet += szNum;
}
}
sRet += "/default] [current]:\n";
std::map<AZStd::string, AZStd::string>::const_iterator it, end = m_CVarGroupDefault.m_KeyValuePair.end();
for (it = m_CVarGroupDefault.m_KeyValuePair.begin(); it != end; ++it)
{
const AZStd::string& rKey = it->first;
sRet += " ... ";
sRet += rKey;
sRet += " = ";
TCVarGroupStateMap::const_iterator it2, end2 = m_CVarGroupStates.end();
for (it2 = m_CVarGroupStates.begin(); it2 != end2; ++it2)
{
sRet += GetValueSpec(rKey, &(it2->first));
sRet += "/";
}
sRet += GetValueSpec(rKey);
ICVar* pCVar = gEnv->pConsole->GetCVar(rKey.c_str());
if (pCVar)
{
sRet += " [";
sRet += pCVar->GetString();
sRet += "]";
}
sRet += "\n";
}
return sRet;
}
const char* CXConsoleVariableCVarGroup::GetHelp()
{
if (m_psHelp)
{
delete m_psHelp;
m_psHelp = NULL;
}
// create help on demand
AZStd::string sRet = "Console variable group to apply settings to multiple variables\n\n";
sRet += GetDetailedInfo();
m_psHelp = new char[sRet.size() + 1];
azstrcpy(m_psHelp, sRet.size() + 1, &sRet[0]);
return m_psHelp;
}
void CXConsoleVariableCVarGroup::DebugLog(const int iExpectedValue, const ICVar::EConsoleLogMode mode) const
{
TCVarGroupStateMap::const_iterator it, end = m_CVarGroupStates.end();
SCVarGroup* pCurrentGrp = 0;
{
TCVarGroupStateMap::const_iterator itCurrentGrp = m_CVarGroupStates.find(iExpectedValue);
if (itCurrentGrp != end)
{
pCurrentGrp = itCurrentGrp->second;
}
}
// try the current state
if (TestCVars(pCurrentGrp, mode))
if (!s)
{
return;
}
if ((m_sValue == s) && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
if (m_pConsole->OnBeforeVarChange(this, s))
{
m_nFlags |= VF_MODIFIED;
{
m_sValue = s;
}
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
int CXConsoleVariableCVarGroup::GetRealIVal() const
void CXConsoleVariableString::Set(float f)
{
TCVarGroupStateMap::const_iterator it, end = m_CVarGroupStates.end();
stack_string s = stack_string::format("%g", f);
int iValue = GetIVal();
SCVarGroup* pCurrentGrp = 0;
if ((m_sValue == s.c_str()) && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
TCVarGroupStateMap::const_iterator itCurrentGrp = m_CVarGroupStates.find(iValue);
if (itCurrentGrp != end)
{
pCurrentGrp = itCurrentGrp->second;
}
return;
}
// first try the current state
if (TestCVars(pCurrentGrp))
{
return iValue;
}
// then all other
for (it = m_CVarGroupStates.begin(); it != end; ++it)
{
SCVarGroup* pLocalGrp = it->second;
if (pLocalGrp == pCurrentGrp)
{
continue;
}
int iLocalState = it->first;
if (TestCVars(pLocalGrp))
{
return iLocalState;
}
}
return -1; // no state found that represent the current one
m_nFlags |= VF_MODIFIED;
Set(s.c_str());
}
void CXConsoleVariableCVarGroup::Set(const int i)
void CXConsoleVariableString::Set(int i)
{
if (i == m_iValue)
stack_string s = stack_string::format("%d", i);
if ((m_sValue == s.c_str()) && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
SCVarGroup* pCurrentGrp = 0;
TCVarGroupStateMap::const_iterator itCurrentGrp = m_CVarGroupStates.find(m_iValue);
if (itCurrentGrp != m_CVarGroupStates.end())
{
pCurrentGrp = itCurrentGrp->second;
}
if (TestCVars(pCurrentGrp))
{
// All cvars in this group match the current state - no further action is necessary
return;
}
return;
}
char sTemp[128];
azsprintf(sTemp, "%d", i);
m_nFlags |= VF_MODIFIED;
Set(s.c_str());
}
bool wasProcessingGroup = m_pConsole->GetIsProcessingGroup();
m_pConsole->SetProcessingGroup(true);
if (m_pConsole->OnBeforeVarChange(this, sTemp))
const char* CXConsoleVariableInt::GetString() const
{
static char szReturnString[256];
sprintf_s(szReturnString, "%d", GetIVal());
return szReturnString;
}
void CXConsoleVariableInt::Set(const char* s)
{
int nValue = TextToInt(s, m_iValue, (m_nFlags & VF_BITFIELD) != 0);
Set(nValue);
}
void CXConsoleVariableInt::Set(float f)
{
Set((int)f);
}
void CXConsoleVariableInt::Set(int i)
{
if (i == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
stack_string s = stack_string::format("%d", i);
if (m_pConsole->OnBeforeVarChange(this, s.c_str()))
{
m_nFlags |= VF_MODIFIED;
m_iValue = i;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
m_pConsole->SetProcessingGroup(wasProcessingGroup);
// Useful for debugging cvar groups
//CryLogAlways("[CVARS]: CXConsoleVariableCVarGroup::Set() Group %s in state %d (wanted %d)", GetName(), m_iValue, i);
}
CXConsoleVariableCVarGroup::~CXConsoleVariableCVarGroup()
const char* CXConsoleVariableIntRef::GetString() const
{
TCVarGroupStateMap::iterator it, end = m_CVarGroupStates.end();
static char szReturnString[256];
for (it = m_CVarGroupStates.begin(); it != end; ++it)
{
SCVarGroup* pGrp = it->second;
delete pGrp;
}
delete m_psHelp;
sprintf_s(szReturnString, "%d", m_iValue);
return szReturnString;
}
void CXConsoleVariableCVarGroup::OnCVarChangeFunc(ICVar* pVar)
void CXConsoleVariableIntRef::Set(const char* s)
{
CXConsoleVariableCVarGroup* pThis = (CXConsoleVariableCVarGroup*)pVar;
int iValue = pThis->GetIVal();
TCVarGroupStateMap::const_iterator itGrp = pThis->m_CVarGroupStates.find(iValue);
SCVarGroup* pGrp = 0;
if (itGrp != pThis->m_CVarGroupStates.end())
int nValue = TextToInt(s, m_iValue, (m_nFlags & VF_BITFIELD) != 0);
if (nValue == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
pGrp = itGrp->second;
return;
}
if (pGrp)
if (m_pConsole->OnBeforeVarChange(this, s))
{
pThis->ApplyCVars(*pGrp);
}
m_nFlags |= VF_MODIFIED;
m_iValue = nValue;
pThis->ApplyCVars(pThis->m_CVarGroupDefault, pGrp);
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
bool CXConsoleVariableCVarGroup::TestCVars(const SCVarGroup* pGroup, const ICVar::EConsoleLogMode mode) const
void CXConsoleVariableIntRef::Set(float f)
{
if (pGroup)
if ((int)f == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
if (!TestCVars(*pGroup, mode))
return;
}
char sTemp[128];
sprintf_s(sTemp, "%g", f);
if (m_pConsole->OnBeforeVarChange(this, sTemp))
{
m_nFlags |= VF_MODIFIED;
m_iValue = (int)f;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
void CXConsoleVariableIntRef::Set(int i)
{
if (i == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
char sTemp[128];
sprintf_s(sTemp, "%d", i);
if (m_pConsole->OnBeforeVarChange(this, sTemp))
{
m_nFlags |= VF_MODIFIED;
m_iValue = i;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
const char* CXConsoleVariableFloat::GetString() const
{
static char szReturnString[256];
sprintf_s(szReturnString, "%g", m_fValue); // %g -> "2.01", %f -> "2.01000"
return szReturnString;
}
void CXConsoleVariableFloat::Set(const char* s)
{
float fValue = 0;
if (s)
{
fValue = (float)atof(s);
}
if (fValue == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
if (m_pConsole->OnBeforeVarChange(this, s))
{
m_nFlags |= VF_MODIFIED;
m_fValue = fValue;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
void CXConsoleVariableFloat::Set(float f)
{
if (f == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
stack_string s = stack_string::format("%g", f);
if (m_pConsole->OnBeforeVarChange(this, s.c_str()))
{
m_nFlags |= VF_MODIFIED;
m_fValue = f;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
void CXConsoleVariableFloat::Set(int i)
{
if ((float)i == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
char sTemp[128];
sprintf_s(sTemp, "%d", i);
if (m_pConsole->OnBeforeVarChange(this, sTemp))
{
m_nFlags |= VF_MODIFIED;
m_fValue = (float)i;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
const char* CXConsoleVariableFloatRef::GetString() const
{
static char szReturnString[256];
sprintf_s(szReturnString, "%g", m_fValue);
return szReturnString;
}
void CXConsoleVariableFloatRef::Set(const char *s)
{
float fValue = 0;
if (s)
{
fValue = (float)atof(s);
}
if (fValue == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
if (m_pConsole->OnBeforeVarChange(this, s))
{
m_nFlags |= VF_MODIFIED;
m_fValue = fValue;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
void CXConsoleVariableFloatRef::Set(float f)
{
if (f == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
char sTemp[128];
sprintf_s(sTemp, "%g", f);
if (m_pConsole->OnBeforeVarChange(this, sTemp))
{
m_nFlags |= VF_MODIFIED;
m_fValue = f;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
void CXConsoleVariableFloatRef::Set(int i)
{
if ((float)i == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
char sTemp[128];
sprintf_s(sTemp, "%d", i);
if (m_pConsole->OnBeforeVarChange(this, sTemp))
{
m_nFlags |= VF_MODIFIED;
m_fValue = (float)i;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
void CXConsoleVariableStringRef::Set(const char *s)
{
if ((m_sValue == s) && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
if (m_pConsole->OnBeforeVarChange(this, s))
{
m_nFlags |= VF_MODIFIED;
{
return false;
}
}
if (!TestCVars(m_CVarGroupDefault, mode, pGroup))
{
return false;
}
return true;
}
bool CXConsoleVariableCVarGroup::TestCVars(const SCVarGroup& rGroup, const ICVar::EConsoleLogMode mode, const SCVarGroup* pExclude) const
{
bool bRet = true;
std::map<AZStd::string, AZStd::string>::const_iterator it, end = rGroup.m_KeyValuePair.end();
for (it = rGroup.m_KeyValuePair.begin(); it != end; ++it)
{
const AZStd::string& rKey = it->first;
const AZStd::string& rValue = it->second;
if (pExclude)
{
if (pExclude->m_KeyValuePair.find(rKey) != pExclude->m_KeyValuePair.end())
{
continue;
}
m_sValue = s;
m_userPtr = m_sValue.c_str();
}
ICVar* pVar = gEnv->pConsole->GetCVar(rKey.c_str());
if (pVar)
{
if (pVar->GetFlags() & VF_CVARGRP_IGNOREINREALVAL) // Ignore the cvars which change often and shouldn't be used to determine state
{
continue;
}
bool bOk = true;
// compare exact type,
// simple string comparison would fail on some comparisons e.g. 2.0 == 2
// and GetString() for int and float return pointer to shared array so this
// can cause problems
switch (pVar->GetType())
{
case CVAR_INT:
{
int iVal;
if (azsscanf(rValue.c_str(), "%d", &iVal) == 1)
{
if (pVar->GetIVal() != atoi(rValue.c_str()))
{
bOk = false;
break;
}
}
if (pVar->GetIVal() != pVar->GetRealIVal())
{
bOk = false;
break;
}
}
break;
case CVAR_FLOAT:
{
float fVal;
if (azsscanf(rValue.c_str(), "%f", &fVal) == 1)
{
if (pVar->GetFVal() != fVal)
{
bOk = false;
break;
}
}
}
break;
case CVAR_STRING:
if (rValue != pVar->GetString())
{
bOk = false;
break;
}
break;
default:
assert(0);
}
if (!bOk)
{
if (mode == ICVar::eCLM_Off)
{
return false; // exit as early as possible
}
bRet = false; // exit with same return code but log all differences
if (strcmp(pVar->GetString(), rValue.c_str()) != 0)
{
switch (mode)
{
case ICVar::eCLM_ConsoleAndFile:
CryLog("[CVARS]: $3[FAIL] [%s] = $6[%s] $4(expected [%s] in group [%s] = [%s])", rKey.c_str(), pVar->GetString(), rValue.c_str(), GetName(), GetString());
break;
case ICVar::eCLM_FileOnly:
case ICVar::eCLM_FullInfo:
gEnv->pLog->LogToFile("[CVARS]: [FAIL] [%s] = [%s] (expected [%s] in group [%s] = [%s])", rKey.c_str(), pVar->GetString(), rValue.c_str(), GetName(), GetString());
break;
default:
assert(0);
}
}
else if (mode == ICVar::eCLM_FullInfo)
{
gEnv->pLog->LogToFile("[CVARS]: [FAIL] [%s] = [%s] (expected [%s] in group [%s] = [%s])", rKey.c_str(), pVar->GetString(), rValue.c_str(), GetName(), GetString());
}
pVar->DebugLog(pVar->GetIVal(), mode); // recursion
}
if (pVar->GetFlags() & (VF_CHEAT | VF_CHEAT_ALWAYS_CHECK | VF_CHEAT_NOCHECK))
{
// either VF_CHEAT should be removed or the var should be not part of the CVarGroup
gEnv->pLog->LogError("[CVARS]: [%s] is cheat protected; referenced in console variable group [%s] = [%s] ", rKey.c_str(), GetName(), GetString());
}
}
else
{
// Do not warn about D3D registered cvars, which carry the prefix "q_", as they are not actually registered with the cvar system.
if (strcmp(rKey.c_str(), "q") == -1)
{
gEnv->pLog->LogError("[CVARS]: [MISSING] [%s] is not a registered console variable; referenced when testing console variable group [%s] = [%s]", rKey.c_str(), GetName(), GetString());
}
}
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
return bRet;
}
AZStd::string CXConsoleVariableCVarGroup::GetValueSpec(const AZStd::string& sKey, const int* pSpec) const
{
if (pSpec)
{
TCVarGroupStateMap::const_iterator itGrp = m_CVarGroupStates.find(*pSpec);
if (itGrp != m_CVarGroupStates.end())
{
const SCVarGroup* pGrp = itGrp->second;
// check in spec
std::map<AZStd::string, AZStd::string>::const_iterator it = pGrp->m_KeyValuePair.find(sKey);
if (it != pGrp->m_KeyValuePair.end())
{
return it->second;
}
}
}
// check in default
std::map<AZStd::string, AZStd::string>::const_iterator it = m_CVarGroupDefault.m_KeyValuePair.find(sKey);
if (it != m_CVarGroupDefault.m_KeyValuePair.end())
{
return it->second;
}
assert(0); // internal error
return "";
}
void CXConsoleVariableCVarGroup::ApplyCVars(const SCVarGroup& rGroup, const SCVarGroup* pExclude)
{
std::map<AZStd::string, AZStd::string>::const_iterator it, end = rGroup.m_KeyValuePair.end();
bool wasProcessingGroup = m_pConsole->GetIsProcessingGroup();
m_pConsole->SetProcessingGroup(true);
for (it = rGroup.m_KeyValuePair.begin(); it != end; ++it)
{
const AZStd::string& rKey = it->first;
if (pExclude)
{
if (pExclude->m_KeyValuePair.find(rKey) != pExclude->m_KeyValuePair.end())
{
continue;
}
}
// Useful for debugging cvar groups
//CryLogAlways("[CVARS]: [APPLY] ([%s]) [%s] = [%s]", GetName(), rKey.c_str(), it->second.c_str());
m_pConsole->LoadConfigVar(rKey.c_str(), it->second.c_str());
}
m_pConsole->SetProcessingGroup(wasProcessingGroup);
}
+62 -582
View File
@@ -6,86 +6,13 @@
*
*/
#ifndef CRYINCLUDE_CRYSYSTEM_XCONSOLEVARIABLE_H
#define CRYINCLUDE_CRYSYSTEM_XCONSOLEVARIABLE_H
#pragma once
#include <IConsole.h>
#include <ISystem.h>
#include "BitFiddling.h"
#include "SFunctor.h"
#include <AzCore/std/function/function_template.h>
class CXConsole;
using stack_string = AZStd::fixed_string<512>;
inline int64 TextToInt64(const char* s, int64 nCurrent, bool bBitfield)
{
int64 nValue = 0;
if (s)
{
char* e;
if (bBitfield)
{
// Bit manipulation.
if (*s == '^')
// Bit number
#if defined(_MSC_VER)
{
nValue = 1LL << _strtoi64(++s, &e, 10);
}
#else
{
nValue = 1LL << strtoll(++s, &e, 10);
}
#endif
else
// Full number
#if defined(_MSC_VER)
{
nValue = _strtoi64(s, &e, 10);
}
#else
{
nValue = strtoll(s, &e, 10);
}
#endif
// Check letter codes.
for (; (*e >= 'a' && *e <= 'z') || (*e >= 'A' && *e <= 'Z'); e++)
{
nValue |= AlphaBit64(*e);
}
if (*e == '+')
{
nValue = nCurrent | nValue;
}
else if (*e == '-')
{
nValue = nCurrent & ~nValue;
}
else if (*e == '^')
{
nValue = nCurrent ^ nValue;
}
}
else
#if defined(_MSC_VER)
{
nValue = _strtoi64(s, &e, 10);
}
#else
{
nValue = strtoll(s, &e, 10);
}
#endif
}
return nValue;
}
inline int TextToInt(const char* s, int nCurrent, bool bBitfield)
{
return (int)TextToInt64(s, nCurrent, bBitfield);
}
class CXConsoleVariableBase
: public ICVar
@@ -107,7 +34,7 @@ public:
void Release() override;
void ForceSet(const char* s) override;
void SetOnChangeCallback(ConsoleVarFunc pChangeFunc) override;
uint64 AddOnChangeFunctor(const SFunctor& pChangeFunctor) override;
virtual uint64 AddOnChangeFunctor(const SFunctor& pChangeFunctor) override;
ConsoleVarFunc GetOnChangeCallback() const override;
bool ShouldReset() const { return (m_nFlags & VF_RESETTABLE) != 0; }
@@ -133,14 +60,7 @@ public:
m_pDataProbeString = new char[ strlen(pDataProbeString) + 1 ];
azstrcpy(m_pDataProbeString, strlen(pDataProbeString) + 1, pDataProbeString);
}
const char* GetDataProbeString() const override
{
if (gEnv->IsDedicated() && m_pDataProbeString)
{
return m_pDataProbeString;
}
return GetOwnDataProbeString();
}
const char* GetDataProbeString() const override;
protected: // ------------------------------------------------------------------------------------------
@@ -157,7 +77,7 @@ protected: // ------------------------------------------------------------------
char* m_pDataProbeString; // value client is required to have for data probes
int m_nFlags; // e.g. VF_CHEAT, ...
using ChangeFunctorContainer = std::vector<std::pair<int, SFunctor> >;
typedef std::vector<std::pair<int, AZStd::function<void ()>> > ChangeFunctorContainer;
ChangeFunctorContainer m_changeFunctors;
ConsoleVarFunc m_pChangeFunc; // Callback function that is called when this variable changes.
CXConsole* m_pConsole; // used for the callback OnBeforeVarChange()
@@ -193,59 +113,11 @@ public:
{
Set(m_sDefault.c_str());
}
void Set(const char* s) override
{
if (!s)
{
return;
}
if ((m_sValue == s) && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
if (m_pConsole->OnBeforeVarChange(this, s))
{
m_nFlags |= VF_MODIFIED;
{
m_sValue = s;
}
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
void Set(float f) override
{
stack_string s = stack_string::format("%g", f);
if ((m_sValue == s.c_str()) && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
m_nFlags |= VF_MODIFIED;
Set(s.c_str());
}
void Set(int i) override
{
stack_string s = stack_string::format("%d", i);
if ((m_sValue == s.c_str()) && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
m_nFlags |= VF_MODIFIED;
Set(s.c_str());
}
void Set(const char* s) override;
void Set(float f) override;
void Set(int i) override;
int GetType() override { return CVAR_STRING; }
void GetMemoryUsage(class ICrySizer* pSizer) const override { pSizer->AddObject(this, sizeof(*this)); }
private: // --------------------------------------------------------------------------------------------
AZStd::string m_sValue;
AZStd::string m_sDefault; //!<
@@ -267,122 +139,21 @@ public:
// interface ICVar --------------------------------------------------------------------------------------
virtual int GetIVal() const { return m_iValue; }
virtual int64 GetI64Val() const { return m_iValue; }
virtual float GetFVal() const { return (float)GetIVal(); }
virtual const char* GetString() const
{
static char szReturnString[256];
sprintf_s(szReturnString, "%d", GetIVal());
return szReturnString;
}
int GetIVal() const override { return m_iValue; }
int64 GetI64Val() const override { return m_iValue; }
float GetFVal() const override { return (float)GetIVal(); }
const char* GetString() const override;
void ResetImpl() override { Set(m_iDefault); }
virtual void Set(const char* s)
{
int nValue = TextToInt(s, m_iValue, (m_nFlags & VF_BITFIELD) != 0);
Set(nValue);
}
virtual void Set(float f)
{
Set((int)f);
}
virtual void Set(int i)
{
if (i == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
stack_string s = stack_string::format("%d", i);
if (m_pConsole->OnBeforeVarChange(this, s.c_str()))
{
m_nFlags |= VF_MODIFIED;
m_iValue = i;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
virtual int GetType() { return CVAR_INT; }
virtual void GetMemoryUsage(class ICrySizer* pSizer) const { pSizer->AddObject(this, sizeof(*this)); }
void Set(const char* s) override;
void Set(float f) override;
void Set(int i) override;
int GetType() override { return CVAR_INT; }
protected: // --------------------------------------------------------------------------------------------
int m_iValue;
int m_iDefault; //!<
};
class CXConsoleVariableInt64
: public CXConsoleVariableBase
{
public:
// constructor
CXConsoleVariableInt64(CXConsole* pConsole, const char* sName, const int64 iDefault, int nFlags, const char* help)
: CXConsoleVariableBase(pConsole, sName, nFlags, help)
, m_iValue(iDefault)
, m_iDefault(iDefault)
{
}
// interface ICVar --------------------------------------------------------------------------------------
virtual int GetIVal() const { return (int)m_iValue; }
virtual int64 GetI64Val() const { return m_iValue; }
virtual float GetFVal() const { return (float)GetIVal(); }
virtual const char* GetString() const
{
static char szReturnString[256];
sprintf_s(szReturnString, "%lld", GetI64Val());
return szReturnString;
}
void ResetImpl() override { Set(m_iDefault); }
virtual void Set(const char* s)
{
int64 nValue = TextToInt64(s, m_iValue, (m_nFlags & VF_BITFIELD) != 0);
Set(nValue);
}
virtual void Set(float f)
{
Set((int)f);
}
virtual void Set(int i)
{
Set((int64)i);
}
virtual void Set(int64 i)
{
if (i == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
stack_string s = stack_string::format("%lld", i);
if (m_pConsole->OnBeforeVarChange(this, s.c_str()))
{
m_nFlags |= VF_MODIFIED;
m_iValue = i;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
virtual int GetType() { return CVAR_INT; }
virtual void GetMemoryUsage(class ICrySizer* pSizer) const { pSizer->AddObject(this, sizeof(*this)); }
protected: // --------------------------------------------------------------------------------------------
int64 m_iValue;
int64 m_iDefault; //!<
};
//////////////////////////////////////////////////////////////////////////
class CXConsoleVariableFloat
: public CXConsoleVariableBase
@@ -401,78 +172,13 @@ public:
virtual int GetIVal() const { return (int)m_fValue; }
virtual int64 GetI64Val() const { return (int64)m_fValue; }
virtual float GetFVal() const { return m_fValue; }
virtual const char* GetString() const
{
static char szReturnString[256];
sprintf_s(szReturnString, "%g", m_fValue); // %g -> "2.01", %f -> "2.01000"
return szReturnString;
}
void ResetImpl() override { Set(m_fDefault); }
virtual void Set(const char* s)
{
float fValue = 0;
if (s)
{
fValue = (float)atof(s);
}
if (fValue == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
if (m_pConsole->OnBeforeVarChange(this, s))
{
m_nFlags |= VF_MODIFIED;
m_fValue = fValue;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(float f)
{
if (f == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
stack_string s = stack_string::format("%g", f);
if (m_pConsole->OnBeforeVarChange(this, s.c_str()))
{
m_nFlags |= VF_MODIFIED;
m_fValue = f;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(int i)
{
if ((float)i == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
char sTemp[128];
sprintf_s(sTemp, "%d", i);
if (m_pConsole->OnBeforeVarChange(this, sTemp))
{
m_nFlags |= VF_MODIFIED;
m_fValue = (float)i;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
virtual const char* GetString() const;
virtual void ResetImpl() { Set(m_fDefault); }
virtual void Set(const char* s);
virtual void Set(float f);
virtual void Set(int i);
virtual int GetType() { return CVAR_FLOAT; }
virtual void GetMemoryUsage(class ICrySizer* pSizer) const { pSizer->AddObject(this, sizeof(*this)); }
protected:
const char* GetOwnDataProbeString() const override
@@ -509,186 +215,19 @@ public:
virtual int GetIVal() const { return m_iValue; }
virtual int64 GetI64Val() const { return m_iValue; }
virtual float GetFVal() const { return (float)m_iValue; }
virtual const char* GetString() const
{
static char szReturnString[256];
sprintf_s(szReturnString, "%d", m_iValue);
return szReturnString;
}
void ResetImpl() override { Set(m_iDefault); }
virtual void Set(const char* s)
{
int nValue = TextToInt(s, m_iValue, (m_nFlags & VF_BITFIELD) != 0);
if (nValue == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
if (m_pConsole->OnBeforeVarChange(this, s))
{
m_nFlags |= VF_MODIFIED;
m_iValue = nValue;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(float f)
{
if ((int)f == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
char sTemp[128];
sprintf_s(sTemp, "%g", f);
if (m_pConsole->OnBeforeVarChange(this, sTemp))
{
m_nFlags |= VF_MODIFIED;
m_iValue = (int)f;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(int i)
{
if (i == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
char sTemp[128];
sprintf_s(sTemp, "%d", i);
if (m_pConsole->OnBeforeVarChange(this, sTemp))
{
m_nFlags |= VF_MODIFIED;
m_iValue = i;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
virtual const char* GetString() const;
virtual void ResetImpl() { Set(m_iDefault); }
virtual void Set(const char* s);
virtual void Set(float f);
virtual void Set(int i);
virtual int GetType() { return CVAR_INT; }
virtual void GetMemoryUsage(class ICrySizer* pSizer) const { pSizer->AddObject(this, sizeof(*this)); }
private: // --------------------------------------------------------------------------------------------
int& m_iValue;
int m_iDefault; //!<
};
class CXConsoleVariableFloatRef
: public CXConsoleVariableBase
{
public:
//! constructor
//!\param pVar must not be 0
CXConsoleVariableFloatRef(CXConsole* pConsole, const char* sName, float* pVar, int nFlags, const char* help)
: CXConsoleVariableBase(pConsole, sName, nFlags, help)
, m_fValue(*pVar)
, m_fDefault(*pVar)
{
assert(pVar);
}
// interface ICVar --------------------------------------------------------------------------------------
virtual int GetIVal() const { return (int)m_fValue; }
virtual int64 GetI64Val() const { return (int64)m_fValue; }
virtual float GetFVal() const { return m_fValue; }
virtual const char* GetString() const
{
static char szReturnString[256];
sprintf_s(szReturnString, "%g", m_fValue);
return szReturnString;
}
void ResetImpl() override { Set(m_fDefault); }
virtual void Set(const char* s)
{
float fValue = 0;
if (s)
{
fValue = (float)atof(s);
}
if (fValue == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
if (m_pConsole->OnBeforeVarChange(this, s))
{
m_nFlags |= VF_MODIFIED;
m_fValue = fValue;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(float f)
{
if (f == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
char sTemp[128];
sprintf_s(sTemp, "%g", f);
if (m_pConsole->OnBeforeVarChange(this, sTemp))
{
m_nFlags |= VF_MODIFIED;
m_fValue = f;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(int i)
{
if ((float)i == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
char sTemp[128];
sprintf_s(sTemp, "%d", i);
if (m_pConsole->OnBeforeVarChange(this, sTemp))
{
m_nFlags |= VF_MODIFIED;
m_fValue = (float)i;
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
virtual int GetType() { return CVAR_FLOAT; }
virtual void GetMemoryUsage(class ICrySizer* pSizer) const { pSizer->AddObject(this, sizeof(*this)); }
protected:
const char* GetOwnDataProbeString() const override
{
static char szReturnString[8];
sprintf_s(szReturnString, "%.1g", m_fValue);
return szReturnString;
}
private: // --------------------------------------------------------------------------------------------
float& m_fValue;
float m_fDefault; //!<
};
class CXConsoleVariableStringRef
: public CXConsoleVariableBase
{
@@ -714,26 +253,8 @@ public:
{
return m_sValue.c_str();
}
void ResetImpl() override { Set(m_sDefault.c_str()); }
virtual void Set(const char* s)
{
if ((m_sValue == s) && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
return;
}
if (m_pConsole->OnBeforeVarChange(this, s))
{
m_nFlags |= VF_MODIFIED;
{
m_sValue = s;
m_userPtr = m_sValue.c_str();
}
CallOnChangeFunctions();
m_pConsole->OnAfterVarChange(this);
}
}
virtual void ResetImpl() { Set(m_sDefault.c_str()); }
virtual void Set(const char* s);
virtual void Set(float f)
{
stack_string s = stack_string::format("%g", f);
@@ -746,7 +267,6 @@ public:
}
virtual int GetType() { return CVAR_STRING; }
virtual void GetMemoryUsage(class ICrySizer* pSizer) const { pSizer->AddObject(this, sizeof(*this)); }
private: // --------------------------------------------------------------------------------------------
AZStd::string m_sValue;
@@ -754,84 +274,44 @@ private: // --------------------------------------------------------------------
const char*& m_userPtr; //!<
};
// works like CXConsoleVariableInt but when changing it sets other console variables
// getting the value returns the last value it was set to - if that is still what was applied
// to the cvars can be tested with GetRealIVal()
class CXConsoleVariableCVarGroup
: public CXConsoleVariableInt
, public ILoadConfigurationEntrySink
class CXConsoleVariableFloatRef
: public CXConsoleVariableBase
{
public:
// constructor
CXConsoleVariableCVarGroup(CXConsole* pConsole, const char* sName, const char* szFileName, int nFlags);
// destructor
~CXConsoleVariableCVarGroup();
// Returns:
// part of the help string - useful to log out detailed description without additional help text
AZStd::string GetDetailedInfo() const;
// interface ICVar -----------------------------------------------------------------------------------
const char* GetHelp() override;
int GetRealIVal() const override;
virtual void DebugLog(const int iExpectedValue, const ICVar::EConsoleLogMode mode) const;
void Set(int i) override;
// ConsoleVarFunc ------------------------------------------------------------------------------------
static void OnCVarChangeFunc(ICVar* pVar);
// interface ILoadConfigurationEntrySink -------------------------------------------------------------
void OnLoadConfigurationEntry(const char* szKey, const char* szValue, const char* szGroup) override;
void OnLoadConfigurationEntry_End() override;
void GetMemoryUsage(class ICrySizer* pSizer) const override
//! constructor
//!\param pVar must not be 0
CXConsoleVariableFloatRef(CXConsole* pConsole, const char* sName, float* pVar, int nFlags, const char* help)
: CXConsoleVariableBase(pConsole, sName, nFlags, help)
, m_fValue(*pVar)
, m_fDefault(*pVar)
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(m_sDefaultValue);
pSizer->AddObject(m_CVarGroupStates);
assert(pVar);
}
// interface ICVar --------------------------------------------------------------------------------------
virtual int GetIVal() const { return (int)m_fValue; }
virtual int64 GetI64Val() const { return (int64)m_fValue; }
virtual float GetFVal() const { return m_fValue; }
virtual const char* GetString() const;
virtual void ResetImpl() { Set(m_fDefault); }
virtual void Set(const char* s);
virtual void Set(float f);
virtual void Set(int i);
virtual int GetType() { return CVAR_FLOAT; }
protected:
virtual const char *GetOwnDataProbeString() const
{
static char szReturnString[8];
sprintf_s(szReturnString, "%.1g", m_fValue);
return szReturnString;
}
private: // --------------------------------------------------------------------------------------------
struct SCVarGroup
{
std::map<AZStd::string, AZStd::string> m_KeyValuePair; // e.g. m_KeyValuePair["r_fullscreen"]="0"
void GetMemoryUsage(class ICrySizer* pSizer) const
{
pSizer->AddObject(m_KeyValuePair);
}
};
SCVarGroup m_CVarGroupDefault;
typedef std::map<int, SCVarGroup*> TCVarGroupStateMap;
TCVarGroupStateMap m_CVarGroupStates;
AZStd::string m_sDefaultValue; // used by OnLoadConfigurationEntry_End()
void ApplyCVars(const SCVarGroup& rGroup, const SCVarGroup* pExclude = nullptr);
// Arguments:
// sKey - must exist, at least in default
// pSpec - can be 0
AZStd::string GetValueSpec(const AZStd::string& sKey, const int* pSpec = nullptr) const;
// should only be used by TestCVars()
// Returns:
// true=all console variables match the state (excluding default state), false otherwise
bool TestCVars(const SCVarGroup& rGroup, const ICVar::EConsoleLogMode mode, const SCVarGroup* pExclude = nullptr) const;
// Arguments:
// pGroup - can be 0 to test if the default state is set
// Returns:
// true=all console variables match the state (including default state), false otherwise
bool TestCVars(const SCVarGroup* pGroup, const ICVar::EConsoleLogMode mode = ICVar::eCLM_Off) const;
float& m_fValue;
float m_fDefault; //!<
};
#endif // CRYINCLUDE_CRYSYSTEM_XCONSOLEVARIABLE_H
@@ -1,43 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_CRYSYSTEM_XML_READWRITEXMLSINK_H
#define CRYINCLUDE_CRYSYSTEM_XML_READWRITEXMLSINK_H
#pragma once
#include <ISystem.h>
#include <IReadWriteXMLSink.h>
class CReadWriteXMLSink
: public IReadWriteXMLSink
{
public:
bool ReadXML(const char* definitionFile, const char* dataFile, IReadXMLSink* pSink);
bool ReadXML(const char* definitionFile, XmlNodeRef node, IReadXMLSink* pSink);
bool ReadXML(XmlNodeRef definition, const char* dataFile, IReadXMLSink* pSink);
bool ReadXML(XmlNodeRef definition, XmlNodeRef node, IReadXMLSink* pSink);
XmlNodeRef CreateXMLFromSource(const char* definitionFile, IWriteXMLSource* pSource);
bool WriteXML(const char* definitionFile, const char* dataFile, IWriteXMLSource* pSource);
};
// helper to define the if/else chain that we need in a few locations...
// types must match IReadXMLSink::TValueTypes
#define XML_SET_PROPERTY_HELPER(ELSE_LOAD_PROPERTY) \
if (false) {; } \
ELSE_LOAD_PROPERTY(Vec3); \
ELSE_LOAD_PROPERTY(int); \
ELSE_LOAD_PROPERTY(float); \
ELSE_LOAD_PROPERTY(AZStd::string); \
ELSE_LOAD_PROPERTY(bool);
#endif // CRYINCLUDE_CRYSYSTEM_XML_READWRITEXMLSINK_H
-683
View File
@@ -1,683 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "CrySystem_precompiled.h"
#include "ReadWriteXMLSink.h"
#include <ISystem.h>
#include <stack>
typedef std::map<AZStd::string, XmlNodeRef> IdTable;
struct SParseParams
{
IdTable idTable;
XmlNodeRef useAlways;
bool strict;
SParseParams()
{
strict = true;
}
};
static XmlNodeRef Clone(XmlNodeRef source);
static void CopyAttributes(const XmlNodeRef& source, XmlNodeRef& dest);
static bool IsOptionalReadXML(const SParseParams& parseParams, XmlNodeRef& definition);
static bool CheckEnum(const SParseParams& parseParams, const char* name, XmlNodeRef& definition, XmlNodeRef& data);
static bool LoadTableInner(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
static bool LoadArray(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
static bool LoadProperty(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
static bool LoadTable(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
static bool LoadReferencedId(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
static bool LoadSomething(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
static bool LoadArraySetValueTable(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink, int elem);
typedef bool (* LoadArraySetValue)(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink, int elem);
typedef bool (* LoadDefinitionFunction)(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
template <class T>
struct ReadPropertyTyped;
template <class T>
struct ReadPropertyTyped
{
static bool Load(const SParseParams& parseParams, const char* name, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
T value;
memset(&value, 0, sizeof(T));
if (!pSink->IsCreationMode())
{
if (!data->haveAttr(name))
{
return false;
}
if (!data->getAttr(name, value))
{
return false;
}
if (!CheckEnum(parseParams, name, definition, data))
{
return false;
}
}
IReadXMLSink::TValue vvalue(value);
pSink->SetValue(name, vvalue, definition);
return true;
}
static bool LoadArray([[maybe_unused]] const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink, int elem)
{
T value;
memset(&value, 0, sizeof(T));
if (!pSink->IsCreationMode())
{
if (!data->haveAttr("value"))
{
return false;
}
if (!data->getAttr("value", value))
{
return false;
}
}
IReadXMLSink::TValue vvalue(value);
pSink->SetAt(elem, vvalue, definition);
return true;
}
};
template <>
struct ReadPropertyTyped<AZStd::string>
{
static bool Load(const SParseParams& parseParams, const char* name, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
const char* value = 0;
if (!pSink->IsCreationMode())
{
if (!data->haveAttr(name))
{
return false;
}
if (!CheckEnum(parseParams, name, definition, data))
{
return false;
}
value = data->getAttr(name);
}
IReadXMLSink::TValue vvalue(value);
pSink->SetValue(name, vvalue, definition);
return true;
}
static bool LoadArray([[maybe_unused]] const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink, int elem)
{
const char* value = 0;
if (!pSink->IsCreationMode())
{
if (!data->haveAttr("value"))
{
return false;
}
value = data->getAttr("value");
}
IReadXMLSink::TValue vvalue(value);
pSink->SetAt(elem, vvalue, definition);
return true;
}
};
XmlNodeRef Clone(XmlNodeRef source)
{
assert(source != (IXmlNode*)NULL);
// Can't use clone() on XmlNodeRef objects since they can contain a CXMLBinaryNode, which doesn't support
// clone(). Instead we just create a regular xml node and manually copy content, tag, attributes and children
XmlNodeRef cloned = GetISystem()->CreateXmlNode(source->getTag());
cloned->setContent(source->getContent());
CopyAttributes(source, cloned);
const int iChildCount = source->getChildCount();
for (int i = 0; i < iChildCount; ++i)
{
cloned->addChild(Clone(source->getChild(i)));
}
return cloned;
}
void CopyAttributes(const XmlNodeRef& source, XmlNodeRef& dest)
{
// Not as fast as CXmlNode::copyAttributes(), but that method will have undefined behavior if the XmlNodeRef contains
// a CBinaryXmlNode object
int nNumAttributes = source->getNumAttributes();
for (int i = 0; i < nNumAttributes; ++i)
{
const char* key = NULL;
const char* value = NULL;
if (source->getAttributeByIndex(i, &key, &value))
{
dest->setAttr(key, value);
}
}
}
bool IsOptionalReadXML(const SParseParams& parseParams, XmlNodeRef& definition)
{
// If strict mode is off, then everything is optional
if (parseParams.strict == false)
{
return true;
}
bool optional = false;
definition->getAttr("optional", optional);
return optional;
}
bool CheckEnum([[maybe_unused]] const SParseParams& parseParams, [[maybe_unused]] const char* name, XmlNodeRef& definition, [[maybe_unused]] XmlNodeRef& data)
{
if (XmlNodeRef enumNode = definition->findChild("Enum"))
{
// If strict mode is off, then no need to check the enum value
return true;
}
return true;
}
bool LoadProperty(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
const char* name = definition->getAttr("name");
if (0 == strlen(name))
{
CryLog("Property has no name");
return false;
}
const char* type = definition->getAttr("type");
if (0 == strlen(type))
{
CryLog("Property '%s' has no type", type);
return false;
}
XmlNodeRef dataToRead = data;
if (!pSink->IsCreationMode())
{
// This check is done so the data xml can specify child elements instead of attributes if desired,
// since the rest of the code assume only attributes
if (XmlNodeRef childRef = data->findChild(name))
{
if (data->haveAttr(name))
{
CryLog("Duplicate definition (attribute and element) for %s", name);
return false;
}
if (childRef->getChildCount())
{
CryLog("Property-style elements can not have children (property was %s)", name);
return false;
}
dataToRead = GetISystem()->CreateXmlNode(data->getTag());
AZStd::string content = childRef->getContent();
AZ::StringFunc::TrimWhiteSpace(content, true, true);
dataToRead->setAttr(name, content.c_str());
}
if (!dataToRead->haveAttr(name))
{
if (!IsOptionalReadXML(parseParams, definition))
{
CryLog("Failed to load property %s", name);
return false;
}
return true;
}
}
bool ok = false;
#define LOAD_PROPERTY(whichType) else if (0 == strcmp(type, #whichType)) ok = ReadPropertyTyped<whichType>::Load(parseParams, name, definition, dataToRead, pSink)
XML_SET_PROPERTY_HELPER(LOAD_PROPERTY);
#undef LOAD_PROPERTY
if (!ok)
{
CryLog("Failed loading attribute %s of type %s", name, type);
}
return ok;
}
bool LoadArraySetValueTable(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink, int elem)
{
IReadXMLSinkPtr pChildSink = pSink->BeginTableAt(elem, definition);
if (pSink->IsCreationMode() && definition->haveAttr("type"))
{
if (!LoadSomething(parseParams, definition, data, &*pChildSink))
{
return false;
}
}
else
{
if (!LoadTableInner(parseParams, definition, data, &*pChildSink))
{
return false;
}
}
if (!pChildSink->EndTableAt(elem))
{
CryLog("Failed to finish table at element %d", elem);
return false;
}
return true;
}
bool LoadArray(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
const char* name = definition->getAttr("name");
if (0 == strlen(name))
{
CryLog("Array has no name");
return false;
}
const char* elementName = definition->getAttr("elementName");
if (0 == strlen(elementName))
{
elementName = "element";
}
bool validateArray = true;
if (definition->haveAttr(elementName))
{
definition->getAttr("validate", validateArray);
}
XmlNodeRef childData;
if (!pSink->IsCreationMode())
{
childData = data->findChild(name);
if (!childData)
{
bool ok = IsOptionalReadXML(parseParams, definition);
if (!ok)
{
CryLog("Failed to load child table %s", name);
}
return ok;
}
}
IReadXMLSinkPtr childSink = pSink->BeginArray(name, definition);
if (!childSink)
{
CryLog("Failed to begin array named %s", name);
return false;
}
LoadArraySetValue setter = NULL;
if (definition->haveAttr("type"))
{
setter = NULL;
const char* type = definition->getAttr("type");
#define SETTER_PROPERTY(whichType) else if (0 == strcmp(type, #whichType)) setter = ReadPropertyTyped<whichType>::LoadArray
XML_SET_PROPERTY_HELPER(SETTER_PROPERTY);
#undef SETTER_PROPERTY
if (!setter)
{
CryLog("Unknown type %s in array %s", type, name);
return false;
}
}
else
{
setter = LoadArraySetValueTable;
}
if (!pSink->IsCreationMode())
{
int numElems = childData->getChildCount();
int elem = 1;
for (int i = 0; i < numElems; i++)
{
XmlNodeRef elemData = childData->getChild(i);
if (0 == strcmp(elemData->getTag(), elementName))
{
int increment = 1;
if (elemData->haveAttr("_index"))
{
if (!elemData->getAttr("_index", elem))
{
CryLog("_index is not an integer in array %s (pos hint=%d)", name, elem);
return false;
}
}
if (!setter(parseParams, definition, elemData, &*childSink, elem))
{
CryLog("Failed loading element %d of array %s", elem, name);
return false;
}
elem += increment;
}
else if (validateArray)
{
CryLog("Invalid node %s in array %s", elemData->getTag(), name);
return false;
}
}
}
else
{
// only process array content for the array being created
if (0 == strcmp(name, pSink->GetCreationNode()->getAttr("name")))
{
if (!setter(parseParams, definition, data, &*childSink, 1))
{
CryLog("[ReadXML CreationMode]: Failed loading element %d of array %s", 1, name);
return false;
}
}
}
if (!pSink->EndArray(name))
{
CryLog("Failed to finish array named %s", name);
return false;
}
return true;
}
bool LoadTable(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
const char* name = definition->getAttr("name");
if (0 == strlen(name))
{
CryLog("Child-table has no name");
return false;
}
XmlNodeRef childData;
if (!pSink->IsCreationMode())
{
childData = data->findChild(name);
if (!childData)
{
bool ok = IsOptionalReadXML(parseParams, definition);
if (!ok)
{
CryLog("Failed to load child table %s", name);
}
return ok;
}
}
IReadXMLSinkPtr childSink = pSink->BeginTable(name, definition);
if (!childSink)
{
CryLog("Sink creation failed for table %s", name);
return false;
}
if (!LoadTableInner(parseParams, definition, childData, childSink))
{
CryLog("Failed to load data for child table %s", name);
return false;
}
if (!pSink->EndTable(name))
{
CryLog("Table %s failed to complete in sink", name);
return false;
}
return true;
}
bool LoadSomething(const SParseParams& parseParams, XmlNodeRef& nodeDefinition, XmlNodeRef& data, IReadXMLSink* pSink)
{
// Ignore if it's the useAlways array
if (parseParams.useAlways == nodeDefinition)
{
return true;
}
static struct
{
const char* name;
LoadDefinitionFunction loader;
} loaderTypes[] = {
{"Property", &LoadProperty},
{"Array", &LoadArray},
{"Table", &LoadTable},
{"Use", &LoadReferencedId},
};
static const int numLoaderTypes = sizeof(loaderTypes) / sizeof(*loaderTypes);
const char* nodeDefinitionTag = nodeDefinition->getTag();
bool ok = false;
int i;
for (i = 0; i < numLoaderTypes; i++)
{
if (0 == strcmp(loaderTypes[i].name, nodeDefinitionTag))
{
ok = loaderTypes[i].loader(parseParams, nodeDefinition, data, pSink);
break;
}
}
if (0 == _stricmp("Settings", nodeDefinitionTag))
{
return true;
}
if (!ok)
{
if (i == numLoaderTypes)
{
CryLog("Invalid definition node type %s, line %d", nodeDefinitionTag, nodeDefinition->getLine());
}
}
return ok;
}
bool LoadReferencedId(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
IdTable::const_iterator iter = parseParams.idTable.find(definition->getAttr("id"));
if (iter == parseParams.idTable.end())
{
CryLog("No definition with id '%s'", definition->getAttr("id"));
return false;
}
XmlNodeRef useDefinition = Clone(iter->second);
CopyAttributes(definition, useDefinition);
return LoadSomething(parseParams, useDefinition, data, pSink);
}
bool LoadTableInner(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
const int nChildrenDefinition = definition->getChildCount();
for (int nChildDefinition = 0; nChildDefinition < nChildrenDefinition; nChildDefinition++)
{
XmlNodeRef nodeDefinition = definition->getChild(nChildDefinition);
if (!LoadSomething(parseParams, nodeDefinition, data, pSink))
{
return false;
}
}
if (parseParams.useAlways != (IXmlNode*)NULL)
{
assert(!definition->haveAttr("type"));
const int nUseAlwaysDefCount = parseParams.useAlways->getChildCount();
for (int i = 0; i < nUseAlwaysDefCount; ++i)
{
XmlNodeRef nodeDefinition = parseParams.useAlways->getChild(i);
// Don't continue loading useAlways nodes in creation mode
if (!pSink->IsCreationMode())
{
if (!LoadSomething(parseParams, nodeDefinition, data, pSink))
{
return false;
}
}
}
}
return true;
}
bool CReadWriteXMLSink::ReadXML(XmlNodeRef rootDefinition, XmlNodeRef rootData, IReadXMLSink* pSink)
{
if (!pSink->IsCreationMode())
{
if (0 == rootData)
{
return false;
}
if (0 != strcmp(rootDefinition->getTag(), "Definition"))
{
CryLog("Root tag of definition file was %s; expected Definition", rootDefinition->getTag());
return false;
}
if (rootDefinition->haveAttr("root"))
{
if (0 != strcmp(rootDefinition->getAttr("root"), rootData->getTag()))
{
CryLog("Root data has wrong tag; was %s expected %s", rootData->getTag(), rootDefinition->getAttr("root"));
return false;
}
}
}
SParseParams parseParams;
parseParams.useAlways = rootDefinition->findChild("AllowAlways");
if (XmlNodeRef settingsParams = rootDefinition->findChild("Settings"))
{
settingsParams->getAttr("strict", parseParams.strict);
}
// scan for id's in the structure (for the Use member)
std::stack<XmlNodeRef> scanStack;
scanStack.push(rootDefinition);
while (!scanStack.empty())
{
XmlNodeRef refNode = scanStack.top();
scanStack.pop();
int numChildren = refNode->getChildCount();
const char* tag = refNode->getTag();
for (int i = 0; i < numChildren; i++)
{
const XmlNodeRef& childNodeRef = refNode->getChild(i);
if (parseParams.useAlways != childNodeRef)
{
scanStack.push(childNodeRef);
}
}
// If the element has an attribute id="" and is not a "<Use>" element add it to the idTable map
if (refNode->haveAttr("id") && 0 != strcmp("Use", tag))
{
parseParams.idTable[refNode->getAttr("id")] = refNode;
}
}
if (pSink->IsCreationMode() && rootDefinition->haveAttr("type"))
{
// if creating from a 0-child definition node, load itself
if (!LoadSomething(parseParams, rootDefinition, rootData, pSink))
{
return false;
}
}
else
{
// load content
if (!LoadTableInner(parseParams, rootDefinition, rootData, pSink))
{
return false;
}
}
bool ok = pSink->Complete();
if (!ok)
{
CryLog("Warning: sink failed to complete reading");
}
return ok;
}
bool CReadWriteXMLSink::ReadXML(XmlNodeRef definition, const char* dataFile, IReadXMLSink* pSink)
{
XmlNodeRef rootData = GetISystem()->LoadXmlFromFile(dataFile);
if (!rootData)
{
CryLog("Unable to load XML-Lua data file: %s", dataFile);
return false;
}
return ReadXML(definition, rootData, pSink);
}
bool CReadWriteXMLSink::ReadXML(const char* definitionFile, XmlNodeRef rootData, IReadXMLSink* pSink)
{
XmlNodeRef rootDefinition = GetISystem()->LoadXmlFromFile(definitionFile);
if (!rootDefinition)
{
CryLog("Unable to load XML-Lua definition file: %s", definitionFile);
return false;
}
return ReadXML(rootDefinition, rootData, pSink);
}
bool CReadWriteXMLSink::ReadXML(const char* definitionFile, const char* dataFile, IReadXMLSink* pSink)
{
XmlNodeRef rootData = GetISystem()->LoadXmlFromFile(dataFile);
if (!rootData)
{
CryLog("Unable to load XML-Lua data file: %s", dataFile);
return false;
}
if (!ReadXML(definitionFile, rootData, pSink))
{
CryLog("Unable to load file %s", dataFile);
return false;
}
return true;
}
@@ -104,23 +104,6 @@ bool CSerializeXMLReaderImpl::Value(const char* name, CTimeValue& value)
return true;
}
bool CSerializeXMLReaderImpl::Value(const char* name, XmlNodeRef& value)
{
DefaultValue(value); // Set input value to default.
if (m_nErrors)
{
return false;
}
if (BeginOptionalGroup(name, true))
{
value = CurNode()->getChild(0);
EndGroup();
}
return true;
}
void CSerializeXMLReaderImpl::BeginGroup(const char* szName)
{
if (m_nErrors)
@@ -173,32 +156,3 @@ void CSerializeXMLReaderImpl::EndGroup()
}
assert(!m_nodeStack.empty());
}
//////////////////////////////////////////////////////////////////////////
AZStd::string CSerializeXMLReaderImpl::GetStackInfo() const
{
AZStd::string str;
for (int i = 0; i < (int)m_nodeStack.size(); i++)
{
const char* name = m_nodeStack[i].m_node->getAttr(TAG_SCRIPT_NAME);
if (name && name[0])
{
str += name;
}
else
{
str += m_nodeStack[i].m_node->getTag();
}
if (i != m_nodeStack.size() - 1)
{
str += "/";
}
}
return str;
}
void CSerializeXMLReaderImpl::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->Add(*this);
pSizer->AddContainer(m_nodeStack);
}
+2 -27
View File
@@ -6,22 +6,16 @@
*
*/
#ifndef CRYINCLUDE_CRYSYSTEM_XML_SERIALIZEXMLREADER_H
#define CRYINCLUDE_CRYSYSTEM_XML_SERIALIZEXMLREADER_H
#pragma once
#include "SimpleSerialize.h"
#include <stack>
#include <IXml.h>
#include <ITimer.h>
#include <IValidator.h>
#include <ISystem.h>
#include "xml.h"
class CSerializeXMLReaderImpl
: public CSimpleSerializeImpl<true, eST_SaveGame>
: public CSimpleSerializeImpl<true, ESerializationTarget::eST_SaveGame>
{
public:
CSerializeXMLReaderImpl(const XmlNodeRef& nodeRef);
@@ -41,7 +35,7 @@ public:
g_pXmlStrCmp = &strcmp; // Do case-sensitive compare
bool bReturn = node->haveAttr(name);
if (bReturn)
{
{
value = node->getAttr(name);
}
g_pXmlStrCmp = pPrevCmpFunc;
@@ -51,10 +45,6 @@ public:
{
return false;
}
ILINE bool GetAttr([[maybe_unused]] const XmlNodeRef& node, [[maybe_unused]] const char* name, [[maybe_unused]] SNetObjectID& value)
{
return false;
}
template <class T_Value>
bool Value(const char* name, T_Value& value)
@@ -77,23 +67,12 @@ public:
bool Value(const char* name, int8& value);
bool Value(const char* name, AZStd::string& value);
bool Value(const char* name, CTimeValue& value);
bool Value(const char* name, XmlNodeRef& value);
template <class T_Value, class T_Policy>
bool Value(const char* name, T_Value& value, [[maybe_unused]] const T_Policy& policy)
{
return Value(name, value);
}
void BeginGroup(const char* szName);
bool BeginOptionalGroup(const char* szName, bool condition);
void EndGroup();
AZStd::string GetStackInfo() const;
void GetMemoryUsage(ICrySizer* pSizer) const;
private:
//CTimeValue m_curTime;
XmlNodeRef CurNode() { return m_nodeStack.back().m_node; }
XmlNodeRef NextOf(const char* name)
{
@@ -171,13 +150,9 @@ private:
void DefaultValue(Ang3& v) const { v.x = 0; v.y = 0; v.z = 0; }
void DefaultValue(Quat& v) const { v.w = 1.0f; v.v.x = 0; v.v.y = 0; v.v.z = 0; }
void DefaultValue(CTimeValue& v) const { v.SetValue(0); }
//void DefaultValue( char *str ) const { if (str) str[0] = 0; }
void DefaultValue(AZStd::string& str) const { str = ""; }
void DefaultValue([[maybe_unused]] const AZStd::string& str) const {}
void DefaultValue([[maybe_unused]] SNetObjectID& id) const {}
void DefaultValue([[maybe_unused]] SSerializeString& str) const {}
void DefaultValue(XmlNodeRef& ref) const { ref = NULL; }
//////////////////////////////////////////////////////////////////////////
};
#endif // CRYINCLUDE_CRYSYSTEM_XML_SERIALIZEXMLREADER_H
@@ -49,16 +49,6 @@ bool CSerializeXMLWriterImpl::Value(const char* name, CTimeValue value)
return true;
}
bool CSerializeXMLWriterImpl::Value(const char* name, XmlNodeRef& value)
{
if (BeginOptionalGroup(name, value != NULL))
{
CurNode()->addChild(value);
EndGroup();
}
return true;
}
void CSerializeXMLWriterImpl::BeginGroup(const char* szName)
{
if (strchr(szName, ' ') != 0)
@@ -104,13 +94,6 @@ void CSerializeXMLWriterImpl::EndGroup()
assert(!m_nodeStack.empty());
}
void CSerializeXMLWriterImpl::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->Add(*this);
pSizer->AddObject(m_nodeStack);
pSizer->AddContainer(m_luaSaveStack);
}
//////////////////////////////////////////////////////////////////////////
AZStd::string CSerializeXMLWriterImpl::GetStackInfo() const
{
+1 -15
View File
@@ -15,11 +15,10 @@
#include <ISystem.h>
#include <ITimer.h>
#include <IXml.h>
#include "IValidator.h"
#include "SimpleSerialize.h"
class CSerializeXMLWriterImpl
: public CSimpleSerializeImpl<false, eST_SaveGame>
: public CSimpleSerializeImpl<false, ESerializationTarget::eST_SaveGame>
{
public:
CSerializeXMLWriterImpl(const XmlNodeRef& nodeRef);
@@ -32,21 +31,12 @@ public:
return true;
}
template <class T_Value, class T_Policy>
bool Value(const char* name, T_Value& value, [[maybe_unused]] const T_Policy& policy)
{
return Value(name, value);
}
bool Value(const char* name, CTimeValue value);
bool Value(const char* name, XmlNodeRef& value);
void BeginGroup(const char* szName);
bool BeginOptionalGroup(const char* szName, bool condition);
void EndGroup();
void GetMemoryUsage(ICrySizer* pSizer) const;
private:
//////////////////////////////////////////////////////////////////////////
// Vars.
@@ -99,10 +89,6 @@ private:
{
AddValue(name, value.c_str());
}
void AddValue([[maybe_unused]] const char* name, [[maybe_unused]] const SNetObjectID& value)
{
assert(false);
}
template <class T>
void AddTypedValue(const char* name, const T& value, const char* type)
{
@@ -1,432 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "CrySystem_precompiled.h"
#include "ReadWriteXMLSink.h"
#include <stack>
typedef std::map<AZStd::string, XmlNodeRef> IdTable;
static bool IsOptionalWriteXML(XmlNodeRef& definition);
static bool SaveTableInner(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
static bool SaveReferencedId(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
static bool SaveSomething(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
static bool SaveArray(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
static bool SaveProperty(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
static bool SaveTable(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
static bool SaveArraySetValueTable(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource, int elem);
typedef bool (* SaveArraySetValue)(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource, int elem);
typedef bool (* SaveDefinitionFunction)(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
template <class T>
struct WritePropertyTyped;
template <class T>
struct WritePropertyTyped
{
static bool Save(const char* name, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
IWriteXMLSource::TValue vvalue((T()));
if (!pSource->GetValue(name, vvalue, definition))
{
return false;
}
T* pValue = AZStd::get_if<T>(&vvalue);
if (!pValue)
{
return false;
}
data->setAttr(name, *pValue);
return true;
}
static bool SaveArray([[maybe_unused]] const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource, int elem)
{
IWriteXMLSource::TValue vvalue((T()));
if (!pSource->GetAt(elem, vvalue, definition))
{
return false;
}
T* pValue = AZStd::get_if<T>(&vvalue);
if (!pValue)
{
return false;
}
data->setAttr("value", *pValue);
return true;
}
};
template <>
struct WritePropertyTyped<AZStd::string>
: public WritePropertyTyped<const char*>
{
};
bool IsOptionalWriteXML(XmlNodeRef& definition)
{
bool optional = false;
definition->getAttr("optional", optional);
return optional;
}
bool SaveProperty([[maybe_unused]] const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
const char* name = definition->getAttr("name");
if (0 == strlen(name))
{
CryLog("Property has no name");
return false;
}
const char* type = definition->getAttr("type");
if (0 == strlen(type))
{
CryLog("Property '%s' has no type", type);
return false;
}
if (IsOptionalWriteXML(definition) && !pSource->HaveValue(name))
{
return true;
}
bool ok = false;
#define SAVE_PROPERTY(whichType) else if (0 == strcmp(type, #whichType)) ok = WritePropertyTyped<whichType>::Save(name, definition, data, pSource)
XML_SET_PROPERTY_HELPER(SAVE_PROPERTY);
#undef SAVE_PROPERTY
if (!ok)
{
CryLog("Failed loading attribute %s of type %s", name, type);
}
return ok;
}
bool SaveArraySetValueTable(const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource, int elem)
{
IWriteXMLSourcePtr pChildSource = pSource->BeginTableAt(elem);
if (!pChildSource)
{
CryLog("Failed to find source table at %d", elem);
return false;
}
if (!SaveTableInner(idTable, definition, data, &*pChildSource))
{
return false;
}
if (!pChildSource->EndTableAt(elem))
{
CryLog("Failed to finish table at element %d", elem);
return false;
}
return true;
}
bool SaveArray(const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
const char* name = definition->getAttr("name");
if (0 == strlen(name))
{
CryLog("Array has no name");
return false;
}
const char* elementName = definition->getAttr("elementName");
if (0 == strlen(elementName))
{
elementName = "element";
}
bool validateArray = true;
if (definition->haveAttr(elementName))
{
definition->getAttr("validate", validateArray);
}
size_t numElems = 0;
IWriteXMLSourcePtr childSource = pSource->BeginArray(name, &numElems, definition);
if (!childSource)
{
bool ok = IsOptionalWriteXML(definition);
if (!ok)
{
CryLog("Failed to begin array named %s", name);
}
return ok;
}
XmlNodeRef childData = data->createNode(name);
SaveArraySetValue setter = NULL;
if (definition->haveAttr("type"))
{
setter = NULL;
const char* type = definition->getAttr("type");
#define SETTER_PROPERTY(whichType) else if (0 == strcmp(type, #whichType)) setter = WritePropertyTyped<whichType>::SaveArray
XML_SET_PROPERTY_HELPER(SETTER_PROPERTY);
#undef SETTER_PROPERTY
if (!setter)
{
CryLog("Unknown type %s in array %s", type, name);
return false;
}
}
else
{
setter = SaveArraySetValueTable;
}
bool needIndex = false;
for (size_t sizei = 1; sizei <= numElems; sizei++)
{
const int i = static_cast<int>(sizei);
if (!childSource->HaveElemAt(i))
{
needIndex = true;
}
else
{
XmlNodeRef elemData = childData->createNode(elementName);
if (needIndex)
{
elemData->setAttr("_index", i);
}
needIndex = false;
if (!setter(idTable, definition, elemData, &*childSource, i))
{
CryLog("Failed saving element %d of array %s", int(i), name);
return false;
}
childData->addChild(elemData);
}
}
if (!pSource->EndArray(name))
{
CryLog("Failed to finish array named %s", name);
return false;
}
data->addChild(childData);
return true;
}
bool SaveTable(const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
const char* name = definition->getAttr("name");
if (0 == strlen(name))
{
CryLog("Child-table has no name");
return false;
}
IWriteXMLSourcePtr childSource = pSource->BeginTable(name);
if (!childSource)
{
bool ok = IsOptionalWriteXML(definition);
if (!ok)
{
CryLog("Source creation failed for table %s", name);
}
return ok;
}
XmlNodeRef childData = data->createNode(name);
if (!SaveTableInner(idTable, definition, childData, childSource))
{
CryLog("Failed to load data for child table %s", name);
return false;
}
if (!pSource->EndTable(name))
{
CryLog("Table %s failed to complete in sink", name);
return false;
}
data->addChild(childData);
return true;
}
bool SaveSomething(const IdTable& idTable, XmlNodeRef& nodeDefinition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
static struct
{
const char* name;
SaveDefinitionFunction saver;
} saverTypes[] = {
{"Property", &SaveProperty},
{"Array", &SaveArray},
{"Table", &SaveTable},
{"Use", &SaveReferencedId},
};
static const int numSaverTypes = sizeof(saverTypes) / sizeof(*saverTypes);
const char* nodeDefinitionTag = nodeDefinition->getTag();
bool ok = false;
int i;
for (i = 0; i < numSaverTypes; i++)
{
if (0 == strcmp(saverTypes[i].name, nodeDefinitionTag))
{
ok = saverTypes[i].saver(idTable, nodeDefinition, data, pSource);
break;
}
}
if (!ok)
{
if (i == numSaverTypes)
{
CryLog("Invalid definition node type %s", nodeDefinitionTag);
}
}
return ok;
}
bool SaveReferencedId(const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
IdTable::const_iterator iter = idTable.find(definition->getAttr("id"));
if (iter == idTable.end())
{
CryLog("No definition with id '%s'", definition->getAttr("id"));
return false;
}
XmlNodeRef useDefinition = iter->second;
useDefinition = useDefinition->clone();
int numAttrs = definition->getNumAttributes();
for (int i = 0; i < numAttrs; i++)
{
const char* key, * value;
definition->getAttributeByIndex(i, &key, &value);
useDefinition->setAttr(key, value);
}
return SaveSomething(idTable, useDefinition, data, pSource);
}
bool SaveTableInner(const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
const int nChildrenDefinition = definition->getChildCount();
for (int nChildDefinition = 0; nChildDefinition < nChildrenDefinition; nChildDefinition++)
{
XmlNodeRef nodeDefinition = definition->getChild(nChildDefinition);
if (!SaveSomething(idTable, nodeDefinition, data, pSource))
{
return false;
}
}
return true;
}
XmlNodeRef CReadWriteXMLSink::CreateXMLFromSource(const char* definitionFile, IWriteXMLSource* pSource)
{
XmlNodeRef rootDefinition = GetISystem()->LoadXmlFromFile(definitionFile);
if (!rootDefinition)
{
CryLog("Unable to load XML-Lua definition file: %s", definitionFile);
return 0;
}
if (0 != strcmp(rootDefinition->getTag(), "Definition"))
{
CryLog("Root tag of definition file was %s; expected Definition", rootDefinition->getTag());
return 0;
}
const char* rootNode = "Root";
if (rootDefinition->haveAttr("root"))
{
rootNode = rootDefinition->getAttr("root");
}
XmlNodeRef rootData = GetISystem()->CreateXmlNode(rootNode);
XmlNodeRef allowAlways = rootDefinition->findChild("AllowAlways");
if (allowAlways != 0)
{
rootDefinition->removeChild(allowAlways);
}
XmlNodeRef settingsParams = rootDefinition->findChild("Settings");
if (settingsParams != 0)
{
rootDefinition->removeChild(settingsParams);
}
// scan for id's in the structure (for the Use member)
IdTable idTable;
std::stack<XmlNodeRef> scanStack;
scanStack.push(rootDefinition);
while (!scanStack.empty())
{
XmlNodeRef refNode = scanStack.top();
scanStack.pop();
int numChildren = refNode->getChildCount();
const char* tag = refNode->getTag();
for (int i = 0; i < numChildren; i++)
{
scanStack.push(refNode->getChild(i));
}
if (refNode->haveAttr("id") && 0 != strcmp("Use", tag))
{
idTable[refNode->getAttr("id")] = refNode;
}
if (allowAlways != 0 && (!strcmp("Table", tag) || !strcmp("Array", tag)))
{
for (int i = 0; i < allowAlways->getChildCount(); ++i)
{
refNode->addChild(allowAlways->getChild(i)->clone());
}
}
}
if (!SaveTableInner(idTable, rootDefinition, rootData, pSource))
{
CryLog("Error createing xml using definition %s", definitionFile);
return 0;
}
bool ok = pSource->Complete();
if (!ok)
{
CryLog("Warning: sink failed to complete writing");
return 0;
}
return rootData;
}
bool CReadWriteXMLSink::WriteXML(const char* definitionFile, const char* dataFile, IWriteXMLSource* pSource)
{
XmlNodeRef data = CreateXMLFromSource(definitionFile, pSource);
if (!data)
{
CryLog("Failed creating %s", dataFile);
return false;
}
if (!data->saveToFile(dataFile))
{
CryLog("Failed saving %s", dataFile);
return false;
}
return true;
}
+1 -46
View File
@@ -8,8 +8,8 @@
#include <platform.h>
#include "Cry_Color.h"
#include "XMLBinaryNode.h"
#include <CrySizer.h>
//////////////////////////////////////////////////////////////////////////
CBinaryXmlData::CBinaryXmlData()
@@ -38,24 +38,10 @@ CBinaryXmlData::~CBinaryXmlData()
pBinaryNodes = 0;
}
void CBinaryXmlData::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(pFileContents, nFileSize);
const XMLBinary::BinaryFileHeader* pHeader = reinterpret_cast<const XMLBinary::BinaryFileHeader*>(pFileContents);
pSizer->AddObject(pBinaryNodes, sizeof(CBinaryXmlNode) * pHeader->nNodeCount);
}
//////////////////////////////////////////////////////////////////////////
// CBinaryXmlNode implementation.
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// collect allocated memory informations
void CBinaryXmlNode::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(m_pData);
}
//////////////////////////////////////////////////////////////////////////
XmlNodeRef CBinaryXmlNode::getParent() const
{
@@ -244,21 +230,6 @@ bool CBinaryXmlNode::getAttr(const char* key, Vec4& value) const
return false;
}
bool CBinaryXmlNode::getAttr(const char* key, Vec3d& value) const
{
const char* svalue = GetValue(key);
if (svalue)
{
double x, y, z;
if (azsscanf(svalue, "%lf,%lf,%lf", &x, &y, &z) == 3)
{
value = Vec3d(x, y, z);
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CBinaryXmlNode::getAttr(const char* key, Vec2& value) const
{
@@ -275,22 +246,6 @@ bool CBinaryXmlNode::getAttr(const char* key, Vec2& value) const
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CBinaryXmlNode::getAttr(const char* key, Vec2d& value) const
{
const char* svalue = GetValue(key);
if (svalue)
{
double x, y;
if (azsscanf(svalue, "%lf,%lf", &x, &y) == 2)
{
value = Vec2d(x, y);
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CBinaryXmlNode::getAttr(const char* key, Quat& value) const
{
@@ -41,8 +41,6 @@ public:
CBinaryXmlData();
~CBinaryXmlData();
void GetMemoryUsage(ICrySizer* pSizer) const;
};
// forward declaration
@@ -59,9 +57,6 @@ class CBinaryXmlNode
{
public:
// collect allocated memory informations
void GetMemoryUsage(ICrySizer* pSizer) const;
//////////////////////////////////////////////////////////////////////////
// Custom new/delete with pool allocator.
//////////////////////////////////////////////////////////////////////////
@@ -164,11 +159,9 @@ public:
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] float value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] f64 value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Vec2& value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Vec2d& value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Ang3& value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Vec3& value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Vec4& value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Vec3d& value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Quat& value) { assert(0); };
void delAttr([[maybe_unused]] const char* key) { assert(0); };
void removeAllAttributes() { assert(0); };
@@ -183,11 +176,9 @@ public:
bool getAttr(const char* key, bool& value) const;
bool getAttr(const char* key, XmlString& value) const {const char* v(NULL); bool boHasAttribute(getAttr(key, &v)); value = v; return boHasAttribute; }
bool getAttr(const char* key, Vec2& value) const;
bool getAttr(const char* key, Vec2d& value) const;
bool getAttr(const char* key, Ang3& value) const;
bool getAttr(const char* key, Vec3& value) const;
bool getAttr(const char* key, Vec4& value) const;
bool getAttr(const char* key, Vec3d& value) const;
bool getAttr(const char* key, Quat& value) const;
bool getAttr(const char* key, ColorB& value) const;
+1 -53
View File
@@ -12,40 +12,6 @@
#include "CryEndian.h"
#include <string.h> // memcpy()
//////////////////////////////////////////////////////////////////////////
namespace XMLBinary
{
void SwapEndianness_Node(Node& t)
{
SwapEndian(t.nTagStringOffset, true);
SwapEndian(t.nContentStringOffset, true);
SwapEndian(t.nAttributeCount, true);
SwapEndian(t.nChildCount, true);
SwapEndian(t.nParentIndex, true);
SwapEndian(t.nFirstAttributeIndex, true);
SwapEndian(t.nFirstChildIndex, true);
}
void SwapEndianness_Attribute(Attribute& t)
{
SwapEndian(t.nKeyStringOffset, true);
SwapEndian(t.nValueStringOffset, true);
}
void SwapEndianness_Header(BinaryFileHeader& t)
{
SwapEndian(t.nXMLSize, true);
SwapEndian(t.nNodeTablePosition, true);
SwapEndian(t.nNodeCount, true);
SwapEndian(t.nAttributeTablePosition, true);
SwapEndian(t.nAttributeCount, true);
SwapEndian(t.nChildTablePosition, true);
SwapEndian(t.nChildCount, true);
SwapEndian(t.nStringDataPosition, true);
SwapEndian(t.nStringDataSize, true);
}
}
//////////////////////////////////////////////////////////////////////////
XMLBinary::CXMLBinaryWriter::CXMLBinaryWriter()
{
@@ -84,7 +50,7 @@ static void write(XMLBinary::IDataWriter* const pFile, size_t& nPosition, const
}
//////////////////////////////////////////////////////////////////////////
bool XMLBinary::CXMLBinaryWriter::WriteNode(IDataWriter* pFile, XmlNodeRef node, bool bNeedSwapEndian, XMLBinary::IFilter* pFilter, AZStd::string& error)
bool XMLBinary::CXMLBinaryWriter::WriteNode(IDataWriter* pFile, XmlNodeRef node, XMLBinary::IFilter* pFilter, AZStd::string& error)
{
error = "";
@@ -135,24 +101,6 @@ bool XMLBinary::CXMLBinaryWriter::WriteNode(IDataWriter* pFile, XmlNodeRef node,
header.nXMLSize = static_cast<uint32>(nTheoreticalPosition);
// Swap endianness of the data structures
if (bNeedSwapEndian)
{
SwapEndianness_Header(header);
for (size_t i = 0, iCount = m_nodes.size(); i < iCount; ++i)
{
SwapEndianness_Node(m_nodes[i]);
}
for (size_t i = 0, iCount = m_attributes.size(); i < iCount; ++i)
{
SwapEndianness_Attribute(m_attributes[i]);
}
for (size_t i = 0, iCount = m_childs.size(); i < iCount; ++i)
{
SwapEndian(m_childs[i], true);
}
}
// Write file
{
nTheoreticalPosition = 0;
+1 -1
View File
@@ -25,7 +25,7 @@ namespace XMLBinary
{
public:
CXMLBinaryWriter();
bool WriteNode(IDataWriter* pFile, XmlNodeRef node, bool bNeedSwapEndian, XMLBinary::IFilter* pFilter, AZStd::string & error);
bool WriteNode(IDataWriter* pFile, XmlNodeRef node, XMLBinary::IFilter* pFilter, AZStd::string & error);
private:
bool CompileTables(XmlNodeRef node, XMLBinary::IFilter* pFilter, AZStd::string& error);
-423
View File
@@ -1,423 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "CrySystem_precompiled.h"
#include "XMLPatcher.h"
CXMLPatcher::CXMLPatcher(XmlNodeRef& patchXML)
{
m_patchXML = patchXML;
#if DATA_PATCH_DEBUG
m_pDumpFilesCVar = REGISTER_INT("g_datapatcher_dumpfiles", 0, NULL, "will dump a copy of every file data patched, before and after patching");
#endif
}
CXMLPatcher::~CXMLPatcher()
{
#if DATA_PATCH_DEBUG
if (IConsole* pIC = gEnv->pConsole)
{
pIC->UnregisterVariable(m_pDumpFilesCVar->GetName());
}
#endif
}
XmlNodeRef CXMLPatcher::DuplicateForPatching(
const XmlNodeRef& inOrig,
bool inShareChildren)
{
XmlNodeRef newNode(0);
if (m_patchXML)
{
newNode = m_patchXML->createNode(inOrig->getTag());
if (newNode)
{
// copy attributes in a safe way, copyAttributes() itself assumes the node being copied from is of the same type
int numAttr = inOrig->getNumAttributes();
for (int i = 0; i < numAttr; i++)
{
const char* pKey, * pValue;
if (inOrig->getAttributeByIndex(i, &pKey, &pValue))
{
newNode->setAttr(pKey, pValue);
}
}
if (inShareChildren)
{
newNode->shareChildren(inOrig);
}
}
}
return newNode;
}
void CXMLPatcher::PatchFail(
const char* pInReason)
{
CryLogAlways("Failed to apply data patch for file '%s' - reason '%s'", m_pFileBeingPatched, pInReason);
}
XmlNodeRef CXMLPatcher::FindPatchForFile(
const char* pInFileToPatch)
{
XmlNodeRef result;
if (m_patchXML)
{
for (int i = 0, m = m_patchXML->getChildCount(); i < m; i++)
{
XmlNodeRef child = m_patchXML->getChild(i);
if (child->isTag("patch"))
{
const char* pForFile = child->getAttr("forfile");
if (pForFile && AZ::StringFunc::Find(pForFile, pInFileToPatch) != AZStd::string::npos)
{
result = child;
break;
}
}
}
}
return result;
}
XmlNodeRef CXMLPatcher::ApplyPatchToNode(
const XmlNodeRef& inNode,
const XmlNodeRef& inPatch)
{
XmlNodeRef result = inNode;
for (int i = 0, m = inPatch->getChildCount(); i < m; i++)
{
XmlNodeRef patchNode = inPatch->getChild(i);
if (!patchNode || _stricmp(patchNode->getTag(), "patchnode") != 0)
{
continue;
}
int indexToPatch;
if (!patchNode->getAttr("index", indexToPatch))
{
PatchFail("found patchnode missing index");
continue;
}
int maxChildren = result->getChildCount();
if ((indexToPatch < 0 || indexToPatch >= maxChildren) && indexToPatch != -1)
{
PatchFail("patchnode index out of valid range");
continue;
}
XmlNodeRef childToPatch = (indexToPatch != -1) ? result->getChild(indexToPatch) : XmlNodeRef(0);
XmlNodeRef matchTag = GetMatchTag(patchNode);
if (childToPatch && matchTag && !CompareTags(matchTag, childToPatch))
{
PatchFail("patch failed to apply, data did not match what was expected");
continue;
}
// we need to apply a patch to this child, make it patchable by duplicating the node
if (inNode == result)
{
// make parent patchable if not already
result = DuplicateForPatching(inNode, true);
}
if (XmlNodeRef insertTag = GetInsertTag(patchNode))
{
// insert a new child after this node
XmlNodeRef newChild = DuplicateForPatching(insertTag, true); // have to duplicate it as we don't have an 'insert shared child' function
result->insertChild(indexToPatch + 1, newChild);
}
else
{
if (indexToPatch == -1)
{
PatchFail("child indices of -1 can only be used when inserting new nodes");
continue;
}
}
bool shouldReplaceChildren = false;
if (XmlNodeRef replaceTag = GetReplaceTag(patchNode, &shouldReplaceChildren))
{
XmlNodeRef newChild = DuplicateForPatching(replaceTag, false);
if (!shouldReplaceChildren)
{
newChild->shareChildren(childToPatch);
}
else
{
// note: this is inserting children that belong to the data patcher into the data being patched
// this is fine to do, as long as the caller doesn't make any permanent changes to the xml tree
// returned. if they did they would alter the patcher's nodes and thus affect future patches
// applied using the same patch
// as most callers are working with binary xmls they don't try and modify them - as this is not
// a supported operation
// note, if a second patch was applied to this patched tree containing the patch nodes, it
// wouldn't mess up the patch, as patching a tree never modifies it, it always returns a new tree
// that may share parts of the original tree
newChild->shareChildren(replaceTag);
}
result->replaceChild(indexToPatch, newChild);
childToPatch = newChild;
}
if (XmlNodeRef deleteTag = GetDeleteTag(patchNode))
{
result->deleteChildAt(indexToPatch);
childToPatch = 0; // deleted - don't recurse into it
}
if (childToPatch)
{
// Apply recursively
XmlNodeRef newChild = ApplyPatchToNode(childToPatch, patchNode);
// child has been patched, insert new child into parent
if (newChild != childToPatch)
{
result->replaceChild(indexToPatch, newChild);
}
}
}
return result;
}
XmlNodeRef CXMLPatcher::ApplyXMLDataPatch(
const XmlNodeRef& inNode,
const char* pInXMLFileName)
{
XmlNodeRef result = inNode;
if (m_patchingEnabled)
{
if (m_patchXML)
{
XmlNodeRef patchForFile = FindPatchForFile(pInXMLFileName);
if (patchForFile)
{
m_pFileBeingPatched = pInXMLFileName;
CryLog("Applying game data patch to %s", pInXMLFileName);
XmlNodeRef containerNode = m_patchXML->createNode("");
containerNode->addChild(inNode);
containerNode = ApplyPatchToNode(containerNode, patchForFile);
result = containerNode->getChild(0);
m_pFileBeingPatched = NULL;
#if DATA_PATCH_DEBUG
if (inNode != result)
{
DumpFiles(pInXMLFileName, inNode, result);
}
#endif
}
}
}
return result;
}
XmlNodeRef CXMLPatcher::GetMatchTag(
const XmlNodeRef& inNode)
{
XmlNodeRef result;
XmlNodeRef nr = inNode->findChild("match");
if (nr && nr->getChildCount() == 1)
{
result = nr->getChild(0);
}
return result;
}
XmlNodeRef CXMLPatcher::GetReplaceTag(
const XmlNodeRef& inNode,
bool* outShouldReplaceChildren)
{
XmlNodeRef result;
XmlNodeRef nr = inNode->findChild("replacewith");
if (nr && nr->getChildCount() == 1)
{
if (!nr->getAttr("replaceChildren", *outShouldReplaceChildren))
{
*outShouldReplaceChildren = false;
}
result = nr->getChild(0);
}
return result;
}
XmlNodeRef CXMLPatcher::GetInsertTag(
const XmlNodeRef& inNode)
{
XmlNodeRef result;
XmlNodeRef nr = inNode->findChild("insertAfter");
if (nr && nr->getChildCount() == 1)
{
result = nr->getChild(0);
}
return result;
}
XmlNodeRef CXMLPatcher::GetDeleteTag(
const XmlNodeRef& inNode)
{
XmlNodeRef result = inNode->findChild("delete");
return result;
}
// compares the two tags for equality of tag and attributes
// used to ensure the source data being patched meets the patches expectations
// only compares tag and attribs, doesn't do deep compare of children
bool CXMLPatcher::CompareTags(
const XmlNodeRef& inA,
const XmlNodeRef& inB)
{
bool result = true;
if (inA != inB)
{
result = false;
if (_stricmp(inA->getTag(), inB->getTag()) == 0)
{
if (inA->getNumAttributes() == inB->getNumAttributes())
{
result = true;
for (int i = 0, m = inA->getNumAttributes(); i < m; i++)
{
const char* pAKey, * pBKey;
const char* pAValue, * pBValue;
inA->getAttributeByIndex(i, &pAKey, &pAValue);
inB->getAttributeByIndex(i, &pBKey, &pBValue);
if (_stricmp(pAKey, pBKey) || _stricmp(pAValue, pBValue))
{
result = false;
break;
}
}
}
}
}
return result;
}
#if DATA_PATCH_DEBUG
static const char* k_lotsOfTabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
#define INDENT() \
if (inIndent > 0) \
{ \
pPak->FWrite(k_lotsOfTabs, inIndent, inFileHandle); \
}
void CXMLPatcher::DumpXMLNodes(
AZ::IO::HandleType inFileHandle,
int inIndent,
const XmlNodeRef& inNode,
AZStd::fixed_string<512>* ioTempString)
{
auto pPak = gEnv->pCryPak;
inIndent = min(inIndent, int(sizeof(k_lotsOfTabs) - 1));
INDENT();
*ioTempString = AZStd::fixed_string<512>::format("<%s ", inNode->getTag());
pPak->FWrite(ioTempString->c_str(), ioTempString->length(), inFileHandle);
for (int i = 0, m = inNode->getNumAttributes(); i < m; i++)
{
const char* pKey, * pVal;
inNode->getAttributeByIndex(i, &pKey, &pVal);
*ioTempString = AZStd::fixed_string<512>::format("%s=\"%s\" ", pKey, pVal);
pPak->FWrite(ioTempString->c_str(), ioTempString->length(), inFileHandle);
}
pPak->FWrite(">\n", 2, inFileHandle);
for (int i = 0, m = inNode->getChildCount(); i < m; i++)
{
DumpXMLNodes(inFileHandle, inIndent + 1, inNode->getChild(i), ioTempString);
}
INDENT();
*ioTempString = AZStd::fixed_string<512>::format("</%s>\n", inNode->getTag());
pPak->FWrite(ioTempString->c_str(), ioTempString->length(), inFileHandle);
}
void CXMLPatcher::DumpFiles(
const char* pInXMLFileName,
const XmlNodeRef& inBefore,
const XmlNodeRef& inAfter)
{
if (m_pDumpFilesCVar->GetIVal())
{
CryLog("Dumping before and after data files for '%s'", pInXMLFileName);
const char* pOrigFileName = strrchr(pInXMLFileName, '/');
if (pOrigFileName)
{
pOrigFileName++;
DumpXMLFile(AZStd::string::format("PATCH_%s", pOrigFileName).c_str(), inBefore);
AZStd::string newFileName(pOrigFileName);
AZ::StringFunc::Replace(newFileName, ".xml", "_patched.xml");
DumpXMLFile(AZStd::string::format("PATCH_%s", newFileName.c_str()).c_str(), inAfter);
}
else
{
CryLog("Couldn't determine file name for path '%s' can't output diffs", pInXMLFileName);
}
}
}
void CXMLPatcher::DumpXMLFile(
const char* pInFilePath,
const XmlNodeRef& inNode)
{
auto pIPak = GetISystem()->GetIPak();
AZ::IO::HandleType fileHandle = pIPak->FOpen(pInFilePath, "wb");
if (fileHandle != AZ::IO::InvalidHandle)
{
AZStd::fixed_string<512> tempStr;
DumpXMLNodes(fileHandle, 0, inNode, &tempStr);
pIPak->FClose(fileHandle);
}
}
#endif
-81
View File
@@ -1,81 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_CRYSYSTEM_XML_XMLPATCHER_H
#define CRYINCLUDE_CRYSYSTEM_XML_XMLPATCHER_H
#pragma once
#if defined(WIN32) && !defined(_RELEASE)
#define DATA_PATCH_DEBUG 1
#else
#define DATA_PATCH_DEBUG 0
#endif
class CXMLPatcher
{
protected:
#if DATA_PATCH_DEBUG
ICVar * m_pDumpFilesCVar;
#endif
XmlNodeRef m_patchXML;
const char* m_pFileBeingPatched;
bool m_patchingEnabled;
void PatchFail(
const char* pInReason);
XmlNodeRef ApplyPatchToNode(
const XmlNodeRef& inNode,
const XmlNodeRef& inPatch);
XmlNodeRef DuplicateForPatching(
const XmlNodeRef& inOrig,
bool inShareChildren);
bool CompareTags(
const XmlNodeRef& inA,
const XmlNodeRef& inB);
XmlNodeRef GetMatchTag(
const XmlNodeRef& inNode);
XmlNodeRef GetReplaceTag(
const XmlNodeRef& inNode,
bool* outShouldReplaceChildren);
XmlNodeRef GetInsertTag(
const XmlNodeRef& inNode);
XmlNodeRef GetDeleteTag(
const XmlNodeRef& inNode);
XmlNodeRef FindPatchForFile(
const char* pInFileToPatch);
#if DATA_PATCH_DEBUG
void DumpXMLNodes(
AZ::IO::HandleType inFileHandle,
int inIndent,
const XmlNodeRef& inNode,
AZStd::fixed_string<512>* ioTempString);
void DumpFiles(
const char* pInXMLFileName,
const XmlNodeRef& inBefore,
const XmlNodeRef& inAfter);
void DumpXMLFile(
const char* pInFilePath,
const XmlNodeRef& inNode);
#endif
public:
CXMLPatcher(XmlNodeRef& patchXML);
~CXMLPatcher();
XmlNodeRef ApplyXMLDataPatch(
const XmlNodeRef& inNode,
const char* pInXMLFileName);
};
#endif // CRYINCLUDE_CRYSYSTEM_XML_XMLPATCHER_H
+4 -222
View File
@@ -11,7 +11,6 @@
#include <IXml.h>
#include "xml.h"
#include "XmlUtils.h"
#include "ReadWriteXMLSink.h"
#include "../SimpleStringPool.h"
#include "SerializeXMLReader.h"
@@ -20,7 +19,6 @@
#include "XMLBinaryWriter.h"
#include "XMLBinaryReader.h"
#include "XMLPatcher.h"
#include <md5.h>
//////////////////////////////////////////////////////////////////////////
@@ -28,23 +26,14 @@
SXmlNodeStats* g_pCXmlNode_Stats = 0;
#endif
extern bool g_bEnableBinaryXmlLoading;
//////////////////////////////////////////////////////////////////////////
CXmlUtils::CXmlUtils(ISystem* pSystem)
{
m_pSystem = pSystem;
// create IReadWriteXMLSink object
m_pReadWriteXMLSink = new CReadWriteXMLSink();
#ifdef CRY_COLLECT_XML_NODE_STATS
g_pCXmlNode_Stats = new SXmlNodeStats();
#endif
m_pStatsXmlNodePool = nullptr;
#ifndef _RELEASE
m_statsThreadOwner = CryGetCurrentThreadId();
#endif
m_pXMLPatcher = nullptr;
}
//////////////////////////////////////////////////////////////////////////
@@ -53,8 +42,6 @@ CXmlUtils::~CXmlUtils()
#ifdef CRY_COLLECT_XML_NODE_STATS
delete g_pCXmlNode_Stats;
#endif
SAFE_DELETE(m_pStatsXmlNodePool);
SAFE_DELETE(m_pXMLPatcher);
}
//////////////////////////////////////////////////////////////////////////
@@ -65,21 +52,13 @@ IXmlParser* CXmlUtils::CreateXmlParser()
}
//////////////////////////////////////////////////////////////////////////
XmlNodeRef CXmlUtils::LoadXmlFromFile(const char* sFilename, bool bReuseStrings, bool bEnablePatching)
XmlNodeRef CXmlUtils::LoadXmlFromFile(const char* sFilename, bool bReuseStrings)
{
XmlParser parser(bReuseStrings);
XmlNodeRef node = parser.ParseFile(sFilename, true);
// XmlParser is supposed to log warnings and errors (if any),
// so we don't need to call parser.getErrorString(),
// CryLog() etc here.
if (node && bEnablePatching && m_pXMLPatcher)
{
node = m_pXMLPatcher->ApplyXMLDataPatch(node, sFilename);
}
return node;
XmlParser parser(bReuseStrings);
return parser.ParseFile(sFilename, true);
}
//////////////////////////////////////////////////////////////////////////
@@ -99,29 +78,6 @@ void GetMD5(const char* pSrcBuffer, int nSrcSize, char signatureMD5[16])
MD5Final((unsigned char*)signatureMD5, &md5c);
}
//////////////////////////////////////////////////////////////////////////
const char* CXmlUtils::HashXml(XmlNodeRef node)
{
static char signature[16 * 2 + 1];
static char temp[16];
static const char* hex = "0123456789abcdef";
XmlString str = node->getXML();
GetMD5(str.data(), static_cast<int>(str.length()), temp);
for (int i = 0; i < 16; i++)
{
signature[2 * i + 0] = hex[((uint8)temp[i]) >> 4];
signature[2 * i + 1] = hex[((uint8)temp[i]) & 0xf];
}
signature[16 * 2] = 0;
return signature;
}
//////////////////////////////////////////////////////////////////////////
IReadWriteXMLSink* CXmlUtils::GetIReadWriteXMLSink()
{
return m_pReadWriteXMLSink;
}
//////////////////////////////////////////////////////////////////////////
class CXmlSerializer
: public IXmlSerializer
@@ -172,12 +128,6 @@ public:
return m_pReaderSer;
}
void GetMemoryUsage(ICrySizer* pSizer) const override
{
pSizer->Add(*this);
pSizer->AddObject(m_pReaderImpl);
pSizer->AddObject(m_pWriterImpl);
}
//////////////////////////////////////////////////////////////////////////
private:
int m_nRefCount;
@@ -194,62 +144,6 @@ IXmlSerializer* CXmlUtils::CreateXmlSerializer()
return new CXmlSerializer;
}
//////////////////////////////////////////////////////////////////////////
void CXmlUtils::GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer)
{
#ifdef CRY_COLLECT_XML_NODE_STATS
// yes, slow
std::vector<const CXmlNode*> rootNodes;
{
TXmlNodeSet::const_iterator iter = g_pCXmlNode_Stats->nodeSet.begin();
TXmlNodeSet::const_iterator iterEnd = g_pCXmlNode_Stats->nodeSet.end();
while (iter != iterEnd)
{
const CXmlNode* pNode = *iter;
if (pNode->getParent() == 0)
{
rootNodes.push_back(pNode);
}
++iter;
}
}
// use the following to log to console
#if 0
CryLogAlways("NumXMLRootNodes=%d NumXMLNodes=%d TotalAllocs=%d TotalFrees=%d",
rootNodes.size(), g_pCXmlNode_Stats->nodeSet.size(),
g_pCXmlNode_Stats->nAllocs, g_pCXmlNode_Stats->nFrees);
#endif
// use the following to debug the nodes in the system
#if 0
{
std::vector<const CXmlNode*>::const_iterator iter = rootNodes.begin();
std::vector<const CXmlNode*>::const_iterator iterEnd = rootNodes.end();
while (iter != iterEnd)
{
const CXmlNode* pNode = *iter;
CryLogAlways("Node 0x%p Tag='%s'", pNode, pNode->getTag());
++iter;
}
}
#endif
// only for debugging, add it as pseudo numbers to the CrySizer.
// shift it by 10, so we get the actual number
{
SIZER_COMPONENT_NAME(pSizer, "#NumTotalNodes");
pSizer->Add("#NumTotalNodes", g_pCXmlNode_Stats->nodeSet.size() << 10);
}
{
SIZER_COMPONENT_NAME(pSizer, "#NumRootNodes");
pSizer->Add("#NumRootNodes", rootNodes.size() << 10);
}
#endif
}
//////////////////////////////////////////////////////////////////////////
class CXmlBinaryDataWriterFile
: public XMLBinary::IDataWriter
@@ -282,49 +176,13 @@ private:
AZ::IO::HandleType m_fileHandle;
};
//////////////////////////////////////////////////////////////////////////
bool CXmlUtils::SaveBinaryXmlFile(const char* filename, XmlNodeRef root)
{
CXmlBinaryDataWriterFile fileSink(filename);
if (!fileSink.IsOk())
{
return false;
}
XMLBinary::CXMLBinaryWriter writer;
AZStd::string error;
return writer.WriteNode(&fileSink, root, false, nullptr, error);
}
//////////////////////////////////////////////////////////////////////////
XmlNodeRef CXmlUtils::LoadBinaryXmlFile(const char* filename, bool bEnablePatching)
{
XMLBinary::XMLBinaryReader reader;
XMLBinary::XMLBinaryReader::EResult result;
XmlNodeRef root = reader.LoadFromFile(filename, result);
if (result == XMLBinary::XMLBinaryReader::eResult_Success && bEnablePatching == true && m_pXMLPatcher != nullptr)
{
root = m_pXMLPatcher->ApplyXMLDataPatch(root, filename);
}
return root;
}
//////////////////////////////////////////////////////////////////////////
bool CXmlUtils::EnableBinaryXmlLoading(bool bEnable)
{
bool bPrev = g_bEnableBinaryXmlLoading;
g_bEnableBinaryXmlLoading = bEnable;
return bPrev;
}
//////////////////////////////////////////////////////////////////////////
class CXmlTableReader
: public IXmlTableReader
{
public:
CXmlTableReader();
virtual ~CXmlTableReader();
~CXmlTableReader() override;
void Release() override;
@@ -332,7 +190,6 @@ public:
int GetEstimatedRowCount() override;
bool ReadRow(int& rowIndex) override;
bool ReadCell(int& columnIndex, const char*& pContent, size_t& contentSize) override;
float GetCurrentRowHeight() override;
private:
bool m_bExcel;
@@ -341,7 +198,6 @@ private:
XmlNodeRef m_rowNode;
float m_currentRowHeight;
int m_rowNodeIndex;
int m_row;
@@ -411,7 +267,6 @@ int CXmlTableReader::GetEstimatedRowCount()
//////////////////////////////////////////////////////////////////////////
bool CXmlTableReader::ReadRow(int& rowIndex)
{
m_currentRowHeight = 0.0f;
if (!m_tableNode)
{
return false;
@@ -459,12 +314,6 @@ bool CXmlTableReader::ReadRow(int& rowIndex)
}
m_row = index;
}
float height;
if (m_rowNode->getAttr("ss:Height", height))
{
m_currentRowHeight = height;
}
rowIndex = m_row;
return true;
}
@@ -617,75 +466,8 @@ bool CXmlTableReader::ReadCell(int& columnIndex, const char*& pContent, size_t&
}
}
float CXmlTableReader::GetCurrentRowHeight()
{
return m_currentRowHeight;
}
//////////////////////////////////////////////////////////////////////////
IXmlTableReader* CXmlUtils::CreateXmlTableReader()
{
return new CXmlTableReader;
}
//////////////////////////////////////////////////////////////////////////
// Init xml stats nodes pool
void CXmlUtils::InitStatsXmlNodePool(uint32 nPoolSize)
{
CHECK_STATS_THREAD_OWNERSHIP();
if (nullptr == m_pStatsXmlNodePool)
{
// create special xml node pools for game statistics
const bool bReuseStrings = true; // TODO parameterise?
m_pStatsXmlNodePool = new CXmlNodePool(nPoolSize, bReuseStrings);
assert(m_pStatsXmlNodePool);
}
else
{
CryLog("[CXmlNodePool]: Xml stats nodes pool already initialized");
}
}
//////////////////////////////////////////////////////////////////////////
// Creates new xml node for statistics.
XmlNodeRef CXmlUtils::CreateStatsXmlNode(const char* sNodeName)
{
CHECK_STATS_THREAD_OWNERSHIP();
if (nullptr == m_pStatsXmlNodePool)
{
CryLog("[CXmlNodePool]: Xml stats nodes pool isn't initialized. Perform default initialization.");
InitStatsXmlNodePool();
}
return m_pStatsXmlNodePool->GetXmlNode(sNodeName);
}
void CXmlUtils::SetStatsOwnerThread([[maybe_unused]] threadID threadId)
{
#ifndef _RELEASE
m_statsThreadOwner = threadId;
#endif
}
void CXmlUtils::FlushStatsXmlNodePool()
{
CHECK_STATS_THREAD_OWNERSHIP();
if (m_pStatsXmlNodePool)
{
if (m_pStatsXmlNodePool->empty())
{
SAFE_DELETE(m_pStatsXmlNodePool);
}
}
}
void CXmlUtils::SetXMLPatcher(XmlNodeRef* pPatcher)
{
SAFE_DELETE(m_pXMLPatcher);
if (pPatcher != nullptr)
{
m_pXMLPatcher = new CXMLPatcher(*pPatcher);
}
}
+1 -42
View File
@@ -20,7 +20,6 @@
#endif
class CXmlNodePool;
class CXMLPatcher;
//////////////////////////////////////////////////////////////////////////
// Implements IXmlUtils interface.
@@ -39,57 +38,17 @@ public:
virtual IXmlParser* CreateXmlParser();
// Load xml from file, returns 0 if load failed.
virtual XmlNodeRef LoadXmlFromFile(const char* sFilename, bool bReuseStrings = false, bool bEnablePatching = true);
virtual XmlNodeRef LoadXmlFromFile(const char* sFilename, bool bReuseStrings = false);
// Load xml from memory buffer, returns 0 if load failed.
virtual XmlNodeRef LoadXmlFromBuffer(const char* buffer, size_t size, bool bReuseStrings = false, bool bSuppressWarnings = false);
// create an MD5 hash of an XML file
virtual const char* HashXml(XmlNodeRef node);
// Get an object that can read a xml into a IReadXMLSink
// and write a xml from a IWriteXMLSource
virtual IReadWriteXMLSink* GetIReadWriteXMLSink();
virtual IXmlSerializer* CreateXmlSerializer();
virtual bool SaveBinaryXmlFile(const char* sFilename, XmlNodeRef root);
virtual XmlNodeRef LoadBinaryXmlFile(const char* sFilename, bool bEnablePatching = true);
virtual bool EnableBinaryXmlLoading(bool bEnable);
// Create XML Table reader.
virtual IXmlTableReader* CreateXmlTableReader();
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
virtual void GetMemoryUsage(ICrySizer* pSizer);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Init xml stats nodes pool
virtual void InitStatsXmlNodePool(uint32 nPoolSize = 1024*1024);
// Create new xml node for statistics
virtual XmlNodeRef CreateStatsXmlNode(const char* sNodeName = "");
// Set owner thread
virtual void SetStatsOwnerThread(threadID threadId);
// Free memory if stats xml node pool is empty
virtual void FlushStatsXmlNodePool();
// Set the XML Patcher. This is an XML object that modifies named XML files as they are loaded
// EXCEPT for xml files loaded from a buffer, for which names aren't passed in
virtual void SetXMLPatcher(XmlNodeRef* pPatcher);
private:
ISystem* m_pSystem;
IReadWriteXMLSink* m_pReadWriteXMLSink;
CXmlNodePool* m_pStatsXmlNodePool;
CXMLPatcher* m_pXMLPatcher; //If set, applies data patches to any XML file that is loaded by this class
#ifndef _RELEASE
threadID m_statsThreadOwner;
#endif
};
#endif // CRYINCLUDE_CRYSYSTEM_XML_XMLUTILS_H
+25 -117
View File
@@ -9,8 +9,6 @@
#include "CrySystem_precompiled.h"
//#define _CRT_SECURE_NO_DEPRECATE 1
//#define _CRT_NONSTDC_NO_DEPRECATE
#include <stdlib.h>
#define XML_STATIC // Alternative to defining this here would be setting it project-wide
@@ -19,6 +17,7 @@
#include <algorithm>
#include <stdio.h>
#include <AzFramework/Archive/IArchive.h>
#include <CryCommon/Cry_Color.h>
#include "XMLBinaryReader.h"
#define FLOAT_FMT "%.8g"
@@ -77,7 +76,6 @@ static int __cdecl ascii_stricmp(const char* dst, const char* src)
//////////////////////////////////////////////////////////////////////////
XmlStrCmpFunc g_pXmlStrCmp = &ascii_stricmp;
bool g_bEnableBinaryXmlLoading = true;
//////////////////////////////////////////////////////////////////////////
class CXmlStringData
@@ -113,10 +111,6 @@ public:
void Clear() { m_stringPool.Clear(); }
void SetBlockSize(unsigned int nBlockSize) { m_stringPool.SetBlockSize(nBlockSize); }
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(m_stringPool);
}
private:
CSimpleStringPool m_stringPool;
};
@@ -174,23 +168,6 @@ CXmlNode::CXmlNode(const char* tag, bool bReuseStrings, bool bIsProcessingInstru
m_tag = m_pStringPool->AddString(tag);
}
//////////////////////////////////////////////////////////////////////////
// collect allocated memory informations
void CXmlNode::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(m_pStringPool);
if (m_pChilds)
{
pSizer->AddObject(*m_pChilds);
}
if (m_pAttributes)
{
pSizer->AddContainer(*m_pAttributes);
}
}
//////////////////////////////////////////////////////////////////////////
XmlNodeRef CXmlNode::createNode(const char* tag)
{
@@ -378,13 +355,6 @@ void CXmlNode::setAttr(const char* key, const Vec4& value)
setAttr(key, str);
}
void CXmlNode::setAttr(const char* key, const Vec3d& value)
{
char str[128];
SCOPED_LOCALE_RESETTER;
sprintf_s(str, DOUBLE_FMT "," DOUBLE_FMT "," DOUBLE_FMT, value.x, value.y, value.z);
setAttr(key, str);
}
void CXmlNode::setAttr(const char* key, const Vec2& value)
{
char str[128];
@@ -392,13 +362,6 @@ void CXmlNode::setAttr(const char* key, const Vec2& value)
sprintf_s(str, FLOAT_FMT "," FLOAT_FMT, value.x, value.y);
setAttr(key, str);
}
void CXmlNode::setAttr(const char* key, const Vec2d& value)
{
char str[128];
SCOPED_LOCALE_RESETTER;
sprintf_s(str, DOUBLE_FMT "," DOUBLE_FMT, value.x, value.y);
setAttr(key, str);
}
void CXmlNode::setAttr(const char* key, const Quat& value)
{
@@ -557,22 +520,6 @@ bool CXmlNode::getAttr(const char* key, Vec4& value) const
return false;
}
bool CXmlNode::getAttr(const char* key, Vec3d& value) const
{
const char* svalue = GetValue(key);
if (svalue)
{
SCOPED_LOCALE_RESETTER;
double x, y, z;
if (azsscanf(svalue, "%lf,%lf,%lf", &x, &y, &z) == 3)
{
value = Vec3d(x, y, z);
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CXmlNode::getAttr(const char* key, Vec2& value) const
{
@@ -590,22 +537,6 @@ bool CXmlNode::getAttr(const char* key, Vec2& value) const
return false;
}
bool CXmlNode::getAttr(const char* key, Vec2d& value) const
{
const char* svalue = GetValue(key);
if (svalue)
{
SCOPED_LOCALE_RESETTER;
double x, y;
if (azsscanf(svalue, "%lf,%lf", &x, &y) == 2)
{
value = Vec2d(x, y);
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CXmlNode::getAttr(const char* key, Quat& value) const
{
@@ -1369,14 +1300,6 @@ public:
// Add new string to pool.
const char* AddString(const char* str) { return m_stringPool.Append(str, (int)strlen(str)); }
//char* AddString( const char *str ) { return (char*)str; }
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(m_stringPool);
pSizer->AddObject(m_nodeStack);
}
protected:
void onStartElement(const char* tagName, const char** atts);
void onEndElement(const char* tagName);
@@ -1410,12 +1333,6 @@ protected:
{
XmlNodeRef node;
std::vector<IXmlNode*> childs; //TODO: is it worth lazily initializing this, like CXmlNode::m_pChilds?
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(node);
pSizer->AddObject(childs);
}
};
// First node will become root node.
@@ -1735,38 +1652,35 @@ XmlNodeRef XmlParserImp::ParseFile(const char* filename, XmlString& errorString,
AZStd::replace(pakPath.begin(), pakPath.end(), '\\', '/');
}
if (g_bEnableBinaryXmlLoading)
XMLBinary::XMLBinaryReader reader;
XMLBinary::XMLBinaryReader::EResult result;
root = reader.LoadFromBuffer(XMLBinary::XMLBinaryReader::eBufferMemoryHandling_TakeOwnership, pFileContents, fileSize, result);
if (root)
{
XMLBinary::XMLBinaryReader reader;
XMLBinary::XMLBinaryReader::EResult result;
root = reader.LoadFromBuffer(XMLBinary::XMLBinaryReader::eBufferMemoryHandling_TakeOwnership, pFileContents, fileSize, result);
if (root)
return root;
}
if (result != XMLBinary::XMLBinaryReader::eResult_NotBinXml)
{
delete [] pFileContents;
sprintf_s(str, "%s%s (%s)", errorPrefix, reader.GetErrorDescription(), filename);
errorString = str;
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "%s", str);
return 0;
}
else
{
// not binary XML - refuse to load if in scripts dir and not in bin xml to help reduce hacking
// wish we could compile the text xml parser out, but too much work to get everything moved over
constexpr AZStd::fixed_string<32> strScripts{"Scripts/"};
// exclude files and PAKs from Mods folder
constexpr AZStd::fixed_string<8> modsStr{"Mods/"};
if (_strnicmp(filename, strScripts.c_str(), strScripts.length()) == 0 &&
_strnicmp(adjustedFilename.c_str(), modsStr.c_str(), modsStr.length()) != 0 &&
_strnicmp(pakPath.c_str(), modsStr.c_str(), modsStr.length()) != 0)
{
return root;
}
if (result != XMLBinary::XMLBinaryReader::eResult_NotBinXml)
{
delete [] pFileContents;
sprintf_s(str, "%s%s (%s)", errorPrefix, reader.GetErrorDescription(), filename);
errorString = str;
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "%s", str);
return 0;
}
else
{
// not binary XML - refuse to load if in scripts dir and not in bin xml to help reduce hacking
// wish we could compile the text xml parser out, but too much work to get everything moved over
constexpr AZStd::fixed_string<32> strScripts{"Scripts/"};
// exclude files and PAKs from Mods folder
constexpr AZStd::fixed_string<8> modsStr{"Mods/"};
if (_strnicmp(filename, strScripts.c_str(), strScripts.length()) == 0 &&
_strnicmp(adjustedFilename.c_str(), modsStr.c_str(), modsStr.length()) != 0 &&
_strnicmp(pakPath.c_str(), modsStr.c_str(), modsStr.length()) != 0)
{
#ifdef _RELEASE
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Non binary XML found in scripts dir (%s)", filename);
#endif
}
}
}
@@ -1806,12 +1720,6 @@ XmlParser::~XmlParser()
m_pImpl->Release();
}
void XmlParser::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(m_pImpl);
}
//////////////////////////////////////////////////////////////////////////
XmlNodeRef XmlParser::ParseBuffer(const char* buffer, int nBufLen, bool bCleanPools, bool bSuppressWarnings)
{
-12
View File
@@ -34,7 +34,6 @@ public:
}
};
virtual const char* AddString(const char* str) = 0;
virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0;
private:
int m_refCount;
};
@@ -68,8 +67,6 @@ public:
const char* getErrorString() const { return m_errorString; }
void GetMemoryUsage(ICrySizer* pSizer) const;
private:
int m_nRefCount;
XmlString m_errorString;
@@ -88,8 +85,6 @@ struct XmlAttribute
const char* key;
const char* value;
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{}
bool operator<(const XmlAttribute& attr) const { return g_pXmlStrCmp(key, attr.key) < 0; }
bool operator>(const XmlAttribute& attr) const { return g_pXmlStrCmp(key, attr.key) > 0; }
bool operator==(const XmlAttribute& attr) const { return g_pXmlStrCmp(key, attr.key) == 0; }
@@ -119,9 +114,6 @@ public:
//! Destructor.
~CXmlNode();
// collect allocated memory informations
void GetMemoryUsage(ICrySizer* pSizer) const;
//////////////////////////////////////////////////////////////////////////
// Custom new/delete with pool allocator.
//////////////////////////////////////////////////////////////////////////
@@ -220,11 +212,9 @@ public:
void setAttr(const char* key, float value);
void setAttr(const char* key, double value);
void setAttr(const char* key, const Vec2& value);
void setAttr(const char* key, const Vec2d& value);
void setAttr(const char* key, const Ang3& value);
void setAttr(const char* key, const Vec3& value);
void setAttr(const char* key, const Vec4& value);
void setAttr(const char* key, const Vec3d& value);
void setAttr(const char* key, const Quat& value);
//! Delete attrbute.
@@ -244,11 +234,9 @@ public:
bool getAttr(const char* key, XmlString& value) const {const char* v(NULL); bool boHasAttribute(getAttr(key, &v)); value = v; return boHasAttribute; }
bool getAttr(const char* key, Vec2& value) const;
bool getAttr(const char* key, Vec2d& value) const;
bool getAttr(const char* key, Ang3& value) const;
bool getAttr(const char* key, Vec3& value) const;
bool getAttr(const char* key, Vec4& value) const;
bool getAttr(const char* key, Vec3d& value) const;
bool getAttr(const char* key, Quat& value) const;
bool getAttr(const char* key, ColorB& value) const;
-17
View File
@@ -1,17 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_CRYSYSTEM_XML_XML_STRING_H
#define CRYINCLUDE_CRYSYSTEM_XML_XML_STRING_H
#pragma once
typedef string xml_string;
#endif // CRYINCLUDE_CRYSYSTEM_XML_XML_STRING_H
@@ -23,7 +23,6 @@ set(FILES
Timer.cpp
XConsole.cpp
XConsoleVariable.cpp
XML/ReadWriteXMLSink.h
AZCrySystemInitLogSink.h
AZCoreLogSink.h
CmdLine.h
@@ -36,7 +35,6 @@ set(FILES
SimpleStringPool.h
CrySystem_precompiled.h
System.h
SystemCFG.h
SystemEventDispatcher.h
Timer.h
XConsole.h
@@ -44,16 +42,11 @@ set(FILES
XML/SerializeXMLReader.cpp
XML/SerializeXMLWriter.cpp
XML/xml.cpp
XML/XMLPatcher.cpp
XML/XmlUtils.cpp
XML/SerializeXMLReader.h
XML/SerializeXMLWriter.h
XML/xml.h
XML/XMLPatcher.h
XML/xml_string.h
XML/XmlUtils.h
XML/ReadXMLSink.cpp
XML/WriteXMLSource.cpp
LocalizedStringManager.cpp
LocalizedStringManager.h
Huffman.cpp