Skip to content
m42a edited this page Mar 29, 2012 · 5 revisions

Writing a minimal lirch plugin is simple. Simply create a .cpp file, and include lirch_plugin.h. Then, create a function void run(plugin_pipe, std::string). You've successfully made a lirch plugin!

In order to make a useful lirch plugin, a bit more work is required. First, you'll want to understand the way you interact with lirch. Every interaction with lirch is done through the plugin_pipe that is passed to your run function. You can send messages to the core by calling plugin_pipe::write(message). You can read messages from the core by calling plugin_pipe::read() or plugin_pipe::blocking_read(). The difference between read and blocking_read is that read returns an empty message if you have no pending messages, whereas blocking_read will suspend your plugin until it reads a message. If you want to get the next message without removing it from the pipe, you can call plugin_pipe::peek(). To check if there is a message available, call plugin_pipe::has_message.

Now that you know how to read and write messages, you can start to add functionality. The first message you'll want to handle is the shutdown message. This message has the message type "shutdown", and has no attributes. This message is sent to you when your plugin should shut down. When you recieve this message, you should do your plugin's cleanup, and then return from the run function.

The next thing you'll want to do is register to receive messages. To do this, you'll need your plugin's name, which is the second parameter to the run function. You'll then need to choose what message type you want to register for, and at what priority. Priorities are handled in descending order, and span from 32766 to -32766. Once you've decided what messages you want to register for, you can send the register message. To do this, call the registration_message::create function with the priority you want to register for, your plugin name, and the message type. If, for example, you want to register for messages of type foo with a priority of 16384, simply call pipe.write(registration_message::create(16384, name, "foo")). After this, you will receive a registration_status message which will tell you whether or not your registration status was successful. As in Demon's Souls, you should beware of false messages, and safely check a message's type before accessing its internal data. The following bit of code is a safe way to get your plugin's registration status:

message m=pipe.read();
if (m.type=="registration_status")
{
    auto internals=dynamic_cast<registration_status *>(m.getdata());
    if (!internals)
    {
        //This wasn't really a registration_status message
    }
    else
    {
        //This is a registration_status message, just like it said
    if (internals->status)
        //We registered for internals->type with priority internals->priority
    else
        //Our registration failed; maybe try registering with a slightly different priority?
    }
}

Since your plugin runs in its own thread, do not call non-reentrant global functions. This is usually not difficult, since no STL functions are reentrant, but some functions inherited from C are. In particular, any of the exit functions should be avoided, since they may quit the entire program instead of just your plugin.

Miscelaneous Notes:

  • Don't start your plugin's function names with plugin_; those are all reserved for future use.

  • If you receive an unexpected message, send it back out with a decremented priority instead of ignoring it; you can simply call pipe.write(m.decrement_priority()) to deal with these.

Clone this wiki locally