Creating a libretroshare service

From RetroShare
Jump to: navigation, search

Creating a new service is quite simple. It breaks down to 5 parts:

  • Creating the Core Interface
  • Creating the New Service
  • Creating Serialisable Data Type
  • Creating the GUI
  • Putting it all together

Contents

Creating the Core Interface

The Core Interface is used by the GUI to get all the data it needs. In this basic example, the GUI can request a list of Example Ids, and the use these Ids to get the details.

The interface header file is located in **libretroshare/src/rsiface/**[rsExampleInterface.h]

<source lang="cpp">

  1. include <string>

class ExampleInfo {

   std::string id;
   std::string msg;

};

class rsExampleInterface {

   public:

virtual bool getExampleIds(std::list<std::string> &ids) = 0; virtual bool getExampleInfo(std::string id, ExampleInfo &info) = 0; virtual bool addExampleInfo(ExampleInfo &info) = 0; };

</source>

Creating the New Service

The service using the "p3Service" to receive and send its network data, and provides the Interface Functions, so the GUI can access the data.

This is the heart of the Service, and provides most of the functionality. These files are located in libretroshare/src/services/[p3ExampleService.h]

<source lang="cpp">

  1. include "rsiface/rsExampleInterface.h"
  2. include "services/p3service.h"

class ExampleService: public p3Service, public rsExampleInterface {

       public:
   ExampleService();

/****** Overloaded from Service *****/ virtual int tick();

/****** I/O handling *******/ int handleIncoming(); /* called by tick() */

/****** GUI Interface ******/ virtual bool getExampleIds(std::list<std::string> &ids); virtual bool getExampleInfo(std::string id, ExampleInfo &info); virtual bool addExampleInfo(ExampleInfo &info);

/****** DATA *****/

   /* what ever you want! */

};

</source>


Internal DataTypes for your New Service

Your service is likely to communicate over the network, using its own DataTypes. These are added to the libretroshare/src/serialiser directory.

The DataTypes are derived from RsItem(), you must implement the clear() and print() functions for each data type. The Serialisers are derived from RsSerialType(), you must implement size() serialise() and deserialise().

Creation of these classes is very easy, and there are lots of examples that you can work from. There are also lots of Base Data Types that you can use to transmit more complex data.

<source lang="cpp">

  1. include "rsiface/rsExampleInterface.h"
  2. include "services/p3service.h"

class RsExampleItem: public RsItem {

       public:
       RsExampleItem()
       :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_EXAMPLE,
               RS_PKT_SUBTYPE_DEFAULT) { return; }

virtual ~RsExampleItem();

virtual void clear(); std::ostream &print(std::ostream &out, uint16_t indent = 0);

       /* DATA */
   std::string exampleId;
   std::string exampleMsg;

};


class RsExampleSerialiser: public RsSerialType {

       public:
       RsExampleSerialiser()
       :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_EXAMPLE)
       { return; }

virtual ~RsExampleSerialiser()

       { return; }

virtual uint32_t size(RsItem *); virtual bool serialise (RsItem *item, void *data, uint32_t *size); virtual RsItem * deserialise(void *data, uint32_t *size);

};


</source>

Creating the GUI.

Here you can let you imagination run wild, we won't give an example as this is the most varied part of the service.

Generally you create a UI design using Qt-Designer, and then have a .h/.cpp pair to attach all the buttons and load the data from the interface.

There are lots of examples in retroshare-gui/src/gui, eg. check out MessagesDialog.h PeerDialog.h ChatDialog.h

Putting it All Together

Inside libretroshare/src/rsserver/p3face-startup.cc, the services are added to the retroshare core.

<source lang="cpp">

  1. include "services/p3ExampleInterface.h"

/*** ... ...

        • /


int RsServer::StartupRetroShare(RsInit *config) {

       /**************************************************************************/
       /* STARTUP procedure */
       /**************************************************************************/
       /**************************************************************************/
       /* STARTUP CORE ... (REMOVED FOR CLARITY) */
   ....
   ....
   ....
       /**************************************************************************/
  1. ifndef RS_RELEASE
       p3ExampleService *exampleService = new p3ExampleService(); /* create service */
       pqih -> addService(exampleService) /* add Service into the Core */
       rsExampleService = exampleService  /* save Pointer for GUI */
  1. else
       rsExampleService = NULL;  /* leave new service out of release until its been well tested! */
  1. endif
   ....
   ....
   ....

}

</source>


Add the GUI Page in retroshare-gui/src/gui/ApplicationWindow.cpp


<source lang="cpp">

  1. include "ExampleDialog.h"

... ... ...

/** Constructor */ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags)

   : QMainWindow(parent, flags)

{

   ....
   ....
   ....
   /* Add Dialog Page into the Stack */
   ExampleDialog *exampleDialog = NULL;
   ui.stackPages->add(exampleDialog = new ExampleDialog(ui.stackPages),
                     createPageAction(QIcon(IMAGE_EXAMPLE), tr("Example Application"), grp));
   ....
   ....
   ....

}


</source>

You should then be able to compile it all together, and run retroshare with your new application!

Personal tools
Namespaces

Variants
Actions
Navigation
External websites
Wiki
Toolbox