Event-Action Mapping
The core of fsmapper's configuration lies in defining actions that are triggered in response to generated events. This section explains how to register these event-action mappings within fsmapper and the crucial concepts associated with it.
Event
Events are identified by unique 64-bit integers assigned to distinguish their types, referred to as Event IDs.
Additionally, each Event ID is given a name in string format for easier user recognition; however, there's no constraint for these names to be unique.
While fsmapper sometimes automatically assigns Event IDs, users can also explicitly designate Event IDs within the system through Lua scripts. To assign Event IDs via scripts, the mapper.register_event()
function is utilized.
local my_event = mapper.register_event('My Event')
When events occur from input devices like flight sticks or from event sources like MSFS, they get stored in fsmapper's event queue. fsmapper calls corresponding actions in the order these events are stored in the queue.
Events stored in the event queue not only retain their Event IDs but also hold values specified by the event source, which are then passed to actions. These values are referred to as Event Values. The type of Event Values varies depending on the type of event. For example, an event triggered by manipulation of the throttle device sets a numerical value representing the throttle position as its Event Value. In contrast, events triggered when switching aircraft within the flight simulator have an Event Value in a Lua table containing simulator software specifics and the name of the aircraft.
Apart from events that occur asynchronously from each event source, it's also possible to explicitly generate events from Lua scripts. For this purpose, mapper.raise_event()
has been made available.
mapper.raise_event(my_event, 'this is a associated value for a event')
Action
Actions are commonly defined as Lua functions, but it's also possible to utilize special objects provided by fsmapper known as native-actions.
When using Lua functions as actions, the Event ID is passed as the first argument and the Event Value as the second.
function ACTION(event_id, event_value)
Native-actions are unique objects that behave as actions compiled into native code. When fsmapper calls a native-action, it can do so directly without going through the Lua interpreter, reducing system load. Additionally, when events and actions are displayed in the message console, Native-actions provide clearer information than Lua function.
Here's an example defining the same action using both a Lua function and a native-action.
-- Note that variable axis is binded with a vJoyUnit object
local action_lua = function (event_id, event_value)
axis:set_value(event_value)
end
local action_native = axis:value_setter()
Below is a list of functions or methods that provide native-action
Device:sender()
Canvas:value_setter()
Canvas:refresher()
vJoyUnit:value_setter()
Keystroke:synthesize()
- filter library functions
msfs.event_sender()
msfs.input_event_executer()
msfs.mfwasm.rpn_executer()
dcs.clickable_action_performer()
dcs.chunk_executer()
Event-Action mapping definition
When registering the correspondence between events and actions in fsmapper,
it's instructed using a Lua table object known as the Event-Action Mapping definition.
This mapping is an associative array that holds the Event ID under the key event
and the action under the key action
.
To actually register the correspondence between events and actions in fsmapper, you pass an array of Event-Action Mapping definition tables.
mapper.set_primary_mappings{
{event=evid1, action=action_func1},
{event=evid2, action=action_func2},
{event=evid3, action=action_func3},
{event=evid4, action=action_func4},
}
Cascading Event-Action mappings
Event-Action mappings are managed across multiple hierarchies. It allows switching mapping definitions dynamically or overriding behaviors with definitions from higher-priority hierarchies.
Here are the levels where Event-Action mappings can be registered and how actions are selected in case multiple actions are registered for the same Event ID with different priorities.
Level | Priority | Remarks |
---|---|---|
Primary Mappings | 4 | |
Secondary Mappings | 3 | |
Mappings associated with a Viewport | 2 | Enabled only when the viewport is displayed |
Mappings associated with a View | 1 | Enabled only when the viewport is displayed and the view is the current view in the viewport |
Here are the functions to configure and modify Event-Action mappings.
Level | Functions to change mappings |
---|---|
Primary Mappings | mapper.set_primary_mappings() mapper.add_primary_mappings() |
Secondary Mappings | mapper.set_secondary_mappings() mapper.add_secondary_mappings() |
Mappings associated with a Viewport | Viewport:set_mappings() Viewport:add_mappings() |
Mappings associated with a View | Viewport:register_view() |
Looking at the above functions, you might have wondered, "There's set and add, but no clear?"
To clear an Event-Action mappings, setting an empty array achieves the same result, so a separate 'clear' function wasn't provided.
If you wish to clear it, do as followings.
mapper.set_primary_mappings({})
Filter
The filter library enables processing events, performing conditional branching, and similar operations through cascaded connections of native-actions. By combining the native-actions provided by the filter library with other native-actions, complex operations can be efficiently executed as native code without the intervention of the Lua interpreter.
Below is an example of mapping throttle input from a physical device to a vJoy device. This setup is designed to accommodate softwares where the afterburner On/Off is assigned to key or button inputs rather than the throttle position. It maps the physical throttle's afterburner detent position to 100% on the vJoy throttle while also triggering button operations for the afterburner On/Off based on the physical throttle's position.
-- throttle.x.change: Event ID of physical throttle
-- v_throttle: vJoyUnit object for the throttle axis of vJoy device
-- v_ab: vJoyUnit object for the afterburner button of vJoy device
set_primary_mappings{
{
event = throttle.x.change,
action = filter.duplicator{
filter.lerp(
v_throttle.value_setter(),
{-50000, -50000},
{-30000, -50000},
{50000, 50000},
),
filter.branch{
{condition="falled", value=-44000, action=v_ab:value_setter(true)},
{condition="exceeded", value=-39000, action=v_ab:value_setter(false)}
}
}
}
}
System Events
Most Event IDs are dynamically allocated during script processing, but some events have their Event IDs reserved by the fsmapper system even before script execution.
These events are referred to as System Events and can be referenced from the mapper.events
table.
Below is a list of currently defined system events.
Key | Description |
---|---|
change_aircraft | The event that occurs when fsmapper connects to the flight simulator or the connection is closed, or when the selected aircraft changes. The event value for this event is a associative array table that holds the simulator type and aircraft name. For details, refer to the SimAircraft Table. |