OMKInteractiveExtension.cpp

Go to the documentation of this file.
00001 
00002 /************************************************************************/
00003 /* This file is part of openMask(c) INRIA, CNRS, Universite de Rennes 1 */
00004 /* 1993-2002, thereinafter the Software                                 */
00005 /*                                                                      */
00006 /* The Software has been developped within the Siames Project.          */
00007 /* INRIA, the University of Rennes 1 and CNRS jointly hold intellectual */
00008 /* property rights                                                      */
00009 /*                                                                      */
00010 /* The Software has been registered with the Agence pour la Protection  */
00011 /* des Programmes (APP) under registration number                       */
00012 /* IDDN.FR.001.510008.00.S.P.2001.000.41200                             */
00013 /*                                                                      */
00014 /* This file may be distributed under the terms of the Q Public License */
00015 /* version 1.0 as defined by Trolltech AS of Norway and appearing in    */
00016 /* the file LICENSE.QPL included in the packaging of this file.         */
00017 /*                                                                      */
00018 /* Licensees holding valid specific licenses issued by INRIA, CNRS or   */
00019 /* Universite Rennes 1 for the software may use this file in            */
00020 /* acordance with that specific license                                 */
00021 /************************************************************************/
00022                 
00023 #include "OMKInteractiveExtension.h"
00024 #include "OMKValuedEventListenerCallBack.h"
00025 #include "OMKEventListenerCallBack.h"
00026 #include "OMKParametersAccessor.inl"
00027 #include "OMKMultipleConfigurationParameter.h"
00028 #include "OMKIAttribute.h"
00029 #include <vector>
00030 #include <string>
00031 #include <iostream>
00032 #include <algorithm>
00033 #include "OMKAccessLevelList.inl"
00034 
00035 using namespace OMK ;
00036 using namespace OMK::Iii ;
00037 using namespace OMK::Type ;
00038 
00039 REGISTER_EXTENSION_FACTORY( InteractiveExtension, "Interactive" ) ;
00040 //-----------------------------------------------------------------
00041 // Default constructor
00042 InteractiveExtension::InteractiveExtension( ExtensibleSimulatedObject* owner, const Name& id, bool registerExtension )
00043 : ExtensionT< ExtensibleSimulatedObject >( owner, id, registerExtension ),
00044   _getAccessibleParametersListener( 0 ),
00045   _controlTakeOverAndGetCurrentValuesListener( 0 ),
00046   _controlReleaseListener( 0 ),
00047   _controlFreezeListener( 0 ),
00048   _controlUnfreezeListener( 0 ),
00049   _getCurrentValuesListener( 0 ),
00050   _newValueAvailableListener( 0 ),
00051   _defaultAccessRule( 0 )
00052 {
00053 }
00054 
00055 //-----------------------------------------------------------------
00056 
00057 // Destructor
00058 InteractiveExtension::~InteractiveExtension()
00059 {
00060   // Destroy each connector, which will disconnect its associated input
00061   for ( ConnectorsMap::const_iterator i = _connectors.begin() ; i !=  _connectors.end() ; ++i )
00062   {
00063     delete i->second ;
00064   }
00065   // Finally clears the map 
00066   _connectors.clear() ;
00067   _preConnectors.clear() ;
00068   _postConnectors.clear() ;
00069 
00070   //Removes event listener
00071   delete _getAccessibleParametersListener ;
00072   delete _controlTakeOverAndGetCurrentValuesListener ;
00073   delete _controlReleaseListener ;
00074   delete _controlFreezeListener ;
00075   delete _controlUnfreezeListener ;
00076   delete _getCurrentValuesListener ;
00077   delete _newValueAvailableListener ;
00078 }
00079 //-----------------------------------------------------------------
00080 
00081 bool InteractiveExtension::loadExtensionParameters( const ConfigurationParameterDescriptor * node ) 
00082 {
00083   // Creates the event listeners
00084   _getAccessibleParametersListener = new GetAccessibleParametersEventListener
00085         ( *_owner, this, 
00086         &InteractiveExtension::processGetAccessibleParameters, 
00087         EventId::GET_ACCESSIBLE_PARAMETERS ) ;
00088   _controlTakeOverAndGetCurrentValuesListener = new TakeOverAndGetCurrentValuesEventListener
00089         ( *_owner, this, 
00090         &InteractiveExtension::processControlTakeOverAndGetCurrentValues,
00091         EventId::CONTROL_TAKE_OVER_AND_GET_CURRENT_VALUES ) ;
00092   _controlReleaseListener = new EventListenerCallBack< InteractiveExtension >
00093         ( *_owner, this, 
00094         &InteractiveExtension::processControlRelease,
00095         EventId::CONTROL_RELEASE ) ;
00096   _controlFreezeListener = new ControlFreezeEventListener
00097         ( *_owner, this, 
00098         &InteractiveExtension::processControlFreeze,
00099         EventId::CONTROL_FREEZE ) ;
00100   _controlUnfreezeListener = new EventListenerCallBack< InteractiveExtension >
00101         ( *_owner, this, 
00102         &InteractiveExtension::processControlUnfreeze,
00103         EventId::CONTROL_UNFREEZE ) ;
00104   _getCurrentValuesListener = new GetCurrentValuesEventListener
00105         ( *_owner, this, 
00106         &InteractiveExtension::processGetCurrentValues, 
00107         EventId::GET_CURRENT_VALUES ) ;
00108   _newValueAvailableListener = new NewValueAvailableEventListener
00109         ( *_owner, this, 
00110         &InteractiveExtension::processNewValueAvailable, 
00111         EventId::NEW_VALUE_AVAILABLE ) ;
00112 
00113   // Retrieve the connector fields to create the connectors which defined a "Class"
00114   const ConfigurationParameterDescriptor * connectorsNode = node ? node->getSubDescriptorByName( "Connectors" ) : 0 ;
00115 
00116   if( connectorsNode )
00117   {
00118     // Create the connectors
00119     int nbItems = connectorsNode->getNumberOfSubItems() ;
00120     for( int i = 0 ; i < nbItems ; ++i )
00121     { 
00122       // Retrieves parameters sets for each extension
00123       Name id( static_cast<const MultipleConfigurationParameter *>( connectorsNode )->getNameOfSubDescriptor( i ) ) ;
00124       const ConfigurationParameterDescriptor * connectorParameters = connectorsNode->getSubDescriptorByPosition( i ) ;
00125       // Try to retrieve the class id to create the extension
00126       Name attributeId( id ) ;
00127       ParametersAccessor::get( connectorParameters, "Attribute", attributeId ) ;
00128       std::string classIdTmp ;
00129       if( ParametersAccessor::get( connectorParameters, "Type", classIdTmp ) )
00130       {
00131         IAttribute *foundAttribute = _owner->getAttribute( attributeId ) ;
00132         if( foundAttribute == 0 )
00133         {
00134           OMFATALERROR( "Attribute ID [" << attributeId
00135                         << "] not found in code for the connector of extension with ID ["
00136                         << getId() << "]" ) ;
00137         }
00138         // Now ClassId is ok => Create the extension
00139         Name classId( classIdTmp + "ConnectorT" + foundAttribute->getTypeId().name() ) ;
00140         ConnectorFactory::getInstance().create( classId )( id, attributeId,
00141                                                            this, connectorParameters ) ;
00142       }
00143       else if( ParametersAccessor::get( connectorParameters, "Class", classIdTmp ) )
00144       { // ClassId is ok => Create the extension
00145         Name classId( classIdTmp + _owner->getAttribute( attributeId )->getTypeId().name() ) ;
00146         ConnectorFactory::getInstance().create( classId )( id, attributeId,
00147                                                            this, connectorParameters ) ;
00148       }
00149       else
00150       {
00151         OMERROR( "Unable to create the connector for the extension with ID [" << getId()
00152                  << "] due to errors in configuration file" ) ;
00153       }
00154     }
00155     // Initialise the connector
00156     for( ConnectorsMap::iterator connector = _connectors.begin() ; 
00157          connector != _connectors.end() ; 
00158          ++connector )
00159     {
00160       connector->second->loadParameters( connectorsNode->getSubDescriptorByName( connector->second->id().getCString() )  ) ;
00161     }
00162   }
00163   return true ;
00164 }
00165 //-----------------------------------------------------------------
00166 void InteractiveExtension::addConnector( IConnector* connector, bool postComputing ) 
00167 {
00168   _connectors.insert( std::pair< const Name, IConnector* >( connector->id(), connector ) ) ;
00169 
00170   if( postComputing ) 
00171   {
00172     _postConnectors.insert( std::pair< const Name, IConnector* >( connector->id(), connector ) ) ;
00173   }
00174   else
00175   {
00176     _preConnectors.insert( std::pair< const Name, IConnector* >( connector->id(), connector ) ) ;
00177   }
00178 }
00179  
00180 //-----------------------------------------------------------------
00181 IConnector* InteractiveExtension::getConnector( const Name& id ) 
00182 {
00183   ConnectorsMap::iterator connector = _connectors.find( id ) ;
00184   return connector != _connectors.end() ? connector->second : 0 ;
00185 }
00186 
00187 //-----------------------------------------------------------------
00188 
00189 void InteractiveExtension::preComputeParameters()
00190 {
00191   // Update the interactive parameters 
00192   for( ConnectorsMap::iterator i = _preConnectors.begin() ; i !=  _preConnectors.end() ; ++i )
00193   {
00194     (*i).second->updateParameter() ;
00195   }
00196 }
00197 //-----------------------------------------------------------------
00198 
00199 void InteractiveExtension::postComputeParameters()
00200 {
00201   // Update the interactive parameters 
00202   for( ConnectorsMap::iterator i = _postConnectors.begin() ; i !=  _postConnectors.end() ; ++i )
00203   {
00204     (*i).second->updateParameter() ;
00205   }
00206 }
00207 
00208 //-----------------------------------------------------------------
00209 bool InteractiveExtension::processGetAccessibleParameters( GetAccessibleParametersEvent *event ) 
00210 {
00211   OMASSERTM( event->eventId == EventId::GET_ACCESSIBLE_PARAMETERS, "The event must be \"connector parameters ?\"" ) ;
00212   AccessibleParametersListPrm connectorsList ;
00213   for( ConnectorsMap::const_iterator i = _connectors.begin() ; i !=  _connectors.end() ; ++i )
00214   {
00215     connectorsList.push_back( AccessibleParameterPrm( i->second, event->value.getValue() ) ) ;
00216   }
00217   _owner->sendValuedEvent( event->sender, EventId::ACCESSIBLE_PARAMETERS, AccessibleParametersListType( connectorsList ) ) ;
00218 
00219   return true ;
00220 }
00221 
00222 //-----------------------------------------------------------------
00223 bool InteractiveExtension::processGetCurrentValues( GetCurrentValuesEvent *event ) 
00224 {
00225   // Establishes the specified connections
00226   const GetCurrentValuesPrm& value = event->value.getValue() ;
00227   for( GetCurrentValuesPrm::ItemsList::const_iterator prm = value._items.begin() ;
00228        prm != value._items.end() ; 
00229        ++prm )
00230   { // Try to connect each id sent by the interactor 
00231     // Is the id in the connector list
00232     ConnectorsMap::iterator connector = _connectors.find( *prm ) ;
00233     if( connector != _connectors.end() 
00234      && connector->second->getAccessRule().isAccessGranted( value._level, event->sender ) )
00235     { // send value
00236       connector->second->sendValue( event->sender ) ;
00237     }
00238     else
00239     { // Fails to find the values
00240       OMTRACEID( OMK_DEBUG_III, ":-( Error for the " << OMK::debugMsg( _owner ) << std::endl
00241           << ">>> \"" << event->sender << "\" cannot get \"" << *prm << "\" value" << std::endl
00242           << ( connector == _connectors.end() 
00243               ? ">>> because => the connector does not exist ! "
00244               : ">>> because => the connector not currently accessible ! " ) ) ;
00245     }
00246   }
00247   _owner->sendEvent( event->sender, EventId::CURRENT_VALUES_SENT ) ;
00248 
00249   return true ;
00250 }
00251 
00252 //-----------------------------------------------------------------
00253 bool InteractiveExtension::processControlTakeOverAndGetCurrentValues( TakeOverAndGetCurrentValuesEvent *event ) 
00254 {
00255   const TakeOverAndGetCurrentValuesPrm& value = event->value.getValue() ;
00256   ControlTakenPrm takenConnectors ;
00257   for( TakeOverAndGetCurrentValuesPrm::ItemsList::const_iterator prm = value._items.begin() ;
00258        prm != value._items.end() ; 
00259        ++prm )
00260   { // Try to connect each id sent by the interactor 
00261     // Is the id in the connector list
00262     ConnectorsMap::iterator connector = _connectors.find( prm->_id ) ;
00263     if( connector != _connectors.end() 
00264      && connector->second->getAccessRule().isAccessGranted( value._level, event->sender )
00265      && connector->second->preConnect( event->sender, prm->_accessGroup, value._level ))
00266     { // Connection
00267       connector->second->sendValue( event->sender ) ;
00268       connector->second->getAccessRule().setCurrentLevel( prm->_accessGroup, value._level ) ;
00269       takenConnectors.push_back( ControlTakenOfParameterPrm( prm->_id, connector->second->getToolsInUse() ) ) ;
00270     }
00271     else
00272     {
00273       OMTRACEID( OMK_DEBUG_III, ":-( Error in InteractiveExtension::processControlTakeOver for the " << OMK::debugMsg( _owner ) << std::endl
00274           << ">>> \"" << event->sender << "\" cannot control \"" << prm->_id << "\" with \"" << prm->_secondId << "\"" << std::endl
00275           << ( connector == _connectors.end()  
00276                ? ">>> because the connector does not exist ! "
00277                : ">>> because the connector is not currently accessible ! " ) ) ;
00278     }
00279   }
00280   _owner->sendValuedEvent( event->sender, EventId::CURRENT_VALUES_SENT_AND_CONTROL_TAKEN, ControlTakenType( takenConnectors ) ) ;
00281 
00282   return true ;
00283 }
00284 //-----------------------------------------------------------------
00285 bool InteractiveExtension::processNewValueAvailable( NewValueAvailableEvent *event ) 
00286 {
00287   // Establishes the specified connections
00288   const NewValueAvailablePrm& prm = event->value ;
00289   ConnectorsMap::iterator connector = _connectors.find( prm.first ) ;
00290   std::list< Name >* toolsInUse = connector != _connectors.end() ? &connector->second->getToolsInUse() : 0 ;
00291   if( toolsInUse
00292     && std::find( toolsInUse->begin(), toolsInUse->end(), event->sender ) != toolsInUse->end() )
00293   {
00294     connector->second->connect( event->sender, prm.second ) ;
00295   }
00296   else
00297   {
00298     OMTRACEID( OMK_DEBUG_III, ":-( Error in InteractiveExtension::processControlTakeOver for the " << OMK::debugMsg( _owner ) << std::endl
00299         << ">>> \"" << event->sender << "\" cannot connect \"" << prm.first << "\" with \"" << prm.second << "\"" << std::endl
00300         << ">>> because " << ( toolsInUse ? "" : "the connector does not exist ! " )
00301         << ( toolsInUse && std::find( toolsInUse->begin(), toolsInUse->end(), event->sender ) != toolsInUse->end() ? "" : "the connector is not available ! " ) ) ;
00302   }
00303   return true ;
00304 }
00305 //-----------------------------------------------------------------
00306 bool InteractiveExtension::processControlRelease( Event *event ) 
00307 {
00308   ControlReleaseEvent* valuedEvent = dynamic_cast< ControlReleaseEvent* >( event ) ;
00309   if( valuedEvent )
00310   { // Removes the specified connections
00311     const ControlReleasePrm& value = valuedEvent->value.getValue() ;
00312     for ( ControlReleasePrm::const_iterator id = value.begin() ; id != value.end() ; ++id )
00313     { // Try to release each id sent by the interactor 
00314       // Is the id in the connector list
00315       ConnectorsMap::iterator connector = _connectors.find( *id ) ;
00316       if( connector != _connectors.end() && connector->second->isConnected( event->sender ) )
00317       { // Disconnection
00318         connector->second->disconnect( event->sender ) ;
00319       }
00320       else
00321       {
00322         OMTRACEID( OMK_DEBUG_III, ":-( Error in InteractiveExtension::processControlRelease for the " << OMK::debugMsg( _owner ) << std::endl
00323                 << ">>> Unable to disconnect \"" << event->sender << "\" from \"" << *id << "\" because "
00324                 << ( connector == _connectors.end() ? "the connector doesn't exist":"the interactor is not connected to the connector") << std::endl ) ;
00325       }
00326     }
00327   }
00328   else
00329   { // Removes all connections from this interactor
00330     for ( ConnectorsMap::const_iterator connector = _connectors.begin() ; connector != _connectors.end() ; ++connector )
00331     {
00332       if( connector->second->isConnected( event->sender ) )
00333       {
00334         connector->second->disconnect( event->sender ) ;
00335       }
00336     }
00337   }
00338   // Even if the disconnection has failed, the message is processed
00339   return true ;
00340 }
00341 
00342 //-----------------------------------------------------------------
00343 bool InteractiveExtension::processControlFreeze( ControlFreezeEvent *event ) 
00344 {
00345   // Change the access level of the specified connections
00346   const ControlFreezePrm& value = event->value.getValue() ;
00347   for ( ControlFreezePrm::ItemsList::const_iterator id = value._items.begin() ; id != value._items.end() ; ++id )
00348   { // Try to release each id sent by the interactor 
00349     // Is the id in the connector list
00350     ConnectorsMap::iterator connector = _connectors.find( id->first ) ;
00351     if( connector != _connectors.end() 
00352      && connector->second->isConnected( event->sender ) )
00353     { // Change current access level
00354       connector->second->getAccessRule().setCurrentLevel( id->second, value._level ) ;
00355     }
00356     else
00357     {
00358       OMTRACEID( OMK_DEBUG_III, ":-( Error in InteractiveExtension::processControlFreeze for the " << OMK::debugMsg( _owner ) << std::endl
00359           << ">>> Unable to freeze \"" << event->sender << "\" from \"" << *id << "\" because "
00360           << ( connector == _connectors.end() ? 
00361           "the connector doesn't exist" : "the interactor is not connected to the connector" ) << std::endl ) ;
00362     }
00363   }
00364   // Even if the action has failed, the message is processed
00365   return true ;
00366 }
00367 
00368 //-----------------------------------------------------------------
00369 bool InteractiveExtension::processControlUnfreeze( Event *event ) 
00370 {
00371   ControlUnfreezeEvent* valuedEvent = dynamic_cast< ControlUnfreezeEvent* >( event ) ;
00372   if( valuedEvent )
00373   { // Unfreezes the specified connections
00374     const ControlUnfreezePrm& value = valuedEvent->value.getValue() ;
00375     for ( ControlUnfreezePrm::const_iterator id = value.begin() ; id != value.end() ; ++id )
00376     { // Try to release each id sent by the interactor 
00377       // Is the id in the connector list
00378       ConnectorsMap::iterator connector = _connectors.find( *id ) ;
00379       if( connector != _connectors.end() && connector->second->isConnected( event->sender ) )
00380       { // Change current access level
00381         connector->second->getAccessRule().resetCurrentLevel() ;
00382       }
00383       else
00384       {
00385         OMTRACEID( OMK_DEBUG_III, ":-( Error in InteractiveExtension::processControlUnfreeze for the " << OMK::debugMsg( _owner ) << std::endl
00386             << ">>> Unable to unfreeze \"" << event->sender << "\" from \"" << *id << "\" because "
00387             << ( connector == _connectors.end() ? "the connector doesn't exist":"the interactor is not connected to the connector") << std::endl ) ;
00388       }
00389     }
00390   }
00391   else
00392   { // Removes all connections from this interactor
00393     for ( ConnectorsMap::const_iterator connector = _connectors.begin() ; connector != _connectors.end() ; ++connector )
00394     {
00395       if( connector->second->isConnected( event->sender ) )
00396       {
00397 //        connector->second->getAccessRule().unfreeze() ;
00398       }
00399     }
00400   }
00401   // Even if the disconnection has failed, the message is processed
00402   return true ;
00403 }
00404 
00405 //-----------------------------------------------------------------
00406 

logo OpenMask

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

Generated with doxygen by Dimitri van Heesch ,   1997-2007