/* * 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 "Actions/ManipulateAtomsProcess.hpp" using namespace std; /******************************* getter and setter ************************/ periodentafel *&World::getPeriode(){ return periode; } 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(); } int World::numMolecules(){ return molecules_deprecated->ListOfMolecules.size(); } /******************** 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); } atom *World::createAtom(){ OBSERVE; atom *res = NewAtom(); assert(!atoms.count(currAtomId)); res->setId(currAtomId++); res->setWorld(this); // store the atom by ID atoms[res->getId()] = res; return res; } int World::registerAtom(atom *atom){ OBSERVE; assert(!atoms.count(currAtomId)); atom->setId(currAtomId++); 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); } 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); } /******************************* Iterators ********************************/ /* * Actual Implementation of the iterators can be found in WorldIterators.cpp */ World::AtomIterator World::getAtomIter(AtomDescriptor descr){ return AtomIterator(descr,this); } World::AtomSet::iterator World::atomEnd(){ return atoms.end(); } /******************************* Singleton Stuff **************************/ // TODO: Hide boost-thread using Autotools stuff when no threads are used World* World::theWorld = 0; boost::mutex World::worldLock; World::World() : currAtomId(0), currMoleculeId(0), periode(new periodentafel), molecules_deprecated(new MoleculeListClass(this)), atoms(), molecules() { molecules_deprecated->signOn(this); } World::~World() { 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(); } World* World::get(){ // boost supports RAII-Style locking, so we don't need to unlock boost::mutex::scoped_lock guard(worldLock); if(!theWorld) { theWorld = new World(); } return theWorld; } void World::destroy(){ // boost supports RAII-Style locking, so we don't need to unlock boost::mutex::scoped_lock guard(worldLock); delete theWorld; theWorld = 0; } World* World::reset(){ World* oldWorld = 0; { // boost supports RAII-Style locking, so we don't need to unlock boost::mutex::scoped_lock guard(worldLock); oldWorld = theWorld; theWorld = new World(); // oldworld does not need protection any more, // since we should have the only reference // worldLock handles access to the pointer, // not to the object } // scope-end releases the lock // we have to let all the observers know that the // oldWorld was destroyed. oldWorld calls subjectKilled // upon destruction. Every Observer getting that signal // should see that it gets the updated new world delete oldWorld; } /******************************* deprecated Legacy Stuff ***********************/ MoleculeListClass *&World::getMolecules() { return molecules_deprecated; }