• 沒有找到結果。

The toolkit be combined with the front-end IDE

Chapter 4 Implementation

4.2. Implementation of the embedding

4.2.1. The toolkit be combined with the front-end IDE

Making users write the program in PUML easily is our motivation. “Easily”

means users can install our toolkit in to the IDE easily, they write the program easily, and they get the result in the language they want easily. In order to simply the installation process of our toolkit, we package our toolkit as a plug–in. Figure 4-3 is the executable file after we package our toolkit.

Figure 4-3 the executable file after we package our toolkit

Users who want to use our toolkit can download the plug-in we have packaged, double click the executable file, and the installation is finished. This is the reason that we package our toolkit as a plug-in.

In the Figure 4-4, we demonstrate the structure of the basic plug-in which be plugged into Visual Studio .NET. This plug-in implements the IDTExtensibility2

interface, which serves as the main conduit for plug-in communication. It implements the interface’s five methods-OnConnection, OnStartupComplete, OnAddInsUpdate, OnBeginShutdown, and OnDisconnection. There’s no Main

method because it is destined to become a DLL. Instead, the OnConnection method serves as the plug-in’s entry point.

Figure 4-4 the basic structure of the plug-in

As we know now, an implementation of IDTExtensibility2 lies at the core of our plug-in. Visual Studio .NET calls the methods on this interface whenever it needs to apprise an plug-in of important events, such as when another plug-in is loaded or unloaded, or when Visual Studio .NET is about to shut down. The communication isn’t just one-way, either: through the IDTExtensibility2 interface, the plug-in has

access to and control over the entire Visual Studio .NET automation object model.

We will describe the implementation of IDTExtensibility2 interface in the following section:

„ OnConnection:

By far the most important of the IDTExtensibility2 methods, OnConnection provides a plug-in with the main object reference

it needs to communicate directly with the IDE.

„ OnStratupComplete:

The OnStrarupComplete event fires only in plug-in that load when Visual Studio .NET starts. An plug-in that loads at startup can’t always rely on OnConnection for its initialization-if the plug-in arrives too early, it will fail when it tries to access a Visual Studio .NET component that hasn’t loaded. In such cases, the plug-in can use OnStratupComplete to guarantee that Visual Studio .NET is up and running first.

„ OnAddInsUpdate:

The OnAddInsUpdate event fires when an plug-in joins or leaves the Visual Studio .NET environment. A plug-in can use this event to enforce dependencies on other plug-ins. The lack of useful parameters reveals OnAddInsUpdate’s passive-aggressive nature-it interrupts the plug-in to tell it that the state of some plug-in triggered the event. If you need to know the plug-in responsible for the event, you have to discover its identity on your own.

„ OnBeginShutdown:

This event fires only when the IDE shuts down while an

plug-in is running. Although an IDE shutdown might get canceled along the way, OnBeginShutdown doesn’t provide a cancellation mechanism, so a plug-in should assume that shutdown is inevitable and perform its cleanup routines accordingly. A plug-in that manipulates IDE state might use the event to restore the original IDE settings.

„ OnDisconnection:

This event is similar to OnBeginShutdown in that is signals the end of a plug-in’s life; it differs form OnBeginShutdown in that the IDE isn’t necessarily about to shut down. OnDisconnection also provides more information to an plug-in than OnBeginShutdown does.

The detail of the IDTEntensibility2 interface we have described above, and we summary the methods of the IDTEntensibility2 interface in Table 4-2.

Table 4-2 IDTEntensibility2 Interface

Method Description

OnConnection Called when the plug-in is loaded.

OnStratupComplete Called when Visual Studio .NET finishes loading.

OnAddInsUpdate Called whenever a plug-in is loaded or unloaded from Visual Studio .NET.

OnBeginShutdown Called when Visual Studio .NET is closed.

OnDisconnection Called when the plug-in is unloaded.

This is the basic structure of the plug-in. From now on, we can add the functions we want into the basic plug-in. After install the plug-in, the function of Visual Studio .NET will be increased.

In this combination phase, we need to determine what the controls has been dragged on the form by users. Because some of the controls have it own sub controls, in the process of determination, we need to find the sub controls. For example, when we edit the selection list, we will drag a Choice Group to the form, add several items on the Choice Group, and we have a selection list on the form. The Choice Group has its own sub controls. In the process of determination, we have to find out the entire sub controls that the Choice Group has. In the following is the algorithm how we determine the controls and the sub controls that they have. We name the algorithm for determination as Determination.

Determination (Control control) { if(control.SubContros = flase ){

generate the PUML code of this control, and the attributes of this control

} else {

Determination (control.SubCollection);

} }

For each control of the collection {

Determination (control);

}

In the algorithm above, we have a collection of the controls on the form. The collection is the record of the controls; we use this collection to get all the controls.

The collection has some function we can use, such as we can extract one of the controls from the collection, get the sub controls from the target control, and count the number of the controls.

At the first of the algorithm, we extract each control from the collection, determine whether the control we get has sub controls or not. If not, we can generate the PUML code of this control on the document. If the control has sub controls, we have to recursive call the algorithm Determination ( ). Until the control inputted into the algorithm has no sub controls, we can take the generation action to generate the PUML code.

Because the situation of adding sub controls is not complex, we can do the recursive call in our algorithm and don’t have to worry about the problem of complexity. We take an example to explain the addition situation of the sub controls. In our elements of PUML, <picture>, <label>, and <textnote> this three element have no sub elements to be added on. The element <listpaper> represents a selection list, and the element <item> is the item of the list added on the element <listpaper>. If the control represented the element <listpaper> is inputted into the algorithm Determination(), the algorithm will recursive call itself, and the sub control is inputted into Determination() will be the element <item>. Because the element <item> has no sub controls to be added on it, the recursive process will be stopped. After the code of

element <item> has been generated, the code of the <listpaper> will be generated in follow. This is the example about when the algorithm will stop. Because the sub controls added on the control are limited, there is nothing to worry about the complexity of the algorithm Determination(). If we define the parameter n as the number of the controls, the complexity of the algorithm will be O(n*n).

相關文件