batframework 1.0.8a7__py3-none-any.whl → 1.0.8a8__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.
Files changed (70) hide show
  1. batFramework/__init__.py +51 -68
  2. batFramework/action.py +99 -126
  3. batFramework/actionContainer.py +9 -53
  4. batFramework/animatedSprite.py +82 -141
  5. batFramework/audioManager.py +26 -69
  6. batFramework/camera.py +69 -259
  7. batFramework/constants.py +54 -16
  8. batFramework/cutscene.py +29 -39
  9. batFramework/cutsceneBlocks.py +43 -36
  10. batFramework/debugger.py +48 -0
  11. batFramework/dynamicEntity.py +9 -18
  12. batFramework/easing.py +71 -0
  13. batFramework/entity.py +97 -48
  14. batFramework/gui/__init__.py +2 -10
  15. batFramework/gui/button.py +78 -9
  16. batFramework/gui/constraints.py +204 -0
  17. batFramework/gui/container.py +32 -174
  18. batFramework/gui/debugger.py +43 -131
  19. batFramework/gui/frame.py +19 -0
  20. batFramework/gui/image.py +20 -56
  21. batFramework/gui/indicator.py +21 -38
  22. batFramework/gui/interactiveWidget.py +13 -192
  23. batFramework/gui/label.py +74 -309
  24. batFramework/gui/layout.py +63 -231
  25. batFramework/gui/root.py +38 -134
  26. batFramework/gui/shape.py +57 -237
  27. batFramework/gui/toggle.py +51 -101
  28. batFramework/gui/widget.py +250 -358
  29. batFramework/manager.py +19 -52
  30. batFramework/particles.py +77 -0
  31. batFramework/scene.py +123 -281
  32. batFramework/sceneManager.py +116 -178
  33. batFramework/stateMachine.py +8 -11
  34. batFramework/time.py +58 -145
  35. batFramework/transition.py +124 -195
  36. batFramework/transitionManager.py +0 -0
  37. batFramework/triggerZone.py +1 -1
  38. batFramework/utils.py +147 -112
  39. batframework-1.0.8a8.dist-info/METADATA +53 -0
  40. batframework-1.0.8a8.dist-info/RECORD +42 -0
  41. {batframework-1.0.8a7.dist-info → batframework-1.0.8a8.dist-info}/WHEEL +1 -1
  42. batFramework/character.py +0 -27
  43. batFramework/easingController.py +0 -58
  44. batFramework/enums.py +0 -113
  45. batFramework/fontManager.py +0 -65
  46. batFramework/gui/clickableWidget.py +0 -220
  47. batFramework/gui/constraints/__init__.py +0 -1
  48. batFramework/gui/constraints/constraints.py +0 -815
  49. batFramework/gui/dialogueBox.py +0 -99
  50. batFramework/gui/draggableWidget.py +0 -40
  51. batFramework/gui/meter.py +0 -74
  52. batFramework/gui/radioButton.py +0 -84
  53. batFramework/gui/slider.py +0 -240
  54. batFramework/gui/style.py +0 -10
  55. batFramework/gui/styleManager.py +0 -48
  56. batFramework/gui/textInput.py +0 -247
  57. batFramework/object.py +0 -123
  58. batFramework/particle.py +0 -115
  59. batFramework/renderGroup.py +0 -67
  60. batFramework/resourceManager.py +0 -100
  61. batFramework/scrollingSprite.py +0 -114
  62. batFramework/sprite.py +0 -51
  63. batFramework/templates/__init__.py +0 -2
  64. batFramework/templates/character.py +0 -44
  65. batFramework/templates/states.py +0 -166
  66. batFramework/tileset.py +0 -46
  67. batframework-1.0.8a7.dist-info/LICENCE +0 -21
  68. batframework-1.0.8a7.dist-info/METADATA +0 -43
  69. batframework-1.0.8a7.dist-info/RECORD +0 -62
  70. {batframework-1.0.8a7.dist-info → batframework-1.0.8a8.dist-info}/top_level.txt +0 -0
@@ -1,227 +1,165 @@
1
1
  import batFramework as bf
2
2
  import pygame
3
- from typing import Self
4
3
 
5
4
 
6
- def swap(lst, index1, index2):
7
- lst[index1], lst[index2] = lst[index2], lst[index1]
8
-
9
5
 
10
6
  class SceneManager:
11
- def __init__(self) -> None:
12
- self.scenes: list[bf.Scene] = []
13
- self.shared_events = {pygame.WINDOWRESIZED}
7
+ def __init__(self, *initial_scenes: bf.Scene) -> None:
8
+ self._debugging = 0
9
+ self.sharedVarDict = {}
14
10
 
11
+ self.transitions: list[bf.BaseTransition] = []
12
+ self.set_sharedVar("is_debugging_func", lambda: self._debugging)
13
+ self.set_sharedVar("in_transition", False)
15
14
  self.set_sharedVar("in_cutscene", False)
16
- self.set_sharedVar("player_has_control", True)
17
- self.old_player_control = True
18
- self.debug_mode: bf.enums.debugMode = bf.debugMode.HIDDEN
19
- self.current_transitions: dict[str, bf.transition.Transition] = {}
20
15
 
21
- def init_scenes(self, *initial_scenes:bf.Scene):
22
- for index, s in enumerate(initial_scenes):
16
+ self._scenes: list[bf.Scene] = list(initial_scenes)
17
+ for index,s in enumerate(self._scenes):
18
+ s.set_manager(self)
23
19
  s.set_scene_index(index)
24
- for s in reversed(initial_scenes):
25
- self.add_scene(s)
26
- # self.scenes = list(initial_scenes)
27
- self.set_scene(initial_scenes[0].get_name())
20
+ s.do_when_added()
21
+ self.set_scene(self._scenes[0]._name)
28
22
  self.update_scene_states()
29
23
 
30
- def set_shared_event(self, event: pygame.Event) -> None:
31
- """
32
- Add an event that will be propagated to all active scenes, not just the one on top.
33
- """
34
- self.shared_events.add(event)
35
-
36
24
  def print_status(self):
37
- """
38
- Print detailed information about the current state of the scenes and shared variables.
39
- """
40
-
41
- def format_scene_info(scene):
42
- status = 'Active' if scene.active else 'Inactive'
43
- visibility = 'Visible' if scene.visible else 'Invisible'
44
- return f"{scene.name:<30} | {status:<8} | {visibility:<10} | Index={scene.scene_index}"
45
-
46
- def format_shared_variable(name, value):
47
- return f"[{name}] = {value}"
48
-
49
- print("\n" + "=" * 50)
50
- print(" SCENE STATUS".center(50))
51
- print("=" * 50)
52
-
53
- # Print scene information
54
- if self.scenes:
55
- header = f"{'Scene Name':<30} | {'Status':<8} | {'Visibility':<10} | {'Index':<7}"
56
- print(header)
57
- print("-" * 50)
58
- print("\n".join(format_scene_info(s) for s in self.scenes))
59
- else:
60
- print("No scenes available.")
61
-
62
- # Print debugging mode status
63
- print("\n" + "=" * 50)
64
- print(" DEBUGGING STATUS".center(50))
65
- print("=" * 50)
66
- print(f"[Debugging Mode] = {self.debug_mode}")
67
-
68
- # Print shared variables
69
- print("\n" + "=" * 50)
70
- print(" SHARED VARIABLES".center(50))
71
- print("=" * 50)
72
-
73
- if bf.ResourceManager().shared_variables:
74
- for name, value in bf.ResourceManager().shared_variables.items():
75
- print(format_shared_variable(name, value))
76
- else:
77
- print("No shared variables available.")
78
-
79
- print("=" * 50 + "\n")
80
-
81
-
82
- def set_sharedVar(self, name, value) -> None:
83
- bf.ResourceManager().set_sharedVar(name,value)
84
-
85
- def get_sharedVar(self, name, error_value=None):
86
- return bf.ResourceManager().get_sharedVar(name, error_value)
87
-
88
- def get_current_scene_name(self) -> str:
89
- """get the name of the current scene"""
90
- return self.scenes[0].get_name()
91
-
92
- def get_current_scene(self) -> bf.Scene:
93
- return self.scenes[0]
25
+ print("-" * 40)
26
+ print([(s._name, s._active, s._visible,s.scene_index) for s in self._scenes])
27
+ print(f"[Debugging] = {self._debugging}")
28
+ print("---SHARED VARIABLES---")
29
+ _ = [
30
+ print(f"[{str(name)} = {str(value)}]")
31
+ for name, value in self.sharedVarDict.items()
32
+ ]
33
+ print("-" * 40)
34
+
35
+ def set_sharedVar(self, name, value) -> bool:
36
+ self.sharedVarDict[name] = value
37
+ return True
38
+
39
+ def get_sharedVar(self, name):
40
+ if name not in self.sharedVarDict:
41
+ return None
42
+ return self.sharedVarDict[name]
43
+
44
+ def get_current_scene_name(self)-> str:
45
+ return self._scenes[0].name
46
+
47
+ def get_current_scene(self)->bf.Scene:
48
+ return self._scenes[0]
94
49
 
95
50
  def update_scene_states(self):
96
- self.active_scenes = [s for s in reversed(self.scenes) if s.active]
97
- self.visible_scenes = [s for s in reversed(self.scenes) if s.visible]
51
+ self.active_scenes = [s for s in reversed(self._scenes) if s._active]
52
+ self.visible_scenes = [s for s in reversed(self._scenes) if s._visible]
98
53
 
99
54
  def add_scene(self, scene: bf.Scene):
100
- if scene in self.scenes and not self.has_scene(scene.name):
55
+ if scene in self._scenes and not self.has_scene(scene._name):
101
56
  return
102
57
  scene.set_manager(self)
103
58
  scene.do_when_added()
104
- self.scenes.insert(0, scene)
59
+ self._scenes.insert(0, scene)
105
60
 
106
61
  def remove_scene(self, name: str):
107
- self.scenes = [s for s in self.scenes if s.name != name]
62
+ self._scenes = [s for s in self._scenes if s._name != name]
108
63
 
109
64
  def has_scene(self, name):
110
- return any(name == scene.name for scene in self.scenes)
65
+ return any(name == scene._name for scene in self._scenes)
111
66
 
112
67
  def get_scene(self, name):
113
68
  if not self.has_scene(name):
114
69
  return None
115
- for scene in self.scenes:
116
- if scene.name == name:
70
+ for scene in self._scenes:
71
+ if scene._name == name:
117
72
  return scene
118
73
 
119
- def get_scene_at(self, index: int) -> bf.Scene | None:
120
- if index < 0 or index >= len(self.scenes):
121
- return None
122
- return self.scenes[index]
123
-
124
- def transition_to_scene(
125
- self,
126
- scene_name: str,
127
- transition: bf.transition.Transition = bf.transition.Fade(0.1),
128
- index: int = 0,
129
- ):
130
- target_scene = self.get_scene(scene_name)
131
- if not target_scene:
132
- print(f"Scene '{scene_name}' does not exist")
133
- return
134
- if len(self.scenes) == 0 or index >= len(self.scenes) or index < 0:
135
- return
136
- source_surface = bf.const.SCREEN.copy()
137
- dest_surface = bf.const.SCREEN.copy()
138
-
139
- # self.draw(source_surface)
140
- target_scene.draw(dest_surface)
141
- target_scene.do_on_enter_early()
142
- self.get_scene_at(index).do_on_exit_early()
143
- self.current_transitions = {"scene_name": scene_name, "transition": transition}
144
- transition.set_start_callback(lambda: self._start_transition(target_scene))
145
- transition.set_end_callback(lambda: self._end_transition(scene_name, index))
146
- transition.set_source(source_surface)
147
- transition.set_dest(dest_surface)
148
- transition.start()
149
-
150
- def _start_transition(self, target_scene: bf.Scene):
151
- target_scene.set_active(True)
152
- target_scene.set_visible(True)
153
- self.old_player_control = bool(self.get_sharedVar("player_has_control"))
154
- self.set_sharedVar("player_has_control", False)
155
-
156
- def _end_transition(self, scene_name, index):
157
- self.set_scene(scene_name, index, True)
158
- self.current_transitions.clear()
159
-
160
- def set_scene(self, scene_name, index=0, ignore_early: bool = False):
161
- target_scene = self.get_scene(scene_name)
162
- if not target_scene:
163
- print(f"'{scene_name}' does not exist")
164
- return
165
- if len(self.scenes) == 0 or index >= len(self.scenes) or index < 0:
166
- return
167
-
168
- # switch
169
- if not ignore_early:
170
- self.scenes[index].do_on_exit_early()
171
- self.scenes[index].on_exit()
172
- # re-insert scene at index 0
173
- self.scenes.remove(target_scene)
174
- self.scenes.insert(index, target_scene)
175
- _ = [s.set_scene_index(i) for i, s in enumerate(self.scenes)]
176
- if not ignore_early:
177
- self.scenes[index].do_on_enter_early()
74
+ def transition_to_scene(self, dest_scene_name, transition, **kwargs):
75
+ if not self.has_scene(dest_scene_name):
76
+ return False
77
+ source_surf = pygame.Surface(bf.const.RESOLUTION,pygame.SRCALPHA).convert_alpha()
78
+ dest_surf = pygame.Surface(bf.const.RESOLUTION,pygame.SRCALPHA).convert_alpha()
79
+
80
+ index = kwargs.pop("index",0)
81
+ #draw the surfaces
82
+ source_scenes = [s for s in self.visible_scenes if s.scene_index >= index and s._visible]
83
+ # source_scenes = self.visible_scenes
84
+ _ = [s.draw(source_surf) for s in source_scenes]
85
+ # self._scenes[index].draw(source_surf)
86
+
87
+ # pygame.image.save_extended:(source_surf,"source_surface.png")
88
+ self.get_scene(dest_scene_name).draw(dest_surf)
89
+ # pygame.image.save_extended(dest_surf,"dest_surface.png")
90
+
91
+ # print(f"start transition from {self._scenes[index]._name} to {dest_scene_name}")
92
+
93
+ instance: bf.BaseTransition = transition(
94
+ source_surf, dest_surf, **kwargs
95
+ )
96
+ instance.set_scene_index(index)
97
+ instance.set_source_name(self._scenes[index]._name)
98
+ instance.set_dest_name(dest_scene_name)
99
+ self.transitions.append(instance)
100
+ self.set_sharedVar("in_transition", True)
101
+
102
+ def set_scene(self, name,index=0):
103
+ if len(self._scenes)==0 or not self.has_scene(name) or index>=len(self._scenes):return
104
+
105
+ target_scene = self.get_scene(name)
106
+ old_scene = self._scenes[index]
107
+
108
+ # print(f"switch from {old_scene._name} to {target_scene._name} in index {index}")
109
+
110
+ #switch
111
+ old_scene.on_exit()
112
+ self.remove_scene(name)
113
+ self._scenes.insert(index,target_scene)
114
+ _ = [s.set_scene_index(i) for i,s in enumerate(self._scenes)]
178
115
  target_scene.on_enter()
179
116
 
180
- self.set_sharedVar("player_has_control", self.old_player_control)
181
-
182
-
183
- def cycle_debug_mode(self):
184
- current_index = self.debug_mode.value
185
- next_index = (current_index + 1) % len(bf.debugMode)
186
- return bf.debugMode(next_index)
187
117
 
188
118
  def process_event(self, event: pygame.Event):
119
+ if self.transitions:
120
+ return
189
121
  keys = pygame.key.get_pressed()
190
122
  if (
191
123
  keys[pygame.K_LCTRL]
192
- and keys[pygame.K_LSHIFT]
193
124
  and event.type == pygame.KEYDOWN
125
+ and event.key == pygame.K_d
126
+ ):
127
+ self._debugging = (self._debugging + 1) % 3
128
+ return
129
+ elif (
130
+ keys[pygame.K_LCTRL]
131
+ and event.type == pygame.KEYDOWN
132
+ and event.key == pygame.K_p
194
133
  ):
195
- if event.key == pygame.K_d:
196
- self.debug_mode = self.cycle_debug_mode()
197
- self.set_sharedVar("debug_mode", self.debug_mode)
198
- return
199
- if event.key == pygame.K_p:
200
- self.print_status()
201
- return
202
- if event.type in self.shared_events:
203
- [s.process_event(event) for s in self.scenes]
204
- else:
205
- self.scenes[0].process_event(event)
134
+ self.print_status()
135
+ self._scenes[0].process_event(event)
206
136
 
207
137
  def update(self, dt: float) -> None:
138
+ if self.transitions:
139
+ transition = self.transitions[0]
140
+ transition.update(dt)
141
+ if transition.has_ended():
142
+ self.set_sharedVar("in_transition", False)
143
+ self.set_scene(transition.dest_scene_name,transition.index)
144
+
145
+ self.transitions.pop(0)
146
+ return
208
147
  for scene in self.active_scenes:
209
148
  scene.update(dt)
210
149
  self.do_update(dt)
211
150
 
212
151
  def do_update(self, dt: float):
213
- pass
152
+ return
214
153
 
215
154
  def draw(self, surface) -> None:
216
- for scene in self.visible_scenes:
155
+ transition_scene_index = -1
156
+ visible_scenes = self.visible_scenes.copy()
157
+ if self.transitions:
158
+ transition_scene_index = self.transitions[0].index
159
+
160
+ if transition_scene_index >=0:
161
+ self.transitions[0].draw(surface)
162
+ visible_scenes = [s for s in visible_scenes if s.scene_index < transition_scene_index]
163
+
164
+ for scene in visible_scenes:
217
165
  scene.draw(surface)
218
- if self.current_transitions:
219
- self._draw_transition(surface)
220
-
221
- def _draw_transition(self, surface):
222
- self.current_transitions["transition"].set_source(surface)
223
- tmp = bf.const.SCREEN.copy()
224
- self.get_scene(self.current_transitions["scene_name"]).draw(tmp)
225
- self.current_transitions["transition"].set_dest(tmp)
226
- self.current_transitions["transition"].draw(surface)
227
- return
@@ -1,17 +1,18 @@
1
1
  import batFramework as bf
2
2
 
3
3
 
4
- class StateMachine: ...
4
+ class StateMachine:
5
+ ...
5
6
 
6
7
 
7
8
  class State:
8
9
  def __init__(self, name: str) -> None:
9
10
  self.name = name
10
- self.parent: bf.Entity | bf.AnimatedSprite = None
11
+ self.parent_entity: bf.Entity | bf.AnimatedSprite = None
11
12
  self.state_machine: StateMachine = None
12
13
 
13
- def set_parent(self, parent: bf.Entity | bf.AnimatedSprite):
14
- self.parent = parent
14
+ def set_parent_entity(self, parent_entity: bf.Entity | bf.AnimatedSprite):
15
+ self.parent_entity = parent_entity
15
16
 
16
17
  def set_stateMachine(self, stateMachine):
17
18
  self.state_machine = stateMachine
@@ -27,26 +28,22 @@ class State:
27
28
 
28
29
 
29
30
  class StateMachine:
30
- def __init__(self, parent) -> None:
31
+ def __init__(self, parent_entity) -> None:
31
32
  self.states: dict[str, State] = {}
32
- self.parent = parent
33
+ self.parent_entity = parent_entity
33
34
  self.current_state = None
34
35
 
35
36
  def add_state(self, state: State):
36
37
  self.states[state.name] = state
37
- state.set_parent(self.parent)
38
+ state.set_parent_entity(self.parent_entity)
38
39
  state.set_stateMachine(self)
39
40
 
40
- def remove_state(self,state_name: str):
41
- self.states.pop(state_name,default=None)
42
-
43
41
  def set_state(self, state_name: str):
44
42
  if state_name in self.states:
45
43
  if self.current_state:
46
44
  self.current_state.on_exit()
47
45
  self.current_state = self.states[state_name]
48
46
  self.current_state.on_enter()
49
-
50
47
  def get_current_state(self) -> State:
51
48
  return self.current_state
52
49
 
batFramework/time.py CHANGED
@@ -1,162 +1,75 @@
1
+ import pygame
1
2
  import batFramework as bf
2
- from typing import Self
3
-
4
-
5
- from typing import Callable, Union, Self
6
-
7
3
 
8
4
  class Timer:
9
- _count: int = 0
10
- _available_ids: set[int] = set()
11
-
12
- def __init__(self, duration: Union[float, int], end_callback: Callable, loop: bool = False, register: str = "global") -> None:
13
- if Timer._available_ids:
14
- self.uid = Timer._available_ids.pop()
15
- else:
16
- self.uid = Timer._count
17
- Timer._count += 1
18
-
19
- self.register = register
20
- self.duration: int | float = duration
5
+ _highest_count = 0
6
+ def __init__(self, name=None, duration=1000, loop=False, end_callback=None,reusable:bool=False):
7
+ # Initialize timer properties
8
+ self.start_time = None
9
+ self.stopped = True
10
+ self.name = name if name is not None else self._highest_count
11
+ Timer._highest_count += 1
12
+ self.duration = duration
13
+ self.loop = loop
14
+ self.elapsed_progress = 0.0
21
15
  self.end_callback = end_callback
16
+ self.reusable:bool = reusable
17
+ def start(self):
18
+ # Start the timer and set the start time
19
+ if self.start_time is None:
20
+ Time().add_timer(self)
21
+
22
+ self.start_time = pygame.time.get_ticks()
23
+ self.stopped = False
24
+ self.elapsed_progress = 0.0
25
+
26
+ def update(self):
27
+ if self.stopped : return False
28
+ current_time = pygame.time.get_ticks()
29
+ if self.elapsed_progress < 1:
30
+ # Calculate elapsed progress
31
+ self.elapsed_progress = (current_time - self.start_time) / self.duration
32
+ if self.elapsed_progress >= 1:
33
+ # Timer has completed
34
+ self.end()
35
+ return True
36
+ elif self.loop:
37
+ # If looping, restart the timer
38
+ self.start()
39
+ return False
22
40
 
23
- self.elapsed_time: float = -1
24
- self.is_over: bool = False
25
- self.is_looping: bool = loop
26
- self.is_paused: bool = False
27
- self.do_delete: bool = False
28
-
29
- def __bool__(self)->bool:
30
- return self.elapsed_time==-1 or self.is_over
31
-
32
- def __str__(self) -> str:
33
- return f"Timer ({self.uid}) {self.elapsed_time}/{self.duration} | {'loop ' if self.is_looping else ''} {'(D) ' if self.do_delete else ''}"
34
-
35
- def stop(self) -> Self:
36
- self.elapsed_time = -1
37
- self.is_over = False
38
- self.is_paused = False
39
- return self
40
-
41
- def start(self, force: bool = False) -> Self:
42
- if self.elapsed_time != -1 and not force:
43
- return self
44
- if not bf.TimeManager().add_timer(self,self.register):
45
- return self
46
- self.elapsed_time = 0
47
- self.is_paused = False
48
- self.is_over = False
49
- return self
50
-
51
- def pause(self) -> Self:
52
- self.is_paused = True
53
- return self
54
-
55
- def resume(self) -> Self:
56
- self.is_paused = False
57
- return self
58
-
59
- def delete(self) -> Self:
60
- self.do_delete = True
61
- return self
62
-
63
- def has_started(self) -> bool:
64
- return self.elapsed_time != -1
65
-
66
- def get_progression(self) -> float:
67
- if self.elapsed_time < 0:
68
- return 0
69
- if self.elapsed_time >= self.duration:
70
- return 1
71
- return self.elapsed_time / self.duration
72
-
73
- def update(self, dt) -> None:
74
- if self.elapsed_time < 0 or self.is_paused or self.is_over:
75
- return
76
- self.elapsed_time += dt
77
- # print("update :",self.elapsed_time,self.duration)
78
- if self.get_progression() == 1:
79
- self.end()
41
+ def stop(self):
42
+ # Stop the timer
43
+ self.stopped = True
80
44
 
81
45
  def end(self):
46
+ self.elapsed_progress = 1
47
+ self.stopped = False
82
48
  if self.end_callback:
83
49
  self.end_callback()
84
- self.elapsed_time = -1
85
- self.is_over = True
86
- if self.is_looping:
87
- self.start()
88
- return
89
-
90
- def should_delete(self) -> bool:
91
- return self.is_over or self.do_delete
92
-
93
- def _release_id(self):
94
- Timer._available_ids.add(self.uid)
95
-
96
-
97
- class SceneTimer(Timer):
98
- def __init__(self, duration: float | int, end_callback, loop: bool = False, scene_name:str = "global") -> None:
99
- super().__init__(duration, end_callback, loop, scene_name)
100
50
 
101
- class TimeManager(metaclass=bf.Singleton):
102
- class TimerRegister:
103
- def __init__(self, active=True):
104
- self.active = active
105
- self.timers: dict[int | str, Timer] = {}
51
+ def ended(self):
52
+ if self.start_time is None:
53
+ return False
54
+ return (not self.loop) and (self.elapsed_progress >= 1) and (not self.stopped) and not self.reusable
106
55
 
107
- def __iter__(self):
108
- return iter(self.timers.values())
109
-
110
- def add_timer(self, timer: Timer):
111
- self.timers[timer.uid] = timer
112
-
113
- def update(self, dt):
114
- expired_timers = []
115
- for timer in list(self.timers.values()):
116
- if not timer.is_paused:
117
- timer.update(dt)
118
- if timer.should_delete():
119
- expired_timers.append(timer.uid)
120
- for uid in expired_timers:
121
- self.timers[uid]._release_id()
122
- del self.timers[uid]
123
56
 
57
+ class Time(metaclass=bf.Singleton):
124
58
  def __init__(self):
125
- self.registers = {"global": TimeManager.TimerRegister()}
126
-
127
- def add_register(self, name, active=True):
128
- if name not in self.registers:
129
- self.registers[name] = TimeManager.TimerRegister(active)
130
-
131
- def add_timer(self, timer, register="global") -> bool:
132
- if register in self.registers:
133
- self.registers[register].add_timer(timer)
134
- return True
135
- print(f"Register '{register}' does not exist.")
136
- return False
137
-
138
- def get_active_registers(self) -> list[TimerRegister]:
139
- return [t for t in self.registers.values() if t.active]
59
+ # Initialize the Time class with a dictionary of timers
60
+ self.timers = {}
140
61
 
141
- def update(self, dt):
142
- for register_name, register in self.registers.items():
143
- if register.active:
144
- register.update(dt)
62
+ def add_timer(self, timer):
63
+ # Add a timer to the dictionary
64
+ self.timers[timer.name] = timer
145
65
 
146
- def activate_register(self, name, active=True):
147
- if name in self.registers:
148
- self.registers[name].active = active
149
- else:
150
- print(f"Register '{name}' does not exist.")
66
+ def update(self):
67
+ # Update all timers and remove completed ones
68
+ for timer in list(self.timers.values()):
69
+ timer.update()
151
70
 
152
- def deactivate_register(self, name):
153
- self.activate_register(name, active=False)
71
+ to_remove = [name for name, timer in self.timers.items() if timer.ended()]
154
72
 
155
- def __str__(self)->str:
156
- res = ""
157
- for name,reg in self.registers.items():
158
- if not reg.timers:continue
159
- res +=name+"\n"
160
- for t in reg.timers.values():
161
- res +="\t"+str(t)+"\n"
162
- return res
73
+ for name in to_remove:
74
+ # print(self.timers.pop(name).name,"removed !")
75
+ self.timers.pop(name)