diff --git a/atbswp/control.py b/atbswp/control.py index 7282d8c..cc898f4 100644 --- a/atbswp/control.py +++ b/atbswp/control.py @@ -348,54 +348,102 @@ def update_timer(self, event): self.timer = self.countdown_dialog.update_ui() -class PlayCtrl: - """Control class for the play button.""" +class PlayControl: + """Control class for playback functionality""" - global TMP_PATH + def __init__(self, count=1, infinite=False): + self.count = count + self.infinite = infinite + self._stop_locks = [True] + self._current_count = 0 + self._play_thread = None - def __init__(self): - self.count = settings.CONFIG.getint('DEFAULT', 'Repeat Count') - self.infinite = settings.CONFIG.getboolean('DEFAULT', 'Infinite Playback') - self.count_was_updated = False - - def play(self, capture, toggle_button): - """Play the loaded capture.""" + def _play(self, capture, append_function=None): for line in capture: - if self.play_thread.ended(): - return + if self.is_stoped(): break exec(line) - btn_event = wx.CommandEvent(wx.wxEVT_TOGGLEBUTTON) - btn_event.EventObject = toggle_button - if self.count <= 0 and not self.infinite: - toggle_button.Value = False - self.action(btn_event) + self._current_count += 1 + if self._current_count < self.count or self.infinite \ + and not self.is_stoped(): + self._play(capture, append_function) + else: + self.stop() + if append_function: + append_function() + + def _start_thread(self, target, *args, daemon=False): + thread = Thread(target=target, args=(*args,)) + thread.daemon = daemon + thread.start() + return thread + + def set_config(self, count, infinite): + """Set the configuration to the next playback""" + self.count = count + self.infinite = infinite + + def get_current_count(self): + """Returns the current playback time""" + return self._current_count + + def is_stoped(self): + return self._stop_locks[0] + + def play(self, capture, append_function=None): + """Starts playback according with configs setted + + :param capture: list of commands to be executed + :param append_function: a function to be executed after + a playback + """ + self._stop_locks[0] = False + self._current_count = 0 + self._play_thread = self._start_thread(self._play, capture, + append_function) + + def stop(self): + self._stop_locks[0] = True + + +class PlayGui: + def __init__(self): + self.play_ctrl = PlayControl() + self.capture = None + self._config_was_updated = False + self._toggle_button = None + + def _load_capture_file(self): + if TMP_PATH is None or not os.path.isfile(TMP_PATH): + wx.LogError("No capture loaded") + self._toggle_button.Value = False + return False + with open(TMP_PATH, 'r') as f: + self.capture = f.readlines() + return True + + def _set_config(self): + if self._config_was_updated: return + count = settings.CONFIG.getint('DEFAULT', 'Repeat Count') + infinite = settings.CONFIG.getboolean('DEFAULT', 'Infinite Playback') + self.play_ctrl.set_config(count, infinite) + self._config_was_updated = False + + def _stop(self): + self._toggle_button.Value = False + self.play_ctrl.stop() + self._config_was_updated = False + settings.save_config() def action(self, event): - """Replay a `count` number of time.""" - toggle_button = event.GetEventObject() - toggle_button.Parent.panel.SetFocus() - self.infinite = settings.CONFIG.getboolean('DEFAULT', 'Infinite Playback') - if toggle_button.Value: - if not self.count_was_updated: - self.count = settings.CONFIG.getint('DEFAULT', 'Repeat Count') - self.count_was_updated = True - if TMP_PATH is None or not os.path.isfile(TMP_PATH): - wx.LogError("No capture loaded") - toggle_button.Value = False - return - with open(TMP_PATH, 'r') as f: - capture = f.readlines() - if self.count > 0 or self.infinite: - self.count = self.count - 1 if not self.infinite else self.count - self.play_thread = PlayThread() - self.play_thread.daemon = True - self.play_thread = PlayThread(target=self.play, - args=(capture, toggle_button,)) - self.play_thread.start() + self._toggle_button = event.GetEventObject() + self._toggle_button.Parent.panel.SetFocus() + if self._toggle_button.Value: + if self.play_ctrl.is_stoped(): + if not self._load_capture_file(): return + self._set_config() + self.play_ctrl.play(self.capture, self._stop) else: - self.play_thread.end() - self.count_was_updated = False - settings.save_config() + self._stop() class CompileCtrl: @@ -527,3 +575,5 @@ def end(self): def ended(self): return self._end.isSet() + + diff --git a/atbswp/gui.py b/atbswp/gui.py index a2e19d8..049d9e9 100644 --- a/atbswp/gui.py +++ b/atbswp/gui.py @@ -203,7 +203,7 @@ def __add_bindings(self): self.Bind(wx.EVT_TOGGLEBUTTON, self.rbc.action, self.record_button) # play_button_ctrl - self.pbc = control.PlayCtrl() + self.pbc = control.PlayGui() self.Bind(wx.EVT_TOGGLEBUTTON, self.pbc.action, self.play_button) # compile_button_ctrl @@ -263,13 +263,10 @@ def on_key_press(self, event): self.rbc.action(btn_event) elif keycode == settings.CONFIG.getint('DEFAULT', 'Playback Hotkey'): - if not self.play_button.Value: - self.play_button.Value = True - btn_event = wx.CommandEvent(wx.wxEVT_TOGGLEBUTTON) - btn_event.EventObject = self.play_button - self.pbc.action(btn_event) - else: - self.play_button.Value = False + self.play_button.Value = not self.play_button.Value + btn_event = wx.CommandEvent(wx.wxEVT_TOGGLEBUTTON) + btn_event.EventObject = self.play_button + self.pbc.action(btn_event) elif keycode == ord("R") and event.CmdDown(): menu_event = wx.CommandEvent(wx.wxEVT_MENU)