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
Documentation generated on Mon Jun 9 11:45:56 2008 |
Generated with doxygen by Dimitri van Heesch , 1997-2007 |