From patchwork Sun Aug 21 01:13:52 2005 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Udo Richter X-Patchwork-Id: 11986 Received: from mail.gmx.de ([213.165.64.20] helo=mail.gmx.net) by www.linuxtv.org with smtp (Exim 4.34) id 1E6ePw-0001TJ-P2 for vdr@linuxtv.org; Sun, 21 Aug 2005 03:14:32 +0200 Received: (qmail invoked by alias); 21 Aug 2005 01:14:01 -0000 Received: from math-ws1.mathematik.uni-kassel.de (EHLO [127.0.0.1]) [141.51.166.3] by mail.gmx.net (mp014) with SMTP; 21 Aug 2005 03:14:01 +0200 X-Authenticated: #1417946 Message-ID: <4307D550.8000205@gmx.de> Date: Sun, 21 Aug 2005 03:13:52 +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> <4304DA44.7030906@gmx.de> <4305D406.3090208@cadsoft.de> <430769B6.3020402@gmx.de> In-Reply-To: <430769B6.3020402@gmx.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: Sun, 21 Aug 2005 01:14:32 -0000 Status: O X-Status: X-Keywords: X-UID: 4332 Udo Richter wrote: > New patch including docs etc. later this day. ... as promised. Custom plugin services, including PLUGINS.html and newplugin update. This version still mentions Data=NULL as supported query. Cheers, Udo diff -au vdr-1.3.29-orig/newplugin vdr-1.3.29/newplugin --- vdr-1.3.29-orig/newplugin 2005-01-30 14:50:05.000000000 +0100 +++ vdr-1.3.29/newplugin 2005-08-20 19:45:04.000000000 +0200 @@ -170,6 +170,7 @@ virtual cOsdObject *MainMenuAction(void); virtual cMenuSetupPage *SetupMenu(void); virtual bool SetupParse(const char *Name, const char *Value); + virtual bool Service(const char *Id, void *Data = NULL); }; cPlugin${PLUGIN_CLASS}::cPlugin$PLUGIN_CLASS(void) @@ -236,6 +237,12 @@ return false; } +bool cPlugin${PLUGIN_CLASS}::Service(const char *Id, void *Data) +{ + // Handle custom service requests from other plugins + return false; +} + VDRPLUGINCREATOR(cPlugin$PLUGIN_CLASS); // Don't touch this! }; 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-20 19:37:41.000000000 +0200 @@ -99,6 +99,11 @@ Setup.Store(Name, Value, this->Name()); } +bool cPlugin::Service(const char *Id, void *Data) +{ + return false; +} + void cPlugin::RegisterI18n(const tI18nPhrase * const Phrases) { I18nRegister(Phrases, Name()); @@ -372,6 +377,31 @@ return NULL; } +cPlugin *cPluginManager::CallFirstService(const char *Id, void *Data) +{ + if (pluginManager) { + for (cDll *dll = pluginManager->dlls.First(); dll; dll = pluginManager->dlls.Next(dll)) { + cPlugin *p = dll->Plugin(); + if (p) + if (p->Service(Id, Data)) return p; + } + } + return NULL; +} + +bool cPluginManager::CallAllServices(const char *Id, 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->Service(Id, 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-21 03:00:29.000000000 +0200 @@ -50,6 +50,8 @@ void RegisterI18n(const tI18nPhrase * const Phrases); + virtual bool Service(const char *Id, void *Data = NULL); + static void SetConfigDirectory(const char *Dir); static const char *ConfigDirectory(const char *PluginName = NULL); }; @@ -88,6 +90,8 @@ static bool HasPlugins(void); static cPlugin *GetPlugin(int Index); static cPlugin *GetPlugin(const char *Name); + static cPlugin *CallFirstService(const char *Id, void *Data = NULL); + static bool CallAllServices(const char *Id, void *Data = NULL); void StopPlugins(void); void Shutdown(void); }; diff -au vdr-1.3.29-orig/PLUGINS.html vdr-1.3.29/PLUGINS.html --- vdr-1.3.29-orig/PLUGINS.html 2005-02-12 18:08:27.000000000 +0100 +++ vdr-1.3.29/PLUGINS.html 2005-08-20 20:34:40.000000000 +0200 @@ -26,6 +26,9 @@
  Important modifications introduced in version 1.3.21 are marked like this.
+
  +Important modifications introduced in version 1.3.30 are marked like this. +

VDR provides an easy to use plugin interface that allows additional functionality to be added to the program by implementing a dynamically loadable library file. @@ -68,6 +71,9 @@

  • The Setup menu
  • Configuration files
  • Internationalization +
      +
  • Custom services +
  • Loading plugins into VDR
  • Building the distribution package @@ -866,6 +872,77 @@ and then in the global VDR texts. So a plugin can make use of texts defined by the core VDR code. +
      +

    Custom services

    + +
    What can I do for you?

    + +In some situations, two plugins may want to communicate directly, talking about things +that VDR doesnt handle yet as mediator. For example, a plugin may want to use features +that a different plugin offers, or a plugin wants to inform other plugins about important +things it does. To receive requests or messages, a plugin can implement the +following function: + +

    +virtual bool Service(const char *Id, void *Data = NULL);
    +

    + +Id is an unique identification string that identifies the service protocol. +To avoid collisions, the string should contain a service name, the plugin name (unless +the service is not related to a single plugin) and a protocol version number. +Data points to a custom data structure or is NULL to detect whether +the plugin supports this service. For each id string there should be a specification +that describes the format of the data structure, and any change to the format should +be reflected by a change of the id string. +

    +The function shall return true for any service ID string it handles, and false +otherwise. The function shall not perform any actions as long as Data is +NULL. The plugins have to agreee in which situations the service +may be called, for example whether the service may be called from every thread, or +just from the main thread. A possible implementation could look like this: + +

    +struct Hello_SetGreetingTime_v1_0 {
    +  int NewGreetingTime;
    +};
    +
    +bool cPluginHello::Service(const char *Id, void *Data)
    +{
    +  if (strcmp(Id, "Hello-SetGreetingTime-v1.0") == 0)
    +  {
    +    if (Data == NULL) return true;
    +    GreetingTime = ((Hello_SetGreetingTime_v1_0*)Data)->NewGreetingTime;
    +    return true;
    +  }
    +  return false;
    +}
    +

    + +

    +To send messages to, or request services from a specific plugin, the plugin can directly call its +service function: + +

    +Hello_SetGreetingTime_v1_0 hellodata;
    +hellodata.NewGreetingTime = 3;
    +cPlugin *Plugin = cPluginManager::GetPlugin("hello");
    +if (Plugin)
    +   Plugin->Service("Hello-SetGreetingTime-v1.0", &hellodata);
    +

    + +To send messages to, or request services from some plugin that offers the protocol, the +plugin can call the function cPluginManager::CallFirstService. This function +will send the request to the first plugin that supports this service protocol. The +function returns a pointer to the plugin that handled the request, or NULL +if no plugin handles the request. +

    +To send a messages to all plugins, the plugin can call the function +cPluginManager::CallAllServices. This function will send the request to +all plugins that support this service protocol. The function returns true if +any plugin handled the request, or false if no plugin handled the request. + +

    +

    Loading plugins into VDR

    Saddling up!