Skip to content

create a template event handler

Alexandre Marcireau edited this page Jun 1, 2018 · 8 revisions
  1. the handler class
  2. the make function
  3. generate a template

the handler class

Tarsier event handlers are template classes with the following parameters:

  1. the input type(s)
  2. the output type(s) (only the ones different from the input types)
  3. inner function(s) type(s) (generally, delegates for output objects construction)
  4. 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.

the make function

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.

generate a template

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 (generally typename 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 either no, mutable, constant or forward.
      • 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 the const 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.

Clone this wiki locally