class

Termisu::Event::Loop

Inherits Reference / Object

Central event loop multiplexer.

Manages multiple Event::Source instances and provides a unified output channel for all events. Handles lifecycle management and graceful shutdown.

Usage

loop = Termisu::Event::Loop.new

# Add event sources
loop.add_source(input_source)
loop.add_source(resize_source)
loop.add_source(timer_source)

# Start all sources
loop.start

# Receive events from unified channel
while event = loop.output.receive?
  case event
  when Termisu::Event::Key
    break if event.key.escape?
  when Termisu::Event::Tick
    # Handle animation frame
  end
end

# Stop all sources and cleanup
loop.stop

Thread Safety

The Event::Loop uses Atomic(Bool) for thread-safe state management. All public methods are safe to call from multiple fibers.

Shutdown Behavior

When stop is called:

  1. Running state is set to false (atomic)
  2. All sources are stopped
  3. Brief wait for fibers to exit gracefully
  4. Output channel is closed

The shutdown timeout prevents hanging on misbehaving sources.

Constants

DEFAULT_BUFFER_SIZE = 32

Default event channel buffer size. 32 events ~= 0.5 seconds of activity at 60 FPS.

Log = Termisu::Logs::Event
SHUTDOWN_TIMEOUT_MS = 100

Graceful shutdown timeout in milliseconds. Sources have this long to finish before channel is closed.

Constructors

new(buffer_size : Int32 = DEFAULT_BUFFER_SIZE)

Creates a new Event::Loop with the specified buffer size.

The buffer size determines how many events can be queued before send operations block. Larger buffers reduce blocking but use more memory.

Source

Instance methods

add_source(source : Source) : self

Adds an event source to the loop.

If the loop is already running, the source is started immediately. Otherwise, it will be started when start is called.

Returns self for method chaining.

Source
output

Returns the event output channel.

Use this channel to receive events from all sources:

while event = loop.output.receive?
  handle(event)
end
Source
remove_source(source : Source) : self

Removes an event source from the loop.

If the source is running, it is stopped before removal. Removing a non-existent source is a no-op.

Returns self for method chaining.

Source
running?

Returns true if the event loop is currently running.

Source
source_names

Returns the names of all registered sources.

Useful for logging and debugging.

Source
start

Starts the event loop and all registered sources.

Each source begins producing events to the shared output channel. This is a non-blocking operation - sources run in their own fibers.

Returns self for method chaining.

Source
stop

Stops the event loop and all sources.

Performs graceful shutdown:

  1. Sets running state to false
  2. Stops all sources
  3. Waits briefly for fibers to exit
  4. Closes the output channel

This unblocks any receivers waiting on the channel. Safe to call multiple times (idempotent).

Returns self for method chaining.

Source