From patchwork Thu Aug 18 18:58:12 2005 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Udo Richter X-Patchwork-Id: 11983 Received: from imap.gmx.net ([213.165.64.20] helo=mail.gmx.net) by www.linuxtv.org with smtp (Exim 4.34) id 1E5pbD-0008OX-5K for vdr@linuxtv.org; Thu, 18 Aug 2005 20:58:47 +0200 Received: (qmail invoked by alias); 18 Aug 2005 18:58:15 -0000 Received: from math-ws1.mathematik.uni-kassel.de (EHLO [127.0.0.1]) [141.51.166.3] by mail.gmx.net (mp003) with SMTP; 18 Aug 2005 20:58:15 +0200 X-Authenticated: #1417946 Message-ID: <4304DA44.7030906@gmx.de> Date: Thu, 18 Aug 2005 20:58:12 +0200 From: Udo Richter User-Agent: Mozilla Thunderbird 1.0+ (Windows/20050712) MIME-Version: 1.0 To: Klaus Schmidinger's VDR Subject: Re: [vdr] Feature request: suggestion for cPlugin References: <4303471D.7860.DFAF9@localhost> <430492A8.2000608@gmx.de> <4304A9B1.2010601@cadsoft.de> In-Reply-To: <4304A9B1.2010601@cadsoft.de> X-Y-GMX-Trusted: 0 X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Klaus Schmidinger's VDR List-Id: Klaus Schmidinger's VDR List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Aug 2005 18:58:47 -0000 Status: O X-Status: X-Keywords: X-UID: 4258 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