D1. Creating a new C++ Module
This tutorial contains short instructions on how to set up a new C++ module for Syntalos.
1. Building Syntalos
The easiest way to add a new C++ module is to build it with Syntalos itself, as building it out-of-tree is not very well tested yet.
Follow the instructions to build Syntalos from source in the Syntalos installation instructions. You can also open the Syntalos sources in QtCreator or any C/C++ IDE you prefer.
Quick build instructions for Debian/Ubuntu:
sudo apt install \
git ca-certificates \
python3-pip \
cmake \
gettext \
libaravis-dev \
libavcodec-dev \
libavformat-dev \
libavutil-dev \
libegl-dev \
libeigen3-dev \
libglib2.0-dev \
libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev \
libkf5archive-dev \
libkf5texteditor-dev \
libqtermwidget5-1-dev \
libvips-dev \
libopencv-dev \
libpipewire-0.3-dev \
libqt5opengl5-dev \
libiceoryx-introspection-dev \
libqt5serialport5-dev \
libqt5svg5-dev \
libswscale-dev \
libusb-1.0-0-dev \
libv4l-dev \
libxml2-dev \
libxxhash-dev \
libsystemd-dev \
systemd-dev \
meson \
ninja-build \
ocl-icd-opencl-dev \
pybind11-dev \
python3-dev \
python3-numpy \
qtbase5-dev \
qtmultimedia5-dev \
udev \
uuid-dev
mkdir build && cd build
meson ..
ninja
sudo ninja install
Once you can build Syntalos, you can set up your new C++ module. Do not hesitate to ask questions in case you run into any issues and file an issue or ask in Discussions on GitHub.
2. Copy a Template
The easiest way to start building a new module is to copy a template. A minimal C++ module exists in the form of example-cpp. Copy its directory and rename it to your chosen ID name. A module ID name must be unique and can not be changed once it is chosen, because otherwise existing configurations would break. It uniquely identifies your module, and may only contain alphanumeric characters, dashes and underscores.
3. Adjust Metadata
Rename the C++ files if you want to and adjust any naming in meson.build
. Also, ensure your new module directory
is included in a subdir()
directive in the toplevel
modules/meson.build file.
Then, open the examplemodule.cpp
file (or what it was renamed to) and scroll to the bottom.
You will find these lines, implementing virtual methods of a ModuleInfo
class:
QString ExampleCppModuleInfo::id() const
{
return QStringLiteral("example-cpp");
}
QString ExampleCppModuleInfo::name() const
{
return QStringLiteral("C++ Module Example");
}
QString ExampleCppModuleInfo::description() const
{
return QStringLiteral("Most basic module, a starting place to develop a new C++ module.");
}
bool ExampleCppModuleInfo::devel() const
{
return true;
}
AbstractModule *ExampleCppModuleInfo::createModule(QObject *parent)
{
return new ExampleCppModule(parent);
}
By removing the ExampleCppModuleInfo::devel()
function, you can declare your module as proper module and not just development-aid.
Adjust all other values accordingly as well to give your module a nice, human-readable name and description.
The module icon is automatically picked up from an SVG file of the same name as your module in the module directory.
Alternatively, it can also be generated by C++ code.
The most important method of a ModuleInfo
is the createModule(QObject *parent)
method.
It is invoked when your module is added to a workspace and creates a new instance of your own module class that inherits
from ÀbstractModule
, in this case ExampleCppModule
defined above.
4. Write your code
You will find these lines in the constructor of your new module class:
m_frameIn = registerInputPort<Frame>(QStringLiteral("frames-in"), QStringLiteral("Frames In"));
m_frameOut = registerOutputPort<Frame>(QStringLiteral("frames-out"), QStringLiteral("Frames Out"));
These register the ports that this module supports. The template argument is the type a port accepts/emits, followed by its unique name
and human-redable name as parameters. The register(In|Out)putPort
will return a refernce to the port that you can use later.
Refer to the AbstractModule API documentation for more information on the methods you can implement to add features to your module. Most usable API for modules can be found in the moduleapi.h header, and is documented there.
The example C++ module also has some inline comments, explaining the purpose of certain functions. If you get stuck while developing a module, do not hesitate to ask for help.
TODO: Add more explanations.
5. Test
Once you recompile Syntalos and run it, your module should automatically show up in the module selection dialog. Once your module addition is ready, we would be happy to merge it into the main Syntalos tree and release it with Syntalos for ease of future use and to make maintenance of new modules easier.