DeviceFactoryImp.h

Go to the documentation of this file.
00001 // Copyright CERN 2012 - Developed in collaboration with GSI
00002 
00003 #ifndef DEVICE_FACTORY_IMP_H_
00004 #define DEVICE_FACTORY_IMP_H_
00005 
00006 #include <fesa-core/DataStore/AbstractField.h>
00007 #include <fesa-core/DataStore/EquipmentData.h>
00008 #include <fesa-core/DataStore/InitializeDataStoreManager.h>
00009 #include <fesa-core/Core/AbstractEquipment.h>
00010 #include <fesa-core/Synchronization/SynchronizationLabObjectFactory.h>
00011 #include <fesa-core/Synchronization/AbstractMultiplexingManager.h>
00012 #include <fesa-core/Persistency/PersistencyManager.h>
00013 #include <fesa-core/Persistency/PersistencyUnit.h>
00014 #include <fesa-core/Utilities/ParserElements.h>
00015 #include <fesa-core/Utilities/StringUtilities.h>
00016 #include <fesa-core/Exception/FesaException.h>
00017 
00018 #include <string>
00019 #include <vector>
00020 #include <sys/stat.h>
00021 
00022 
00023 namespace fesa
00024 {
00025 
00037 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00038 class DeviceFactoryImp
00039 {
00040   public:
00045     DeviceFactoryImp(const std::string& className);
00046 
00050     virtual ~DeviceFactoryImp();
00051 
00056     const std::vector<DevInstType*>& getDeviceCollection();
00057 
00062     GlobalDeviceType* getGlobalDevice();
00063 
00069     DevInstType* getDevice(const std::string& deviceName);
00070 
00079     void initialize();
00080 
00081   protected:
00082 
00088     virtual bool setUpMemory() = 0;
00089 
00095     void computeMemorySize();
00096 
00101     void mapFields(char* p, bool initializeFields);
00102 
00106     void unmapFields();
00107 
00111     void registerPersistenceFields();
00112 
00116     std::vector<DevInstType *> pDeviceCol_;
00117 
00121     std::vector<DomainStoreType*> pDomainStoreCol_;
00122 
00126     GlobalDeviceType* pGlobalDevice_;
00127 
00131     int32_t size_;
00132 
00136     int32_t globalDeviceSize_;
00137 
00141     int32_t domainStoreSize_;
00142 
00146     int32_t devicesSize_;
00147 
00151     int32_t muxManagersSize_;
00152 
00156     int32_t equimentDataSize_;
00157 
00158   private:
00159 
00163     void createDevices(const std::vector<DeviceElement*>& pDeviceElementCol);
00164 
00168     void createDomainStores(const std::vector<DomainStoreElement*>& pDomainStoreElementCol);
00169 
00173     void createGlobalDevice(GlobalDeviceElement& pGlobalDeviceElement);
00174 
00179     void configureFields(DataStore* dataStore, DataStoreElement* dataStoreElement);
00180 
00184     void initializeDevices(const std::vector<DeviceElement*>& pDeviceElementCol);
00185 
00189     void initializeDomainStores(const std::vector<DomainStoreElement*>& pDomainStoreElementCol);
00190 
00194     void initializeGlobalDevice(GlobalDeviceElement& pGlobalDeviceElement);
00195 
00199     std::string className_;
00200 };
00201 
00202 //******************************************************************
00203 
00204 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00205 DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::DeviceFactoryImp(const std::string& className) :
00206     pDeviceCol_(0), pDomainStoreCol_(0), pGlobalDevice_(0), className_(className)
00207 {
00208 }
00209 
00210 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00211 DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::~DeviceFactoryImp<GlobalDeviceType,
00212                                                                                     DomainStoreType, DevInstType>()
00213 {
00214     //delete all device-factory resources
00215     for (uint32_t i = 0; i < pDomainStoreCol_.size(); pDomainStoreCol_[i++])
00216     {
00217         delete pDomainStoreCol_[i];
00218     }
00219     for (uint32_t i = 0; i < pDeviceCol_.size(); pDeviceCol_[i++])
00220     {
00221         delete pDeviceCol_[i];
00222     }
00223 
00224     delete pGlobalDevice_;
00225 }
00226 
00227 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00228 void DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::initialize()
00229 {
00230 
00231 
00232     bool optional = AbstractEquipment::getInstance()->isClassOptional(className_);
00233 
00234     struct stat stFileInfo;
00235 
00236     std::string instanceFile = AbstractEquipment::getInstance()->getDeviceDataFileName();
00237 
00238     int32_t exists = stat(instanceFile.c_str(),&stFileInfo); // returns 0 if the file exists
00239 
00240     // file does not exist and not optional exception
00241     if (exists != 0 && !optional)
00242     {
00243         throw FesaFileException(__FILE__, __LINE__, FesaErrorOpenXMLFile.c_str(), instanceFile.c_str());
00244 
00245     }
00246     // does not exist but it is optional. return
00247     else if (exists != 0 && optional)
00248     {
00249         return;
00250     }
00251 
00252     InitializeDataStoreManager* manager = new InitializeDataStoreManager(className_);
00253 
00254     GlobalDeviceElement& pGlobalDeviceElement = manager->retrieveGlobalDeviceElement();
00255 
00256     const std::vector<DeviceElement*>& pDeviceElementCol = manager->retrieveDeviceElements();
00257 
00258     const std::vector<DomainStoreElement*>& pDomainStoreElementCol = manager->retrieveDomainStoreElements();
00259 
00260     // Instantiate Device, GlobalDevice and DomainStore concrete objects
00261     createDevices(pDeviceElementCol);
00262 
00263     createDomainStores(pDomainStoreElementCol);
00264 
00265     createGlobalDevice(pGlobalDeviceElement);
00266 
00267 
00268     std::vector<AbstractDevice*> tmpDevices(pDeviceCol_.begin(), pDeviceCol_.end());
00269     std::vector<DomainStore*> tmpDomains(pDomainStoreCol_.begin(), pDomainStoreCol_.end());
00270 
00271     std::string persistencyFile = AbstractEquipment::getInstance()->getPersistencyFileName(className_);
00272 
00273     // Allocate the related data store memory and map all fields inside
00274     if (setUpMemory() == true)
00275     {
00276         initializeGlobalDevice(pGlobalDeviceElement);
00277 
00278         if (pDeviceElementCol.size() > 0)
00279             initializeDevices(pDeviceElementCol);
00280 
00281         if (pDomainStoreElementCol.size() > 0)
00282             initializeDomainStores(pDomainStoreElementCol);
00283 
00284         exists = stat(persistencyFile.c_str(),&stFileInfo);
00285 
00286         if (exists == 0)//check, if file exists
00287         {
00288             StoreManager storeManager;//restore persistent field values
00289             storeManager.restore(*pGlobalDevice_, tmpDevices, tmpDomains, className_);
00290         }
00291 
00292         EquipmentData::getInstance()->initialize();
00293     }
00294 
00295 
00296     PersistencyUnit * pPersistencyUnit = new PersistencyUnit(*pGlobalDevice_, tmpDevices, tmpDomains,
00297                                                              persistencyFile);
00298 
00299     (PersistencyManager::getInstance())->registerPersistencyUnit(pPersistencyUnit);
00300 
00301     delete manager;
00302 }
00303 
00304 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00305 inline GlobalDeviceType* DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::getGlobalDevice()
00306 {
00307     return pGlobalDevice_;
00308 }
00309 
00310 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00311 inline DevInstType* DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::getDevice(const std::string& devName)
00312 {
00313     for (uint32_t i = 0; i < pDeviceCol_.size(); i++)
00314     {
00315         if (devName == pDeviceCol_[i]->name.get())
00316         {
00317             return pDeviceCol_[i];
00318         }
00319     }
00320     return NULL;
00321 }
00322 
00323 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00324 inline const std::vector<DevInstType *>& DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::getDeviceCollection()
00325 {
00326     return pDeviceCol_;
00327 }
00328 
00329 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00330 void DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::createDevices(
00331     const std::vector<DeviceElement*>& pDeviceElementCol)
00332 
00333 {
00334 
00335     // Instanciates the Devices .........................................
00336 
00337     for (uint32_t devIdx = 0; devIdx < pDeviceElementCol.size(); devIdx++)
00338     {
00339         // ... now the device (generated part) is instantiated with all the fields;
00340         // each field (during construction) registers itself in the related collection
00341         DevInstType* pDevice = new DevInstType();
00342 
00343         // create the fields
00344         this->configureFields(pDevice, pDeviceElementCol[devIdx]);
00345 
00346         pDeviceCol_.push_back(pDevice);
00347 
00348     } // for devices end
00349 
00350 }
00351 
00352 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00353 void DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::createGlobalDevice(
00354     GlobalDeviceElement& pGlobalDeviceElement)
00355 {
00356 
00357     //Instantiate the unique GlobalDevice instance ..........................
00358     pGlobalDevice_ = new GlobalDeviceType();
00359     this->configureFields(pGlobalDevice_, &pGlobalDeviceElement);
00360 
00361 }
00362 
00363 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00364 void DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::createDomainStores(
00365     const std::vector<DomainStoreElement*>& pDomainStoreElementCol)
00366 {
00367 
00368     //Instantiates the DomainStore instances if necessary ..................
00369 
00370     for (uint32_t devIdx = 0; devIdx < pDomainStoreElementCol.size(); devIdx++)
00371     {
00372         // ... now the domainStore (generated part) is instantiated with all the fields;
00373         // each field (during construction) registers itself in the vector created above
00374         DomainStoreType * pDomainStore = new DomainStoreType();
00375 
00376         this->configureFields(pDomainStore, pDomainStoreElementCol[devIdx]);
00377 
00378         pDomainStoreCol_.push_back(pDomainStore);
00379     } // for domainStore end
00380 }
00381 
00382 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00383 void DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::configureFields(DataStore* dataStore,
00384                                                                                        DataStoreElement* dataStoreElement)
00385 {
00386 
00387     // ... now we have to create and assign the appropriate MultiplexingManager to each field
00388     const std::vector<AbstractField*>& pFieldCol = dataStore->getFieldCollection();
00389 
00390     //Lab specific errors are caught in the main
00391     SynchronizationLabObjectFactory* labFactory = SynchronizationLabObjectFactory::getInstance();
00392 
00393     InitializeDataStoreManager manager(className_);
00394 
00395     AbstractMultiplexingManager* rolling = NULL;
00396 
00397     AbstractMultiplexingManager* multiplexingManager = NULL;
00398     AbstractMultiplexingManager* extendedMultiplexingManager = NULL;
00399 
00400 
00401     // check that the device is multiplexed
00402 
00403     if (dataStoreElement->isMultiplexed())
00404     {
00405 
00406         if (AbstractEquipment::getInstance()->getProcessType() == unsplit)
00407 
00408         {
00409             rolling = labFactory->createRollingMultiplexingManager(dataStoreElement->getTimingDomain(),
00410                                                                    dataStoreElement->getTimingCriterion(), manager.getRollingManagerDepth());
00411 
00412             multiplexingManager = labFactory->createMultiplexingManager(dataStoreElement->getTimingDomain(),
00413                                                                         dataStoreElement->getTimingCriterion());
00414 
00415         }
00416         else
00417         {
00418 
00419             rolling = labFactory->createRollingSharedMultiplexingManager(dataStoreElement->getTimingDomain(),
00420                                                                          dataStoreElement->getTimingCriterion(), manager.getRollingManagerDepth());
00421 
00422             multiplexingManager = labFactory->createSharedMultiplexingManager(dataStoreElement->getTimingDomain(),
00423                                                                               dataStoreElement->getTimingCriterion());
00424 
00425         }
00426 
00427     }
00428 
00429     for (uint32_t fieldIdx = 0; fieldIdx < pFieldCol.size(); fieldIdx++)
00430     {
00431 
00432         FieldElement* pFieldElement = dataStoreElement->getFieldElement(pFieldCol[fieldIdx]->getName());
00433 
00434         if (pFieldElement != NULL)
00435         {
00436 
00437             pFieldCol[fieldIdx]->initialize(*pFieldElement);
00438 
00439         }
00440 
00441         // if the device is not multiplexed then change the multiplexing value for the field
00442         if (!dataStoreElement->isMultiplexed())
00443         {
00444             pFieldCol[fieldIdx]->setMultiplexed(false);
00445 
00446         }
00447 
00448         // The device and the field are Multiplexed
00449         // So we have to associate the field with the right multiplexing manager
00450         // For this, build the complete multiplexing criterion (timingDomain + muxCriterion)
00451 
00452 
00453         if (pFieldCol[fieldIdx]->isMultiplexed())
00454         {
00455             if (pFieldCol[fieldIdx]->getType() == Acquisition)
00456             {
00457 
00458                 pFieldCol[fieldIdx]->setMultiplexingManager(rolling);
00459             }
00460             else
00461             {
00462 
00463                 pFieldCol[fieldIdx]->setMultiplexingManager(multiplexingManager);
00464 
00465             }
00466         }
00467         // field not multiplexed
00468         else
00469         {
00470             pFieldCol[fieldIdx]->setMultiplexingManager(NULL);
00471         }
00472 
00473         if (pFieldCol[fieldIdx]->isMultiMux())
00474         {
00475 
00476             DeviceElement* device = (DeviceElement*) dataStore;
00477 
00478             extendedMultiplexingManager
00479                 = SynchronizationLabObjectFactory::getInstance()->createExtendedMultiplexingManager(
00480                     pFieldCol[fieldIdx]->getMultiplexingManager(),
00481                     device->extraCriterionCol_);
00482 
00483             pFieldCol[fieldIdx]->setMultiplexingManager(extendedMultiplexingManager);
00484         }
00485 
00486     }
00487 
00488 }
00489 
00490 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00491 void DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::initializeGlobalDevice(
00492     GlobalDeviceElement& pGlobalDeviceElement)
00493 {
00494     pGlobalDevice_->initializeFromElement(pGlobalDeviceElement);
00495 
00496 }
00497 
00498 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00499 void DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::initializeDevices(
00500     const std::vector<DeviceElement*>& pDeviceElementCol)
00501 {
00502     if (pDeviceElementCol.size() != pDeviceCol_.size())
00503 
00504         throw FesaException(__FILE__, __LINE__, FesaErrorDeviceFactoryCheckingDeviceCollectionSize.c_str(),
00505                             StringUtilities::toString(static_cast<int32_t>(pDeviceElementCol.size())).c_str(), StringUtilities::toString(
00506                                     static_cast<int32_t>(pDeviceCol_.size())).c_str());
00507     else
00508 
00509         for (uint32_t iDevEl = 0; iDevEl < pDeviceElementCol.size(); iDevEl++)
00510         {
00511             pDeviceCol_[iDevEl]->initializeFromElement(*pDeviceElementCol[iDevEl]);
00512         }
00513 
00514 }
00515 
00516 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00517 void DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::initializeDomainStores(
00518     const std::vector<DomainStoreElement*>& pDomainStoreElementCol)
00519 {
00520 
00521     if (pDomainStoreElementCol.size() != pDomainStoreCol_.size())
00522     {
00523         throw FesaException(__FILE__, __LINE__,
00524                             FesaErrorDeviceFactoryCheckingDomainStoreCollectionSize.c_str(),
00525                             StringUtilities::toString(static_cast<int32_t>(pDomainStoreElementCol.size())).c_str(),
00526                             StringUtilities::toString(static_cast<int32_t>(pDomainStoreCol_.size())).c_str());
00527     }
00528     else
00529     {
00530 
00531         for (uint32_t iDomEl = 0; iDomEl < pDomainStoreElementCol.size(); iDomEl++)
00532         {
00533             pDomainStoreCol_[iDomEl]->initializeFromElement(*pDomainStoreElementCol[iDomEl]);
00534 
00535         }
00536 
00537     }
00538 
00539 }
00540 
00541 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00542 void DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::computeMemorySize()
00543 
00544 {
00545     muxManagersSize_ = AbstractMultiplexingManager::getMemorySizeToAllocate();
00546 
00547     // Compute the size of all Fields values for the GlobalDevice
00548     globalDeviceSize_ = pGlobalDevice_->getMemorySizeToAllocate();
00549 
00550     // Now compute the size of domainStore if any
00551     domainStoreSize_ = 0;
00552     for (uint32_t devIdx = 0; devIdx < this->pDomainStoreCol_.size(); devIdx++)
00553     {
00554         domainStoreSize_ += pDomainStoreCol_[devIdx]->getMemorySizeToAllocate();
00555     }
00556 
00557     // Now compute the size of devices
00558     devicesSize_ = 0;
00559     for (uint32_t devIdx = 0; devIdx < this->pDeviceCol_.size(); devIdx++)
00560     {
00561         devicesSize_ += pDeviceCol_[devIdx]->getMemorySizeToAllocate();
00562     }
00563 
00564     equimentDataSize_ = 0;
00565 
00566     EquipmentData * equipmentData = EquipmentData::getInstance();
00567     if (equipmentData->isInitialize_ == NULL)
00568     {
00569         equimentDataSize_ = equipmentData->getMemorySizeToAllocate();
00570 
00571     }
00572 
00573     // The result of the memory computation
00574     size_ = muxManagersSize_ + globalDeviceSize_ + domainStoreSize_ + devicesSize_ + equimentDataSize_;
00575 }
00576 
00577 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00578 void DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::mapFields(char* p, bool initializeFields)
00579 {
00580     char* pAddrMuxManagersSpace = p;
00581     char* pAddrGlobalDeviceSpace = pAddrMuxManagersSpace + muxManagersSize_;
00582     char* pAddrDomainStoreSpace = pAddrGlobalDeviceSpace + globalDeviceSize_;
00583     char* pAddrDeviceInstanceSpace = pAddrDomainStoreSpace + domainStoreSize_;
00584     char* pAddrEquipmentInstanceSpace = pAddrDeviceInstanceSpace + devicesSize_;
00585 
00586     AbstractMultiplexingManager::mapMemory(pAddrMuxManagersSpace);
00587 
00588     p = pAddrGlobalDeviceSpace;
00589     pGlobalDevice_->mapMemory(p, initializeFields);
00590 
00591     p = pAddrDomainStoreSpace;
00592     for (uint32_t devIdx = 0; devIdx < pDomainStoreCol_.size(); devIdx++)
00593     {
00594         pDomainStoreCol_[devIdx]->mapMemory(p, initializeFields);
00595         p += pDomainStoreCol_[devIdx]->getMemorySizeToAllocate();
00596     }
00597 
00598     p = pAddrDeviceInstanceSpace;
00599     for (uint32_t devIdx = 0; devIdx < pDeviceCol_.size(); devIdx++)
00600     {
00601         pDeviceCol_[devIdx]->mapMemory(p, initializeFields);
00602         p += pDeviceCol_[devIdx]->getMemorySizeToAllocate();
00603     }
00604 
00605     p = pAddrEquipmentInstanceSpace;
00606 
00607     EquipmentData * equipmentData = EquipmentData::getInstance();
00608     if (equipmentData->isInitialize_ == NULL)
00609     {
00610         equipmentData->mapMemory(p,initializeFields);
00611         *(equipmentData->isInitialize_) = true;
00612     }
00613 
00614 }
00615 
00616 template<typename GlobalDeviceType, typename DomainStoreType, typename DevInstType>
00617 void DeviceFactoryImp<GlobalDeviceType, DomainStoreType, DevInstType>::unmapFields()
00618 {
00619     // In theory this method should unmap all the fields; but as so far the only field  that is used
00620     // during the startup of the memory is the equipmentData.initialize; this method only unmap this field
00621     EquipmentData * equipmentData = EquipmentData::getInstance();
00622     equipmentData->isInitialize_ = NULL;
00623 }
00624 
00625 } // fesa
00626 
00627 #endif // DEVICE_FACTORY_IMP_H_

Generated on 18 Jan 2013 for Fesa by  doxygen 1.6.1