Signal

Namespace:

namespace Lenga\Engine\Core;

class Signal

Signal is an owner-scoped callback surface for one specific behaviour or system instance.

Subscribers still need a reference to the owner in order to subscribe. If you want decoupled gameplay communication where listeners react without knowing the dispatcher ahead of time, use EventBus instead.

If one known object can just call one known collaborator directly, a public method is often simpler than a Signal. Signal is most useful when an owner wants to expose a one-to-many callback point with add(...), once(...), and disposal semantics.

Methods

add

public function add(callable $listener)

addListener

public function addListener(callable $listener)

once

public function once(callable $listener)

onceListener

public function onceListener(callable $listener)

remove

public function remove(SignalSubscription|callable $listener)

removeListener

public function removeListener(SignalSubscription|callable $listener)

clear

public function clear()

hasListeners

public function hasListeners()

count

public function count()

dispatch

public function dispatch(mixed ...$arguments)

invoke

public function invoke(mixed ...$arguments)

Example

use Lenga\Engine\Core\Behaviour;
use Lenga\Engine\Core\Signal;
use Lenga\Engine\Core\SignalSubscription;

final class Door extends Behaviour
{
    public Signal $onOpened;

    public function awake(): void
    {
        $this->onOpened = $this->createSignal();
    }

    public function open(): void
    {
        $this->onOpened->dispatch($this);
    }
}

final class DoorIndicator extends Behaviour
{
    public ?Door $door = null;
    private ?SignalSubscription $subscription = null;

    public function onEnable(): void
    {
        $this->subscription = $this->door?->onOpened->add(function (Door $door): void {
            $this->flashIndicator();
        });
    }

    public function onDisable(): void
    {
        $this->subscription?->dispose();
        $this->subscription = null;
    }

    private function flashIndicator(): void
    {
    }
}

This pattern fits when the listener already knows which owner instance it wants to observe.