Extension

Documentation for each extension module in the main NUbots codebase
Updated 23 Mar 2026

Director

Description

See the Director NUbook page for details on how to use the Director in modules.

This module triggers on BehaviourTasks from the Behaviour extension and turns them into a DirectorTask TaskPack for the run_task_pack function. This function:

  • Checks if the Provider is active, otherwise it cannot make subtasks
  • Handles Done tasks
  • Schedules any Wait tasks
  • Clears any null tasks, clears root tasks
  • Check priority changes and test challenges in the tree
  • Removes tasks that were in the last task pack for this Provider, but are now gone
  • Handle optional tasks
  • Update subtasks for the Provider

Usage

The easiest way to use the Director in a module is to generate the module using the --director flag:

./b module generate <module_name> --director

Check the Director NUbook page for information on functionality.

Dependencies

  • The Behaviour extension

FileWatcher

Description

FileWatcher provides the on<extension::FileWatch>(path, events) DSL so modules can react to file-system changes.

It supports watching:

  • A specific file
  • A directory
  • A glob pattern

The extension tracks matching files and runs your reaction when files are discovered, modified, renamed/created, or deleted (depending on the event mask you subscribe to).

Usage

Install module::extension::FileWatcher in your powerplant, then use the extension::FileWatch DSL in any reactor.

Basic file watch

##include "extension/FileWatch.hpp"
on<extension::FileWatch>("config/MyModule.yaml", extension::FileWatch::CHANGED)
.then([](const extension::FileWatch& watch) {
// watch.path is the absolute path to the file that changed
// watch.events is one of extension::FileWatch::Event
});

Watch a directory

Passing a directory path watches all files below that directory recursively.

on<extension::FileWatch>("config", extension::FileWatch::CHANGED)
.then([](const extension::FileWatch& watch) {
// Triggered when a matching file in config/ changes
});

Watch a glob

Passing a non-existent path is treated as a glob pattern. Examples:

  • config/*.yaml
  • module/**/README.md (single /**/ recursive segment supported)

The glob is translated internally to an ECMAScript regex.

Event mask

Available events:

  • extension::FileWatch::NO_OP: Initial discovery event for files already present when the watch is added
  • extension::FileWatch::RENAMED: File created or renamed into a watched location
  • extension::FileWatch::CHANGED: File contents changed
  • extension::FileWatch::DELETED: File deleted or renamed out of a watched location

Use bitwise OR to subscribe to multiple event types.

on<extension::FileWatch>(
"config/**/*.yaml",
extension::FileWatch::CHANGED | extension::FileWatch::RENAMED | extension::FileWatch::DELETED)
.then([](const extension::FileWatch& watch) {
// Handle create/rename, modify, and delete events
});

Startup synchronisation

FileWatcher emits extension::FileWatcherReady once its libuv loop is initialised. If you need to delay file operations until watches are active, trigger your startup logic from this event.

on<Trigger<extension::FileWatcherReady>>().then([this] {
// Safe place to kick off logic that depends on active file watches
});

Emits

  • extension::FileWatcherReady: emitted once when the watcher is initialised and ready

Note: extension::FileWatch is provided via the NUClear DSL/thread store and invokes matching reactions directly. It is not broadcast as a normal global message type.

Dependencies

  • libuv for cross-platform file-system notifications
Modules
Actuation
Modules
Input
NUbots acknowledges the traditional custodians of the lands within our footprint areas: Awabakal, Darkinjung, Biripai, Worimi, Wonnarua, and Eora Nations. We acknowledge that our laboratory is situated on unceded Pambalong land. We pay respect to the wisdom of our Elders past and present.
Copyright © 2026 NUbots - CC-BY-4.0
Deploys by Netlify