salabim 24.0.16__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 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.16"
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._wait_all:
9062
- honored = True
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
- honored = False
9079
- for state, value, valuetype in self._waits:
9080
- if valuetype == 0:
9081
- if value == state._value:
9082
- honored = True
9083
- break
9084
- elif valuetype == 1:
9085
- if eval(value.replace("$", str(state._value))):
9086
- honored = True
9087
- break
9088
- elif valuetype == 2:
9089
- if value(state._value, self, state):
9090
- honored = True
9091
- 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
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(f"Pause not valid")
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(f"Pause interval not valid")
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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: salabim
3
- Version: 24.0.16
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=VwDD1blpoFir2EYTfcAt0_EGuvwDnbup3RcNyc7v7hI,1115673
7
- salabim-24.0.16.dist-info/METADATA,sha256=FY3hDeBvxppeETZEjWRUerghxNtRYadYrCElZjy-dD0,3458
8
- salabim-24.0.16.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
9
- salabim-24.0.16.dist-info/top_level.txt,sha256=UE6zVlbi3F6T5ma1a_5TrojMaF21GYKDt9svvm0U4cQ,8
10
- salabim-24.0.16.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