diff options
| author | Alexander Gavrilov | 2012-03-15 13:01:23 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-03-15 13:01:23 +0400 |
| commit | 87f925e72e7c6f923a595cc930728483a3f1422e (patch) | |
| tree | 4da81e9346e9f21599cea8c7a2d95d8da4628e2e /library/PluginManager.cpp | |
| parent | e7851f5abdd1a84d29020f2789efc0f932284bf0 (diff) | |
| download | dfhack-87f925e72e7c6f923a595cc930728483a3f1422e.tar.gz dfhack-87f925e72e7c6f923a595cc930728483a3f1422e.tar.bz2 dfhack-87f925e72e7c6f923a595cc930728483a3f1422e.tar.xz | |
Add support for exporting functions from plugins, with example in rename.
TODO: test by actually calling them remotely.
Diffstat (limited to 'library/PluginManager.cpp')
| -rw-r--r-- | library/PluginManager.cpp | 70 |
1 files changed, 53 insertions, 17 deletions
diff --git a/library/PluginManager.cpp b/library/PluginManager.cpp index d36ba665..f7af9c95 100644 --- a/library/PluginManager.cpp +++ b/library/PluginManager.cpp @@ -26,9 +26,11 @@ distribution. #include "Core.h" #include "MemAccess.h" #include "PluginManager.h" +#include "RemoteServer.h" #include "Console.h" #include "DataDefs.h" +#include "MiscUtils.h" using namespace DFHack; @@ -146,6 +148,7 @@ Plugin::Plugin(Core * core, const std::string & filepath, const std::string & _f plugin_status = 0; plugin_onupdate = 0; plugin_onstatechange = 0; + plugin_rpcconnect = 0; state = PS_UNLOADED; access = new RefLock(); } @@ -154,12 +157,12 @@ Plugin::~Plugin() { if(state == PS_LOADED) { - unload(); + unload(Core::getInstance().getConsole()); } delete access; } -bool Plugin::load() +bool Plugin::load(color_ostream &con) { RefAutolock lock(access); if(state == PS_BROKEN) @@ -170,8 +173,6 @@ bool Plugin::load() { return true; } - Core & c = Core::getInstance(); - Console & con = c.getConsole(); DFLibrary * plug = OpenPlugin(filename.c_str()); if(!plug) { @@ -208,6 +209,7 @@ bool Plugin::load() plugin_onupdate = (command_result (*)(color_ostream &)) LookupPlugin(plug, "plugin_onupdate"); 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"); this->name = *plug_name; plugin_lib = plug; if(plugin_init(con,commands) == CR_OK) @@ -225,10 +227,8 @@ bool Plugin::load() } } -bool Plugin::unload() +bool Plugin::unload(color_ostream &con) { - Core & c = Core::getInstance(); - Console & con = c.getConsole(); // get the mutex access->lock(); // if we are actually loaded @@ -266,18 +266,18 @@ bool Plugin::unload() return false; } -bool Plugin::reload() +bool Plugin::reload(color_ostream &out) { if(state != PS_LOADED) return false; - if(!unload()) + if(!unload(out)) return false; - if(!load()) + if(!load(out)) return false; return true; } -command_result Plugin::invoke(color_ostream &out, std::string & command, std::vector <std::string> & parameters, bool interactive_) +command_result Plugin::invoke(color_ostream &out, const std::string & command, std::vector <std::string> & parameters) { Core & c = Core::getInstance(); command_result cr = CR_NOT_IMPLEMENTED; @@ -290,7 +290,7 @@ command_result Plugin::invoke(color_ostream &out, std::string & command, std::ve if(cmd.name == command) { // running interactive things from some other source than the console would break it - if(!(interactive_ && out.is_console()) && cmd.interactive) + if(!out.is_console() && cmd.interactive) cr = CR_WOULD_BREAK; else if (cmd.guard) { @@ -325,7 +325,7 @@ command_result Plugin::invoke(color_ostream &out, std::string & command, std::ve return cr; } -bool Plugin::can_invoke_hotkey( std::string & command, df::viewscreen *top ) +bool Plugin::can_invoke_hotkey(const std::string & command, df::viewscreen *top ) { Core & c = Core::getInstance(); bool cr = false; @@ -375,6 +375,42 @@ command_result Plugin::on_state_change(color_ostream &out, state_change_event ev return cr; } +RPCService *Plugin::rpc_connect(color_ostream &out) +{ + RPCService *rv = NULL; + + access->lock_add(); + + if(state == PS_LOADED && plugin_rpcconnect) + { + rv = plugin_rpcconnect(out); + } + + if (rv) + { + // Retain the access reference + assert(!rv->holder); + services.push_back(rv); + rv->holder = this; + return rv; + } + else + { + access->lock_sub(); + return NULL; + } +} + +void Plugin::detach_connection(RPCService *svc) +{ + int idx = linear_index(services, svc); + + assert(svc->holder == this && idx >= 0); + + vector_erase_at(services, idx); + access->lock_sub(); +} + Plugin::plugin_state Plugin::getState() const { return state; @@ -399,7 +435,7 @@ PluginManager::PluginManager(Core * core) Plugin * p = new Plugin(core, path + filez[i], filez[i], this); all_plugins.push_back(p); // make all plugins load by default (until a proper design emerges). - p->load(); + p->load(core->getConsole()); } } } @@ -435,13 +471,13 @@ Plugin *PluginManager::getPluginByCommand(const std::string &command) } // FIXME: handle name collisions... -command_result PluginManager::InvokeCommand(color_ostream &out, std::string & command, std::vector <std::string> & parameters, bool interactive) +command_result PluginManager::InvokeCommand(color_ostream &out, const std::string & command, std::vector <std::string> & parameters) { Plugin *plugin = getPluginByCommand(command); - return plugin ? plugin->invoke(out, command, parameters, interactive) : CR_NOT_IMPLEMENTED; + return plugin ? plugin->invoke(out, command, parameters) : CR_NOT_IMPLEMENTED; } -bool PluginManager::CanInvokeHotkey(std::string &command, df::viewscreen *top) +bool PluginManager::CanInvokeHotkey(const std::string &command, df::viewscreen *top) { Plugin *plugin = getPluginByCommand(command); return plugin ? plugin->can_invoke_hotkey(command, top) : false; |
