Back to logs
2026-03-05 enginemapping-core

Profile validation and layer stack

A MapXr profile is a JSON file that users write by hand. That means the engine needs to catch mistakes clearly and early. Validation runs at load time, not at runtime when a tap fires the wrong action. This session focused on building out that validation layer and the LayerStack that manages runtime layer switching.

Profile validation

Validation runs immediately after deserialization, before any profile is made active. The rules enforced include:

  • Duplicate triggers: the same finger combination bound to two actions in the same layer is always a mistake
  • Missing layer references: a push_layer action that names a layer not defined in the profile
  • Empty layers: a layer with no mappings is valid but suspicious; flagged as a warning
  • Hold modifier constraints: the modifier key in a hold_modifier action can't also be a trigger key in the same layer
  • Default layer must exist: the default_layer field must name a layer actually defined in the profile

Each rule has at least one passing test and one failing test in the unit suite, as required by the project's testing rules.

LayerStack

The LayerStack maintains the ordered list of active layers at runtime. Trigger resolution walks the stack from top to bottom. The first layer with a matching mapping wins; lower layers act as fallbacks.

Three operations are supported:

push_layer(name)
Adds a layer on top of the current stack. The previous layers remain as fallbacks.
pop_layer()
Removes the topmost layer. Has no effect if only the default layer remains.
activate_layer(name)
Replaces the entire stack with a single layer. Used for switching contexts completely.