Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/World.cpp

    r6e97e5 r70378e  
    11/*
    2  * World.cpp
     2 * world.cpp
    33 *
    4  *  Created on: Feb 3, 2010
     4 *  Created on: Mar 3, 2010
    55 *      Author: crueger
    66 */
     
    88#include "World.hpp"
    99
    10 #include "atom.hpp"
    11 #include "molecule.hpp"
    12 #include "periodentafel.hpp"
    13 #include "Descriptors/AtomDescriptor.hpp"
    14 #include "Descriptors/AtomDescriptor_impl.hpp"
    15 #include "Descriptors/MoleculeDescriptor.hpp"
    16 #include "Descriptors/MoleculeDescriptor_impl.hpp"
    17 #include "Descriptors/SelectiveIterator_impl.hpp"
    18 #include "Actions/ManipulateAtomsProcess.hpp"
     10double *World::cell_size = 0;
    1911
    20 #include "Patterns/Singleton_impl.hpp"
     12/** Constructor of World.
     13 *
     14 */
     15World::World()
     16{
     17  cell_size = new double[6];
     18};
    2119
    22 using namespace std;
     20/** Destructor of World.
     21 *
     22 */
     23World::~World()
     24{
     25  delete[](cell_size);
     26};
    2327
    24 /******************************* getter and setter ************************/
    25 periodentafel *&World::getPeriode(){
    26   return periode;
     28
     29// TODO: Hide boost-thread using Autotools stuff when no threads are used
     30World* World::theWorld = 0;
     31
     32
     33World* World::get(){
     34  // boost supports RAII-Style locking, so we don't need to unlock
     35  if(!theWorld) {
     36    theWorld = new World();
     37  }
     38  return theWorld;
    2739}
    2840
    29 // Atoms
    30 
    31 atom* World::getAtom(AtomDescriptor descriptor){
    32   return descriptor.find();
     41void World::destroy(){
     42  delete theWorld;
     43  theWorld = 0;
    3344}
    3445
    35 vector<atom*> World::getAllAtoms(AtomDescriptor descriptor){
    36   return descriptor.findAll();
     46World* World::reset(){
     47  World* oldWorld = 0;
     48  {
     49    oldWorld = theWorld;
     50    theWorld = new World();
     51    // oldworld does not need protection any more,
     52    // since we should have the only reference
     53
     54    // worldLock handles access to the pointer,
     55    // not to the object
     56  } // scope-end releases the lock
     57
     58  // we have to let all the observers know that the
     59  // oldWorld was destroyed. oldWorld calls subjectKilled
     60  // upon destruction. Every Observer getting that signal
     61  // should see that it gets the updated new world
     62  delete oldWorld;
    3763}
    38 
    39 vector<atom*> World::getAllAtoms(){
    40   return getAllAtoms(AllAtoms());
    41 }
    42 
    43 int World::numAtoms(){
    44   return atoms.size();
    45 }
    46 
    47 // Molecules
    48 
    49 molecule *World::getMolecule(MoleculeDescriptor descriptor){
    50   return descriptor.find();
    51 }
    52 
    53 std::vector<molecule*> World::getAllMolecules(MoleculeDescriptor descriptor){
    54   return descriptor.findAll();
    55 }
    56 
    57 int World::numMolecules(){
    58   return molecules_deprecated->ListOfMolecules.size();
    59 }
    60 
    61 /******************** Methods to change World state *********************/
    62 
    63 molecule* World::createMolecule(){
    64   OBSERVE;
    65   molecule *mol = NULL;
    66   mol = NewMolecule();
    67   assert(!molecules.count(currMoleculeId));
    68   mol->setId(currMoleculeId++);
    69   // store the molecule by ID
    70   molecules[mol->getId()] = mol;
    71   mol->signOn(this);
    72   return mol;
    73 }
    74 
    75 void World::destroyMolecule(molecule* mol){
    76   OBSERVE;
    77   destroyMolecule(mol->getId());
    78 }
    79 
    80 void World::destroyMolecule(moleculeId_t id){
    81   OBSERVE;
    82   molecule *mol = molecules[id];
    83   assert(mol);
    84   DeleteMolecule(mol);
    85   molecules.erase(id);
    86 }
    87 
    88 
    89 atom *World::createAtom(){
    90   OBSERVE;
    91   atomId_t id = getNextAtomId();
    92   atom *res = NewAtom(id);
    93   res->setWorld(this);
    94   // store the atom by ID
    95   atoms[res->getId()] = res;
    96   return res;
    97 }
    98 
    99 int World::registerAtom(atom *atom){
    100   OBSERVE;
    101   atomId_t id = getNextAtomId();
    102   atom->setId(id);
    103   atom->setWorld(this);
    104   atoms[atom->getId()] = atom;
    105   return atom->getId();
    106 }
    107 
    108 void World::destroyAtom(atom* atom){
    109   OBSERVE;
    110   int id = atom->getId();
    111   destroyAtom(id);
    112 }
    113 
    114 void World::destroyAtom(atomId_t id) {
    115   OBSERVE;
    116   atom *atom = atoms[id];
    117   assert(atom);
    118   DeleteAtom(atom);
    119   atoms.erase(id);
    120   releaseAtomId(id);
    121 }
    122 
    123 bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
    124   OBSERVE;
    125   // in case this call did not originate from inside the atom, we redirect it,
    126   // to also let it know that it has changed
    127   if(!target){
    128     target = atoms[oldId];
    129     assert(target && "Atom with that ID not found");
    130     return target->changeId(newId);
    131   }
    132   else{
    133     if(reserveAtomId(newId)){
    134       atoms.erase(oldId);
    135       atoms.insert(pair<atomId_t,atom*>(newId,target));
    136       return true;
    137     }
    138     else{
    139       return false;
    140     }
    141   }
    142 }
    143 
    144 ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
    145   return new ManipulateAtomsProcess(op, descr,name,true);
    146 }
    147 
    148 ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
    149   return manipulateAtoms(op,name,AllAtoms());
    150 }
    151 
    152 /********************* Internal Change methods for double Callback and Observer mechanism ********/
    153 
    154 void World::doManipulate(ManipulateAtomsProcess *proc){
    155   proc->signOn(this);
    156   {
    157     OBSERVE;
    158     proc->doManipulate(this);
    159   }
    160   proc->signOff(this);
    161 }
    162 /******************************* IDManagement *****************************/
    163 
    164 // Atoms
    165 
    166 atomId_t World::getNextAtomId(){
    167   // see if we can reuse some Id
    168   if(atomIdPool.empty()){
    169     return currAtomId++;
    170   }
    171   else{
    172     // we give out the first ID from the pool
    173     atomId_t id = *(atomIdPool.begin());
    174     atomIdPool.erase(id);
    175     return id;
    176   }
    177 }
    178 
    179 void World::releaseAtomId(atomId_t id){
    180   atomIdPool.insert(id);
    181   // defragmentation of the pool
    182   set<atomId_t>::reverse_iterator iter;
    183   // go through all Ids in the pool that lie immediately below the border
    184   while(!atomIdPool.empty() && *(atomIdPool.rbegin())==(currAtomId-1)){
    185     atomIdPool.erase(--currAtomId);
    186   }
    187 }
    188 
    189 bool World::reserveAtomId(atomId_t id){
    190   if(id>=currAtomId ){
    191     // add all ids between the new one and current border as available
    192     for(atomId_t pos=currAtomId; pos<id; ++pos){
    193       atomIdPool.insert(pos);
    194     }
    195     currAtomId=id+1;
    196     return true;
    197   }
    198   else if(atomIdPool.count(id)){
    199     atomIdPool.erase(id);
    200     return true;
    201   }
    202   else{
    203     // this ID could not be reserved
    204     return false;
    205   }
    206 }
    207 
    208 // Molecules
    209 
    210 /******************************* Iterators ********************************/
    211 
    212 // Build the AtomIterator from template
    213 CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
    214 
    215 
    216 World::AtomIterator World::getAtomIter(AtomDescriptor descr){
    217   return AtomIterator(descr,atoms);
    218 }
    219 
    220 World::AtomIterator World::atomEnd(){
    221   return AtomIterator(AllAtoms(),atoms,atoms.end());
    222 }
    223 
    224 // build the MoleculeIterator from template
    225 CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
    226 
    227 World::MoleculeIterator World::getMoleculeIter(MoleculeDescriptor descr){
    228   return MoleculeIterator(descr,molecules);
    229 }
    230 
    231 World::MoleculeIterator World::moleculeEnd(){
    232   return MoleculeIterator(AllMolecules(),molecules,molecules.end());
    233 }
    234 
    235 /******************************* Singleton Stuff **************************/
    236 
    237 World::World() :
    238     periode(new periodentafel),
    239     atoms(),
    240     currAtomId(0),
    241     molecules(),
    242     currMoleculeId(0),
    243     molecules_deprecated(new MoleculeListClass(this))
    244 {
    245   molecules_deprecated->signOn(this);
    246 }
    247 
    248 World::~World()
    249 {
    250   molecules_deprecated->signOff(this);
    251   delete molecules_deprecated;
    252   delete periode;
    253   MoleculeSet::iterator molIter;
    254   for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
    255     DeleteMolecule((*molIter).second);
    256   }
    257   molecules.clear();
    258   AtomSet::iterator atIter;
    259   for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
    260     DeleteAtom((*atIter).second);
    261   }
    262   atoms.clear();
    263 }
    264 
    265 // Explicit instantiation of the singleton mechanism at this point
    266 
    267 CONSTRUCT_SINGLETON(World)
    268 
    269 /******************************* deprecated Legacy Stuff ***********************/
    270 
    271 MoleculeListClass *&World::getMolecules() {
    272   return molecules_deprecated;
    273 }
Note: See TracChangeset for help on using the changeset viewer.