# Codeware callbacks

Unlike [How to create a hook](/redscript/language/intro/how-to-create-a-hook.md), a callback can be be registered **through Codeware** **callback system**.&#x20;

{% hint style="info" %}
This method depends on Codeware. You can't use it alone.
{% endhint %}

## Example

```swift
class ExampleService extends ScriptableService {
  // instance variables
  private let callbackSystem: wref<CallbackSystem>;
  private let found: Bool = false;
  
  // This function is always executed
  private func OnLoad() {
    this.callbackSystem = GameInstance.GetCallbackSystem();
    this.callbackSystem.RegisterCallback(n"Input/Key", this, n"OnKeyInput", true);
    
    LogChannel(n"DEBUG", s"ExampleService loaded");
  } 
  
  // Will always listen, but only react once
  private cb func OnKeyInput(event: ref<KeyInputEvent>) {
    if this.found {
      return;
    }    
    LogChannel(n"DEBUG", s"You pressed your key, going dormant now: \(event.GetAction()) \(event.GetKey())");
    this.found = true;
  }

}
```

Let's go over it bit by bit:

### OnLoad

This function is always executed, because our `ExampleService` inherits from `ScriptableService`.

* It sets the instance variable `callbackSystem`, making sure that we don't have to get it each time we want to use it.
* It **binds to the `Input/Key` callback**, telling Codeware to run the function `OnKeyInput` each time
* It prints to log

### OnKeyInput

{% hint style="info" %}
You can see that this function is a callback from the `cb func` rather than just `func`&#x20;
{% endhint %}

This function will be executed every time the registered event (`Input/Key`) is triggered.

Since we are checking our internal variable `found` before running any logic, this will only become active once.

## Unregistering callbacks

Once you're done with your logic, you can unregister your callback again.

{% hint style="danger" %}
As of **v0.5.19** (Mar 31 2024), unregistering `Input/Key` will crash the game (link to [github issue](https://github.com/jac3km4/redscript/issues/104)). Unregistering other kinds of callback works, though.
{% endhint %}

```swift
private cb func OnKeyInput(event: ref<KeyInputEvent>) {
  LogChannel(n"DEBUG", s"Input: \(event.GetAction()) \(event.GetKey())");
  this.callbackSystem.UnregisterCallback(n"Input/Key", this, n"OnKeyInput");
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://wiki.redmodding.org/redscript/references-and-examples/codeware-callbacks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
