Lua: can make new tabs from lua scripts, doc generation for available tabs to use (#1593)
* lua api: add globals.get_uint and globals.set_uint * lua doc: remove duplicate function check as we can overload so it doesn't make sense * lua doc gen: add support for parsing the tabs enum * gui: custom lua tabs don't have a `func` rendering function but can still have elements to draw * lua doc: update generated doc * chore: code style * chore: minor spelling mistake * chore: code style * gui_service: add runtime removal of tabs * refactor: make it so that it's less likely defining tabs and their translation key in a wrong way. * lua api: ability to add custom tabs to the gui from lua
This commit is contained in:
@ -13,7 +13,7 @@ namespace lua::event
|
||||
// Table: menu_event
|
||||
// Field: PlayerLeave: integer
|
||||
// Event that is triggered when a player leave the game session.
|
||||
// **Exemple Usage:**
|
||||
// **Example Usage:**
|
||||
// ```lua
|
||||
// event.register_handler(menu_event.PlayerLeave, function (player_name)
|
||||
// log.info(player_name)
|
||||
@ -24,7 +24,7 @@ namespace lua::event
|
||||
// Table: menu_event
|
||||
// Field: PlayerJoin: integer
|
||||
// Event that is triggered when a player join the game session.
|
||||
// **Exemple Usage:**
|
||||
// **Example Usage:**
|
||||
// ```lua
|
||||
// event.register_handler(menu_event.PlayerJoin, function (player_name, player_id)
|
||||
// log.info(player_name)
|
||||
@ -36,7 +36,7 @@ namespace lua::event
|
||||
// Table: menu_event
|
||||
// Field: PlayerMgrInit: integer
|
||||
// Event that is triggered when the player manager initialize. Usually called when we are joining a session.
|
||||
// **Exemple Usage:**
|
||||
// **Example Usage:**
|
||||
// ```lua
|
||||
// event.register_handler(menu_event.PlayerMgrInit, function ()
|
||||
// log.info("Player manager inited, we just joined a session.")
|
||||
@ -47,10 +47,10 @@ namespace lua::event
|
||||
// Table: menu_event
|
||||
// Field: PlayerMgrShutdown: integer
|
||||
// Event that is triggered when the player manager shutdown. Usually called when we are leaving a session.
|
||||
// **Exemple Usage:**
|
||||
// **Example Usage:**
|
||||
// ```lua
|
||||
// event.register_handler(menu_event.PlayerMgrShutdown, function ()
|
||||
// log.info("Player manager inited, we just joined a session.")
|
||||
// log.info("Player manager inited, we just left a session.")
|
||||
// end)
|
||||
// ```
|
||||
|
||||
@ -58,7 +58,7 @@ namespace lua::event
|
||||
// Table: menu_event
|
||||
// Field: ChatMessageReceived: integer
|
||||
// Event that is triggered when we receive a in-game chat message.
|
||||
// **Exemple Usage:**
|
||||
// **Example Usage:**
|
||||
// ```lua
|
||||
// event.register_handler(menu_event.ChatMessageReceived, function (player_id, chat_message)
|
||||
// log.info(player_id)
|
||||
@ -70,7 +70,7 @@ namespace lua::event
|
||||
// Table: menu_event
|
||||
// Field: ScriptedGameEventReceived: integer
|
||||
// Event that is triggered when we receive a scripted game event.
|
||||
// **Exemple Usage:**
|
||||
// **Example Usage:**
|
||||
// ```lua
|
||||
// event.register_handler(menu_event.ScriptedGameEventReceived, function (player_id, script_event_args)
|
||||
// log.info(player_id)
|
||||
|
@ -19,6 +19,17 @@ namespace lua::globals
|
||||
return *big::script_global(global).as<int*>();
|
||||
}
|
||||
|
||||
// Lua API: Function
|
||||
// Table: globals
|
||||
// Name: get_uint
|
||||
// Param: global: integer: index of the global
|
||||
// Returns: integer: value of the global
|
||||
// Retrieves an uint global value.
|
||||
static int get_uint(int global)
|
||||
{
|
||||
return *big::script_global(global).as<unsigned int*>();
|
||||
}
|
||||
|
||||
// Lua API: Function
|
||||
// Table: globals
|
||||
// Name: get_float
|
||||
@ -52,6 +63,17 @@ namespace lua::globals
|
||||
*big::script_global(global).as<int*>() = val;
|
||||
}
|
||||
|
||||
// Lua API: Function
|
||||
// Table: globals
|
||||
// Name: set_uint
|
||||
// Param: global: integer: index of the global
|
||||
// Param: val: integer: new value for the global
|
||||
// Sets an uint global value.
|
||||
static void set_uint(int global, unsigned int val)
|
||||
{
|
||||
*big::script_global(global).as<unsigned int*>() = val;
|
||||
}
|
||||
|
||||
// Lua API: Function
|
||||
// Table: globals
|
||||
// Name: set_float
|
||||
@ -89,9 +111,11 @@ namespace lua::globals
|
||||
{
|
||||
auto ns = state["globals"].get_or_create<sol::table>();
|
||||
ns["get_int"] = get_int;
|
||||
ns["get_uint"] = get_uint;
|
||||
ns["get_float"] = get_float;
|
||||
ns["get_string"] = get_string;
|
||||
ns["set_int"] = set_int;
|
||||
ns["set_uint"] = set_uint;
|
||||
ns["set_float"] = set_float;
|
||||
ns["set_string"] = set_string;
|
||||
ns["get_pointer"] = get_pointer;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "gui/separator.hpp"
|
||||
#include "gui/text.hpp"
|
||||
#include "lua/lua_module.hpp"
|
||||
#include "services/gui/gui_service.hpp"
|
||||
|
||||
namespace lua::gui
|
||||
{
|
||||
@ -27,12 +28,136 @@ namespace lua::gui
|
||||
// Class for representing a tab within the GUI.
|
||||
class tab
|
||||
{
|
||||
big::tabs m_id;
|
||||
rage::joaat_t m_tab_hash;
|
||||
|
||||
public:
|
||||
tab(rage::joaat_t hash) :
|
||||
m_tab_hash(hash)
|
||||
inline big::tabs id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
inline rage::joaat_t hash() const
|
||||
{
|
||||
return m_tab_hash;
|
||||
}
|
||||
|
||||
bool check_if_existing_tab_and_fill_id(const std::map<big::tabs, big::navigation_struct>& nav)
|
||||
{
|
||||
for (const auto& nav_item : nav)
|
||||
{
|
||||
if (nav_item.second.hash == m_tab_hash)
|
||||
{
|
||||
m_id = nav_item.first;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (check_if_existing_tab_and_fill_id(nav_item.second.sub_nav))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void add_to_existing_tab(std::map<big::tabs, big::navigation_struct>& nav, const rage::joaat_t existing_tab_hash, const std::pair<big::tabs, big::navigation_struct>& new_tab, const sol::this_state& state)
|
||||
{
|
||||
for (auto& nav_item : nav)
|
||||
{
|
||||
if (nav_item.second.hash == existing_tab_hash)
|
||||
{
|
||||
auto module = sol::state_view(state)["!this"].get<big::lua_module*>();
|
||||
module->m_tab_to_sub_tabs[nav_item.first].push_back(new_tab.first);
|
||||
|
||||
nav_item.second.sub_nav.emplace(new_tab);
|
||||
return;
|
||||
}
|
||||
|
||||
add_to_existing_tab(nav_item.second.sub_nav, existing_tab_hash, new_tab, state);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<big::tabs, big::navigation_struct> make_tab_nav(const std::string& name, const rage::joaat_t tab_hash, const sol::this_state& state)
|
||||
{
|
||||
static size_t custom_tab_count = size_t(big::tabs::RUNTIME_CUSTOM);
|
||||
m_id = big::tabs(custom_tab_count);
|
||||
|
||||
custom_tab_count++;
|
||||
|
||||
big::navigation_struct new_navigation_struct{};
|
||||
strcpy(new_navigation_struct.name, name.c_str());
|
||||
new_navigation_struct.hash = tab_hash;
|
||||
|
||||
return std::make_pair(m_id, new_navigation_struct);
|
||||
}
|
||||
|
||||
tab(const std::string& name, const sol::this_state& state) :
|
||||
m_tab_hash(rage::joaat(name))
|
||||
{
|
||||
auto& nav = big::g_gui_service->get_navigation();
|
||||
|
||||
if (check_if_existing_tab_and_fill_id(nav))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// add top tab
|
||||
nav.emplace(make_tab_nav(name, m_tab_hash, state));
|
||||
|
||||
auto module = sol::state_view(state)["!this"].get<big::lua_module*>();
|
||||
module->m_owned_tabs.push_back(id());
|
||||
}
|
||||
|
||||
tab(const std::string& name, const rage::joaat_t parent_tab_hash, const sol::this_state& state) :
|
||||
m_tab_hash(rage::joaat(name))
|
||||
{
|
||||
auto& nav = big::g_gui_service->get_navigation();
|
||||
|
||||
if (check_if_existing_tab_and_fill_id(nav))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto sub_tab = make_tab_nav(name, m_tab_hash, state);
|
||||
add_to_existing_tab(nav, parent_tab_hash, sub_tab, state);
|
||||
|
||||
auto module = sol::state_view(state)["!this"].get<big::lua_module*>();
|
||||
module->m_owned_tabs.push_back(id());
|
||||
}
|
||||
|
||||
// Lua API: Function
|
||||
// Class: tab
|
||||
// Name: clear
|
||||
// Clear the tab of all its custom lua content that you own.
|
||||
void clear(sol::this_state state)
|
||||
{
|
||||
auto module = sol::state_view(state)["!this"].get<big::lua_module*>();
|
||||
|
||||
if (module->m_gui.contains(m_tab_hash))
|
||||
module->m_gui[m_tab_hash] = {};
|
||||
|
||||
for (auto sub_tab : module->m_tab_to_sub_tabs[id()])
|
||||
{
|
||||
for (const auto owned_tab : module->m_owned_tabs)
|
||||
{
|
||||
if (sub_tab == owned_tab)
|
||||
{
|
||||
big::g_gui_service->remove_from_nav(sub_tab);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lua API: Function
|
||||
// Class: tab
|
||||
// Name: add_tab
|
||||
// Add a sub tab to this tab.
|
||||
tab add_tab(const std::string& name, sol::this_state state)
|
||||
{
|
||||
const auto sub_tab = tab(name, m_tab_hash, state);
|
||||
|
||||
return sub_tab;
|
||||
}
|
||||
|
||||
// Lua API: Function
|
||||
@ -147,9 +272,21 @@ namespace lua::gui
|
||||
// Name: get_tab
|
||||
// Param: tab_name: string: Name of the tab to get.
|
||||
// Returns: tab: A tab instance which corresponds to the tab in the GUI.
|
||||
static tab get_tab(const std::string& tab_name)
|
||||
static tab get_tab(const std::string& tab_name, sol::this_state state)
|
||||
{
|
||||
return tab(rage::joaat(tab_name));
|
||||
return tab(tab_name, state);
|
||||
}
|
||||
|
||||
// Lua API: Function
|
||||
// Table: gui
|
||||
// Name: add_tab
|
||||
// Param: tab_name: string: Name of the tab to add.
|
||||
// Returns: tab: A tab instance which corresponds to the new tab in the GUI.
|
||||
static tab add_tab(const std::string& tab_name, sol::this_state state)
|
||||
{
|
||||
const auto new_tab = tab(tab_name, state);
|
||||
|
||||
return new_tab;
|
||||
}
|
||||
|
||||
// Lua API: Function
|
||||
@ -195,6 +332,7 @@ namespace lua::gui
|
||||
{
|
||||
auto ns = state["gui"].get_or_create<sol::table>();
|
||||
ns["get_tab"] = get_tab;
|
||||
ns["add_tab"] = add_tab;
|
||||
ns["show_message"] = show_message;
|
||||
ns["show_warning"] = show_warning;
|
||||
ns["show_error"] = show_error;
|
||||
@ -244,6 +382,8 @@ namespace lua::gui
|
||||
);
|
||||
|
||||
ns.new_usertype<tab>("tab",
|
||||
"clear", &tab::clear,
|
||||
"add_tab", &tab::add_tab,
|
||||
"add_button", &tab::add_button,
|
||||
"add_text", &tab::add_text,
|
||||
"add_checkbox", &tab::add_checkbox,
|
||||
|
@ -24,6 +24,24 @@ namespace big
|
||||
g_lua_manager = nullptr;
|
||||
}
|
||||
|
||||
bool lua_manager::has_gui_to_draw(rage::joaat_t tab_hash)
|
||||
{
|
||||
std::lock_guard guard(m_module_lock);
|
||||
|
||||
for (const auto& module : m_modules)
|
||||
{
|
||||
if (const auto it = module->m_gui.find(tab_hash); it != module->m_gui.end())
|
||||
{
|
||||
if (it->second.size())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void lua_manager::draw_gui(rage::joaat_t tab_hash)
|
||||
{
|
||||
std::lock_guard guard(m_module_lock);
|
||||
|
@ -37,11 +37,15 @@ namespace big
|
||||
return m_modules.size();
|
||||
}
|
||||
|
||||
|
||||
bool has_gui_to_draw(rage::joaat_t tab_hash);
|
||||
|
||||
inline const folder& get_scripts_folder() const
|
||||
{
|
||||
return m_scripts_folder;
|
||||
}
|
||||
|
||||
|
||||
void draw_gui(rage::joaat_t tab_hash);
|
||||
|
||||
void unload_module(rage::joaat_t module_id);
|
||||
|
@ -79,17 +79,16 @@ namespace big
|
||||
|
||||
lua_module::~lua_module()
|
||||
{
|
||||
for (const auto owned_tab : m_owned_tabs)
|
||||
{
|
||||
big::g_gui_service->remove_from_nav(owned_tab);
|
||||
}
|
||||
|
||||
for (auto script : m_registered_scripts)
|
||||
g_script_mgr.remove_script(script);
|
||||
|
||||
for (auto& patch : m_registered_patches)
|
||||
patch.reset();
|
||||
|
||||
for (auto memory : m_allocated_memory)
|
||||
delete[] memory;
|
||||
|
||||
m_registered_scripts.clear();
|
||||
m_registered_patches.clear();
|
||||
}
|
||||
|
||||
rage::joaat_t lua_module::module_id() const
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "lua_patch.hpp"
|
||||
#include "sol.hpp"
|
||||
#include "core/data/menu_event.hpp"
|
||||
#include <services/gui/gui_service.hpp>
|
||||
|
||||
namespace big
|
||||
{
|
||||
@ -20,6 +21,11 @@ namespace big
|
||||
public:
|
||||
std::vector<script*> m_registered_scripts;
|
||||
std::vector<std::shared_ptr<lua_patch>> m_registered_patches;
|
||||
|
||||
std::vector<big::tabs> m_owned_tabs;
|
||||
|
||||
std::unordered_map<big::tabs, std::vector<big::tabs>> m_tab_to_sub_tabs;
|
||||
|
||||
std::unordered_map<rage::joaat_t, std::vector<std::shared_ptr<lua::gui::gui_element>>> m_gui;
|
||||
std::unordered_map<menu_event, std::vector<sol::function>> m_event_callbacks;
|
||||
std::vector<void*> m_allocated_memory;
|
||||
|
Reference in New Issue
Block a user