Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

PsObjectDescriptor.cxx

Go to the documentation of this file.
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 

logo OpenMask

Documentation generated on Mon Nov 25 15:25:02 2002

Generated with doxygen 1.2.12 by Dimitri van Heesch ,   1997-2001