Virtual bus¶
The VirtualBus is a class encapsulating different communication mechanism to allow different controllers and widget to exchange controls and/or data streams. It provides a "Qt-like" mechanism of signal connection through the psygnal package, where objects can dinamically register signals and connect to remote slots for communication in the main thread.
Signal connection¶
The VirtualBus allows to create a connection between objects living in different plugins.
Suppose you have the following example:
In a normal scenario where you have access to the codebase of both Emitter and Receiver, you would simply do the following:
emitter = Emitter()
receiver = Receiver()
emitter.sigSender.connect(receiver.receiver_slot)
emitter.sigSender.emit(10)
# prints "I received 10"
Redsun operates by dinamically loading plugins, which means that Emitter and Receiver may come from different packages.
The VirtualBus takes care of giving a common exposure and retrieval point between different plugins. The catch is that to be able to share a connection, Emitter and Receiver must be adapted to talk to the bus:
from sunflare.virtual import VirtualBus
class Emitter:
sigSender = Signal(int)
def __init__(self, virtual_bus: VirtualBus) -> None:
self.virtual_bus = virtual_bus
def registration_phase(self) -> None:
self.virtual_bus.register_signals(self)
from sunflare.virtual import VirtualBus
class Receiver:
def __init__(self, virtual_bus: VirtualBus):
self.virtual_bus = virtual_bus
def receiver_slot(param: int) -> None:
print("I received", param)
def connection_phase(self) -> None:
self.virtual_bus["Emitter"]["sigSender"].connect(self.receiver_slot)
With this modifications, Emitter has informed the VirtualBus of the existence of sigSender, and Receiver can retrieve sigSender from Emitter to connect the signal to its slot receiver_slot.
This enforces a specific call order: all Emitter-like object must call the registration_phase method before any Receiver-like´object can call the connection_phase method, otherwise there will be a mismatch.
Note
If a Receiver-like object tries to connect to a non-defined signal, your application will not crash, but there will be simply no connection enstablished with your slots.
As a user, you only need to provide these two methods to ensure a safe connection. When Redsun is launched, it takes care of calling registration_phase and connection_phase in the correct order to ensure a safe connection.
Using Sunflare without Redsun
If you're using Sunflare in a non-Redsun application, you'll have to:
- create an instance of
VirtualBus; - ensure
Emitterobjects call theirregistration_phasemethod beforeReceiverobjects call theirconnection_phasemethod.