Skip to content

Commit

Permalink
Merge pull request #2621 from ivan-mogilko/experiment--nonforkingscri…
Browse files Browse the repository at this point in the history
…ptrunner

AGS 4.0: rewrite ccInstance into non-forking ScriptExecutor
  • Loading branch information
ivan-mogilko authored Jan 31, 2025
2 parents ecba911 + 2d98d99 commit 35e5663
Show file tree
Hide file tree
Showing 48 changed files with 2,211 additions and 1,766 deletions.
4 changes: 2 additions & 2 deletions Common/game/main_game_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,15 +213,15 @@ HGameFileError OpenMainGameFileFromDefaultAsset(MainGameSource &src, AssetManage
return OpenMainGameFileBase(src);
}

HGameFileError ReadDialogScript(PScript &dialog_script, Stream *in, GameDataVersion data_ver)
HGameFileError ReadDialogScript(UScript &dialog_script, Stream *in, GameDataVersion data_ver)
{
dialog_script.reset(ccScript::CreateFromStream(in));
if (dialog_script == nullptr)
return new MainGameFileError(kMGFErr_CreateDialogScriptFailed, cc_get_error().ErrorString);
return HGameFileError::None();
}

HGameFileError ReadScriptModules(std::vector<PScript> &sc_mods, Stream *in, GameDataVersion data_ver)
HGameFileError ReadScriptModules(std::vector<UScript> &sc_mods, Stream *in, GameDataVersion data_ver)
{
int count = in->ReadInt32();
sc_mods.resize(count);
Expand Down
6 changes: 3 additions & 3 deletions Common/game/main_game_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ struct LoadedGameEntities
GUICollection GuiControls;
std::vector<DialogTopic> Dialogs;
std::vector<ViewStruct> Views;
PScript GlobalScript;
PScript DialogScript;
std::vector<PScript> ScriptModules;
UScript GlobalScript;
UScript DialogScript;
std::vector<UScript> ScriptModules;
std::vector<PluginInfo> PluginInfos;

// Original sprite data (when it was read into const-sized arrays)
Expand Down
1 change: 0 additions & 1 deletion Common/game/roomstruct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
// https://opensource.org/license/artistic-2-0/
//
//=============================================================================

#include "ac/common.h" // quit
#include "game/room_file.h"
#include "game/roomstruct.h"
Expand Down
7 changes: 2 additions & 5 deletions Common/game/roomstruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,11 @@
#include "ac/common_defines.h"
#include "game/interactions.h"
#include "gfx/gfx_def.h"
#include "script/cc_script.h"
#include "util/error.h"
#include "util/geometry.h"
#include "util/string_types.h"

struct ccScript;
struct SpriteInfo;
typedef std::shared_ptr<ccScript> PScript;

// TODO: move the following enums under AGS::Common namespace
// later, when more engine source is put in AGS namespace and
// refactored.
Expand Down Expand Up @@ -325,7 +322,7 @@ class RoomStruct
// Event script links
UInteractionEvents EventHandlers;
// Compiled room script
PScript CompiledScript;
UScript CompiledScript;
// Various extended options with string values, meta-data etc
StringMap StrOptions;
};
Expand Down
1 change: 1 addition & 0 deletions Common/script/cc_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
#define CC_NUM_SCCMDS 76
#define MAX_SCMD_ARGS 3 // maximal possible number of arguments

#define EXPORT_NONE 0
#define EXPORT_FUNCTION 1
#define EXPORT_DATA 2

Expand Down
37 changes: 37 additions & 0 deletions Common/script/cc_reflect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,21 @@ void RTTISerializer::Write(const RTTI &rtti, Stream *out)
out->Seek(end_soff, kSeekBegin);
}

RTTI::RTTI(const RTTI &rtti)
{
*this = rtti;
}

RTTI &RTTI::operator=(const RTTI &rtti)
{
_locs = rtti._locs;
_types = rtti._types;
_fields = rtti._fields;
_strings = rtti._strings;
CreateQuickRefs();
return *this;
}

const RTTI::Location *RTTI::FindLocationByLocalID(uint32_t loc_id) const
{
if (loc_id >= _locs.size())
Expand Down Expand Up @@ -785,6 +800,28 @@ void ScriptTOCSerializer::Write(const ScriptTOC &toc, Stream *out)
out->Seek(end_soff, kSeekBegin);
}

ScriptTOC::ScriptTOC(const ScriptTOC &toc)
{
*this = toc;
}

ScriptTOC &ScriptTOC::operator=(const ScriptTOC &toc)
{
_glVariables = toc._glVariables;
_locVariables = toc._locVariables;
_functions = toc._functions;
_fparams = toc._fparams;
_strings = toc._strings;
// FIXME: this is dangerous because of how RTTI is referenced using raw pointer
CreateQuickRefs(toc._rtti);
return *this;
}

void ScriptTOC::RebindRTTI(RTTI *rtti)
{
CreateQuickRefs(rtti);
}

void ScriptTOC::CreateQuickRefs(const RTTI *rtti)
{
for (auto &var : _glVariables)
Expand Down
16 changes: 10 additions & 6 deletions Common/script/cc_reflect.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,10 @@ class RTTI
_strings.push_back(0); // guarantee zero-len string at index 0
}

RTTI(const RTTI &rtti) = default;
RTTI(const RTTI &rtti);
RTTI(RTTI &&rtti) = default;

RTTI &operator = (const RTTI &rtti) = default;
RTTI &operator = (const RTTI &rtti);
RTTI &operator = (RTTI &&rtti) = default;

bool IsEmpty() const { return _types.empty(); }
Expand Down Expand Up @@ -454,11 +454,11 @@ class ScriptTOC
_strings.push_back(0); // guarantee zero-len string at index 0
}

ScriptTOC(const ScriptTOC &rtti) = default;
ScriptTOC(ScriptTOC &&rtti) = default;
ScriptTOC(const ScriptTOC &toc);
ScriptTOC(ScriptTOC &&toc) = default;

ScriptTOC &operator = (const ScriptTOC &rtti) = default;
ScriptTOC &operator = (ScriptTOC &&rtti) = default;
ScriptTOC &operator = (const ScriptTOC &toc);
ScriptTOC &operator = (ScriptTOC &&toc) = default;

bool IsEmpty() const { return _glVariables.empty() && _functions.empty(); }
// Returns list of global variables
Expand All @@ -468,6 +468,10 @@ class ScriptTOC
// Returns list of functions
const std::vector<Function> &GetFunctions() const { return _functions; }

// Rebinds ScriptTOC collection with another RTTI object,
// updates "quick references"
void RebindRTTI(RTTI *rtti);

//
// Various helpers
//
Expand Down
3 changes: 0 additions & 3 deletions Common/script/cc_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,6 @@ ccScript &ccScript::operator =(const ccScript &src)
sectionNames = src.sectionNames;
sectionOffsets = src.sectionOffsets;
rtti.reset(new RTTI(*src.rtti));

instances = 0; // don't copy reference count, since it's a new object
return *this;
}

Expand Down Expand Up @@ -171,7 +169,6 @@ void ccScript::Write(Stream *out)

bool ccScript::Read(Stream *in)
{
instances = 0;
currentline = -1;

char gotsig[5]{};
Expand Down
8 changes: 3 additions & 5 deletions Common/script/cc_script.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ struct ccScript
static const std::string unknownSectionName;

std::string scriptname;
std::vector<char> globaldata;
std::vector<uint8_t> globaldata;
std::vector<int32_t> code; // executable byte-code, 32-bit per op or arg
std::vector<char> strings;
std::vector<char> fixuptypes; // global data/string area/ etc
std::vector<uint8_t> fixuptypes; // global data/string area/ etc
std::vector<int32_t> fixups; // code array index to fixup (in ints)
std::vector<std::string> imports; // names of imports
std::vector<std::string> exports; // names of exports
Expand All @@ -51,8 +51,6 @@ struct ccScript
std::unique_ptr<RTTI> rtti;
std::unique_ptr<ScriptTOC> sctoc;

int instances = 0; // reference count for this script object

static ccScript *CreateFromStream(Common::Stream *in);
static ccScript *CreateFromStream(const std::string &name, Common::Stream *in);

Expand All @@ -74,6 +72,6 @@ struct ccScript
bool Read(Common::Stream *in);
};

typedef std::shared_ptr<ccScript> PScript;
typedef std::unique_ptr<ccScript> UScript;

#endif // __CC_SCRIPT_H
13 changes: 6 additions & 7 deletions Editor/AGS.Native/CompiledScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,17 @@ using namespace AGS::Types;
public ref class CompiledScript : ICompiledScript
{
private:
PScript* _compiledScript;
UScript* _compiledScript;
public:
CompiledScript(PScript script)
CompiledScript(UScript &&script)
{
_compiledScript = new PScript();
*_compiledScript = script;
_compiledScript = new UScript(std::move(script));
}

property PScript Data
property UScript &Data
{
PScript get() { return *_compiledScript; }
void set(PScript newScript) { *_compiledScript = newScript; }
UScript &get() { return *_compiledScript; }
void set(UScript &newScript) { *_compiledScript = std::move(newScript); }
}

~CompiledScript()
Expand Down
4 changes: 2 additions & 2 deletions Editor/AGS.Native/ScriptCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public ref class AGS3ScriptCompiler : public IScriptCompiler
}

// Success, create new CompiledData
return gcnew CompiledScript(PScript(cc_script.release()));
return gcnew CompiledScript(std::move(cc_script));
}
};

Expand Down Expand Up @@ -223,7 +223,7 @@ public ref class AGS4ScriptCompiler : public IScriptCompiler
}

// Success, create new CompiledData
return gcnew CompiledScript(PScript(cc_script.release()));
return gcnew CompiledScript(std::move(cc_script));
}
};

Expand Down
2 changes: 1 addition & 1 deletion Editor/AGS.Native/agsnative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3119,7 +3119,7 @@ void convert_room_to_native(Room ^room, RoomStruct &rs)
// Prepare script links
convert_room_interactions_to_native(room, rs);
if (room->Script && room->Script->CompiledData)
rs.CompiledScript = ((AGS::Native::CompiledScript^)room->Script->CompiledData)->Data;
rs.CompiledScript = std::move(((AGS::Native::CompiledScript^)room->Script->CompiledData)->Data);

// Encoding hint
rs.StrOptions["textencoding"].Format("%d", tcv->GetEncoding()->CodePage);
Expand Down
6 changes: 4 additions & 2 deletions Engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -391,14 +391,14 @@ target_sources(engine
plugin/plugin_engine.h
plugin/plugin_stubs.cpp
resource/resource.h
script/cc_instance.cpp
script/cc_instance.h
script/cc_reflecthelper.cpp
script/cc_reflecthelper.h
script/executingscript.cpp
script/executingscript.h
script/exports.cpp
script/exports.h
script/runtimescript.cpp
script/runtimescript.h
script/runtimescriptvalue.cpp
script/runtimescriptvalue.h
script/script.cpp
Expand All @@ -407,6 +407,8 @@ target_sources(engine
script/script_api.h
script/script_runtime.cpp
script/script_runtime.h
script/scriptexecutor.cpp
script/scriptexecutor.h
script/systemimports.cpp
script/systemimports.h
util/library.h
Expand Down
17 changes: 9 additions & 8 deletions Engine/ac/dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
#include "ac/system.h"
#include "debug/debug_log.h"
#include "font/fonts.h"
#include "script/cc_instance.h"
#include "main/game_run.h"
#include "platform/base/agsplatformdriver.h"
#include "script/script.h"
#include "script/scriptexecutor.h"
#include "ac/spritecache.h"
#include "gfx/ddb.h"
#include "gfx/gfx_util.h"
Expand Down Expand Up @@ -204,7 +204,7 @@ static int run_dialog_request(int parmtr)
{
play.stop_dialog_at_end = DIALOG_RUNNING;
RuntimeScriptValue params[]{ parmtr };
RunScriptFunction(gameinst.get(), "dialog_request", 1, params);
RunScriptFunction(gamescript.get(), "dialog_request", 1, params);

if (play.stop_dialog_at_end == DIALOG_STOP)
{
Expand Down Expand Up @@ -250,13 +250,13 @@ int run_dialog_script(int dialogID, int offse, int optionIndex)
said_speech_line = 0;
int result = RUN_DIALOG_STAY;

if (dialogScriptsInst)
if (dialogScriptsScript)
{
char func_name[100];
snprintf(func_name, sizeof(func_name), "_run_dialog%d", dialogID);
RuntimeScriptValue params[]{ optionIndex };
RunScriptFunction(dialogScriptsInst.get(), func_name, 1, params);
result = dialogScriptsInst->GetReturnValue();
RunScriptFunction(dialogScriptsScript.get(), func_name, 1, params);
result = scriptExecutor->GetReturnValue();
}

if (in_new_room > 0)
Expand Down Expand Up @@ -1438,22 +1438,23 @@ bool is_in_dialogoptions()

bool is_dialog_executing_script()
{
return dialogExec && dialogScriptsInst && dialogExec->GetExecutedOption() >= 0;
return dialogExec && (dialogExec->GetExecutedOption() >= 0)
&& scriptExecutor && (scriptExecutor->GetRunningScript() == dialogScriptsScript.get());
}

// TODO: this is ugly, but I could not come to a better solution at the time...
void set_dialog_result_goto(int dlgnum)
{
assert(is_dialog_executing_script());
if (is_dialog_executing_script())
dialogScriptsInst->SetReturnValue(dlgnum);
scriptExecutor->SetReturnValue(dlgnum);
}

void set_dialog_result_stop()
{
assert(is_dialog_executing_script());
if (is_dialog_executing_script())
dialogScriptsInst->SetReturnValue(RUN_DIALOG_STOP_DIALOG);
scriptExecutor->SetReturnValue(RUN_DIALOG_STOP_DIALOG);
}

bool handle_state_change_in_dialog_request(const char *apiname, int dlgreq_retval)
Expand Down
Loading

0 comments on commit 35e5663

Please sign in to comment.