#pragma once #include "lua_module.hpp" #include "core/enums.hpp" namespace big { class lua_manager { private: std::mutex m_module_lock; std::vector> m_modules; struct module_load_info { std::string m_name; std::function)> m_on_module_loaded; }; std::queue m_modules_load_queue; static constexpr std::chrono::seconds m_delay_between_changed_scripts_check = 3s; std::chrono::high_resolution_clock::time_point m_wake_time_changed_scripts_check; folder m_scripts_folder; public: bool m_schedule_reload_modules; public: lua_manager(folder scripts_folder); ~lua_manager(); void load_all_modules(); void unload_all_modules(); inline auto get_module_count() const { return m_modules.size(); } 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); void load_module(const std::string& module_name); void reload_changed_scripts(); void queue_load_module(const std::string& module_name, std::function)> on_module_loaded); void load_modules_from_queue(); std::weak_ptr get_module(rage::joaat_t module_id); void handle_error(const sol::error& error, const sol::state_view& state); template inline std::conditional_t, void, std::optional> trigger_event(Args&&... args) { std::lock_guard guard(m_module_lock); for (auto& module : m_modules) { if (auto vec = module->m_event_callbacks.find(menu_event_); vec != module->m_event_callbacks.end()) { for (auto& cb : vec->second) { auto result = cb(args...); if (!result.valid()) { handle_error(result, result.lua_state()); continue; } if constexpr (!std::is_void_v) { if (result.return_count() == 0) continue; if (!result[0].is()) continue; return result[0].get(); } } } } if constexpr (!std::is_void_v) return std::nullopt; } inline void for_each_module(auto func) { std::lock_guard guard(m_module_lock); for (auto& module : m_modules) { func(module); } } }; inline lua_manager* g_lua_manager; }