/* * World.hpp * * Created on: Feb 3, 2010 * Author: crueger */ #ifndef WORLD_HPP_ #define WORLD_HPP_ /*********************************************** includes ***********************************/ #include #include #include #include #include #include #include "types.hpp" #include "Descriptors/SelectiveIterator.hpp" #include "Patterns/Observer.hpp" #include "Patterns/Cacheable.hpp" #include "Patterns/Singleton.hpp" #include "Patterns/ObservedContainer.hpp" // include config.h #ifdef HAVE_CONFIG_H #include #endif // forward declarations class atom; class AtomDescriptor; class AtomDescriptor_impl; template class AtomsCalculation; class Box; class config; class ManipulateAtomsProcess; class Matrix; class molecule; class MoleculeDescriptor; class MoleculeDescriptor_impl; class MoleculeListClass; class periodentafel; class ThermoStatContainer; /****************************************** forward declarations *****************************/ /********************************************** Class World *******************************/ class World : public Singleton, public Observable { // Make access to constructor and destructor possible from inside the singleton friend class Singleton; // necessary for coupling with descriptors friend class AtomDescriptor_impl; friend class AtomDescriptor; friend class MoleculeDescriptor_impl; friend class MoleculeDescriptor; // Actions, calculations etc associated with the World friend class ManipulateAtomsProcess; template friend class AtomsCalculation; public: // Types for Atom and Molecule structures typedef ObservedContainer > AtomSet; typedef ObservedContainer > MoleculeSet; /***** getter and setter *****/ // reference to pointer is used for legacy reason... reference will be removed latter to keep encapsulation of World object /** * returns the periodentafel for the world. */ periodentafel *&getPeriode(); /** * returns the configuration for the world. */ config *&getConfig(); /** * returns the first atom that matches a given descriptor. * Do not rely on ordering for descriptors that match more than one atom. */ atom* getAtom(AtomDescriptor descriptor); /** * returns a vector containing all atoms that match a given descriptor */ std::vector getAllAtoms(AtomDescriptor descriptor); std::vector getAllAtoms(); /** * returns a calculation that calls a given function on all atoms matching a descriptor. * the calculation is not called at this point and can be used as an action, i.e. be stored in * menus, be kept around for later use etc. */ template AtomsCalculation* calcOnAtoms(boost::function,std::string,AtomDescriptor); template AtomsCalculation* calcOnAtoms(boost::function,std::string); /** * get the number of atoms in the World */ int numAtoms(); /** * returns the first molecule that matches a given descriptor. * Do not rely on ordering for descriptors that match more than one molecule. */ molecule *getMolecule(MoleculeDescriptor descriptor); /** * returns a vector containing all molecules that match a given descriptor */ std::vector getAllMolecules(MoleculeDescriptor descriptor); std::vector getAllMolecules(); /** * get the number of molecules in the World */ int numMolecules(); /** * get the domain size as a symmetric matrix (6 components) */ Box& getDomain(); /** * Set the domain size from a matrix object * * Matrix needs to be symmetric */ void setDomain(const Matrix &mat); /** * set the domain size as a symmetric matrix (6 components) */ void setDomain(double * matrix); /** * get the default name */ std::string getDefaultName(); /** * set the default name */ void setDefaultName(std::string name); /** * get pointer to World's ThermoStatContainer */ ThermoStatContainer * getThermostats(); /* * get the ExitFlag */ int getExitFlag(); /* * set the ExitFlag */ void setExitFlag(int flag); /***** Methods to work with the World *****/ /** * create a new molecule. This method should be used whenever any kind of molecule is needed. Assigns a unique * ID to the molecule and stores it in the World for later retrieval. Do not create molecules directly. */ molecule *createMolecule(); void destroyMolecule(molecule*); void destroyMolecule(moleculeId_t); /** * Create a new atom. This method should be used whenever any atom is needed. Assigns a unique ID and stores * the atom in the World. If the atom is not destroyed it will automatically be destroyed when the world ends. */ atom *createAtom(); /** * Registers a Atom unknown to world. Needed in some rare cases, e.g. when cloning atoms, or in some unittests. * Do not re-register Atoms already known to the world since this will cause double-frees. */ int registerAtom(atom*); /** * Delete some atom and erase it from the world. Use this whenever you need to destroy any atom. Do not call delete on * atom directly since this will leave the pointer inside the world. */ void destroyAtom(atom*); /** * Delete some atom and erase it from the world. Use this whenever you need to destroy any atom. Do not call delete on * atom directly since this will leave the pointer inside the world. */ void destroyAtom(atomId_t); /** * used when changing an atom Id. * Unless you are calling this method from inside an atom don't fiddle with the third parameter. * * Return value indicates wether the change could be done or not. */ bool changeAtomId(atomId_t oldId, atomId_t newId, atom* target=0); /** * Produces a process that calls a function on all Atoms matching a given descriptor. The process is not * called at this time, so it can be passed around, stored inside menuItems etc. */ ManipulateAtomsProcess* manipulateAtoms(boost::function,std::string,AtomDescriptor); ManipulateAtomsProcess* manipulateAtoms(boost::function,std::string); /**** * Iterators to use internal data structures * All these iterators are observed to track changes. * There is a corresponding protected section with unobserved iterators, * which ca be used internally when the extra speed is needed */ typedef SelectiveIterator AtomIterator; /** * returns an iterator over all Atoms matching a given descriptor. * This iterator is observed, so don't keep it around unnecessary to * avoid unintended blocking. */ AtomIterator getAtomIter(AtomDescriptor descr); AtomIterator getAtomIter(); AtomIterator atomEnd(); typedef SelectiveIterator MoleculeIterator; protected: /**** * Iterators to use internal data structures * All these iterators are unobserved for speed reasons. * There is a corresponding public section to these methods, * which produce observed iterators.*/ // Atoms typedef SelectiveIterator internal_AtomIterator; /** * returns an iterator over all Atoms matching a given descriptor. * used for internal purposes, like AtomProcesses and AtomCalculations. */ internal_AtomIterator getAtomIter_internal(AtomDescriptor descr); /** * returns an iterator to the end of the AtomSet. Due to overloading this iterator * can be compared to iterators produced by getAtomIter (see the mis-matching types). * Thus it can be used to detect when such an iterator is at the end of the list. * used for internal purposes, like AtomProcesses and AtomCalculations. */ internal_AtomIterator atomEnd_internal(); // Molecules typedef SelectiveIterator internal_MoleculeIterator; /** * returns an iterator over all Molecules matching a given descriptor. * used for internal purposes, like MoleculeProcesses and MoleculeCalculations. */ internal_MoleculeIterator getMoleculeIter_internal(MoleculeDescriptor descr); /** * returns an iterator to the end of the MoleculeSet. Due to overloading this iterator * can be compared to iterators produced by getMoleculeIter (see the mis-matching types). * Thus it can be used to detect when such an iterator is at the end of the list. * used for internal purposes, like MoleculeProcesses and MoleculeCalculations. */ internal_MoleculeIterator moleculeEnd_internal(); /******* Internal manipulation routines for double callback and Observer mechanism ******/ void doManipulate(ManipulateAtomsProcess *); private: atomId_t getNextAtomId(); void releaseAtomId(atomId_t); bool reserveAtomId(atomId_t); void defragAtomIdPool(); moleculeId_t getNextMoleculeId(); void releaseMoleculeId(moleculeId_t); bool reserveMoleculeId(moleculeId_t); void defragMoleculeIdPool(); periodentafel *periode; config *configuration; Box *cell_size; std::string defaultName; class ThermoStatContainer *Thermostats; int ExitFlag; public: AtomSet atoms; private: typedef std::set > atomIdPool_t; /** * stores the pool for all available AtomIds below currAtomId * * The pool contains ranges of free ids in the form [bottom,top). */ atomIdPool_t atomIdPool; atomId_t currAtomId; //!< stores the next available Id for atoms size_t lastAtomPoolSize; //!< size of the pool after last defrag, to skip some defrags unsigned int numAtomDefragSkips; MoleculeSet molecules; typedef std::set > moleculeIdPool_t; moleculeIdPool_t moleculeIdPool; moleculeId_t currMoleculeId; size_t lastMoleculePoolSize; //!< size of the pool after last defrag, to skip some defrags unsigned int numMoleculeDefragSkips; private: /** * private constructor to ensure creation of the world using * the singleton pattern. */ World(); /** * private destructor to ensure destruction of the world using the * singleton pattern. */ virtual ~World(); /***** * some legacy stuff that is include for now but will be removed later *****/ public: MoleculeListClass *&getMolecules(); private: MoleculeListClass *molecules_deprecated; }; #endif /* WORLD_HPP_ */