00001 /* 00002 * This file is part of openMask © INRIA, CNRS, Universite de Rennes 1 1993-2002, thereinafter the Software 00003 * 00004 * The Software has been developped within the Siames Project. 00005 * INRIA, the University of Rennes 1 and CNRS jointly hold intellectual property rights 00006 * 00007 * The Software has been registered with the Agence pour la Protection des 00008 * Programmes (APP) under registration number IDDN.FR.001.510008.00.S.P.2001.000.41200 00009 * 00010 * This file may be distributed under the terms of the Q Public License 00011 * version 1.0 as defined by Trolltech AS of Norway and appearing in the file 00012 * LICENSE.QPL included in the packaging of this file. 00013 * 00014 * Licensees holding valid specific licenses issued by INRIA, CNRS or Université de Rennes 1 00015 * for the software may use this file in accordance with that specific license 00016 * 00017 */ 00018 00019 #include "PsObjectDescriptor.h" 00020 #include "PsMultipleConfigurationParameter.h" 00021 #include "PsUniqueConfigurationParameter.h" 00022 #include "PsSimulatedObject.h" 00023 #include "PsnCurrentActiveObject.h" 00024 00025 #include "tokens.h" 00026 #include "genericKernelParser.h" 00027 #include "KernelIstreamLexer.h" 00028 00029 const PsName & PsObjectDescriptor::getName () const 00030 { 00031 return _objectName ; 00032 } 00033 00034 const PsName & PsObjectDescriptor::getClass () const 00035 { 00036 return _classId; 00037 } 00038 00039 const PsName & PsObjectDescriptor::getProcess () const 00040 { 00041 return _processId ; 00042 } 00043 00044 const PsFrequency & PsObjectDescriptor::getFrequency () const 00045 { 00046 return _frequency ; 00047 } 00048 00049 00050 const PsFrequency & PsObjectDescriptor::getOriginalFrequency () const 00051 { 00052 return _originalFrequency ; 00053 } 00054 00055 const PsConfigurationParameterDescriptor * PsObjectDescriptor::getConfigurationParameters() const 00056 { 00057 return _configurationParameters ; 00058 } 00059 00060 PsConfigurationParameterDescriptor * PsObjectDescriptor::getConfigurationParameters() 00061 { 00062 return _configurationParameters ; 00063 } 00064 00065 const PsMultipleConfigurationParameter * PsObjectDescriptor::getSchedulingParameters() const 00066 { 00067 return _schedulingParameters ; 00068 } 00069 00070 PsMultipleConfigurationParameter * PsObjectDescriptor::getSchedulingParameters() 00071 { 00072 return _schedulingParameters ; 00073 } 00074 00075 const PsMultipleConfigurationParameter * PsObjectDescriptor::getOriginalSchedulingParameters() const 00076 { 00077 return _originalSchedulingParameters ; 00078 } 00079 00080 00081 00082 void PsObjectDescriptor::unpack (PsIncomingSynchronisationMessage & in) 00083 { 00084 #ifdef _USESSTREAM 00085 // but much simpler to decode 00086 string messageBuffer ; 00087 00088 in>>messageBuffer ; 00089 00090 istringstream message ( messageBuffer ); 00091 00092 extract (message ) ; 00093 #else 00094 // but much simpler to decode 00095 int messageSize ; 00096 00097 in>>messageSize ; 00098 char * messageBuffer = new char [messageSize]; 00099 in>>messageBuffer ; 00100 00101 assert (messageBuffer[messageSize -1] == '\0' ) ; 00102 00103 istrstream message ( messageBuffer ); 00104 extract (message ) ; 00105 #endif 00106 } 00107 00108 00109 00110 void PsObjectDescriptor::pack (PsOutgoingSynchronisationMessage & out) const 00111 { 00112 // packed in a quite inefficient way (unsing the string representation of the object descriptor), 00113 // but much simpler to decode : therefore, use extract 00114 #ifdef _USESSTREAM 00115 ostringstream char_out ; 00116 printToStream ( char_out, 0 ) ; 00117 out<<char_out.str() ; 00118 #else 00119 ostrstream char_out ; 00120 printToStream ( char_out, 0 ) ; 00121 char_out.put ('\0') ; 00122 char * C_string = char_out.str() ; 00123 assert (C_string[char_out.pcount()-1] == '\0') ; 00124 out<<char_out.pcount() ; 00125 out<<C_string; 00126 delete C_string ; 00127 #endif 00128 } 00129 00130 void PsObjectDescriptor::extract (istream & in) 00131 { 00132 _sonsContainer.clear() ; 00133 00134 KernelIstreamLexer<istream> inputStream (in) ; 00135 DLGLexer scan( & inputStream ) ; 00136 ANTLRTokenBuffer pipe ( & scan ) ; 00137 ANTLRTokenPtr aToken = new ANTLRToken() ; 00138 scan.setToken(mytoken(aToken)) ; 00139 genericKernelParser extractor ( &pipe ) ; 00140 extractor.init() ; 00141 00142 string stringName; 00143 extractor.key ( stringName ) ; 00144 _objectName = stringName ; 00145 00146 PsConfigurationParameterDescriptor * genericSubDescription = extractor.anonymousValue() ; 00147 PsMultipleConfigurationParameter * generalDescription = dynamic_cast<PsMultipleConfigurationParameter *> ( genericSubDescription ); 00148 00149 if ( generalDescription == NULL ) 00150 { 00151 throw PsUserException("Unable to extract a name for an ObjectDescriptor from a stream") ; 00152 } 00153 00154 00155 genericSubDescription = generalDescription->getSubDescriptorByName ("Class") ; 00156 if ( genericSubDescription == NULL ) 00157 { 00158 throw PsUserException("Unable to extract a class for an ObjectDescriptor from a stream") ; 00159 } 00160 _classId = genericSubDescription->getAssociatedString() ; 00161 00162 delete _configurationParameters ; 00163 _configurationParameters = generalDescription->getSubDescriptorByName ("UserParams") ; 00164 00165 genericSubDescription = generalDescription->getSubDescriptorByName ("Scheduling") ; 00166 if (genericSubDescription!=NULL) 00167 { 00168 interpretSchedulingParameters( dynamic_cast<PsMultipleConfigurationParameter * >(genericSubDescription ) ) ; 00169 } 00170 else 00171 { 00172 interpretSchedulingParameters(NULL) ; 00173 } 00174 00175 genericSubDescription = generalDescription->getSubDescriptorByName ("Sons") ; 00176 generalDescription = dynamic_cast<PsMultipleConfigurationParameter *> (genericSubDescription) ; 00177 if (generalDescription != NULL) 00178 { 00179 interpretConfigurationParameterAsListOfSons ( _sonsContainer, generalDescription ) ; 00180 } 00181 } 00182 00183 00184 void PsObjectDescriptor::printToStream (ostream & out, int offset) const 00185 { 00186 //suppose any needed offset has allready been printed 00187 out<<getName()<<endl; 00188 printTabToStream(out,offset+2) ; 00189 out<<"{"<<endl; 00190 printTabToStream(out,offset+4) ; 00191 out<<"Class "<<getClass()<<endl; 00192 if ( getSchedulingParameters() != NULL ) 00193 { 00194 printTabToStream(out,offset+4) ; 00195 out<<"Scheduling " ; 00196 getSchedulingParameters()->printToStream(out,offset+6) ; 00197 out<<endl; 00198 } 00199 if ( getConfigurationParameters() != NULL ) 00200 { 00201 printTabToStream(out,offset+4) ; 00202 out<<"UserParams " ; 00203 getConfigurationParameters()->printToStream(out,offset+6) ; 00204 out<<endl; 00205 } 00206 if ( _sonsContainer.size() != 0 ) 00207 { 00208 printTabToStream(out,offset+4) ; 00209 out<<"Sons"<<endl; 00210 printTabToStream(out,offset+6) ; 00211 out<<"{"<<endl; 00212 for ( SonsContainerType::const_iterator i = _sonsContainer.begin() ; 00213 i != _sonsContainer.end() ; 00214 ++i ) 00215 { 00216 printTabToStream(out,offset+8) ; 00217 (*i)->printToStream (out, offset+8 ) ; 00218 } 00219 printTabToStream(out,offset+6) ; 00220 out<<"}"<<endl; 00221 } 00222 printTabToStream(out,offset+2) ; 00223 out<<"}"<<endl; 00224 } 00225 00226 00227 00228 void PsObjectDescriptor::insertInStream (ostream & out) const 00229 { 00230 printToStream ( out, 0 ) ; 00231 } 00232 00233 00234 00235 void PsObjectDescriptor::setProcess (const PsName & newProcessName) 00236 { 00237 _processId = newProcessName ; 00238 PsUniqueConfigurationParameter * description = dynamic_cast<PsUniqueConfigurationParameter *>(_schedulingParameters->getSubDescriptorByName ("Process") ); 00239 if ( description != NULL ) 00240 { 00241 description->changeConfigurationParameter (newProcessName.getCString() ) ; 00242 } 00243 else 00244 { 00245 _schedulingParameters->appendSubDescriptorNamed ("Process", 00246 new PsUniqueConfigurationParameter (newProcessName.getCString() ) ) ; 00247 00248 } 00249 } 00250 void PsObjectDescriptor::setFrequency (const PsFrequency & newFrequency) 00251 { 00252 _frequency = newFrequency ; 00253 00254 PsUniqueConfigurationParameter * description = dynamic_cast<PsUniqueConfigurationParameter *>(_schedulingParameters->getSubDescriptorByName ("Frequency") ); 00255 00256 if ( description != NULL ) 00257 { 00258 #ifdef _USESSTREAM 00259 ostringstream freq ; 00260 freq << newFrequency ; 00261 description->changeConfigurationParameter ( freq.str() ) ; 00262 #else 00263 ostrstream freq ; 00264 freq << newFrequency ; 00265 freq.put ('\0') ; 00266 description->changeConfigurationParameter ( freq.str() ) ; 00267 delete freq.str() ; 00268 #endif 00269 } 00270 else 00271 { 00272 #ifdef _USESSTREAM 00273 ostringstream freq ; 00274 freq << newFrequency ; 00275 _schedulingParameters->appendSubDescriptorNamed ("Frequency", 00276 new PsUniqueConfigurationParameter (freq.str() ) ) ; 00277 #else 00278 ostrstream freq ; 00279 freq << newFrequency ; 00280 freq.put ('\0') ; 00281 _schedulingParameters->appendSubDescriptorNamed ("Frequency", 00282 new PsUniqueConfigurationParameter (freq.str() ) ) ; 00283 delete freq.str() ; 00284 #endif 00285 } 00286 } 00287 00288 void PsObjectDescriptor::interpretSchedulingParameters (PsMultipleConfigurationParameter * schedulingParameters) 00289 { 00290 if ( (_schedulingParameters != NULL) && (_schedulingParameters != schedulingParameters ) ) delete _schedulingParameters ; 00291 00292 _schedulingParameters = schedulingParameters ; 00293 00294 if ( _schedulingParameters == NULL ) 00295 { 00296 _schedulingParameters = new PsMultipleConfigurationParameter() ; 00297 } 00298 00299 const PsConfigurationParameterDescriptor * description ; 00300 description = _schedulingParameters->getSubDescriptorByName ("Frequency") ; 00301 00302 if ( description != NULL ) 00303 { 00304 _frequency = atoi (description->getAssociatedString().c_str() ) ; 00305 } 00306 else 00307 { 00308 _frequency = 0 ; 00309 _schedulingParameters->appendSubDescriptorNamed ("Frequency", 00310 new PsUniqueConfigurationParameter ("0") ) ; 00311 } 00312 00313 if ( _originalSchedulingParameters != NULL ) 00314 { 00315 delete _originalSchedulingParameters ; 00316 } 00317 _originalSchedulingParameters = dynamic_cast<PsMultipleConfigurationParameter *> ( _schedulingParameters->clone () ) ; 00318 assert ( _originalSchedulingParameters != NULL ) ; 00319 00320 _originalFrequency = _frequency ; 00321 00322 description = _schedulingParameters->getSubDescriptorByName ("Process") ; 00323 00324 if ( description != NULL ) 00325 { 00326 _processId = description->getAssociatedString() ; 00327 } 00328 } 00329 00330 PsObjectDescriptor::PsObjectDescriptor () : 00331 _configurationParameters (NULL), 00332 _originalSchedulingParameters (NULL), 00333 _schedulingParameters (NULL), 00334 _fathersDescription (NULL), 00335 _frequency(0), 00336 _originalFrequency ( 0 ), 00337 _creatingObject (false ), 00338 _creatingThread (0), 00339 _destroySimulatedObject (false ), 00340 _pointerToSimulatedObject (NULL) 00341 { 00342 // otherwise, the initial value of _creatingThread is inappropriate 00343 assert (pthread_self() != 0) ; 00344 } 00345 00346 PsObjectDescriptor::PsObjectDescriptor ( const PsObjectDescriptor & orig ) : 00347 _pointerToSimulatedObject (NULL ), 00348 _destroySimulatedObject ( false ), 00349 _objectName (orig._objectName), 00350 _classId ( orig._classId), 00351 _fathersDescription ( NULL ), 00352 _processId ( orig._processId), 00353 _frequency ( orig._frequency ), 00354 _originalFrequency ( orig._originalFrequency ), 00355 _creatingObject ( false ) 00356 { 00357 if ( orig._configurationParameters != NULL ) 00358 { 00359 _configurationParameters = orig._configurationParameters->clone() ; 00360 } 00361 else 00362 { 00363 _configurationParameters = NULL ; 00364 } 00365 if ( orig._originalSchedulingParameters != NULL ) 00366 { 00367 _originalSchedulingParameters = dynamic_cast<PsMultipleConfigurationParameter *> (orig._originalSchedulingParameters->clone() ) ; 00368 assert ( _originalSchedulingParameters != NULL ) ; 00369 } 00370 else 00371 { 00372 _originalSchedulingParameters = NULL ; 00373 } 00374 if ( orig._schedulingParameters != NULL ) 00375 { 00376 _schedulingParameters = dynamic_cast<PsMultipleConfigurationParameter *> (orig._schedulingParameters->clone()) ; 00377 assert ( _schedulingParameters != NULL ) ; 00378 } 00379 else 00380 { 00381 _schedulingParameters = NULL ; 00382 } 00383 00384 // only one descriptor by object. Assume descriptor is copied only before the described object is created 00385 assert ( orig._pointerToSimulatedObject == NULL ) ; 00386 assert ( orig._destroySimulatedObject == false ) ; 00387 00388 // copy the sons 00389 for ( SonsContainerType::const_iterator i = orig._sonsContainer.begin() ; 00390 i != orig. _sonsContainer.end() ; 00391 ++i ) 00392 { 00393 addSon ( new PsObjectDescriptor (*(*i)) ) ; 00394 } 00395 } 00396 00397 PsObjectDescriptor::PsObjectDescriptor (const PsName & objectName, 00398 const PsName & classId, 00399 const PsName & processId, 00400 const PsFrequency & frequency, 00401 PsConfigurationParameterDescriptor * configurationParameters) : 00402 _objectName ( objectName ), 00403 _classId ( classId ), 00404 _processId ( processId ), 00405 _frequency ( frequency ), 00406 _originalFrequency ( frequency ), 00407 _configurationParameters ( configurationParameters ), 00408 _pointerToSimulatedObject( NULL ), 00409 _destroySimulatedObject ( false ), 00410 _fathersDescription ( NULL ), 00411 _creatingObject (false), 00412 _creatingThread ( 0 ) 00413 { 00414 assert (pthread_self() != 0) ; 00415 _schedulingParameters = new PsMultipleConfigurationParameter () ; 00416 #ifdef _USESSTREAM 00417 ostringstream freq ; 00418 freq << frequency ; 00419 _schedulingParameters->appendSubDescriptorNamed ("Frequency", 00420 new PsUniqueConfigurationParameter (freq.str() ) ) ; 00421 #else 00422 ostrstream freq ; 00423 freq << frequency ; 00424 freq.put('\0') ; 00425 _schedulingParameters->appendSubDescriptorNamed ("Frequency", 00426 new PsUniqueConfigurationParameter (freq.str() ) ) ; 00427 delete freq.str() ; 00428 #endif 00429 _schedulingParameters->appendSubDescriptorNamed ("Process", 00430 new PsUniqueConfigurationParameter (processId.getCString() ) ) ; 00431 _originalSchedulingParameters = dynamic_cast<PsMultipleConfigurationParameter * >(_schedulingParameters->clone ()) ; 00432 assert (_originalSchedulingParameters != NULL ) ; 00433 } 00434 00435 00436 00437 PsObjectDescriptor::PsObjectDescriptor (const PsName & objectName, 00438 const PsName & classId, 00439 const PsFrequency & frequency, 00440 PsConfigurationParameterDescriptor * configurationParameters) : 00441 _objectName ( objectName ), 00442 _classId ( classId ), 00443 _frequency ( frequency ), 00444 _originalFrequency ( frequency ), 00445 _configurationParameters ( configurationParameters ), 00446 _pointerToSimulatedObject( NULL ), 00447 _destroySimulatedObject ( false ), 00448 _fathersDescription ( NULL ), 00449 _creatingObject (false), 00450 _creatingThread ( 0 ) 00451 { 00452 assert (pthread_self() != 0) ; 00453 _schedulingParameters = new PsMultipleConfigurationParameter () ; 00454 #ifdef _USESSTREAM 00455 ostringstream freq ; 00456 freq << frequency ; 00457 _schedulingParameters->appendSubDescriptorNamed ("Frequency", 00458 new PsUniqueConfigurationParameter (freq.str() ) ) ; 00459 #else 00460 ostrstream freq ; 00461 freq << frequency ; 00462 freq.put('\0') ; 00463 _schedulingParameters->appendSubDescriptorNamed ("Frequency", 00464 new PsUniqueConfigurationParameter (freq.str() ) ) ; 00465 delete freq.str() ; 00466 #endif 00467 _originalSchedulingParameters = dynamic_cast<PsMultipleConfigurationParameter * >(_schedulingParameters->clone ()) ; 00468 assert (_originalSchedulingParameters != NULL ) ; 00469 } 00470 00471 00472 00473 PsObjectDescriptor::PsObjectDescriptor (const PsName & objectName, 00474 const PsName & classId, 00475 PsMultipleConfigurationParameter * schedulingParameters, 00476 PsConfigurationParameterDescriptor * configurationParameters) : 00477 _objectName ( objectName ), 00478 _classId ( classId ), 00479 _configurationParameters ( configurationParameters ), 00480 _schedulingParameters ( schedulingParameters ), 00481 _pointerToSimulatedObject( NULL ), 00482 _destroySimulatedObject ( false ), 00483 _fathersDescription ( NULL ), 00484 _originalSchedulingParameters (NULL), 00485 _creatingObject (false), 00486 _creatingThread ( 0 ) 00487 { 00488 assert (pthread_self() != 0) ; 00489 interpretSchedulingParameters (schedulingParameters) ; 00490 } 00491 00492 00493 00494 PsObjectDescriptor::~PsObjectDescriptor() 00495 { 00496 if ( _destroySimulatedObject ) 00497 { 00498 assert (_pointerToSimulatedObject != NULL) ; 00499 delete _pointerToSimulatedObject ; 00500 } 00501 00502 if ( _fathersDescription != NULL ) 00503 { 00504 _fathersDescription->removeSon (this) ; 00505 } 00506 00507 if ( _originalSchedulingParameters != NULL ) delete _originalSchedulingParameters ; 00508 if ( _schedulingParameters != NULL ) delete _schedulingParameters ; 00509 if ( _configurationParameters != NULL ) delete _configurationParameters ; 00510 00511 if (! _sonsContainer.empty() ) 00512 { 00513 cout<<"PsObjectDescriptor with "<<_sonsContainer.size()<<" remaining sons deleted. Sons not deleted"<<endl; 00514 } 00515 } 00516 00517 void PsObjectDescriptor::setFathersDescription ( PsObjectDescriptor * newFather ) 00518 { 00519 assert (newFather != NULL) ; 00520 if ( _fathersDescription != NULL ) 00521 { 00522 _fathersDescription->removeSon (this) ; 00523 } 00524 00525 if ( newFather->findDescendantNamed ( getName() ) != NULL ) 00526 { 00527 //cannot add the object : do nothing 00528 #ifdef _USESSTREAM 00529 ostringstream warningMessage ; 00530 warningMessage<<"PsObjectDescriptor::setFathersDescription of object named "<<getName() 00531 <<" failed because descendant with the same name allready exists for object named " 00532 <<newFather->getName()<<"\n"; 00533 PsController::warning ( warningMessage.str() , PsController::SomeWarnings) ; 00534 #else 00535 ostrstream warningMessage ; 00536 warningMessage<<"PsObjectDescriptor::setFathersDescription of object named "<<getName() 00537 <<" failed because descendant with the same name allready exists for object named " 00538 <<newFather->getName()<<"\n"; 00539 warningMessage.put('\0') ; 00540 PsController::warning ( warningMessage.str() , PsController::SomeWarnings) ; 00541 delete warningMessage.str() ; 00542 #endif 00543 } 00544 else 00545 { 00546 newFather->addSon ( this ) ; 00547 } 00548 } 00549 00550 PsSimulatedObject * PsObjectDescriptor::createDescribedObject() const 00551 { 00552 //here, use mutual exclusion, to avoid 00553 // 1 - recursive creation loops 00554 // 2 - simultaneous creations 00555 // 3 - recursive creation loops during simultaneous creations !!! 00556 00557 //therefore, only allow one thread to do creation at a time (share the creatingThread exclusion lock, 00558 // and test to see if we're in a recursive loop ) 00559 00560 _dataLock.protect() ; 00561 00562 PsSimulatedObject * result = _pointerToSimulatedObject ; 00563 00564 if ( _pointerToSimulatedObject == NULL ) 00565 { 00566 00567 if ( _creatingObject && (_creatingThread == pthread_self() ) ) 00568 { 00569 // recursive creation loop : return NULL is the best that can be done 00570 _dataLock.unprotect() ; 00571 } 00572 else 00573 { 00574 // the object needs creating : here the question is whether an other thread is creating it or not 00575 if ( _creatingObject ) 00576 { 00577 //other thread is creating the object : wait for it to finish creation 00578 _createdCondition.waitForChange(_dataLock) ; 00579 } 00580 else 00581 { 00582 //no thread is creating the object, 00583 //therefore this thread takes responsability for creation 00584 _creatingObject = true ; 00585 _creatingThread = pthread_self() ; 00586 _dataLock.unprotect() ; 00587 00588 //here, we can garantie that we are the only creating thread, 00589 //and that 00590 // 1 - any recursive creation loop is a non-blocking creation 00591 // 2 - other threads creating the object are waiting on the condition 00592 00593 //attempt object creation 00594 PsSimulatedObject * father = NULL ; 00595 const PsObjectDescriptor * fathersDescription = _fathersDescription ; 00596 00597 // as creation can happen during a paralel simulation, 00598 // it can happen at a time where getCurrentActiveObject returns the object whose request 00599 // triggered instance creation. 00600 // Therefore, the current active object is temporarly set to NULL, so as to mimic creation phase 00601 // If it is set to the controller, changing a controlparamter triggers the sending of a valueEvent by the controller, which might not have it's objectHandle initialized in order to avoid being scheduled by itself 00602 PsnCurrentActiveObject context ( NULL ) ; 00603 00604 while ( fathersDescription != NULL ) 00605 { 00606 father = fathersDescription->createDescribedObject() ; 00607 if ( father != NULL ) 00608 { 00609 result = father -> createInstanceOfEncapsulatedClass (*this); 00610 _dataLock.protect() ; 00611 _pointerToSimulatedObject = result ; 00612 _dataLock.unprotect() ; 00613 if ( _pointerToSimulatedObject != NULL ) 00614 { 00615 _destroySimulatedObject = true ; 00616 fathersDescription = NULL ; 00617 } 00618 else 00619 { 00620 fathersDescription = fathersDescription->getFathersObjectDescriptor() ; 00621 } 00622 } 00623 else 00624 { 00625 fathersDescription = NULL ; 00626 } 00627 } 00628 } 00629 if ( _pointerToSimulatedObject == NULL ) 00630 { 00631 #ifdef _USESSTREAM 00632 ostringstream warningMessage; 00633 warningMessage<<"PsController::createReferenceObject: unable to create "<<getName() 00634 <<" of class "<<getClass()<<endl; 00635 00636 PsController::warning ( warningMessage.str() , PsController::SomeWarnings ) ; 00637 #else 00638 ostrstream warningMessage; 00639 warningMessage<<"PsController::createReferenceObject: unable to create "<<getName() 00640 <<" of class "<<getClass()<<endl; 00641 00642 warningMessage.put('\0') ; 00643 PsController::warning ( warningMessage.str() , PsController::SomeWarnings ) ; 00644 delete warningMessage.str() ; 00645 #endif 00646 } 00647 _dataLock.protect() ; 00648 _creatingObject = false ; 00649 _creatingThread = 0 ; 00650 _dataLock.unprotect() ; 00651 //wathever the result, unblock other waiting threads 00652 _createdCondition.signalChange() ; 00653 } 00654 } 00655 else 00656 { 00657 _dataLock.unprotect() ; 00658 } 00659 return result ; 00660 } 00661 00662 00663 00664 const PsObjectDescriptor * PsObjectDescriptor::getFathersObjectDescriptor() const 00665 { 00666 return _fathersDescription ; 00667 } 00668 00669 00670 PsObjectDescriptor * PsObjectDescriptor::getFathersObjectDescriptor() 00671 { 00672 return _fathersDescription ; 00673 } 00674 00675 00676 00677 void PsObjectDescriptor::deleteCachedData() 00678 { 00679 if ( _destroySimulatedObject ) 00680 { 00681 assert (_pointerToSimulatedObject != NULL) ; 00682 delete _pointerToSimulatedObject ; 00683 _pointerToSimulatedObject = NULL ; 00684 } 00685 _destroySimulatedObject = false ; 00686 } 00687 00688 00689 00690 const list<PsObjectDescriptor *> * PsObjectDescriptor::getSons() const 00691 { 00692 return & _sonsContainer ; 00693 } 00694 00695 PsObjectDescriptor::SonsContainerType & PsObjectDescriptor::getSons() 00696 { 00697 return _sonsContainer ; 00698 } 00699 00700 00701 void PsObjectDescriptor::addSon(PsObjectDescriptor * newSon ) 00702 { 00703 assert ( newSon != NULL ) ; 00704 const PsObjectDescriptor * duplicate = findDescendantNamed (newSon->getName() ) ; 00705 if ( duplicate == NULL ) 00706 { 00707 _sonsContainer.push_back ( newSon ) ; 00708 newSon->_fathersDescription = this ; 00709 } 00710 else 00711 { 00712 #ifdef _USESSTREAM 00713 ostringstream warningMessage ; 00714 warningMessage<<"PsObjectDescriptor::addSon named "<<newSon->getName() 00715 <<" failed because descendant with the same name allready exists for object named " 00716 <<getName()<<"\n"; 00717 PsController::warning ( warningMessage.str() , PsController::SomeWarnings) ; 00718 #else 00719 ostrstream warningMessage ; 00720 warningMessage<<"PsObjectDescriptor::addSon named "<<newSon->getName() 00721 <<" failed because descendant with the same name allready exists for object named " 00722 <<getName()<<"\n"; 00723 warningMessage.put('\0') ; 00724 PsController::warning ( warningMessage.str() , PsController::SomeWarnings) ; 00725 delete warningMessage.str() ; 00726 #endif 00727 // as respnsability is transfered and the son is not added, delete it 00728 delete newSon ; 00729 } 00730 } 00731 00732 00733 00734 void PsObjectDescriptor::removeSon(PsObjectDescriptor * oldSon ) 00735 { 00736 _sonsContainer.remove (oldSon) ; 00737 } 00738 00739 00740 00741 list<const PsObjectDescriptor *> * PsObjectDescriptor::getDescendants() const 00742 { 00743 list<const PsObjectDescriptor *> * result = new list<const PsObjectDescriptor *> () ; 00744 return getDescendants (result) ; 00745 } 00746 00747 00748 list<const PsObjectDescriptor *> * PsObjectDescriptor::getDescendants(list<const PsObjectDescriptor *> * resultList) const 00749 { 00750 for ( SonsContainerType::const_iterator i = _sonsContainer.begin() ; 00751 i != _sonsContainer.end() ; 00752 ++i ) 00753 { 00754 resultList->push_back( (*i) ) ; 00755 (*i)->getDescendants ( resultList ) ; 00756 } 00757 return resultList ; 00758 } 00759 00760 00761 list<PsObjectDescriptor *> * PsObjectDescriptor::getDescendants() 00762 { 00763 list<PsObjectDescriptor *> * result = new list<PsObjectDescriptor *> () ; 00764 return getDescendants (result) ; 00765 } 00766 00767 00768 00769 list< PsObjectDescriptor *> * PsObjectDescriptor::getDescendants(list<PsObjectDescriptor *> * resultList) 00770 { 00771 for ( SonsContainerType::const_iterator i = _sonsContainer.begin() ; 00772 i != _sonsContainer.end() ; 00773 ++i ) 00774 { 00775 resultList->push_back( (*i) ) ; 00776 (*i)->getDescendants ( resultList ) ; 00777 } 00778 return resultList ; 00779 } 00780 00781 00782 00783 const PsObjectDescriptor * 00784 PsObjectDescriptor::findDescendantNamed(const PsName & name) const 00785 { 00786 const PsObjectDescriptor * resul = NULL ; 00787 00788 if ( name == getName() ) 00789 { 00790 resul = this ; 00791 } 00792 else 00793 { 00794 SonsContainerType::const_iterator i = _sonsContainer.begin() ; 00795 while ( (resul == NULL) && 00796 (i != _sonsContainer.end() ) ) 00797 { 00798 resul = (*i)->findDescendantNamed ( name ) ; 00799 ++i ; 00800 } 00801 } 00802 return resul ; 00803 } 00804 00805 00806 00807 PsObjectDescriptor * 00808 PsObjectDescriptor::findDescendantNamed(const PsName & name) 00809 { 00810 PsObjectDescriptor * resul = NULL ; 00811 00812 if ( name == getName() ) 00813 { 00814 resul = this ; 00815 } 00816 else 00817 { 00818 SonsContainerType::iterator i = _sonsContainer.begin() ; 00819 while ( (resul == NULL) && 00820 (i != _sonsContainer.end() ) ) 00821 { 00822 resul = (*i)->findDescendantNamed ( name ) ; 00823 ++i ; 00824 } 00825 } 00826 return resul ; 00827 } 00828 00829 void PsObjectDescriptor::interpretConfigurationParameterAsListOfSons (SonsContainerType & listOfSons, 00830 PsMultipleConfigurationParameter * sonsDescription ) 00831 { 00832 if ( sonsDescription != NULL ) 00833 { 00834 int nbSons = sonsDescription->getNumberOfSubItems() ; 00835 string sonName ; 00836 for ( int i = 0 ; i < nbSons ; ++i ) 00837 { 00838 PsConfigurationParameterDescriptor * aGenericSonsDescription ; 00839 aGenericSonsDescription = sonsDescription->getSubDescriptorByPosition(i) ; 00840 sonName = sonsDescription->getNameOfSubDescriptor (i) ; 00841 PsMultipleConfigurationParameter * aSonsDescription ; 00842 aSonsDescription = dynamic_cast<PsMultipleConfigurationParameter *> ( aGenericSonsDescription ) ; 00843 if ( aSonsDescription != NULL ) 00844 { 00845 PsObjectDescriptor * descriptionOfSon ; 00846 descriptionOfSon = interpretConfigurationParameterAsObjectDescription ( sonName, 00847 aSonsDescription ) ; 00848 listOfSons.push_back ( descriptionOfSon ); 00849 } 00850 } 00851 } 00852 } 00853 00854 PsObjectDescriptor * PsObjectDescriptor::interpretConfigurationParameterAsObjectDescription ( string objectName, 00855 PsMultipleConfigurationParameter * generalDescription ) 00856 { 00857 assert (generalDescription != NULL) ; 00858 00859 PsConfigurationParameterDescriptor * genericSubDescription = generalDescription->getSubDescriptorByName ("Class") ; 00860 00861 if ( genericSubDescription == NULL ) 00862 { 00863 throw PsUserException("Unable to extract a class for an ObjectDescriptor from a stream") ; 00864 } 00865 00866 string classId = genericSubDescription->getAssociatedString() ; 00867 00868 00869 PsConfigurationParameterDescriptor * configurationParameters ; 00870 configurationParameters = generalDescription->getSubDescriptorByName ("UserParams") ; 00871 00872 00873 PsMultipleConfigurationParameter * schedulingParameters ; 00874 schedulingParameters = dynamic_cast<PsMultipleConfigurationParameter *> 00875 ( generalDescription->getSubDescriptorByName ("Scheduling") ) ; 00876 00877 00878 PsObjectDescriptor * result = new PsObjectDescriptor (PsName (objectName), 00879 PsName (classId), 00880 schedulingParameters, 00881 configurationParameters) ; 00882 00883 00884 genericSubDescription = generalDescription->getSubDescriptorByName ("Sons") ; 00885 generalDescription = dynamic_cast<PsMultipleConfigurationParameter *> (genericSubDescription) ; 00886 if (generalDescription != NULL) 00887 { 00888 interpretConfigurationParameterAsListOfSons ( result->_sonsContainer, generalDescription ) ; 00889 //for all the sons, connect to their father, only known here 00890 for ( SonsContainerType::const_iterator i = result->_sonsContainer.begin() ; 00891 i != result->_sonsContainer.end() ; 00892 ++i ) 00893 { 00894 (*i)->_fathersDescription = result ; 00895 } 00896 } 00897 return result ; 00898 } 00899 00900 00901 00902 00903 00904
| Documentation generated on Mon Nov 25 15:25:02 2002 |
Generated with doxygen 1.2.12 by Dimitri van Heesch , 1997-2001 |