salabim 25.0.10__tar.gz → 25.0.12__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.12}/PKG-INFO +1 -1
- {salabim-25.0.10 → salabim-25.0.12}/pyproject.toml +1 -1
- {salabim-25.0.10 → salabim-25.0.12}/salabim/salabim.py +72 -35
- {salabim-25.0.10 → salabim-25.0.12}/salabim.egg-info/PKG-INFO +1 -1
- {salabim-25.0.10 → salabim-25.0.12}/README.md +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/salabim/DejaVuSansMono.ttf +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/salabim/LICENSE.txt +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/salabim/__init__.py +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/salabim/calibri.ttf +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/salabim/mplus-1m-regular.ttf +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/salabim.egg-info/SOURCES.txt +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/salabim.egg-info/dependency_links.txt +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/salabim.egg-info/top_level.txt +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/setup.cfg +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/tests/test salabim.py +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/tests/test_cap_now.py +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/tests/test_componentgenerator.py +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/tests/test_datetime.py +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/tests/test_distributions.py +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/tests/test_misc.py +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/tests/test_monitor.py +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/tests/test_process.py +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/tests/test_queue.py +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/tests/test_state.py +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/tests/test_store.py +0 -0
- {salabim-25.0.10 → salabim-25.0.12}/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.12"
|
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.12"
|
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)
|
@@ -13385,6 +13410,12 @@ class Environment:
|
|
13385
13410
|
self.step()
|
13386
13411
|
|
13387
13412
|
def do_simulate_and_animate(self):
|
13413
|
+
self._x0z = self._x0
|
13414
|
+
self._y0z = self._y0
|
13415
|
+
self._x1z = self._x1
|
13416
|
+
self._y1z = self._y1
|
13417
|
+
self._scalez = self._last_scalez = self._scale
|
13418
|
+
|
13388
13419
|
if Pythonista:
|
13389
13420
|
if self._animate3d:
|
13390
13421
|
self.running = False
|
@@ -13395,12 +13426,7 @@ class Environment:
|
|
13395
13426
|
raise SimulationStopped
|
13396
13427
|
else:
|
13397
13428
|
self.root.after(0, self.simulate_and_animate_loop)
|
13398
|
-
self._x0z = self._x0
|
13399
|
-
self._y0z = self._y0
|
13400
|
-
self._x1z = self._x1
|
13401
|
-
self._y1z = self._y1
|
13402
13429
|
|
13403
|
-
self._scalez = self._scale
|
13404
13430
|
self.root.mainloop()
|
13405
13431
|
if self._animate and self.running:
|
13406
13432
|
if self._video:
|
@@ -18212,6 +18238,7 @@ class AnimateQueue(DynamicClass):
|
|
18212
18238
|
over3d=None,
|
18213
18239
|
keep=True,
|
18214
18240
|
visible=True,
|
18241
|
+
screen_coordinates=True,
|
18215
18242
|
):
|
18216
18243
|
super().__init__()
|
18217
18244
|
_checkisqueue(queue)
|
@@ -18242,7 +18269,7 @@ class AnimateQueue(DynamicClass):
|
|
18242
18269
|
self.keep = keep
|
18243
18270
|
self.over3d = _default_over3d if over3d is None else over3d
|
18244
18271
|
self.trajectory = trajectory
|
18245
|
-
self.screen_coordinates =
|
18272
|
+
self.screen_coordinates = screen_coordinates
|
18246
18273
|
self.register_dynamic_attributes(
|
18247
18274
|
"xy_anchor x y id max_length direction reverse titleoffsetx titleoffsety titlefont titlefontsize titlecolor title layer visible keep trajectory"
|
18248
18275
|
)
|
@@ -18267,6 +18294,7 @@ class AnimateQueue(DynamicClass):
|
|
18267
18294
|
if not self.keep(t):
|
18268
18295
|
self.remove()
|
18269
18296
|
return
|
18297
|
+
screen_coordinates = self.screen_coordinates
|
18270
18298
|
prev_aos = self.current_aos
|
18271
18299
|
self.current_aos = {}
|
18272
18300
|
xy_anchor = self.xy_anchor(t)
|
@@ -18288,8 +18316,8 @@ class AnimateQueue(DynamicClass):
|
|
18288
18316
|
titleoffsetx = self.titleoffsetx(t)
|
18289
18317
|
titleoffsety = self.titleoffsety(t)
|
18290
18318
|
|
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=
|
18319
|
+
x += self._queue.env.xy_anchor_to_x(xy_anchor, screen_coordinates=screen_coordinates, over3d=self.over3d)
|
18320
|
+
y += self._queue.env.xy_anchor_to_y(xy_anchor, screen_coordinates=screen_coordinates, over3d=self.over3d)
|
18293
18321
|
|
18294
18322
|
if direction == "e":
|
18295
18323
|
self.x_t = x + (-25 if titleoffsetx is None else titleoffsetx)
|
@@ -18321,20 +18349,21 @@ class AnimateQueue(DynamicClass):
|
|
18321
18349
|
if ((max_length is not None) and n >= max_length) or not self.visible_t:
|
18322
18350
|
break
|
18323
18351
|
|
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:
|
18352
|
+
if c in prev_aos and self.env._scalez != self.env._last_scalez: # if scale changed (due to zooming), rerender the animation_objects
|
18331
18353
|
animation_objects = self.current_aos[c] = prev_aos[c]
|
18332
18354
|
del prev_aos[c]
|
18355
|
+
else:
|
18356
|
+
parameters = inspect.signature(c.animation_objects).parameters
|
18357
|
+
kwargs = {}
|
18358
|
+
if "id" in parameters:
|
18359
|
+
kwargs["id"] = self.id(t)
|
18360
|
+
if "screen_coordinates" in parameters:
|
18361
|
+
kwargs["screen_coordinates"] = self.screen_coordinates
|
18362
|
+
animation_objects = self.current_aos[c] = c.animation_objects(**kwargs)
|
18333
18363
|
|
18334
18364
|
dimx = _call(animation_objects[0], t, c)
|
18335
18365
|
dimy = _call(animation_objects[1], t, c)
|
18336
18366
|
for ao in animation_objects[2:]:
|
18337
|
-
ao.screen_coordinates = self.screen_coordinates
|
18338
18367
|
if isinstance(ao, AnimateClassic):
|
18339
18368
|
if direction == "t":
|
18340
18369
|
ao.x0 = xt + trajectory.x(t=x * 1.00, _t0=0)
|
@@ -18460,9 +18489,17 @@ class Animate3dQueue(DynamicClass):
|
|
18460
18489
|
if given, the animation object will be removed
|
18461
18490
|
automatically when the parent component is no longer accessible
|
18462
18491
|
|
18492
|
+
screen_coordinates : bool
|
18493
|
+
use screen_coordinates
|
18494
|
+
|
18495
|
+
if True (default), screen_coordinates will be used instead.
|
18496
|
+
|
18497
|
+
if False, all parameters are scaled for positioning and scaling
|
18498
|
+
objects.
|
18499
|
+
|
18463
18500
|
Note
|
18464
18501
|
----
|
18465
|
-
All parameters, apart from queue, id, arg and parent can be specified as:
|
18502
|
+
All parameters, apart from queue, id, arg, screen_coordinates and parent can be specified as:
|
18466
18503
|
|
18467
18504
|
- a scalar, like 10
|
18468
18505
|
|
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
|