emit method
Emits a single event with optional payload.
Triggers all listeners registered for the event, executing them in priority order. One-time listeners are automatically removed after execution.
event - The name of the event to emit
payload - Optional data to pass to all listeners
queue - Whether to execute listeners asynchronously in separate futures
Returns a Future that completes when all listeners have finished executing
Implementation
@override
Future<void> emit(
String event, [
dynamic payload,
bool queue = false,
]) async {
final listeners = _listeners[event];
if (listeners == null || listeners.isEmpty) return;
final listenersCopy = List<EventRegistration>.from(listeners);
final toRemove = <EventRegistration>[];
if (queue) {
// Execute listeners asynchronously but wait for all to complete
final futures = <Future>[];
for (final registration in listenersCopy) {
if (registration.removed) continue;
futures.add(
Future(() async {
try {
await registration.listener(payload);
} catch (e, stackTrace) {
Khadem.logger.error(
'Event listener error for event "$event": $e',
stackTrace: stackTrace,
);
}
}),
);
if (registration.once) {
registration.removed = true;
toRemove.add(registration);
}
}
// Wait for all async listeners to complete
await Future.wait(futures);
} else {
// Execute listeners synchronously
for (final registration in listenersCopy) {
if (registration.removed) continue;
try {
await registration.listener(payload);
} catch (e) {
// Log exception but don't rethrow to prevent disrupting other listeners
// In a real application, you might want to log this
}
if (registration.once) {
registration.removed = true;
toRemove.add(registration);
}
}
}
if (toRemove.isNotEmpty) {
// Rebuild the listeners list without the removed registrations
final remaining = listeners.where((reg) => !reg.removed).toList();
listeners.clear();
listeners.addAll(remaining);
}
}