18.4 Handling transmissions
The fundamental idea behind Glamour starts from the observation that the navigation flow should be orthogonal to the way of presentation. In Glamour, this navigation flow is captured through Panes, Ports and Transmissions: the Panes represent the building blocks, the Ports provide the hooks, and the Transmissions form the fiber of the browser by connecting the ports.
The following UML class diagram shows the most important classes and methods related to understanding Transmissions. A Transmission connects a destination port with one or multiple origin Ports. When triggered, the main job of the Transmission is to take the values from the origin ports and combines them to populate the destination port. Further behavior can be appended to this basic one through a transmission strategy.
An origin port can be either active (specified using from:port:
) or passive (specified using passivelyFrom:port:
). Only the active origin ports can trigger a transmission. This information is captured by the PortReference.
explain what is the use of a passive port
As mentioned, a Transmission can have several origin ports. This is achieved by sending multiple messages like from:port:
. As a result of triggering a transmission with multiple origins, the target port contains a special ordered collection populated with the values from the origins. These values are then accessible when defining the properties of the desired presentations.
In most cases transmissions originate in a #selection
port and have as destination an #entity
port. For convenience, Glamour provides some shorter messages that make use of this observation:
- For specifying a transmission origin that points to a
#selection
port of a pane, you simply usefrom:
. - Similarly, for specifying a transmission destination that points to an
#entity
port of a pane, you can useto:
.
The triggering of a Transmission can be controlled by a condition specification. This condition is set via a when:
message that takes as a parameter a block returning a boolean depending on the values of the origin ports.
Transmissions have deep control over the values passed around via transformation specifications. There are two hooks for such transformations.
The main transformation is offered by the Transmission itself and it comes in the form of a block that takes as parameters the values from the origin ports and returns the desired value to be set in the destination port. This can be specified via a transformed:
message sent to the transmission.
The second hook is provided by the PortReference. Using this transformation, we can transform each individual port before it gets in the Transmission transformation. We can specify such a transformation for each individual origin port using from:transformed:
or passivelyFrom:transformed:
.
Besides setting the value to a destination port, a Transmission can have further behavior via a TransmissionStrategy. This is useful when we want the transmission to also impact the presentations from the pane of the target destination. Besides the NoStrategy default strategy, there are two more semantics presently implemented:
- ReplacePresentationsStrategy replaces the presentations from the pane of the destination port with those specified by the strategy. This one is set via the
andShow:
message. - PresentIfNoneStrategy sets presentations only if none exits in the pane of the destination port. This one is set via the
andShowIfNone:
message.
Both the andShow:
and the andShowIfNone:
messages expect a block with one parameter consisting of a composite presentation that will be used by the transmission.
The following pieces of code offer some examples of the most common cases of transmissions:
"transmission with multiple origins that replaces presentations"
browser transmit
from: #paneOne;
from: #paneTwo port: #portB;
to: #paneThree;
andShow: [ :a |
"specification of presentations based on two variables" ].
"transmission that installs a presentation only if none exists in the target panel"
browser transmit
from: #paneOne;
to: #paneTwo;
andShowIfNone: [ :a |
"specification of presentations" ].
"transmission with multiple origins and with transformations"
browser transmit
from: #paneOne transformed: [ :paneOneSelectionValue |
"computation of the transformed value based on one variable" ];
from: #paneTwo port: #portB;
to: #paneThree;
transformed: [ :transformedPaneOneSelectionValue :portBValue |
"computation of the destination value based on two variables" ]
"transmission with one origin bound to the pane surrounding the browser
(i.e., the outside port)"
browser transmit
fromOutsidePort: #outsidePort;
to: #paneThree port: #portC.
"transmission with the origin bound to the #entity port of the pane of the browser"
browser transmit
to: #paneThree port: #portC.