Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/World.cpp

    r70378e r97ebf8  
    11/*
    2  * world.cpp
     2 * World.cpp
    33 *
    4  *  Created on: Mar 3, 2010
     4 *  Created on: Feb 3, 2010
    55 *      Author: crueger
    66 */
     
    88#include "World.hpp"
    99
    10 double *World::cell_size = 0;
    11 
    12 /** Constructor of World.
    13  *
    14  */
    15 World::World()
     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"
     20
     21#include "Patterns/Singleton_impl.hpp"
     22
     23using namespace std;
     24
     25/******************************* getter and setter ************************/
     26periodentafel *&World::getPeriode(){
     27  return periode;
     28}
     29
     30config *&World::getConfig(){
     31  return configuration;
     32}
     33
     34// Atoms
     35
     36atom* World::getAtom(AtomDescriptor descriptor){
     37  return descriptor.find();
     38}
     39
     40vector<atom*> World::getAllAtoms(AtomDescriptor descriptor){
     41  return descriptor.findAll();
     42}
     43
     44vector<atom*> World::getAllAtoms(){
     45  return getAllAtoms(AllAtoms());
     46}
     47
     48int World::numAtoms(){
     49  return atoms.size();
     50}
     51
     52// Molecules
     53
     54molecule *World::getMolecule(MoleculeDescriptor descriptor){
     55  return descriptor.find();
     56}
     57
     58std::vector<molecule*> World::getAllMolecules(MoleculeDescriptor descriptor){
     59  return descriptor.findAll();
     60}
     61
     62std::vector<molecule*> World::getAllMolecules(){
     63  return getAllMolecules(AllMolecules());
     64}
     65
     66int World::numMolecules(){
     67  return molecules_deprecated->ListOfMolecules.size();
     68}
     69
     70// system
     71
     72double * World::getDomain() {
     73  return cell_size;
     74}
     75
     76void World::setDomain(double * matrix)
     77{
     78
     79}
     80
     81char * World::getDefaultName() {
     82  return defaultName;
     83}
     84
     85void 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");
     94};
     95
     96
     97/******************** Methods to change World state *********************/
     98
     99molecule* 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;
     109}
     110
     111void World::destroyMolecule(molecule* mol){
     112  OBSERVE;
     113  destroyMolecule(mol->getId());
     114}
     115
     116void World::destroyMolecule(moleculeId_t id){
     117  OBSERVE;
     118  molecule *mol = molecules[id];
     119  assert(mol);
     120  DeleteMolecule(mol);
     121  molecules.erase(id);
     122}
     123
     124double *World::cell_size = NULL;
     125char *World::defaultName = NULL;
     126
     127atom *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
     138int 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
     147void World::destroyAtom(atom* atom){
     148  OBSERVE;
     149  int id = atom->getId();
     150  destroyAtom(id);
     151}
     152
     153void 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
     162bool 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
     183ManipulateAtomsProcess* World::manipulateAtoms(boost::function<void(atom*)> op,std::string name,AtomDescriptor descr){
     184  return new ManipulateAtomsProcess(op, descr,name,true);
     185}
     186
     187ManipulateAtomsProcess* 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
     193void 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
     205atomId_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
     218void 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
     228bool 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
     252CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
     253
     254
     255World::AtomIterator World::getAtomIter(AtomDescriptor descr){
     256  return AtomIterator(descr,atoms);
     257}
     258
     259World::AtomIterator World::atomEnd(){
     260  return AtomIterator(AllAtoms(),atoms,atoms.end());
     261}
     262
     263// build the MoleculeIterator from template
     264CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
     265
     266World::MoleculeIterator World::getMoleculeIter(MoleculeDescriptor descr){
     267  return MoleculeIterator(descr,molecules);
     268}
     269
     270World::MoleculeIterator World::moleculeEnd(){
     271  return MoleculeIterator(AllMolecules(),molecules,molecules.end());
     272}
     273
     274/******************************* Singleton Stuff **************************/
     275
     276World::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))
    16284{
    17285  cell_size = new double[6];
    18 };
    19 
    20 /** Destructor of World.
    21  *
    22  */
     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
    23297World::~World()
    24298{
    25   delete[](cell_size);
    26 };
    27 
    28 
    29 // TODO: Hide boost-thread using Autotools stuff when no threads are used
    30 World* World::theWorld = 0;
    31 
    32 
    33 World* 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;
    39 }
    40 
    41 void World::destroy(){
    42   delete theWorld;
    43   theWorld = 0;
    44 }
    45 
    46 World* 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;
    63 }
     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
     319CONSTRUCT_SINGLETON(World)
     320
     321/******************************* deprecated Legacy Stuff ***********************/
     322
     323MoleculeListClass *&World::getMolecules() {
     324  return molecules_deprecated;
     325}
Note: See TracChangeset for help on using the changeset viewer.