salabim 24.0.17__py3-none-any.whl → 24.0.18__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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
|