salabim 25.0.10__tar.gz → 25.0.11__tar.gz
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-25.0.10 → salabim-25.0.11}/PKG-INFO +1 -1
- {salabim-25.0.10 → salabim-25.0.11}/pyproject.toml +1 -1
- {salabim-25.0.10 → salabim-25.0.11}/salabim/salabim.py +67 -31
- {salabim-25.0.10 → salabim-25.0.11}/salabim.egg-info/PKG-INFO +1 -1
- {salabim-25.0.10 → salabim-25.0.11}/README.md +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/salabim/DejaVuSansMono.ttf +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/salabim/LICENSE.txt +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/salabim/__init__.py +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/salabim/calibri.ttf +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/salabim/mplus-1m-regular.ttf +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/salabim.egg-info/SOURCES.txt +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/salabim.egg-info/dependency_links.txt +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/salabim.egg-info/top_level.txt +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/setup.cfg +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/tests/test salabim.py +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/tests/test_cap_now.py +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/tests/test_componentgenerator.py +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/tests/test_datetime.py +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/tests/test_distributions.py +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/tests/test_misc.py +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/tests/test_monitor.py +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/tests/test_process.py +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/tests/test_queue.py +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/tests/test_state.py +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/tests/test_store.py +0 -0
- {salabim-25.0.10 → salabim-25.0.11}/tests/test_timeunit.py +0 -0
@@ -10,7 +10,7 @@ authors = [
|
|
10
10
|
{ name = "Ruud van der Ham", email = "rt.van.der.ham@gmail.com" },
|
11
11
|
]
|
12
12
|
description = "salabim - discrete event simulation in Python"
|
13
|
-
version = "25.0.
|
13
|
+
version = "25.0.11"
|
14
14
|
readme = "README.md"
|
15
15
|
requires-python = ">=3.7"
|
16
16
|
dependencies = []
|
@@ -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__ = "25.0.
|
10
|
+
__version__ = "25.0.11"
|
11
11
|
import heapq
|
12
12
|
import random
|
13
13
|
import time
|
@@ -2890,6 +2890,14 @@ class Monitor:
|
|
2890
2890
|
|
2891
2891
|
if False (default), the normal 2D plane will be used.
|
2892
2892
|
|
2893
|
+
screen_coordinates : bool
|
2894
|
+
use screen_coordinates
|
2895
|
+
|
2896
|
+
if True (default), screen_coordinates will be used instead.
|
2897
|
+
|
2898
|
+
if False, all parameters are scaled for positioning and scaling
|
2899
|
+
objects.
|
2900
|
+
|
2893
2901
|
Returns
|
2894
2902
|
-------
|
2895
2903
|
reference to AnimateMonitor object : AnimateMonitor
|
@@ -3663,6 +3671,14 @@ class AnimateMonitor(DynamicClass):
|
|
3663
3671
|
if False, animation monitor is not shown, shown otherwise
|
3664
3672
|
(default True)
|
3665
3673
|
|
3674
|
+
screen_coordinates : bool
|
3675
|
+
use screen_coordinates
|
3676
|
+
|
3677
|
+
if True (default), screen_coordinates will be used instead.
|
3678
|
+
|
3679
|
+
if False, all parameters are scaled for positioning and scaling
|
3680
|
+
objects.
|
3681
|
+
|
3666
3682
|
Note
|
3667
3683
|
----
|
3668
3684
|
All measures are in screen coordinates
|
@@ -3707,6 +3723,7 @@ class AnimateMonitor(DynamicClass):
|
|
3707
3723
|
as_points: bool = None,
|
3708
3724
|
over3d: bool = None,
|
3709
3725
|
layer: Union[float, Callable] = 0,
|
3726
|
+
screen_coordinates=True,
|
3710
3727
|
visible: Union[bool, Callable] = True,
|
3711
3728
|
keep: Union[bool, Callable] = True,
|
3712
3729
|
arg: Any = None,
|
@@ -3767,7 +3784,7 @@ class AnimateMonitor(DynamicClass):
|
|
3767
3784
|
self._monitor = monitor
|
3768
3785
|
self.as_level = monitor._level
|
3769
3786
|
self.over3d = over3d
|
3770
|
-
self.screen_coordinates =
|
3787
|
+
self.screen_coordinates = screen_coordinates
|
3771
3788
|
self.register_dynamic_attributes(
|
3772
3789
|
"linecolor linewidth fillcolor bordercolor borderlinewidth titlecolor nowcolor titlefont titlefontsize title "
|
3773
3790
|
"x y offsetx offsety angle vertical_offset parent vertical_scale horizontal_scale width height "
|
@@ -4388,6 +4405,14 @@ class Queue:
|
|
4388
4405
|
|
4389
4406
|
default: self (instance itself)
|
4390
4407
|
|
4408
|
+
screen_coordinates : bool
|
4409
|
+
use screen_coordinates
|
4410
|
+
|
4411
|
+
if True (default), screen_coordinates will be used instead.
|
4412
|
+
|
4413
|
+
if False, all parameters are scaled for positioning and scaling
|
4414
|
+
objects.
|
4415
|
+
|
4391
4416
|
Returns
|
4392
4417
|
-------
|
4393
4418
|
reference to AnimationQueue object : AnimationQueue
|
@@ -7196,7 +7221,7 @@ by adding at the end:
|
|
7196
7221
|
|
7197
7222
|
overridden_lineno = None
|
7198
7223
|
|
7199
|
-
def animation_objects(self, id: Any) -> Tuple:
|
7224
|
+
def animation_objects(self, id: Any, screen_coordinates: bool = True) -> Tuple:
|
7200
7225
|
"""
|
7201
7226
|
defines how to display a component in AnimateQueue
|
7202
7227
|
|
@@ -7226,7 +7251,9 @@ by adding at the end:
|
|
7226
7251
|
"""
|
7227
7252
|
size_x = 50
|
7228
7253
|
size_y = 50
|
7229
|
-
ao0 = AnimateRectangle(
|
7254
|
+
ao0 = AnimateRectangle(
|
7255
|
+
text=str(self.sequence_number()), textcolor="bg", spec=(-20, -20, 20, 20), linewidth=0, fillcolor="fg", screen_coordinates=screen_coordinates
|
7256
|
+
)
|
7230
7257
|
return (size_x, size_y, ao0)
|
7231
7258
|
|
7232
7259
|
def animation3d_objects(self, id: Any) -> Tuple:
|
@@ -10738,7 +10765,8 @@ class Environment:
|
|
10738
10765
|
self._x1 = self._x1_org
|
10739
10766
|
self._y0 = self._y0_org
|
10740
10767
|
self._y1 = self._y1_org
|
10741
|
-
self._scale = self.
|
10768
|
+
self._scale = self._scale_org
|
10769
|
+
self._last_scalez = self._scalez
|
10742
10770
|
|
10743
10771
|
def animation_pre_tick_sys(self, t: float) -> None:
|
10744
10772
|
for ao in self.sys_objects.copy(): # copy required as ao's may be removed due to keep
|
@@ -11263,7 +11291,6 @@ class Environment:
|
|
11263
11291
|
def on_closing(self):
|
11264
11292
|
self.an_quit()
|
11265
11293
|
|
11266
|
-
|
11267
11294
|
def on_mousewheel(self, event):
|
11268
11295
|
x_mouse = self.root.winfo_pointerx() - self.root.winfo_rootx()
|
11269
11296
|
y_mouse = self.height() - self.root.winfo_pointery() + self.root.winfo_rooty()
|
@@ -11308,14 +11335,13 @@ class Environment:
|
|
11308
11335
|
|
11309
11336
|
def do_pan(self, event):
|
11310
11337
|
dx = -((event.x - self.lastx) / self._scale)
|
11311
|
-
dy = (
|
11338
|
+
dy = (event.y - self.lasty) / self._scale
|
11312
11339
|
# self._x0z = max(self._x0,self.lastx0 + dx)
|
11313
11340
|
# self._y0z = max(self._y0,self.lasty0 + dy)
|
11314
11341
|
self._x0z = self.lastx0 + dx
|
11315
|
-
self._y0z = self.lasty0 + dy
|
11316
|
-
self._x1z = self._x0z + (self._x1 - self._x0)
|
11317
|
-
self._y1z = self._y0z + (self._y1 - self._y0)
|
11318
|
-
|
11342
|
+
self._y0z = self.lasty0 + dy
|
11343
|
+
self._x1z = self._x0z + (self._x1 - self._x0)
|
11344
|
+
self._y1z = self._y0z + (self._y1 - self._y0)
|
11319
11345
|
|
11320
11346
|
def end_pan(self, event):
|
11321
11347
|
g.canvas.config(cursor="") # Reset to default
|
@@ -11927,13 +11953,12 @@ class Environment:
|
|
11927
11953
|
self.root.bind("<B1-Motion>", self.do_pan)
|
11928
11954
|
self.root.bind("<ButtonRelease-1>", self.end_pan)
|
11929
11955
|
|
11930
|
-
|
11931
11956
|
g.canvas = tkinter.Canvas(self.root, width=self._width, height=self._height)
|
11932
11957
|
g.canvas.configure(background=self.colorspec_to_hex("bg", False))
|
11933
11958
|
g.canvas.pack()
|
11934
11959
|
g.canvas_objects = []
|
11935
11960
|
g.canvas_object_overflow_image = None
|
11936
|
-
|
11961
|
+
|
11937
11962
|
# g.canvas.move("all", 1, 1)
|
11938
11963
|
# g.canvas.update()
|
11939
11964
|
# g.canvas.move("all", -1, -1)
|
@@ -13400,7 +13425,7 @@ class Environment:
|
|
13400
13425
|
self._x1z = self._x1
|
13401
13426
|
self._y1z = self._y1
|
13402
13427
|
|
13403
|
-
self._scalez = self._scale
|
13428
|
+
self._scalez = self._last_scalez = self._scale
|
13404
13429
|
self.root.mainloop()
|
13405
13430
|
if self._animate and self.running:
|
13406
13431
|
if self._video:
|
@@ -18212,6 +18237,7 @@ class AnimateQueue(DynamicClass):
|
|
18212
18237
|
over3d=None,
|
18213
18238
|
keep=True,
|
18214
18239
|
visible=True,
|
18240
|
+
screen_coordinates=True,
|
18215
18241
|
):
|
18216
18242
|
super().__init__()
|
18217
18243
|
_checkisqueue(queue)
|
@@ -18242,7 +18268,7 @@ class AnimateQueue(DynamicClass):
|
|
18242
18268
|
self.keep = keep
|
18243
18269
|
self.over3d = _default_over3d if over3d is None else over3d
|
18244
18270
|
self.trajectory = trajectory
|
18245
|
-
self.screen_coordinates =
|
18271
|
+
self.screen_coordinates = screen_coordinates
|
18246
18272
|
self.register_dynamic_attributes(
|
18247
18273
|
"xy_anchor x y id max_length direction reverse titleoffsetx titleoffsety titlefont titlefontsize titlecolor title layer visible keep trajectory"
|
18248
18274
|
)
|
@@ -18267,6 +18293,7 @@ class AnimateQueue(DynamicClass):
|
|
18267
18293
|
if not self.keep(t):
|
18268
18294
|
self.remove()
|
18269
18295
|
return
|
18296
|
+
screen_coordinates = self.screen_coordinates
|
18270
18297
|
prev_aos = self.current_aos
|
18271
18298
|
self.current_aos = {}
|
18272
18299
|
xy_anchor = self.xy_anchor(t)
|
@@ -18288,8 +18315,8 @@ class AnimateQueue(DynamicClass):
|
|
18288
18315
|
titleoffsetx = self.titleoffsetx(t)
|
18289
18316
|
titleoffsety = self.titleoffsety(t)
|
18290
18317
|
|
18291
|
-
x += self._queue.env.xy_anchor_to_x(xy_anchor, screen_coordinates=
|
18292
|
-
y += self._queue.env.xy_anchor_to_y(xy_anchor, screen_coordinates=
|
18318
|
+
x += self._queue.env.xy_anchor_to_x(xy_anchor, screen_coordinates=screen_coordinates, over3d=self.over3d)
|
18319
|
+
y += self._queue.env.xy_anchor_to_y(xy_anchor, screen_coordinates=screen_coordinates, over3d=self.over3d)
|
18293
18320
|
|
18294
18321
|
if direction == "e":
|
18295
18322
|
self.x_t = x + (-25 if titleoffsetx is None else titleoffsetx)
|
@@ -18321,20 +18348,21 @@ class AnimateQueue(DynamicClass):
|
|
18321
18348
|
if ((max_length is not None) and n >= max_length) or not self.visible_t:
|
18322
18349
|
break
|
18323
18350
|
|
18324
|
-
if c
|
18325
|
-
nargs = c.animation_objects.__code__.co_argcount
|
18326
|
-
if nargs == 1:
|
18327
|
-
animation_objects = self.current_aos[c] = c.animation_objects()
|
18328
|
-
else:
|
18329
|
-
animation_objects = self.current_aos[c] = c.animation_objects(self.id(t))
|
18330
|
-
else:
|
18351
|
+
if c in prev_aos and self.env._scalez != self.env._last_scalez: # if scale changed (due to zooming), rerender the animation_objects
|
18331
18352
|
animation_objects = self.current_aos[c] = prev_aos[c]
|
18332
18353
|
del prev_aos[c]
|
18354
|
+
else:
|
18355
|
+
parameters = inspect.signature(c.animation_objects).parameters
|
18356
|
+
kwargs = {}
|
18357
|
+
if "id" in parameters:
|
18358
|
+
kwargs["id"] = self.id(t)
|
18359
|
+
if "screen_coordinates" in parameters:
|
18360
|
+
kwargs["screen_coordinates"] = self.screen_coordinates
|
18361
|
+
animation_objects = self.current_aos[c] = c.animation_objects(**kwargs)
|
18333
18362
|
|
18334
18363
|
dimx = _call(animation_objects[0], t, c)
|
18335
18364
|
dimy = _call(animation_objects[1], t, c)
|
18336
18365
|
for ao in animation_objects[2:]:
|
18337
|
-
ao.screen_coordinates = self.screen_coordinates
|
18338
18366
|
if isinstance(ao, AnimateClassic):
|
18339
18367
|
if direction == "t":
|
18340
18368
|
ao.x0 = xt + trajectory.x(t=x * 1.00, _t0=0)
|
@@ -18460,9 +18488,17 @@ class Animate3dQueue(DynamicClass):
|
|
18460
18488
|
if given, the animation object will be removed
|
18461
18489
|
automatically when the parent component is no longer accessible
|
18462
18490
|
|
18491
|
+
screen_coordinates : bool
|
18492
|
+
use screen_coordinates
|
18493
|
+
|
18494
|
+
if True (default), screen_coordinates will be used instead.
|
18495
|
+
|
18496
|
+
if False, all parameters are scaled for positioning and scaling
|
18497
|
+
objects.
|
18498
|
+
|
18463
18499
|
Note
|
18464
18500
|
----
|
18465
|
-
All parameters, apart from queue, id, arg and parent can be specified as:
|
18501
|
+
All parameters, apart from queue, id, arg, screen_coordinates and parent can be specified as:
|
18466
18502
|
|
18467
18503
|
- a scalar, like 10
|
18468
18504
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|