Skip to content

08 ‐ Threading

Marco Klein edited this page Aug 23, 2024 · 1 revision

Dispatcher

When you use the Task object together with async and await keywords of C#, you are likely to run into Thread permission problems. Threads, that are not the main/UI Thread of Godot are not allowed to modify UI Elements.

The Dispatcher service can help you "jumping back" to the main thread after resolving data or resources from another non-main thread.

Enabling the dispatcher

The dispatcher does not come pre-initialized with the default set of services provided by GoDough. To activate it, run:

using GoDough.Threading;

// Inside your AppHost.ConfigureServices Method:
services
  .AddThreadingUtilities();

Using the dispatcher

using Godot;
using System.Collections.Generic;
using GoDough.Runtime;
using GoDough.Visuals;
using GoDough.Visuals.Extensions;
using System;
using System.Threading.Tasks;

namespace Game.Client.Services {
  public class ModelRegistry {
    private readonly IGodotApi _godotApi;
    private readonly GoDough.Threading.Dispatcher _dispatcher;

    public ModelRegistry(
      IGodotApi godotApi,
      GoDough.Threading.Dispatcher dispatcher) =>
      (_dispatcher, _godotApi) = (dispatcher, godotApi);

    public async Task<Node3D> LoadModelAsync(String modelId, bool forceReload = false) {
      var scene = await this._godotApi.LoadSceneAsync("res://scenes/my-scene.tscn");
      var node = await this._dispatcher.Invoke(() => scene.Instantiate<Node3D>());

      return node;
    }
  }
}