1+ import 'dart:collection' ;
2+
13import 'package:meta/meta.dart' ;
24import 'package:simdart/src/internal/completer_action.dart' ;
35import 'package:simdart/src/internal/event_action.dart' ;
4- import 'package:simdart/src/internal/resource.dart' ;
56import 'package:simdart/src/simdart.dart' ;
67import 'package:simdart/src/simulation_track.dart' ;
78
9+ @internal
10+ class ResourceStore {
11+ /// Holds the resources in the simulator.
12+ final Map <String , _ResourceImpl > _map = {};
13+ final List <_ResourceImpl > _list = [];
14+ late final UnmodifiableListView <_ResourceImpl > _unmodifiableList =
15+ UnmodifiableListView (_list);
16+
17+ Map <String , int > usage () {
18+ Map <String , int > result = {};
19+ for (_ResourceImpl resource in _map.values) {
20+ result[resource.name] = resource._queue.length;
21+ }
22+ return result;
23+ }
24+ }
25+
26+ abstract interface class Resource {
27+ String get name;
28+ int get capacity;
29+ bool isAvailable ();
30+ }
31+
32+ abstract interface class LimitedResource extends Resource {}
33+
34+ abstract class _ResourceImpl implements Resource {
35+ _ResourceImpl (
36+ {required this .name,
37+ required this .capacity,
38+ required this .acquisitionRule});
39+
40+ @override
41+ final String name;
42+
43+ @override
44+ final int capacity;
45+
46+ final List <EventAction > _queue = [];
47+ final bool Function (EventAction event)? acquisitionRule;
48+
49+ /// A queue that holds completer to resume events waiting for a resource to become available.
50+ final List <EventAction > _waiting = [];
51+
52+ bool acquire (EventAction event);
53+
54+ bool release (SimDart sim, EventAction event);
55+ }
56+
57+ class _LimitedResourceImpl extends _ResourceImpl implements LimitedResource {
58+ _LimitedResourceImpl (
59+ {required super .name,
60+ required super .capacity,
61+ required super .acquisitionRule});
62+
63+ @override
64+ bool acquire (EventAction event) {
65+ if (acquisitionRule != null && ! acquisitionRule !(event)) {
66+ return false ;
67+ }
68+ if (isAvailable ()) {
69+ _queue.add (event);
70+ return true ;
71+ }
72+
73+ return false ;
74+ }
75+
76+ @override
77+ bool release (SimDart sim, EventAction event) {
78+ return _queue.remove (event);
79+ }
80+
81+ @override
82+ bool isAvailable () {
83+ return _queue.length < capacity;
84+ }
85+ }
86+
887class Resources {
9- Resources ._(SimDart sim) : _sim = sim;
88+ Resources ._(SimDart sim)
89+ : _sim = sim,
90+ _store = SimDartHelper .resourceStore (sim: sim);
1091
1192 final SimDart _sim;
93+ final ResourceStore _store;
94+
95+ List <Resource > get all => _store._unmodifiableList;
96+
97+ int get length => _store._map.length;
1298
1399 /// Creates a resource with limited capacity.
14100 ///
15101 /// This method adds a resource with the specified capacity.
16102 /// The resource will be configured as limited, meaning it will have a maximum
17103 /// capacity defined by the [capacity] parameter.
18104 ///
19- /// - [id ] : The unique identifier of the resource (required).
105+ /// - [name ] : The unique name of the resource (required).
20106 /// - [capacity] : The maximum capacity of the resource. The default value is 1.
21- void limited ({required String id, int capacity = 1 }) {
22- SimDartHelper .addResource (
23- sim: _sim,
24- resourceId: id,
25- create: () => LimitedResource (id: id, capacity: capacity));
107+ Resource limited ({required String name, int capacity = 1 }) {
108+ _ResourceImpl ? resource = _store._map[name];
109+ if (resource == null ) {
110+ resource = _LimitedResourceImpl (
111+ name: name, capacity: capacity, acquisitionRule: null );
112+ _store._map[name] = resource;
113+ _store._list.add (resource);
114+ }
115+ return resource;
26116 }
27117
28118 /// Checks if a resource is available.
29119 ///
30- /// - [id ] : The id of the resource to check.
120+ /// - [name ] : The name of the resource to check.
31121 /// - Returns: `true` if the resource is available, `false` otherwise.
32- bool isAvailable (String id ) {
33- Resource ? resource = SimDartHelper . getResource (sim : _sim, resourceId : id) ;
122+ bool isAvailable (String name ) {
123+ _ResourceImpl ? resource = _store._map[name] ;
34124 if (resource != null ) {
35125 return resource.isAvailable ();
36126 }
@@ -47,10 +137,10 @@ class ResourcesContext extends Resources {
47137
48138 /// Tries to acquire a resource immediately.
49139 ///
50- /// - [id ] : The id of the resource to acquire.
140+ /// - [name ] : The name of the resource to acquire.
51141 /// - Returns: `true` if the resource was acquired, `false` otherwise.
52- bool tryAcquire (String id ) {
53- Resource ? resource = SimDartHelper . getResource (sim : _sim, resourceId : id) ;
142+ bool tryAcquire (String name ) {
143+ _ResourceImpl ? resource = _store._map[name] ;
54144 if (resource != null ) {
55145 return resource.acquire (_event);
56146 }
@@ -59,17 +149,17 @@ class ResourcesContext extends Resources {
59149
60150 /// Acquires a resource, waiting if necessary until it becomes available.
61151 ///
62- /// - [id ] : The id of the resource to acquire.
152+ /// - [name ] : The name of the resource to acquire.
63153 /// - Returns: A [Future] that completes when the resource is acquired.
64- Future <void > acquire (String id ) async {
154+ Future <void > acquire (String name ) async {
65155 if (_event.eventCompleter != null ) {
66156 SimDartHelper .error (
67157 sim: _sim,
68158 msg:
69159 "This event should be waiting for the resource to be released. Did you forget to use 'await'?" );
70160 return ;
71161 }
72- Resource ? resource = SimDartHelper . getResource (sim : _sim, resourceId : id) ;
162+ _ResourceImpl ? resource = _store._map[name] ;
73163 if (resource != null ) {
74164 bool acquired = resource.acquire (_event);
75165 if (! acquired) {
@@ -78,23 +168,23 @@ class ResourcesContext extends Resources {
78168 sim: _sim, eventName: _event.eventName, status: Status .yielded);
79169 }
80170 _event.buildCompleter ();
81- resource.waiting .add (_event);
171+ resource._waiting .add (_event);
82172 SimDartHelper .scheduleNextAction (sim: _sim);
83173 await _event.eventCompleter! .future;
84- return await acquire (id );
174+ return await acquire (name );
85175 }
86176 }
87177 }
88178
89179 /// Releases a previously acquired resource.
90180 ///
91- /// - [id ] : The id of the resource to release.
92- void release (String id ) {
93- Resource ? resource = SimDartHelper . getResource (sim : _sim, resourceId : id) ;
181+ /// - [name ] : The name of the resource to release.
182+ void release (String name ) {
183+ _ResourceImpl ? resource = _store._map[name] ;
94184 if (resource != null ) {
95185 if (resource.release (_sim, _event)) {
96- if (resource.waiting .isNotEmpty) {
97- EventAction other = resource.waiting .removeAt (0 );
186+ if (resource._waiting .isNotEmpty) {
187+ EventAction other = resource._waiting .removeAt (0 );
98188 // Schedule a complete to resume this event in the future.
99189 SimDartHelper .addAction (
100190 sim: _sim,
0 commit comments