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 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.17"
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._wait_all:
9061
- honored = True
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
- honored = False
9078
- for state, value, valuetype in self._waits:
9079
- if valuetype == 0:
9080
- if value == state._value:
9081
- honored = True
9082
- break
9083
- elif valuetype == 1:
9084
- if eval(value.replace("$", str(state._value))):
9085
- honored = True
9086
- break
9087
- elif valuetype == 2:
9088
- if value(state._value, self, state):
9089
- honored = True
9090
- break
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(f"Pause not valid")
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(f"Pause interval not valid")
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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: salabim
3
- Version: 24.0.17
3
+ Version: 24.0.18
4
4
  Summary: salabim - discrete event simulation in Python
5
5
  Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
6
6
  Project-URL: Homepage, https://salabim.org
@@ -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=-u4nEmv4kHg0im9ZC_yL31bvXNBuJNWFLuBf_FYhCpE,1115641
7
- salabim-24.0.17.dist-info/METADATA,sha256=1ZtRaop2jcG8-kTv1-viuasV_UnkXuT46PuvMG6uGDs,3458
8
- salabim-24.0.17.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
9
- salabim-24.0.17.dist-info/top_level.txt,sha256=UE6zVlbi3F6T5ma1a_5TrojMaF21GYKDt9svvm0U4cQ,8
10
- salabim-24.0.17.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.5.0)
2
+ Generator: setuptools (75.6.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5