/* ----------------------------------------------------------------------- Copyright: 2010-2021, imec Vision Lab, University of Antwerp 2014-2021, CWI, Amsterdam Contact: astra@astra-toolbox.com Website: http://www.astra-toolbox.com/ This file is part of the ASTRA Toolbox. The ASTRA Toolbox is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The ASTRA Toolbox is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with the ASTRA Toolbox. If not, see . ----------------------------------------------------------------------- */ #ifndef _INC_ASTRA_ASTRAOBJECTMANAGER #define _INC_ASTRA_ASTRAOBJECTMANAGER #include #include #include "Globals.h" #include "Singleton.h" #include "Projector2D.h" #include "Projector3D.h" #include "Float32Data2D.h" #include "Float32Data3D.h" #include "SparseMatrix.h" #include "Algorithm.h" namespace astra { /** * This class contains functionality to store objects. A unique index handle * will be assigned to each data object by which it can be accessed in the * future. Indices are always >= 1. * * We store them in a special common base class to make indices unique * among all ObjectManagers. */ class CAstraObjectManagerBase { public: virtual std::string getInfo(int index) const =0; virtual void remove(int index) =0; virtual std::string getType() const =0; }; class _AstraExport CAstraIndexManager : public Singleton { public: CAstraIndexManager() : m_iLastIndex(0) { } int store(CAstraObjectManagerBase* m) { m_table[++m_iLastIndex] = m; return m_iLastIndex; } CAstraObjectManagerBase* get(int index) const { std::map::const_iterator i; i = m_table.find(index); if (i != m_table.end()) return i->second; else return 0; } void remove(int index) { std::map::iterator i; i = m_table.find(index); if (i != m_table.end()) m_table.erase(i); } private: /** The index last handed out */ int m_iLastIndex; std::map m_table; }; template class CAstraObjectManager : public CAstraObjectManagerBase { public: /** Default constructor. */ CAstraObjectManager(); /** Destructor. */ ~CAstraObjectManager(); /** Store the object in the manager and assign a unique index handle to it. * * @param _pObject A pointer to the object that should be stored. * @return The index of the stored data object. If the index in negative, an error occurred * and the object was NOT stored. */ int store(T* _pObject); /** Does the manager contain an object with the index _iIndex? * * @param _iIndex Index handle to the data object in question. * @return True if the manager contains an object with the index handle _iIndex. */ bool hasIndex(int _iIndex) const; /** Fetch the object to which _iIndex refers to. * * @param _iIndex Index handle to the data object in question. * @return Pointer to the stored data object. A null pointer is returned if no object with index _iIndex is found. */ T* get(int _iIndex) const; /** Delete an object that was previously stored. This actually DELETES the objecy. Therefore, after this * function call, the object in question will have passed on. It will be no more. It will have ceased * to be. It will be expired and will go to meet its maker. Bereft of life, it will rest in peace. * It will be an EX-OBJECT. * * @param _iIndex Index handle to the object in question. * @return Error code. 0 for success. */ void remove(int _iIndex); /** Get the index of the object, zero if it doesn't exist. * * @param _pObject The data object. * @return Index of the stored object, 0 if not found. */ int getIndex(const T* _pObject) const; /** Clear all data. This will also delete all the content of each object. */ void clear(); /** Get info of object. */ std::string getInfo(int index) const; /** Get list with info of all managed objects. */ std::string info(); protected: /** Map each data object to a unique index. */ std::map m_mIndexToObject; }; //---------------------------------------------------------------------------------------- // Constructor template CAstraObjectManager::CAstraObjectManager() { } //---------------------------------------------------------------------------------------- // Destructor template CAstraObjectManager::~CAstraObjectManager() { } //---------------------------------------------------------------------------------------- // store data template int CAstraObjectManager::store(T* _pDataObject) { int iIndex = CAstraIndexManager::getSingleton().store(this); m_mIndexToObject[iIndex] = _pDataObject; return iIndex; } //---------------------------------------------------------------------------------------- // has data? template bool CAstraObjectManager::hasIndex(int _iIndex) const { typename std::map::const_iterator it = m_mIndexToObject.find(_iIndex); return it != m_mIndexToObject.end(); } //---------------------------------------------------------------------------------------- // get data template T* CAstraObjectManager::get(int _iIndex) const { typename std::map::const_iterator it = m_mIndexToObject.find(_iIndex); if (it != m_mIndexToObject.end()) return it->second; else return 0; } //---------------------------------------------------------------------------------------- // delete data template void CAstraObjectManager::remove(int _iIndex) { // find data typename std::map::iterator it = m_mIndexToObject.find(_iIndex); if (it == m_mIndexToObject.end()) return; // delete data delete (*it).second; // delete from map m_mIndexToObject.erase(it); CAstraIndexManager::getSingleton().remove(_iIndex); } //---------------------------------------------------------------------------------------- // Get Index template int CAstraObjectManager::getIndex(const T* _pObject) const { for (typename std::map::const_iterator it = m_mIndexToObject.begin(); it != m_mIndexToObject.end(); it++) { if ((*it).second == _pObject) return (*it).first; } return 0; } //---------------------------------------------------------------------------------------- // clear template void CAstraObjectManager::clear() { for (typename std::map::iterator it = m_mIndexToObject.begin(); it != m_mIndexToObject.end(); it++) { // delete data delete (*it).second; (*it).second = 0; } m_mIndexToObject.clear(); } //---------------------------------------------------------------------------------------- // Print info to string template std::string CAstraObjectManager::getInfo(int index) const { typename std::map::const_iterator it = m_mIndexToObject.find(index); if (it == m_mIndexToObject.end()) return ""; const T* pObject = it->second; std::stringstream res; res << index << " \t"; if (pObject->isInitialized()) { res << "v "; } else { res << "x "; } res << pObject->description(); return res.str(); } template std::string CAstraObjectManager::info() { std::stringstream res; res << "id init description" << std::endl; res << "-----------------------------------------" << std::endl; for (typename std::map::const_iterator it = m_mIndexToObject.begin(); it != m_mIndexToObject.end(); it++) { res << getInfo(it->first) << std::endl; } res << "-----------------------------------------" << std::endl; return res.str(); } //---------------------------------------------------------------------------------------- // Create the necessary Object Managers /** * This class contains functionality to store 2D projector objects. A unique index handle will be * assigned to each data object by which it can be accessed in the future. * Indices are always >= 1. */ class _AstraExport CProjector2DManager : public Singleton, public CAstraObjectManager { virtual std::string getType() const { return "projector2d"; } }; /** * This class contains functionality to store 3D projector objects. A unique index handle will be * assigned to each data object by which it can be accessed in the future. * Indices are always >= 1. */ class _AstraExport CProjector3DManager : public Singleton, public CAstraObjectManager { virtual std::string getType() const { return "projector3d"; } }; /** * This class contains functionality to store 2D data objects. A unique index handle will be * assigned to each data object by which it can be accessed in the future. * Indices are always >= 1. */ class _AstraExport CData2DManager : public Singleton, public CAstraObjectManager { virtual std::string getType() const { return "data2d"; } }; /** * This class contains functionality to store 3D data objects. A unique index handle will be * assigned to each data object by which it can be accessed in the future. * Indices are always >= 1. */ class _AstraExport CData3DManager : public Singleton, public CAstraObjectManager { virtual std::string getType() const { return "data3d"; } }; /** * This class contains functionality to store algorithm objects. A unique index handle will be * assigned to each data object by which it can be accessed in the future. * Indices are always >= 1. */ class _AstraExport CAlgorithmManager : public Singleton, public CAstraObjectManager { virtual std::string getType() const { return "algorithm"; } }; /** * This class contains functionality to store matrix objects. A unique index handle will be * assigned to each data object by which it can be accessed in the future. * Indices are always >= 1. */ class _AstraExport CMatrixManager : public Singleton, public CAstraObjectManager { virtual std::string getType() const { return "matrix"; } }; } // end namespace #endif