Skip to content

14 version 030 #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 0.3.0

* Access the list of created resources.
* Added
* `runState` getter to determine whether the simulation has not started, is running, or has completed.
* `stop` method to manually stop the simulation before it completes.
* Observer to receive data throughout the simulation.

## 0.2.0

* Setting to determine how often `Future.delayed` is used instead of `Future.microtask` during event execution to allow GUI refresh.
Expand All @@ -8,8 +16,8 @@
## 0.1.0

* Initial release
* Discrete event processing
* Event scheduling, execution, waiting, and repetition
* Intervals management
* Discrete event processing.
* Event scheduling, execution, waiting, and repetition.
* Intervals management.
* Resources
* Capacity limit
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
It is designed to model and simulate systems where events occur at discrete points in time,
allowing for the analysis of complex processes and workflows.

Explore and learn more by clicking [here](https://simdart.github.io/simdart-demo/).

## Why Dart?

[Dart](https://dart.dev/) was chosen for this project due to its fast execution, single-threaded nature, and ease of use.
Expand Down Expand Up @@ -125,7 +123,7 @@ import 'package:simdart/simdart.dart';
void main() async {
final SimDart sim = SimDart();

sim.resources.limited(id: 'resource', capacity: 1);
sim.resources.limited(name: 'resource', capacity: 1);

sim.process(event: _eventResource, name: 'A');
sim.process(event: _eventResource, name: 'B');
Expand Down
3 changes: 1 addition & 2 deletions example/example.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import 'package:simdart/simdart.dart';

void main() async {
final SimDart sim = SimDart(includeTracks: true);
final SimDart sim = SimDart(observer: ConsoleEventObserver());

sim.process(event: _eventA, name: 'A');

SimResult result = await sim.run();

result.tracks?.forEach((track) => print(track));
print('startTime: ${result.startTime}');
print('duration: ${result.duration}');
}
Expand Down
6 changes: 3 additions & 3 deletions lib/simdart.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export 'src/event.dart';
export 'src/interval.dart';
export 'src/observable.dart';
export 'src/resources_context.dart';
export 'src/resources.dart';
export 'src/sim_observer.dart';
export 'src/event_phase.dart';
export 'src/resources.dart' hide ResourcesFactory, ResourceStore;
export 'src/simdart.dart' hide SimDartHelper;
export 'src/simulation_track.dart';
export 'src/start_time_handling.dart';
export 'src/sim_result.dart';
export 'src/sim_num.dart';
Expand Down
21 changes: 21 additions & 0 deletions lib/src/event_phase.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/// Enum representing the possible event phases.
///
/// This enumeration is used to track and distinguish different event status
/// during the lifecycle of the simulation.
enum EventPhase {
/// The event was called for the first time.
called,

/// The event was resumed after being paused.
resumed,

yielded,

finished;

/// Returns the string representation of the status.
@override
String toString() {
return name;
}
}
3 changes: 3 additions & 0 deletions lib/src/internal/completer_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ class CompleterAction extends TimeAction {
void execute() {
complete.call();
}

@override
void dispose() {}
}
101 changes: 37 additions & 64 deletions lib/src/internal/event_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@ import 'dart:async';

import 'package:meta/meta.dart';
import 'package:simdart/src/event.dart';
import 'package:simdart/src/event_phase.dart';
import 'package:simdart/src/internal/completer_action.dart';
import 'package:simdart/src/internal/resource.dart';
import 'package:simdart/src/internal/resources_context_impl.dart';
import 'package:simdart/src/internal/time_action.dart';
import 'package:simdart/src/interval.dart';
import 'package:simdart/src/resources_context.dart';
import 'package:simdart/src/resources.dart';
import 'package:simdart/src/sim_context.dart';
import 'package:simdart/src/sim_counter.dart';
import 'package:simdart/src/sim_num.dart';
import 'package:simdart/src/simdart.dart';
import 'package:simdart/src/simulation_track.dart';

@internal
class EventAction extends TimeAction implements SimContext {
Expand All @@ -35,24 +33,30 @@ class EventAction extends TimeAction implements SimContext {
final SimDart sim;

@override
late final ResourcesContext resources = ResourcesContextImpl(sim, this);
late final ResourcesContext resources = ResourcesFactory.context(sim, this);

@override
int get now => sim.now;

/// Internal handler for resuming a waiting event.
EventCompleter? _eventCompleter;
EventCompleter? get eventCompleter => _eventCompleter;

void buildCompleter() {
_eventCompleter = EventCompleter(event: this);
}

@override
void execute() {
if (_eventCompleter != null) {
throw StateError('This event is yielding');
}

if (sim.includeTracks) {
SimDartHelper.addSimulationTrack(
sim: sim, eventName: eventName, status: Status.called);
}
sim.observer?.onEvent(
name: eventName,
time: sim.now,
phase: EventPhase.called,
executionHash: hashCode);

_runEvent().then((_) {
if (_eventCompleter != null) {
Expand All @@ -62,7 +66,15 @@ class EventAction extends TimeAction implements SimContext {
"Next event is being scheduled, but the current one is still paused waiting for continuation. Did you forget to use 'await'?");
return;
}
sim.observer?.onEvent(
name: eventName,
time: sim.now,
phase: EventPhase.finished,
executionHash: hashCode);

SimDartHelper.scheduleNextAction(sim: sim);
}).catchError((e) {
// Sim already marked to finish. Let the last event finalize.
});
}

Expand All @@ -79,10 +91,12 @@ class EventAction extends TimeAction implements SimContext {
return;
}

if (sim.includeTracks) {
SimDartHelper.addSimulationTrack(
sim: sim, eventName: eventName, status: Status.yielded);
}
sim.observer?.onEvent(
name: eventName,
time: sim.now,
phase: EventPhase.yielded,
executionHash: hashCode);

_eventCompleter = EventCompleter(event: this);

// Schedule a complete to resume this event in the future.
Expand All @@ -95,53 +109,6 @@ class EventAction extends TimeAction implements SimContext {
SimDartHelper.scheduleNextAction(sim: sim);

await _eventCompleter!.future;
_eventCompleter = null;
}

Future<void> acquireResource(String id) async {
if (_eventCompleter != null) {
SimDartHelper.error(
sim: sim,
msg:
"This event should be waiting for the resource to be released. Did you forget to use 'await'?");
return;
}
Resource? resource = SimDartHelper.getResource(sim: sim, resourceId: id);
if (resource != null) {
bool acquired = resource.acquire(this);
if (!acquired) {
if (sim.includeTracks) {
SimDartHelper.addSimulationTrack(
sim: sim, eventName: eventName, status: Status.yielded);
}
_eventCompleter = EventCompleter(event: this);
resource.waiting.add(this);
SimDartHelper.scheduleNextAction(sim: sim);
await _eventCompleter!.future;
_eventCompleter = null;
return await acquireResource(id);
}
}
}

void releaseResource(String id) {
Resource? resource = SimDartHelper.getResource(sim: sim, resourceId: id);
if (resource != null) {
if (resource.release(sim, this)) {
if (resource.waiting.isNotEmpty) {
//resource.waiting.removeAt(0).call();
EventAction other = resource.waiting.removeAt(0);
// Schedule a complete to resume this event in the future.
SimDartHelper.addAction(
sim: sim,
action: CompleterAction(
start: sim.now,
complete: other._eventCompleter!.complete,
order: other.order));
SimDartHelper.scheduleNextAction(sim: sim);
}
}
}
}

@override
Expand Down Expand Up @@ -175,6 +142,11 @@ class EventAction extends TimeAction implements SimContext {
SimNum num(String name) {
return sim.num(name);
}

@override
void dispose() {
_eventCompleter?.complete();
}
}

class EventCompleter {
Expand All @@ -187,10 +159,11 @@ class EventCompleter {
Future<void> get future => _completer.future;

void complete() {
if (event.sim.includeTracks) {
SimDartHelper.addSimulationTrack(
sim: event.sim, eventName: event.eventName, status: Status.resumed);
}
event.sim.observer?.onEvent(
name: event.eventName,
time: event.sim.now,
phase: EventPhase.resumed,
executionHash: hashCode);
_completer.complete();
event._eventCompleter = null;
}
Expand Down
3 changes: 3 additions & 0 deletions lib/src/internal/repeat_event_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,7 @@ class RepeatEventAction extends TimeAction {
}
SimDartHelper.scheduleNextAction(sim: sim);
}

@override
void dispose() {}
}
50 changes: 0 additions & 50 deletions lib/src/internal/resource.dart

This file was deleted.

34 changes: 0 additions & 34 deletions lib/src/internal/resources_context_impl.dart

This file was deleted.

28 changes: 0 additions & 28 deletions lib/src/internal/resources_impl.dart

This file was deleted.

Loading