Skip to content
This repository has been archived by the owner on Jan 5, 2024. It is now read-only.

Commit

Permalink
Merge branch 'development' into walkpath-auto-crouch
Browse files Browse the repository at this point in the history
  • Loading branch information
Causeless committed Dec 27, 2023
2 parents fe59de9 + e0a4a22 commit c003b2c
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 57 deletions.
28 changes: 23 additions & 5 deletions Activities/GAScripted.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,17 +204,30 @@ int GAScripted::ReloadScripts() {
}
}

std::unordered_map<std::string, LuabindObjectWrapper*> scriptFileFunctions;
if ((error = g_LuaMan.GetMasterScriptState().RunScriptFileAndRetrieveFunctions(m_ScriptPath, m_LuaClassName, GetSupportedScriptFunctionNames(), scriptFileFunctions, true)) < 0) {
if ((error = g_LuaMan.GetMasterScriptState().RunScriptFile(m_ScriptPath, true, false)) < 0) {
return error;
}

RefreshActivityFunctions();

return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void GAScripted::RefreshActivityFunctions() {
m_ScriptFunctions.clear();
if (m_ScriptPath.empty()) {
return;
}

// We use m_LuaClassName here, because we ran the script file in the global state instead of in an environment
std::unordered_map<std::string, LuabindObjectWrapper*> scriptFileFunctions;
g_LuaMan.GetMasterScriptState().RetrieveFunctions(m_LuaClassName, GetSupportedScriptFunctionNames(), scriptFileFunctions);

for (const auto& [functionName, functionObject] : scriptFileFunctions) {
m_ScriptFunctions[functionName] = std::unique_ptr<LuabindObjectWrapper>(functionObject);
}

return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -485,7 +498,12 @@ int GAScripted::RunLuaFunction(const std::string& functionName, const std::vecto
return 0;
}

return g_LuaMan.GetMasterScriptState().RunScriptFunctionObject(funcItr->second.get(), "_G", m_LuaClassName, functionEntityArguments, functionLiteralArguments, functionObjectArguments);
int error = g_LuaMan.GetMasterScriptState().RunScriptFunctionObject(funcItr->second.get(), "_G", m_LuaClassName, functionEntityArguments, functionLiteralArguments, functionObjectArguments);

// Need to call this continually unfortunately, as something might change due to dofile()
RefreshActivityFunctions();

return error;
}


Expand Down
5 changes: 5 additions & 0 deletions Activities/GAScripted.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ ClassInfoGetters;

int ReloadScripts() override;

/// <summary>
/// Refreshes our activity functions to find any changes from script.
/// </summary>
void RefreshActivityFunctions();


//////////////////////////////////////////////////////////////////////////////////////////
// Virtual method: GetLuaClassName
Expand Down
2 changes: 1 addition & 1 deletion Entities/AEJetpack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ namespace RTE {
switch (m_JetpackType)
{
case JetpackType::Standard:
if (controller.IsState(BODY_JUMPSTART) && !IsOutOfFuel() && IsFullyFueled()) {
if (controller.IsState(BODY_JUMPSTART) && !IsOutOfFuel()) {
Burst(parentActor, fuelUseMultiplier);
} else if (controller.IsState(BODY_JUMP) && !IsOutOfFuel() && (GetJetTimeRatio() >= m_MinimumFuelRatio || wasEmittingLastFrame)) {
Thrust(parentActor, fuelUseMultiplier);
Expand Down
6 changes: 5 additions & 1 deletion Entities/MovableObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,10 @@ void MovableObject::Destroy(bool notInherited) {
// TODO: try to make this at least reasonably workable
//DestroyScriptState();

if (m_ThreadedLuaState) {
m_ThreadedLuaState->UnregisterMO(this);
}

g_MovableMan.UnregisterObject(this);
if (!notInherited) {
SceneObject::Destroy();
Expand Down Expand Up @@ -587,7 +591,7 @@ int MovableObject::LoadScript(const std::string &scriptPath, bool loadAsEnabledS
m_AllLoadedScripts.try_emplace(scriptPath, loadAsEnabledScript);

std::unordered_map<std::string, LuabindObjectWrapper *> scriptFileFunctions;
if (usedState.RunScriptFileAndRetrieveFunctions(scriptPath, "", GetSupportedScriptFunctionNames(), scriptFileFunctions) < 0) {
if (usedState.RunScriptFileAndRetrieveFunctions(scriptPath, GetSupportedScriptFunctionNames(), scriptFileFunctions) < 0) {
return -4;
}

Expand Down
2 changes: 1 addition & 1 deletion Entities/PieSlice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ namespace RTE {
std::string filePath = m_LuabindFunctionObject->GetFilePath();
std::unordered_map<std::string, LuabindObjectWrapper *> scriptFileFunctions;

status = g_LuaMan.GetMasterScriptState().RunScriptFileAndRetrieveFunctions(filePath, "", { m_FunctionName }, scriptFileFunctions, true);
status = g_LuaMan.GetMasterScriptState().RunScriptFileAndRetrieveFunctions(filePath, { m_FunctionName }, scriptFileFunctions, true);
if (scriptFileFunctions.find(m_FunctionName) != scriptFileFunctions.end()) {
m_LuabindFunctionObject = std::unique_ptr<LuabindObjectWrapper>(scriptFileFunctions.at(m_FunctionName));
}
Expand Down
88 changes: 49 additions & 39 deletions Managers/LuaMan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace RTE {

const std::unordered_set<std::string> LuaMan::c_FileAccessModes = { "r", "r+", "w", "w+", "a", "a+" };
const std::unordered_set<std::string> LuaMan::c_FileAccessModes = { "r", "r+", "w", "w+", "a", "a+", "rt", "wt"};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -227,8 +227,9 @@ namespace RTE {
// Override "math.random" in the lua state to use RTETools MT19937 implementation. Preserve return types of original to not break all the things.
"math.random = function(lower, upper) if lower ~= nil and upper ~= nil then return LuaMan:SelectRand(lower, upper); elseif lower ~= nil then return LuaMan:SelectRand(1, lower); else return LuaMan:PosRand(); end end"
"\n"
// Override "dofile" to be able to account for Data/ or Mods/ directory.
// Override "dofile"/"loadfile" to be able to account for Data/ or Mods/ directory.
"OriginalDoFile = dofile; dofile = function(filePath) filePath = PresetMan:GetFullModulePath(filePath); if filePath ~= '' then return OriginalDoFile(filePath); end end;"
"OriginalLoadFile = loadfile; loadfile = function(filePath) filePath = PresetMan:GetFullModulePath(filePath); if filePath ~= '' then return OriginalLoadFile(filePath); end end;"
// Internal helper functions to add callbacks for async pathing requests
"_AsyncPathCallbacks = {};"
"_AddAsyncPathCallback = function(id, callback) _AsyncPathCallbacks[id] = callback; end\n"
Expand Down Expand Up @@ -636,7 +637,7 @@ namespace RTE {

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int LuaStateWrapper::RunScriptFile(const std::string &filePath, bool consoleErrors) {
int LuaStateWrapper::RunScriptFile(const std::string &filePath, bool consoleErrors, bool doInSandboxedEnvironment) {
const std::string fullScriptPath = g_PresetMan.GetFullModulePath(filePath);
if (fullScriptPath.empty()) {
m_LastError = "Can't run a script file with an empty filepath!";
Expand Down Expand Up @@ -674,20 +675,22 @@ namespace RTE {
}

if (error == 0) {
// create a new environment table
lua_getglobal(m_State, filePath.c_str());
if (lua_isnil(m_State, -1)) {
lua_pop(m_State, 1);
lua_newtable(m_State);
lua_newtable(m_State);
lua_getglobal(m_State, "_G");
lua_setfield(m_State, -2, "__index");
lua_setmetatable(m_State, -2);
lua_setglobal(m_State, filePath.c_str());
if (doInSandboxedEnvironment) {
// create a new environment table
lua_getglobal(m_State, filePath.c_str());
}
if (lua_isnil(m_State, -1)) {
lua_pop(m_State, 1);
lua_newtable(m_State);
lua_newtable(m_State);
lua_getglobal(m_State, "_G");
lua_setfield(m_State, -2, "__index");
lua_setmetatable(m_State, -2);
lua_setglobal(m_State, filePath.c_str());
lua_getglobal(m_State, filePath.c_str());
}

lua_setfenv(m_State, -2);
lua_setfenv(m_State, -2);
}

// execute script file with pcall. Pcall will call the file and line error handler if there's an error by pointing 2 up the stack to it.
if (lua_pcall(m_State, 0, LUA_MULTRET, -2)) {
Expand All @@ -710,7 +713,36 @@ namespace RTE {

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int LuaStateWrapper::RunScriptFileAndRetrieveFunctions(const std::string &filePath, const std::string &prefix, const std::vector<std::string> &functionNamesToLookFor, std::unordered_map<std::string, LuabindObjectWrapper *> &outFunctionNamesAndObjects, bool forceReload) {
bool LuaStateWrapper::RetrieveFunctions(const std::string& funcObjectName, const std::vector<std::string>& functionNamesToLookFor, std::unordered_map<std::string, LuabindObjectWrapper*>& outFunctionNamesAndObjects) {
std::lock_guard<std::recursive_mutex> lock(m_Mutex);
s_currentLuaState = this;

luabind::object funcHoldingObject = luabind::globals(m_State)[funcObjectName.c_str()];
if (luabind::type(funcHoldingObject) == LUA_TNIL) {
return false;
}

auto& newScript = m_ScriptCache[funcObjectName.c_str()];
newScript.functionNamesAndObjects.clear();
for (const std::string& functionName : functionNamesToLookFor) {
luabind::object functionObject = funcHoldingObject[functionName];
if (luabind::type(functionObject) == LUA_TFUNCTION) {
luabind::object* functionObjectCopyForStoring = new luabind::object(functionObject);
newScript.functionNamesAndObjects.try_emplace(functionName, new LuabindObjectWrapper(functionObjectCopyForStoring, funcObjectName));
}
}

for (auto& pair : newScript.functionNamesAndObjects) {
luabind::object* functionObjectCopyForStoring = new luabind::object(*pair.second->GetLuabindObject());
outFunctionNamesAndObjects.try_emplace(pair.first, new LuabindObjectWrapper(functionObjectCopyForStoring, funcObjectName));
}

return true;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int LuaStateWrapper::RunScriptFileAndRetrieveFunctions(const std::string &filePath, const std::vector<std::string> &functionNamesToLookFor, std::unordered_map<std::string, LuabindObjectWrapper *> &outFunctionNamesAndObjects, bool forceReload) {
static bool disableCaching = false;
forceReload = forceReload || disableCaching;

Expand All @@ -733,32 +765,10 @@ namespace RTE {
return error;
}

luabind::object prefixObject;
if (prefix == "") {
prefixObject = luabind::globals(m_State)[filePath.c_str()];
} else {
prefixObject = luabind::globals(m_State)[filePath.c_str()][prefix];
}

if (luabind::type(prefixObject) == LUA_TNIL) {
if (!RetrieveFunctions(filePath, functionNamesToLookFor, outFunctionNamesAndObjects)) {
return -1;
}

auto &newScript = m_ScriptCache[filePath];
newScript.functionNamesAndObjects.clear();
for (const std::string& functionName : functionNamesToLookFor) {
luabind::object functionObject = prefixObject[functionName];
if (luabind::type(functionObject) == LUA_TFUNCTION) {
luabind::object* functionObjectCopyForStoring = new luabind::object(functionObject);
newScript.functionNamesAndObjects.try_emplace(functionName, new LuabindObjectWrapper(functionObjectCopyForStoring, filePath));
}
}

for (auto& pair : newScript.functionNamesAndObjects) {
luabind::object* functionObjectCopyForStoring = new luabind::object(*pair.second->GetLuabindObject());
outFunctionNamesAndObjects.try_emplace(pair.first, new LuabindObjectWrapper(functionObjectCopyForStoring, filePath));
}

return 0;
}

Expand Down
15 changes: 12 additions & 3 deletions Managers/LuaMan.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,19 +148,28 @@ namespace RTE {
/// </summary>
/// <param name="filePath">The path to the file to load and run.</param>
/// <param name="consoleErrors">Whether to report any errors to the console immediately.</param>
/// <param name="doInSandboxedEnvironment">Whether to do it in a sandboxed environment, or the global environment.</param>
/// <returns>Returns less than zero if any errors encountered when running this script. To get the actual error string, call GetLastError.</returns>
int RunScriptFile(const std::string &filePath, bool consoleErrors = true);
int RunScriptFile(const std::string &filePath, bool consoleErrors = true, bool doInSandboxedEnvironment = true);

/// <summary>
/// Retrieves all of the specified functions that exist into the output map, and refreshes the cache.
/// </summary>
/// <param name="filePath">The path to the file to load and run.</param>
/// <param name="functionNamesToLookFor">The vector of strings defining the function names to be retrieved.</param>
/// <param name="outFunctionNamesAndObjects">The map of function names to LuabindObjectWrappers to be retrieved from the script that was run.</param>
/// <returns>Returns whether functions were successfully retrieved.</returns>
bool RetrieveFunctions(const std::string& functionObjectName, const std::vector<std::string>& functionNamesToLookFor, std::unordered_map<std::string, LuabindObjectWrapper*>& outFunctionNamesAndObjects);

/// <summary>
/// Opens and loads a file containing a script and runs it on the state, then retrieves all of the specified functions that exist into the output map.
/// </summary>
/// <param name="filePath">The path to the file to load and run.</param>
/// <param name="prefix">The prefix before each function we're looking for. With normal objects this is usually nothing (free floating), but activities expect the activity name beforehand.</param>
/// <param name="functionNamesToLookFor">The vector of strings defining the function names to be retrieved.</param>
/// <param name="outFunctionNamesAndObjects">The map of function names to LuabindObjectWrappers to be retrieved from the script that was run.</param>
/// <param name="noCaching">Whether caching shouldn't be used.</param>
/// <returns>Returns less than zero if any errors encountered when running this script. To get the actual error string, call GetLastError.</returns>
int RunScriptFileAndRetrieveFunctions(const std::string &filePath, const std::string &prefix, const std::vector<std::string> &functionNamesToLookFor, std::unordered_map<std::string, LuabindObjectWrapper *> &outFunctionNamesAndObjects, bool forceReload = false);
int RunScriptFileAndRetrieveFunctions(const std::string &filePath, const std::vector<std::string> &functionNamesToLookFor, std::unordered_map<std::string, LuabindObjectWrapper *> &outFunctionNamesAndObjects, bool forceReload = false);
#pragma endregion

#pragma region Concrete Methods
Expand Down
5 changes: 3 additions & 2 deletions Managers/MovableMan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,8 @@ void MovableMan::PurgeAllMOs()
m_AddedAlarmEvents.clear();
m_AlarmEvents.clear();
m_MOIDIndex.clear();
m_KnownObjects.clear();
// We want to keep known objects around, 'cause these can exist even when not in the simulation (they're here from creation till deletion, regardless of whether they are in sim)
//m_KnownObjects.clear();
}


Expand Down Expand Up @@ -1720,7 +1721,7 @@ void MovableMan::Update()
LuaStateWrapper& luaState = luaStates[start];
g_LuaMan.SetThreadLuaStateOverride(&luaState);

for (MovableObject *mo : luaState.GetRegisteredMOs()) {
for (MovableObject *mo : luaState.GetRegisteredMOs()) {
mo->RunScriptedFunctionInAppropriateScripts(threadedUpdate, false, false, {}, {}, {});
}

Expand Down
10 changes: 5 additions & 5 deletions Menus/TitleScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,11 @@ namespace RTE {
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void TitleScreen::DrawTitleScreenScene() {
// This only needs to be done once, but bitmaps can be reloaded which effectively undoes this, so just do it all the time to not deal with flags and checks.
set_write_alpha_blender();
draw_trans_sprite(m_Planet.GetSpriteFrame(0), ContentFile("Base.rte/GUIs/Title/PlanetAlpha.png").GetAsBitmap(), 0, 0);
draw_trans_sprite(m_Moon.GetSpriteFrame(0), ContentFile("Base.rte/GUIs/Title/MoonAlpha.png").GetAsBitmap(), 0, 0);

Box nebulaTargetBox;
m_Nebula.SetOffset(Vector(static_cast<float>((m_TitleScreenMaxWidth - m_Nebula.GetBitmap()->w) / 2), m_ScrollOffset.GetY()));
m_Nebula.Draw(g_FrameMan.GetBackBuffer32(), nebulaTargetBox, true);
Expand All @@ -565,11 +570,6 @@ namespace RTE {
m_Station.SetPos(m_PlanetPos + m_StationOffset);
m_Station.SetRotAngle(-c_HalfPI + m_StationOrbitRotation);
m_Station.Draw(g_FrameMan.GetBackBuffer32());

// This only needs to be done once, but bitmaps can be reloaded which effectively undoes this, so just do it all the time to not deal with flags and checks.
set_write_alpha_blender();
draw_trans_sprite(m_Planet.GetSpriteFrame(0), ContentFile("Base.rte/GUIs/Title/PlanetAlpha.png").GetAsBitmap(), 0, 0);
draw_trans_sprite(m_Moon.GetSpriteFrame(0), ContentFile("Base.rte/GUIs/Title/MoonAlpha.png").GetAsBitmap(), 0, 0);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit c003b2c

Please sign in to comment.