source: molecuilder/src/World.cpp@ a5471c

Last change on this file since a5471c was a5471c, checked in by Tillmann Crueger <crueger@…>, 16 years ago

Added iterator structure that allows iterating over selected atoms in the World.

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 * World.cpp
3 *
4 * Created on: Feb 3, 2010
5 * Author: crueger
6 */
7
8#include "World.hpp"
9
10#include "atom.hpp"
11#include "molecule.hpp"
12#include "periodentafel.hpp"
13#include "Descriptors/AtomDescriptor.hpp"
14#include "Descriptors/AtomDescriptor_impl.hpp"
15
16using namespace std;
17
18/******************************* getter and setter ************************/
19periodentafel *&World::getPeriode(){
20 return periode;
21}
22
23atom* World::getAtom(AtomDescriptor descriptor){
24 return descriptor.find();
25}
26
27vector<atom*> World::getAllAtoms(AtomDescriptor descriptor){
28 return descriptor.findAll();
29}
30
31int World::numAtoms(){
32 return atoms.size();
33}
34
35int World::numMolecules(){
36 return molecules_deprecated->ListOfMolecules.size();
37}
38
39molecule* World::createMolecule(){
40 OBSERVE;
41 molecule *mol = NULL;
42 mol = new molecule(periode);
43 molecules_deprecated->insert(mol);
44 molecules.insert(mol);
45 mol->signOn(this);
46 return mol;
47}
48
49/******************************* Iterators ********************************/
50
51World::AtomIterator::AtomIterator(AtomDescriptor _descr, World* _world) :
52 descr(_descr.get_impl()),
53 world(_world)
54{
55 state = world->atoms.begin();
56 advanceState();
57}
58
59World::AtomIterator::AtomIterator(const AtomIterator& rhs) :
60 state(rhs.state),
61 descr(rhs.descr)
62 {}
63
64World::AtomIterator& World::AtomIterator::operator++(){
65 advanceState();
66}
67
68bool World::AtomIterator::operator==(const AtomIterator& rhs){
69 return state==rhs.state;
70}
71
72bool World::AtomIterator::operator!=(const AtomIterator& rhs){
73 return state!=rhs.state;
74}
75
76atom* World::AtomIterator::operator*(){
77 return (*state).second;
78}
79
80void World::AtomIterator::advanceState(){
81 while(state!=world->atoms.end() && !descr->predicate(*state))
82 state++;
83}
84
85World::AtomIterator World::getAtomIter(AtomDescriptor descr){
86 return AtomIterator(descr,this);
87}
88
89/******************************* Singleton Stuff **************************/
90
91// TODO: Hide boost-thread using Autotools stuff when no threads are used
92World* World::theWorld = 0;
93boost::mutex World::worldLock;
94
95
96
97World::World() :
98 dummyId(0),
99 periode(new periodentafel),
100 molecules_deprecated(new MoleculeListClass)
101{
102 molecules_deprecated->signOn(this);
103}
104
105World::~World()
106{
107 delete periode;
108}
109
110World* World::get(){
111 // boost supports RAII-Style locking, so we don't need to unlock
112 boost::mutex::scoped_lock guard(worldLock);
113 if(!theWorld) {
114 theWorld = new World();
115 }
116 return theWorld;
117}
118
119void World::destroy(){
120 // For legacy reasons all atoms have to be destroyed first, since unregistering would cause deadlocks otherwise
121 theWorld->destroyLegacy();
122 //WARNING: at this point we have a small race condition, when sombody now tries to access the world.
123
124 // boost supports RAII-Style locking, so we don't need to unlock
125 boost::mutex::scoped_lock guard(worldLock);
126 delete theWorld;
127 theWorld = 0;
128}
129
130World* World::reset(){
131 // For legacy reasons all atoms have to be destroyed first, since unregistering would cause deadlocks otherwise
132 theWorld->destroyLegacy();
133 //WARNING: at this point we have a small race condition, when sombody now tries to access the world.
134
135 World* oldWorld = 0;
136 {
137 // boost supports RAII-Style locking, so we don't need to unlock
138 boost::mutex::scoped_lock guard(worldLock);
139
140 oldWorld = theWorld;
141 theWorld = new World();
142 // oldworld does not need protection any more,
143 // since we should have the only reference
144
145 // worldLock handles access to the pointer,
146 // not to the object
147 } // scope-end releases the lock
148
149 // we have to let all the observers know that the
150 // oldWorld was destroyed. oldWorld calls subjectKilled
151 // upon destruction. Every Observer getting that signal
152 // should see that it gets the updated new world
153 delete oldWorld;
154}
155
156/******************************* deprecated Legacy Stuff ***********************/
157
158MoleculeListClass *&World::getMolecules() {
159 return molecules_deprecated;
160}
161
162// some legacy stuff to let the World know about items created outside
163void World::registerAtom(atom *theAtom){
164 OBSERVE;
165 atoms[dummyId++] = theAtom;
166}
167
168void World::destroyLegacy(){
169 //delete molecules_deprecated;
170}
171
172void World::unregisterAtom(atom *theAtom){
173 OBSERVE;
174 atoms.erase(theAtom->getId());
175}
Note: See TracBrowser for help on using the repository browser.