forked from Mirrors/openclonk
Fix crash on global or scenario script reload.
The string table of System.ocg scripts (except the global System.ocg) pointed to nowhere after the initial load phase, but is still required for reload. Added a ref counting option to keep these string tables alive.lights3
parent
0d102d2184
commit
5ec9999d4c
|
@ -23,7 +23,7 @@
|
|||
#include "C4LangStringTable.h"
|
||||
#include "C4InputValidation.h"
|
||||
|
||||
C4LangStringTable::C4LangStringTable() {}
|
||||
C4LangStringTable::C4LangStringTable() : ref_count(1) {}
|
||||
|
||||
bool C4LangStringTable::HasTranslation(const std::string &text) const
|
||||
{
|
||||
|
|
|
@ -30,6 +30,7 @@ class C4LangStringTable : public C4ComponentHost
|
|||
typedef std::map<std::string, std::string> Table;
|
||||
mutable Table strings;
|
||||
void PopulateStringTable() const;
|
||||
int32_t ref_count; // ref counter initialized to 1 on ctor; delete when zero is reached
|
||||
public:
|
||||
C4LangStringTable();
|
||||
const std::string &Translate(const std::string &text) const;
|
||||
|
@ -39,6 +40,9 @@ public:
|
|||
void ReplaceStrings(StdStrBuf &rBuf);
|
||||
void ReplaceStrings(const StdStrBuf &rBuf, StdStrBuf &rTarget);
|
||||
|
||||
void AddRef() { ++ref_count; }
|
||||
void DelRef() { if (!--ref_count) delete this; }
|
||||
|
||||
class NoSuchTranslation : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -2827,14 +2827,14 @@ bool C4Game::LoadAdditionalSystemGroup(C4Group &parent_group)
|
|||
char fn[_MAX_FNAME+1] = { 0 };
|
||||
if (SysGroup.OpenAsChild(&parent_group, C4CFN_System))
|
||||
{
|
||||
C4LangStringTable SysGroupString;
|
||||
C4Language::LoadComponentHost(&SysGroupString, SysGroup, C4CFN_ScriptStringTbl, Config.General.LanguageEx);
|
||||
C4LangStringTable *pSysGroupString = new C4LangStringTable();
|
||||
C4Language::LoadComponentHost(pSysGroupString, SysGroup, C4CFN_ScriptStringTbl, Config.General.LanguageEx);
|
||||
// load custom scenario control definitions
|
||||
if (SysGroup.FindEntry(C4CFN_PlayerControls))
|
||||
{
|
||||
Log("[!]Loading local scenario player control definitions...");
|
||||
C4PlayerControlFile PlayerControlFile;
|
||||
if (!PlayerControlFile.Load(SysGroup, C4CFN_PlayerControls, &SysGroupString))
|
||||
if (!PlayerControlFile.Load(SysGroup, C4CFN_PlayerControls, pSysGroupString))
|
||||
{
|
||||
// non-fatal error here
|
||||
Log("[!]Error loading scenario defined player controls");
|
||||
|
@ -2854,12 +2854,14 @@ bool C4Game::LoadAdditionalSystemGroup(C4Group &parent_group)
|
|||
// host will be destroyed by script engine, so drop the references
|
||||
C4ScriptHost *scr = new C4ExtraScriptHost();
|
||||
scr->Reg2List(&ScriptEngine);
|
||||
scr->Load(SysGroup, fn, Config.General.LanguageEx, &SysGroupString);
|
||||
scr->Load(SysGroup, fn, Config.General.LanguageEx, pSysGroupString);
|
||||
}
|
||||
// if it's a physical group: watch out for changes
|
||||
if (!SysGroup.IsPacked() && Game.pFileMonitor)
|
||||
Game.pFileMonitor->AddDirectory(SysGroup.GetFullName().getData());
|
||||
SysGroup.Close();
|
||||
// release string table if no longer used
|
||||
pSysGroupString->DelRef();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,11 @@ void C4ScriptHost::Clear()
|
|||
LocalValues.Clear();
|
||||
SourceScripts.clear();
|
||||
SourceScripts.push_back(this);
|
||||
if (stringTable)
|
||||
{
|
||||
stringTable->DelRef();
|
||||
stringTable = NULL;
|
||||
}
|
||||
// remove includes
|
||||
Includes.clear();
|
||||
Appends.clear();
|
||||
|
@ -62,7 +67,12 @@ bool C4ScriptHost::Load(C4Group &hGroup, const char *szFilename,
|
|||
// Base load
|
||||
bool fSuccess = ComponentHost.Load(hGroup,szFilename,szLanguage);
|
||||
// String Table
|
||||
stringTable = pLocalTable;
|
||||
if (stringTable != pLocalTable)
|
||||
{
|
||||
if (stringTable) stringTable->DelRef();
|
||||
stringTable = pLocalTable;
|
||||
if (stringTable) stringTable->AddRef();
|
||||
}
|
||||
// set name
|
||||
ScriptName.Ref(ComponentHost.GetFilePath());
|
||||
// preparse script
|
||||
|
@ -73,7 +83,13 @@ bool C4ScriptHost::Load(C4Group &hGroup, const char *szFilename,
|
|||
|
||||
bool C4ScriptHost::LoadData(const char *szFilename, const char *szData, class C4LangStringTable *pLocalTable)
|
||||
{
|
||||
stringTable = pLocalTable;
|
||||
// String Table
|
||||
if (stringTable != pLocalTable)
|
||||
{
|
||||
if (stringTable) stringTable->DelRef();
|
||||
stringTable = pLocalTable;
|
||||
if (stringTable) stringTable->AddRef();
|
||||
}
|
||||
ScriptName.Copy(szFilename);
|
||||
|
||||
StdStrBuf tempScript;
|
||||
|
|
Loading…
Reference in New Issue