From 11c453a71f0c803b6426fb9290bc3b4d20cc3b99 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Jan 2019 21:03:25 +0100 Subject: [PATCH] - fix handling of the global script in FraggleScript. Depending on serialization order is not a good idea here, so now it's no longer stored as a parent in the main level script but explicitly checked for when looking for a variable. --- src/fragglescript/t_oper.cpp | 11 ++++++----- src/fragglescript/t_parse.cpp | 4 ++-- src/fragglescript/t_script.cpp | 18 +++++++----------- src/fragglescript/t_script.h | 4 ++-- src/fragglescript/t_variable.cpp | 10 ++++++++-- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/fragglescript/t_oper.cpp b/src/fragglescript/t_oper.cpp index 3208eb9e66..8b4368db77 100644 --- a/src/fragglescript/t_oper.cpp +++ b/src/fragglescript/t_oper.cpp @@ -31,6 +31,7 @@ /* includes ************************/ #include "t_script.h" +#include "g_levellocals.h" #define evaluate_leftnright(a, b, c) {\ @@ -84,7 +85,7 @@ void FParser::OPequals(svalue_t &result, int start, int n, int stop) { DFsVariable *var; - var = Script->FindVariable(Tokens[start]); + var = Script->FindVariable(Tokens[start], Level->FraggleScriptThinker->GlobalScript); if(var) { @@ -478,7 +479,7 @@ void FParser::OPincrement(svalue_t &result, int start, int n, int stop) { DFsVariable *var; - var = Script->FindVariable(Tokens[stop]); + var = Script->FindVariable(Tokens[stop], Level->FraggleScriptThinker->GlobalScript); if(!var) { script_error("unknown variable '%s'\n", Tokens[stop]); @@ -503,7 +504,7 @@ void FParser::OPincrement(svalue_t &result, int start, int n, int stop) svalue_t newvalue; DFsVariable *var; - var = Script->FindVariable(Tokens[start]); + var = Script->FindVariable(Tokens[start], Level->FraggleScriptThinker->GlobalScript); if(!var) { script_error("unknown variable '%s'\n", Tokens[start]); @@ -541,7 +542,7 @@ void FParser::OPdecrement(svalue_t &result, int start, int n, int stop) { DFsVariable *var; - var = Script->FindVariable(Tokens[stop]); + var = Script->FindVariable(Tokens[stop], Level->FraggleScriptThinker->GlobalScript); if(!var) { script_error("unknown variable '%s'\n", Tokens[stop]); @@ -567,7 +568,7 @@ void FParser::OPdecrement(svalue_t &result, int start, int n, int stop) svalue_t newvalue; DFsVariable *var; - var = Script->FindVariable(Tokens[start]); + var = Script->FindVariable(Tokens[start], Level->FraggleScriptThinker->GlobalScript); if(!var) { script_error("unknown variable '%s'\n", Tokens[start]); diff --git a/src/fragglescript/t_parse.cpp b/src/fragglescript/t_parse.cpp index d7747b1bc2..16cfdda492 100644 --- a/src/fragglescript/t_parse.cpp +++ b/src/fragglescript/t_parse.cpp @@ -34,7 +34,7 @@ #include #include "t_script.h" #include "v_text.h" - +#include "g_levellocals.h""" CVAR(Bool, script_debug, false, 0) @@ -561,7 +561,7 @@ void FParser::SimpleEvaluate(svalue_t &returnvar, int n) break; case name_: - var = Script->FindVariable(Tokens[n]); + var = Script->FindVariable(Tokens[n], Level->FraggleScriptThinker->GlobalScript); if(!var) { script_error("unknown variable '%s'\n", Tokens[n]); diff --git a/src/fragglescript/t_script.cpp b/src/fragglescript/t_script.cpp index 47f0a1bf3a..818323eefe 100644 --- a/src/fragglescript/t_script.cpp +++ b/src/fragglescript/t_script.cpp @@ -176,8 +176,6 @@ void DFsScript::OnDestroy() void DFsScript::Serialize(FSerializer &arc) { Super::Serialize(arc); - // don't save a reference to the global script, which contains unserializable data. - if (parent == level.FraggleScriptThinker->GlobalScript) parent = nullptr; arc("data", data) ("scriptnum", scriptnum) @@ -188,8 +186,6 @@ void DFsScript::Serialize(FSerializer &arc) .Array("sections", sections, SECTIONSLOTS) .Array("variables", variables, VARIABLESLOTS) .Array("children", children, MAXSCRIPTS); - - if (parent == nullptr) parent = level.FraggleScriptThinker->GlobalScript; } //========================================================================== @@ -200,7 +196,7 @@ void DFsScript::Serialize(FSerializer &arc) // //========================================================================== -void DFsScript::ParseScript(char *position) +void DFsScript::ParseScript(char *position, AActor **pTrigger) { if (position == nullptr) { @@ -215,7 +211,7 @@ void DFsScript::ParseScript(char *position) return; } - level.FraggleScriptThinker->trigger_obj = trigger; // set trigger + *pTrigger = trigger; // set trigger variable. try { @@ -387,7 +383,7 @@ void DFraggleThinker::Construct() RunningScripts = Create(); GC::WriteBarrier(this, RunningScripts); LevelScript = Create(); - LevelScript->parent = GlobalScript; + LevelScript->parent = nullptr; GC::WriteBarrier(this, LevelScript); } @@ -465,10 +461,10 @@ bool DFraggleThinker::wait_finished(DRunningScript *script) case wt_tagwait: { int secnum; - auto itr = level.GetSectorTagIterator(script->wait_data); + auto itr = Level->GetSectorTagIterator(script->wait_data); while ((secnum = itr.Next()) >= 0) { - sector_t *sec = &level.sectors[secnum]; + sector_t *sec = &Level->sectors[secnum]; if(sec->floordata || sec->ceilingdata || sec->lightingdata) return false; // not finished } @@ -532,7 +528,7 @@ void DFraggleThinker::Tick() next = current->next; // save before freeing // continue the script - current->script->ParseScript (current->script->data + current->save_point); + current->script->ParseScript (current->script->data + current->save_point, &trigger_obj); // free current->Destroy(); @@ -623,7 +619,7 @@ void T_PreprocessScripts(FLevelLocals *Level) th->LevelScript->trigger = players[0].mo; th->LevelScript->Preprocess(); - th->LevelScript->ParseScript(); + th->LevelScript->ParseScript(nullptr, &th->trigger_obj); } } diff --git a/src/fragglescript/t_script.h b/src/fragglescript/t_script.h index 3887f736d1..6d09d0d012 100644 --- a/src/fragglescript/t_script.h +++ b/src/fragglescript/t_script.h @@ -341,7 +341,7 @@ public: void NewFunction(const char *name, void (FParser::*handler)()); DFsVariable *VariableForName(const char *name); - DFsVariable *FindVariable(const char *name); + DFsVariable *FindVariable(const char *name, DFsScript *global); void ClearVariables(bool complete= false); DFsVariable *NewLabel(char *labelptr); char *LabelValue(const svalue_t &v); @@ -363,7 +363,7 @@ public: void DryRunScript(); void Preprocess(); void ParseInclude(char *lumpname); - void ParseScript(char *rover = NULL); + void ParseScript(char *rover, AActor **pTrigger); void ParseData(char *rover, char *data, char *end); }; diff --git a/src/fragglescript/t_variable.cpp b/src/fragglescript/t_variable.cpp index 25776970e4..c73bf14fc8 100644 --- a/src/fragglescript/t_variable.cpp +++ b/src/fragglescript/t_variable.cpp @@ -364,7 +364,7 @@ DFsVariable *DFsScript::VariableForName(const char *name) // //========================================================================== -DFsVariable *DFsScript::FindVariable(const char *name) +DFsVariable *DFsScript::FindVariable(const char *name, DFsScript *GlobalScript) { DFsVariable *var; DFsScript *current = this; @@ -374,7 +374,13 @@ DFsVariable *DFsScript::FindVariable(const char *name) // check this script if ((var = current->VariableForName(name))) return var; - current = current->parent; // try the parent of this one + + // Since the global script cannot be serialized, we cannot store a pointer to it, because this cannot be safely restored during deserialization. + // To compensate we need to check the relationship explicitly here. + if (current->parent == nullptr && current != GlobalScript) + current = GlobalScript; + else + current = current->parent; // try the parent of this one } return NULL; // no variable