Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/World.cpp

    r97ebf8 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   defaultName = new char[length+2];
    90   if (length < MAXSTRINGSIZE)
    91     strncpy(defaultName, name, length);
    92   else
    93     strcpy(defaultName, "none");
     25  delete[](cell_size);
    9426};
    9527
    9628
    97 /******************** Methods to change World state *********************/
     29// TODO: Hide boost-thread using Autotools stuff when no threads are used
     30World* World::theWorld = 0;
    9831
    99 molecule* World::createMolecule(){
    100   OBSERVE;
    101   molecule *mol = NULL;
    102   mol = NewMolecule();
    103   assert(!molecules.count(currMoleculeId));
    104   mol->setId(currMoleculeId++);
    105   // store the molecule by ID
    106   molecules[mol->getId()] = mol;
    107   mol->signOn(this);
    108   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;
    10939}
    11040
    111 void World::destroyMolecule(molecule* mol){
    112   OBSERVE;
    113   destroyMolecule(mol->getId());
     41void World::destroy(){
     42  delete theWorld;
     43  theWorld = 0;
    11444}
    11545
    116 void World::destroyMolecule(moleculeId_t id){
    117   OBSERVE;
    118   molecule *mol = molecules[id];
    119   assert(mol);
    120   DeleteMolecule(mol);
    121   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;
    12263}
    123 
    124 double *World::cell_size = NULL;
    125 char *World::defaultName = NULL;
    126 
    127 atom *World::createAtom(){
    128   OBSERVE;
    129   atomId_t id = getNextAtomId();
    130   atom *res = NewAtom(id);
    131   res->setWorld(this);
    132   // store the atom by ID
    133   atoms[res->getId()] = res;
    134   return res;
    135 }
    136 
    137 
    138 int World::registerAtom(atom *atom){
    139   OBSERVE;
    140   atomId_t id = getNextAtomId();
    141   atom->setId(id);
    142   atom->setWorld(this);
    143   atoms[atom->getId()] = atom;
    144   return atom->getId();
    145 }
    146 
    147 void World::destroyAtom(atom* atom){
    148   OBSERVE;
    149   int id = atom->getId();
    150   destroyAtom(id);
    151 }
    152 
    153 void World::destroyAtom(atomId_t id) {
    154   OBSERVE;
    155   atom *atom = atoms[id];
    156   assert(atom);
    157   DeleteAtom(atom);
    158   atoms.erase(id);
    159   releaseAtomId(id);
    160 }
    161 
    162 bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
    163   OBSERVE;
    164   // in case this call did not originate from inside the atom, we redirect it,
    165   // to also let it know that it has changed
    166   if(!target){
    167     target = atoms[oldId];
    168     assert(target && "Atom with that ID not found");
    169     return target->changeId(newId);
    170   }
    171   else{
    172     if(reserveAtomId(newId)){
    173       atoms.erase(oldId);
    174       atoms.insert(pair<atomId_t,atom*>(newId,target));
    175       return true;
    176     }
    177     else{
    178       return false;
    179     }
    180   }
    181 }
    182 
    183 ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
    184   return new ManipulateAtomsProcess(op, descr,name,true);
    185 }
    186 
    187 ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name){
    188   return manipulateAtoms(op,name,AllAtoms());
    189 }
    190 
    191 /********************* Internal Change methods for double Callback and Observer mechanism ********/
    192 
    193 void World::doManipulate(ManipulateAtomsProcess *proc){
    194   proc->signOn(this);
    195   {
    196     OBSERVE;
    197     proc->doManipulate(this);
    198   }
    199   proc->signOff(this);
    200 }
    201 /******************************* IDManagement *****************************/
    202 
    203 // Atoms
    204 
    205 atomId_t World::getNextAtomId(){
    206   // see if we can reuse some Id
    207   if(atomIdPool.empty()){
    208     return currAtomId++;
    209   }
    210   else{
    211     // we give out the first ID from the pool
    212     atomId_t id = *(atomIdPool.begin());
    213     atomIdPool.erase(id);
    214     return id;
    215   }
    216 }
    217 
    218 void World::releaseAtomId(atomId_t id){
    219   atomIdPool.insert(id);
    220   // defragmentation of the pool
    221   set<atomId_t>::reverse_iterator iter;
    222   // go through all Ids in the pool that lie immediately below the border
    223   while(!atomIdPool.empty() && *(atomIdPool.rbegin())==(currAtomId-1)){
    224     atomIdPool.erase(--currAtomId);
    225   }
    226 }
    227 
    228 bool World::reserveAtomId(atomId_t id){
    229   if(id>=currAtomId ){
    230     // add all ids between the new one and current border as available
    231     for(atomId_t pos=currAtomId; pos<id; ++pos){
    232       atomIdPool.insert(pos);
    233     }
    234     currAtomId=id+1;
    235     return true;
    236   }
    237   else if(atomIdPool.count(id)){
    238     atomIdPool.erase(id);
    239     return true;
    240   }
    241   else{
    242     // this ID could not be reserved
    243     return false;
    244   }
    245 }
    246 
    247 // Molecules
    248 
    249 /******************************* Iterators ********************************/
    250 
    251 // Build the AtomIterator from template
    252 CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
    253 
    254 
    255 World::AtomIterator World::getAtomIter(AtomDescriptor descr){
    256   return AtomIterator(descr,atoms);
    257 }
    258 
    259 World::AtomIterator World::atomEnd(){
    260   return AtomIterator(AllAtoms(),atoms,atoms.end());
    261 }
    262 
    263 // build the MoleculeIterator from template
    264 CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
    265 
    266 World::MoleculeIterator World::getMoleculeIter(MoleculeDescriptor descr){
    267   return MoleculeIterator(descr,molecules);
    268 }
    269 
    270 World::MoleculeIterator World::moleculeEnd(){
    271   return MoleculeIterator(AllMolecules(),molecules,molecules.end());
    272 }
    273 
    274 /******************************* Singleton Stuff **************************/
    275 
    276 World::World() :
    277     periode(new periodentafel),
    278     configuration(new config),
    279     atoms(),
    280     currAtomId(0),
    281     molecules(),
    282     currMoleculeId(0),
    283     molecules_deprecated(new MoleculeListClass(this))
    284 {
    285   cell_size = new double[6];
    286   cell_size[0] = 20.;
    287   cell_size[1] = 0.;
    288   cell_size[2] = 20.;
    289   cell_size[3] = 0.;
    290   cell_size[4] = 0.;
    291   cell_size[5] = 20.;
    292   defaultName = new char[MAXSTRINGSIZE];
    293   strcpy(defaultName, "none");
    294   molecules_deprecated->signOn(this);
    295 }
    296 
    297 World::~World()
    298 {
    299   molecules_deprecated->signOff(this);
    300   delete[] cell_size;
    301   delete[] defaultName;
    302   delete molecules_deprecated;
    303   delete periode;
    304   delete configuration;
    305   MoleculeSet::iterator molIter;
    306   for(molIter=molecules.begin();molIter!=molecules.end();++molIter){
    307     DeleteMolecule((*molIter).second);
    308   }
    309   molecules.clear();
    310   AtomSet::iterator atIter;
    311   for(atIter=atoms.begin();atIter!=atoms.end();++atIter){
    312     DeleteAtom((*atIter).second);
    313   }
    314   atoms.clear();
    315 }
    316 
    317 // Explicit instantiation of the singleton mechanism at this point
    318 
    319 CONSTRUCT_SINGLETON(World)
    320 
    321 /******************************* deprecated Legacy Stuff ***********************/
    322 
    323 MoleculeListClass *&World::getMolecules() {
    324   return molecules_deprecated;
    325 }
Note: See TracChangeset for help on using the changeset viewer.