Extension feature

Collaboration diagram for Extension feature:

A simulated object which is a child of the extensible simulated object class can add to itself extensions (children of Extension class). More...


Modules

 Extensions
 Some extensions.

Classes

class  OMK::ContainerExtension
 An extension which is a container for other extensions. More...
class  OMK::DuplicatedAttributeExtension< AttributType, Type >
 Extension to add an offset to a Transform attribute of the object. More...
class  OMK::Extension
 Ancestor of every extension of extensible simulated objects. More...
class  OMK::ExtensionT< SimulatedObjectType >
 Specialisation of Extension which references the extension owner. More...
class  OMK::ExtensionCreator
 Ancestor of every Extension creator class used by the PrototypeFactory. More...
class  OMK::ExtensionCreatorT< T >
 Extension creator class to be parametrized by the descendants of Extension. More...
class  OMK::ExtensionManager
 Ancestor of classes which manage extensions. More...
class  OMK::ExtensionOfExtensionCreatorEvent
 Extension to create extension by event. More...
class  OMK::ExtensibleSimulatedObject
 Ancestor of every extensible objects. More...
class  OMK::TriggerContainerExtension
 An extension which is a container for other extensions. More...
class  OMK::MultiTriggerContainerExtension
 An extension which is a container for other extensions. More...

Macros.

#define DECLARE_EXTENSION_FACTORY(ExtensionClass)
 This define declares factory utilities, constructor and destructor for an extension.
#define DECLARE_TEMPLATE_EXTENSION_FACTORY(ExtensionClass, Type)
 This define declares factory utilities, constructor and destructor for an extension.
#define REGISTER_EXTENSION_FACTORY(ExtensionClass, Id)
 This define implements factory utilities, constructor and destructor for an extension.
#define REGISTER_TEMPLATE_EXTENSION_FACTORY(ExtensionClass, Id)
 This define implements factory utilities, constructor and destructor for an extension.

Typedefs

typedef OBT::Singleton< OBT::PrototypeFactory<
OMK::Name, ExtensionCreator > > 
OMK::ExtensionFactory
 The factory of the extension.

Detailed Description

A simulated object which is a child of the extensible simulated object class can add to itself extensions (children of Extension class).

The aim of the extension is to provide a simple way to extend the simulated object initialisation, behavior, functionnality,... In this aim the extension provides an interface to extend the initialising, configuration and computing.

The structure of the extensible object is:

extensionUML1.png

How to implement an extension ?

There is macros to help to declare and implement extensions.

Example of use for an extension which redefines the preComputeParameters (can redefine any other virtual member):

The other base class for extension is ExtensionT. This class stores the owner of the extension. See How to retrieve the owner of an extension ? for more details.

Live cycle of an extension

Creation

The extension can be created: See below How to create an extension ?

Creation

The destruction of an extension can be made in two manners: The extension can be only remove of the object, but it is not deleted, with removeExtension. This method returns the extension, the one which calls the method has to take in charge the extension because the object doesn't know it anymore, and it will not delete it.

How to create an extension ?

There is many ways to add an extension to a simulated object :

In the constructor

In the constructor of the simulated object, this one can add to itself some extensions. This offers the opportunity to add some parameters to the extension constructor.

The main avantage of this method is that you can add use generic extensions. The default is that the simulated object must update its implementation to add the extension and gives it the parameters.

This is useful, for creating transform extension. In the following example, the extension is a generic one, which takes a pointer on a OM::Type::Transform to modify the position before the object uses it to compute the outputs. (This is only for example, you should better use attributes)

MyObject::MyObject( PsController& ctrl, const PsObjectDescriptor& objectDescriptor ) :
OM::ExtensibleSimulatedObject( ctrl, objectDescriptor ),
_theInputPositionPrm(),
_theInputPosition( addInput< OM::Type::Transform >( "the_position" ) )
{
  new MyTransformExtension( this, "the_extension", &_theInputPositionPrm )
}
void MyObject::computeInputs()
{
  _theInputPositionPrm = _theInputPosition.get() ;
}
void MyObject::computeParameters()
{
  // do something with '_theInputPositionPrm'
}
MyTransformExtension::MyTransformExtension( ExtensibleSimulatedObject* owner, const PsName& id, OM::Type::Transform* thePosition ) :
OM::Extension( owner, id ), // The constructor adds automatically the extension to its owner
_thePosition( thePosition ),
_theTransformationToApply() 
{
}
bool MyTransformExtension::loadExtensionParameters( const PsConfigurationParameterDescriptor * node ) 
{
  // Initialise '_theTransformationToApply' with the values found in the 'node'
}
void MyTransformExtension::preCompute()
{
  // do something like 
  _thePosition->setRotate( _theTransformationToApply ) ;
}

In the creator

In the creator of the simulated object, it is a similar case of the previous one. The main advantage is that the object doesn't have to know the extension, only the new creator has to know the object class and the extension constructor.

This is the better way to add some behaviors to an object after it was designed because its code doesn't need to be updated to add the extension.

In the following example we use the same extension than in the previous case, and add it to a similar object. The object declares an accessor to its parameter, but its constructor is simplest and it doesn't have to handle the extension, the creator does it for it. (This is only for example, you should better use attributes)

MyObject2::MyObject2( PsController& ctrl, const PsObjectDescriptor& objectDescriptor ) :
OM::ExtensibleSimulatedObject( ctrl, objectDescriptor ),
_theInputPositionPrm(),
_theInputPosition( addInput< OM::Type::Transform >( "the position" ) )
{
}
OM::Type::Transform* MyObject2::getThePositionRef() 
{
  return &_theInputPositionPrm ;
}
class MyExtendedObjectCreator : public OM::SimulatedObjectCreatorT< MyObject2 >
{
public:
  virtual MyExtendedObjectCreator() : OM::SimulatedObjectCreatorT< MyObject2 >() {}
  PsSimulatedObject* operator()( PsController & ctrl, const PsObjectDescriptor & objectDescription ) const
  {
    MyObject2* myObject = dynamic_cast< MyObject2* >( OM::SimulatedObjectCreatorT< MyObject2 >::operator()( ctrl, objectDescription ) ) ;
    OMASSERTM( myObject, "Unable to create the object !" ) ;
    new MyTransformExtension( "the extension", myObject->getThePositionRef() );
    return myObject ;
  }
} ;
and in the main we add two creators, with or without extension. In the previous example, we had no choice, the extension has been added automatically to the object.
OM::SimulatedObjectFactory::getInstance().registerCreator< MyExtendedObjectCreator >( "MyInteractiveObject_with_extension" ) ;
OM::SimulatedObjectFactory::getInstance().registerCreator< OM::SimulatedObjectCreatorT< MyObject2 > >( "MyInteractiveObject" ) ;

In the configuration file

The extensible simulated object class gets a new field in its object descriptor. The Extensions field is added at the same level as Scheduling or UserParams ones. This example shows where to declare the extension in a object configuration file :
    #OpenMASK3

    root 
    {
        Class Controller
        Sons 
        {
            myObject
            {
                Class MyObjectClassId
                Scheduling
                {
                      ...scheduling parameters
                }
                UserParams
                {
                    ...user parameters
The extension   }
field takes---->Extensions
place here      {
                    myExtension
                    {
Class id for----------->Class MyExtensionClassId
dynamically             ...other parameters of the extension
creating the        }
extension           ...other extensions
                }
            }
            ...other objects
        }
    }
Every extension which has a Class id will be created and added to the object during its post-construction step (see postConstruction). Previously, in that purpose the extension creator must be registered in the extensions factory like this :
OM::ExtensionFactory::getInstance().registerCreator
  < OM::ExtensionCreatorT< MyExtension > >( MyExtension::s_id )
This work should be done with the macros DECLARE_EXTENSION_FACTORY.

The main avantage of this method is that you can add the extension without updating the object implementation. The default is that the extension can only get generic informations about the simulated object (like inputs, outputs, or configuration parameters) or know the object class to dynamically cast the object to retrieve informations (see next section How to initialise an extension ?).

This is useful, for example, for creating a visual object with an animator plugged on an output of the simulated object. See OM::Vis::VisualObjectExtension.

Somewhere during the running

In the three previous cases, the extension was added during constructing the object, but it is possible to add a extension in the running step. This can be done in the computeParameters or in with a event handling.

The extension ExtensionOfExtensionCreatorEvent allows the object to handle the creation of extension by event.

When the extension is created during running (after the call to the init method of the object), the configuration loaders (loadExtensionParameters and loadObjectParameters) will never be called.

How to initialise an extension ?

The initialization of the extension is made in its constructor.

See below How to retrieve the owner of an extension ?.

How to configure an extension ?

The extension has two methods to configure its owner object, or itself : loadObjectParameters and loadExtensionParameters.

Parameters loaders methods are called by the extensible simulated object at its init step. Its call takes place at the end of the init method of the simulated object. So these two methods will be never called for the mirror of a simulated object or if they were added to an object while it is running. These two loaders will be called only when the simulated object is created, an extension added in the object constructor will be called during the init step, an extension added in the object after the init will be never called.

The only difference between loadObjectParameters and loadExtensionParameters is the given node.

                myObject
                {
                      ...
loadObjectParameters  UserParams
uses this node------->{    
                            ...
                      }
                      Extensions
                      {
loadExtensionParameters     myExtension
uses this node------------->{
                                  ...
                            }
                            ...
                      }
                }

How to retrieve the owner of an extension ?

Most of the time the extension need to access to its owner to get informations.

The owner parameter of the constructor
The owner parameter of the constructor, which is a pointer on the extensible simulated object, owner of the extension, allows the extension to get informations of the object in its constructor. Nevertheless, the object is not typed, it is a generic ExtensibleSimulatedObject, and it is not stored, so it is no more available for configuration step.
To cast and store the owner you should use ExtensionT. This extension base class dynamically casts the owner during its constructor call and store it, so the extension can identify and modify the object.

The following example retrieve the position parameter of an object :
(the extension is dynamically created with the configuration parameters, see In the configuration file, and the object is the same than the one declared in In the creator)

MyExtension::MyExtension( ExtensibleSimulatedObject* owner, const PsName& id )
: OM::ExtensionT< MyObject2 >( owner, id )
{
  _thePosition = _owner->getThePositionRef() ;
}

Define Documentation

#define DECLARE_EXTENSION_FACTORY ( ExtensionClass   ) 

Value:

public: \ \
  friend class OMK::ExtensionCreatorT< ExtensionClass > ; \ \
  static OMK::Name OMK_CLASS_ID ; \ \
  static const bool REGISTERED_IN_EXTENSION_FACTORY ; \
protected: \ \
   ExtensionClass( OMK::ExtensibleSimulatedObject* owner, const OMK::Name& id, bool registerExtension = true ) ; \
public: \
        virtual ~ExtensionClass()
This define declares factory utilities, constructor and destructor for an extension.

Date:
2007-02-28
Author:
Benoît Chanclou Should be use with REGISTER_EXTENSION_FACTORY.

Definition at line 39 of file OMKExtension.h.

#define DECLARE_TEMPLATE_EXTENSION_FACTORY ( ExtensionClass,
Type   ) 

Value:

public: \ \
  friend class OMK::ExtensionCreatorT< ExtensionClass< Type > > ; \ \
  static OMK::Name OMK_CLASS_ID ; \ \
  static const bool REGISTERED_IN_EXTENSION_FACTORY ; \
protected: \ \
   ExtensionClass( OMK::ExtensibleSimulatedObject* owner, const OMK::Name& id, bool registerExtension = true ) ; \
public: \
  virtual ~ExtensionClass()
This define declares factory utilities, constructor and destructor for an extension.

Date:
2007-02-28
Author:
Benoît Chanclou Should be use with REGISTER_TEMPLATE_EXTENSION_FACTORY.

Definition at line 59 of file OMKExtension.h.

#define REGISTER_EXTENSION_FACTORY ( ExtensionClass,
Id   ) 

Value:

/* Factory */ \
  Name ExtensionClass::OMK_CLASS_ID( Id ) ; \
  const bool ExtensionClass::REGISTERED_IN_EXTENSION_FACTORY( OMK::ExtensionFactory::getInstance().registerCreator< OMK::ExtensionCreatorT< ExtensionClass > >( Id ) )
This define implements factory utilities, constructor and destructor for an extension.

Date:
2007-02-28
Author:
Benoît Chanclou Should be use with DECLARE_EXTENSION_FACTORY.

Definition at line 79 of file OMKExtension.h.

#define REGISTER_TEMPLATE_EXTENSION_FACTORY ( ExtensionClass,
Id   ) 

Value:

/* Factory */ \
  template <> Name ExtensionClass::OMK_CLASS_ID( Id ) ; \
  template <> const bool ExtensionClass::REGISTERED_IN_EXTENSION_FACTORY( OMK::ExtensionFactory::getInstance().registerCreator< OMK::ExtensionCreatorT< ExtensionClass > >( Id ) )
This define implements factory utilities, constructor and destructor for an extension.

Date:
2007-02-28
Author:
Benoît Chanclou Should be use with DECLARE_TEMPLATE_EXTENSION_FACTORY.

Definition at line 89 of file OMKExtension.h.


Typedef Documentation

typedef OBT::Singleton< OBT::PrototypeFactory< OMK::Name, ExtensionCreator > > OMK::ExtensionFactory

The factory of the extension.

Date:
2007-02-14
Author:
Benoît Chanclou
Every extension which wants to be dynamically created must be registered in this factory.
OMK::ExtensionFactory::getInstance().registerCreator
                                                 < OMK::ExtensionCreatorT< MyExtension > >( MyExtension::s_id ) ;
where

Definition at line 304 of file OMKExtension.h.


logo OpenMask

Documentation generated on Mon Jun 9 11:45:59 2008

Generated with doxygen by Dimitri van Heesch ,   1997-2007