summaryrefslogtreecommitdiff
path: root/library/PluginManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'library/PluginManager.cpp')
-rw-r--r--library/PluginManager.cpp68
1 files changed, 63 insertions, 5 deletions
diff --git a/library/PluginManager.cpp b/library/PluginManager.cpp
index a314883e..d8b9ff27 100644
--- a/library/PluginManager.cpp
+++ b/library/PluginManager.cpp
@@ -108,6 +108,50 @@ struct Plugin::RefAutoinc
~RefAutoinc(){ lock->lock_sub(); };
};
+struct Plugin::LuaCommand {
+ Plugin *owner;
+ std::string name;
+ int (*command)(lua_State *state);
+
+ LuaCommand(Plugin *owner, std::string name)
+ : owner(owner), name(name), command(NULL) {}
+};
+
+struct Plugin::LuaFunction {
+ Plugin *owner;
+ std::string name;
+ function_identity_base *identity;
+ bool silent;
+
+ LuaFunction(Plugin *owner, std::string name)
+ : owner(owner), name(name), identity(NULL), silent(false) {}
+};
+
+struct Plugin::LuaEvent : public Lua::Event::Owner {
+ LuaFunction handler;
+ Lua::Notification *event;
+ bool active;
+ int count;
+
+ LuaEvent(Plugin *owner, std::string name)
+ : handler(owner,name), event(NULL), active(false), count(0)
+ {
+ handler.silent = true;
+ }
+
+ void on_count_changed(int new_cnt, int delta) {
+ RefAutoinc lock(handler.owner->access);
+ count = new_cnt;
+ if (event)
+ event->on_count_changed(new_cnt, delta);
+ }
+ void on_invoked(lua_State *state, int nargs, bool from_c) {
+ RefAutoinc lock(handler.owner->access);
+ if (event)
+ event->on_invoked(state, nargs, from_c);
+ }
+};
+
Plugin::Plugin(Core * core, const std::string & filepath, const std::string & _filename, PluginManager * pm)
{
filename = filepath;
@@ -151,6 +195,9 @@ bool Plugin::load(color_ostream &con)
{
return true;
}
+ // enter suspend
+ CoreSuspender suspend;
+ // open the library, etc
DFLibrary * plug = OpenPlugin(filename.c_str());
if(!plug)
{
@@ -188,7 +235,7 @@ bool Plugin::load(color_ostream &con)
plugin_shutdown = (command_result (*)(color_ostream &)) LookupPlugin(plug, "plugin_shutdown");
plugin_onstatechange = (command_result (*)(color_ostream &, state_change_event)) LookupPlugin(plug, "plugin_onstatechange");
plugin_rpcconnect = (RPCService* (*)(color_ostream &)) LookupPlugin(plug, "plugin_rpcconnect");
- plugin_eval_ruby = (command_result (*)(const char*)) LookupPlugin(plug, "plugin_eval_ruby");
+ plugin_eval_ruby = (command_result (*)(color_ostream &, const char*)) LookupPlugin(plug, "plugin_eval_ruby");
index_lua(plug);
this->name = *plug_name;
plugin_lib = plug;
@@ -226,6 +273,8 @@ bool Plugin::unload(color_ostream &con)
}
// wait for all calls to finish
access->wait();
+ // enter suspend
+ CoreSuspender suspend;
// notify plugin about shutdown, if it has a shutdown function
command_result cr = CR_OK;
if(plugin_shutdown)
@@ -439,7 +488,11 @@ void Plugin::index_lua(DFLibrary *lib)
cmd->handler.identity = evlist->event->get_handler();
cmd->event = evlist->event;
if (cmd->active)
+ {
cmd->event->bind(Lua::Core::State, cmd);
+ if (cmd->count > 0)
+ cmd->event->on_count_changed(cmd->count, 0);
+ }
}
}
}
@@ -467,7 +520,7 @@ int Plugin::lua_cmd_wrapper(lua_State *state)
luaL_error(state, "plugin command %s() has been unloaded",
(cmd->owner->name+"."+cmd->name).c_str());
- return cmd->command(state);
+ return Lua::CallWithCatch(state, cmd->command, cmd->name.c_str());
}
int Plugin::lua_fun_wrapper(lua_State *state)
@@ -477,8 +530,13 @@ int Plugin::lua_fun_wrapper(lua_State *state)
RefAutoinc lock(cmd->owner->access);
if (!cmd->identity)
+ {
+ if (cmd->silent)
+ return 0;
+
luaL_error(state, "plugin function %s() has been unloaded",
(cmd->owner->name+"."+cmd->name).c_str());
+ }
return LuaWrapper::method_wrapper_core(state, cmd->identity);
}
@@ -506,14 +564,14 @@ void Plugin::open_lua(lua_State *state, int table)
{
for (auto it = lua_events.begin(); it != lua_events.end(); ++it)
{
- Lua::MakeEvent(state, it->second);
+ Lua::Event::Make(state, it->second, it->second);
push_function(state, &it->second->handler);
- lua_rawsetp(state, -2, NULL);
+ Lua::Event::SetPrivateCallback(state, -2);
it->second->active = true;
if (it->second->event)
- it->second->event->bind(state, it->second);
+ it->second->event->bind(Lua::Core::State, it->second);
lua_setfield(state, table, it->first.c_str());
}