/* * 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 config.h #ifdef HAVE_CONFIG_H #include #endif // forward declarations class periodentafel; class MoleculeListClass; class atom; class molecule; class AtomDescriptor; class AtomDescriptor_impl; class MoleculeDescriptor; class MoleculeDescriptor_impl; class ManipulateAtomsProcess; template class AtomsCalculation; /****************************************** 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 std::map AtomSet; typedef std::map 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 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); /** * get the number of molecules in the World */ int numMolecules(); /** * get the domain size as a symmetric matrix (6 components) */ double * getDomain(); /** * set the domain size as a symmetric matrix (6 components) */ void setDomain(double * matrix); /** * get the default name */ char * getDefaultName(); /** * set the default name */ void setDefaultName(char * name); /***** 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); protected: /**** Iterators to use internal data structures */ // Atoms typedef SelectiveIterator AtomIterator; /** * returns an iterator over all Atoms matching a given descriptor. * used for internal purposes, like AtomProcesses and AtomCalculations. */ AtomIterator getAtomIter(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. */ AtomIterator atomEnd(); // Molecules typedef SelectiveIterator MoleculeIterator; /** * returns an iterator over all Molecules matching a given descriptor. * used for internal purposes, like MoleculeProcesses and MoleculeCalculations. */ MoleculeIterator getMoleculeIter(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. */ MoleculeIterator moleculeEnd(); /******* Internal manipulation routines for double callback and Observer mechanism ******/ void doManipulate(ManipulateAtomsProcess *); private: atomId_t getNextAtomId(); void releaseAtomId(atomId_t); bool reserveAtomId(atomId_t); periodentafel *periode; static double *cell_size; static char *defaultName; public: AtomSet atoms; private: std::set atomIdPool; //