mirror of
https://github.com/edubart/otclient.git
synced 2025-10-14 11:34:54 +02:00
add modulemanager module
This commit is contained in:
@@ -162,8 +162,6 @@ void Application::terminate()
|
||||
|
||||
void Application::run()
|
||||
{
|
||||
g_lua.callGlobalField("g_app", "onRun");
|
||||
|
||||
ticks_t lastPollTicks = g_clock.updateTicks();
|
||||
m_stopping = false;
|
||||
m_running = true;
|
||||
|
@@ -221,7 +221,7 @@ namespace Fw
|
||||
|
||||
enum FocusReason {
|
||||
MouseFocusReason = 0,
|
||||
TabFocusReason,
|
||||
KeyboardFocusReason,
|
||||
ActiveFocusReason,
|
||||
OtherFocusReason
|
||||
};
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <framework/global.h>
|
||||
|
||||
class ModuleManager;
|
||||
class Module;
|
||||
class Event;
|
||||
class ScheduledEvent;
|
||||
|
@@ -31,36 +31,6 @@ Module::Module(const std::string& name)
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
void Module::discover(const OTMLNodePtr& moduleNode)
|
||||
{
|
||||
const static std::string none = "none";
|
||||
m_description = moduleNode->valueAt("description", none);
|
||||
m_author = moduleNode->valueAt("author", none);
|
||||
m_website = moduleNode->valueAt("website", none);
|
||||
m_version = moduleNode->valueAt("version", none);
|
||||
m_autoLoad = moduleNode->valueAt<bool>("autoLoad", false);
|
||||
m_autoLoadAntecedence = moduleNode->valueAt<int>("autoLoadAntecedence", 100);
|
||||
|
||||
if(OTMLNodePtr node = moduleNode->get("dependencies")) {
|
||||
for(const OTMLNodePtr& tmp : node->children())
|
||||
m_dependencies.push_back(tmp->value());
|
||||
}
|
||||
|
||||
// set onLoad callback
|
||||
if(OTMLNodePtr node = moduleNode->get("onLoad")) {
|
||||
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
|
||||
g_lua.useValue();
|
||||
m_loadCallback = g_lua.polymorphicPop<SimpleCallback>();
|
||||
}
|
||||
|
||||
// set onUnload callback
|
||||
if(OTMLNodePtr node = moduleNode->get("onUnload")) {
|
||||
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
|
||||
g_lua.useValue();
|
||||
m_unloadCallback = g_lua.polymorphicPop<SimpleCallback>();
|
||||
}
|
||||
}
|
||||
|
||||
bool Module::load()
|
||||
{
|
||||
if(m_loaded)
|
||||
@@ -95,3 +65,34 @@ void Module::unload()
|
||||
m_loaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Module::discover(const OTMLNodePtr& moduleNode)
|
||||
{
|
||||
const static std::string none = "none";
|
||||
m_description = moduleNode->valueAt("description", none);
|
||||
m_author = moduleNode->valueAt("author", none);
|
||||
m_website = moduleNode->valueAt("website", none);
|
||||
m_version = moduleNode->valueAt("version", none);
|
||||
m_autoLoad = moduleNode->valueAt<bool>("autoLoad", false);
|
||||
m_autoLoadAntecedence = moduleNode->valueAt<int>("autoLoadAntecedence", 100);
|
||||
|
||||
if(OTMLNodePtr node = moduleNode->get("dependencies")) {
|
||||
for(const OTMLNodePtr& tmp : node->children())
|
||||
m_dependencies.push_back(tmp->value());
|
||||
}
|
||||
|
||||
// set onLoad callback
|
||||
if(OTMLNodePtr node = moduleNode->get("onLoad")) {
|
||||
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
|
||||
g_lua.useValue();
|
||||
m_loadCallback = g_lua.polymorphicPop<SimpleCallback>();
|
||||
}
|
||||
|
||||
// set onUnload callback
|
||||
if(OTMLNodePtr node = moduleNode->get("onUnload")) {
|
||||
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
|
||||
g_lua.useValue();
|
||||
m_unloadCallback = g_lua.polymorphicPop<SimpleCallback>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -26,12 +26,12 @@
|
||||
#include "declarations.h"
|
||||
|
||||
#include <framework/otml/declarations.h>
|
||||
#include <framework/luascript/luaobject.h>
|
||||
|
||||
class Module
|
||||
class Module : public LuaObject
|
||||
{
|
||||
public:
|
||||
Module(const std::string& name);
|
||||
void discover(const OTMLNodePtr& moduleNode);
|
||||
|
||||
bool load();
|
||||
void unload();
|
||||
@@ -46,6 +46,10 @@ public:
|
||||
bool isAutoLoad() { return m_autoLoad; }
|
||||
int getAutoLoadAntecedence() { return m_autoLoadAntecedence; }
|
||||
|
||||
protected:
|
||||
void discover(const OTMLNodePtr& moduleNode);
|
||||
friend class ModuleManager;
|
||||
|
||||
private:
|
||||
Boolean<false> m_loaded;
|
||||
Boolean<false> m_autoLoad;
|
||||
|
@@ -30,6 +30,9 @@ ModuleManager g_modules;
|
||||
|
||||
void ModuleManager::discoverModules()
|
||||
{
|
||||
// remove modules that are not loaded
|
||||
m_autoLoadModules.clear();
|
||||
|
||||
auto moduleDirs = g_resources.listDirectoryFiles("/");
|
||||
for(const std::string& moduleDir : moduleDirs) {
|
||||
auto moduleFiles = g_resources.listDirectoryFiles("/" + moduleDir);
|
||||
@@ -85,12 +88,19 @@ ModulePtr ModuleManager::discoverModule(const std::string& moduleFile)
|
||||
OTMLNodePtr moduleNode = doc->at("Module");
|
||||
|
||||
std::string name = moduleNode->valueAt("name");
|
||||
if(getModule(name))
|
||||
Fw::throwException("module '", name, "' already exists, cannot have duplicate module names");
|
||||
//if(getModule(name))
|
||||
// Fw::throwException("module '", name, "' already exists, cannot have duplicate module names");
|
||||
|
||||
module = ModulePtr(new Module(name));
|
||||
bool push = false;
|
||||
module = getModule(name);
|
||||
if(!module) {
|
||||
module = ModulePtr(new Module(name));
|
||||
push = true;
|
||||
}
|
||||
module->discover(moduleNode);
|
||||
m_modules.push_back(module);
|
||||
|
||||
if(push)
|
||||
m_modules.push_back(module);
|
||||
} catch(Exception& e) {
|
||||
logError("Unable to discover module from file '", moduleFile, "': ", e.what());
|
||||
}
|
||||
|
@@ -36,6 +36,7 @@ public:
|
||||
void unloadModules();
|
||||
|
||||
ModulePtr getModule(const std::string& moduleName);
|
||||
std::vector<ModulePtr> getModules() { return m_modules; }
|
||||
|
||||
private:
|
||||
std::vector<ModulePtr> m_modules;
|
||||
|
@@ -30,6 +30,8 @@
|
||||
#include <framework/otml/otml.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/platform/platformwindow.h>
|
||||
#include <framework/core/modulemanager.h>
|
||||
#include <framework/core/module.h>
|
||||
|
||||
void Application::registerLuaFunctions()
|
||||
{
|
||||
@@ -83,6 +85,7 @@ void Application::registerLuaFunctions()
|
||||
g_lua.bindClassMemberFunction<UIWidget>("ungrabKeyboard", &UIWidget::ungrabKeyboard);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("bindRectToParent", &UIWidget::bindRectToParent);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("destroy", &UIWidget::destroy);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("destroyChildren", &UIWidget::destroyChildren);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setId", &UIWidget::setId);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setParent", &UIWidget::setParent);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setLayout", &UIWidget::setLayout);
|
||||
@@ -361,6 +364,19 @@ void Application::registerLuaFunctions()
|
||||
// Protocol
|
||||
g_lua.registerClass<Protocol>();
|
||||
|
||||
// Module
|
||||
g_lua.registerClass<Module>();
|
||||
g_lua.bindClassMemberFunction<Module>("load", &Module::load);
|
||||
g_lua.bindClassMemberFunction<Module>("unload", &Module::unload);
|
||||
g_lua.bindClassMemberFunction<Module>("isLoaded", &Module::isLoaded);
|
||||
g_lua.bindClassMemberFunction<Module>("getDescription", &Module::getDescription);
|
||||
g_lua.bindClassMemberFunction<Module>("getName", &Module::getName);
|
||||
g_lua.bindClassMemberFunction<Module>("getAuthor", &Module::getAuthor);
|
||||
g_lua.bindClassMemberFunction<Module>("getWebsite", &Module::getWebsite);
|
||||
g_lua.bindClassMemberFunction<Module>("getVersion", &Module::getVersion);
|
||||
g_lua.bindClassMemberFunction<Module>("isAutoLoad", &Module::isAutoLoad);
|
||||
g_lua.bindClassMemberFunction<Module>("getAutoLoadAntecedence", &Module::getAutoLoadAntecedence);
|
||||
|
||||
// network manipulation via lua is disabled for a while
|
||||
/*
|
||||
// OutputMessage
|
||||
@@ -451,6 +467,17 @@ void Application::registerLuaFunctions()
|
||||
g_lua.bindClassStaticFunction("g_ui", "setDebugBoxesDrawing", std::bind(&UIManager::setDebugBoxesDrawing, &g_ui, _1));
|
||||
g_lua.bindClassStaticFunction("g_ui", "isDrawingDebugBoxes", std::bind(&UIManager::setDebugBoxesDrawing, &g_ui, _1));
|
||||
|
||||
// ModuleManager
|
||||
g_lua.registerStaticClass("g_modules");
|
||||
g_lua.bindClassStaticFunction("g_modules", "discoverModulesPath", std::bind(&ModuleManager::discoverModulesPath, &g_modules));
|
||||
g_lua.bindClassStaticFunction("g_modules", "discoverModules", std::bind(&ModuleManager::discoverModules, &g_modules));
|
||||
g_lua.bindClassStaticFunction("g_modules", "autoLoadModules", std::bind(&ModuleManager::autoLoadModules, &g_modules, _1));
|
||||
g_lua.bindClassStaticFunction("g_modules", "discoverModule", std::bind(&ModuleManager::discoverModule, &g_modules, _1));
|
||||
g_lua.bindClassStaticFunction("g_modules", "ensureModuleLoaded", std::bind(&ModuleManager::ensureModuleLoaded, &g_modules, _1));
|
||||
g_lua.bindClassStaticFunction("g_modules", "unloadModules", std::bind(&ModuleManager::unloadModules, &g_modules));
|
||||
g_lua.bindClassStaticFunction("g_modules", "getModule", std::bind(&ModuleManager::getModule, &g_modules, _1));
|
||||
g_lua.bindClassStaticFunction("g_modules", "getModules", std::bind(&ModuleManager::getModules, &g_modules));
|
||||
|
||||
// FontManager
|
||||
g_lua.registerStaticClass("g_fonts");
|
||||
g_lua.bindClassStaticFunction("g_fonts", "importFont", std::bind(&FontManager::importFont, &g_fonts, _1));
|
||||
|
@@ -421,7 +421,7 @@ void UILineEdit::onGeometryChange(const Rect& oldRect, const Rect& newRect)
|
||||
void UILineEdit::onFocusChange(bool focused, Fw::FocusReason reason)
|
||||
{
|
||||
if(focused && !m_alwaysActive) {
|
||||
if(reason == Fw::TabFocusReason)
|
||||
if(reason == Fw::KeyboardFocusReason)
|
||||
setCursorPos(m_text.length());
|
||||
else
|
||||
blinkCursor();
|
||||
@@ -452,7 +452,7 @@ bool UILineEdit::onKeyPress(uchar keyCode, int keyboardModifiers, bool wouldFilt
|
||||
else if(keyCode == Fw::KeyTab) {
|
||||
if(!m_alwaysActive) {
|
||||
if(UIWidgetPtr parent = getParent())
|
||||
parent->focusNextChild(Fw::TabFocusReason);
|
||||
parent->focusNextChild(Fw::KeyboardFocusReason);
|
||||
}
|
||||
} else
|
||||
return false;
|
||||
|
@@ -219,6 +219,8 @@ void UIWidget::focusChild(const UIWidgetPtr& child, Fw::FocusReason reason)
|
||||
oldFocused->updateState(Fw::FocusState);
|
||||
oldFocused->updateState(Fw::ActiveState);
|
||||
}
|
||||
|
||||
onChildFocusChange(child, oldFocused, reason);
|
||||
}
|
||||
|
||||
void UIWidget::focusNextChild(Fw::FocusReason reason)
|
||||
@@ -485,7 +487,6 @@ void UIWidget::lower()
|
||||
|
||||
void UIWidget::raise()
|
||||
{
|
||||
focus();
|
||||
UIWidgetPtr parent = getParent();
|
||||
if(parent)
|
||||
parent->raiseChild(asUIWidget());
|
||||
@@ -546,9 +547,7 @@ void UIWidget::destroy()
|
||||
parent->removeChild(asUIWidget());
|
||||
}
|
||||
|
||||
// destroy children
|
||||
while(!m_children.empty())
|
||||
getFirstChild()->destroy();
|
||||
destroyChildren();
|
||||
|
||||
callLuaField("onDestroy");
|
||||
|
||||
@@ -568,6 +567,12 @@ void UIWidget::destroy()
|
||||
m_destroyed = true;
|
||||
}
|
||||
|
||||
void UIWidget::destroyChildren()
|
||||
{
|
||||
while(!m_children.empty())
|
||||
getFirstChild()->destroy();
|
||||
}
|
||||
|
||||
void UIWidget::setId(const std::string& id)
|
||||
{
|
||||
m_id = id;
|
||||
@@ -1108,6 +1113,11 @@ void UIWidget::onFocusChange(bool focused, Fw::FocusReason reason)
|
||||
callLuaField("onFocusChange", focused, reason);
|
||||
}
|
||||
|
||||
void UIWidget::onChildFocusChange(const UIWidgetPtr& focusedChild, const UIWidgetPtr& unfocusedChild, Fw::FocusReason reason)
|
||||
{
|
||||
callLuaField("onChildFocusChange", focusedChild, unfocusedChild, reason);
|
||||
}
|
||||
|
||||
void UIWidget::onHoverChange(bool hovered)
|
||||
{
|
||||
callLuaField("onHoverChange", hovered);
|
||||
@@ -1168,7 +1178,7 @@ bool UIWidget::onMousePress(const Point& mousePos, Fw::MouseButton button)
|
||||
bool UIWidget::onMouseRelease(const Point& mousePos, Fw::MouseButton button)
|
||||
{
|
||||
if(isPressed() && getRect().contains(mousePos))
|
||||
callLuaField("onClick");
|
||||
onClick(mousePos);
|
||||
|
||||
UIWidgetPtr draggedWidget = g_ui.getDraggingWidget();
|
||||
if(draggedWidget && button == Fw::MouseLeftButton && (containsPoint(mousePos) || asUIWidget() == g_ui.getRootWidget())) {
|
||||
@@ -1196,6 +1206,11 @@ bool UIWidget::onMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direc
|
||||
return callLuaField<bool>("onMouseWheel", mousePos, direction);
|
||||
}
|
||||
|
||||
bool UIWidget::onClick(const Point& mousePos)
|
||||
{
|
||||
return callLuaField<bool>("onClick", mousePos);
|
||||
}
|
||||
|
||||
bool UIWidget::onDoubleClick(const Point& mousePos)
|
||||
{
|
||||
return callLuaField<bool>("onDoubleClick", mousePos);
|
||||
|
@@ -105,6 +105,7 @@ public:
|
||||
void ungrabKeyboard();
|
||||
void bindRectToParent();
|
||||
void destroy();
|
||||
void destroyChildren();
|
||||
|
||||
void setId(const std::string& id);
|
||||
void setParent(const UIWidgetPtr& parent);
|
||||
@@ -169,6 +170,7 @@ protected:
|
||||
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
||||
virtual void onGeometryChange(const Rect& oldRect, const Rect& newRect);
|
||||
virtual void onFocusChange(bool focused, Fw::FocusReason reason);
|
||||
virtual void onChildFocusChange(const UIWidgetPtr& focusedChild, const UIWidgetPtr& unfocusedChild, Fw::FocusReason reason);
|
||||
virtual void onHoverChange(bool hovered);
|
||||
virtual void onDragEnter(const Point& mousePos);
|
||||
virtual void onDragLeave(UIWidgetPtr droppedWidget, const Point& mousePos);
|
||||
@@ -181,6 +183,7 @@ protected:
|
||||
virtual bool onMouseRelease(const Point& mousePos, Fw::MouseButton button);
|
||||
virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved);
|
||||
virtual bool onMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direction);
|
||||
virtual bool onClick(const Point& mousePos);
|
||||
virtual bool onDoubleClick(const Point& mousePos);
|
||||
|
||||
bool propagateOnKeyText(const std::string& keyText);
|
||||
|
Reference in New Issue
Block a user