part of 'command_executor.dart'; extension _CommandExecutorLifecycle on CommandExecutor { Future<_CommandResult> _delay( RuntimeCommand command, _CommandContext context, RuntimeCommandHandle? handle, ) { final scope = _scopeFor(command, context, defaultTarget: false); final scopeEpoch = _scopeEpochFor(scope, context); final task = _registerTask(scope, handle); _schedule(_duration(command, defaultValue: 0), task, () { if ((handle?.isCancelled ?? false) || !_scopeIsAlive(scope)) { task.cancel(); return; } _emitCommandCompletion( command, context.copyWith(scope: scope, scopeEpoch: scopeEpoch), ); task.complete(_CommandResult.completed); }); return task.future; } void _schedule( double seconds, RuntimeTask<_CommandResult> task, void Function() callback, ) { void guardedCallback() { if (_disposed || task.isCancelled) { return; } callback(); } if (seconds <= 0) { async.scheduleMicrotask(guardedCallback); return; } late final async.Timer timer; timer = async.Timer(Duration(milliseconds: (seconds * 1000).round()), () { task.removeTimer(timer); guardedCallback(); }); task.addTimer(timer); } RuntimeTask<_CommandResult> _registerTask( String? scope, RuntimeCommandHandle? handle, ) { final task = _tasks.create(scope: scope); handle?.addCancelCallback(task.cancel); return task; } _CommandContext _commandContextFor( RuntimeCommand command, _CommandContext context, ) { return context.copyWith(group: _commandGroupFor(command, context)); } RuntimeCommandHandle? _createCommandHandle( RuntimeCommand command, _CommandContext context, ) { if (command.type == RuntimeCommandType.cancelCommands) { return null; } final id = _optionalString(command.payload['id'], 'id'); final group = context.group; final scope = _completionScopeFor(command, context); if (id == null && group == null && scope == null) { return null; } return _commandRegistry.create(id: id, group: group, scope: scope); } _CommandContext _childContextFor( RuntimeCommand command, _CommandContext context, ) { final scope = _scopeFor(command, context, defaultTarget: false); return context.copyWith( scope: scope, scopeEpoch: _scopeEpochFor(scope, context), group: _commandGroupFor(command, context), ); } String? _commandGroupFor(RuntimeCommand command, _CommandContext context) { final commandGroup = _optionalString( command.payload['commandGroup'], 'commandGroup', ); if (commandGroup != null) { return commandGroup; } if (_usesGroupAsCommandGroup(command.type)) { final legacyGroup = _optionalString(command.payload['group'], 'group'); if (legacyGroup != null) { return legacyGroup; } } return context.group; } bool _usesGroupAsCommandGroup(String commandType) { return commandType != RuntimeCommandType.preloadResources && commandType != RuntimeCommandType.evictResources && commandType != RuntimeCommandType.cancelCommands; } String? _scopeFor( RuntimeCommand command, _CommandContext context, { required bool defaultTarget, }) { final explicit = _optionalString(command.payload['scope'], 'scope'); if (explicit != null) { return explicit; } if (context.scope != null) { return context.scope; } if (defaultTarget) { return command.target; } return null; } String? _completionScopeFor(RuntimeCommand command, _CommandContext context) { final explicit = _optionalString(command.payload['scope'], 'scope'); return explicit ?? context.scope; } int? _scopeEpochFor(String? scope, _CommandContext context) { if (scope == null) { return null; } if (scope == context.scope && context.scopeEpoch != null) { return context.scopeEpoch; } return _renderTree.epochOf(scope); } bool _scopeIsAlive(String? scope) { return scope == null || _renderTree.contains(scope); } }