-
Notifications
You must be signed in to change notification settings - Fork 6
create a template event handler
Tarsier event handlers are template classes with the following parameters:
- the input type(s)
- the output type(s) (only the ones different from the input types)
- inner function(s) type(s) (generally, delegates for output objects construction)
- output type(s) handler(s)
As an example, the stitch event handler turns a stream of threshold crossings (input type) into a stream of events (output type). It requires a function to create an event from a threshold crossing and a time delta (inner function), and a function to be called when an event is produced (output type handler).
The class requires a constructor, which must take all the delegates and event handlers as parameters. The use of std::forward
makes it possible to use any kind of callable element (function, lambda function, callable class...) as parameter.
std::forward
is only required for template parameters types.
Every Tarsier class must overload the operator ()
for each input type. Moreover, it is a good practice to explicitly declare the copy and move constructors of the class.
There are no .cpp
files associated with the Tarsier headers: all the classes' elements are defined in one file.
In order to use lambda functions as callbacks, the template class parameters must be deduced from the constructor arguments. Such a deduction is not allowed by the C++ standard (until C++17). To support earlier C++ versions, each Tarsier handler class is associated with a make function, which handles template parameters deduction. The make function must have the same parameters as the constructor, and must forward the template-dependent arguments using std::forward
.
Writing the make function implies a lot of code duplication. To ease the process, Tarsier provides a template generator. To use it, one must first create a configuration.json file which describes the event handler template parameters and the constructor parameters. As an example, a configuration file to create a template for the tarsier::average_position
handler would contain:
{
"filename": "average_position.hpp",
"name": "average_position",
"description": [
"average_position calculates the average position of the given events.",
"An exponential event-wise decay is used as weight."
],
"template_parameters": [
{"name": "Event", "type": "typename"},
{"name": "Position", "type": "typename"},
{"name": "EventToPosition", "type": "typename"},
{"name": "HandlePosition", "type": "typename"}
],
"parameters": [
{"name": "x", "type": "float", "store": "mutable"},
{"name": "y", "type": "float", "store": "mutable"},
{"name": "inertia", "type": "float", "store": "constant"},
{"name": "event_to_position", "type": "EventToPosition", "store": "forward"},
{"name": "handle_position", "type": "HandlePosition", "store": "forward"}
],
"input": {"name": "event", "type": "Event"}
}
The configuration file must contain a single JSON object with the following fields:
-
filename
(string) is the path to the generated template (absolute or relative to the current working directory). -
name
(string) is the event handler's class name (by convention, it should be a verb or action). -
description
(array of strings) contains the comment lines preceding the class definition. -
template_parameters
(array of objects) list the class's template parameters. Each object has the following fields:-
name
(string) is the parameter name (by convention, it should use CamelCase). -
type
(string) is the parameter type (generallytypename
or a union / integer type).
-
-
parameters
(array of objects) list the constructor's parameters. Each object has the following fields:-
name
(string) is the parameter name (by convention, it should use snake_case). -
type
(string) is the parameter type. -
store
(string) determines if and how the parameter is bound to a class member. It must be eitherno
,mutable
,constant
orforward
.-
no
does not create an associated class member. -
mutable
creates a class member with the same type. -
constant
creates a class member with the same type and theconst
modifier. -
forward
creates a class member with the same type. The parameter is forwarded during initialization rather than copied.
-
-
-
input
(object) configures the argument for the call function. It has the following fields:-
name
is the parameter name (generally,event
). -
type
is the parameter type (generally,Event
).
-
Template generation is done by running from the tarsier directory:
premake4 --configuration='/path/to/configuration.json' template
If the --configuration
option is omitted, the file configuration.json (relative to the current working directory) is used.
The generated template must be formatted using clang-format -i /path/to/handle_event.hpp
.