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 #if !defined OMK_III_CONNECTORS_INL 00024 #define OMK_III_CONNECTORS_INL 00025 00026 // methods implementation 00027 #include "OMKConnectors.h" 00028 #include <algorithm> 00029 #include "OMKExtensibleSimulatedObject.h" 00030 #include "OMKInteractiveExtension.h" 00031 #include "OMKIConvertor.h" 00032 #include "OMKAttribute.inl" 00033 #include "OMKAccessLevelList.inl" 00034 00035 namespace OMK 00036 { 00037 namespace Iii 00038 { 00039 //======================================================================== 00040 //SimpleConnectorT 00041 //======================================================================== 00042 //----------------------------------------------------------------- 00043 00044 template< typename T > 00045 SimpleConnectorT< T >::SimpleConnectorT( const Name& id, 00046 const Name& attributeId, 00047 InteractiveExtension *extension, 00048 const ConfigurationParameterDescriptor* node ) 00049 : IConnector( id, attributeId, typeid( T ).name(), extension, node ), 00050 _input( 0 ), 00051 _attribute( extension->getOwner()->getBaseAttribute< T >( attributeId ) ), 00052 _convertor( 0 ) 00053 { 00054 OMASSERT( _attribute && "A valid interface must be set for accessor methods" ) ; 00055 _convertor = IConvertorT< T, T >::create( node ) ; 00056 OMTRACEID( OMK_DEBUG_III, "Creation in " << OMK::debugMsg( _interactiveExtension, _owner ) << " of a simple connector \"" << _id 00057 << "\" for the attribute \"" << attributeId << "\" category \"" << _category << "\"" ) ; 00058 } 00059 //----------------------------------------------------------------- 00060 template< typename T > 00061 SimpleConnectorT< T >::~SimpleConnectorT() 00062 { 00063 disconnect() ; 00064 } 00065 //----------------------------------------------------------------- 00066 template< typename T > 00067 bool SimpleConnectorT< T >::isConnected( const Name& interactor ) const 00068 { 00069 return _input 00070 && _input->getConnectedOutput() 00071 && _input->getConnectedOutput()->getOwner().getName() == interactor ; 00072 } 00073 //----------------------------------------------------------------- 00074 template< typename T > 00075 bool SimpleConnectorT< T >::preConnect( const Name& interactor, 00076 const OMK::Type::AccessGroupLevel& freezeLevel, 00077 OMK::Type::AccessLevel toolLevel ) 00078 { 00079 // The current interactor should be informed of the new interactor 00080 SendControlTakenBy( interactor ) ; 00081 // To avoid reconnection 00082 disconnect() ; 00083 // conditions 00084 OMASSERT( !_input && _toolsInUse.empty() && "The connector must be available" ) ; 00085 00086 // Update of the tool list 00087 _toolsOnStandby.push_back( interactor ) ; 00088 _toolsInUse.push_back( interactor ) ; 00089 _accessRule->setCurrentLevel( freezeLevel, toolLevel ) ; 00090 00091 return true ; 00092 } 00093 //----------------------------------------------------------------- 00094 template< typename T > 00095 bool SimpleConnectorT< T >::connect( const Name& interactor, const Name& outputName ) 00096 { 00097 bool ok = false ; 00098 Name inputName ; 00099 if( std::find( _toolsOnStandby.begin(), _toolsOnStandby.end(), interactor ) != _toolsOnStandby.end() ) 00100 { 00101 // preconditions 00102 OMASSERT( !_input && "The connector must be disconnected" ) ; 00103 // creates the name's input 00104 inputName = interactor.getString() + outputName.getString() ; 00105 // creates the input in the interactive object 00106 _input = _attribute->createInput( inputName ) ; 00107 // connects it to the interactor output 00108 ok = _input && _input->connect( interactor, outputName ) ; 00109 } 00110 if( ok ) 00111 { // The interactor is no more waiting list 00112 _toolsOnStandby.clear() ; 00113 } 00114 else 00115 { // Unsuccessful connection => delete the input 00116 OMTRACEID( OMK_DEBUG_III, ":-( Error in SimpleConnectorT< \"" << _id 00117 << "\" >:: connect for the " << OMK::debugMsg( _owner ) << std::endl 00118 << ">>> The interactor \"" << interactor << "\" cannot be connected !" ) ; 00119 _owner->deleteInput( inputName ) ; 00120 _input = 0 ; 00121 } 00122 return ok ; 00123 } 00124 //----------------------------------------------------------------- 00125 template< typename T > 00126 void SimpleConnectorT< T >::disconnect( const Name& interactor ) 00127 { 00128 if( isConnected( interactor ) ) 00129 { 00130 SimpleConnectorT< T >::disconnect() ; 00131 } 00132 else 00133 { 00134 OMTRACEID( OMK_DEBUG_III, ":-( Error in SimpleConnectorT< \"" << _id.getString() 00135 << "\" >:: disconnect for the " << OMK::debugMsg( _owner ) << std::endl 00136 << ">>> The interactor \"" << interactor.getString() << "\" is not one of those which are connected !" ) ; 00137 } 00138 } 00139 //----------------------------------------------------------------- 00140 template< typename T > 00141 void SimpleConnectorT< T >::disconnect() 00142 { 00143 // Must send a event to inform the old interactor it was disconnected 00144 if( !_toolsInUse.empty() ) 00145 { 00146 SendControlEnded( *_toolsInUse.begin() ) ; 00147 } 00148 if( _input ) 00149 { 00150 _input->disconnect() ; 00151 _owner->deleteInput( _input->getName() ) ; 00152 _input = 0 ; 00153 } 00154 _toolsOnStandby.clear() ; // discard the possible waiting tool 00155 _toolsInUse.clear() ; 00156 _accessRule->resetCurrentLevel() ; // unfreeze if necessary 00157 } 00158 //----------------------------------------------------------------- 00159 template< typename T > 00160 void SimpleConnectorT< T >::updateParameter() const 00161 { // if it is connected, it updates the parameter 00162 if( _input ) 00163 { 00164 // Update the parameter 00165 if( _convertor ) 00166 { // Through the convertor 00167 T valueOut = _attribute->get() ; 00168 T valueIn ; 00169 _attribute->getValueFromInput( valueIn, _input ) ; 00170 _convertor->convert( valueOut, valueIn ) ; 00171 _attribute->set( valueOut ) ; 00172 } 00173 else 00174 { // directly 00175 _attribute->getValueFromInput( _input ) ; 00176 } 00177 } 00178 } 00179 //----------------------------------------------------------------- 00180 template< typename T > 00181 void SimpleConnectorT< T >::sendValue( const Name& receiver ) const 00182 { 00183 _attribute->sendIdAndValue( receiver, EventId::CURRENT_VALUE, _id ) ; 00184 } 00185 //----------------------------------------------------------------- 00186 00187 00188 //======================================================================== 00189 // SharedConnectorT 00190 //======================================================================== 00191 //----------------------------------------------------------------- 00192 template< typename T > 00193 SharedConnectorT< T >::SharedConnectorT( const Name& id, 00194 const Name& attributeId, 00195 InteractiveExtension *extension, 00196 const ConfigurationParameterDescriptor* node ) 00197 : IConnector( id, attributeId, typeid( T ).name(), extension, node ), 00198 _attribute( extension->getOwner()->getBaseAttribute< T >( attributeId ) ), 00199 _convertor( 0 ) 00200 { 00201 _convertor = IConvertorT< T, std::vector< T > >::create( node ) ; 00202 OMTRACEID( OMK_DEBUG_III, "Creation in " << OMK::debugMsg( _interactiveExtension, _owner ) << " of a shared connector \"" << _id 00203 << "\" for the attribute \"" << attributeId << "\" category \"" << _category << "\"" ) ; 00204 } 00205 //----------------------------------------------------------------- 00206 template< typename T > 00207 SharedConnectorT< T >::~SharedConnectorT() 00208 { 00209 disconnect() ; 00210 delete _convertor ; 00211 } 00212 //----------------------------------------------------------------- 00213 template< typename T > 00214 bool SharedConnectorT< T >::isConnected( const Name& interactor ) const 00215 { 00216 typename MapInput::const_iterator input = _inputs.find( interactor ) ; 00217 return input != _inputs.end() ; 00218 } 00219 //----------------------------------------------------------------- 00220 template< typename T > 00221 bool SharedConnectorT< T >::preConnect( const Name& interactor, 00222 const OMK::Type::AccessGroupLevel& freezeLevel, 00223 OMK::Type::AccessLevel toolLevel ) 00224 { 00225 // The current interactor should be informed of the new interactor 00226 SendControlTakenBy( interactor ) ; 00227 00228 // Update of the tool list 00229 _toolsOnStandby.push_back( interactor ) ; 00230 _toolsInUse.push_back( interactor ) ; 00231 _accessRule->setCurrentLevel( freezeLevel, toolLevel ) ; 00232 00233 return true ; 00234 } 00235 //----------------------------------------------------------------- 00236 template< typename T > 00237 bool SharedConnectorT< T >::connect( const Name& interactor, const Name& outputName ) 00238 { 00239 bool ok = false ; 00240 Name inputName ; 00241 InputNT* input = 0 ; 00242 std::list< Name >::iterator onStandby = std::find( _toolsOnStandby.begin(), _toolsOnStandby.end(), interactor ) ; 00243 if( onStandby != _toolsOnStandby.end() ) 00244 { 00245 // creates the name's input 00246 inputName = interactor.getString() + outputName.getString() ; 00247 // creates the input in the interactive object 00248 input = _attribute->createInput( inputName ) ; 00249 // connects it to the interactor output 00250 ok = input->connect( interactor, outputName ) ; 00251 } 00252 if( ok ) 00253 { // successful connection => add the input to the list 00254 _inputs.insert( std::pair< const Name, InputNT* >( interactor, input ) ) ; 00255 _toolsOnStandby.erase( onStandby ) ; 00256 } 00257 else 00258 { // Unsuccessful connection => delete the input 00259 OMTRACEID( OMK_DEBUG_III, ":-( Error in SharedConnectorT< \"" << _id.getString() 00260 << "\" >:: connect for the " << OMK::debugMsg( _owner ) << std::endl 00261 << ">>> The interactor \"" << interactor.getString() << "\" cannot be connected !" ) ; 00262 if( !input ) 00263 { 00264 _owner->deleteInput( inputName ) ; 00265 } 00266 } 00267 return ok ; 00268 } 00269 //----------------------------------------------------------------- 00270 template< typename T > 00271 void SharedConnectorT< T >::disconnect( const Name& interactor ) 00272 { 00273 // Only this iterator will be disconnected => find it 00274 std::list< Name >::iterator inUse = std::find( _toolsInUse.begin(), _toolsInUse.end(), interactor ) ; 00275 if( inUse != _toolsInUse.end() ) 00276 { 00277 // Inform interactor 00278 SendControlReleased( interactor ) ; 00279 // Clean the lists => no more interactor in them 00280 _toolsInUse.erase( inUse ) ; 00281 std::list< Name >::iterator onStanby = std::find( _toolsOnStandby.begin(), _toolsOnStandby.end(), interactor ) ; 00282 if( onStanby != _toolsOnStandby.end() ) _toolsOnStandby.erase( onStanby ) ; 00283 // Informs every other interactor in use or standby 00284 SendControlReleasedBy( interactor ) ; 00285 // find the input connected to the interactor, disconnects and deletes it 00286 typename MapInput::iterator input = _inputs.find( interactor ) ; 00287 if( input != _inputs.end() ) 00288 { 00289 input->second->disconnect() ; 00290 _owner->deleteInput( input->second->getName() ) ; 00291 _inputs.erase( input ) ; 00292 if( _inputs.empty() ) _accessRule->resetCurrentLevel() ; // unfreeze if necessary 00293 } 00294 } 00295 else 00296 { 00297 OMTRACEID( OMK_DEBUG_III, ":-( Error in SharedConnectorT< \"" << _id.getString() 00298 << "\" >:: disconnect for the " << OMK::debugMsg( _owner ) << std::endl 00299 << ">>> The interactor \"" << interactor.getString() << "\" is not one of those which are connected !" ) ; 00300 } 00301 } 00302 //----------------------------------------------------------------- 00303 template< typename T > 00304 void SharedConnectorT< T >::disconnect() 00305 { 00306 // Inform every connected interactor 00307 for ( std::list< Name >::const_iterator interactor = _toolsInUse.begin() ; interactor != _toolsInUse.end() ; ++interactor ) 00308 { 00309 SendControlEnded( *interactor ) ; 00310 } 00311 // All the iterators will be disconnected 00312 // disconnects and deletes all the inputs and clear the map 00313 for ( typename MapInput::const_iterator i = _inputs.begin() ; i != _inputs.end() ; ++i ) 00314 { 00315 i->second->disconnect() ; 00316 _owner->deleteInput( i->second->getName() ) ; 00317 } 00318 _inputs.clear() ; 00319 _toolsOnStandby.clear() ; 00320 _toolsInUse.clear() ; 00321 _accessRule->resetCurrentLevel() ; // unfreeze if necessary 00322 } 00323 //----------------------------------------------------------------- 00324 template< typename T > 00325 void SharedConnectorT< T >::updateParameter() const 00326 { 00327 // if at least one input is connected, it updates the parameter 00328 if( _inputs.size() ) 00329 { 00330 // Creating a vector with the appropriate size 00331 std::vector< T > values( _inputs.size() ) ; 00332 // Retrieve the value in the inputs 00333 int j = 0 ; 00334 for ( typename MapInput::const_iterator i = _inputs.begin() ; 00335 i != _inputs.end() ; 00336 ++i, j++ ) 00337 { 00338 _attribute->getValueFromInput( values[j], i->second ) ; 00339 } 00340 // Update the parameter 00341 if( _convertor ) 00342 { 00343 T valueOut = _attribute->get() ; 00344 _convertor->convert( valueOut, values ) ; 00345 _attribute->set( valueOut ) ; 00346 } 00347 } 00348 } 00349 //----------------------------------------------------------------- 00350 template< typename T > 00351 void SharedConnectorT< T >::sendValue( const Name& receiver ) const 00352 { 00353 _attribute->sendIdAndValue( receiver, EventId::CURRENT_VALUE, _id ) ; 00354 } 00355 //----------------------------------------------------------------- 00356 00357 00358 00359 //======================================================================== 00360 // AssociatedConnectorT 00361 //======================================================================== 00362 00363 //----------------------------------------------------------------- 00364 template< typename T > 00365 AssociatedConnectorT< T >::AssociatedConnectorT( const Name& id, 00366 const Name& attributeId, 00367 InteractiveExtension *extension, 00368 const ConfigurationParameterDescriptor* node ) 00369 : SimpleConnectorT< T >( id, attributeId, extension, node ), 00370 _associatedConnector( 0 ) 00371 { 00372 } 00373 00374 //----------------------------------------------------------------- 00375 template< typename T > 00376 AssociatedConnectorT< T >::~AssociatedConnectorT() 00377 { 00378 } 00379 00380 //----------------------------------------------------------------- 00381 template< typename T > 00382 bool AssociatedConnectorT< T >::preConnect( const Name& interactor, 00383 const OMK::Type::AccessGroupLevel& freezeLevel, 00384 OMK::Type::AccessLevel toolLevel ) 00385 { 00386 // Disconnect the associated connector if necessary 00387 if( _associatedConnector ) 00388 { 00389 _associatedConnector->disconnect() ; 00390 _associatedConnector->getAccessRule().setCurrentLevel( freezeLevel, toolLevel ) ; 00391 } 00392 return SimpleConnectorT< T >::preConnect( interactor, freezeLevel, toolLevel ) ; 00393 } 00394 00395 //----------------------------------------------------------------- 00396 template< typename T > 00397 bool AssociatedConnectorT< T >::loadParameters( const ConfigurationParameterDescriptor* node ) 00398 { 00399 // Retrieve the associated connector 00400 Name id ; 00401 ParametersAccessor::get( node, "AssociatedTo", id ) ; 00402 _associatedConnector = this->_interactiveExtension->getConnector( id ) ; 00403 00404 return OMK::Iii::SimpleConnectorT< T >::loadParameters( node ) ; 00405 } 00406 00407 //----------------------------------------------------------------- 00408 00409 }// namespace Iii 00410 }// namespace OMK 00411 00412 #endif // defined OMK_III_CONNECTORS_INL
Documentation generated on Mon Jun 9 11:45:56 2008 |
Generated with doxygen by Dimitri van Heesch , 1997-2007 |