Skip to content

Commit 8e7f5e8

Browse files
committed
Methods for scheduling new events have been added to the EventContext. (#6)
1 parent 6bff398 commit 8e7f5e8

File tree

11 files changed

+132
-66
lines changed

11 files changed

+132
-66
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void main() async {
9090
9191
void _a(EventContext context) async {
9292
await context.wait(10);
93-
context.sim.process(event: _c, delay: 1, name: 'C');
93+
context.process(event: _c, delay: 1, name: 'C');
9494
}
9595
9696
void _b(EventContext context) async {

example/example.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ void main() async {
1010

1111
void _a(EventContext context) async {
1212
await context.wait(2);
13-
context.sim.process(event: _a, delay: 2, name: 'A');
13+
context.process(event: _a, delay: 2, name: 'A');
1414
}

lib/simdart.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
export 'src/start_time_handling.dart';
2-
export 'src/simdart.dart' hide SimDartHelper;
31
export 'src/event.dart';
4-
export 'src/simulation_track.dart';
2+
export 'src/execution_priority.dart';
53
export 'src/interval.dart';
64
export 'src/observable.dart';
75
export 'src/resource_configurator.dart' hide ResourcesConfiguratorHelper;
8-
export 'src/execution_priority.dart';
6+
export 'src/simdart.dart' hide SimDartHelper;
7+
export 'src/simulation_track.dart';
8+
export 'src/start_time_handling.dart';

lib/src/event.dart

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'dart:async';
22

3-
import 'package:simdart/src/simdart.dart';
3+
import 'package:simdart/src/internal/event_scheduler_interface.dart';
44

55
/// The event to be executed.
66
///
@@ -12,10 +12,7 @@ typedef Event = void Function(EventContext context);
1212
///
1313
/// Encapsulates the information and state of an event being executed
1414
/// within the simulation.
15-
mixin EventContext {
16-
/// The simulation instance managing this event.
17-
SimDart get sim;
18-
15+
abstract interface class EventContext implements EventSchedulerInterface {
1916
/// Pauses the execution of the event for the specified [delay] in simulation time.
2017
///
2118
/// The event is re-added to the simulation's event queue and will resume after

lib/src/internal/event_action.dart

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,25 @@ import 'dart:async';
22

33
import 'package:meta/meta.dart';
44
import 'package:simdart/src/event.dart';
5-
import 'package:simdart/src/internal/time_action.dart';
65
import 'package:simdart/src/internal/resource.dart';
6+
import 'package:simdart/src/internal/time_action.dart';
7+
import 'package:simdart/src/interval.dart';
78
import 'package:simdart/src/simdart.dart';
89
import 'package:simdart/src/simulation_track.dart';
910

1011
@internal
11-
class EventAction extends TimeAction with EventContext {
12+
class EventAction extends TimeAction implements EventContext {
1213
EventAction(
13-
{required this.sim,
14+
{required SimDart sim,
1415
required super.start,
1516
required String? eventName,
1617
required this.event,
1718
required this.resourceId,
1819
required this.onTrack,
1920
required this.onReject,
2021
required this.secondarySortByName})
21-
: _eventName = eventName;
22+
: _sim = sim,
23+
_eventName = eventName;
2224

2325
/// The name of the event.
2426
final String? _eventName;
@@ -34,8 +36,7 @@ class EventAction extends TimeAction with EventContext {
3436

3537
final Function? onReject;
3638

37-
@override
38-
final SimDart sim;
39+
final SimDart _sim;
3940

4041
/// The resource id required by the event.
4142
final String? resourceId;
@@ -64,15 +65,15 @@ class EventAction extends TimeAction with EventContext {
6465
if (resume != null) {
6566
if (onTrack != null) {
6667
onTrack!(SimDartHelper.buildSimulationTrack(
67-
sim: sim, eventName: eventName, status: Status.resumed));
68+
sim: _sim, eventName: eventName, status: Status.resumed));
6869
}
6970
// Resume the event if it is waiting, otherwise execute its action.
7071
resume.call();
7172
return;
7273
}
7374

7475
Resource? resource =
75-
SimDartHelper.getResource(sim: sim, resourceId: resourceId);
76+
SimDartHelper.getResource(sim: _sim, resourceId: resourceId);
7677
if (resource != null) {
7778
_resourceAcquired = resource.acquire(this);
7879
}
@@ -83,7 +84,7 @@ class EventAction extends TimeAction with EventContext {
8384
status = Status.rejected;
8485
}
8586
onTrack!(SimDartHelper.buildSimulationTrack(
86-
sim: sim, eventName: eventName, status: status));
87+
sim: _sim, eventName: eventName, status: status));
8788
}
8889

8990
if (_canRun) {
@@ -94,12 +95,12 @@ class EventAction extends TimeAction with EventContext {
9495
_resourceAcquired = false;
9596
}
9697
// Event released some resource, others events need retry.
97-
SimDartHelper.restoreWaitingEventsForResource(sim: sim);
98+
SimDartHelper.restoreWaitingEventsForResource(sim: _sim);
9899
}
99100
});
100101
} else {
101102
onReject?.call();
102-
SimDartHelper.queueOnWaitingForResource(sim: sim, action: this);
103+
SimDartHelper.queueOnWaitingForResource(sim: _sim, action: this);
103104
}
104105
}
105106

@@ -109,9 +110,9 @@ class EventAction extends TimeAction with EventContext {
109110
return;
110111
}
111112

112-
start = sim.now + delay;
113+
start = _sim.now + delay;
113114
// Adds it back to the loop to be resumed in the future.
114-
SimDartHelper.addAction(sim: sim, action: this);
115+
SimDartHelper.addAction(sim: _sim, action: this);
115116

116117
final Completer<void> resume = Completer<void>();
117118
_resume = () {
@@ -124,4 +125,42 @@ class EventAction extends TimeAction with EventContext {
124125
Future<void> _runEvent() async {
125126
return event(this);
126127
}
128+
129+
@override
130+
int get now => _sim.now;
131+
132+
@override
133+
void process(
134+
{required Event event,
135+
String? resourceId,
136+
String? name,
137+
int? start,
138+
int? delay}) {
139+
_sim.process(
140+
event: event,
141+
resourceId: resourceId,
142+
name: name,
143+
start: start,
144+
delay: delay);
145+
}
146+
147+
@override
148+
void repeatProcess(
149+
{required Event event,
150+
int? start,
151+
int? delay,
152+
required Interval interval,
153+
RejectedEventPolicy rejectedEventPolicy =
154+
RejectedEventPolicy.keepRepeating,
155+
String? resourceId,
156+
String? name}) {
157+
_sim.repeatProcess(
158+
event: event,
159+
interval: interval,
160+
start: start,
161+
delay: delay,
162+
rejectedEventPolicy: rejectedEventPolicy,
163+
resourceId: resourceId,
164+
name: name);
165+
}
127166
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import 'package:meta/meta.dart';
2+
import 'package:simdart/src/event.dart';
3+
import 'package:simdart/src/internal/now_interface.dart';
4+
import 'package:simdart/src/interval.dart';
5+
import 'package:simdart/src/simdart.dart';
6+
7+
@internal
8+
abstract interface class EventSchedulerInterface implements NowInterface {
9+
/// Schedules a new event to occur repeatedly based on the specified interval configuration.
10+
///
11+
/// [event] is the function that represents the action to be executed when the event occurs.
12+
/// [start] is the absolute time at which the event should occur. If null, the event will
13+
/// occur at the [now] simulation time.
14+
/// [delay] is the number of time units after the [now] when the event has been scheduled.
15+
/// It cannot be provided if [start] is specified.
16+
/// [interval] defines the timing configuration for the event, including its start time and
17+
/// the interval between repetitions. The specific details of the interval behavior depend
18+
/// on the implementation of the [Interval].
19+
/// [resourceId] is an optional parameter that specifies the ID of the resource required by the event.
20+
/// [name] is an optional identifier for the event.
21+
/// [rejectedEventPolicy] defines the behavior of the interval after a newly created event has been rejected.
22+
///
23+
/// Throws an [ArgumentError] if the provided interval configuration is invalid, such as
24+
/// containing negative or inconsistent timing values.
25+
void repeatProcess(
26+
{required Event event,
27+
int? start,
28+
int? delay,
29+
required Interval interval,
30+
RejectedEventPolicy rejectedEventPolicy =
31+
RejectedEventPolicy.keepRepeating,
32+
String? resourceId,
33+
String? name});
34+
35+
/// Schedules a new event to occur at a specific simulation time or after a delay.
36+
///
37+
/// [event] is the function that represents the action to be executed when the event occurs.
38+
/// [start] is the absolute time at which the event should occur. If null, the event will
39+
/// occur at the [now] simulation time.
40+
/// [delay] is the number of time units after the [now] when the event has been scheduled.
41+
/// It cannot be provided if [start] is specified.
42+
/// [resourceId] is an optional parameter that specifies the ID of the resource required by the event.
43+
/// [name] is an optional identifier for the event.
44+
///
45+
/// Throws an [ArgumentError] if both [start] and [delay] are provided or if [delay] is negative.
46+
void process(
47+
{required Event event,
48+
String? resourceId,
49+
String? name,
50+
int? start,
51+
int? delay});
52+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import 'package:meta/meta.dart';
2+
3+
@internal
4+
abstract interface class NowInterface {
5+
/// Gets the current simulation time.
6+
int get now;
7+
}

lib/src/internal/time_loop.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import 'package:collection/collection.dart';
44
import 'package:meta/meta.dart';
55
import 'package:simdart/src/execution_priority.dart';
66
import 'package:simdart/src/internal/time_action.dart';
7-
import 'package:simdart/src/internal/time_loop_mixin.dart';
7+
import 'package:simdart/src/internal/time_loop_interface.dart';
88
import 'package:simdart/src/start_time_handling.dart';
99

1010
/// Represents the temporal loop in the algorithm, managing the execution of actions at specified times.
1111
@internal
12-
class TimeLoop with TimeLoopMixin {
12+
class TimeLoop implements TimeLoopInterface {
1313
TimeLoop(
1414
{required int? now,
1515
required this.beforeRun,

lib/src/internal/time_loop_mixin.dart renamed to lib/src/internal/time_loop_interface.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import 'package:meta/meta.dart';
22
import 'package:simdart/src/execution_priority.dart';
3+
import 'package:simdart/src/internal/now_interface.dart';
34
import 'package:simdart/src/start_time_handling.dart';
45

56
/// Represents the temporal loop in the algorithm, managing the execution of actions at specified times.
67
@internal
7-
mixin TimeLoopMixin {
8+
abstract interface class TimeLoopInterface implements NowInterface {
89
/// Specifies how the simulation handles start times in the past.
910
StartTimeHandling get startTimeHandling;
1011

@@ -32,7 +33,4 @@ mixin TimeLoopMixin {
3233
///
3334
/// The value will be `null` if the duration has not been calculated or set.
3435
int? get duration;
35-
36-
/// Gets the current simulation time.
37-
int get now;
3836
}

lib/src/simdart.dart

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@ import 'package:meta/meta.dart';
66
import 'package:simdart/src/event.dart';
77
import 'package:simdart/src/execution_priority.dart';
88
import 'package:simdart/src/internal/event_action.dart';
9+
import 'package:simdart/src/internal/event_scheduler_interface.dart';
910
import 'package:simdart/src/internal/repeat_event_action.dart';
11+
import 'package:simdart/src/internal/resource.dart';
1012
import 'package:simdart/src/internal/time_action.dart';
1113
import 'package:simdart/src/internal/time_loop.dart';
12-
import 'package:simdart/src/internal/time_loop_mixin.dart';
14+
import 'package:simdart/src/internal/time_loop_interface.dart';
1315
import 'package:simdart/src/interval.dart';
14-
import 'package:simdart/src/internal/resource.dart';
1516
import 'package:simdart/src/resource_configurator.dart';
1617
import 'package:simdart/src/simulation_track.dart';
1718
import 'package:simdart/src/start_time_handling.dart';
1819

1920
/// Represents a discrete-event simulation engine.
20-
class SimDart with TimeLoopMixin {
21+
class SimDart implements TimeLoopInterface, EventSchedulerInterface {
2122
/// Creates a simulation instance.
2223
///
2324
/// - [now]: The starting time of the simulation. Defaults to `0` if null.
@@ -104,22 +105,7 @@ class SimDart with TimeLoopMixin {
104105
return _loop.run(until: until);
105106
}
106107

107-
/// Schedules a new event to occur repeatedly based on the specified interval configuration.
108-
///
109-
/// [event] is the function that represents the action to be executed when the event occurs.
110-
/// [start] is the absolute time at which the event should occur. If null, the event will
111-
/// occur at the [now] simulation time.
112-
/// [delay] is the number of time units after the [now] when the event has been scheduled.
113-
/// It cannot be provided if [start] is specified.
114-
/// [interval] defines the timing configuration for the event, including its start time and
115-
/// the interval between repetitions. The specific details of the interval behavior depend
116-
/// on the implementation of the [Interval].
117-
/// [resourceId] is an optional parameter that specifies the ID of the resource required by the event.
118-
/// [name] is an optional identifier for the event.
119-
/// [rejectedEventPolicy] defines the behavior of the interval after a newly created event has been rejected.
120-
///
121-
/// Throws an [ArgumentError] if the provided interval configuration is invalid, such as
122-
/// containing negative or inconsistent timing values.
108+
@override
123109
void repeatProcess(
124110
{required Event event,
125111
int? start,
@@ -140,17 +126,7 @@ class SimDart with TimeLoopMixin {
140126
rejectedEventPolicy: rejectedEventPolicy);
141127
}
142128

143-
/// Schedules a new event to occur at a specific simulation time or after a delay.
144-
///
145-
/// [event] is the function that represents the action to be executed when the event occurs.
146-
/// [start] is the absolute time at which the event should occur. If null, the event will
147-
/// occur at the [now] simulation time.
148-
/// [delay] is the number of time units after the [now] when the event has been scheduled.
149-
/// It cannot be provided if [start] is specified.
150-
/// [resourceId] is an optional parameter that specifies the ID of the resource required by the event.
151-
/// [name] is an optional identifier for the event.
152-
///
153-
/// Throws an [ArgumentError] if both [start] and [delay] are provided or if [delay] is negative.
129+
@override
154130
void process(
155131
{required Event event,
156132
String? resourceId,

0 commit comments

Comments
 (0)