salabim 24.0.16__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 +192 -41
- {salabim-24.0.16.dist-info → salabim-24.0.18.dist-info}/METADATA +1 -1
- {salabim-24.0.16.dist-info → salabim-24.0.18.dist-info}/RECORD +5 -5
- {salabim-24.0.16.dist-info → salabim-24.0.18.dist-info}/WHEEL +1 -1
- {salabim-24.0.16.dist-info → salabim-24.0.18.dist-info}/top_level.txt +0 -0
salabim/salabim.py
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
# _ _ _ ____ _ _ ___ _
|
2
|
-
# ___ __ _ | | __ _ | |__ (_) _ __ ___ |___ \ | || | / _ \ / |
|
3
|
-
# / __| / _` || | / _` || '_ \ | || '_ ` _ \ __) || || |_ | | | | |
|
1
|
+
# _ _ _ ____ _ _ ___ _ ___
|
2
|
+
# ___ __ _ | | __ _ | |__ (_) _ __ ___ |___ \ | || | / _ \ / | ( _ )
|
3
|
+
# / __| / _` || | / _` || '_ \ | || '_ ` _ \ __) || || |_ | | | | | | / _ \
|
4
4
|
# \__ \| (_| || || (_| || |_) || || | | | | | / __/ |__ _| _ | |_| | _ | || (_) |
|
5
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
|
@@ -7956,7 +7979,6 @@ by adding:
|
|
7956
7979
|
lineno = self.lineno_txt(add_at=True)
|
7957
7980
|
self.env.print_trace("", "", self.name() + " resume (" + self.status() + ")", merge_blanks(lineno, self._modetxt()))
|
7958
7981
|
if self.status.value == scheduled:
|
7959
|
-
reason = "hold"
|
7960
7982
|
self._reschedule(self.env._now + self._remaining_duration, priority, urgent, "hold", False)
|
7961
7983
|
else:
|
7962
7984
|
raise Exception(self.name() + " unexpected interrupted_status", self.status.value())
|
@@ -8830,6 +8852,131 @@ by adding:
|
|
8830
8852
|
for r in list(self._claims):
|
8831
8853
|
self._release(r)
|
8832
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
|
+
|
8833
8980
|
def wait(self, *args, **kwargs) -> None:
|
8834
8981
|
"""
|
8835
8982
|
wait for any or all of the given state values are met
|
@@ -8979,6 +9126,8 @@ by adding:
|
|
8979
9126
|
schedule_priority = kwargs.pop("priority", 0)
|
8980
9127
|
cap_now = kwargs.pop("cap_now", None)
|
8981
9128
|
|
9129
|
+
self._cond=None
|
9130
|
+
|
8982
9131
|
if kwargs:
|
8983
9132
|
raise TypeError("wait() got an unexpected keyword argument '" + tuple(kwargs)[0] + "'")
|
8984
9133
|
|
@@ -9056,39 +9205,43 @@ by adding:
|
|
9056
9205
|
return
|
9057
9206
|
|
9058
9207
|
def _trywait(self):
|
9208
|
+
|
9059
9209
|
if self.status.value == interrupted:
|
9060
9210
|
return False
|
9061
|
-
if self.
|
9062
|
-
honored =
|
9063
|
-
for state, value, valuetype in self._waits:
|
9064
|
-
if valuetype == 0:
|
9065
|
-
if value != state._value:
|
9066
|
-
honored = False
|
9067
|
-
break
|
9068
|
-
elif valuetype == 1:
|
9069
|
-
if eval(value.replace("$", "state._value")):
|
9070
|
-
honored = False
|
9071
|
-
break
|
9072
|
-
elif valuetype == 2:
|
9073
|
-
if not value(state._value, self, state):
|
9074
|
-
honored = False
|
9075
|
-
break
|
9076
|
-
|
9211
|
+
if self._cond:
|
9212
|
+
honored = self._cond()
|
9077
9213
|
else:
|
9078
|
-
|
9079
|
-
|
9080
|
-
|
9081
|
-
if
|
9082
|
-
|
9083
|
-
|
9084
|
-
|
9085
|
-
|
9086
|
-
|
9087
|
-
|
9088
|
-
|
9089
|
-
|
9090
|
-
|
9091
|
-
|
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
|
9092
9245
|
|
9093
9246
|
if honored:
|
9094
9247
|
for s, _, _ in self._waits:
|
@@ -15005,7 +15158,7 @@ class Environment:
|
|
15005
15158
|
self.pause_at = inf
|
15006
15159
|
|
15007
15160
|
if self.pause_at is None:
|
15008
|
-
sg.popup(
|
15161
|
+
sg.popup("Pause not valid")
|
15009
15162
|
else:
|
15010
15163
|
if "-PAUSE-EACH-" in self._ui_keys:
|
15011
15164
|
pause_each_str = values["-PAUSE-EACH-"]
|
@@ -15024,7 +15177,7 @@ class Environment:
|
|
15024
15177
|
self.pause_at = None
|
15025
15178
|
|
15026
15179
|
if self.pause_at is None:
|
15027
|
-
sg.popup(
|
15180
|
+
sg.popup("Pause interval not valid")
|
15028
15181
|
else:
|
15029
15182
|
if self.pause_at > self.t() * 0.99999999:
|
15030
15183
|
if "-ANIMATE-" in self._ui_keys:
|
@@ -23509,7 +23662,7 @@ class State:
|
|
23509
23662
|
self.value.tally(value_after)
|
23510
23663
|
self._trywait()
|
23511
23664
|
|
23512
|
-
def _trywait(self, max=inf):
|
23665
|
+
def _trywait(self, max=inf): # this _trywait of a state
|
23513
23666
|
mx = self._waiters._head.successor
|
23514
23667
|
while mx != self._waiters._tail:
|
23515
23668
|
c = mx.component
|
@@ -26977,8 +27130,6 @@ def getfont(fontname, fontsize):
|
|
26977
27130
|
return getfont.lookup[(fontname, fontsize)]
|
26978
27131
|
else:
|
26979
27132
|
getfont.lookup = {}
|
26980
|
-
if fontname == "":
|
26981
|
-
a = 1
|
26982
27133
|
if isinstance(fontname, str):
|
26983
27134
|
fontlist1 = [fontname]
|
26984
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
|