From 06a27f142b65cef811d7e0a5931d54ed15725a7d Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 21 Aug 2005 10:44:29 +0200 Subject: Added 'Service' functions to the plugin interface --- PLUGINS.html | 108 +++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 87 insertions(+), 21 deletions(-) (limited to 'PLUGINS.html') diff --git a/PLUGINS.html b/PLUGINS.html index 111b545a..9cc53153 100644 --- a/PLUGINS.html +++ b/PLUGINS.html @@ -9,23 +9,23 @@
Version 1.3

-Copyright © 2004 Klaus Schmidinger
+Copyright © 2005 Klaus Schmidinger
kls@cadsoft.de
www.cadsoft.de/vdr

-
  -Important modifications introduced in version 1.3.18 are marked like this. -
-
  +
  Important modifications introduced in version 1.3.19 are marked like this.
-
  +
  Important modifications introduced in version 1.3.20 are marked like this.
-
  +
  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. @@ -58,7 +58,7 @@ structures and allows it to hook itself into specific areas to perform special a

  • Command line arguments
  • Command line help
  • Getting started -
      +
     
  • Shutting down
  • Main menu entry @@ -68,6 +68,9 @@ structures and allows it to hook itself into specific areas to perform special a
  • The Setup menu
  • Configuration files
  • Internationalization +
      +
  • Custom services +
  • Loading plugins into VDR
  • Building the distribution package @@ -81,7 +84,7 @@ structures and allows it to hook itself into specific areas to perform special a
  • Skins
  • Themes
  • Devices -
      +
     
  • Audio
  • Remote Control @@ -308,7 +311,7 @@ since VDR, for instance, has to create the plugin objects in order to get their command line help - and after that immediately destroys them again.

    The destructor has to clean up any data created by the plugin. -
      +
      Any threads the plugin may have created shall be stopped in the Stop() function.
    @@ -506,7 +509,7 @@ VDR to exit. If the plugin doesn't implement any background functionality or internationalized texts, it doesn't need to implement either of these functions. -
      +
     

    Shutting down

    Stop it, right there!

    @@ -866,6 +869,77 @@ Texts are first searched for in the Phrases registered for this plugin (i 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 doesn't handle itself. For example, a plugin may want to use features +that some other plugin offers, or it may want 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 a 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, one plugin can directly +call another plugin's 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, a +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 handled the request. +

    +To send a messages to all plugins, a 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!

    @@ -1046,7 +1120,6 @@ public: Take a look at the files player.h and dvbplayer.c to see how VDR implements its own player for the VDR recordings.

    -
      To play the actual data, the player needs to call its member function

    @@ -1060,7 +1133,6 @@ is attached to. There are no prerequisites regarding the length or alignment of
     individual block of data. The sum of all blocks must simply result in the
     desired data stream, and it must be delivered fast enough so that the
     DVB device doesn't run out of data.
    -
    To avoid busy loops the player should call its member function

    @@ -1069,7 +1141,6 @@ bool DevicePoll(cPoller &Poller, int TimeoutMs = 0);
     
     to determine whether the device is ready for further data.
     

    -
      By default all audio track handling is done by the device a player is attached to. If the player can provide more than a single audio track, and has special @@ -1088,7 +1159,6 @@ bool DeviceSetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char

    See device.h for details about the parameters for track handling. -

    The second part needed here is a control object that receives user input from the main program loop and reacts on this by telling the player what to do: @@ -1206,7 +1276,7 @@ public: }; cMyReceiver::cMyReceiver(int Pid) -
      +
      :cReceiver(0, -1, Pid)
    { @@ -1384,9 +1454,7 @@ public: virtual cSkinDisplayMenu *DisplayMenu(void); virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly); virtual cSkinDisplayVolume *DisplayVolume(void); -
      virtual cSkinDisplayMessage *DisplayTrack(int NumTracks, const char * const *Tracks); -
    virtual cSkinDisplayMessage *DisplayMessage(void); };

    @@ -1513,13 +1581,11 @@ repectively. If the device can provide more than a single audio track, it can implement the following function to make them available: -
     

     virtual void SetAudioTrackDevice(eTrackType Type);
     virtual int GetAudioChannelDevice(void);
     virtual void SetAudioChannelDevice(int AudioChannel);
     

    -

    Recording @@ -1669,7 +1735,7 @@ private: virtual void Action(void); public: cMyAudio(void); -
      +
      virtual void Play(const uchar *Data, int Length, uchar Id);
    virtual void Mute(bool On); -- cgit v1.2.3