Collaboration diagram for Interactor:
Classes | |
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::InteractorOutput |
This class defines informations about interactor output. More... | |
class | OMK::Iii::SessionPrm |
Define a session of interaction between an interactor and an interactive object. More... |
The main job to do in your extension is to create a state machine call by the postComputeParameters. The state of the machine will evolve according to events that the object will receive, so you will need to define some listeners and associated call back methods to update the internal state of your states machine.
class MyInteractorExtension : public OM::Iii::InteractorExtension { DECLARE_EXTENSION_FACTORY( MyInteractorExtension ) ; ...
// states of state machine enum States{ EWaitingState, EStartInteraction, EControlTakeOver, EControlState, EControlRelease, EFinishInteraction } ; // Current state States _state ;
// Associated attribute
PsName _attributeId ;
// The id of the interactive object to control
OM::AttributeTypeT< PsName > _interactiveObject ;
bool startInteraction( PsEvent* e ) ; bool stopInteraction( PsEvent* e ) ;
bool loadExtensionParameters( const PsConfigurationParameterDescriptor * node ) ; void postComputeParameters() ; } ;
REGISTER_EXTENSION_FACTORY( MyInteractorExtension, "MyInteractorExtension" ) ;
MyInteractorExtension::MyInteractorExtension( OM::ExtensibleSimulatedObject *owner, const PsName &id ) : OM::Iii::InteractorExtension( owner, id ), _interactiveObject( "interactiveObject", "unknow" ), _state( EWaitingState ), _attributeId( "Position" ) { owner->addAttribute( _interactiveObject ) ; }
MyInteractorExtension::~MyInteractorExtension() { }
bool MyInteractorExtension::loadExtensionParameters( const PsConfigurationParameterDescriptor * node ) { // The extension need to know the name of the visualisation object to add the keyboard call back methods std::string visuName ; if( PsParametersAccessor::get( node, "VisuName", visuName, _owner ) ) { // The call back for take control of the interactive object std::string key = "T" ; PsParametersAccessor::get( node, "TakeControlKey", key ) ; // optional new PsEventListenerCallBack< MyInteractorExtension > ( *_owner, this, &MyInteractorExtension::startInteraction, OM::Inp::KeyListener::getKeyReleaseCode( key ) ) ; _owner->sendValuedEvent( visuName, OM::Inp::InputExtension::ADD_KEY, OM::Inp::AddInputKeyPrm( key, _owner->getName() ) ) ; // The call back for release the control of the interactive object std::string key = "R" ; PsParametersAccessor::get( node, "ReleaseKey", key ) ; // optional new PsEventListenerCallBack< MyInteractorExtension > ( *_owner, this, &MyInteractorExtension::stopInteraction, OM::Inp::KeyListener::getKeyReleaseCode( key ) ) ; _owner->sendValuedEvent( visuName, OM::Inp::InputExtension::ADD_KEY, OM::Inp::AddInputKeyPrm( key, _owner->getName() ) ) ; } // the following attribute should declare an associated output, // optional because set to the "Position" attribute of the object PsParametersAccessor::get( node, "AttributeId", _attributeId ) ; // will retrieve the optional parameter to set the _interactiveObject return InteractorExtension::loadExtensionParameters( node ) ; }
bool MyInteractorExtension::startInteraction( PsEvent* e ) { if( _state == EWaitingState ) { _state = EStartInteraction ; } }
bool MyInteractorExtension::stopInteraction( PsEvent* e ) { if( _state == EControlState ) { _state = EControlRelease ; } }
void MyInteractorExtension::postComputeParameters() { switch( _state ) { // Waiting for the call of the startInteraction call back case EWaitingState : break; // Starts the session with the interactive object and goes to the next state case EStartInteraction : { OMMESSAGE( "I am going to start with " << _interactiveObject ) ; startSessionWith( _interactiveObject ) ; _state = EControlTakeOver ; } break ; // Send the messages to take the control and to retrieve the current position of the interactive object // then goes to the next state case EControlTakeOver : { OMMESSAGE( "I am taking control of " << _interactiveObject ) ; (*getSessionWith( _interactiveObject )).c( _attributeId ).c( OM::Iii::controlTakeOver ) ; (*getSessionWith( _interactiveObject )).c( _attributeId ).c( OM::Iii::getCurrentValues ) ; _state = EControlState ; } break ; // The objetc is under control // Waiting for the call of the stopInteraction call back case EControlState : break; // Stops the session with interactive object then goes to the next state case EControlRelease : { OMMESSAGE( "I am releasing " << _interactiveObject ) ; (*getSessionWith( _interactiveObject )).c( _attributeId ).c( OM::Iii::controlRelease ) ; _state = EFinishInteraction ; } break; // Closes the session then returns to the waiting state case EFinishInteraction : { OMMESSAGE( "Session closed with " << _interactiveObject ) ; closeSessionWith( _interactiveObject ) ; _state = EWaitingState ; } break; default: OMASSERTM( false, "Forbidden state" ) ; } }
interactor { Class SimplePoint Scheduling { Frequency 60 } Extensions { interactor { Class MyInteractorExtension Level 0 // The access level of the interactor Outputs // Define the interactor outputs { Position // for the attribute "Position" { Category "absolute" // The category of the output } } VisuName visuOgre // Specific parameter of MyInteractorExtension to activate the keyboard } } }
startSessionWith( _interactiveObject ) ;
(*getSessionWith( _interactiveObject )).c( OM::Iii::getCurrentValues ) ;
(*getSessionWith( _interactiveObject )).c( Prm::integerValue ).c( OM::Iii::getCurrentValues ) ;
class SessionPrmBis : public OM::Iii::SessionPrm { protected: // Constructor SessionPrmBis( OM::Iii::IEventInteractiveObjectListener* listener, const PsName& interactiveObject ) : OM::Iii::SessionPrm( listener, interactiveObject ) { } public: // Creator static SessionPrmBis* create( OM::Iii::IEventInteractiveObjectListener* listener, const PsName& interactiveObject ) { return new SessionPrmBis( listener, interactiveObject ) ; } // Destructor virtual ~SessionPrmBis() {}
protected: static PsName freezeId ; static PsName unfreezeId ;
public: // Overwrite the flow operator to add two ids at once virtual OM::Iii::SessionPrm& c ( const OMK::Name& interactiveObjectId ) { _ids.push_back( interactiveObjectId ) ; _ids.push_back( freezeId ) ; return *this; }
protected: // To set the freeze flag void selfFreeze( bool freeze ) { // Should test the size ! _ids[_ids.size()-1] = freeze ? freezeId : unfreezeId ; } public: inline friend OM::Iii::SessionPrm& frozen( OM::Iii::SessionPrm & s ) { // Must cast the object to access to inner method dynamic_cast<SessionPrmBis&>(s).selfFreeze( true ) ; return s ; } inline friend OM::Iii::SessionPrm& notFrozen( OM::Iii::SessionPrm & s ) { // Must cast the object to access to inner method dynamic_cast<SessionPrmBis&>(s).selfFreeze( false ) ; return s ; }
protected: // Overwrite the "control take over" to take into account the frozen flag void selfControlTakeOver() { OM::Type::AccessTakeOverPrm connectorsToControl( _listener->getAccessLevel() ) ; if( !_ids.empty() ) { // loop with a step of 2, the first "_ids[ i ]" is the parameter id, the second "_ids[ i + 1 ]" the freeze flag for ( int i = 0 ; i < _ids.size() ; i += 2 ) { std::map< PsName, SessionPrm::Link >::const_iterator link = _links.find( _ids[ i ] ) ; if( link != _links.end() ) { connectorsToControl.addItem( OM::Iii::ControlTakeOverPrm( link->second.connector, link->first, _ids[ i + 1 ] == freezeId ) ) ; } else { OMTRACE( "the id \"" << _ids[ i ] << "\" is not available" ) ; } } } else { OMTRACE( "cannot use an empty list" ) ; } if( !connectorsToControl.getItems().empty() ) { _listener->getInteractor()->sendValuedEvent( _interactiveObject, EventId::controlTakeOver, AccessTakeOverType( connectorsToControl ) ) ; } _ids.clear() ; } } ;
class MyInteractorObject : public OM::Iii::InteractiveSimulatedObject { //... // Overwrites the startSessionWith method to use the new session object instead of the old one virtual void startSessionWith( const PsName& interactiveObject ) { OMASSERT( _eventInteractiveObjectListener && "cannot be null, must be an initialized interactor object" ) ; _eventInteractiveObjectListener->addSession( SessionPrmBis::create( _eventInteractiveObjectListener, interactiveObject ) ) ; } //... } ;
startSessionWith( _interactiveObject ) ;
(*getSessionWith( _interactiveObject ))).c( Prm::integerValue ).c( frozen ) .c( Prm::floatingValue ).c( notFrozen ) .c( OM::Iii::controlTakeOver ) ;
Documentation generated on Mon Jun 9 11:46:00 2008 |
Generated with doxygen by Dimitri van Heesch , 1997-2007 |