Klaus Schmidinger wrote:
Udo Richter wrote:
A far better way would be of course if VDR's cPlugin would have such a general purpose interface. My approach would be like this:
virtual bool ExtensionInterface(const char *ExtensionId, void *Data)
Plugins return false unless ExtensionId matches a known unique protocol ID. If the plugin supports this protocol, true will be returned in any case. If *Data is not NULL, it points to a protocol-specific buffer. If *Data is NULL, this is just a protocol-supported call.
cPluginManager should have methods to call ExtensionInterface for all plugins (broadcast-like), or for all plugins until one plugin returns true (find one that offers the interface).
@Klaus: I can implement that if interested.
Well, since I'm not going to use that interface, anyway, and it shouldn't have any impact on plain vanilla VDR, just go ahead and send a patch.
And don't forget to adjust PLUGINS.html ;-)
Ok, here's a first implementation of what I had in mind. The attached patch implements the interface for VDR 1.3.20 and newer. PLUGINS.html and newplugin still need to be updated. ;)
The attached vdr-extintf-0.1.0.tgz implements two sample plugins that do some communication: Direct communication to a specific plugin, detecting presence of plugins that offer a service, use a service provided by some plugin and broadcast a message to all interested plugins. Install as usual. Load the two plugins with vdr -P extcli -P extsvr.
@Plugin developers: Suggestions, reviews and comments are welcome!
Cheers,
Udo
diff -au vdr-1.3.29-orig/plugin.c vdr-1.3.29/plugin.c --- vdr-1.3.29-orig/plugin.c 2005-01-30 15:05:20.000000000 +0100 +++ vdr-1.3.29/plugin.c 2005-08-18 18:20:05.000000000 +0200 @@ -99,6 +99,11 @@ Setup.Store(Name, Value, this->Name()); }
+bool cPlugin::ExtensionInterface(const char *ExtensionId, void *Data) +{ + return false; +} + void cPlugin::RegisterI18n(const tI18nPhrase * const Phrases) { I18nRegister(Phrases, Name()); @@ -372,6 +377,43 @@ return NULL; }
+cPlugin *cPluginManager::CallFirstExtension(const char *ExtensionId, void *Data) +{ + if (pluginManager) { + for (cDll *dll = pluginManager->dlls.First(); dll; dll = pluginManager->dlls.Next(dll)) { + cPlugin *p = dll->Plugin(); + if (p) + if (p->ExtensionInterface(ExtensionId, Data)) return p; + } + } + return NULL; +} + +cPlugin *cPluginManager::CallPluginExtension(const char *PluginName, const char *ExtensionId, void *Data) +{ + if (pluginManager) { + for (cDll *dll = pluginManager->dlls.First(); dll; dll = pluginManager->dlls.Next(dll)) { + cPlugin *p = dll->Plugin(); + if (p && strcmp(p->Name(), PluginName) == 0) + if (p->ExtensionInterface(ExtensionId, Data)) return p; + } + } + return NULL; +} + +bool cPluginManager::CallAllExtensions(const char *ExtensionId, void *Data) +{ + bool found=false; + if (pluginManager) { + for (cDll *dll = pluginManager->dlls.First(); dll; dll = pluginManager->dlls.Next(dll)) { + cPlugin *p = dll->Plugin(); + if (p) + if (p->ExtensionInterface(ExtensionId, Data)) found=true; + } + } + return found; +} + void cPluginManager::StopPlugins(void) { for (cDll *dll = dlls.Last(); dll; dll = dlls.Prev(dll)) { diff -au vdr-1.3.29-orig/plugin.h vdr-1.3.29/plugin.h --- vdr-1.3.29-orig/plugin.h 2005-01-30 15:03:48.000000000 +0100 +++ vdr-1.3.29/plugin.h 2005-08-18 20:22:20.000000000 +0200 @@ -50,6 +50,8 @@
void RegisterI18n(const tI18nPhrase * const Phrases);
+ virtual bool ExtensionInterface(const char *ExtensionId, void *Data = NULL); + static void SetConfigDirectory(const char *Dir); static const char *ConfigDirectory(const char *PluginName = NULL); }; @@ -88,8 +90,12 @@ static bool HasPlugins(void); static cPlugin *GetPlugin(int Index); static cPlugin *GetPlugin(const char *Name); + static cPlugin *CallFirstExtension(const char *ExtensionId, void *Data = NULL); + static cPlugin *CallPluginExtension(const char *PluginName, const char *ExtensionId, void *Data = NULL); + static bool CallAllExtensions(const char *ExtensionId, void *Data = NULL); void StopPlugins(void); void Shutdown(void); }; +#define PATCH_EXTENSIONINTERFACE
#endif //__PLUGIN_H