def _setup(self): """Initialise all the status data structures.""" # Execution lock object. self.exec_lock = Exec_lock() # The data pipe lock object. self.pipe_lock = Relax_lock(name='pipe_lock') # The molecule, residue, spin structure lock object. self.spin_lock = Relax_lock(name='spin_lock') # The exception queue for handling exceptions in threads. self.exception_queue = Queue() # The auto-analysis status containers. self.auto_analysis = {} self.current_analysis = None # GUI structures. self.controller_max_entries = 100000 # Scroll back limit in the relax controller. # A structure for skipped system and unit tests. self.skipped_tests = [] """The skipped tests list. Each element should be a list of the test case name, the missing Python module, and the name of the test suite category (i.e. 'system' or 'unit').""" # Set up the observer objects. self._setup_observers() # Text wrapping on different operating systems. if platform.uname()[0] in ['Windows', 'Microsoft']: self.text_width = 79 else: self.text_width = 100
def __init__(self): """Initialise the object.""" # Set up the thread object. Thread.__init__(self) # Set the thread to be daemonic so that relax can exit. self.daemon = True # Create a queue object for the user function calls. self._queue = Queue() # The list of user functions still in the queue. self._uf_list = [] # A flag for exiting the thread. self._exit = False
class Interpreter_thread(Thread): """The threaded interpreter.""" def __init__(self): """Initialise the object.""" # Set up the thread object. Thread.__init__(self) # Set the thread to be daemonic so that relax can exit. self.daemon = True # Create a queue object for the user function calls. self._queue = Queue() # The list of user functions still in the queue. self._uf_list = [] # A flag for exiting the thread. self._exit = False def empty(self): """Is the queue empty?""" # Execution is locked. if status.exec_lock.locked(): return False # There are still queued calls. elif len(self._uf_list): return False # The queue is empty. else: return True def exit(self): """Cause the thread to exit once all currently queued user functions are processed.""" # First set the flag. self._exit = True # Then queue a dummy user function. self._queue.put([None, None, None]) def join(self): """Wrapper method for the Queue.join() method.""" # Join the queue. self._queue.join() def queue(self, fn, *args, **kwds): """Queue up a user function for asynchronous execution. @param fn: The user function as a string. @type fn: str @param args: The user function arguments. @type args: any arguments @param kwds: The user function keyword arguments. @type kwds: any keyword arguments """ # Add the user function name to the list. self._uf_list.append(repr(fn)) # Place the user function and its args onto the queue. self._queue.put([fn, args, kwds]) def run(self): """Execute the thread.""" # Loop until told to exit. while not self._exit: # Get the user function from the queue. fn, args, kwds = self._queue.get() # No user function. if fn == None: continue # Execution lock. status.exec_lock.acquire('gui', mode='interpreter thread') # Execute the user function, catching errors (the nested try-except statements within the try-finally statements are for Python 2.4 and earlier support). try: try: fn(*args, **kwds) # Catch all RelaxErrors. except AllRelaxErrors: instance = sys.exc_info()[1] # Display a dialog with the error. wx.CallAfter(gui_raise, instance, raise_flag=False) # Handle all other errors. except: # Print the exception. print_exc() # Release the lock. finally: # Signal that the queue item has been processed. self._queue.task_done() # Release the execution lock. status.exec_lock.release() # Remove the user function from the list. self._uf_list.pop(self._uf_list.index(repr(fn))) # Notify all observers that a user function has completed. status.observers.gui_uf.notify()
def __init__(self, gui): """Set up the relax controller frame. @param gui: The GUI object. @type gui: wx.Frame instance """ # Store the args. self.gui = gui # Initialise the base class. super(Controller, self).__init__(self.gui, -1, style=wx.DEFAULT_FRAME_STYLE) # Some default values. self.size_x = 800 self.size_y = 700 self.border = 5 self.spacer = 10 # Set up the frame. sizer = self.setup_frame() # Add the relax logo. self.add_relax_logo(sizer) # Spacing. sizer.AddSpacer(20) # Add the current analysis info. self.name = self.add_text(self.main_panel, sizer, "Current GUI analysis:") # Add the current data pipe info. self.cdp = self.add_text(self.main_panel, sizer, "Current data pipe:") # Create the relaxation curve-fitting specific panel. self.create_rx(sizer) # Create the model-free specific panel. self.create_mf(sizer) # Add the main execution gauge. self.main_gauge = self.add_gauge( self.main_panel, sizer, "Execution progress:", tooltip= "This gauge will pulse while relax is executing an auto-analysis (when the execution lock is turned on) and will be set to 100% once the analysis is complete." ) # Initialise a queue for log messages. self.log_queue = Queue() # Add the log panel. self.log_panel = LogCtrl(self.main_panel, self, log_queue=self.log_queue, id=-1) sizer.Add(self.log_panel, 1, wx.EXPAND | wx.ALL, 0) # IO redirection for STDOUT (with splitting if logging or teeing modes are set). out = Redirect_text(self.log_panel, self.log_queue, orig_io=sys.stdout, stream=0) if sys.stdout == sys.__stdout__ or status.relax_mode in [ 'test suite', 'system tests', 'unit tests', 'GUI tests' ]: sys.stdout = out else: split_stdout = SplitIO() split_stdout.split(sys.stdout, out) sys.stdout = split_stdout # IO redirection for STDERR (with splitting if logging or teeing modes are set). err = Redirect_text(self.log_panel, self.log_queue, orig_io=sys.stderr, stream=1) if sys.stderr == sys.__stderr__ or status.relax_mode in [ 'test suite', 'system tests', 'unit tests', 'GUI tests' ]: sys.stderr = err else: split_stderr = SplitIO() split_stderr.split(sys.stderr, err) sys.stderr = split_stderr # Initial update of the controller. self.update_controller() # Create a timer for updating the controller elements. self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.handler_timer, self.timer) # The relax intro printout, to mimic the prompt/script interface. if not status.test_mode: info = Info_box() sys.stdout.write(info.intro_text()) sys.stdout.write("\n") sys.stdout.flush() # Set the focus on the log control. self.log_panel.SetFocus() # Register functions with the observer objects. status.observers.pipe_alteration.register( 'controller', self.update_controller, method_name='update_controller') status.observers.auto_analyses.register( 'controller', self.update_controller, method_name='update_controller') status.observers.gui_analysis.register('controller', self.update_controller, method_name='update_controller') status.observers.exec_lock.register('controller', self.update_gauge, method_name='update_gauge')