diff --git a/packages/cli/lib/behavior/behavior.dart b/packages/cli/lib/behavior/behavior.dart index 7b658241..115da8ef 100644 --- a/packages/cli/lib/behavior/behavior.dart +++ b/packages/cli/lib/behavior/behavior.dart @@ -1,3 +1,7 @@ +import 'package:cli/behavior/central_command.dart'; +import 'package:cli/cache/caches.dart'; +import 'package:cli/logger.dart'; +import 'package:db/db.dart'; import 'package:meta/meta.dart'; import 'package:types/types.dart'; @@ -87,3 +91,128 @@ T assertNotNull( } return value; } + +enum _JobResultType { + waitOrLoop, + complete, +} + +/// The result from doJob +class JobResult { + /// Wait tells the caller to return out the DateTime? to have the ship + /// wait. Does not advance to the next job. + JobResult.wait(DateTime? wait) + : _type = _JobResultType.waitOrLoop, + _waitTime = wait; + + /// Complete tells the caller this job is complete. If wait is null + /// the caller may continue to the next job, otherwise it should wait + /// until the given time. + JobResult.complete([DateTime? wait]) + : _type = _JobResultType.complete, + _waitTime = wait; + + final _JobResultType _type; + final DateTime? _waitTime; + + /// Is this job complete? (Not necessarily the whole behavior) + bool get isComplete => _type == _JobResultType.complete; + + /// Whether the caller should return after the navigation action + bool get shouldReturn => _type != _JobResultType.complete; + + /// The wait time if [shouldReturn] is true + DateTime? get waitTime { + if (!shouldReturn) { + throw StateError('Cannot get wait time for non-wait result'); + } + return _waitTime; + } + + @override + String toString() { + if (isComplete) { + return 'Complete'; + } + final wait = _waitTime; + if (wait == null) { + return 'Return and loop'; + } + return 'Wait until ${wait.toIso8601String()}'; + } +} + +/// Creates a behavior from jobs. +@immutable +class MultiJob { + /// Create a new multi-job. + const MultiJob(this.name, this.jobFunctions); + + /// The name of this multi-job. + final String name; + + /// The job functions to run. + final List< + Future Function( + BehaviorState, + Api, + Database, + CentralCommand, + Caches, + Ship, { + DateTime Function() getNow, + })> jobFunctions; + + /// Run the multi-job. + Future run( + Api api, + Database db, + CentralCommand centralCommand, + Caches caches, + BehaviorState state, + Ship ship, { + DateTime Function() getNow = defaultGetNow, + }) async { + for (var i = 0; i < 10; i++) { + shipInfo(ship, '$name ${state.jobIndex}'); + if (state.jobIndex < 0 || state.jobIndex >= jobFunctions.length) { + centralCommand.disableBehaviorForShip( + ship, + 'No behavior state.', + const Duration(hours: 1), + ); + return null; + } + + final jobFunction = jobFunctions[state.jobIndex]; + final result = await jobFunction( + state, + api, + db, + centralCommand, + caches, + ship, + ); + shipInfo(ship, '$name ${state.jobIndex} $result'); + if (result.isComplete) { + state.jobIndex++; + if (state.jobIndex < jobFunctions.length) { + centralCommand.setBehavior(ship.shipSymbol, state); + } else { + centralCommand.completeBehavior(ship.shipSymbol); + shipInfo(ship, '$name complete!'); + return null; + } + } + if (result.shouldReturn) { + return result.waitTime; + } + } + centralCommand.disableBehaviorForAll( + ship, + 'Too many $name job iterations', + const Duration(hours: 1), + ); + return null; + } +} diff --git a/packages/cli/lib/behavior/deliver.dart b/packages/cli/lib/behavior/deliver.dart index 192d8ddc..60c5cd46 100644 --- a/packages/cli/lib/behavior/deliver.dart +++ b/packages/cli/lib/behavior/deliver.dart @@ -9,7 +9,6 @@ import 'package:cli/net/actions.dart'; import 'package:cli/printing.dart'; import 'package:cli/trading.dart'; import 'package:db/db.dart'; -import 'package:meta/meta.dart'; import 'package:more/collection.dart'; import 'package:types/types.dart'; @@ -90,56 +89,6 @@ class DeliverState { final BuyJob buyJob; } -enum _JobResultType { - waitOrLoop, - complete, -} - -/// The result from doJob -class JobResult { - /// Wait tells the caller to return out the DateTime? to have the ship - /// wait. Does not advance to the next job. - JobResult.wait(DateTime? wait) - : _type = _JobResultType.waitOrLoop, - _waitTime = wait; - - /// Complete tells the caller this job is complete. If wait is null - /// the caller may continue to the next job, otherwise it should wait - /// until the given time. - JobResult.complete([DateTime? wait]) - : _type = _JobResultType.complete, - _waitTime = wait; - - final _JobResultType _type; - final DateTime? _waitTime; - - /// Is this job complete? (Not necessarily the whole behavior) - bool get isComplete => _type == _JobResultType.complete; - - /// Whether the caller should return after the navigation action - bool get shouldReturn => _type != _JobResultType.complete; - - /// The wait time if [shouldReturn] is true - DateTime? get waitTime { - if (!shouldReturn) { - throw StateError('Cannot get wait time for non-wait result'); - } - return _waitTime; - } - - @override - String toString() { - if (isComplete) { - return 'Complete'; - } - final wait = _waitTime; - if (wait == null) { - return 'Return and loop'; - } - return 'Wait until ${wait.toIso8601String()}'; - } -} - /// Determine what BuyJob to issue, if any. Future computeBuyJob( CentralCommand centralCommand, @@ -415,81 +364,6 @@ Future doInitJob( return JobResult.complete(); } -/// Creates a behavior from jobs. -@immutable -class MultiJob { - /// Create a new multi-job. - const MultiJob(this.name, this.jobFunctions); - - /// The name of this multi-job. - final String name; - - /// The job functions to run. - final List< - Future Function( - BehaviorState, - Api, - Database, - CentralCommand, - Caches, - Ship, { - DateTime Function() getNow, - })> jobFunctions; - - /// Run the multi-job. - Future run( - Api api, - Database db, - CentralCommand centralCommand, - Caches caches, - BehaviorState state, - Ship ship, { - DateTime Function() getNow = defaultGetNow, - }) async { - for (var i = 0; i < 10; i++) { - shipInfo(ship, '$name ${state.jobIndex}'); - if (state.jobIndex < 0 || state.jobIndex >= jobFunctions.length) { - centralCommand.disableBehaviorForShip( - ship, - 'No behavior state.', - const Duration(hours: 1), - ); - return null; - } - - final jobFunction = jobFunctions[state.jobIndex]; - final result = await jobFunction( - state, - api, - db, - centralCommand, - caches, - ship, - ); - shipInfo(ship, '$name ${state.jobIndex} $result'); - if (result.isComplete) { - state.jobIndex++; - if (state.jobIndex < jobFunctions.length) { - centralCommand.setBehavior(ship.shipSymbol, state); - } else { - centralCommand.completeBehavior(ship.shipSymbol); - shipInfo(ship, '$name complete!'); - return null; - } - } - if (result.shouldReturn) { - return result.waitTime; - } - } - centralCommand.disableBehaviorForAll( - ship, - 'Too many $name job iterations', - const Duration(hours: 1), - ); - return null; - } -} - /// Advance the behavior of the given ship. final advanceDeliver = const MultiJob('Deliver', [ doInitJob, diff --git a/packages/cli/lib/behavior/trader.dart b/packages/cli/lib/behavior/trader.dart index 8f2ad27d..36758dc4 100644 --- a/packages/cli/lib/behavior/trader.dart +++ b/packages/cli/lib/behavior/trader.dart @@ -2,7 +2,6 @@ import 'dart:math'; import 'package:cli/behavior/behavior.dart'; import 'package:cli/behavior/central_command.dart'; -import 'package:cli/behavior/deliver.dart'; import 'package:cli/behavior/explorer.dart'; import 'package:cli/cache/caches.dart'; import 'package:cli/logger.dart';