Linkage View Persistence

[A New Related Page]

The Linkage view not being persistent was a major problem, and therefore, we decided to work on that.

We found it extremely difficultcult to understand the internal workings of the Action-based persistency model. Therefore, once we got familiar with them, we thought of documenting them so that a future programmer could easily come up to speed in this area.

Widget Movement

Following is a code walk-through for Linkage Widget Movement.


Figure 1

Figure 1 shows the activities in the Linkage view (Builder) when a user moves a widget. Accordingly, when the user moves a widget in the Linkage view, GEF calls getMoveChildrenCommand() in order to find out the command corresponding to widget movement. GEF sends the movement information in org.eclipse.gef.Request. This method is overloaded in WidgetXYLayoutEditPolicy such that it returns LinkageWidgetMoveCommand. GEF then calls execute on this command, which results in a SetWidgetLinkagePositionRequest inserted to the Event Channel.


Figure 2

The Runtime receiving the event from the Even Channel is shown in figure 2. LinkageGraphWidgetReactor is registered to receive SetWidgetLinkagePositionRequest and therefore it's receive() is invoked by the Event Channel. The reactor sets the corresponding widget property, which results in SetLinkageGraphPositionAction's execute() getting invoked. execute() writes the action to the Action Logger and calls fire().


Figure 3

The fire() method of an action, is where the actual steps related to perform it's task are carried out. For example, in SetLinkageGraphPositionAction, fire() invokes
the methods calls to perform the widget movement. As shown in figure 3, it creates a WidgetLinkageMoveEvent and sends to the Event Channel. LinkageViewAdapter
receives this event and finds the appropriate event handler, WidgetLinkageMoveHandler, using the event name. The handler's execute() is called which sets the location of the widget model.


Figure 4

Figure 4 indicates the sequence of actions related to restoring the widget movement action. DefaultActionMemento gets the corresponding action, SetLinkageGraphPositionAction and calls its execute(), which in turn calls fire(). The rest of the activities are the same as shown in figure 3.


Figure 5

Figure 5 shows how the sequence diagrams fit together.

Pipe Creation

In the Fluency builder, pipe is the connection between two widget anchors so that incoming event from one widget can be passed in to trigger the outgoing event/action in another widget. Our goal was to make Fluency store the pipe information in both builder and runtime so that author can easily continue work on his interface when reopening Fluency. Current Fluency follows action based persistence in which every operation is recorded as an action and gets logged if it is necessary for the restoration. In this section, we explain how pipe persistence works on both persist and restore phase.

In the following diagrams, we demonstrate a code walk through for pipe creation and pipe restoration in Fuency linkage view.


Figure 6

Figure 6 shows what happens when author creates a new pipe between two widgets. With the GEF framework, the corresponding command PipeConnectionCreateCommand gets invoked and its fire() method will create the model PipeConnection for the pipe's virtual representation. PipeConnection calls BasicFluencyRuntime's createLink() method to retrieve the instance of Fluency Pipe widget. The information passed to the Fluency runtime includes both source and target widgets, and source/target events. BasicFluencyRuntime then calls Fluency to get Pipe instance.


Figure 7

Figure 7 shows the next steps in pipe creation. In addition to creating and returning Pipe instance back to builder, BasicFluencyRuntime also create a LinkWithPipeAction and pass the information from the builder to this action by setting input docks of source widget, target widget and newly created pipe. Then action's fire() method is invoked. At this point, the pipe creation action gets logged and a PipeAddedEvent is sent out to event channel to notify builder that runtime information is updated.


Figure 8

Figure 8 mainly represents the pipe restoration process. Currently, Fluency workbench has two editors with a file associated with each of them when created. Only the file read by layout editor is used for both layout and linkage persistence. So in the diagram, LayoutEditor's restore() opens file and then calls Fluency's restore() and then calls Persistor's restore(). Persistor extracts the input file into a LinkList of DefaultActionMemento then calls each DefaultActionMemento's restore() in which memento's target widget, action associated with this widget and input docks for this action. Then the action gets executed. In this pipe restoration, we are only concerned about LinkWithPipeAction which is an internal class in FluencyReactor. When LinkWithPipeAction executes, it updates Fluency runtime and sends PipeAddedEvent through DefaultEventChannel back to builder to make pipe visually show up in the linkage view editor.


Figure 9

Figure 9 is the common part for both pipe creation and restoration. It shows how builder gets updated based on the information received from the Fluency runtime.

When PipeAddedEvent is sent to builder, LinkageViewAdaptor catches the event and passes it to PipeAddedHandler in which the pipe connection information is extracted from event, and PipeConnection gets updated with these information.


Figure 10

Figure 10 gives the overall diagram for both pipe creation and restoration. For pipe deletion, the similar steps should happen for UnLinkWithPipeAction. Current implementation has a problem with tightly coupling builder and Fluency runtime in the way directly invoking the runtime methods such as createLink in builder part. The system may need refactoring by adding the CreatePipeRequest to encapsulate the information in the builder such as source/target widget, source/target events/actions.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.