Managers

Managers manage displaying panels and retrieving user input, so you don’t have to worry about it. Your code just needs to tell the manager what you want to display and watch for messages back from the manager containing input from the user.

thurible.queued_manager(q_to: Queue, q_from: Queue, term: Terminal | None = None, displays: dict | None = None) None[source]

Manage a terminal display by sending and receiving thurible.messages.Message objects through queue.Queue objects.

Warning

thurible.queued_manager() is intended to be run in its own thread or process. If you try to run it synchronously with the rest of your application, the loop will prevent your application from completing execution. This is why it is a “queued” manager.

Parameters:
  • q_to – A queue for messages the program sends to the manager.

  • q_from – A queue for messages the manager sends to the program.

  • term – An instance of blessed.Terminal used to interact with the terminal.

  • displays – (Optional.) Storage for the panels the program may want the manager to display.

Returns:

None.

Return type:

NoneType

Usage:

>>> from queue import Queue
>>> from threading import Thread
>>> from thurible import get_terminal, queued_manager
>>> from thurible.messages import End
>>>
>>> # Create a queue to send messages to the manager.
>>> q_in = Queue()
>>>
>>> # Create a queue to receive messages from the manager.
>>> q_out = Queue()
>>>
>>> # Get a terminal instance for the manager to use.
>>> term = get_terminal()
>>>
>>> # Run the manager in a separate thread.
>>> T = Thread(target=queued_manager, args=(q_in, q_out, term))
>>> T.start()
>>>
>>> # End the thread running the queued_manager.
>>> msg = End('Ending.')
>>> q_in.put(msg)
thurible.event_manager(event_map: dict[type, Callable] | None = None, initial_panel: Panel | None = None) None[source]

Manage a terminal display by mapping Response Messages to functions in your application.

Parameters:
  • event_map – (Optional.) A dict mapping the thurible.panel.Message types managers can send to applications (Response Messages) to functions in your application. These functions must accept a queue.Queue object and the response message as parameters. It must return a bool indicating whether the application should continue running.

  • initial_panel – (Optional.) The first panel displayed in the terminal. While this is technically optional, that’s just for testing purposes. You should really provide this to the manager. The panel passed this way will be stored as “__init”.

Returns:

None

Return type:

NoneType

Usage:

from thurible import event_manager, Splash
import thurible.messages as tm

# Create the event handlers.
def data_handler(msg, q_to):
    msg = tm.End('Quitting.')
    q_to.put(msg)
    return False

def ending_handler(msg, q_to):
    if msg.exception:
        raise msg.exception
    return False

# Map the handlers to event messages.
event_map = {
    tm.Data: data_handler,
    tm.Ending: ending_handler,
}

# Create the panel to display when the manager starts.
splash = Splash('SPAM!')

# Run the event_manager.
event_manager(event_map, splash)

The Manager Loop

Once started, a manager loops through a standard set of actions until it is told to close or crashes. Those actions are:

  1. Check for a message from the application.

    1. If there was a comand message, perform the commanded action.

    2. If the commanded action should return a response to the application, send that response.

    3. If there is no action for the command message received, send that message to the Panel.update() of the currently displayed panel.

  2. Check for a key press from the user.

    1. If there was a key press, send the blessed.keyboard.Keystroke object to the Panel.action() of the currently displayed panel.

    2. If the Panel.action() returns data, send that data to the application in a thurible.messages.Data message.

    3. If the Panel.action() returns an update, print that update to the terminal.

The loop will end under the following conditions:

  • The application sends a thurible.messages.End message,

  • The manager encounters a known exception it cannot recover from.

  • The manager encounters an unknown exception.

When possible, the manager will send a thurible.messages.Ending message to announce the end of the loop. If the loop is ending due to and exception, that exception is passed to the application within the thurible.messages.Ending message.

Storing Panels

To allow your application to pre-load panels and easily switch back and forth between panels without having to recreate them, the manager stores all panels sent to it with the thurible.messages.Store message or created with the thurible.messages.Alert message. Those messages allow you to assign a name to the panel, which is then used by other messages, like thurible.messages.Show, to interact with the stored panels.

Warning

Managers store panels in a dict object, using the name given to the panel as the key. This means that if you provide the same name for two panels, one panel will overwrite the other panel. For this reason, it is recommended all panels be given unique names.