3D PLM Enterprise Architecture |
Middleware Abstraction - Object Modeler |
Using ComponentsCreating components, asking for interface pointers, and managing component life cycle |
Use Case |
AbstractThis article shows how to create interfaces. |
This use case is intended to show you how to create interfaces that declare either a type or a behavior that a component [1] can implement [2] and that can be used in client application [3].
[Top]
CAASysUsingComp is a use case of the CAASystem.edu framework that illustrates CATIA System framework capabilities.
[Top]
This use case illustrates the usage of components. They are created using a factory, and accessed and modified using pointers to the interfaces they implement. The use case shows also how to manage their life cycle. This use case uses a circle component that implements a circle type interface named CAAISysCircle, and another interface: CAAISysColorProperties.
[Top]
To launch CAASysUsingComp, you will need to set up the build time environment, then compile CAASysUsingComp along with its prerequisites, set up the run time environment, and then execute the use case [4].
Do not type the module name on the command line, but type CNEXT instead. When CATIA is ready, do the following:
[Top]
The CAASysUsingComp use case is made of several classes located in the CAASysUsingComp.m module of the CAASystem.edu framework:
Windows | InstallRootDirectory\CAASystem.edu\CAASysUsingComp.m\ |
Unix | InstallRootDirectory/CAASystem.edu/CAASysUsingComp.m/ |
where InstallRootDirectory
is the directory where the CAA CD-ROM
is installed.
[Top]
To create an interface such as CAAISysCircle, there are three main steps:
# |
Step |
---|---|
1 | Instantiating the component |
2 | Modifying the Component Instance Using the CAAISysCircle Interface |
3 | Retrieve and use a pointer to the CAAISysColorProperties interface |
4 | Attempting to retrieve a pointer to an interface that the circle component doesn't implement |
5 | Manage the component life cycle |
[Top]
... int ReturnCode = 0; CAAISysCircle * piSysCircleOnCircle = NULL; HRESULT rc = ::CATInstantiateComponent("CAASysCircle", IID_CAAISysCircle, (void**)&piSysCircleOnCircle); if (FAILED(rc)) return 1; ... |
The CATInstantiateComponent
global function creates an instance
of the CAASysCircle component and retrieves a pointer to CAAISysCircle.
The parameters are:
CAASysCircle |
Name of the component to instantiate. It's the name of its main class |
IID_CAAISysCircle |
IID of the interface to which a pointer is requested |
piSysCircleOnCircle |
The pointer retrieved to CAAISysCircle |
The CATInstantiateComponent
global function calls AddRef
for the piSysCircleOnCircle
pointer returned. To prevent from
memory leak, this pointer will be released when it will be no longer needed.
[Top]
... CATMathPoint Center(-4.f,0.f,0.f); rc = piSysCircleOnCircle->SetCenter(Center); ... // Process failing rc float Radius = 10.f ; rc = piSysCircleOnCircle->SetRadius(Radius); ... // Process failing rc CATMathVector Normal(1.f,0.f,0.f) ; CATMathVector Axis (0.f,1.f,0.f) ; rc = piSysCircleOnCircle->SetPlanar(Normal,Axis); ... // Process failing rc ... |
The center, radius, and support plane are successively set thanks to the SetCenter
,
SetRadius
, and SetPlanar
methods of CAAISysCircle
[1].
[Top]
... CAAISysColorProperties *piSysColorPropOnCircle = NULL; rc = piSysCircleOnCircle->QueryInterface(IID_CAAISysColorProperties, (void**)&piSysColorPropOnCircle); if (SUCCEEDED(rc)) { int red = 100; int green = 100; int blue = 100; rc = piSysColorPropOnCircle->SetColor(red, green, blue); ... // Check that the color is correctly set piSysColorPropOnCircle->Release(); piSysColorPropOnCircle = NULL; } else ReturnCode = 1; ... |
The pointer to the CAAISysCircle interface on the circle component can
be used to retrieve pointers to other interfaces implemented by the component,
such as a pointer to CAAISysColorProperties, using the QueryInterface
method. The variable used to return the pointer must be created with the CAAISysColorProperties
type and initialized to NULL
. Always test the returned HRESULT
value using the macros SUCCEEDED
and FAILED
. The SetColor
method of CAAISysColorProperties can then be used to set the circle color
to green. As soon as the pointer to xx is no longer needed, it is released, and
set tu NULL
.
[Top]
... CAAISysPointProperties * piSysPointPropOnCircle = NULL; rc = piSysCircleOnCircle->QueryInterface(IID_CAAISysPointProperties, (void**)&piSysPointPropOnCircle); if (SUCCEEDED(rc)) { cout << "The circle component doesn't implement CAAISysPointProperties" << endl; cout << "This trace should never be displayed" << endl; piSysCircleOnCircle->Release(); piSysCircleOnCircle = NULL; } else { cout << "QueryInterface fails: this trace should always be displayed" << endl; } ... |
The pointer to the CAAISysCircle interface on the circle component is
used to retrieve a pointer to CAAISysPointProperties. The variable used
to return the pointer must be created with the CAAISysPointProperties
type and initialized to NULL
. But since the circle component
doesn't implement this interface, QueryInterface
will always fail.
Even if this seems improbable, you may find components that you expect to
implement a given interface and that do not. For example, you may get a list of
pointers to an interface implemented by a set of components, and ask these
pointers for another interface. Some of the components may not implement it, and
the calling code falls in the case described above. This is the reason why the
returned HRESULT
value must be tested using the macros SUCCEEDED
and FAILED
.
[Top]
... piSysCircleOnCircle->Release(); piSysCircleOnCircle = NULL; ... |
The only pointer that remains at thi spoint is piSysCircleOnCircle
.
The other pointers created or retrieved were released as soon as they were no
longer needed, and set to NULL
to prevent from a fortuitious but
illegal usage. To prevent from memory leak, piSysCircleOnCircle
is
released and set to NULL
.
[Top]
This use case shows how to use a component, that is how to create a component
using the CATInstantiateComponent
global function and retrieve a
pointer to an interface the component implements. Using this interface pointer,
the component is initialized, and a pointer to another interface is asked for,
and used. Then a pointer to an interface that the component doesn't implement is
asked for, to show what to do if this happens. The component life cycle is
managed by releasing and setting to NULL the interface pointers as soon as they
are no longer needed.
[Top]
[1] | Creating Components |
[2] | Creating Interfaces |
[3] | Object Modeler Component and Implementation Inheritance |
[4] | Building and Launching a CAA V5 Use Case |
[Top] |
Version: 1 [Mar 2000] | Document created |
[Top] |
Copyright © 2000, Dassault Systèmes. All rights reserved.