salabim 24.0.17__py3-none-any.whl → 24.0.18__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- salabim/salabim.py +194 -42
- {salabim-24.0.17.dist-info → salabim-24.0.18.dist-info}/METADATA +1 -1
- {salabim-24.0.17.dist-info → salabim-24.0.18.dist-info}/RECORD +5 -5
- {salabim-24.0.17.dist-info → salabim-24.0.18.dist-info}/WHEEL +1 -1
- {salabim-24.0.17.dist-info → salabim-24.0.18.dist-info}/top_level.txt +0 -0
salabim/salabim.py
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
# _ _ _ ____ _ _ ___ _
|
2
|
-
# ___ __ _ | | __ _ | |__ (_) _ __ ___ |___ \ | || | / _ \ /
|
3
|
-
# / __| / _` || | / _` || '_ \ | || '_ ` _ \ __) || || |_ | | | | | |
|
4
|
-
# \__ \| (_| || || (_| || |_) || || | | | | | / __/ |__ _| _ | |_| | _ | |
|
5
|
-
# |___/ \__,_||_| \__,_||_.__/ |_||_| |_| |_| |_____| |_| (_) \___/ (_)|_| /
|
1
|
+
# _ _ _ ____ _ _ ___ _ ___
|
2
|
+
# ___ __ _ | | __ _ | |__ (_) _ __ ___ |___ \ | || | / _ \ / | ( _ )
|
3
|
+
# / __| / _` || | / _` || '_ \ | || '_ ` _ \ __) || || |_ | | | | | | / _ \
|
4
|
+
# \__ \| (_| || || (_| || |_) || || | | | | | / __/ |__ _| _ | |_| | _ | || (_) |
|
5
|
+
# |___/ \__,_||_| \__,_||_.__/ |_||_| |_| |_| |_____| |_| (_) \___/ (_)|_| \___/
|
6
6
|
# discrete event simulation
|
7
7
|
#
|
8
8
|
# see www.salabim.org for more information, the documentation and license information
|
9
9
|
|
10
|
-
__version__ = "24.0.
|
10
|
+
__version__ = "24.0.18"
|
11
11
|
|
12
12
|
import heapq
|
13
13
|
import random
|
@@ -31,7 +31,6 @@ import subprocess
|
|
31
31
|
import tempfile
|
32
32
|
import struct
|
33
33
|
import binascii
|
34
|
-
import operator
|
35
34
|
import copy
|
36
35
|
import numbers
|
37
36
|
import platform
|
@@ -7317,6 +7316,30 @@ by adding at the end:
|
|
7317
7316
|
def __repr__(self):
|
7318
7317
|
return object_to_str(self) + " (" + self.name() + ")"
|
7319
7318
|
|
7319
|
+
def reset_monitors(self, monitor: bool = None, stats_only: bool = None) -> None:
|
7320
|
+
"""
|
7321
|
+
resets the monitor for the component's status and mode monitors
|
7322
|
+
|
7323
|
+
Parameters
|
7324
|
+
----------
|
7325
|
+
monitor : bool
|
7326
|
+
if True, monitoring will be on.
|
7327
|
+
|
7328
|
+
if False, monitoring is disabled
|
7329
|
+
|
7330
|
+
if omitted, no change of monitoring state
|
7331
|
+
|
7332
|
+
stats_only : bool
|
7333
|
+
if True, only statistics will be collected (using less memory, but also less functionality)
|
7334
|
+
|
7335
|
+
if False, full functionality
|
7336
|
+
|
7337
|
+
if omittted, no change of stats_only
|
7338
|
+
"""
|
7339
|
+
self.status.reset(monitor=monitor, stats_only=stats_only)
|
7340
|
+
self.mode.reset(monitor=monitor, stats_only=stats_only)
|
7341
|
+
|
7342
|
+
|
7320
7343
|
def register(self, registry: List) -> "Component":
|
7321
7344
|
"""
|
7322
7345
|
registers the component in the registry
|
@@ -8829,6 +8852,131 @@ by adding:
|
|
8829
8852
|
for r in list(self._claims):
|
8830
8853
|
self._release(r)
|
8831
8854
|
|
8855
|
+
def wait_for(self,cond, states, priority=0, urgent=False, mode=None,fail_delay=None, fail_at=None, cap_now=None):
|
8856
|
+
schedule_priority = priority
|
8857
|
+
"""
|
8858
|
+
wait for any or all of the given state values are met
|
8859
|
+
|
8860
|
+
Parameters
|
8861
|
+
----------
|
8862
|
+
cond : callable
|
8863
|
+
parameterless function that return True if wait is over
|
8864
|
+
|
8865
|
+
states : iterable
|
8866
|
+
specicies which states should trigger the cond to be checked
|
8867
|
+
|
8868
|
+
priority : float
|
8869
|
+
priority of the fail event
|
8870
|
+
|
8871
|
+
default: 0
|
8872
|
+
|
8873
|
+
if a component has the same time on the event list, this component is sorted accoring to
|
8874
|
+
the priority.
|
8875
|
+
|
8876
|
+
urgent : bool
|
8877
|
+
urgency indicator
|
8878
|
+
|
8879
|
+
if False (default), the component will be scheduled
|
8880
|
+
behind all other components scheduled
|
8881
|
+
for the same time and priority
|
8882
|
+
|
8883
|
+
if True, the component will be scheduled
|
8884
|
+
in front of all components scheduled
|
8885
|
+
for the same time and priority
|
8886
|
+
|
8887
|
+
fail_at : float or distribution
|
8888
|
+
time out
|
8889
|
+
|
8890
|
+
if the wait is not honored before fail_at,
|
8891
|
+
the wait will be cancelled and the
|
8892
|
+
parameter failed will be set.
|
8893
|
+
|
8894
|
+
if not specified, the wait will not time out.
|
8895
|
+
|
8896
|
+
if distribution, the distribution is sampled
|
8897
|
+
|
8898
|
+
fail_delay : float or distribution
|
8899
|
+
time out
|
8900
|
+
|
8901
|
+
if the wait is not honored before now+fail_delay,
|
8902
|
+
the request will be cancelled and the
|
8903
|
+
parameter failed will be set.
|
8904
|
+
|
8905
|
+
if not specified, the wait will not time out.
|
8906
|
+
|
8907
|
+
if distribution, the distribution is sampled
|
8908
|
+
|
8909
|
+
mode : str preferred
|
8910
|
+
mode
|
8911
|
+
|
8912
|
+
will be used in trace and can be used in animations
|
8913
|
+
|
8914
|
+
if nothing specified, the mode will be unchanged.
|
8915
|
+
|
8916
|
+
also mode_time will be set to now, if mode is set.
|
8917
|
+
|
8918
|
+
cap_now : bool
|
8919
|
+
indicator whether times (fail_at, fail_duration) in the past are allowed. If, so now() will be used.
|
8920
|
+
default: sys.default_cap_now(), usualy False
|
8921
|
+
|
8922
|
+
Note
|
8923
|
+
----
|
8924
|
+
Not allowed for data components or main.
|
8925
|
+
|
8926
|
+
Only if yieldless is False: If to be used for the current component
|
8927
|
+
(which will be nearly always the case),
|
8928
|
+
use ``yield self.wait(...)``.
|
8929
|
+
|
8930
|
+
"""
|
8931
|
+
if self.status.value != current:
|
8932
|
+
self._checkisnotdata()
|
8933
|
+
self._checkisnotmain()
|
8934
|
+
self._remove()
|
8935
|
+
self._check_fail()
|
8936
|
+
|
8937
|
+
self._failed = False
|
8938
|
+
|
8939
|
+
if fail_at is None:
|
8940
|
+
if fail_delay is None:
|
8941
|
+
scheduled_time = inf
|
8942
|
+
else:
|
8943
|
+
if fail_delay == inf:
|
8944
|
+
scheduled_time = inf
|
8945
|
+
else:
|
8946
|
+
fail_delay = self.env.spec_to_duration(fail_delay)
|
8947
|
+
scheduled_time = self.env._now + fail_delay
|
8948
|
+
else:
|
8949
|
+
if fail_delay is None:
|
8950
|
+
fail_at = self.env.spec_to_time(fail_at)
|
8951
|
+
scheduled_time = fail_at + self.env._offset
|
8952
|
+
else:
|
8953
|
+
raise ValueError("both fail_at and fail_delay specified")
|
8954
|
+
|
8955
|
+
self.set_mode(mode)
|
8956
|
+
|
8957
|
+
self._cond=cond # add test ***
|
8958
|
+
for state in states:
|
8959
|
+
self._waits.append((state, None,None))
|
8960
|
+
if priority is None:
|
8961
|
+
self.enter(state._waiters)
|
8962
|
+
else:
|
8963
|
+
self.enter_sorted(state._waiters, priority)
|
8964
|
+
|
8965
|
+
if not self._waits:
|
8966
|
+
raise TypeError("no states specified")
|
8967
|
+
|
8968
|
+
self._remaining_duration = scheduled_time - self.env._now
|
8969
|
+
|
8970
|
+
self._trywait()
|
8971
|
+
|
8972
|
+
if self._waits:
|
8973
|
+
self.status._value = waiting
|
8974
|
+
self._reschedule(scheduled_time, schedule_priority, urgent, "wait_for", cap_now)
|
8975
|
+
else:
|
8976
|
+
return
|
8977
|
+
|
8978
|
+
|
8979
|
+
|
8832
8980
|
def wait(self, *args, **kwargs) -> None:
|
8833
8981
|
"""
|
8834
8982
|
wait for any or all of the given state values are met
|
@@ -8978,6 +9126,8 @@ by adding:
|
|
8978
9126
|
schedule_priority = kwargs.pop("priority", 0)
|
8979
9127
|
cap_now = kwargs.pop("cap_now", None)
|
8980
9128
|
|
9129
|
+
self._cond=None
|
9130
|
+
|
8981
9131
|
if kwargs:
|
8982
9132
|
raise TypeError("wait() got an unexpected keyword argument '" + tuple(kwargs)[0] + "'")
|
8983
9133
|
|
@@ -9055,39 +9205,43 @@ by adding:
|
|
9055
9205
|
return
|
9056
9206
|
|
9057
9207
|
def _trywait(self):
|
9208
|
+
|
9058
9209
|
if self.status.value == interrupted:
|
9059
9210
|
return False
|
9060
|
-
if self.
|
9061
|
-
honored =
|
9062
|
-
for state, value, valuetype in self._waits:
|
9063
|
-
if valuetype == 0:
|
9064
|
-
if value != state._value:
|
9065
|
-
honored = False
|
9066
|
-
break
|
9067
|
-
elif valuetype == 1:
|
9068
|
-
if not eval(value.replace("$", "state._value")):
|
9069
|
-
honored = False
|
9070
|
-
break
|
9071
|
-
elif valuetype == 2:
|
9072
|
-
if not value(state._value, self, state):
|
9073
|
-
honored = False
|
9074
|
-
break
|
9075
|
-
|
9211
|
+
if self._cond:
|
9212
|
+
honored = self._cond()
|
9076
9213
|
else:
|
9077
|
-
|
9078
|
-
|
9079
|
-
|
9080
|
-
if
|
9081
|
-
|
9082
|
-
|
9083
|
-
|
9084
|
-
|
9085
|
-
|
9086
|
-
|
9087
|
-
|
9088
|
-
|
9089
|
-
|
9090
|
-
|
9214
|
+
if self._wait_all:
|
9215
|
+
honored = True
|
9216
|
+
for state, value, valuetype in self._waits:
|
9217
|
+
if valuetype == 0:
|
9218
|
+
if value != state._value:
|
9219
|
+
honored = False
|
9220
|
+
break
|
9221
|
+
elif valuetype == 1:
|
9222
|
+
if not eval(value.replace("$", "state._value")):
|
9223
|
+
honored = False
|
9224
|
+
break
|
9225
|
+
elif valuetype == 2:
|
9226
|
+
if not value(state._value, self, state):
|
9227
|
+
honored = False
|
9228
|
+
break
|
9229
|
+
|
9230
|
+
else:
|
9231
|
+
honored = False
|
9232
|
+
for state, value, valuetype in self._waits:
|
9233
|
+
if valuetype == 0:
|
9234
|
+
if value == state._value:
|
9235
|
+
honored = True
|
9236
|
+
break
|
9237
|
+
elif valuetype == 1:
|
9238
|
+
if eval(value.replace("$", str(state._value))):
|
9239
|
+
honored = True
|
9240
|
+
break
|
9241
|
+
elif valuetype == 2:
|
9242
|
+
if value(state._value, self, state):
|
9243
|
+
honored = True
|
9244
|
+
break
|
9091
9245
|
|
9092
9246
|
if honored:
|
9093
9247
|
for s, _, _ in self._waits:
|
@@ -15004,7 +15158,7 @@ class Environment:
|
|
15004
15158
|
self.pause_at = inf
|
15005
15159
|
|
15006
15160
|
if self.pause_at is None:
|
15007
|
-
sg.popup(
|
15161
|
+
sg.popup("Pause not valid")
|
15008
15162
|
else:
|
15009
15163
|
if "-PAUSE-EACH-" in self._ui_keys:
|
15010
15164
|
pause_each_str = values["-PAUSE-EACH-"]
|
@@ -15023,7 +15177,7 @@ class Environment:
|
|
15023
15177
|
self.pause_at = None
|
15024
15178
|
|
15025
15179
|
if self.pause_at is None:
|
15026
|
-
sg.popup(
|
15180
|
+
sg.popup("Pause interval not valid")
|
15027
15181
|
else:
|
15028
15182
|
if self.pause_at > self.t() * 0.99999999:
|
15029
15183
|
if "-ANIMATE-" in self._ui_keys:
|
@@ -23508,7 +23662,7 @@ class State:
|
|
23508
23662
|
self.value.tally(value_after)
|
23509
23663
|
self._trywait()
|
23510
23664
|
|
23511
|
-
def _trywait(self, max=inf):
|
23665
|
+
def _trywait(self, max=inf): # this _trywait of a state
|
23512
23666
|
mx = self._waiters._head.successor
|
23513
23667
|
while mx != self._waiters._tail:
|
23514
23668
|
c = mx.component
|
@@ -26976,8 +27130,6 @@ def getfont(fontname, fontsize):
|
|
26976
27130
|
return getfont.lookup[(fontname, fontsize)]
|
26977
27131
|
else:
|
26978
27132
|
getfont.lookup = {}
|
26979
|
-
if fontname == "":
|
26980
|
-
a = 1
|
26981
27133
|
if isinstance(fontname, str):
|
26982
27134
|
fontlist1 = [fontname]
|
26983
27135
|
else:
|
@@ -3,8 +3,8 @@ salabim/LICENSE.txt,sha256=qHlBa-POyexatCxDTjSKMlYtkBFQDn9lu-YV_1L6V0U,1106
|
|
3
3
|
salabim/__init__.py,sha256=r7qPLvlmX0dkZDyjuTo8Jo3ex3sD1L4pmK6K5ib9vyw,56
|
4
4
|
salabim/calibri.ttf,sha256=RWpf8Uo31RfvGGNaSt9-2sXSuN87AVE_NFMRsV3LhBk,1330156
|
5
5
|
salabim/mplus-1m-regular.ttf,sha256=EuFHr90BJjuAn_r5MleJFN-WfkeWJ4tf7DweI5zr8tU,289812
|
6
|
-
salabim/salabim.py,sha256
|
7
|
-
salabim-24.0.
|
8
|
-
salabim-24.0.
|
9
|
-
salabim-24.0.
|
10
|
-
salabim-24.0.
|
6
|
+
salabim/salabim.py,sha256=Ic3A6isSW-Ybu3nvB8judAXxfqp9mh1iCYBx-ACKBPY,1120439
|
7
|
+
salabim-24.0.18.dist-info/METADATA,sha256=oVc1cFiKv3eqzVQbIH78pnnMu1afHe1S2K-glVtqnyU,3458
|
8
|
+
salabim-24.0.18.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
9
|
+
salabim-24.0.18.dist-info/top_level.txt,sha256=UE6zVlbi3F6T5ma1a_5TrojMaF21GYKDt9svvm0U4cQ,8
|
10
|
+
salabim-24.0.18.dist-info/RECORD,,
|
File without changes
|