Move CLanguage and LoadLanguageIndexfile to localization

The `CLanguage` class and `LoadLanguageIndexfile` function are more appropriately located in the file for the other localization functions.
This commit is contained in:
Robert Müller 2023-03-20 21:06:53 +01:00
parent 413227a5c1
commit 481698c7d0
3 changed files with 101 additions and 91 deletions

View file

@ -2026,96 +2026,16 @@ void CMenus::RenderSettingsSound(CUIRect MainView)
}
}
class CLanguage
{
public:
CLanguage() = default;
CLanguage(const char *pName, const char *pFileName, int Code) :
m_Name(pName), m_FileName(pFileName), m_CountryCode(Code) {}
std::string m_Name;
std::string m_FileName;
int m_CountryCode;
bool operator<(const CLanguage &Other) const { return m_Name < Other.m_Name; }
};
void LoadLanguageIndexfile(IStorage *pStorage, IConsole *pConsole, std::vector<CLanguage> &vLanguages)
{
const char *pFilename = "languages/index.txt";
IOHANDLE File = pStorage->OpenFile(pFilename, IOFLAG_READ | IOFLAG_SKIP_BOM, IStorage::TYPE_ALL);
if(!File)
{
char aBuf[128];
str_format(aBuf, sizeof(aBuf), "couldn't open index file '%s'", pFilename);
pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", aBuf);
return;
}
char aOrigin[128];
char aReplacement[128];
CLineReader LineReader;
LineReader.Init(File);
char *pLine;
while((pLine = LineReader.Get()))
{
if(!str_length(pLine) || pLine[0] == '#') // skip empty lines and comments
continue;
str_copy(aOrigin, pLine);
pLine = LineReader.Get();
if(!pLine)
{
pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", "unexpected end of index file");
break;
}
if(pLine[0] != '=' || pLine[1] != '=' || pLine[2] != ' ')
{
char aBuf[128];
str_format(aBuf, sizeof(aBuf), "malform replacement for index '%s'", aOrigin);
pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", aBuf);
(void)LineReader.Get();
continue;
}
str_copy(aReplacement, pLine + 3);
pLine = LineReader.Get();
if(!pLine)
{
pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", "unexpected end of index file");
break;
}
if(pLine[0] != '=' || pLine[1] != '=' || pLine[2] != ' ')
{
char aBuf[128];
str_format(aBuf, sizeof(aBuf), "malform replacement for index '%s'", aOrigin);
pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", aBuf);
continue;
}
char aFileName[IO_MAX_PATH_LENGTH];
str_format(aFileName, sizeof(aFileName), "languages/%s.txt", aOrigin);
vLanguages.emplace_back(aReplacement, aFileName, str_toint(pLine + 3));
}
io_close(File);
}
bool CMenus::RenderLanguageSelection(CUIRect MainView)
{
static int s_SelectedLanguage = -1;
static std::vector<CLanguage> s_vLanguages;
static CListBox s_ListBox;
if(s_vLanguages.empty())
if(g_Localization.Languages().empty())
{
s_vLanguages.emplace_back("English", "", 826);
LoadLanguageIndexfile(Storage(), Console(), s_vLanguages);
std::sort(s_vLanguages.begin(), s_vLanguages.end());
for(size_t i = 0; i < s_vLanguages.size(); i++)
if(str_comp(s_vLanguages[i].m_FileName.c_str(), g_Config.m_ClLanguagefile) == 0)
g_Localization.LoadIndexfile(Storage(), Console());
for(size_t i = 0; i < g_Localization.Languages().size(); i++)
if(str_comp(g_Localization.Languages()[i].m_FileName.c_str(), g_Config.m_ClLanguagefile) == 0)
{
s_SelectedLanguage = i;
break;
@ -2124,11 +2044,11 @@ bool CMenus::RenderLanguageSelection(CUIRect MainView)
const int OldSelected = s_SelectedLanguage;
s_ListBox.DoStart(24.0f, s_vLanguages.size(), 1, 3, s_SelectedLanguage, &MainView, true);
s_ListBox.DoStart(24.0f, g_Localization.Languages().size(), 1, 3, s_SelectedLanguage, &MainView, true);
for(auto &Language : s_vLanguages)
for(const auto &Language : g_Localization.Languages())
{
const CListboxItem Item = s_ListBox.DoNextItem(&Language.m_Name, s_SelectedLanguage != -1 && !str_comp(s_vLanguages[s_SelectedLanguage].m_Name.c_str(), Language.m_Name.c_str()));
const CListboxItem Item = s_ListBox.DoNextItem(&Language.m_Name, s_SelectedLanguage != -1 && !str_comp(g_Localization.Languages()[s_SelectedLanguage].m_Name.c_str(), Language.m_Name.c_str()));
if(!Item.m_Visible)
continue;
@ -2148,8 +2068,8 @@ bool CMenus::RenderLanguageSelection(CUIRect MainView)
if(OldSelected != s_SelectedLanguage)
{
str_copy(g_Config.m_ClLanguagefile, s_vLanguages[s_SelectedLanguage].m_FileName.c_str());
g_Localization.Load(s_vLanguages[s_SelectedLanguage].m_FileName.c_str(), Storage(), Console());
str_copy(g_Config.m_ClLanguagefile, g_Localization.Languages()[s_SelectedLanguage].m_FileName.c_str());
g_Localization.Load(g_Localization.Languages()[s_SelectedLanguage].m_FileName.c_str(), Storage(), Console());
GameClient()->OnLanguageChange();
}

View file

@ -35,9 +35,73 @@ CLocalizationDatabase::CLocalizationDatabase()
m_CurrentVersion = 0;
}
void CLocalizationDatabase::AddString(const char *pOrgStr, const char *pNewStr, const char *pContext)
void CLocalizationDatabase::LoadIndexfile(IStorage *pStorage, IConsole *pConsole)
{
m_vStrings.emplace_back(str_quickhash(pOrgStr), str_quickhash(pContext), m_StringsHeap.StoreString(*pNewStr ? pNewStr : pOrgStr));
m_vLanguages.clear();
m_vLanguages.emplace_back("English", "", 826);
const char *pFilename = "languages/index.txt";
IOHANDLE File = pStorage->OpenFile(pFilename, IOFLAG_READ | IOFLAG_SKIP_BOM, IStorage::TYPE_ALL);
if(!File)
{
char aBuf[128];
str_format(aBuf, sizeof(aBuf), "couldn't open index file '%s'", pFilename);
pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", aBuf);
return;
}
char aOrigin[128];
char aReplacement[128];
CLineReader LineReader;
LineReader.Init(File);
char *pLine;
while((pLine = LineReader.Get()))
{
if(!str_length(pLine) || pLine[0] == '#') // skip empty lines and comments
continue;
str_copy(aOrigin, pLine);
pLine = LineReader.Get();
if(!pLine)
{
pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", "unexpected end of index file");
break;
}
if(pLine[0] != '=' || pLine[1] != '=' || pLine[2] != ' ')
{
char aBuf[128];
str_format(aBuf, sizeof(aBuf), "malform replacement for index '%s'", aOrigin);
pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", aBuf);
(void)LineReader.Get();
continue;
}
str_copy(aReplacement, pLine + 3);
pLine = LineReader.Get();
if(!pLine)
{
pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", "unexpected end of index file");
break;
}
if(pLine[0] != '=' || pLine[1] != '=' || pLine[2] != ' ')
{
char aBuf[128];
str_format(aBuf, sizeof(aBuf), "malform replacement for index '%s'", aOrigin);
pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", aBuf);
continue;
}
char aFileName[IO_MAX_PATH_LENGTH];
str_format(aFileName, sizeof(aFileName), "languages/%s.txt", aOrigin);
m_vLanguages.emplace_back(aReplacement, aFileName, str_toint(pLine + 3));
}
io_close(File);
std::sort(m_vLanguages.begin(), m_vLanguages.end());
}
bool CLocalizationDatabase::Load(const char *pFilename, IStorage *pStorage, IConsole *pConsole)
@ -119,6 +183,11 @@ bool CLocalizationDatabase::Load(const char *pFilename, IStorage *pStorage, ICon
return true;
}
void CLocalizationDatabase::AddString(const char *pOrgStr, const char *pNewStr, const char *pContext)
{
m_vStrings.emplace_back(str_quickhash(pOrgStr), str_quickhash(pContext), m_StringsHeap.StoreString(*pNewStr ? pNewStr : pOrgStr));
}
const char *CLocalizationDatabase::FindString(unsigned Hash, unsigned ContextHash) const
{
CString String;

View file

@ -4,9 +4,26 @@
#define GAME_LOCALIZATION_H
#include <base/system.h> // GNUC_ATTRIBUTE
#include <engine/shared/memheap.h>
#include <string>
#include <vector>
class CLanguage
{
public:
CLanguage() = default;
CLanguage(const char *pName, const char *pFileName, int Code) :
m_Name(pName), m_FileName(pFileName), m_CountryCode(Code) {}
std::string m_Name;
std::string m_FileName;
int m_CountryCode;
bool operator<(const CLanguage &Other) const { return m_Name < Other.m_Name; }
};
class CLocalizationDatabase
{
class CString
@ -27,6 +44,7 @@ class CLocalizationDatabase
bool operator==(const CString &Other) const { return m_Hash == Other.m_Hash && m_ContextHash == Other.m_ContextHash; }
};
std::vector<CLanguage> m_vLanguages;
std::vector<CString> m_vStrings;
CHeap m_StringsHeap;
int m_VersionCounter;
@ -35,6 +53,9 @@ class CLocalizationDatabase
public:
CLocalizationDatabase();
void LoadIndexfile(class IStorage *pStorage, class IConsole *pConsole);
const std::vector<CLanguage> &Languages() const { return m_vLanguages; }
bool Load(const char *pFilename, class IStorage *pStorage, class IConsole *pConsole);
int Version() const { return m_CurrentVersion; }