0% found this document useful (0 votes)
7 views

workshop_net_plugins

Uploaded by

Linda Fu
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

workshop_net_plugins

Uploaded by

Linda Fu
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

PARASOLID WORKSHOP.

NET PLUGIN
CREATION GUIDE
Important Note

This Software and Related Documentation are proprietary to Siemens Industry Software Inc.

© 2020 Siemens Industry Software Inc. All rights reserved.


TABLE OF CONTENTS

Introduction .............................................................................................................................................. 3

Who Should Read this Guide? .................................................................................................................. 3

Why Should I Write a Plugin? ................................................................................................................... 4

Plugins and Alternative Approaches ......................................................................................................... 5

Plugin Implementation and Architecture ............................................................................................. 5

When Should I Write a Plugin? ............................................................................................................. 6

When Should I Consider Alternative Approaches? ............................................................................... 6

Code Walkthrough for a Simple Plugin ..................................................................................................... 7

What the Plugin Does ........................................................................................................................... 7

Application Startup ............................................................................................................................... 7

Responding to the Standard Plugin Event to Create Menu Items ........................................................ 8

Providing a Service ............................................................................................................................... 9

How Do I Add a Plugin to Workshop.Net? .............................................................................................. 10

A More Complex Plugin: Requesting Services and Adding New Behaviour ........................................... 11

What the Plugin Does ......................................................................................................................... 11

Sending Messages to Request Services .............................................................................................. 12

Functions for Sending Messages ........................................................................................................ 12

Passing Data to Delegates .................................................................................................................. 12

Adding New Behaviour and Maintaining Existing Functionality ......................................................... 14

How Do I Create a New Application with a Plugin? ............................................................................... 16

Integrating a Plugin in Workshop.Net: Guidelines ................................................................................. 17

Recommendations for Successful Extension of Workshop.Net ......................................................... 17

A Simple Approach to Plugin Design .................................................................................................. 17

Managing Models and Windows ........................................................................................................ 18

Appendix A – Glossary ............................................................................................................................ 19

Appendix B - The Plugin Lifecycle ........................................................................................................... 20


INTRODUCTION

The Parasolid Workshop.Net Plugin Creation Guide provides information to help you extend
Workshop.Net by using its ‘plugin’ mechanism. It also explains how to use this mechanism in other
applications.

WHO SHOULD READ THIS GUIDE?

This guide is for experienced users of C# and Visual Studio who are interested in using
Workshop.Net’s extensibility mechanism, either to extend Workshop.Net or to create further
applications. Less experienced C# users may need to refer to standard reference material for C# and
Visual Studio in addition to this guide.
WHY SHOULD I WRITE A PLUGIN?

By writing a plugin, you can extend Workshop.Net’s functionality. You can create a self-contained,
custom component which is fully integrated with existing Workshop.Net features such as model
display and entity selection. You can easily re-use many of the capabilities of Workshop.Net’s source
code, such as gathering and managing information about Parasolid models.

The plugin mechanism supports self-contained extensions to Workshop.Net: optional components


which you can include or omit from the application as you wish.

Parasolid Application Framework

Existing Workshop.Net Plugins Your Custom Plugins


The plugin mechanism is also extremely flexible: a plugin may define a whole new application, built on
the Parasolid Application Framework but not dependent on the Workshop.Net user interface. (The
Parasolid C# Example Application is built by using the plugin mechanism in this way.)

PLUGINS AND ALTERNATIVE APPROACHES

The plugin mechanism is powerful and flexible but is not the only way to extend Workshop.Net. You
might alternatively choose to add your functionality simply by adding code to existing plugins or other
components of the Workshop.Net source.

PLUGIN IMPLEMENTATION AND ARCHITECTURE

In C# implementation terms, a plugin is a collection of classes, one of which implements a required C#


interface. Plugins provide services to the rest of the application by responding to custom events which
may be referred to as plugin messages (indicated by two-way arrows in the following diagram).

Plugin 2

Plugin 3
Plugin 1

Main
Application
A plugin is typically built in its own DLL, separate from the main application executable and other
plugins. Plugins, then, have the advantage of being self-contained and potentially optional
components of an application. Creating a plugin involves writing code to support plugin messaging,
however, which is not needed if you add functionality in other ways.

WHEN SHOULD I WRITE A PLUGIN?

In the following situations, you should write a plugin.

• Re-use of the application framework from the Workshop.Net source to build a new
application
• Extension of Workshop.Net where the extension must build as a separate .Net assembly and
be an optional component
• Integrating functionality in various versions of Workshop.Net with minimal effort (so that
you need as few code-changes as possible when you install the latest release of
Workshop.Net)

WHEN SHOULD I CONSIDER ALTERNATIVE APPROACHES?

Adding code without making a new plugin may be more efficient when:

• You need to add only a small amount of functionality


• You do not need an optional component (i.e. a separate C# assembly or DLL)

Implementation Advice: When deciding whether to create a plugin, you should also
consider application testing. Plugins often communicate with the rest of the application
via events, rather than calling functions directly, which means that certain coding faults
become evident at run time rather than build time. So interactive testing is particularly
important for plugins.
CODE WALKTHROUGH FOR A SIMPLE PLUGIN

The following code walkthrough describes the source code for a simple Workshop.Net plugin and
shows how a plugin operates. For more formal documentation of the plugin mechanism (glossary and
details of the plugin lifecycle), see Appendices A and B of this guide.

The source code of the Example Plugin is in the Workshop.Net solution (project ‘Workshop.Example’).
You may wish to examine the code as you read this walkthrough.

WHAT THE PLUGIN DOES

The Example Plugin provides a simple service: it reports the number of faces on the model in
Workshop.Net’s active display window.

APPLICATION STARTUP

On application startup, the plugin mechanism calls the method ‘RegisterPlugin’ in the class which
implements the interface ‘IFrameworkPlugin’. (See PluginRegistration.cs for the code of this method.)

This ‘RegisterPlugin’ method calls ‘PluginManager.RegisterPlugin’ several times to associate delegates


(functions) with plugin events (messages). This association means that, when the application is
running, the plugin manager calls the appropriate delegate in response to a given event. For example,
the Example Plugin’s function ‘ExampleMenuItem_Click’ gets associated with the event whose string
identifier is “ExampleMenuItem_Click”. This association means that when the event named
“ExampleMenuItem_Click” is passed to the plugin manager from any part of the application, the
plugin manager calls the function ‘ExampleMenuItem_Click’. (The delegate name and the string
identifier of its associated event are the same in this case, but need not be the same in general.)

The rest of the code in PluginRegistration.cs implements the delegates and the constructor of the
‘RegisterPlugin’ class.

Key Concepts

• On application startup, the Plugin Manager executes the RegisterPlugin


method of any class which implements the IFrameworkPlugin interface
• The RegisterPlugin method of the plugin sets up associations between
delegates and plugin events
RESPONDING TO THE STANDARD PLUGIN EVENT TO CREATE MENU ITEMS

One of the events which has a delegate specified in ‘RegisterPlugin’ is


‘StandardPluginEvents.CreateMenuStripItems’. This is a standard event which is provided in the
Workshop.Net source code and is expected to be re-used by plugins (see ‘StandardPluginEvents.cs’ in
the project ‘Framework.PluginManager’ for the full list of standard plugin events). The delegate
specified for this event is the ‘CreateMenuStripItems’ function of the Example Plugin.

When the constructor of Workshop.Net’s main user interface runs, it sends the plugin event
‘StandardPluginEvents.CreateMenuStripItems’ to the plugin manager (see constructor in ‘MainGUI.cs’
in project ‘Workshop.GUI’). The plugin manager then calls all the delegates associated with this event.
Since the ‘CreateMenuStripItems’ function of the Example Plugin is one of these delegates, it gets
called when the user interface is created. The ‘CreateMenuStripItems’ function adds an appropriate
menu item to the Workshop.Net menu strip.

Key Concepts

• There are predefined standard plugin events and you can find these in the
Workshop.Net source code
• When the application code sends a plugin event (message) to the plugin
manager, the plugin manager calls all delegates which have been registered
for that event
PROVIDING A SERVICE

The Example Plugin provides a service in response to the user’s clicking on ‘Example Plugin->Example
Menu Item’. The code in ‘CreateMenuItems’ sets up this menu item to send the plugin event
“ExampleMenuItem_Click” when the item is clicked. So, when the item is clicked, the delegate
‘ExampleMenuItem_Click’ gets called because it has been registered to handle that plugin event. This
delegate displays the Example Plugin’s form. When the user clicks the ‘OK’ button on the form, the
plugin reports the number of faces on the body in the active display window.
HOW DO I ADD A PLUGIN TO WORKSHOP.NET?

To add a plugin to Workshop.Net, you can take the following steps.

1. Open the Parasolid Workshop.Net solution from the Workshop.Net sub-directory of the
source directory. This solution contains a set of plugins which implement Workshop.Net’s
specific functionality. It also references Framework projects, including the definition of the
plugin mechanism itself and many Parasolid-specific and general utilities.
2. Add a new Class Library Project to the solution. Name your new Workshop plugin
“Workshop.XXX” and use the “PLMComponents.Parasolid.Workshop.XXX” namespace for
your plugin code. The plugin mechanism does not restrict the name or namespace but this
naming scheme is recommended. A Class Library project should build as a DLL.
3. Add a post-build event to your plugin project, to ensure that your plugin DLL is copied to
Workshop.Net’s central build area. You can do this via the ‘Project Properties’ for your
plugin project. This post-build event is needed because the plugin DLL needs to be in the
‘Plugins’ subdirectory of the Workshop.Net executable’s working directory in order to be
detected on application startup. To allow debugging, the pdb file for the plugin must also be
in this subdirectory. You can use the following code for the event and you should set it to run
“Only when the build updates the Project output”.

echo ----Copying Built Files to Solution Level output


directory----

xcopy /y /f /e /r "$(TargetPath)"
"$(SolutionDir)Build\$(ConfigurationName)\Plugins\"

if “$(ConfigurationName)”==”Debug” echo ----Copying PDB


Files to Solution Level output directory----

if “$(ConfigurationName)”==”Debug” xcopy /y /f /e /r
"$(TargetDir)$(TargetName).pdb"
4. Add references in your plugin project to Framework.PluginManager and
"$(SolutionDir)Build\$(ConfigurationName)\Plugins\"
Framework.ExceptionManager. In order to re-use existing code from other Framework or
Workshop.Net projects, add references to these projects as required.
5. Create a class which implements the IFrameworkPlugin interface. This interface is defined
in PLMComponents.Parasolid.Framework.Plugins. It is essential since it allows Workshop.Net
to recognise your DLL as a plugin. Your class must have a constructor and must implement a
RegisterPlugin function which returns void and accepts no arguments. This function should
register any delegates to handle plugin events. See code walkthroughs and source code for
examples.
6. When you have built Workshop.Net including your plugin, you should be able to run and
debug the application according to the instructions in the Parasolid Workshop.Net Source
Code Overview. The information in the ‘Overview’ about copying the Parasolid library and
schemas to the build directory and setting the correct executable for debugging is
particularly relevant.
7. Add code to your plugin to implement your new functionality. You should take into account
the information from the code walkthroughs and other sections of this guide.

Implementation Advice: Inserting breakpoints in your RegisterPlugin function and


debugging through it as soon as you have written it lets you check that your plugin is
loaded and registered correctly.

A MORE COMPLEX PLUGIN: REQUESTING SERVICES AND ADDING NEW


BEHAVIOUR

The basic sequence of operations, on application startup and when responding to events, is the same
for all plugins. Certain features of a more complex plugin than the Example Plugin are of particular
interest, however.

• Plugins may send messages as well as responding to them


• If a delegate is associated with the same event as any existing delegates then it should avoid
interfering with existing functionality

The source code for the following discussion of a more complex plugin, the Boolean Plugin, is in the
Workshop.Net solution (project ‘Workshop.Boolean’).

WHAT THE PLUGIN DOES

The Boolean Plugin supports Boolean operations on Parasolid models: unite, subtract and intersect,
with various options for merging topology. To allow the user to set up these operations, this plugin
uses existing application functionality via plugin messages.

The following discussion concerns the Boolean Plugin’s use of the plugin mechanism, rather than the
details of the modelling operations (which are implemented using standard Parasolid coding
practices).
SENDING MESSAGES TO REQUEST SERVICES

One of the actions which this more complex plugin takes is to request services from other parts of the
application by sending plugin messages. You can see an example of this action in the function
‘SelectedEntity’ in the file BooleanControl.cs. The function sends the standard plugin events
“UnselectEntity” and “SelectEntity”, to unselect an entity in the current display window and select the
whole body instead. (In the following picture, the user has clicked on a face of the target body – if the
Boolean Plugin were not operating then only the face would be selected, but since the Boolean Plugin
is active the whole body is selected and is shown in red.)

FUNCTIONS FOR SENDING MESSAGES

The functions for sending messages are ‘SendSynchronousMessage’ and


‘SendAsynchronousMessage’. The ‘synchronous’ function causes the delegate(s) associated with an
event to be run in the current thread. The ‘asynchronous’ function causes the delegate(s) associated
with the event to be run in a new thread. Both functions take a PluginEvent structure as input, but
only the ‘synchronous’ function returns data (an array of PluginEventResult structures) since the
calling thread for an asynchronous call might not exist when all the delegates finish. You should use
the ‘synchronous’ function unless you particularly require a new thread.

PASSING DATA TO DELEGATES

You can pass arguments to the event handler using one of the constructors of the ‘PluginEvent’
structure, as in the following code. The following sample code sends both an event and a string
argument containing information for any delegates associated with the event.

PluginEventResult[] res = PluginManager.SendSynchronousEvent(new


PluginEvent("Event", new PluginEventArgument(“StringArgument”,
typeof(string))));
Implementation Advice: Allow for the possibility that there are several delegates or no
delegates associated with an event. When using existing events, always check the source
code to find out which arguments to supply and which results may be returned. Code
defensively when receiving plugin inputs or processing PluginEventResult arrays.

Plugin Delegate
•Receives
• Sends event and
PluginEventArgument
PluginEventArgument
•Provides service
• Receives
and/or returns
PluginEventResults
PluginEventResults
ADDING NEW BEHAVIOUR AND MAINTAINING EXISTING FUNCTIONALITY

One of the delegates in the Boolean Plugin responds to the event for selection of an entity (see the
delegate ‘EntitySelected’ in this plugin’s PluginRegistration.cs file). This standard plugin event is raised
by the Workshop.Net GUI when the user clicks on an entity within a Parasolid model. This event has
delegates associated with it already, to provide Workshop.Net’s default selection behaviour. So, while
the Boolean Plugin’s delegate needs to provide plugin-specific behaviour while the plugin is active, it
must also preserve the default behaviour when the Boolean Plugin is not in use.

When the Boolean plugin’s form is visible, the Boolean Plugin’s delegate overrides the standard
behaviour of Workshop.Net for the “StandardPluginEvents.EntitySelected” event: it selects the whole
body rather than an entity on the body. When the Boolean Plugin’s form is not shown, however, this
specific behaviour should not override the standard behaviour, so the Boolean Plugin’s delegate does
nothing. (The delegate checks for the Boolean Plugin’s form being set to ‘null’ in order to determine
whether the form is visible: other code within the plugin ensures that this value is null when the form
is invisible – see function ‘BooleanCtrl_VisibleChanged’ for details.)

The following picture shows the behaviour of the application when the Boolean Plugin’s form has
been closed: the user has selected a face on the model and only the face is highlighted in red, rather
than the whole body as would be selected for a Boolean operation.

Key Concepts

• A plugin can send messages and other information to the rest of the
application code in order to use services or get information
• The functions for sending messages are ‘SendSynchronousMessage’ and
‘SendAsynchronousMessage’
• A plugin’s delegates may override the application’s default functionality if they
respond to standard plugin events.
Key Concepts Summary

• On application startup, the Plugin Manager executes the RegisterPlugin


method of any class which implements the IFrameworkPlugin interface
• The RegisterPlugin method of the plugin sets up associations between
delegates and plugin events
• There are predefined standard plugin events and you can find these in the
Workshop.Net source code
• When the application code sends a plugin event (message) to the plugin
manager, the plugin manager calls all delegates which have been registered
for that event
• A plugin can send messages and other information to the rest of the
application code in order to use services or get information
• The functions for sending messages are ‘SendSynchronousMessage’ and
‘SendAsynchronousMessage’
• A plugin’s delegates may override the application’s default functionality if they
respond to standard plugin events
HOW DO I CREATE A NEW APPLICATION WITH A PLUGIN?

To make a new application by using your own GUI with the Framework, write a plugin which responds
to the message ‘StandardPluginEvents.CreateGUI’. Then the Framework calls your delegate for this
message in a new thread during application startup. In this scenario you should start with an empty
Framework solution, rather than with the Parasolid Workshop.Net solution. The Framework solution
contains only Framework projects (not the plugins which implement Workshop.Net) and is in the
Framework sub-directory of the installed Workshop.Net source directory. Add a new Class Library
project to begin coding your plugin, as in the preceding section “How Do I Add a Plugin to
Workshop.Net?”.

In your event handler, you should create and display the appropriate GUI elements (e.g. Windows
Forms). This event handler should also return a result to indicate that the GUI has successfully started.
For example:

Application.Run(new Form1());

return new PluginEventResult(true, typeof(bool));


INTEGRATING A PLUGIN IN WORKSHOP.NET: GUIDELINES

You are free to adjust existing Workshop.Net functionality when adding a plugin, but you may find the
following recommendations useful if you wish to keep the existing behaviour.

RECOMMENDATIONS FOR SUCCESSFUL EXTENSION OF WORKSHOP.NET

Check Validity After If your plugin creates or changes Parasolid models,


Modelling Operations then ensure that the models are valid before
Workshop.Net displays them. Workshop.Net uses
Parasolid line-rendering and faceting, which requires
valid Parasolid models.

Consider If your plugin might hold a significant amount of


Memory/Resource Usage memory or other resource while inactive, then
consider limiting this usage. For example, you could
set some variables to null when your plugin is
inactive, to allow memory to be reclaimed by the
garbage collector, or use an explicit ‘Dispose’
method.

Multiple Application Workshop.Net, as shipped, uses only one thread to


Threads call Parasolid. Therefore, it uses a single exclusive
thread chain for fastest performance and handles
errors assuming that only one thread calls Parasolid.
If you call Parasolid from multiple threads
simultaneously then you need different strategies for
error handling and thread chains.

A SIMPLE APPROACH TO PLUGIN DESIGN

A simple approach for adding plugins to Workshop.Net is to use the source code of existing plugins as
a model. This approach ensures that your plugin delegates operate only when your plugin is visibly
active and ensures that your plugin does not store data unnecessarily.

This approach is useful but is not imposed by the plugin mechanism: by default, plugins have the
flexibility to operate differently. You could define an extended plugin interface if you require plugins
to conform to a more formal standard.
MANAGING MODELS AND WINDOWS

Relationship between A display window in Workshop.Net is a view of a


Models and Windows model (or several models). One model may be visible
in several windows, particularly if the user uses
‘Combine All Parts’ (from the File Menu). Opening a
new display window does not mean creating a new
model. (In the picture below this table, the model in
the bottom right corner is shown in all three
windows but under different viewing and selection
conditions.)

The ‘Active’ Window The display window which has been most recently
selected by the user is considered to be ‘active’.
When there is only one display window, it is always
the active window.

Updating Window If your plugin deletes a part from the Parasolid


Information session then your plugin must also update the parts
list of any display windows which show that part.
(There is no automatic mechanism to correct a
display window’s parts list.) Keeping the parts list up-
to-date is also important because existing plugins
may depend on it. You can use the
‘UpdatePartsInDisplay’ event to set the parts list
correctly.
APPENDIX A – GLOSSARY

Application Framework A C# codebase providing the basis for a new application, including its
main executable. The Framework comprises the
PLMComponents.Parasolid.Framework namespace. (Workshop.Net is
an application built using the Application Framework.)

Plugin A plugin typically provides an extension to Workshop.Net specifically


or to the Application Framework more generally (a plugin is not a
standalone application). This extension may be anything from a
minimal “service” to a fully featured GUI. In implementation terms, a
plugin is a set of C# classes, one of which implements the
IRegisterPlugin interface defined in the Application Framework.

Service A service is an appropriate response to a plugin message or set of


messages. As an example, a service might consist of returning the
number of Parasolid models in a window in response to a specific
message.

Plugin Message Handler A function which is registered with the Plugin Manager to respond to
a particular message. A Message Handler accepts arguments and
returns a response to the application. Both the arguments and the
response can be an object of any type.

Plugin Message A Plugin Message is a structure that is passed to a Plugin Message


Handler. It comprises an identifying name and a set of arguments
which are specific to the message with that name.

Plugin Manager The Plugin Manager is the base functionality in the Application
Framework which starts and runs plugins. The Plugin Manager also
delivers messages to plugins. All plugins should register message
handlers with the Plugin Manager to identify the messages to which
they can respond and to associate each message handler a specific
message.
APPENDIX B - THE PLUGIN LIFECYCLE

The plugin mechanism involves passing messages between various components in the Framework.
The components register delegate functions for specific event messages. When an event occurs, the
plugin mechanism calls the registered delegate functions for that event and passes to the delegate
functions any arguments associated with the event. The plugin lifecycle is:

1. The Plugin Manager is created during application start-up.

2. The Plugin Manager searches a pre-defined directory (‘Plugins’) for .Net assemblies, loads
the assemblies and searches within them for any class which implements the
IFrameworkPlugin interface.

3. The Plugin Manager executes the RegisterPlugin method of any class which implements the
IFrameworkPlugin interface.

4. During each call to IFrameworkPlugin.RegisterPlugin, the plugin’s code calls the


PluginManager.RegisterPlugin method once or more, passing a specified delegate function
and its associated event message to the Plugin Manager. The delegate function must
conform to a specified prototype.

5. At some point during its execution, the application raises a plugin event with the Plugin
Manager.

6. The Plugin Manager examines the list of all the plugins currently registered with that event
and calls all the delegate functions associated with the raised event. (These functions may be
from any plugin and may be called in any order.)

7. When a delegate function has finished executing, it returns a result to the Plugin Manager.

8. The Plugin Manager collates the results from all the delegate functions that it called in
response to the raised event and passes these back to the calling function (i.e. the function
which raised the event).

9. When the application is shut down, any plugin assemblies that are in memory are unloaded
with the rest of the application.

You might also like