Skip to content

Commit

Permalink
Expose mod input handlers for better integration between mods
Browse files Browse the repository at this point in the history
Allow mods to:
 - Get name list of other installed mods
 - Get info about input handlers, registered for other mods
 - Call input handlers from lua, as if user presses an input key
 - Split responsibilities: mods will delegate input management to other specific mods
  • Loading branch information
Supremist committed Jan 7, 2024
1 parent 18e08a8 commit f1af8e9
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/VKBindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct VKBind
std::string DisplayName{};
std::variant<std::string, std::function<void()>> Description{};
std::variant<std::function<TVKBindHotkeyCallback>, std::function<TVKBindInputCallback>> Handler{};
sol::function VmHandler{};

[[nodiscard]] std::function<void()> DelayedCall(const bool acIsDown) const;
void Call(const bool acIsDown) const;
Expand Down
2 changes: 1 addition & 1 deletion src/scripting/LuaSandbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ static constexpr const char* s_cPostInitializeTweakDBProtectedList[] = {

static constexpr const char* s_cPostInitializeModsProtectedList[] = {
// initialized by Scripting
"NewObject", "GetSingleton", "GetMod", "GameDump", "Dump", "DumpType", "DumpAllTypeNames", "DumpVtables", "DumpReflection", "Game",
"NewObject", "GetSingleton", "GetModNames", "GetModInputHandlers", "GetMod", "GameDump", "Dump", "DumpType", "DumpAllTypeNames", "DumpVtables", "DumpReflection", "Game",

// initialized by RTTIMapper
"Vector3", "ToVector3", "Vector4", "ToVector4", "EulerAngles", "ToEulerAngles", "Quaternion", "ToQuaternion", "ItemID", "ToItemID"};
Expand Down
14 changes: 12 additions & 2 deletions src/scripting/ScriptContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ ScriptContext::ScriptContext(LuaSandbox& aLuaSandbox, const std::filesystem::pat
return std::get<std::string>(acDescription);
};

auto registerBinding = [this, &wrapHandler, &wrapDescription](
auto registerBinding = [this, &wrapHandler, &wrapDescription, &lockedState](
const std::string& acID, const std::string& acDisplayName, const std::variant<std::string, sol::function>& acDescription, sol::function aCallback,
const bool acIsHotkey)
{
Expand Down Expand Up @@ -145,8 +145,18 @@ ScriptContext::ScriptContext(LuaSandbox& aLuaSandbox, const std::filesystem::pat
inputTypeStr, acID, acDisplayName, bindIt->DisplayName);
return;
}
sol::function vmHandler = aCallback;
if (acIsHotkey)
{
vmHandler = MakeSolFunction(lockedState, [aCallback](bool isPressed) {
if (isPressed)
{
aCallback();
}
});
}

m_vkBinds.emplace_back(acID, acDisplayName, wrapDescription(acDescription), wrapHandler(aCallback, acIsHotkey));
m_vkBinds.emplace_back(acID, acDisplayName, wrapDescription(acDescription), wrapHandler(aCallback, acIsHotkey), vmHandler);
};

env["registerHotkey"] = sol::overload(
Expand Down
12 changes: 12 additions & 0 deletions src/scripting/ScriptStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ const TiltedPhoques::Map<std::string, std::reference_wrapper<const TiltedPhoques
return m_vkBinds;
}

const VKBindings& ScriptStore::GetBindings() const
{
return m_bindings;
}

void ScriptStore::TriggerOnHook() const
{
for (const auto& mod : m_contexts | std::views::values)
Expand Down Expand Up @@ -147,6 +152,13 @@ void ScriptStore::TriggerOnOverlayClose() const
mod.TriggerOnOverlayClose();
}

TiltedPhoques::Vector<std::string> ScriptStore::GetModNames() const
{
TiltedPhoques::Vector<std::string> result;
std::ranges::copy(m_contexts | std::views::keys, std::back_inserter(result));
return result;
}

sol::object ScriptStore::GetMod(const std::string& acName) const
{
const auto it = m_contexts.find(acName);
Expand Down
2 changes: 2 additions & 0 deletions src/scripting/ScriptStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct ScriptStore
[[nodiscard]] const VKBind* GetBind(const VKModBind& acModBind) const;
[[nodiscard]] const TiltedPhoques::Vector<VKBind>* GetBinds(const std::string& acModName) const;
[[nodiscard]] const TiltedPhoques::Map<std::string, std::reference_wrapper<const TiltedPhoques::Vector<VKBind>>>& GetAllBinds() const;
[[nodiscard]] const VKBindings& GetBindings() const;

void TriggerOnHook() const;
void TriggerOnTweak() const;
Expand All @@ -23,6 +24,7 @@ struct ScriptStore
void TriggerOnOverlayOpen() const;
void TriggerOnOverlayClose() const;

[[nodiscard]] TiltedPhoques::Vector<std::string> GetModNames() const;
[[nodiscard]] sol::object GetMod(const std::string& acName) const;

private:
Expand Down
44 changes: 44 additions & 0 deletions src/scripting/Scripting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,16 @@ void Scripting::PostInitializeScripting()
return this->GetSingletonHandle(acName, aThisEnv);
};

globals["GetModNames"] = [this]() -> sol::object
{
return GetModNames();
};

globals["GetModInputHandlers"] = [this](const std::string& acName) -> sol::object
{
return GetModInputHandlers(acName);
};

globals["GetMod"] = [this](const std::string& acName) -> sol::object
{
return GetMod(acName);
Expand Down Expand Up @@ -599,11 +609,45 @@ void Scripting::TriggerOnOverlayClose() const
m_store.TriggerOnOverlayClose();
}

sol::object Scripting::GetModNames() const
{
auto lockedState = m_lua.Lock();
sol::table res(lockedState.Get(), sol::create);
for (const auto& name : m_store.GetModNames())
res.add(name);
return res;
}

sol::object Scripting::GetMod(const std::string& acName) const
{
return m_store.GetMod(acName);
}

sol::object Scripting::GetModInputHandlers(const std::string& acName) const
{
const auto* modBinds = m_store.GetBinds(acName);
if (!modBinds)
return sol::nil;

auto lockedState = m_lua.Lock();
const auto& bindings = m_store.GetBindings();
sol::table res(lockedState.Get(), sol::create);
for (const auto& bind : *modBinds)
{
sol::table info(lockedState.Get(), sol::create);
info["slug"] = bind.ID;
info["label"] = bind.DisplayName;
info["callback"] = bind.VmHandler;
if (std::holds_alternative<std::string>(bind.Description))
{
info["description"] = std::get<std::string>(bind.Description);
}
info["bind"] = bindings.GetBindString({acName, bind.ID});
res[bind.ID] = info;
}
return res;
}

void Scripting::UnloadAllMods()
{
m_override.Clear();
Expand Down
2 changes: 2 additions & 0 deletions src/scripting/Scripting.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ struct Scripting
void TriggerOnOverlayOpen() const;
void TriggerOnOverlayClose() const;

sol::object GetModNames() const;
sol::object GetMod(const std::string& acName) const;
sol::object GetModInputHandlers(const std::string& acName) const;
void UnloadAllMods();
void ReloadAllMods();
bool ExecuteLua(const std::string& acCommand) const;
Expand Down

0 comments on commit f1af8e9

Please sign in to comment.