/* * 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(); } molecule* World::createMolecule(){ OBSERVE; molecule *mol = NULL; mol = new molecule(periode); molecules_deprecated->insert(mol); molecules.insert(mol); mol->signOn(this); return mol; } ManipulateAtomsProcess* World::manipulateAtoms(boost::function op,std::string name,AtomDescriptor descr){ return new ManipulateAtomsProcess(op, descr,name,true); } /******************************* 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() : dummyId(0), periode(new periodentafel), molecules_deprecated(new MoleculeListClass), atoms() { molecules_deprecated->signOn(this); } World::~World() { delete periode; } 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(){ // For legacy reasons all atoms have to be destroyed first, since unregistering would cause deadlocks otherwise theWorld->destroyLegacy(); //WARNING: at this point we have a small race condition, when sombody now tries to access the world. // 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(){ // For legacy reasons all atoms have to be destroyed first, since unregistering would cause deadlocks otherwise theWorld->destroyLegacy(); //WARNING: at this point we have a small race condition, when sombody now tries to access the world. 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; } // some legacy stuff to let the World know about items created outside void World::registerAtom(atom *theAtom){ OBSERVE; atoms[dummyId++] = theAtom; } void World::destroyLegacy(){ //delete molecules_deprecated; } void World::unregisterAtom(atom *theAtom){ OBSERVE; atoms.erase(theAtom->getId()); }