Here you will find implementations details
Tracing functionality consists of following projects:
This feature provides three new views:
Those views are grouped under a new perspective called Erlang Tracing. To provide communication between all views an Observer pattern was used. Each view is represented by class that implements org.erlide.tracing.core.ITraceNodeObserver. This interface must be implemented by every class that want be notified by org.erlide.tracing.core.TraceBackend whenever some event occurs. org.erlide.tracing.core.TraceBackend is a singleton class that is responsible for creating tracing node and running tracing tool (ttb) on it. When a view is created it registers itself in org.erlide.tracing.core.TraceBackend as an listener. Following diagram shows relations between those classes:
Such design makes it easy to add a new view (in future there should be added view that represents trace events in a form of sequence diagram). Every view performs action on org.erlide.tracing.core.TraceBackend (e.g. starting/stopping tracing) and this class after performing action, notifies all views (listeners) so they can update themselves.
Erlang trace browser and Erlang tracing tree viewer views use JFace TreeViewer to display data. TreeViewer provides mvc architecture to raw SWT Tree class. To create a tree view you need:
new TreeViewer(container, SWT.SINGLE);
setContentProvider()
method (Content provider is a class that provides data to be displayed).setLabelProvider()
method (Label provider is a class that tells tree viewer how to display each element).You can find good example of creating tree viewer here:
In tracing plugin there is an org.erlide.tracing.core.mvc.model.treenodes.ITreeNode interface which should be implemented by class that represents concrete tree node. Following class diagram shows those classes:
Most of the nodes in Erlang tracing tree viewer view are represented by TreeNode class. However nodes representing functions and modules are represented by FunctionNode and ModuleNode classes. It is because when user double-clicks on them some action should be invoked (classes are used to distinguish type of node that was selected). In Erlang trace browser view are nodes are instances of TracingResultsNode because they contain some additional information, such as path, dates and number of events. Data for each tree viewer is stored in different list. You can obtain those list from org.erlide.tracing.core.mvc.model.TraceCollections using static methods:
getFilesList()
- data displayed in Erlang trace browser (all tracing results loaded into Eclipse)getTracesList()
- data displayed in Erlang tracing tree viewer (content of selected tracing result)TreeContentProvider and TreeLabelProvider provide data to be displayed.
All listeners assigned to tree viewer act as controllers.
TableViewer is a JFace class that provides mvc architecture to raw SWT Table class. It works very similar to TreeViewer, i.e. you also have to provide label and content providers. Only difference is that some fields can be edited. In such situation you have to provide two extra classes:
To show busy dialog you can use following code (from wikipedia):
IRunnableWithProgress op = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) {
runDecathlon(monitor);
}
};
IWorkbench wb = PlatformUI.getWorkbench();
IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
Shell shell = win != null ? win.getShell() : null;
new ProgressMonitorDialog(shell).run(true, true, op);
In this way job is executed in new thread while execution of UI thread pauses until run method is finished (i.e. work is done). However, in tracing feature sometimes we need to show busy dialog when calling one method and hide it when another method is called. It is because of design which uses observer pattern: one view invokes an action and when this action is finished its “notify” method is invoked to signal that action is done. Consider loading files:
finishLoadingFile
method so each view can refresh itself if it is needed. In case of browser view it should hide busy dialog.Similar use case is when stopping tracing.
To provide this functionality org.erlide.tracing.core.ui.dialogs.RunnableWithProgress abstract class was implemented. All work (e.g. initialize loading file) you implement in abstract method doAction()
of extending class. Then you pass instance of this class to ProgressMonitorDialog.run()
method and after it you put code which has to be executed when busy dialog is hidden. In method which will be called when job is done you have to call RunnableWithProgress.finish()
. Here is an example:
//create variable that represents task
private RunnableWithProgress task;
//................
public void widgetSelected(SelectionEvent e) {
task = new RunnableWithProgress("Loading trace results...") {
@Override
public void doAction() {
//initialize loading
}
};
//show busy dialog
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
new ProgressMonitorDialog(shell).run(true, false, task);
//execute when dialog is hidden:
doAfterLoadingTraces();
}
//................
//called to notify that loading is finished
public void notify() {
if (task != null)
task.finish();
}
This section describes main use cases.
All UML diagrams were created using Eclipse UMLet plugin. Sources of diagrams are available in doc/uml directory of org.erlide.tracing.core project.
Did you find errors in the documentation? Do you have improvements to suggest? Suggest edits!