/* * World.cpp * * Created on: Feb 3, 2010 * Author: crueger */ #include "World.hpp" #include "atom.hpp" #include "molecule.hpp" #include "periodentafel.hpp" #include "Descriptors/AtomDescriptor.hpp" #include "Descriptors/AtomDescriptor_impl.hpp" #include "Descriptors/MoleculeDescriptor.hpp" #include "Descriptors/MoleculeDescriptor_impl.hpp" #include "Descriptors/SelectiveIterator_impl.hpp" #include "Actions/ManipulateAtomsProcess.hpp" #include "Patterns/Singleton_impl.hpp" using namespace std; /******************************* getter and setter ************************/ periodentafel *&World::getPeriode(){ return periode; } // Atoms atom* World::getAtom(AtomDescriptor descriptor){ return descriptor.find(); } vector World::getAllAtoms(AtomDescriptor descriptor){ return descriptor.findAll(); } vector World::getAllAtoms(){ return getAllAtoms(AllAtoms()); } int World::numAtoms(){ return atoms.size(); } // Molecules molecule *World::getMolecule(MoleculeDescriptor descriptor){ return descriptor.find(); } std::vector World::getAllMolecules(MoleculeDescriptor descriptor){ return descriptor.findAll(); } int World::numMolecules(){ return molecules_deprecated->ListOfMolecules.size(); } // system double * World::getDomain() { return cell_size; } void World::setDomain(double * matrix) { } char * World::getDefaultName() { return defaultName; } void World::setDefaultName(char * name) { delete[](defaultName); const int length = strlen(name); defaultName = new char[length+2]; if (length < MAXSTRINGSIZE) strncpy(defaultName, name, length); else strcpy(defaultName, "none"); }; /******************** Methods to change World state *********************/ molecule* World::createMolecule(){ OBSERVE; molecule *mol = NULL; mol = NewMolecule(); assert(!molecules.count(currMoleculeId)); mol->setId(currMoleculeId++); // store the molecule by ID molecules[mol->getId()] = mol; mol->signOn(this); return mol; } void World::destroyMolecule(molecule* mol){ OBSERVE; destroyMolecule(mol->getId()); } void World::destroyMolecule(moleculeId_t id){ OBSERVE; molecule *mol = molecules[id]; assert(mol); DeleteMolecule(mol); molecules.erase(id); } double *World::cell_size = NULL; char *World::defaultName = NULL; atom *World::createAtom(){ OBSERVE; atomId_t id = getNextAtomId(); atom *res = NewAtom(id); res->setWorld(this); // store the atom by ID atoms[res->getId()] = res; return res; } int World::registerAtom(atom *atom){ OBSERVE; atomId_t id = getNextAtomId(); atom->setId(id); atom->setWorld(this); atoms[atom->getId()] = atom; return atom->getId(); } void World::destroyAtom(atom* atom){ OBSERVE; int id = atom->getId(); destroyAtom(id); } void World::destroyAtom(atomId_t id) { OBSERVE; atom *atom = atoms[id]; assert(atom); DeleteAtom(atom); atoms.erase(id); releaseAtomId(id); } bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){ OBSERVE; // in case this call did not originate from inside the atom, we redirect it, // to also let it know that it has changed if(!target){ target = atoms[oldId]; assert(target && "Atom with that ID not found"); return target->changeId(newId); } else{ if(reserveAtomId(newId)){ atoms.erase(oldId); atoms.insert(pair(newId,target)); return true; } else{ return false; } } } ManipulateAtomsProcess* World::manipulateAtoms(boost::function op,std::string name,AtomDescriptor descr){ return new ManipulateAtomsProcess(op, descr,name,true); } ManipulateAtomsProcess* World::manipulateAtoms(boost::function op,std::string name){ return manipulateAtoms(op,name,AllAtoms()); } /********************* Internal Change methods for double Callback and Observer mechanism ********/ void World::doManipulate(ManipulateAtomsProcess *proc){ proc->signOn(this); { OBSERVE; proc->doManipulate(this); } proc->signOff(this); } /******************************* IDManagement *****************************/ // Atoms atomId_t World::getNextAtomId(){ // see if we can reuse some Id if(atomIdPool.empty()){ return currAtomId++; } else{ // we give out the first ID from the pool atomId_t id = *(atomIdPool.begin()); atomIdPool.erase(id); return id; } } void World::releaseAtomId(atomId_t id){ atomIdPool.insert(id); // defragmentation of the pool set::reverse_iterator iter; // go through all Ids in the pool that lie immediately below the border while(!atomIdPool.empty() && *(atomIdPool.rbegin())==(currAtomId-1)){ atomIdPool.erase(--currAtomId); } } bool World::reserveAtomId(atomId_t id){ if(id>=currAtomId ){ // add all ids between the new one and current border as available for(atomId_t pos=currAtomId; possignOn(this); } World::~World() { molecules_deprecated->signOff(this); delete[] cell_size; delete[] defaultName; delete molecules_deprecated; delete periode; MoleculeSet::iterator molIter; for(molIter=molecules.begin();molIter!=molecules.end();++molIter){ DeleteMolecule((*molIter).second); } molecules.clear(); AtomSet::iterator atIter; for(atIter=atoms.begin();atIter!=atoms.end();++atIter){ DeleteAtom((*atIter).second); } atoms.clear(); } // Explicit instantiation of the singleton mechanism at this point CONSTRUCT_SINGLETON(World) /******************************* deprecated Legacy Stuff ***********************/ MoleculeListClass *&World::getMolecules() { return molecules_deprecated; }