-
- class LogicServer(threading.Thread):
- def __init__(self):
- threading.Thread.__init__(self)
- self._game_running = True
- self._paused = False
- self._no_interaction = False
- self._is_started = False
- self._time = None
- self._panda = None
-
- self._objects = []
- self._scheduled_events = []
-
-
- # Internal methods
- def _tick(self):
- if self._paused:
- return
-
- self._no_interaction = True
- self._time = time.time()
- for event in self._scheduled_events:
- self._resolve_event(event)
- self._no_interaction = False
-
-
- def _resolve_event(self, _event_data):
- game, originator, event, call_time, fire_time, on_event, args, kwargs = _event_data
- mod_time = time.time() - self._time
- call_time += mod_time
- if fire_time is None:
- is_once = event(call_time, *args, **kwargs)
- if on_event is not None:
- self._fire_event(on_event, originator)
- if is_once:
- self._remove_event(_event_data)
- else:
- if call_time >= fire_time:
- mod_time = time.time() - self._time
- is_once = event(mod_time, *args, **kwargs)
- _event_data[3] = 0
- if on_event is not None:
- self._fire_event(on_event, originator)
- if is_once:
- self._remove_event(_event_data)
- else:
- _event_data[3] = call_time
-
-
- def _resolve_event_return_stack(self, _event_data):
- game, originator, event, call_time, fire_time, on_event, args, kwargs = _event_data
- mod_time = time.time() - self._time
- call_time += mod_time
- if fire_time is None:
- return True, event, call_time, args, kwargs
- else:
- if call_time >= fire_time:
- _event_data[3] = 0
- return True, event, call_time, args, kwargs
- else:
- _event_data[3] += call_time
- return False, None, None, None, None
-
-
- def _remove_event(self, event):
- try:
- self._scheduled_events.remove(event)
- except ValueError:
- pass # the event was already remove by some other means, usually by removing it in the logic
-
-
- def _fire_event(self, event, *args, **kwargs):
- for child in self._objects:
- stop = child._resolve_event(event, *args, **kwargs)
- if stop:
- return
-
- # API Methods
- def kill(self):
- """stops the execution of this Logic server"""
-
- assert self._is_started, "Cannot kill Logic server. It was either killed already or never started in the first place."
- self._game_running = False
-
-
- def parent_object(self, object):
- """parents Logic object to this server"""
-
- assert self._is_started, "Cannot reparent to Logic server. It was either killed already or never started in the first place."
- assert object not in self._objects, "Object already exists in the Logic, reparent failed."
- self._objects.append(object)
-
-
- def deparent_object(self, object):
- """parents Logic object to this server"""
-
- assert self._is_started, "Cannot reparent to Logic server. It was either killed already or never started in the first place."
- assert object in self._objects, "Object is not in the Logic, deparent failed."
- self._objects.remove(object)
-
-
- def schedule(self, originator, event, delay=None, on_event=None, *args, **kwargs):
- """schedules event on this Logic server"""
- assert self._is_started, "Cannot schedule event. It was either killed already or never started in the first place."
-
- event_data = [None, originator, event, 0, delay, on_event, args, kwargs]
- self._scheduled_events.append(event_data)
-
-
- def unschedule(self, originator, event):
- """unschedules event/events.
-
- If all is passed instead of event, it will unschedule ALL events owned by that originator.
- Otherwise, it will only unschedule first event (should be the only one anyways).
- """
- assert self._is_started, "Cannot unschedule event. It was either killed already or never started in the first place."
-
- if event != "all":
- for ev in self._scheduled_events:
- if (ev[1] is originator) and (ev[2] is event):
- self._remove_event(ev)
- return
- else:
- for ev in self._scheduled_events:
- if (ev[1] is originator):
- self._remove_event(ev)
-
-
-
- def trigger(self, event, *args, **kwargs):
- """triggers event on all children of this Logic server"""
-
- assert self._is_started, "Cannot trigger an event. It was either killed already or never started in the first place."
- self._fire_event(event, *args, **kwargs)
-
-
- def pause(self):
- """pauses this Logic server"""
-
- assert self._is_started, "Cannot pause Logic server. It was either killed already or never started in the first place."
- self._paused = True
-
-
- def resume(self):
- """resumes this Logic server"""
-
- assert self._is_started, "Cannot run Logic server. It was either killed already or never started in the first place."
- self._paused = False
-
-
- def restart(self):
- """restarts this Logic server"""
-
- assert self._is_started, "Cannot run Logic server. It was either killed already or never started in the first place."
- self._paused = True
-
-
- def return_status(self):
- return self._is_started
-
-
- # Run method
- def run(self):
- self._is_started = True
- while self._game_running:
- self._tick()
- time.sleep(0.000001)
- self._is_started = False
-
-
- logic_server = LogicServer()
-
-
- def run_logic():
- logic_server.start()
-
-
- def stop_logic():
- logic_server.kill()
-
-
- def pause_logic():
- logic_server.pause()
-
-
- def resume_logic():
- logic_server.resume()
-
-
- def restart_logic():
- logic_server.restart()
-
-