Companion Types
A companion is any type that is declared in C# that is bound to your template
, typography
, function
or decorator
declaration. The purpose of a companion is to provide a generic way to integrate C# code with a template.
A type is valid as a companion as long as it is public and defines a parameterless constructor or is a struct.
// C# type somewhere in your project
public struct SomeCompanion {
public int hitPoints;
public string currentLevelName;
public void ReloadWeapon() {
// assume this does work in your game
}
}
// ... some template file ...
// : typeName syntax declares a companion type binding for this template
// there can only be 1 companion per template. When declaring a companion type,
// a new built-in variable becomes available in the template: $companion.
// this refers to the companion instance for this template. From this reference
// you can use any public field, method, property, or event that the type exposes.
template ThingWithCompanion : SomeCompanion {
render {
Text($"Current Level is {$companion.currentLevelName}")
HealthBar($companion.hitPoints);
// you can call methods exposed on the companion instance
Button("Reload", mouse:click => $companion.ReloadWeapon());
}
}
Mapping values from companions
You can map values from a companion in the same way you could map them from state
.
// c# file
public class Inventory {
public int selectedItemIndex;
public string[] GetItemNames() { ... }
public string GetEquippedItemName(int itemIndex) { ... }
}
// template file
template InventoryUI : Inventory {
// we alias the selectedItemIndex parameter from the selectedItemIndex field on the companion
required int selectedItemIndex from $companion.selectedItemIndex;
// when mapping from a companion, if the companion's field name matches the template's declared name
// then you can omit the field name. This line is the same as the one above but shorter.
required int selectedItemIndex from $companion;
method string[] GetItemNames() from $companion; // when mapping a method, the signatures must match exactly.
// you can pick a different name for the template value if you specify the source explicitly;
method string GetItemName(int itemIndex) from $companion.GetEquippedItemName;
}
Mapping event and life cycle handlers from companions
An event or life cycle can also be mapped from the companion. As long as the signatures match between the event you are mapping and the method on the companion instance, the mapping is valid.
There is also a shorthand for mapping both input event names and life cycle handlers. For lifecycle events the return type is ignored and can be anything as long as your mapping method defines no parameters.
The name mapping table for lifecycle events is below:
Event Name | Method Mapping Name |
---|---|
before:create | OnBeforeCreate |
after:create | OnAfterCreate |
before:enable | OnBeforeEnable |
after:enable | OnAfterEnable |
before:update | OnBeforeUpdate |
after:update | OnAfterUpdate |
before:input | OnBeforeInput |
after:input | OnAfterInput |
before:finish | OnBeforeFinish |
after:finish | OnAfterFinish |
before:disable | OnBeforeDisable |
after:disable | OnAfterDisable |
before:destroy | OnBeforeDestroy |
after:destroy | OnAfterDestroy |
There is a similar mapping table for input event names, however with the added caveat that signature of your method must also match
Event Name | Method Mapping Name |
---|---|
mouse:enter | OnMouseEnter(MouseInputEvent) |
mouse:exit | OnMouseExit(MouseInputEvent) |
mouse:up | OnMouseUp(MouseInputEvent) |
mouse:down | OnMouseDown(MouseInputEvent) |
mouse:heldDown | OnMouseHeldDown(MouseInputEvent) |
mouse:move | OnMouseMove(MouseInputEvent) |
mouse:hover | OnMouseHover(MouseInputEvent) |
mouse:context | OnMouseContext(MouseInputEvent) |
mouse:scroll | OnMouseScroll(MouseInputEvent) |
mouse:click | OnMouseClick(MouseInputEvent) |
mouse:update | OnMouseUpdate(MouseInputEvent) |
Event Name | Mapping Method Name |
---|---|
key:down | OnKeyDown(KeyboardInputEvent) |
key:heldDown | OnKeyHeldDown(KeyboardInputEvent) |
key:up | OnKeyUp(KeyboardInputEvent) |
Event Name | Mapping Method Name |
---|---|
focus:gain | OnFocusGained(FocusChangeEvent) |
focus:lost | OnFocusLost(FocusChangeEvent) |
Drag create is a special snowflake because it accepts a MouseInputEvent
and expects to return an instance of DragEvent
.
All other drag handlers conform to the same signature requirements.
Event Name | Mapping Method Name | Description |
---|---|---|
drag:create | DragEvent OnDragCreate(MouseInputEvent)) | Fires when a drag could begin. Returning null will not start a drag. Returning any other subclass of DragEvent will being a drag. |
drag:move<T> | OnDragMove(DragEvent) | Fires when a drag of type T moves across this element |
drag:hover<T> | OnDragHover(DragEvent) | Fires when a drag of type T hovers over this element |
drag:update<T> | OnDragUpdate(DragEvent) | Fires when a drag of type T moves or hovers over this element |
drag:enter<T> | OnDragEnter(DragEvent) | Fires when a drag of type T enters this element |
drag:exit<T> | OnDragExit(DragEvent) | Fires when a drag of type T exits this element |
drag:drop<T> | OnDragDrop(DragEvent) | Fires when a drop event of type T occurs on this element |
drag:cancel<T> | OnDragCancel(DragEvent) | Fires when a drag event of type T is canceled on this element |