diff --git a/BasaltTrainer/main.py b/BasaltTrainer/main.py index 66415ce..c9b58cc 100644 --- a/BasaltTrainer/main.py +++ b/BasaltTrainer/main.py @@ -1,5 +1,7 @@ from command_server import CommandServer, HandshakePayload, PixelKind +from while_stopper import WhileStopper import logging +import signal def receive_data() -> None: @@ -9,20 +11,26 @@ def receive_data() -> None: def main(): server = CommandServer() - print( - 'Please launch BasaltPresenter now and then press Enter to continue.') + print('Please launch BasaltPresenter now.') + print('Then press Enter to continue...') input() logging.info('Waiting BasaltPresenter...') server.wait_handshake(HandshakePayload(PixelKind.GRAY_U8, 600, 600)) logging.info('Start to running.') + stopper = WhileStopper() + stopper.register() while True: - if server.tick(receive_data, False): + if server.tick(receive_data, stopper.is_stop_requested()): break + stopper.unregister() logging.info('Program stop.') + print('Press Enter to exit...') + input() + if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG, diff --git a/BasaltTrainer/pipe_operator.py b/BasaltTrainer/pipe_operator.py index a3470d8..3cd8790 100644 --- a/BasaltTrainer/pipe_operator.py +++ b/BasaltTrainer/pipe_operator.py @@ -48,9 +48,6 @@ class PipeOperator: else: # POSIX implementation self.pipe_name = f"/tmp/{name}" - # If there is an existing FIFO file, remove it - if os.path.exists(self.pipe_name): - os.unlink(self.pipe_name) # Create pipe try: os.mkfifo(self.pipe_name) diff --git a/BasaltTrainer/while_stopper.py b/BasaltTrainer/while_stopper.py new file mode 100644 index 0000000..c8648a0 --- /dev/null +++ b/BasaltTrainer/while_stopper.py @@ -0,0 +1,52 @@ +import sys + +IS_WINDOWS: bool = sys.platform == "win32" + +if IS_WINDOWS: + import win32api +else: + import signal + + +class WhileStopper: + + is_registered: bool + stop_requested: bool + + def __init__(self) -> None: + self.is_registered = False + self.stop_requested = False + + def is_stop_requested(self) -> bool: + if not self.is_registered: + raise RuntimeError('unexpected stopper status') + + return self.stop_requested + + def register(self): + if self.is_registered: + raise RuntimeError('unexpected stopper status') + + self.stop_requested = False + if IS_WINDOWS: + win32api.SetConsoleCtrlHandler(self.__win_handler, True) + else: + signal.signal(signal.SIGINT, self.__posix_handler) + self.is_registered = True + + def unregister(self): + if not self.is_registered: + raise RuntimeError('unexpected stopper status') + + if IS_WINDOWS: + win32api.SetConsoleCtrlHandler(None, False) + else: + signal.signal(signal.SIGINT, signal.SIG_DFL) + self.is_registered = False + + def __win_handler(self, ctrl_type: int) -> bool: + self.stop_requested = True + return True + + def __posix_handler(self, signal, frame) -> None: + self.stop_requested = True