# Modifiers

Modifiers allow you to change the values before they are set or retrieved by requesters. Modifiers provide flexibility in manipulating the bound values. Like converters, modifiers are relatively simple to implement and extend.

{% hint style="danger" %}
The modifiers must not change output value type, at most have a value which is of an inherited type relative to input value type.
{% endhint %}

<figure><img src="https://2360058278-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3rw9jjjjlPycieM3U3MU%2Fuploads%2FRwLwuaKCcMo1US3ZTrBe%2FModifiers_Example.png?alt=media&#x26;token=2fc50588-32a6-46c1-9c5b-0607712730f0" alt=""><figcaption><p>Inspector VIew of Modifiers</p></figcaption></figure>

To add a new modifier, it is sufficient to implement the `IReadWriteModifier<T>` interface:

```csharp
public class MyModifier : IReadWriteModifier<bool>
{
    public string Id => "Invert";
    public string ShortDataDescription => "[Invert X]";
    public BindMode ModifyMode => BindMode.ReadWrite;
    public object Modify(BindMode modifyMode, object value) => !((bool)value); // This is the fallback method
    public bool ModifyRead(in bool value) => !value; // Used when reading a value from source
    public bool ModifyWrite(in bool value) => !value; // Used when writing a value to source
}
```

The `IReadWriteModifier<T>` interface implements both `IReadModifier<T>` and `IWriteModifier<T>`. Implement one of them if you need only one-way modifier.

<figure><img src="https://2360058278-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3rw9jjjjlPycieM3U3MU%2Fuploads%2FEFO02uJBt9NxuVestpjk%2FBS_Modifiers_Interfaces.png?alt=media&#x26;token=7e24209c-3a07-46b2-b6a8-fed5254fa2af" alt="" width="563"><figcaption><p>Modifiers interfaces</p></figcaption></figure>

`ISmartModifier` gets the bind field it is currently attached to, while its generic version gets as well the possibility to force a value into the pipeline even when there was no request for it.

`IObjectModifier` is specifically designed to handle non-value types. It is recomended to implement this interface (or its generic version) for modifiers which intend to modify instance values and their inherited types.

The system will automatically pick up the new modifier and make it available in **Bind Menu**. To avoid auto registration of the new modifier, add `[HideMember]` attribute over the class.

{% hint style="info" %}
Sometimes the system will need another recompilation round to successfully register the new modifier.
{% endhint %}

{% hint style="warning" %}
The modifier must have a parameterless constructor.
{% endhint %}

For new numeric modifiers, we suggest extending `NumericModifier` for simplicity. It only requires to implement a simple `Modify(double)` method and optionally another `Modify(long)` method to cover all numeric modification cases.

Most of the modifiers have their code exposed, this is to allow users to change them at their heart's content.
