Plugins and mode - p-o-n-y/pony GitHub Wiki

The main part of work done by users is writing plugins. While they can differ from each other, there are some rules and recommendations for all of them.

First, pony requires that plugins have return type void and do not have parameters, so their signature should look like this:

void plugin_name(void)

(Writing void plugin_name() would suggest that you can pass unspecified/variable arguments)

Then, plugins should in general have the following structure,

void plugin_name(void)
{
    ...
    if (pony.bus.mode > 0)
    {
        ...
    }
    else if (pony.bus.mode == 0)
    {
        ...
    }
    else
    {
        ...
    }
}

which allows the plugin to initialise, work regularly and terminate when it should, depending on the current work mode. On the topic of work modes, there are three of them: 0 is initialisation, when you open files, set all the constants, pointers and so on to the needed values; greater than 0 (typically 1) is regular work mode, which contains actions done in a cycle (calculations, reading the next line from file, ect.); and less than 0 is termination, when resourses get released (freeing memory allocated by the user, closing files). Regular work mode and termination can be set by user in the plugin. In case of the regular work mode, it can be set only when the plugin is in another regular work mode (for instance, from 1 to 2). Pony does not have special directions for that, this is just a mechanic that might be useful is your plugins. In case of termination, it can be set either in initialisation or in regular work mode. Pony suggests that mode being -1 is intended (successful) termination and other values are set when errors happen (for instance, not opening the file "a1.txt" because there is no file "a1.txt"). We are currently considering reserving minimal value of int for termination caused by host in multithreaded applications. Also, except for certain cases covered in multithreaded applications, in regular work mode at least one of the plugins has to be able to set the mode to termination to avoid infinite loop.

Finally, some recommendations on how to make your plugin more easily transferable between projects and between versions of pony.

Consider using static variables in your plugins. Since they keep their values between function calls, they can be used to store plugin-specific values, for instance data parsed from configuration string or pointers to parts of bus.

In terms of storing pointers this way, if the bus structure changes, this also allows to change only one line per pointer in your plugin instead of searching for multiple. Less changes - less mistakes (*note: theoretically).

However, if you do use static variables, we strongly recommend that all non-pointers get initialised in mode == 0 block, and all pointers are initialised with NULL when declared and are set to NULL after the associated resourses have been released during termination. There is always a chance that a previous plugin has failed initialisation and so has set mode to <0 (which means you have to check your resourses for having been allocated before releasing them, which is most easily done by checking for NULL), and there is a chance that your plugin will later be used in a project where pony gets reinitialised, so try to leave the plugn in the same condition as you recieved it - non-pointers are considered to contain garbage and pointers are NULL. Also, if you add a plugin to the execution list multiple times, add a check for the pointers being NULL before allocating resourses, like you would do before releasing resourses.