2023-06-20 04:33:09 +00:00
|
|
|
#include "StarLuaComponents.hpp"
|
|
|
|
#include "StarUtilityLuaBindings.hpp"
|
|
|
|
#include "StarRootLuaBindings.hpp"
|
|
|
|
|
|
|
|
namespace Star {
|
|
|
|
|
|
|
|
LuaBaseComponent::LuaBaseComponent() {
|
|
|
|
addCallbacks("sb", LuaBindings::makeUtilityCallbacks());
|
|
|
|
addCallbacks("root", LuaBindings::makeRootCallbacks());
|
|
|
|
setAutoReInit(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
LuaBaseComponent::~LuaBaseComponent() {}
|
|
|
|
|
|
|
|
StringList const& LuaBaseComponent::scripts() const {
|
|
|
|
return m_scripts;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LuaBaseComponent::setScript(String script) {
|
2024-02-19 15:55:19 +00:00
|
|
|
setScripts({std::move(script)});
|
2023-06-20 04:33:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void LuaBaseComponent::setScripts(StringList scripts) {
|
|
|
|
if (initialized())
|
|
|
|
throw LuaComponentException("Cannot call LuaWorldComponent::setScripts when LuaWorldComponent is initialized");
|
|
|
|
|
2024-02-19 15:55:19 +00:00
|
|
|
m_scripts = std::move(scripts);
|
2023-06-20 04:33:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void LuaBaseComponent::addCallbacks(String groupName, LuaCallbacks callbacks) {
|
|
|
|
if (!m_callbacks.insert(groupName, callbacks).second)
|
2023-06-27 10:23:44 +00:00
|
|
|
throw LuaComponentException::format("Duplicate callbacks named '{}' in LuaBaseComponent", groupName);
|
2023-06-20 04:33:09 +00:00
|
|
|
|
|
|
|
if (m_context)
|
|
|
|
m_context->setCallbacks(groupName, callbacks);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LuaBaseComponent::removeCallbacks(String const& groupName) {
|
|
|
|
if (m_callbacks.remove(groupName)) {
|
|
|
|
if (m_context)
|
|
|
|
m_context->remove(groupName);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LuaBaseComponent::autoReInit() const {
|
|
|
|
return (bool)m_reloadTracker;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LuaBaseComponent::setAutoReInit(bool autoReInit) {
|
|
|
|
if (autoReInit) {
|
|
|
|
m_reloadTracker = make_shared<TrackerListener>();
|
|
|
|
Root::singleton().registerReloadListener(m_reloadTracker);
|
|
|
|
} else {
|
|
|
|
m_reloadTracker.reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void LuaBaseComponent::setLuaRoot(LuaRootPtr luaRoot) {
|
2024-02-19 15:55:19 +00:00
|
|
|
m_luaRoot = std::move(luaRoot);
|
2023-06-20 04:33:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
LuaRootPtr const& LuaBaseComponent::luaRoot() {
|
|
|
|
return m_luaRoot;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LuaBaseComponent::init() {
|
|
|
|
uninit();
|
|
|
|
|
|
|
|
if (!m_luaRoot)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
m_error.reset();
|
|
|
|
try {
|
|
|
|
m_context = m_luaRoot->createContext(m_scripts);
|
|
|
|
} catch (LuaException const& e) {
|
2023-06-27 10:23:44 +00:00
|
|
|
Logger::error("Exception while creating lua context for scripts '{}': {}", m_scripts, outputException(e, true));
|
2023-06-20 04:33:09 +00:00
|
|
|
m_error = String(printException(e, false));
|
|
|
|
m_context.reset();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
contextSetup();
|
|
|
|
|
|
|
|
if (m_context->containsPath("init")) {
|
|
|
|
try {
|
|
|
|
m_context->invokePath("init");
|
|
|
|
} catch (LuaException const& e) {
|
2023-06-27 10:23:44 +00:00
|
|
|
Logger::error("Exception while calling script init: {}", outputException(e, true));
|
2023-06-20 04:33:09 +00:00
|
|
|
m_error = String(printException(e, false));
|
|
|
|
m_context.reset();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LuaBaseComponent::uninit() {
|
|
|
|
if (m_context) {
|
|
|
|
if (m_context->containsPath("uninit")) {
|
|
|
|
try {
|
|
|
|
m_context->invokePath("uninit");
|
|
|
|
} catch (LuaException const& e) {
|
2023-06-27 10:23:44 +00:00
|
|
|
Logger::error("Exception while calling script uninit: {}", outputException(e, true));
|
2023-06-20 04:33:09 +00:00
|
|
|
m_error = String(printException(e, false));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
contextShutdown();
|
|
|
|
m_context.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_error.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LuaBaseComponent::initialized() const {
|
|
|
|
return m_context.isValid();
|
|
|
|
}
|
|
|
|
|
|
|
|
Maybe<String> const& LuaBaseComponent::error() const {
|
|
|
|
return m_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
Maybe<LuaContext> const& LuaBaseComponent::context() const {
|
|
|
|
return m_context;
|
|
|
|
}
|
|
|
|
|
|
|
|
Maybe<LuaContext>& LuaBaseComponent::context() {
|
|
|
|
return m_context;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LuaBaseComponent::contextSetup() {
|
|
|
|
m_context->setPath("self", m_context->createTable());
|
|
|
|
|
|
|
|
for (auto const& p : m_callbacks)
|
|
|
|
m_context->setCallbacks(p.first, p.second);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LuaBaseComponent::contextShutdown() {}
|
|
|
|
|
|
|
|
void LuaBaseComponent::setError(String error) {
|
|
|
|
m_context.reset();
|
2024-02-19 15:55:19 +00:00
|
|
|
m_error = std::move(error);
|
2023-06-20 04:33:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool LuaBaseComponent::checkInitialization() {
|
|
|
|
// We should re-initialize if we are either already initialized or in an
|
|
|
|
// error state (which means we WERE initialized until we had an error)
|
|
|
|
bool shouldBeInitialized = initialized() || error();
|
|
|
|
if (shouldBeInitialized && m_reloadTracker && m_reloadTracker->pullTriggered())
|
|
|
|
init();
|
|
|
|
return initialized();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|