/* * 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(); } 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 = new molecule(periode); molecules_deprecated->insert(mol); molecules.insert(mol); mol->signOn(this); return mol; } atom *World::createAtom(){ OBSERVE; atom *res = NewAtom(); res->setId(currAtomId++); res->setWorld(this); atoms[res->getId()] = res; return res; } int World::registerAtom(atom *atom){ OBSERVE; 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(int 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); } /********************* 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 ********************************/ World::AtomIterator::AtomIterator(){ state = World::get()->atomEnd(); } World::AtomIterator::AtomIterator(AtomDescriptor _descr, World* _world) : descr(_descr.get_impl()), world(_world), index(0) { state = world->atoms.begin(); advanceState(); } World::AtomIterator::AtomIterator(const AtomIterator& rhs) : state(rhs.state), descr(rhs.descr), index(rhs.index), world(rhs.world) {} World::AtomIterator& World::AtomIterator::operator=(const AtomIterator& rhs) { if(&rhs!=this){ state=rhs.state; descr=rhs.descr; index=rhs.index; world=rhs.world; } return *this; } World::AtomIterator& World::AtomIterator::operator++(){ ++state; ++index; advanceState(); return *this; } World::AtomIterator World::AtomIterator::operator++(int){ AtomIterator res(*this); ++(*this); return res; } bool World::AtomIterator::operator==(const AtomIterator& rhs){ return state==rhs.state; } bool World::AtomIterator::operator==(const World::AtomList::iterator& rhs){ return state==rhs; } bool World::AtomIterator::operator!=(const AtomIterator& rhs){ return state!=rhs.state; } bool World::AtomIterator::operator!=(const World::AtomList::iterator& rhs){ return state!=rhs; } atom* World::AtomIterator::operator*(){ return (*state).second; } void World::AtomIterator::advanceState(){ while((state!=world->atoms.end()) && (!descr->predicate(*state))){ ++state; ++index; } } int World::AtomIterator::getCount(){ return index; } World::AtomIterator World::getAtomIter(AtomDescriptor descr){ return AtomIterator(descr,this); } World::AtomList::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), periode(new periodentafel), molecules_deprecated(new MoleculeListClass), atoms() { molecules_deprecated->signOn(this); } World::~World() { delete molecules_deprecated; delete periode; AtomList::iterator iter; for(iter=atoms.begin();iter!=atoms.end();++iter){ DeleteAtom((*iter).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; }