Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/World.cpp

    r93d732b 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 "config.hpp"
    12 #include "molecule.hpp"
    13 #include "periodentafel.hpp"
    14 #include "Descriptors/AtomDescriptor.hpp"
    15 #include "Descriptors/AtomDescriptor_impl.hpp"
    16 #include "Descriptors/MoleculeDescriptor.hpp"
    17 #include "Descriptors/MoleculeDescriptor_impl.hpp"
    18 #include "Descriptors/SelectiveIterator_impl.hpp"
    19 #include "Actions/ManipulateAtomsProcess.hpp"
     10double *World::cell_size = 0;
    2011
    21 #include "Patterns/Singleton_impl.hpp"
     12/** Constructor of World.
     13 *
     14 */
     15World::World()
     16{
     17  cell_size = new double[6];
     18};
    2219
    23 using namespace std;
    24 
    25 /******************************* getter and setter ************************/
    26 periodentafel *&World::getPeriode(){
    27   return periode;
    28 }
    29 
    30 config *&World::getConfig(){
    31   return configuration;
    32 }
    33 
    34 // Atoms
    35 
    36 atom* World::getAtom(AtomDescriptor descriptor){
    37   return descriptor.find();
    38 }
    39 
    40 vector<atom*> World::getAllAtoms(AtomDescriptor descriptor){
    41   return descriptor.findAll();
    42 }
    43 
    44 vector<atom*> World::getAllAtoms(){
    45   return getAllAtoms(AllAtoms());
    46 }
    47 
    48 int World::numAtoms(){
    49   return atoms.size();
    50 }
    51 
    52 // Molecules
    53 
    54 molecule *World::getMolecule(MoleculeDescriptor descriptor){
    55   return descriptor.find();
    56 }
    57 
    58 std::vector<molecule*> World::getAllMolecules(MoleculeDescriptor descriptor){
    59   return descriptor.findAll();
    60 }
    61 
    62 std::vector<molecule*> World::getAllMolecules(){
    63   return getAllMolecules(AllMolecules());
    64 }
    65 
    66 int World::numMolecules(){
    67   return molecules_deprecated->ListOfMolecules.size();
    68 }
    69 
    70 // system
    71 
    72 double * World::getDomain() {
    73   return cell_size;
    74 }
    75 
    76 void World::setDomain(double * matrix)
     20/** Destructor of World.
     21 *
     22 */
     23World::~World()
    7724{
    78 
    79 }
    80 
    81 char * World::getDefaultName() {
    82   return defaultName;
    83 }
    84 
    85 void World::setDefaultName(char * name)
    86 {
    87   delete[](defaultName);
    88   const int length = strlen(name);
    89   if (length < MAXSTRINGSIZE) {
    90     defaultName = new char[length+2];
    91     strncpy(defaultName, name, length);
    92   } else {
    93     defaultName = new char[MAXSTRINGSIZE];
    94     strncpy(defaultName, "none", MAXSTRINGSIZE-1);
    95   }
     25  delete[](cell_size);
    9626};
    9727
    9828
    99 /******************** Methods to change World state *********************/
     29// TODO: Hide boost-thread using Autotools stuff when no threads are used
     30World* World::theWorld = 0;
    10031
    101 molecule* World::createMolecule(){
    102   OBSERVE;
    103   molecule *mol = NULL;
    104   mol = NewMolecule();
    105   assert(!molecules.count(currMoleculeId));
    106   mol->setId(currMoleculeId++);
    107   // store the molecule by ID
    108   molecules[mol->getId()] = mol;
    109   mol->signOn(this);
    110   return mol;
     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;
    11139}
    11240
    113 void World::destroyMolecule(molecule* mol){
    114   OBSERVE;
    115   destroyMolecule(mol->getId());
     41void World::destroy(){
     42  delete theWorld;
     43  theWorld = 0;
    11644}
    11745
    118 void World::destroyMolecule(moleculeId_t id){
    119   OBSERVE;
    120   molecule *mol = molecules[id];
    121   assert(mol);
    122   DeleteMolecule(mol);
    123   molecules.erase(id);
     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;
    12463}
    125 
    126 double *World::cell_size = NULL;
    127 char *World::defaultName = NULL;
    128 
    129 atom *World::createAtom(){
    130   OBSERVE;
    131   atomId_t id = getNextAtomId();
    132   atom *res = NewAtom(id);
    133   res->setWorld(this);
    134   // store the atom by ID
    135   atoms[res->getId()] = res;
    136   return res;
    137 }
    138 
    139 
    140 int World::registerAtom(atom *atom){
    141   OBSERVE;
    142   atomId_t id = getNextAtomId();
    143   atom->setId(id);
    144   atom->setWorld(this);
    145   atoms[atom->getId()] = atom;
    146   return atom->getId();
    147 }
    148 
    149 void World::destroyAtom(atom* atom){
    150   OBSERVE;
    151   int id = atom->getId();
    152   destroyAtom(id);
    153 }
    154 
    155 void World::destroyAtom(atomId_t id) {
    156   OBSERVE;
    157   atom *atom = atoms[id];
    158   assert(atom);
    159   DeleteAtom(atom);
    160   atoms.erase(id);
    161   releaseAtomId(id);
    162 }
    163 
    164 bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
    165   OBSERVE;
    166   // in case this call did not originate from inside the atom, we redirect it,
    167   // to also let it know that it has changed
    168   if(!target){
    169     target = atoms[oldId];
    170     assert(target && "Atom with that ID not found");
    171     return target->changeId(newId);
    172   }
    173   else{
    174     if(reserveAtomId(newId)){
    175       atoms.erase(oldId);
    176       atoms.insert(pair<atomId_t,atom*>(newId,target));
    177       return true;
    178     }
    179     else{
    180       return false;
    181     }
    182   }
    183 }
    184 
    185 ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
    186   return new ManipulateAtomsProcess(op, descr,name,true);
    187 }
    188 
    189 ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
    190   return manipulateAtoms(op,name,AllAtoms());
    191 }
    192 
    193 /********************* Internal Change methods for double Callback and Observer mechanism ********/
    194 
    195 void World::doManipulate(ManipulateAtomsProcess *proc){
    196   proc->signOn(this);
    197   {
    198     OBSERVE;
    199     proc->doManipulate(this);
    200   }
    201   proc->signOff(this);
    202 }
    203 /******************************* IDManagement *****************************/
    204 
    205 // Atoms
    206 
    207 atomId_t World::getNextAtomId(){
    208   // see if we can reuse some Id
    209   if(atomIdPool.empty()){
    210     return currAtomId++;
    211   }
    212   else{
    213     // we give out the first ID from the pool
    214     atomId_t id = *(atomIdPool.begin());
    215     atomIdPool.erase(id);
    216     return id;
    217   }
    218 }
    219 
    220 void World::releaseAtomId(atomId_t id){
    221   atomIdPool.insert(id);
    222   // defragmentation of the pool
    223   set<atomId_t>::reverse_iterator iter;
    224   // go through all Ids in the pool that lie immediately below the border
    225   while(!atomIdPool.empty() && *(atomIdPool.rbegin())==(currAtomId-1)){
    226     atomIdPool.erase(--currAtomId);
    227   }
    228 }
    229 
    230 bool World::reserveAtomId(atomId_t id){
    231   if(id>=currAtomId ){
    232     // add all ids between the new one and current border as available
    233     for(atomId_t pos=currAtomId; pos<id; ++pos){
    234       atomIdPool.insert(pos);
    235     }
    236     currAtomId=id+1;
    237     return true;
    238   }
    239   else if(atomIdPool.count(id)){
    240     atomIdPool.erase(id);
    241     return true;
    242   }
    243   else{
    244     // this ID could not be reserved
    245     return false;
    246   }
    247 }
    248 
    249 // Molecules
    250 
    251 /******************************* Iterators ********************************/
    252 
    253 // Build the AtomIterator from template
    254 CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
    255 
    256 
    257 World::AtomIterator World::getAtomIter(AtomDescriptor descr){
    258   return AtomIterator(descr,atoms);
    259 }
    260 
    261 World::AtomIterator World::atomEnd(){
    262   return AtomIterator(AllAtoms(),atoms,atoms.end());
    263 }
    264 
    265 // build the MoleculeIterator from template
    266 CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
    267 
    268 World::MoleculeIterator World::getMoleculeIter(MoleculeDescriptor descr){
    269   return MoleculeIterator(descr,molecules);
    270 }
    271 
    272 World::MoleculeIterator World::moleculeEnd(){
    273   return MoleculeIterator(AllMolecules(),molecules,molecules.end());
    274 }
    275 
    276 /******************************* Singleton Stuff **************************/
    277 
    278 World::World() :
    279     periode(new periodentafel),
    280     configuration(new config),
    281     atoms(),
    282     currAtomId(0),
    283     molecules(),
    284     currMoleculeId(0),
    285     molecules_deprecated(new MoleculeListClass(this))
    286 {
    287   cell_size = new double[6];
    288   cell_size[0] = 20.;
    289   cell_size[1] = 0.;
    290   cell_size[2] = 20.;
    291   cell_size[3] = 0.;
    292   cell_size[4] = 0.;
    293   cell_size[5] = 20.;
    294   defaultName = new char[MAXSTRINGSIZE];
    295   strcpy(defaultName, "none");
    296   molecules_deprecated->signOn(this);
    297 }
    298 
    299 World::~World()
    300 {
    301   molecules_deprecated->signOff(this);
    302   delete[] cell_size;
    303   delete[] defaultName;
    304   delete molecules_deprecated;
    305   delete periode;
    306   delete configuration;
    307   MoleculeSet::iterator molIter;
    308   for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
    309     DeleteMolecule((*molIter).second);
    310   }
    311   molecules.clear();
    312   AtomSet::iterator atIter;
    313   for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
    314     DeleteAtom((*atIter).second);
    315   }
    316   atoms.clear();
    317 }
    318 
    319 // Explicit instantiation of the singleton mechanism at this point
    320 
    321 CONSTRUCT_SINGLETON(World)
    322 
    323 /******************************* deprecated Legacy Stuff ***********************/
    324 
    325 MoleculeListClass *&World::getMolecules() {
    326   return molecules_deprecated;
    327 }
Note: See TracChangeset for help on using the changeset viewer.