|
|
(33 intermediate revisions by one user not shown) |
Line 1: |
Line 1: |
| + | __NOTOC__ |
| =Welcome= | | =Welcome= |
| This part of the Wiki is dedicated to developers who would like to implement their own plug-ins for AnyWave.<br /> | | This part of the Wiki is dedicated to developers who would like to implement their own plug-ins for AnyWave.<br /> |
− | AnyWave is written using the Qt Framework and the Qt plugin mechanism, so a good knowledge of the Qt Framework is required.
| + | {| style="text-align: center; margin: auto;" |
− | | + | |+ Quick Navigation |
− | =The SDK=
| + | |- |
− | If you have installed AnyWave on your system, you will find all the required files in the installation folder.<br />
| + | | [[File:Menu_matlab_plugin.png|400px|link=AnyWave:MATLAB_Plugin|'''Write a MATLAB Plugin''']] || [[File:Menu_cpp_plugin.png|400px|link=AnyWave:Cpp_Plugin|'''Write a c++ Plugin''']] |
− | ==Linux==
| + | |- |
− | Build from sources following the instructions on our [https://gitlab.thevirtualbrain.org/anywave Gitlab].<br />
| + | | [[File:Menu_matlab_batch.png|400px|link=AnyWave:Plugin_Batch|'''Make your plugin batchable''']] || [[File:Menu_matlab_batch_gui_compatible.png|400px|link=AnyWave:MATLAB_Batch_GUI|'''Make your plugin compatible with the batch GUI of AnyWave''']] |
− | Considering the default installation path, the requires folders to build a plugin are:<br />
| + | |} |
− | * '''/usr/local/AnyWave/include'''
| + | |
− | * '''/usr/local/AnyWave/lib'''
| + | |
− | ==Mac OS==
| + | |
− | The required folders to build a plugin are:<br />
| + | |
− | * '''/Applications/AnyWave.app/Contents/include'''
| + | |
− | * '''/Applications/AnyWave.app/Contents/dylibs'''
| + | |
− | | + | |
− | ==Windows==
| + | |
− | The required folders to build a plugin are:<br />
| + | |
− | * '''AnyWave\include'''
| + | |
− | * '''AnyWave\lib'''
| + | |
− | | + | |
− | =Basic requirements to build a plugin=
| + | |
− | We strongly recommend QtCreator as the tool to use which is available along with the Qt open source package you will need to build a plugin. <br/>
| + | |
− | Download Qt and Qt Creator here: [https://www.qt.io/download Get Qt and Qt Creator] <br/>
| + | |
− | '''Note about Windows:'''<br/>
| + | |
− | The Windows version of AnyWave is built with Visual Studio 2017 though, so, if you plan to build a plugin for Windows, consider using Visual Studio along with the Qt VS Addin.<br/>
| + | |
− | Technically speaking you can build a plugin with QtCreator using another compiler like '''gcc''' or '''clang'''.<br/>
| + | |
− | You will need to put the runtime DLL files of the chosen compiler into the AnyWave folder after you copied the plugin into the Plugins subdirectory.
| + | |
− | | + | |
− | ==Prepare a project== | + | |
− | Every Qt project starts with a .pro file which is the format used by qmake, the tool for building Qt projects.<br/>
| + | |
− | Building an AnyWave plugin requires that the paths to AnyWave headers and libraries must be set.<br/>
| + | |
− | A good practice is to set an environment variable called '''AW_ROOT''' that points to the root folder of your AnyWave installation.<br />
| + | |
− | Example:<br/>
| + | |
− | <syntaxhighlight lang="text">
| + | |
− | CONFIG += release warn_off c++11 plugin
| + | |
− | ROOT=$$(AW_ROOT)
| + | |
− | # on Mac OS the required folders are located inside the application bundle.
| + | |
− | macx{
| + | |
− | ROOT = $$(AW_ROOT)/Contents
| + | |
− | }
| + | |
− | INCLUDEPATH += $$ROOT/include
| + | |
− | LIBS += -L$$ROOT/lib
| + | |
− | DESTDIR = $$ROOT/Plugins
| + | |
− | | + | |
− | # Mac OS application has a separated folder for Plugins.
| + | |
− | macx {
| + | |
− | DESTDIR = $$ROOT/../../Anywave_Plugins
| + | |
− | # shared libs on Mac are located in the application bundle.
| + | |
− | LIBS += -F/Library/Frameworks -L$$ROOT/dylibs
| + | |
− | }
| + | |
− | </syntaxhighlight>
| + | |
− | You may use this file as .pri that you could include in every project you plan to develop:<br/>
| + | |
− | [http://meg.univ-amu.fr/AnyWave/sdk/plugins.pri Get plugins.pri file]
| + | |
− | | + | |
− | =Build a reader plugin=
| + | |
− | As a tutorial, we are going to develop here a reader plugin called "My Reader".<br/>
| + | |
− | Each Qt project starts with a .pro file which qmake use to compile and link a Qt project.<br/>
| + | |
− | A Reader plugin is a Qt shared library that should be placed in the Plugins directory of AnyWave.<br/>
| + | |
− | ==Step 1: Prepare the folder==
| + | |
− | Let's create a folder in which we will put the files required to build our plugin:<br/>
| + | |
− | <syntaxhighlight lang="bash">
| + | |
− | mkdir MyReader && cd MyReader
| + | |
− | </syntaxhighlight>
| + | |
− | | + | |
− | ==Step 2: create the project file==
| + | |
− | Now we can create the .pro file for our project:<br>
| + | |
− | <syntaxhighlight lang="text">
| + | |
− | # We assume that the plugins.pri file is also in our plugin directory.
| + | |
− | include(plugins.pri)
| + | |
− | # The name of our plugin
| + | |
− | TARGET=MyReader
| + | |
− | # Our project must be a library
| + | |
− | TEMPLATE = lib
| + | |
− | # Just to avoid unwanted libs, Qt GUI is not usefull for a reader plugin (no widgets/no graphics items).
| + | |
− | QT -= gui
| + | |
− | | + | |
− | # We must link with some AnyWave libs
| + | |
− | # AwRW is the AnyWave ReadWrite lib.
| + | |
− | unix{
| + | |
− | LIBS += -lAwRW
| + | |
− | }
| + | |
− | win32{
| + | |
− | LIBS += AwReadWriteLib.lib
| + | |
− | }
| + | |
− | | + | |
− | HEADERS += MyReader.h
| + | |
− | SOURCES += MyReader.cpp
| + | |
− | </syntaxhighlight>
| + | |
− | | + | |
− | ==Step 3: Let's code==
| + | |
− | The header file:<br/>
| + | |
− | <syntaxhighlight lang="cpp">
| + | |
− | #pragma once
| + | |
− | #include <AwFileIO.h>
| + | |
− | | + | |
− | class Q_DECL_EXPORT MyReader : public AwFileIO
| + | |
− | {
| + | |
− | Q_OBJECT
| + | |
− | Q_INTERFACES(AwFileIO)
| + | |
− | public:
| + | |
− | explicit MyReader(const QString& fileName);
| + | |
− | ~MyReader();
| + | |
− | | + | |
− | qint64 readDataFromChannels(float start, float duration, QList<AwChannel *>& channels) override;
| + | |
− | AwFileIO::FileStatus openFile(const QString &path) override;
| + | |
− | AwFileIO::FileStatus canRead(const QString &path) override;
| + | |
− | void cleanUpAndClose() override;
| + | |
− | };
| + | |
− | | + | |
− | class Q_DECL_EXPORT MyReaderPlugin : public AwFileIOPlugin
| + | |
− | {
| + | |
− | Q_OBJECT
| + | |
− | Q_INTERFACES(AwFileIOPlugin)
| + | |
− | Q_PLUGIN_METADATA(IID AwFileIOInterfacePlugin_IID)
| + | |
− | public:
| + | |
− | MyReaderPlugin();
| + | |
− | MyReader *newInstance(const QString& fileName) { return new MyReader(fileName); }
| + | |
− | };
| + | |
− | | + | |
− | </syntaxhighlight>
| + | |
− | The header file declares two classes: One is the reader object itself and the other one is the plugin object.<br/>
| + | |
− | The methods declared with the override keyword MUST be implemented otherwise the compiler will complain and your plugin won't be a valid AnyWave plugin.<br/>
| + | |
− | ===constructor/destructor (init our plugin)===
| + | |
− | Let's have a closer look at methods we have to implement:<br/>
| + | |
− | <syntaxhighlight lang="cpp">
| + | |
− | explicit MyReader(const QString& fileName);
| + | |
− | ~MyReader();
| + | |
− | </syntaxhighlight>
| + | |
− | The constructor/destructor methods. This is where you initialise the member variables and handle the destruction by releasing allocated memory and open files.<br/>
| + | |
− | Let's see the code for our constructor:<br/>
| + | |
− | <syntaxhighlight lang="cpp">
| + | |
− | #include "MyReader.h"
| + | |
− | | + | |
− | // constructor for reader object
| + | |
− | MyReader::MyReader(const QString& fileName) : AwFileIO(fileName)
| + | |
− | {
| + | |
− | // do some inits here.
| + | |
− | }
| + | |
− | | + | |
− | // constructor of Plugin object
| + | |
− | // Here we will define the name of our Plugin and it's properties/flags for AnyWave
| + | |
− | MyReaderPlugin::MyReaderPlugin() : AwFileIOPlugin()
| + | |
− | {
| + | |
− | // define the name (must be unique in AnyWave)
| + | |
− | name = QString("MyReader Plugin");
| + | |
− | // short description of what the plugin does.
| + | |
− | description = QString("Read My Format");
| + | |
− | // info about manufacturer/author
| + | |
− | manufacturer = QString("Myself");
| + | |
− | // version string
| + | |
− | version = QString("1.0");
| + | |
− | // the file extensions the reader can open.
| + | |
− | fileExtensions = { ".myr" };
| + | |
− | // Flags to define the behavior in AnyWave
| + | |
− | m_flags = Aw::HasExtension|Aw::CanRead; // Here we tell AnyWave that the plugin handle file extension (mostly the case)
| + | |
− | // and we also specify CanRead flag to tell AnyWave that this is a READER plugin.
| + | |
− | }
| + | |
− | </syntaxhighlight>
| + | |
− | | + | |
− | =Build a signal processing plug-in=
| + | |
− | ==[[AnyWave:WriteMatlabScripted|How to write a MATLAB plug-in]]==
| + | |
− | ===[[AnyWave:MATLAB_API|MATLAB API]]===
| + | |
− | | + | |
− | ==[[AnyWave:WritePythonScripted|How to write a Python Scripted plug-in]]==
| + | |
This part of the Wiki is dedicated to developers who would like to implement their own plug-ins for AnyWave.