81 lines
2.3 KiB
Dart
81 lines
2.3 KiB
Dart
import '../diagnostics/runtime_diagnostics.dart';
|
|
import '../lifecycle/runtime_serial_queue.dart';
|
|
import '../lifecycle/runtime_session.dart';
|
|
import '../models/game_diff.dart';
|
|
import '../models/runtime_event.dart';
|
|
import '../scripting/script_engine.dart';
|
|
import 'runtime_event_gate.dart';
|
|
|
|
class RuntimeEventDispatcher {
|
|
RuntimeEventDispatcher({
|
|
required RuntimeSession session,
|
|
required ScriptEngine scriptEngine,
|
|
required bool Function(String id) isScopeAlive,
|
|
bool Function(String id, int epoch)? isNodeEpochAlive,
|
|
required void Function(GameDiff diff) applyDiff,
|
|
RuntimeDiagnostics? diagnostics,
|
|
void Function(Object error)? onError,
|
|
}) : _scriptEngine = scriptEngine,
|
|
_applyDiff = applyDiff,
|
|
_diagnostics = diagnostics,
|
|
_onError = onError,
|
|
_gate = RuntimeEventGate(
|
|
session: session,
|
|
isScopeAlive: isScopeAlive,
|
|
isNodeEpochAlive: isNodeEpochAlive,
|
|
) {
|
|
_queue = RuntimeSerialQueue<RuntimeEvent>(
|
|
shouldContinue: () => !_disposed && session.isActive,
|
|
onItem: _dispatch,
|
|
);
|
|
}
|
|
|
|
final ScriptEngine _scriptEngine;
|
|
final void Function(GameDiff diff) _applyDiff;
|
|
final RuntimeDiagnostics? _diagnostics;
|
|
final void Function(Object error)? _onError;
|
|
final RuntimeEventGate _gate;
|
|
late final RuntimeSerialQueue<RuntimeEvent> _queue;
|
|
bool _disposed = false;
|
|
|
|
int get pendingEventCount => _queue.pendingCount;
|
|
|
|
void enqueue(RuntimeEvent event) {
|
|
if (_disposed || !_gate.session.isActive) {
|
|
return;
|
|
}
|
|
_queue.enqueue(_gate.attachSession(event));
|
|
}
|
|
|
|
void dispose() {
|
|
_disposed = true;
|
|
_queue.dispose();
|
|
}
|
|
|
|
void _dispatch(RuntimeEvent event) {
|
|
if (!_gate.accepts(event)) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
final diff = _scriptEngine.dispatchEvent(event);
|
|
if (_disposed || !_gate.session.isActive || !_gate.accepts(event)) {
|
|
return;
|
|
}
|
|
_applyDiff(diff);
|
|
} catch (error) {
|
|
_diagnostics?.record(
|
|
type: RuntimeDiagnosticType.luaEventError,
|
|
message: 'Lua event dispatch failed',
|
|
error: error,
|
|
context: {
|
|
'eventType': event.type,
|
|
if (event.target != null) 'target': event.target,
|
|
if (event.handler != null) 'handler': event.handler,
|
|
},
|
|
);
|
|
_onError?.call(error);
|
|
}
|
|
}
|
|
}
|