1
0
forked from 0ad/0ad

Add hotloading for translation files. Fixes #2915.

This was SVN commit r15947.
This commit is contained in:
leper 2014-11-09 16:58:14 +00:00
parent 8b9847e007
commit e108b162b6
4 changed files with 72 additions and 1 deletions

View File

@ -272,6 +272,15 @@ Status CGUIManager::ReloadChangedFile(const VfsPath& path)
return INFO::OK;
}
Status CGUIManager::ReloadAllPages()
{
// TODO: this can crash if LoadPage runs an init script which modifies the page stack and breaks our iterators
for (PageStackType::iterator it = m_PageStack.begin(); it != m_PageStack.end(); ++it)
LoadPage(*it);
return INFO::OK;
}
CScriptVal CGUIManager::GetSavedGameData(ScriptInterface*& pPageScriptInterface)
{
JSContext* cx = top()->GetScriptInterface()->GetContext();

View File

@ -92,6 +92,11 @@ public:
*/
Status ReloadChangedFile(const VfsPath& path);
/**
* Called when we should reload all pages (e.g. translation hotloading update).
*/
Status ReloadAllPages();
/**
* Pass input events to the currently active GUI page.
*/

View File

@ -25,17 +25,23 @@
#include <iostream>
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/concept_check.hpp>
#include "gui/GUIManager.h"
#include "lib/file/file_system.h"
#include "lib/utf8.h"
#include "ps/CLogger.h"
#include "ps/ConfigDB.h"
#include "ps/Filesystem.h"
#include "ps/GameSetup/GameSetup.h"
static Status ReloadChangedFileCB(void* param, const VfsPath& path)
{
return static_cast<L10n*>(param)->ReloadChangedFile(path);
}
L10n::L10n()
: currentLocaleIsOriginalGameLocale(false), useLongStrings(false), dictionary(new tinygettext::Dictionary())
{
@ -52,10 +58,15 @@ L10n::L10n()
LoadListOfAvailableLocales();
ReevaluateCurrentLocaleAndReload();
// Handle hotloading
RegisterFileReloadFunc(ReloadChangedFileCB, this);
}
L10n::~L10n()
{
UnregisterFileReloadFunc(ReloadChangedFileCB, this);
for (std::vector<Locale*>::iterator iterator = availableLocales.begin(); iterator != availableLocales.end(); ++iterator)
delete *iterator;
delete dictionary;
@ -437,6 +448,46 @@ VfsPath L10n::LocalizePath(VfsPath sourcePath)
return path;
}
Status L10n::ReloadChangedFile(const VfsPath& path)
{
if (!boost::algorithm::starts_with(path.string(), L"l10n/"))
return INFO::OK;
if (path.Extension() != L".po")
return INFO::OK;
// If the file was deleted, ignore it
if (!VfsFileExists(path))
return INFO::OK;
std::wstring dictName = GetFallbackToAvailableDictLocale(currentLocale);
if (useLongStrings)
dictName = L"long";
if (dictName.empty())
return INFO::OK;
// Only the currently used language is loaded, so ignore all others
if (path.string().rfind(dictName) == std::string::npos)
return INFO::OK;
LOGMESSAGE(L"Hotloading translations from '%ls'", path.string().c_str());
CVFSFile file;
if (file.Load(g_VFS, path) != PSRETURN_OK)
{
LOGERROR(L"Failed to read translations from '%ls'", path.string().c_str());
return ERR::FAIL;
}
std::string content = file.DecodeUTF8();
ReadPoIntoDictionary(content, dictionary);
if (g_GUI)
g_GUI->ReloadAllPages();
return INFO::OK;
}
void L10n::LoadDictionaryForCurrentLocale()
{
delete dictionary;

View File

@ -528,6 +528,12 @@ public:
*/
VfsPath LocalizePath(VfsPath sourcePath);
/**
* Loads @p path into the dictionary if it is a translation file of the
* @link L10n::GetCurrentLocale() current locale@endlink.
*/
Status ReloadChangedFile(const VfsPath& path);
private:
/**