aboutsummaryrefslogtreecommitdiff
path: root/doc/APIdoc.md
blob: 5b69b5e680dbb83c409c8c7df22bd8e526a24ce1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# The API documentation of QMidiPlayer for plugin developers

*This manual is not yet complete. It's only a working draft for the always-changing plugin system in QMP.*
*Handle with care.*

# 0. Overview

Plugin for QMidiPlayer is a dynamically-loaded library that exports the symbol `qmpPluginGetInterface` and `qmpPluginGetAPIRev`.
Before starting developing your own plugin, make sure to have a look at the sample plugin in the "sample-plugin" folder.

# 1. "QMidiPlayer Plugin SDK"

SDK for developing QMidiPlayer plugins is merely the `qmpcorepublic.hpp` header found in the "include" directory in
the source tree. It includes classes used by QMidiPlayer's internal plugin infrastructure.

# 2. Basics for a working plugin

First of all, you should make your library distinct from other libraries that are not QMidiPlayer plugins. You can achive
it by exporting the symbols `qmpPluginGetInterface` and `qmpPluginGetAPIRev`. Specifically, what you should do is to add
the following snipplet to somewhere of your code:

```
extern "C"{
	EXPORTSYM qmpPluginIntf* qmpPluginGetInterface(qmpPluginAPI* api)
	//semicolon or implementation here.
	EXPORTSYM const char* qmpPluginGetAPIRev()
	{return QMP_PLUGIN_API_REV;}
}
```

The `EXPORTSYM` macro tells the compiler to export the following symbol. `qmpPluginIntf` is the abstract class which every
plugin class should derive from. The parameter api provides access to QMidiPlayer's plugin API, which should be stored
for future use. `qmpPluginGetAPIRev` helps the core to determine whether the plugin is compatible with the API it exports.

Next you should create your own plugin class which implements the abstract class `qmpPluginIntf`.

# 3. A peek into the class `qmpPluginIntf`

It has 6 public members: one default constructor, one default destructor and four methods:

- `void init()`  
  Called on start up if the plugin is loaded successfully and enabled.
- `void deinit()`  
  Called on shutdown if the plugin is enabled.
- `const char* pluginGetName()`  
  This function should return the display name of the plugin.
- `const char* pluginGetVersion()`  
  This function should return the version of the plugin, which will be shown in the plugin manager.

Your plugin is expected to register handlers (hooks) and functionalities when init() is called by the host,
and do clean-up jobs when deinit() is caled.

Currently plugins can register handlers for these functionalities:

- Visualization (via `(un)registerVisualizationIntf`)
- MIDI File Reader (via `(un)registerFileReader`)

...and can hooks into the following processes:

- Event reader, after an event is read or after the whole file reading process is completed
  (via `(un)registerEventReaderIntf` and `(un)registerFileReadFinishedHandlerIntf`)
- Event handler, when an event is going to be sent by the player (via `(un)registerEventHandlerIntf`)

Functionalities has their own interfaces you need to implement(`qmpVisualizationIntf` and `IMidiFileReader`, respectively),
while hooks uses the universal `IMidiCallBack` interface. Functionalities are discussed later.

When you register a hook, you provide the core with a instance of your class that implements the `IMidiCallBack` interface
and your `userdata` to be used when the core is calling the callback. When the callback is called, it will be fed with
proper `callerdata` generated by the core and the `userdata` you provided. Type of `callerdata` varies by hooks. Event
reader and handler hooks have `SEventCallBackData*` as their `callerdata` while file read finish hook doesn't provide
`callerdata` (`NULL`).

# 4. Functionalities
Plugins extend the hosts with extra functionalities. With hooks, handlers and the built-in core API, you can already do a
lot of hacking. If that cannot make you satisfied, QMidiPlayer have several vacancies that are expected to be implemented
by plugins.