/* * World.hpp * * Created on: Feb 3, 2010 * Author: crueger */ #ifndef WORLD_HPP_ #define WORLD_HPP_ #include #include #include #include #include #include #include "Patterns/Observer.hpp" #include "Patterns/Cacheable.hpp" // forward declarations class periodentafel; class MoleculeListClass; class atom; class molecule; class AtomDescriptor; class AtomDescriptor_impl; class ManipulateAtomsProcess; class World : public Observable { friend class AtomDescriptor_impl; friend class AtomDescriptor; friend class ManipulateAtomsProcess; typedef std::map AtomList; public: /***** getter and setter *****/ // reference to pointer is used for legacy reason... reference will be removed latter to keep encapsulation of World object periodentafel *&getPeriode(); atom* getAtom(AtomDescriptor descriptor); std::vector getAllAtoms(AtomDescriptor descriptor); int numAtoms(); int numMolecules(); /***** Methods to work with the World *****/ molecule *createMolecule(); ManipulateAtomsProcess* manipulateAtoms(boost::function,std::string,AtomDescriptor); protected: /**** Iterators to use internal data structures */ class AtomIterator { public: AtomIterator(); AtomIterator(AtomDescriptor, World*); AtomIterator(const AtomIterator&); AtomIterator& operator=(const AtomIterator&); AtomIterator& operator++(); // prefix AtomIterator operator++(int); // postfix with dummy parameter bool operator==(const AtomIterator&); bool operator==(const AtomList::iterator&); bool operator!=(const AtomIterator&); bool operator!=(const AtomList::iterator&); atom* operator*(); int getCount(); protected: void advanceState(); World* world; AtomList::iterator state; boost::shared_ptr descr; int index; }; AtomIterator getAtomIter(AtomDescriptor descr); AtomList::iterator atomEnd(); /******* Internal manipulation routines for double callback and Observer mechanism ******/ void doManipulate(ManipulateAtomsProcess *); private: periodentafel *periode; AtomList atoms; std::set molecules; /***** singleton Stuff *****/ public: static World* get(); static void destroy(); static World* reset(); private: World(); virtual ~World(); static World *theWorld; // this mutex only saves the singleton pattern... // use other mutexes to protect internal data as well // this mutex handles access to the pointer, not to the object!!! static boost::mutex worldLock; /***** * some legacy stuff that is include for now but will be removed later *****/ public: MoleculeListClass *&getMolecules(); // functions used for the WorldContent template mechanism void registerAtom(atom *theAtom); void unregisterAtom(atom *theAtom); private: // this function cleans up anything that cannot be cleaned while the lock is active // at a later point all these cleanups have to be moved to the World Class so the deadlock and // race condition can both be avoided. void destroyLegacy(); MoleculeListClass *molecules_deprecated; // this is needed to assign unique IDs to atoms... so far // IDs are not assigned upon Atom creation, so we cannot query the ID // during construction. By using the dummy ID we can make sure all atoms // are actually stored in the map and don't overwrite each other. int dummyId; }; #endif /* WORLD_HPP_ */