Interactive object
[The interaction protocol]

Collaboration diagram for Interactive object:

The module for simulated object defined as interactive object. More...

Classes

class  OMK::Iii::SimpleConnectorT< Type >
 The implementation class for simple connectors. More...
class  OMK::Iii::SharedConnectorT< Type >
 The implementation class for shared connectors. More...
class  OMK::Iii::AssociatedConnectorT< Type >
 The implementation class for associated connectors. More...
class  OMK::Iii::AccessRuleCreator
 Ancestor of every access rule creator class used by the PrototypeFactory. More...
class  OMK::Iii::AccessRuleCreatorT< T >
 Access rule creator class to be parametrized by the descendants of IAccessRule. More...
class  OMK::Iii::IConnector
 Connector interface. More...
class  OMK::Iii::ConnectorCreator
 Ancestor of every Connector creator class used by the PrototypeFactory. More...
class  OMK::Iii::ConnectorCreatorT< T >
 Connector creator class to be parametrized by the descendants of IConnector. More...
class  OMK::Iii::IConvertorCreator< TypeOut, TypeIn >
 Ancestor of every convertor creator class used by the PrototypeFactory. More...
class  OMK::Iii::ConvertorCreatorT< TypeOut, TypeIn, ConvertorType >
 Convertor creator class to be parametrized by the descendants of IConvertorT. More...
class  OMK::Iii::ConvertorFactoryT< TypeIn, TypeOut >
 The factory of the average object. More...
class  OMK::Iii::InteractiveExtension
 The extension to make an object interactive. More...
class  OMK::Iii::InteractorExtension
 Ancestor of every interactive, interactor or inspector objects. More...
class  OMK::Iii::InteractorOutputCreator
 Ancestor of every Interactor output creator class used by the PrototypeFactory. More...
class  OMK::Iii::InteractorOutputCreatorT< T >
 Connector creator of InteractorOutputT. More...

Typedefs

typedef OBT::Singleton< OBT::PrototypeFactory<
OMK::Name, Iii::AccessRuleCreator > > 
OMK::AccessRuleFactory
 The factory of the access rules.
typedef OBT::Singleton< OBT::PrototypeFactory<
OMK::Name, Iii::ConnectorCreator > > 
OMK::ConnectorFactory
 The factory of the connectors.

Detailed Description

The module for simulated object defined as interactive object.

The main aim of the interactive object is to answer to the events which come from the interactor. To make a simulated object an interactive one, you have to add the extension InteractiveExtension. This one automatically creates and adds the event listener and the connectors to the object.

The event listener is defined by the class EventInteractorListener, it is in charge of the interaction protocol. The event listener is created by tyhe extension and it is never seen by the user, it does its job automatically.

The connectors are the part of the interactive object seen by the interactor. They are associated with a attribute and they manage the input(s) and the update of the attribute. The extension creates them according to the configuration file.

How to define an interactive object ?

To define an interactive object you have to: The connectors are Simple or Shared. In the first case, only one interactor can interact with the parameter, in the second case, many interactors can interact with the parameter. Both of the connector is associated with an attribute to access to the parameter value.

See InteractiveExtension and connectors for more details.

Create connectors

Connectors are defined in the configuration file and created by the interactive extension. The following example shows a configuration file.
interactiveObject
{
  Class MyInteractiveObject
  Scheduling
  {
    Frequency 25
  }
  Extensions
  {
    interaction                // <---The name of the extension
    {
      Class Interactive        // <---The id of the interactive extension class
      Connectors               // <---The field which defined the connectors
      {
        parameter_number_one   // <---The id of connector by default the same id is used to find the 
        {                      //     associated attribute to which the extension has to add a connector
          Type Simple          // <---The type of connector Simple or Shared
          AccessLevel 1        // <---The necessary access level for a interactor to see this connector
          Category "absolute"  // <---The base name for the category which identify the connector type
        }
        //...
      }
    }
  }
}
The common parameters for connectors are: See simple and shared connectors for more details and Example for a concrete example.

Example

The following example shows a code that define an interactive object called MyInteractiveObject with two parameters encapsuled in attributes. The first parameter is an int, the second one is a float. The complete code of our interactive simulated object MyInteractiveObject is
class MyInteractiveObject : public ExtensibleSimulatedObject
{
  DECLARE_OBJECT_FACTORY( MyInteractiveObject ) ;
protected:
  // Display a message to show the value
  virtual void computeParameters() ;
  // The two atttributes which encapsulate the parameters
  AttributeT<int> _myOwnParam ;
  AttributeT<float> _secondParam ;
} ;

REGISTER_OBJECT_FACTORY( MyInteractiveObject, "MyInteractiveObject" ) ;
MyInteractiveObject::MyInteractiveObject( PsController& ctrl, const PsObjectDescriptor& objectDescriptor )
: ExtensibleSimulatedObject( ctrl, objectDescriptor ),
  _myOwnParam ( PrmId::MyOwnParam,   2 ),
  _secondParam( PrmId::SecondParam, 3.3f )
{
  addAttribute( _myOwnParam ) ;
  addAttribute( _secondParam ) ;
}
MyInteractiveObject::~MyInteractiveObject()
{
}
void MyInteractiveObject::computeParameters() 
{
  OMMESSAGE( "MyInteractiveObject::computeParameters \"" << getName().getPsString() << "\"" << std::endl 
      << "my own param :" << _myOwnParam << std::endl  
      << "second param :" << _secondParam << std::endl 
      << "Press [return] to continue [q]+[return] will quit" ) ;
  if( getchar() == 'q' )
  {
    sendEvent( getController().getName(), PsSystemEventIdentifier::MaskStop ) ;
  }
}

How to extend the behavior ?

The connector can be associated with a convertor. With the shared connectors, it is necessary to convert the many input values in one value to set the parameter. With the simple connector, it is an option.

The convertor can do many things, they can define new behaviors as we will see in the following examples. The other way to extend the behavior is to define new kind of connectors.

In the configuration file there are two ways to declare a convertor

By creating a new kind of connector

To extend the behavior of interactive parameter it is possible to define and create a new class of connector. The following example shows a code that defines a new type of connector, which automatically freeze the access to its parameter when it is connected.
template< typename Type >
class FreezeConnectorT : public OM::Iii::SimpleConnectorT< Type >
{ 
  DECLARE_TEMPLATE_CONNECTOR_FACTORY( FreezeConnectorT, Type ) ;
public:
  // redefines the connect method to set the freeze flag
  virtual bool connect( const PsName& interactor, const PsName& outputName, bool freeze )
  {
    return OM::Iii::SimpleConnectorT< Type >::connect( interactor, outputName, true ) ;
  }
} ;
template< typename Type >
FreezeConnectorT< Type >::FreezeConnectorT( const PsName& id, 
                                    OM::Iii::EventInteractorListener *listener, 
                                    OM::ExtensibleSimulatedObject *owner, 
                                    const PsConfigurationParameterDescriptor* node ) 
: OM::Iii::SimpleConnectorT< Type >( id, listener, owner, node )
{
}
template< typename Type >
FreezeConnectorT< Type >::~FreezeConnectorT() 
{
}
REGISTER_TEMPLATE_CONNECTOR_FACTORY( FreezeConnectorT, int ) ;
REGISTER_TEMPLATE_CONNECTOR_FACTORY( FreezeConnectorT, float ) ;

In MyInteractiveObject (used in Example), we only have to change the Type of the connector to use this new one instead of the previous one.

...
        parameter_number_one
        {
          Type Freeze
...

By offering two categories for the same parameter

In this example, based on MyInteractiveObject (used in Example), two categories will be offer for the first parameter : an absolute and an offset.

The following informations are added to configuration file

        parameter_number_one_offset        // <--- A different id for the connector
        {
          Attribute parameter_number_one   // <--- The same id for the attribute
          Category "offset"                // <--- Change the category to "offset"
                Convertor IntegratorInt          // <--- The convertor to increment the value of the attribute
          Type Simple
          AccessLevel 1
          Freezable on
        }
This allows to change the attribute parameter_number_one, but it could have a conflict between the access through absolute or offset connector. The following connector is a new kind of connector to solve this problem.
template< typename Type >
class AssociatedConnectorT : public OM::Iii::SimpleConnectorT< Type >
{ 
  DECLARE_TEMPLATE_CONNECTOR_FACTORY( AssociatedConnectorT, Type ) ;
public:
  virtual bool connect( const PsName& interactor, const PsName& outputName, bool freeze )
  {
    // Disconnect the associated connector if necessary
    if( _associatedConnector ) 
    {
      _associatedConnector->disconnect() ;
      _associatedConnector->setFreeze( freeze ) ;
    }
    return SimpleConnectorT< Type >::connect( interactor, outputName, freeze ) ;
  }
  virtual bool LoadParameters( const PsConfigurationParameterDescriptor* node ) 
  {
    // Retrieve the associated connector
    PsName id ;
    PsParametersAccessor::get( node, "AssociatedTo", id ) ;
    _associatedConnector = _eventInteractorListener->getConnector( id ) ;

    return OM::Iii::SimpleConnectorT< Type >::LoadParameters( node ) ;
  }
protected:
  IConnector *_associatedConnector ;
} ;
template< typename Type >
AssociatedConnectorT< Type >::AssociatedConnectorT( const PsName& id, 
                                                    const PsName& attributeId, 
                                                    OM::Iii::EventInteractorListener *listener, 
                                                    OM::ExtensibleSimulatedObject *owner, 
                                                    const PsConfigurationParameterDescriptor* node ) 
: SimpleConnectorT< Type >( id, attributeId, listener, owner, node ),
_associatedConnector( 0 )
{
}
template< typename Type >
AssociatedConnectorT< Type >::~AssociatedConnectorT() 
{
}
REGISTER_TEMPLATE_CONNECTOR_FACTORY( AssociatedConnectorT, int ) ;
REGISTER_TEMPLATE_CONNECTOR_FACTORY( AssociatedConnectorT, float ) ;
In configuration file we can uses this connector for the first parameter instead of the Simple one. The configuration file is modified as this:
        parameter_number_one
        {
          Type Associated                          // <--- The new type
          AccessLevel 1
          Freezable on
          Category "absolute"
          AssociatedTo parameter_number_one_offset // <--- The associated connector
        }
        parameter_number_one_inc                
        {
          Attribute parameter_number_one           // <--- The same id for the attribute
          Category "offset"                        // <--- Change the category to "offset"
          Convertor IntegratorInt                  // <--- The convertor to increment the value of the attribute
          Type Associated                          // <--- The new type
          AccessLevel 1
          Freezable on
          Category "offset"
                Convertor IntegratorInt
          AssociatedTo parameter_number_one        // <--- The associated connector
        }

By offering two types for the same parameter

To add a new type for a parameter we have to create a duplicated attribute to access to the initial attribute with the new type. This can be done by the object which declares this attribute, or by adding an extension DuplicatedAttribute.

The following lines declare and define a duplicated attribute.
In the header, the class add the new attribute after the two existing ones.

...
  // The two atttributes which encapsulate the parameters
  OM::AttributeT<int> _myOwnParam ;
  OM::AttributeT<float> _secondParam ;
  // The duplicated attribute
  OM::AttributeAccT< float, int > _duplicatedAttribute ;
...
In the constructor
...
_myOwnParam ( "parameter_number_one",    2 ),
_secondParam( "parameter_number_two", 3.3f ),
_duplicatedAttribute( "duplicatedAttribute", &_myOwnParam );
  {
    addAttribute( _myOwnParam ) ;
    addAttribute( _secondParam ) ;
    addAttribute( _duplicatedAttribute ) ;
  }
...

Or by extension in the configuration file

                    duplicatedAttribute
                    {
                      Class DuplicatedAttribute_int_SeeAsA_float 
                      Attribute parameter_number_one
                      Id parameter_number_one_float
                    }
The name of the extension depends of the types of the reference and duplicated attribute.

After adding the duplicated attribute, we can add a connector to this new attribute in the configuration file

            parameter_number_one_float
            {
              Type Associated
              AccessLevel 1
              Freezable on
              Category "absolute"
              AssociatedTo parameter_number_one
            }

Typedef Documentation

typedef OBT::Singleton< OBT::PrototypeFactory< OMK::Name, Iii::AccessRuleCreator > > OMK::AccessRuleFactory

The factory of the access rules.

Date:
2007-03-27
Author:
Beno� Chanclou
Every access rule which wants to be dynamically created must be registered in this factory.
OMK::Iii::AccessRuleFactory::getInstance().registerCreator
                                                 < OMK::Iii::AccessRuleCreatorT< MyAccessRule > >( MyAccessRule::s_id ) ;
where

Definition at line 158 of file OMKIAccessRule.h.

typedef OBT::Singleton< OBT::PrototypeFactory< OMK::Name, Iii::ConnectorCreator > > OMK::ConnectorFactory

The factory of the connectors.

Date:
2007-03-27
Author:
Benoît Chanclou
Every connector which wants to be dynamically created must be registered in this factory.
OMK::Iii::ConnectorFactory::getInstance().registerCreator
                                                 < OMK::Iii::ConnectorCreatorT< MyConnector > >( MyConnector::s_id ) ;
where
Class name Factory id Type Class
SimpleConnectorT<> SimpleConnectorT###Type Simple SimpleConnectorT
SharedConnectorT<> SharedConnectorT###Type Shared SharedConnectorT
AssociatedConnectorT<> AssociatedConnectorT###Type Associated AssociatedConnectorT

Definition at line 308 of file OMKIConnectors.h.


logo OpenMask

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

Generated with doxygen by Dimitri van Heesch ,   1997-2007