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.