Changes in / [cd032d:68d781]


Ignore:
Location:
src
Files:
9 added
1 deleted
72 edited

Legend:

Unmodified
Added
Removed
  • src/Actions/Action.cpp

    rcd032d r68d781  
    1010#include "Actions/Action.hpp"
    1111#include "Actions/ActionRegistry.hpp"
     12#include "Actions/ActionHistory.hpp"
    1213
    1314using namespace std;
     15
     16// An empty state to indicate success
     17Action::state_ptr Action::success = Action::state_ptr(new ActionState());
     18Action::state_ptr Action::failure = Action::state_ptr(new ActionState());
    1419
    1520Action::Action(std::string _name,bool _doRegister) :
     
    2732  return name;
    2833}
     34
     35void Action::call(){
     36  // forward to private virtual
     37  state_ptr state = performCall();
     38  if(shouldUndo() && state != failure){
     39    if(canUndo()){
     40      ActionHistory::getInstance().addElement(this,state);
     41    }
     42    else{
     43      ActionHistory::getInstance().clear();
     44    }
     45  }
     46}
     47Action::state_ptr Action::undo(state_ptr _state) {
     48  // forward to private virtual
     49  return performUndo(_state);
     50}
     51Action::state_ptr Action::redo(state_ptr _state) {
     52  // forward to private virtual
     53  return performRedo(_state);
     54}
  • src/Actions/Action.hpp

    rcd032d r68d781  
    1010
    1111#include <string>
     12#include <boost/shared_ptr.hpp>
     13
     14// forward declaration
     15
     16class ActionState;
     17class ActionSequence;
    1218
    1319/**
     
    2127class Action
    2228{
    23 protected:
     29friend class ActionSequence;
    2430public:
     31
     32  typedef boost::shared_ptr<ActionState> state_ptr;
     33
    2534  Action(std::string _name,bool _doRegister=true);
    2635  virtual ~Action();
    2736
    28   virtual void call()=0;
    29   virtual void undo()=0;
     37  // this method only handles the infrastructure
     38  // actuall action is passed on to a private virtual
     39  void call();
     40  state_ptr undo(state_ptr);
     41  state_ptr redo(state_ptr);
     42
    3043  virtual bool canUndo()=0;
    31   //virtual bool shouldUndo()=0;
     44  virtual bool shouldUndo()=0;
    3245
    3346  virtual const std::string getName();
    3447
     48protected:
     49  static state_ptr success;
     50  static state_ptr failure;
     51
    3552private:
     53  virtual state_ptr performCall()=0;
     54  virtual state_ptr performUndo(state_ptr)=0;
     55  virtual state_ptr performRedo(state_ptr)=0;
     56
    3657  std::string name;
    3758};
    3859
     60/**
     61 * This class can be used by actions to save the state.
     62 *
     63 * It is implementing a memento pattern. The base class is completely empty,
     64 * since no general state internals can be given. The Action performing
     65 * the Undo should downcast to the apropriate type.
     66 */
     67class ActionState{
     68public:
     69  ActionState(){}
     70  virtual ~ActionState(){}
     71};
     72
    3973#endif /* ACTION_H_ */
  • src/Actions/ActionRegistry.cpp

    rcd032d r68d781  
    1212
    1313#include <string>
    14 #include <cassert>
     14#include "Helpers/Assert.hpp"
    1515#include <iostream>
    1616
     
    3333  map<const string,Action*>::iterator iter;
    3434  iter = actionMap.find(name);
    35   assert(iter!=actionMap.end() && "Query for an action not stored in registry");
     35  ASSERT(iter!=actionMap.end(),"Query for an action not stored in registry");
    3636  return iter->second;
    3737}
     
    4040  pair<map<const string,Action*>::iterator,bool> ret;
    4141  ret = actionMap.insert(pair<const string,Action*>(action->getName(),action));
    42   assert(ret.second && "Two actions with the same name added to registry");
     42  ASSERT(ret.second,"Two actions with the same name added to registry");
    4343}
    4444
  • src/Actions/ActionSequence.cpp

    rcd032d r68d781  
    88#include "Actions/ActionSequence.hpp"
    99#include "Actions/Action.hpp"
     10
     11#include "Helpers/Assert.hpp"
    1012
    1113using namespace std;
     
    3436}
    3537
    36 void ActionSequence::callAll(){
    37   deque<Action*>::iterator it;
    38   for(it=actions.begin(); it!=actions.end(); it++)
    39     (*it)->call();
     38ActionSequence::stateSet ActionSequence::callAll(){
     39  stateSet states;
     40  for(actionSet::iterator it=actions.begin(); it!=actions.end(); it++){
     41    // we want to have a global bookkeeping for all actions in the sequence, so
     42    // we bypass the normal call
     43    Action::state_ptr state = (*it)->performCall();
     44    states.push_back(state);
     45  }
     46  return states;
    4047}
    4148
    42 void ActionSequence::undoAll(){
    43   deque<Action*>::reverse_iterator rit;
    44   for(rit=actions.rbegin(); rit!=actions.rend(); rit++)
    45     (*rit)->undo();
     49ActionSequence::stateSet ActionSequence::undoAll(stateSet states){
     50  ASSERT(canUndo(),"Trying to undo a sequence that contains methods that can't be undone");
     51  stateSet res;
     52  actionSet::reverse_iterator actionRit = actions.rbegin();
     53  stateSet::reverse_iterator stateRit = states.rbegin();
     54  for(;actionRit!=actions.rend();++actionRit,++stateRit){
     55    ASSERT(stateRit!=states.rend(),"End of states prematurely reached.");
     56    if((*actionRit)->shouldUndo()){
     57      Action::state_ptr newState = (*actionRit)->performUndo(*stateRit);
     58      // The order of the states has to correspond to the order of the actions
     59      // this is why we have to add at the beginning
     60      res.push_front(newState);
     61    }
     62    else{
     63      res.push_front(Action::success);
     64    }
     65  }
     66  return res;
     67}
     68
     69ActionSequence::stateSet ActionSequence::redoAll(stateSet states){
     70  stateSet res;
     71  actionSet::iterator actionIt = actions.begin();
     72  stateSet::iterator stateIt = states.begin();
     73  for(;actionIt!=actions.end();++actionIt,++stateIt){
     74    ASSERT(stateIt!=states.end(),"End of states prematurely reached.");
     75    if((*actionIt)->shouldUndo()){
     76      Action::state_ptr newState =(*actionIt)->performRedo(*stateIt);
     77      res.push_back(newState);
     78    }
     79    else{
     80      res.push_back(Action::success);
     81    }
     82  }
     83  return res;
    4684}
    4785
    4886bool ActionSequence::canUndo(){
    4987  bool canUndo=true;
    50   deque<Action*>::iterator it;
    51   for(it=actions.begin(); it!=actions.end(); it++)
    52     canUndo &= (*it)->canUndo();
     88  for(deque<Action*>::iterator it=actions.begin(); it!=actions.end(); ++it){
     89    if((*it)->shouldUndo()){
     90      canUndo &= (*it)->canUndo();
     91    }
     92  }
    5393  return canUndo;
    5494}
     95
     96bool ActionSequence::shouldUndo(){
     97  bool shouldUndo = false;
     98  for(deque<Action*>::iterator it=actions.begin();it!=actions.end();++it){
     99    shouldUndo |= (*it)->shouldUndo();
     100  }
     101  return shouldUndo;
     102}
  • src/Actions/ActionSequence.hpp

    rcd032d r68d781  
    99#define ACTIONSEQUENZE_HPP_
    1010
     11#include "Actions/Action.hpp"
     12
    1113#include <deque>
    12 
    13 class Action;
    1414
    1515/**
     
    1919{
    2020public:
     21  typedef std::deque<Action*> actionSet;
     22  typedef std::deque<Action::state_ptr> stateSet;
     23
    2124  ActionSequence();
    2225  virtual ~ActionSequence();
     
    2528  Action* removeLastAction();
    2629
    27   void callAll();
    28   void undoAll();
     30  stateSet callAll();
     31  stateSet undoAll(stateSet);
     32  stateSet redoAll(stateSet);
    2933
    3034  bool canUndo();
     35  bool shouldUndo();
    3136
    3237private:
    33   std::deque<Action*> actions;
     38  actionSet actions;
    3439};
    3540
  • src/Actions/AtomsCalculation_impl.hpp

    rcd032d r68d781  
    1919AtomsCalculation<T>::AtomsCalculation(boost::function<T(atom*)> _op,std::string name,AtomDescriptor _descr) :
    2020  Calculation<std::vector<T> >(0,name,false),
    21   op(_op),
    22   descr(_descr)
     21  descr(_descr),
     22  op(_op)
    2323{}
    2424
     
    3535  Process::setMaxSteps(steps);
    3636  Process::start();
    37   World::AtomIterator iter;
    38   for(iter=world->getAtomIter(descr);iter!=world->atomEnd();++iter){
     37  for(World::AtomIterator iter=world->getAtomIter(descr);iter!=world->atomEnd();++iter){
    3938    Process::setCurrStep(iter.getCount());
    4039    res->push_back(op(*iter));
  • src/Actions/Calculation.hpp

    rcd032d r68d781  
    2929   * from menu Items or other places.
    3030   */
    31   virtual void call();
    32   virtual void undo();
    3331  virtual bool canUndo();
     32
     33  virtual bool shouldUndo();
    3434
    3535  /**
     
    6464  virtual T* doCalc()=0;
    6565private:
     66  virtual Action::state_ptr performCall();
     67  virtual Action::state_ptr performUndo(Action::state_ptr);
     68  virtual Action::state_ptr performRedo(Action::state_ptr);
     69
    6670  bool done;
    6771};
  • src/Actions/Calculation_impl.hpp

    rcd032d r68d781  
    1616Calculation<T>::Calculation(int _maxSteps, std::string _name, bool _doRegister) :
    1717  Process(_maxSteps,_name,_doRegister),
    18   done(false),
    19   result(0)
     18  result(0),
     19  done(false)
    2020{}
    2121
     
    2929
    3030template<typename T>
    31 void Calculation<T>::call(){
     31Action::state_ptr Calculation<T>::performCall(){
    3232  reset();
    3333  (*this)();
     34  return Action::success;
    3435}
    3536
    3637template<typename T>
    37 void Calculation<T>::undo(){}
     38Action::state_ptr Calculation<T>::performUndo(Action::state_ptr){
     39  ASSERT(0,"Cannot undo a calculation");
     40  return Action::success;
     41}
     42template<typename T>
     43Action::state_ptr Calculation<T>::performRedo(Action::state_ptr){
     44  ASSERT(0,"Cannot redo a calculation");
     45  return Action::success;
     46}
    3847
    3948template<typename T>
    4049bool Calculation<T>::canUndo()
     50{
     51  return false;
     52}
     53
     54template<typename T>
     55bool Calculation<T>::shouldUndo()
    4156{
    4257  return false;
  • src/Actions/ErrorAction.cpp

    rcd032d r68d781  
    1111#include "log.hpp"
    1212#include "verbose.hpp"
     13#include "Helpers/Assert.hpp"
    1314
    1415using namespace std;
     
    2425}
    2526
    26 void ErrorAction::call() {
     27Action::state_ptr ErrorAction::performCall() {
    2728  Log() << Verbose(0) << errorMsg << endl;
     29  return Action::success;
    2830}
    29 void ErrorAction::undo() {
     31Action::state_ptr ErrorAction::performUndo(Action::state_ptr) {
     32  ASSERT(0,"Undo called for an ErrorAction");
     33  return Action::success;
     34}
     35
     36Action::state_ptr ErrorAction::performRedo(Action::state_ptr) {
     37  ASSERT(0,"Redo called for an ErrorAction");
     38  return Action::success;
    3039}
    3140
     
    3342  return false;
    3443}
     44
     45bool ErrorAction::shouldUndo(){
     46  return false;
     47}
  • src/Actions/ErrorAction.hpp

    rcd032d r68d781  
    1818  virtual ~ErrorAction();
    1919
    20   virtual void call();
    21   virtual void undo();
    2220  virtual bool canUndo();
     21  virtual bool shouldUndo();
    2322
    2423private:
     24
     25  virtual Action::state_ptr performCall();
     26  virtual Action::state_ptr performUndo(Action::state_ptr);
     27  virtual Action::state_ptr performRedo(Action::state_ptr);
     28
    2529  std::string errorMsg;
    2630};
  • src/Actions/MakroAction.cpp

    rcd032d r68d781  
    1111#include "Actions/Action.hpp"
    1212#include "Actions/ActionSequence.hpp"
     13#include "Helpers/Assert.hpp"
    1314
    1415using namespace std;
     16
     17class MakroActionState : public ActionState{
     18public:
     19  MakroActionState(ActionSequence::stateSet _states) :
     20    states(_states)
     21  {}
     22  virtual ~MakroActionState(){
     23    // All contained states are destroyed by the shared ptrs
     24  }
     25
     26  ActionSequence::stateSet states;
     27};
    1528
    1629MakroAction::MakroAction(string _name,ActionSequence* _actions,bool _doRegister) :
     
    3043
    3144
    32 void MakroAction::call(){
    33   actions->callAll();
     45Action::state_ptr MakroAction::performCall(){
     46  ActionSequence::stateSet states = actions->callAll();
     47  return Action::state_ptr(new MakroActionState(states));
    3448}
    3549
    36 void MakroAction::undo() {
    37   actions->undoAll();
     50Action::state_ptr MakroAction::performUndo(Action::state_ptr _state) {
     51  MakroActionState *state = dynamic_cast<MakroActionState*>(_state.get());
     52  ASSERT(state,"Type mismatch for the state of the MakroAction");
     53  ActionSequence::stateSet states = actions->undoAll(state->states);
     54  return Action::state_ptr(new MakroActionState(states));
     55}
     56
     57Action::state_ptr MakroAction::performRedo(Action::state_ptr _state){
     58  MakroActionState *state = dynamic_cast<MakroActionState*>(_state.get());
     59  ASSERT(state,"Type mismatch for the state of the MakroAction");
     60  ActionSequence::stateSet states = actions->redoAll(state->states);
     61  return Action::state_ptr(new MakroActionState(states));
    3862}
    3963
     
    4165  return actions->canUndo();
    4266}
     67
     68bool MakroAction::shouldUndo() {
     69  return actions->shouldUndo();
     70}
  • src/Actions/MakroAction.hpp

    rcd032d r68d781  
    2626  virtual ~MakroAction();
    2727
    28   virtual void call();
    29   virtual void undo();
    30   virtual bool canUndo();
     28  bool canUndo();
     29  bool shouldUndo();
    3130
    3231private:
     32  virtual Action::state_ptr performCall();
     33  virtual Action::state_ptr performUndo(Action::state_ptr);
     34  virtual Action::state_ptr performRedo(Action::state_ptr);
     35
    3336  ActionSequence *actions;
    3437};
  • src/Actions/ManipulateAtomsProcess.cpp

    rcd032d r68d781  
    99
    1010#include <iostream>
     11
     12#include "World.hpp"
     13#include "Helpers/Assert.hpp"
    1114
    1215using namespace std;
     
    2225{}
    2326
    24 void ManipulateAtomsProcess::call(){
     27Action::state_ptr ManipulateAtomsProcess::performCall(){
    2528  World::getInstance().doManipulate(this);
     29  return Action::success;
    2630}
    2731
    28 void ManipulateAtomsProcess::undo(){
     32Action::state_ptr ManipulateAtomsProcess::performUndo(Action::state_ptr){
     33  ASSERT(0,"Undo called for a ManipulateAtomsProcess");
     34  return Action::success;
     35}
    2936
     37Action::state_ptr ManipulateAtomsProcess::performRedo(Action::state_ptr){
     38  ASSERT(0,"Redo called for a ManipulateAtomsProcess");
     39  return Action::success;
    3040}
    3141
     
    3444}
    3545
     46bool ManipulateAtomsProcess::shouldUndo(){
     47  return true;
     48}
     49
    3650void ManipulateAtomsProcess::doManipulate(World *world){
    3751  setMaxSteps(world->numAtoms());
    3852  start();
    39   World::AtomIterator iter;
    40   for(iter=world->getAtomIter(descr);iter!=world->atomEnd();++iter){
     53  for(World::AtomIterator iter=world->getAtomIter(descr);iter!=world->atomEnd();++iter){
    4154    setCurrStep(iter.getCount());
    4255    operation(*iter);
  • src/Actions/ManipulateAtomsProcess.hpp

    rcd032d r68d781  
    1010
    1111#include "Actions/Process.hpp"
     12
     13#include<boost/function.hpp>
     14
    1215#include "Descriptors/AtomDescriptor.hpp"
     16
     17class World;
    1318
    1419class ManipulateAtomsProcess : public Process
     
    1823  virtual ~ManipulateAtomsProcess();
    1924
    20   virtual void call();
    21   virtual void undo();
    2225  virtual bool canUndo();
     26  virtual bool shouldUndo();
    2327
    2428  virtual void doManipulate(World *);
    2529private:
     30
     31  virtual Action::state_ptr performCall();
     32  virtual Action::state_ptr performUndo(Action::state_ptr);
     33  virtual Action::state_ptr performRedo(Action::state_ptr);
     34
    2635  AtomDescriptor descr;
    2736  boost::function<void(atom*)> operation;
  • src/Actions/MethodAction.cpp

    rcd032d r68d781  
    1010#include <string>
    1111
    12 #include "MethodAction.hpp"
     12#include "Actions/MethodAction.hpp"
     13#include "Helpers/Assert.hpp"
    1314
    1415using namespace std;
     
    2122
    2223MethodAction::~MethodAction()
    23 {
    24   // TODO Auto-generated destructor stub
     24{}
     25
     26
     27Action::state_ptr MethodAction::performCall() {
     28  executeMethod();
     29  // we don't have a state to save so we return Action::success
     30  return Action::success;
    2531}
    2632
     33Action::state_ptr MethodAction::performUndo(Action::state_ptr) {
     34  ASSERT(0,"Cannot undo a MethodAction");
     35  return Action::success;
     36}
    2737
    28 void MethodAction::call() {
    29   executeMethod();
    30 }
    31 void MethodAction::undo() {
    32 
     38Action::state_ptr MethodAction::performRedo(Action::state_ptr){
     39  ASSERT(0,"Cannot redo a MethodAction");
     40  return Action::success;
    3341}
    3442
     
    3644  return false;
    3745}
     46
     47bool MethodAction::shouldUndo(){
     48  return true;
     49}
  • src/Actions/MethodAction.hpp

    rcd032d r68d781  
    2222  MethodAction(std::string _name,boost::function<void()> _executeMethod,bool _doRegister=true);
    2323  virtual ~MethodAction();
     24  virtual bool canUndo();
     25  virtual bool shouldUndo();
    2426
    25   virtual void call();
    26   virtual void undo();
    27   virtual bool canUndo();
     27private:
     28  virtual Action::state_ptr performCall();
     29  virtual Action::state_ptr performUndo(Action::state_ptr);
     30  virtual Action::state_ptr performRedo(Action::state_ptr);
     31
    2832
    2933  boost::function<void()> executeMethod; //!< this stores the method to be called
    30 
    31 
    3234};
    3335
  • src/Actions/small_actions.cpp

    rcd032d r68d781  
    1414/****** ChangeMoleculeNameAction *****/
    1515
    16 char ChangeMoleculeNameAction::NAME[] = "Change filename of Molecule";
     16// memento to remember the state when undoing
     17
     18class ChangeMoleculeNameState : public ActionState {
     19public:
     20  ChangeMoleculeNameState(molecule* _mol,std::string _lastName) :
     21    mol(_mol),
     22    lastName(_lastName)
     23  {}
     24  molecule* mol;
     25  std::string lastName;
     26};
     27
     28const char ChangeMoleculeNameAction::NAME[] = "Change filename of Molecule";
    1729
    1830ChangeMoleculeNameAction::ChangeMoleculeNameAction(MoleculeListClass *_molecules) :
     
    2436{}
    2537
    26 void ChangeMoleculeNameAction::call() {
     38Action::state_ptr ChangeMoleculeNameAction::performCall() {
    2739  string filename;
    2840  molecule *mol = NULL;
     
    3143  dialog->queryMolecule("Enter index of molecule: ",&mol,molecules);
    3244  dialog->queryString("Enter name: ",&filename);
     45
    3346  if(dialog->display()) {
     47    string oldName = mol->getName();
    3448    mol->setName(filename);
     49    delete dialog;
     50    return Action::state_ptr(new ChangeMoleculeNameState(mol,oldName));
    3551  }
    36 
    3752  delete dialog;
     53  return Action::failure;
    3854}
    3955
    40 void ChangeMoleculeNameAction::undo() {
     56Action::state_ptr ChangeMoleculeNameAction::performUndo(Action::state_ptr _state) {
     57  ChangeMoleculeNameState *state = dynamic_cast<ChangeMoleculeNameState*>(_state.get());
     58  ASSERT(state,"State passed to ChangeMoleculeNameAction::performUndo did not have correct type");
    4159
     60  string newName = state->mol->getName();
     61  state->mol->setName(state->lastName);
     62
     63  return Action::state_ptr(new ChangeMoleculeNameState(state->mol,newName));
     64}
     65
     66Action::state_ptr ChangeMoleculeNameAction::performRedo(Action::state_ptr _state){
     67  // Undo and redo have to do the same for this action
     68  return performUndo(_state);
    4269}
    4370
    4471bool ChangeMoleculeNameAction::canUndo() {
    45   return false;
     72  return true;
    4673}
    4774
  • src/Actions/small_actions.hpp

    rcd032d r68d781  
    1414  virtual ~ChangeMoleculeNameAction();
    1515
    16   void call();
    17   void undo();
    1816  bool canUndo();
    1917  bool shouldUndo();
     
    2119  virtual const std::string getName();
    2220private:
     21  virtual Action::state_ptr performCall();
     22  virtual Action::state_ptr performUndo(Action::state_ptr);
     23  virtual Action::state_ptr performRedo(Action::state_ptr);
     24
    2325  MoleculeListClass *molecules;
    24   static char NAME[];
     26  static const char NAME[];
    2527};
    2628
  • src/Descriptors/AtomDescriptor.hpp

    rcd032d r68d781  
    3636  friend atom* World::getAtom(AtomDescriptor descriptor);
    3737  friend std::vector<atom*> World::getAllAtoms(AtomDescriptor descriptor);
    38   friend class World::AtomIterator;
     38  template <class,class,class> friend class SelectiveIterator;
    3939
    4040  friend AtomDescriptor operator&&(const AtomDescriptor &lhs, const AtomDescriptor &rhs);
  • src/Descriptors/AtomTypeDescriptor.cpp

    rcd032d r68d781  
    1313#include "periodentafel.hpp"
    1414
    15 AtomTypeDescriptor_impl::AtomTypeDescriptor_impl(element* _type) :
     15AtomTypeDescriptor_impl::AtomTypeDescriptor_impl(const element* _type) :
    1616  type(_type)
    1717{}
     
    2424}
    2525
    26 AtomDescriptor AtomByType(element *elem){
     26AtomDescriptor AtomByType(const element *elem){
    2727  return AtomDescriptor(AtomDescriptor::impl_ptr(new AtomTypeDescriptor_impl(elem)));
    2828}
    2929
    3030AtomDescriptor AtomByType(int Z){
    31   element * elem = World::getInstance().getPeriode()->FindElement(Z);
     31  const element * elem = World::getInstance().getPeriode()->FindElement(Z);
    3232  return AtomByType(elem);
    3333}
  • src/Descriptors/AtomTypeDescriptor.hpp

    rcd032d r68d781  
    1313class element;
    1414
    15 AtomDescriptor AtomByType(element *);
     15AtomDescriptor AtomByType(const element *);
    1616AtomDescriptor AtomByType(int);
    1717
  • src/Descriptors/AtomTypeDescriptor_impl.hpp

    rcd032d r68d781  
    1414{
    1515public:
    16   AtomTypeDescriptor_impl(element* _type);
     16  AtomTypeDescriptor_impl(const element* _type);
    1717  virtual ~AtomTypeDescriptor_impl();
    1818
    1919  bool predicate(std::pair<atomId_t,atom*> atom);
    2020private:
    21   element *type;
     21  const element * const type;
    2222};
    2323
  • src/Descriptors/MoleculeDescriptor.hpp

    rcd032d r68d781  
    3636  friend molecule* World::getMolecule(MoleculeDescriptor descriptor);
    3737  friend std::vector<molecule*> World::getAllMolecules(MoleculeDescriptor descriptor);
    38   friend class World::MoleculeIterator;
     38  template <class,class,class> friend class SelectiveIterator;
    3939
    4040  friend MoleculeDescriptor operator&&(const MoleculeDescriptor &lhs, const MoleculeDescriptor &rhs);
     
    4343
    4444public:
    45   typedef boost::shared_ptr<MoleculeDescriptor_impl> impl_ptr; //!< Allow easy changes of the pointer-to-implementation type
     45  typedef MoleculeDescriptor_impl impl_t;
     46  typedef boost::shared_ptr<impl_t> impl_ptr; //!< Allow easy changes of the pointer-to-implementation type
    4647
    4748  MoleculeDescriptor(impl_ptr);
  • src/Legacy/oldmenu.cpp

    rcd032d r68d781  
    748748  int axis,faktor,count,j;
    749749  atom *first = NULL;
    750   element **Elements;
     750  const element **Elements;
    751751  Vector x,y;
    752752  Vector **vectors;
     
    764764    if (mol->AtomCount != 0) {  // if there is more than none
    765765      count = mol->AtomCount;  // is changed becausing of adding, thus has to be stored away beforehand
    766       Elements = new element *[count];
     766      Elements = new const element *[count];
    767767      vectors = new Vector *[count];
    768768      j = 0;
  • src/Makefile.am

    rcd032d r68d781  
    88ANALYSISHEADER = analysis_bonds.hpp analysis_correlation.hpp
    99
    10 # only include Actions that are free of user interaction at this point
    11 # the UIFactory et. al. wont be known for the libmolecuilder, so the user interaction cannot be done.
    12 ACTIONSSOURCE = Actions/Action.cpp Actions/Process.cpp Actions/MethodAction.cpp Actions/ActionSequence.cpp Actions/MakroAction.cpp Actions/ManipulateAtomsProcess.cpp Actions/ActionRegistry.cpp
    13 ACTIONSHEADER = Actions/Action.hpp Actions/Process.hpp Actions/Calculation.hpp Actions/Calculation_impl.hpp Actions/MethodAction.hpp Actions/ActionSequence.hpp Actions/MakroAction.hpp Actions/ManipulateAtomsProcess.hpp Actions/ActionRegistry.hpp
    14 
     10ACTIONSSOURCE = Actions/Action.cpp \
     11                                Actions/ActionHistory.cpp \
     12                                Actions/ActionRegistry.cpp \
     13                                Actions/ActionSequence.cpp \
     14                                Actions/MakroAction.cpp \
     15                                Actions/ManipulateAtomsProcess.cpp \
     16                                Actions/MethodAction.cpp \
     17                Actions/Process.cpp
     18                 
     19ACTIONSHEADER = Actions/Action.hpp \
     20                                Actions/ActionHistory.hpp \
     21                                Actions/ActionRegistry.hpp \
     22                                Actions/ActionSequence.hpp \
     23                            Actions/Calculation.hpp \
     24                            Actions/Calculation_impl.hpp \
     25                            Actions/MakroAction.hpp \
     26                            Actions/ManipulateAtomsProcess.hpp \
     27                            Actions/MethodAction.hpp \
     28                            Actions/Process.hpp
     29                           
     30                           
    1531# All actions that need user interaction go here
    1632MENUACTIONSSOURCE = Actions/ErrorAction.cpp Actions/small_actions.cpp
     
    6076                                   Descriptors/AtomTypeDescriptor.cpp \
    6177                                   Descriptors/MoleculeDescriptor.cpp \
    62                                    Descriptors/MoleculeIdDescriptor.cpp
     78                                   Descriptors/MoleculeIdDescriptor.cpp
     79                                   
    6380                                   
    6481DESCRIPTORHEADER = Descriptors/AtomDescriptor.hpp \
     
    6784                                   Descriptors/MoleculeDescriptor.hpp \
    6885                                   Descriptors/MoleculeIdDescriptor.hpp
     86                                   
     87
    6988
    7089QTUISOURCE = ${QTUIMOC_TARGETS} \
     
    82101QTUI_DEFS =
    83102
    84 SOURCE = ${ANALYSISSOURCE} ${ATOMSOURCE} ${PATTERNSOURCE} ${ACTIONSSOURCE} ${DESCRIPTORSOURCE}  bond.cpp bondgraph.cpp boundary.cpp config.cpp element.cpp ellipsoid.cpp errorlogger.cpp graph.cpp helpers.cpp info.cpp leastsquaremin.cpp linkedcell.cpp lists.cpp log.cpp logger.cpp memoryusageobserver.cpp moleculelist.cpp molecule.cpp molecule_dynamics.cpp molecule_fragmentation.cpp molecule_geometry.cpp molecule_graph.cpp molecule_pointcloud.cpp parser.cpp periodentafel.cpp tesselation.cpp tesselationhelpers.cpp vector.cpp verbose.cpp World.cpp WorldIterators.cpp
    85 HEADER = ${ANALYSISHEADER} ${ATOMHEADER} ${PATTERNHEADER} ${ACTIONSHEADER} ${DESCRIPTORHEADER} ${LEGACYHEADER} bond.hpp bondgraph.hpp boundary.hpp config.hpp defs.hpp element.hpp ellipsoid.hpp errorlogger.hpp graph.hpp helpers.hpp info.hpp leastsquaremin.hpp linkedcell.hpp lists.hpp log.hpp logger.hpp memoryallocator.hpp memoryusageobserver.hpp molecule.hpp molecule_template.hpp parser.hpp periodentafel.hpp stackclass.hpp tesselation.hpp tesselationhelpers.hpp vector.hpp verbose.hpp World.hpp
     103#SOURCE = ${ANALYSISSOURCE} ${ATOMSOURCE} ${PATTERNSOURCE}  ${DESCRIPTORSOURCE}  bond.cpp bondgraph.cpp boundary.cpp config.cpp element.cpp ellipsoid.cpp errorlogger.cpp graph.cpp helpers.cpp info.cpp leastsquaremin.cpp linkedcell.cpp lists.cpp log.cpp logger.cpp memoryusageobserver.cpp moleculelist.cpp molecule.cpp molecule_dynamics.cpp molecule_fragmentation.cpp molecule_geometry.cpp molecule_graph.cpp molecule_pointcloud.cpp parser.cpp periodentafel.cpp tesselation.cpp tesselationhelpers.cpp vector.cpp verbose.cpp World.cpp WorldIterators.cpp
     104#HEADER = ${ANALYSISHEADER} ${ATOMHEADER} ${PATTERNHEADER} ${ACTIONSHEADER} ${DESCRIPTORHEADER} ${LEGACYHEADER} bond.hpp bondgraph.hpp boundary.hpp config.hpp defs.hpp element.hpp ellipsoid.hpp errorlogger.hpp graph.hpp helpers.hpp info.hpp leastsquaremin.hpp linkedcell.hpp lists.hpp log.hpp logger.hpp memoryallocator.hpp memoryusageobserver.hpp molecule.hpp molecule_template.hpp parser.hpp periodentafel.hpp stackclass.hpp tesselation.hpp tesselationhelpers.hpp vector.hpp verbose.hpp World.hpp
     105
     106SOURCE = ${ANALYSISSOURCE} \
     107                 ${ATOMSOURCE} \
     108                 ${PATTERNSOURCE} \
     109                 ${ACTIONSSOURCE} \
     110                 ${DESCRIPTORSOURCE} \
     111                 ${LEGACYSOURCE} \
     112                 bond.cpp \
     113                 bondgraph.cpp \
     114                 boundary.cpp \
     115                 config.cpp \
     116                 element.cpp \
     117                 ellipsoid.cpp \
     118                 errorlogger.cpp \
     119                 graph.cpp \
     120                 helpers.cpp \
     121                 Helpers/Assert.cpp \
     122                 info.cpp \
     123                 leastsquaremin.cpp \
     124                 linkedcell.cpp \
     125                 lists.cpp \
     126                 log.cpp \
     127                 logger.cpp \
     128                 memoryusageobserver.cpp \
     129                 moleculelist.cpp \
     130                 molecule.cpp \
     131                 molecule_dynamics.cpp \
     132                 molecule_fragmentation.cpp \
     133                 molecule_geometry.cpp \
     134                 molecule_graph.cpp \
     135                 molecule_pointcloud.cpp \
     136                 parser.cpp \
     137                 periodentafel.cpp \
     138                 tesselation.cpp \
     139                 tesselationhelpers.cpp \
     140                 vector.cpp \
     141                 verbose.cpp \
     142                 World.cpp
     143
     144HEADER = ${ANALYSISHEADER}\
     145         ${ATOMHEADER} \
     146         ${PATTERNHEADER} \
     147         ${DESCRIPTORHEADER} \
     148         ${LEGACYHEADER} \
     149         bond.hpp \
     150         bondgraph.hpp \
     151         boundary.hpp \
     152         config.hpp \
     153         defs.hpp \
     154         element.hpp \
     155         ellipsoid.hpp \
     156         errorlogger.hpp \
     157         graph.hpp \
     158         helpers.hpp \
     159         info.hpp \
     160         leastsquaremin.hpp \
     161         linkedcell.hpp \
     162         lists.hpp \
     163         log.hpp \
     164         logger.hpp \
     165         memoryallocator.hpp \
     166         memoryusageobserver.hpp \
     167         molecule.hpp \
     168         molecule_template.hpp \
     169         parser.hpp \
     170         periodentafel.hpp \
     171         stackclass.hpp \
     172         tesselation.hpp \
     173         tesselationhelpers.hpp \
     174         vector.hpp \
     175         verbose.hpp \
     176         World.hpp
    86177
    87178BOOST_LIB = $(BOOST_LDFLAGS) $(BOOST_MPL_LIB)
  • src/Menu/TextMenu.cpp

    rcd032d r68d781  
    1111#include "Menu/TextMenu.hpp"
    1212#include "Menu/MenuItem.hpp"
     13#include "Helpers/Assert.hpp"
    1314
    1415
     
    8889}
    8990
     91string TextMenu::getTitle(){
     92  return title;
     93}
     94
    9095void TextMenu::addDefault(MenuItem* _defaultItem) {
    9196  defaultItem = _defaultItem;
    9297}
     98
     99/****************************** Contained Actions ****************/
     100
     101const string TextMenu::LeaveAction::nameBase = "Leave menu: ";
     102
     103TextMenu::LeaveAction::LeaveAction(TextMenu* _menu) :
     104Action(nameBase+_menu->getTitle()),
     105menu(_menu)
     106{}
     107
     108TextMenu::LeaveAction::~LeaveAction(){}
     109
     110bool TextMenu::LeaveAction::canUndo(){
     111  return false;
     112}
     113
     114bool TextMenu::LeaveAction::shouldUndo(){
     115  return false;
     116}
     117
     118Action::state_ptr TextMenu::LeaveAction::performCall(){
     119  menu->doQuit();
     120  return Action::success;
     121}
     122
     123
     124Action::state_ptr TextMenu::LeaveAction::performUndo(Action::state_ptr){
     125  ASSERT(0,"Cannot undo leaving a menu");
     126  return Action::success;
     127}
     128
     129Action::state_ptr TextMenu::LeaveAction::performRedo(Action::state_ptr){
     130  ASSERT(0,"Cannot redo leaving a menu");
     131  return Action::success;
     132}
  • src/Menu/TextMenu.hpp

    rcd032d r68d781  
    1414
    1515#include "Menu/Menu.hpp"
     16#include "Actions/Action.hpp"
    1617#include "defs.hpp"
    1718
     
    2627{
    2728public:
     29  class LeaveAction : public Action {
     30  public:
     31    LeaveAction(TextMenu*);
     32    virtual ~LeaveAction();
     33
     34    bool canUndo();
     35    bool shouldUndo();
     36
     37  private:
     38    virtual Action::state_ptr performCall();
     39    virtual Action::state_ptr performUndo(Action::state_ptr);
     40    virtual Action::state_ptr performRedo(Action::state_ptr);
     41
     42    TextMenu* menu;
     43
     44    static const string nameBase;
     45  };
     46
    2847  TextMenu(ostream& _outputter, string _title, char _spacer=STD_MENU_TITLE_SPACER,int _length=STD_MENU_LENGTH);
    2948  virtual ~TextMenu();
     
    3251  virtual void removeItem(MenuItem*);
    3352  virtual void display();
     53  virtual string getTitle();
    3454
    3555  /**
  • src/Patterns/Cacheable.hpp

    rcd032d r68d781  
    1111#include "Patterns/Observer.hpp"
    1212#include <boost/function.hpp>
     13#include <boost/shared_ptr.hpp>
     14#include <iostream>
     15
     16#include "Helpers/Assert.hpp"
    1317
    1418#ifndef NO_CACHING
     
    1721  class Cacheable : public Observer
    1822  {
     23    // we define the states of the cacheable so we can do very fast state-checks
     24    class State{
     25    public:
     26      State(Cacheable *_owner) :
     27        busy(false),
     28        owner(_owner)
     29        {}
     30      virtual T getValue()=0;
     31      virtual void invalidate()=0;
     32      virtual bool isValid()=0;
     33      virtual void enter()=0;
     34      bool isBusy(){
     35        return busy;
     36      }
     37    protected:
     38      bool busy;
     39      Cacheable *owner;
     40    };
     41
     42    class InvalidState : public State{
     43    public:
     44      InvalidState(Cacheable *_owner):
     45        State(_owner)
     46        {}
     47
     48      virtual T getValue(){
     49        // set the state to valid
     50        State::owner->switchState(State::owner->validState);
     51        // get the value from the now valid state
     52        return State::owner->state->getValue();
     53      }
     54
     55      virtual void invalidate(){
     56        // nothing to do on this message
     57      }
     58
     59      virtual bool isValid(){
     60        return false;
     61      }
     62
     63      virtual void enter(){
     64        // nothing to do when entering this
     65      }
     66    };
     67
     68    class ValidState : public State{
     69    public:
     70      ValidState(Cacheable *_owner) :
     71        State(_owner)
     72        {}
     73
     74      virtual T getValue(){
     75        return content;
     76      }
     77
     78      virtual void invalidate(){
     79        State::owner->switchState(State::owner->invalidState);
     80      }
     81
     82      virtual bool isValid(){
     83        return true;
     84      }
     85
     86      virtual void enter(){
     87        State::busy= true;
     88        // as soon as we enter the valid state we recalculate
     89        content = State::owner->recalcMethod();
     90        State::busy = false;
     91      }
     92    private:
     93      T content;
     94    };
     95
     96    class DestroyedState : public State {
     97    public:
     98      DestroyedState(Cacheable *_owner) :
     99        State(_owner)
     100        {}
     101
     102      virtual T getValue(){
     103        ASSERT(0,"Cannot get a value from a Cacheable after it's Observable has died");
     104        // we have to return a grossly invalid reference, because no value can be produced anymore
     105        return *(static_cast<T*>(0));
     106      }
     107
     108      virtual void invalidate(){
     109        ASSERT(0,"Cannot invalidate a Cacheable after it's Observable has died");
     110      }
     111
     112      virtual bool isValid(){
     113        ASSERT(0,"Cannot check validity of a Cacheable after it's Observable has died");
     114        return false;
     115      }
     116
     117      virtual void enter(){
     118        // nothing to do when entering this state
     119      }
     120    };
     121
     122
     123  typedef boost::shared_ptr<State> state_ptr;
     124
    19125  public:
    20126    Cacheable(Observable *_owner, boost::function<T()> _recalcMethod);
    21127    virtual ~Cacheable();
    22128
    23     const bool isValid();
    24     const T& operator*();
    25     const bool operator==(const T&);
    26     const bool operator!=(const T&);
     129    const bool isValid() const;
     130    const T operator*() const;
    27131
    28132    // methods implemented for base-class Observer
     
    30134    void subjectKilled(Observable *subject);
    31135  private:
    32     void checkValid();
    33 
    34     T content;
     136
     137    void switchState(state_ptr newState);
     138
     139    mutable state_ptr state;
     140    // pre-defined state so we don't have to construct to much
     141    state_ptr invalidState;
     142    state_ptr validState;
     143    // destroyed state is not predefined, because we rarely enter that state and never leave
     144
    35145    Observable *owner;
    36     bool valid;
    37     bool canBeUsed;
     146
    38147    boost::function<T()> recalcMethod;
     148
     149    // de-activated copy constructor
     150    Cacheable(const Cacheable&);
    39151  };
    40152
     
    43155  Cacheable<T>::Cacheable(Observable *_owner, boost::function<T()> _recalcMethod) :
    44156    owner(_owner),
    45     valid(false),
    46     canBeUsed(true),
    47157    recalcMethod(_recalcMethod)
    48158  {
     159    // create all states needed for this object
     160    invalidState = state_ptr(new InvalidState(this));
     161    validState = state_ptr(new ValidState(this));
     162    state = invalidState;
    49163    // we sign on with the best(=lowest) priority, so cached values are recalculated before
    50164    // anybody else might ask for updated values
     
    52166  }
    53167
    54   template<typename T>
    55   const T& Cacheable<T>::operator*(){
    56     checkValid();
    57     return content;
    58   }
    59 
    60   template<typename T>
    61   const bool Cacheable<T>::operator==(const T& rval){
    62     checkValid();
    63     return (content == rval);
    64   }
    65 
    66   template<typename T>
    67   const bool Cacheable<T>::operator!=(const T& rval){
    68     checkValid();
    69     return (content != rval);
     168  // de-activated copy constructor
     169  template<typename T>
     170  Cacheable<T>::Cacheable(const Cacheable&){
     171    ASSERT(0,"Cacheables should never be copied");
     172  }
     173
     174  template<typename T>
     175  const T Cacheable<T>::operator*() const{
     176    // we can only use the cacheable when the owner is not changing at the moment
     177    if(!owner->isBlocked()){
     178      return state->getValue();
     179    }
     180    else{
     181      return recalcMethod();
     182    }
    70183  }
    71184
     
    77190
    78191  template<typename T>
    79   const bool Cacheable<T>::isValid(){
    80     return valid;
     192  const bool Cacheable<T>::isValid() const{
     193    return state->isValid();
    81194  }
    82195
    83196  template<typename T>
    84197  void Cacheable<T>::update(Observable *subject) {
    85     valid = false;
     198    state->invalidate();
    86199  }
    87200
    88201  template<typename T>
    89202  void Cacheable<T>::subjectKilled(Observable *subject) {
    90     valid = false;
    91     canBeUsed = false;
    92   }
    93 
    94   template<typename T>
    95   void Cacheable<T>::checkValid(){
    96     assert(canBeUsed && "Cacheable used after owner was deleted");
    97     if(!isValid()){
    98       content = recalcMethod();
    99     }
    100   }
     203    state_ptr destroyed = state_ptr(new DestroyedState(this));
     204    switchState(destroyed);
     205  }
     206
     207  template<typename T>
     208  void Cacheable<T>::switchState(state_ptr newState){
     209    ASSERT(!state->isBusy(),"LOOP DETECTED: Cacheable state switched while recalculating.\nDid the recalculation trigger the Observable?");
     210    state = newState;
     211    state->enter();
     212  }
     213
    101214#else
    102215  template<typename T>
     
    107220    virtual ~Cacheable();
    108221
    109     const bool isValid();
    110     const T& operator*();
    111     const bool operator==(const T&);
    112     const bool operator!=(const T&);
     222    const bool isValid() const;
     223    const T operator*() const;
    113224
    114225    // methods implemented for base-class Observer
     
    126237
    127238  template<typename T>
    128   const T& Cacheable<T>::operator*(){
     239  const T Cacheable<T>::operator*() const{
    129240    return recalcMethod();
    130   }
    131 
    132   template<typename T>
    133   const bool Cacheable<T>::operator==(const T& rval){
    134     return (recalcMethod() == rval);
    135   }
    136 
    137   template<typename T>
    138   const bool Cacheable<T>::operator!=(const T& rval){
    139     return (recalcMethod() != rval);
    140241  }
    141242
     
    145246
    146247  template<typename T>
    147   const bool Cacheable<T>::isValid(){
     248  const bool Cacheable<T>::isValid() const{
    148249    return true;
    149250  }
     
    151252  template<typename T>
    152253  void Cacheable<T>::update(Observable *subject) {
    153     assert(0 && "Cacheable::update should never be called when caching is disabled");
    154   }
    155 
    156   template<typename T>
    157   void Cacheable<T>::subjectKilled(Observable *subject) {
    158     assert(0 && "Cacheable::subjectKilled should never be called when caching is disabled");
     254    ASSERT(0, "Cacheable::update should never be called when caching is disabled");
     255  }
     256
     257  template<typename T>
     258  void Cacheable<T>::subjectKilled(Observable *subject){
     259    ASSERT(0, "Cacheable::subjectKilled should never be called when caching is disabled");
    159260  }
    160261#endif
  • src/Patterns/Observer.cpp

    rcd032d r68d781  
    1010
    1111#include <iostream>
    12 #include <cassert>
     12
     13#include "Helpers/Assert.hpp"
    1314
    1415using namespace std;
     
    127128    // observers, but still we are called by one of our sub-Observables
    128129    // we cannot be sure observation will still work at this point
    129     cerr << "Circle detected in observation-graph." << endl;
    130     cerr << "Observation-graph always needs to be a DAG to work correctly!" << endl;
    131     cerr << "Please check your observation code and fix this!" << endl;
     130    ASSERT(0,"Circle detected in observation-graph.\n"
     131             "Observation-graph always needs to be a DAG to work correctly!\n"
     132             "Please check your observation code and fix this!\n");
    132133    return;
    133134  }
     
    148149 */
    149150void Observable::signOn(Observer *target,int priority) {
    150   assert(priority>=-20 && priority<=+20 && "Priority out of range [-20:+20]");
     151  ASSERT(priority>=-20 && priority<=+20, "Priority out of range [-20:+20] when signing on Observer");
    151152  bool res = false;
    152153  callees_t *callees = 0;
     
    172173 */
    173174void Observable::signOff(Observer *target) {
    174   assert(callTable.count(this) && "SignOff called for an Observable without Observers.");
     175  ASSERT(callTable.count(this),"SignOff called for an Observable without Observers.");
    175176  callees_t *callees = callTable[this];
    176177  callees_t::iterator iter;
     
    188189    delete callees;
    189190  }
     191}
     192
     193bool Observable::isBlocked(){
     194  return depth.count(this) > 0;
    190195}
    191196
  • src/Patterns/Observer.hpp

    rcd032d r68d781  
    9595  virtual void signOff(Observer *target);
    9696
     97  /**
     98   * Ask an Observer if it is currently in a blocked state, i.e. if
     99   * Changes are in Progress, that are not yet published.
     100   */
     101  virtual bool isBlocked();
     102
    97103protected:
    98104  virtual void update(Observable *publisher);
     
    119125  static std::set<Observable*> busyObservables;
    120126
     127  //! @cond
    121128  // Structure for RAII-Style notification
    122129protected:
     
    133140    Observable *protege;
    134141  };
     142  //! @endcond
    135143};
    136144
  • src/Patterns/Singleton.hpp

    rcd032d r68d781  
    1616/**
    1717 * This template produces the generic singleton pattern using the CRTP idiom.
     18 *
     19 * <h1> Singleton Howto </h1>
     20 * <h2> Introduction </h2>
     21 *
     22 * A Singleton is a class of which there can only be a single Object in the programm. It is
     23 * described as an design-pattern in Gof:96 (the famous design-pattern book). In the
     24 * molecuilder there are so far several Singletons serving a wide range of purposes:
     25 *
     26 * - the World, which handles all atoms, molecules and bonds
     27 * - the ActionRegistry, which stores all created actions by name for later use
     28 * - the UIFactory, which is an AbstractFactory (another design-pattern from Gof:96) and
     29 *   handles all creation of gui elements to ensure a single type throughout the programm
     30 * - the logger and errorLogger classes, that can be used to output messages on the screen
     31 *   depending on certain conditions
     32 *
     33 * Because those classes can only be instantiated once you cannot simply call <code>new World()</code>
     34 * or <code>delete</code> on them. Rather they have to be constructed and accessed using the singleton
     35 * mechanism. This mechanism consists of four static functions (and a fifth that is used internally,
     36 * but we will get to that later). These functions are:
     37 *
     38 * - <code>Singleton& Singleton::getInstance()</code> : returns the instance of the singleton as
     39 *    a reference
     40 * - <code>Singleton* Singleton::getPointer()</code> : returns the instance of the singleton as a
     41 *    pointer
     42 * - <code>void Singleton::purgeInstance()</code> : destroys the single Instance of the singleton
     43 * - <code>Singleton& Singleton::resetInstance()</code> : resets the Singleton, i.e. destroys the
     44 *    old instance and creates a new one
     45 *
     46 * If you need the instance of the singleton it is usually fine just to use one off the accessor
     47 * functions (i.e. <code>getInstance()</code> or <code>getPointer()</code>. Any creation of the
     48 * Singleton is then handled by these functions, so that the same object will be returned whenever
     49 * one of these functions is called. This easy process is true for most singletons you will need
     50 * to use. The only special singleton is the UIFactory.
     51 *
     52 * <h3>Special functions of the UIFactory</h3>
     53 *
     54 * If you simply call the <code>getInstance()</code> method of the UIFactory class the program
     55 * will crash. This happens, because the UIFactory in itself is abstract and needs to know what
     56 * kind of user interface it should produce later on. You need to tell the class the type of UI
     57 * using the void <code>UIFactory::makeUserInterface(InterfaceTypes type)</code> method. This will
     58 * also take care of creating the sole instance, so that the accessor functions will work afterwards.
     59 * What this also means is, that you cannot <code>reset()</code> the UIFactory, because at that
     60 * point it wont know anymore what to construct. A sequence of <code>UIFactory::purgeInstance()</code>,
     61 * <code>UIFactory::makeUserInterface()</code> and <code>UIFactory::getInstance()</code> will work
     62 * though.
     63 *
     64 * In order to make life easier and propagate changes to the singleton mechanism to all those
     65 * classes, there is a simple framework class that can be used to make any other class a
     66 * singleton through inheritance. This class can be found in the Pattern directory.
     67 *
     68 * <h2>How to make a class Singleton</h2>
     69 *
     70 * Most of the time you will only need singletons that don't require additional
     71 * information for creation. So I will cover the basic case for constructing singletons
     72 * first and then explain what has to be changed to make it accept special parameters.
     73 * Singletons are created by inheriting from the <code>Singleton<class T></code> template
     74 * using the Curiously recurring template pattern (CRTP). What this means is, that the
     75 * class they inherit from carries the inheriting class as a template parameter. For example
     76 * <code>class MySingletonExaple : public Singleton<MySingletonExample>{...}</code>. If you
     77 * want to know more about this idiom have a look at the
     78 * <A HREF="http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern">wikipedia
     79 * page for this idiom</A>, but don't worry if you don't quite get how this works for now, for
     80 * the use of the singleton framework this is not important.
     81 *
     82 * If you want to make a class a singleton you can use the following sequence of steps.
     83 *
     84 * - Inherit from the singleton pattern using the CRTP as above:<br>
     85 *   @code
     86 *     class MySingletonExaple : public Singleton<MySingletonExample>{ ...}
     87 *   @endcode
     88 * - Make constructor and destructor private to avoid creation or destruction from
     89 *   outside the class:<br>
     90 *    @code
     91 *      class MySingletonExaple : public Singleton<MySingletonExample>{
     92 *        private:
     93 *          MySingletonExample();
     94 *          ~MySingletonExample();
     95 *      ...}
     96 *    @endcode
     97 * - give the inherited class access to the class internals using a friend declaration:<br>
     98 *    @code
     99 *       class MySingletonExaple : public Singleton<MySingletonExample>{
     100 *         friend class Singleton<MySingletonExample>; // don't forget the template parameters here
     101 *         private:
     102 *           MySingletonExample();
     103 *           ~MySingletonExample();
     104 *       ...}
     105 *    @endcode
     106 *
     107 * - include the file "Patterns/Singleton_impl.hpp" that carries the implementation details of
     108 *   the singleton functions in your implementation file of the class.
     109 * - make the compiler construct the template instantiations. For this you can use the defined
     110 *   keyword <code>CONSTRUCT_SINGLETON(name)</code> at any toplevel point in the implementation
     111 *   file:<br>
     112 *    @code
     113 *       void MySingletonExample::foo(){...}
     114 *       void MySingletonExample::bar(){...}
     115 *       CONSTRUCT_SINGLETON(MySingletonExample) // no ; after this
     116 *     @endcode
     117 *
     118 * <h3>Singleton with initialization parameters</h3>
     119 *
     120 * Sometimes it is necessary for a singleton to be passed some initilization parameters. For
     121 * example the UIFactory mentioned above needs to know what kind of user interface it has to
     122 * produce. Making a singleton that takes initialization parameters is only sligtly different
     123 * from the steps lined out above. Here are all the differences:
     124 *
     125 * - pass an extra <code>false</code> to the template to deactivate the standard instantiation
     126 *   mechanism
     127 * - write a method that handles the special parameters and instantiation. In this method you
     128 *   can use the <code>setInstance(T*)</code> method inherited from the singleton pattern to set
     129 *   the created instance. The <code>setInstance()</code> method will only work when the
     130 *   <code>false<code> template parameter has been set and produce errors otherwise.
     131 *
    18132 */
    19133template <class T, bool _may_create=true>
     
    21135{
    22136private:
    23   // simple auto_ptr that allows destruction of the object
    24   // std::auto_ptr cannot do this because the destructor of T is ussually private
     137  /**
     138   * simple auto_ptr that is used by Singleton template
     139   *
     140   * This ptr_t allows destruction of the object using a private destructor,
     141   * when only the Singleton pattern is friend with the class
     142   *
     143   * All methods have similar sematics to auto_ptr
     144   */
    25145  class ptr_t {
    26146  public:
     
    32152    void reset(T* _content);
    33153    void reset();
    34     ptr_t& operator=(ptr_t& rhs);
     154    ptr_t& operator=(const ptr_t& rhs);
    35155  private:
    36     T* content;
    37   };
    38 
    39   /**
    40    * this creator checks what it may or may not do
     156    mutable T* content;
     157  };
     158
     159  /**
     160   * This object handles the actual creation inside the singleton
     161   *
     162   * Using template specialization this will allways know what it can
     163   * do or cannot do at compile time
    41164   */
    42165  template<class creator_T, bool creator_may_create>
    43166  struct creator_t {
    44     static creator_T* make();
    45     static void set(creator_T*&,creator_T*);
     167    inline static creator_T* make();
     168    inline static void set(creator_T*&,creator_T*);
    46169  };
    47170
    48171  // specialization to allow fast creations
    49172
     173  /**
     174   * Specialized template that allows automatic construction only
     175   */
    50176  template<class creator_T>
    51177  struct creator_t<creator_T,true>{
    52     static creator_T* make(){
     178    inline static creator_T* make(){
    53179      return new creator_T();
    54180    }
    55181
    56     static void set(creator_T*&,creator_T*){
     182    inline static void set(creator_T*&,creator_T*){
    57183      assert(0 && "Cannot set the Instance for a singleton of this type");
    58184    }
    59185  };
    60186
     187  /**
     188   * specialized template that allows setting only
     189   */
    61190  template<class creator_T>
    62191  struct creator_t<creator_T,false>{
    63     static creator_T* make(){
     192    inline static creator_T* make(){
    64193      assert(0 && "Cannot create a singleton of this type directly");
    65194    }
    66     static void set(ptr_t& dest,creator_T* src){
     195    inline static void set(ptr_t& dest,creator_T* src){
    67196      dest.reset(src);
    68197    }
    69198  };
    70199
     200  // this is used for creation
     201  typedef creator_t<T,_may_create> creator; //< the creator used
     202
    71203public:
    72 
    73204  // make the state of this singleton accessible
    74   static const bool may_create=_may_create;
    75 
    76   // this is used for creation
    77   typedef creator_t<T,_may_create> creator;
    78 
     205  static const bool may_create=_may_create; //!< the type of singleton that we have
     206
     207  /**
     208   * returns the instance of this Singleton as a reference
     209   *
     210   * If no Singleton exists at this point and we are allowed to create one
     211   * a new one is created and stored inside the singleton
     212   *
     213   * If no automatic creation is allowed, make sure to create an instance first
     214   * using the appropriate methods of the derived class. Otherwise this method
     215   * would fail.
     216   */
    79217  static T& getInstance();
     218
     219  /**
     220   * returns the instance of this singleton as a pointer
     221   *
     222   * If no Singleton exists at this point and we are allowed to create one
     223   * a new one is created and stored inside the singleton.
     224   *
     225   * If no automatic creation is allowed, make sure to create an instance first
     226   * using the appropriate methods of the derived class. Otherwise this method
     227   * would fail.
     228   */
    80229  static T* getPointer();
    81230
     231  /**
     232   * destroys the current instance of this singleton
     233   */
    82234  static void purgeInstance();
     235
     236  /**
     237   * destroys the current instance of the singleton and immidiately constructs
     238   * a new one. Similar to using <code>purgeInstance()</code> and <code>getInstance()</code>
     239   * but plays more nicely when observers are present. Especially the new instance is created
     240   * before the old one is destroyed so observers can switch their targets, when they are notified
     241   * of the destruction.
     242   *
     243   * If no automatic creation is allowed this method wont work.
     244   */
    83245  static T&   resetInstance();
    84246
     247protected:
     248  /**
     249   * Method used to set the instance, when no automatic creation is allowed.
     250   *
     251   * Call this after the instantiation method in the derived class has created
     252   * it's instance and want's the singleton mechanism to keep it around for later
     253   * use.
     254   *
     255   * This method will always fail when automatic creation is enabled.
     256   */
    85257  static void setInstance(T*);
    86 protected:
     258
     259
     260  /**
     261   * empty constructor to allow creation of subclases
     262   */
     263  Singleton();
    87264
    88265private:
    89   static boost::recursive_mutex instanceLock;
    90   static ptr_t theInstance;
     266  /**
     267   * the copy constructor is private to avoid accidental copying of Singletons, for example
     268   * when passing singletons to functions by value instead of by reference. If you
     269   * need copying of singletons call the default constructor in the copy constructor
     270   * of the derived object. The copyied object wont be known to the singleton mechanism.
     271   */
     272  Singleton(const Singleton&);
     273
     274  static boost::recursive_mutex instanceLock; //!< a lock for the pointer of the instance
     275  static ptr_t theInstance; //!< the actual instance of the singleton
    91276};
    92277
  • src/Patterns/Singleton_impl.hpp

    rcd032d r68d781  
    7777}
    7878
     79template<class T, bool _may_create>
     80Singleton<T,_may_create>::Singleton(){/* empty */}
     81
     82// private copy constructor to avoid unintended copying
     83template <class T, bool _may_create>
     84Singleton<T,_may_create>::Singleton(const Singleton<T,_may_create>&){
     85  assert(0 && "Copy constructor of singleton template called");
     86}
     87
    7988/**
    8089 * This define allows simple instantiation of the necessary singleton functions
     
    121130
    122131template <class T,bool _may_create>
    123 typename Singleton<T,_may_create>::ptr_t& Singleton<T,_may_create>::ptr_t::operator=(typename Singleton<T,_may_create>::ptr_t& rhs){
     132typename Singleton<T,_may_create>::ptr_t& Singleton<T,_may_create>::ptr_t::operator=(const typename Singleton<T,_may_create>::ptr_t& rhs){
    124133  if(&rhs!=this){
    125134    delete content;
  • src/UIElements/Dialog.cpp

    rcd032d r68d781  
    148148
    149149// Element Queries
    150 Dialog::ElementQuery::ElementQuery(std::string title, element **_target) :
     150Dialog::ElementQuery::ElementQuery(std::string title, const element **_target) :
    151151  Query(title),
    152   target(_target),
    153   tmp(0)
     152  tmp(0),
     153  target(_target)
    154154  {}
    155155
  • src/UIElements/Dialog.hpp

    rcd032d r68d781  
    2828  virtual void queryMolecule(const char*,molecule**,MoleculeListClass*)=0;
    2929  virtual void queryVector(const char*,Vector *,const double *const,bool)=0;
    30   virtual void queryElement(const char*,element **)=0;
     30  virtual void queryElement(const char*,const element **)=0;
    3131
    3232  virtual bool display();
     
    126126  class ElementQuery : public Query {
    127127  public:
    128     ElementQuery(std::string title, element**_target);
     128    ElementQuery(std::string title, const element**_target);
    129129    virtual ~ElementQuery();
    130130    virtual bool handle()=0;
    131131    virtual void setResult();
    132132  protected:
    133     element *tmp;
     133    const element *tmp;
    134134  private:
    135     element **target;
     135    const element **target;
    136136  };
    137137
  • src/UIElements/QT4/QTDialog.cpp

    rcd032d r68d781  
    9898}
    9999
    100 void QTDialog::queryElement(const char* title, element **target){
     100void QTDialog::queryElement(const char* title, const element **target){
    101101  registerQuery(new ElementQTQuery(title,target,inputLayout,this));
    102102}
     
    262262
    263263
    264 QTDialog::ElementQTQuery::ElementQTQuery(std::string _title, element **_target, QBoxLayout *_parent, QTDialog *_dialog) :
     264QTDialog::ElementQTQuery::ElementQTQuery(std::string _title, const element **_target, QBoxLayout *_parent, QTDialog *_dialog) :
    265265    Dialog::ElementQuery(_title,_target),
    266266    parent(_parent)
     
    270270  titleLabel = new QLabel(QString(getTitle().c_str()));
    271271  inputBox = new QComboBox();
    272   element* Elemental = 0;
    273   for(Elemental = periode->start->next;
    274       Elemental!=periode->end;
    275       Elemental = Elemental->next)
     272  for(periodentafel::const_iterator iter = periode->begin();
     273      iter!=periode->end();
     274      ++iter)
    276275  {
    277276    stringstream sstr;
    278     sstr << Elemental->Z << "\t" << Elemental->name;
    279     inputBox->addItem(QString(sstr.str().c_str()),QVariant(Elemental->Z));
     277    sstr << (*iter).first << "\t" << (*iter).second->name;
     278    inputBox->addItem(QString(sstr.str().c_str()),QVariant((*iter).first));
    280279  }
    281280  parent->addLayout(thisLayout);
     
    355354}
    356355
    357 ElementQTQueryPipe::ElementQTQueryPipe(element **_content, QTDialog *_dialog, QComboBox *_theBox) :
     356ElementQTQueryPipe::ElementQTQueryPipe(const element **_content, QTDialog *_dialog, QComboBox *_theBox) :
    358357  content(_content),
    359358  dialog(_dialog),
  • src/UIElements/QT4/QTDialog.hpp

    rcd032d r68d781  
    4040  virtual void queryMolecule(const char*,molecule**,MoleculeListClass*);
    4141  virtual void queryVector(const char*,Vector *,const double *const,bool);
    42   virtual void queryElement(const char*,element **);
     42  virtual void queryElement(const char*,const element **);
    4343
    4444  virtual bool display();
     
    122122    class ElementQTQuery : public Dialog::ElementQuery {
    123123    public:
    124       ElementQTQuery(std::string _title, element **_target, QBoxLayout *_parent, QTDialog *_dialog);
     124      ElementQTQuery(std::string _title, const element **_target, QBoxLayout *_parent, QTDialog *_dialog);
    125125      virtual ~ElementQTQuery();
    126126      virtual bool handle();
     
    210210  Q_OBJECT
    211211public:
    212   ElementQTQueryPipe(element **_content, QTDialog *_dialog, QComboBox *_theBox);
     212  ElementQTQueryPipe(const element **_content, QTDialog *_dialog, QComboBox *_theBox);
    213213  virtual ~ElementQTQueryPipe();
    214214
     
    217217
    218218private:
    219   element **content;
     219  const element **content;
    220220  QTDialog *dialog;
    221221  QComboBox *theBox;
  • src/UIElements/TextDialog.cpp

    rcd032d r68d781  
    4949}
    5050
    51 void TextDialog::queryElement(const char* title, element **target){
     51void TextDialog::queryElement(const char* title, const element **target){
    5252  registerQuery(new ElementTextQuery(title,target));
    5353}
     
    125125
    126126
    127 TextDialog::ElementTextQuery::ElementTextQuery(std::string title, element **target) :
     127TextDialog::ElementTextQuery::ElementTextQuery(std::string title, const element **target) :
    128128    Dialog::ElementQuery(title,target)
    129129{}
  • src/UIElements/TextDialog.hpp

    rcd032d r68d781  
    2424  virtual void queryMolecule(const char*,molecule**,MoleculeListClass*);
    2525  virtual void queryVector(const char*,Vector *,const double * const,bool);
    26   virtual void queryElement(const char*,element **);
     26  virtual void queryElement(const char*,const element **);
    2727
    2828protected:
     
    6565  class ElementTextQuery : public Dialog::ElementQuery {
    6666  public:
    67     ElementTextQuery(std::string title, element **_target);
     67    ElementTextQuery(std::string title, const element **_target);
    6868    virtual ~ElementTextQuery();
    6969    virtual bool handle();
  • src/UIElements/TextWindow.cpp

    rcd032d r68d781  
    3939#include "Actions/MethodAction.hpp"
    4040#include "Actions/ErrorAction.hpp"
     41#include "Actions/ActionRegistry.hpp"
    4142#include "Views/StreamStringView.hpp"
    4243#include "Views/MethodStringView.hpp"
     
    5657  moleculeView = new StreamStringView(boost::bind(&MoleculeListClass::Enumerate,molecules,_1));
    5758  new DisplayMenuItem(main_menu,moleculeView,"Molecule List");
     59
     60  new SeperatorItem(main_menu);
     61
     62  Action* undoAction = ActionRegistry::getInstance().getActionByName("Undo");
     63  new ActionMenuItem('u',"Undo last operation",main_menu,undoAction);
     64
     65  Action* redoAction = ActionRegistry::getInstance().getActionByName("Redo");
     66  new ActionMenuItem('r',"Redo last operation",main_menu,redoAction);
    5867
    5968  new SeperatorItem(main_menu);
     
    94103  populaters.MakeEditMoleculesMenu(editMoleculesMenu,molecules,configuration,periode);
    95104
    96   returnFromEditMoleculeAction = new MethodAction("returnAction",boost::bind(&TextMenu::doQuit,editMoleculesMenu),false);
     105  Action *returnFromEditMoleculeAction = new TextMenu::LeaveAction(editMoleculesMenu);
    97106  MenuItem *returnItem = new ActionMenuItem('q',"return to Main menu",editMoleculesMenu,returnFromEditMoleculeAction);
    98107
     
    108117  delete old_menu;
    109118  delete quitAction;
    110   delete returnFromEditMoleculeAction;
    111119  delete moleculeView;
    112120  delete statusIndicator;
  • src/UIElements/TextWindow.hpp

    rcd032d r68d781  
    2929  // some actions only needed in textMenus
    3030  Action *quitAction;
    31   Action *returnFromEditMoleculeAction;
    3231  // all views that are contained in the main Menu
    3332  StringView *moleculeView;
  • src/World.cpp

    rcd032d r68d781  
    1515#include "Descriptors/MoleculeDescriptor.hpp"
    1616#include "Descriptors/MoleculeDescriptor_impl.hpp"
     17#include "Descriptors/SelectiveIterator_impl.hpp"
    1718#include "Actions/ManipulateAtomsProcess.hpp"
    1819
     
    209210/******************************* Iterators ********************************/
    210211
    211 /*
    212  * Actual Implementation of the iterators can be found in WorldIterators.cpp
    213  */
     212// Build the AtomIterator from template
     213CONSTRUCT_SELECTIVE_ITERATOR(atom*,World::AtomSet,AtomDescriptor);
     214
    214215
    215216World::AtomIterator World::getAtomIter(AtomDescriptor descr){
    216   return AtomIterator(descr,this);
    217 }
    218 
    219 World::AtomSet::iterator World::atomEnd(){
    220   return atoms.end();
    221 }
     217  return AtomIterator(descr,atoms);
     218}
     219
     220World::AtomIterator World::atomEnd(){
     221  return AtomIterator(AllAtoms(),atoms,atoms.end());
     222}
     223
     224// build the MoleculeIterator from template
     225CONSTRUCT_SELECTIVE_ITERATOR(molecule*,World::MoleculeSet,MoleculeDescriptor);
    222226
    223227World::MoleculeIterator World::getMoleculeIter(MoleculeDescriptor descr){
    224   return MoleculeIterator(descr,this);
    225 }
    226 
    227 World::MoleculeSet::iterator World::moleculeEnd(){
    228   return molecules.end();
     228  return MoleculeIterator(descr,molecules);
     229}
     230
     231World::MoleculeIterator World::moleculeEnd(){
     232  return MoleculeIterator(AllMolecules(),molecules,molecules.end());
    229233}
    230234
  • src/World.hpp

    rcd032d r68d781  
    1616#include <boost/shared_ptr.hpp>
    1717
    18 #include "defs.hpp"
     18#include "types.hpp"
     19#include "Descriptors/SelectiveIterator.hpp"
    1920#include "Patterns/Observer.hpp"
    2021#include "Patterns/Cacheable.hpp"
     
    160161
    161162  // Atoms
    162 
    163   class AtomIterator :
    164     public std::iterator<std::iterator_traits<AtomSet::iterator>::difference_type,
    165                          std::iterator_traits<AtomSet::iterator>::value_type,
    166                          std::iterator_traits<AtomSet::iterator>::pointer,
    167                          std::iterator_traits<AtomSet::iterator>::reference>
    168   {
    169   public:
    170 
    171     typedef AtomSet::iterator _Iter;
    172     typedef _Iter::value_type value_type;
    173     typedef _Iter::difference_type difference_type;
    174     typedef _Iter::pointer pointer;
    175     typedef _Iter::reference reference;
    176     typedef _Iter::iterator_category iterator_category;
    177 
    178 
    179     AtomIterator();
    180     AtomIterator(AtomDescriptor, World*);
    181     AtomIterator(const AtomIterator&);
    182     AtomIterator& operator=(const AtomIterator&);
    183     AtomIterator& operator++();     // prefix
    184     AtomIterator  operator++(int);  // postfix with dummy parameter
    185     bool operator==(const AtomIterator&);
    186     bool operator==(const AtomSet::iterator&);
    187     bool operator!=(const AtomIterator&);
    188     bool operator!=(const AtomSet::iterator&);
    189     atom* operator*();
    190 
    191     int getCount();
    192   protected:
    193     void advanceState();
    194     AtomSet::iterator state;
    195     boost::shared_ptr<AtomDescriptor_impl>  descr;
    196     int index;
    197 
    198     World* world;
    199   };
     163  typedef SelectiveIterator<atom*,AtomSet,AtomDescriptor> AtomIterator;
    200164
    201165  /**
     
    211175   * used for internal purposes, like AtomProcesses and AtomCalculations.
    212176   */
    213   AtomSet::iterator atomEnd();
     177  AtomIterator atomEnd();
    214178
    215179  // Molecules
    216180
    217   class MoleculeIterator :
    218     public std::iterator<std::iterator_traits<MoleculeSet::iterator>::difference_type,
    219                          std::iterator_traits<MoleculeSet::iterator>::value_type,
    220                          std::iterator_traits<MoleculeSet::iterator>::pointer,
    221                          std::iterator_traits<MoleculeSet::iterator>::reference>
    222   {
    223   public:
    224 
    225     typedef MoleculeSet::iterator _Iter;
    226     typedef _Iter::value_type value_type;
    227     typedef _Iter::difference_type difference_type;
    228     typedef _Iter::pointer pointer;
    229     typedef _Iter::reference reference;
    230     typedef _Iter::iterator_category iterator_category;
    231 
    232     MoleculeIterator();
    233     MoleculeIterator(MoleculeDescriptor, World*);
    234     MoleculeIterator(const MoleculeIterator&);
    235     MoleculeIterator& operator=(const MoleculeIterator&);
    236     MoleculeIterator& operator++();     // prefix
    237     MoleculeIterator  operator++(int);  // postfix with dummy parameter
    238     bool operator==(const MoleculeIterator&);
    239     bool operator==(const MoleculeSet::iterator&);
    240     bool operator!=(const MoleculeIterator&);
    241     bool operator!=(const MoleculeSet::iterator&);
    242     molecule* operator*();
    243 
    244     int getCount();
    245   protected:
    246     void advanceState();
    247     MoleculeSet::iterator state;
    248     boost::shared_ptr<MoleculeDescriptor_impl>  descr;
    249     int index;
    250 
    251     World* world;
    252   };
     181  typedef SelectiveIterator<molecule*,MoleculeSet,MoleculeDescriptor> MoleculeIterator;
    253182
    254183  /**
     
    264193   * used for internal purposes, like MoleculeProcesses and MoleculeCalculations.
    265194   */
    266   MoleculeSet::iterator moleculeEnd();
     195  MoleculeIterator moleculeEnd();
    267196
    268197
     
    277206
    278207  periodentafel *periode;
     208public:
    279209  AtomSet atoms;
     210private:
    280211  std::set<atomId_t> atomIdPool; //<!stores the pool for all available AtomIds below currAtomId
    281212  atomId_t currAtomId; //!< stores the next available Id for atoms
  • src/atom.hpp

    rcd032d r68d781  
    2828#include "atom_trajectoryparticle.hpp"
    2929#include "tesselation.hpp"
     30#include "types.hpp"
    3031
    3132/****************************************** forward declarations *****************************/
  • src/atom_atominfo.cpp

    rcd032d r68d781  
    2020};
    2121
    22 element *AtomInfo::getType(){
     22const element *AtomInfo::getType(){
    2323  return type;
    2424}
    2525
    26 void AtomInfo::setType(element* _type) {
     26void AtomInfo::setType(const element* _type) {
    2727  type = _type;
    2828}
    2929
    3030void AtomInfo::setType(int Z) {
    31   element *elem = World::getInstance().getPeriode()->FindElement(Z);
     31  const element *elem = World::getInstance().getPeriode()->FindElement(Z);
    3232  setType(elem);
    3333}
  • src/atom_atominfo.hpp

    rcd032d r68d781  
    3232  Vector v;       //!< velocity vector of atom, giving last velocity within cell
    3333  Vector F;       //!< Force vector of atom, giving last force within cell
    34   element *type;  //!< pointing to element
     34  const element *type;  //!< pointing to element
    3535
    3636  AtomInfo();
    3737  ~AtomInfo();
    3838
    39   element *getType();
    40   void setType(element *);
     39  const element *getType();
     40  void setType(const element *);
    4141  void setType(int);
    4242
  • src/builder.cpp

    rcd032d r68d781  
    7474#include "Menu/ActionMenuItem.hpp"
    7575#include "Actions/ActionRegistry.hpp"
     76#include "Actions/ActionHistory.hpp"
    7677#include "Actions/MethodAction.hpp"
    7778#include "Actions/small_actions.hpp"
     
    15941595                }
    15951596                LCList = new LinkedCell(Boundary, 2.*radius);
    1596                 element *elemental = periode->FindElement((const int) atoi(argv[argptr]));
     1597                const element *elemental = periode->FindElement((atomicNumber_t) atoi(argv[argptr]));
    15971598                FindNonConvexBorder(Boundary, TesselStruct, LCList, radius, NULL);
    15981599                int ranges[NDIM] = {1,1,1};
     
    20712072                  int faktor = atoi(argv[argptr++]);
    20722073                  int count;
    2073                   element ** Elements;
     2074                  const element ** Elements;
    20742075                  Vector ** vectors;
    20752076                  if (faktor < 1) {
    2076                     eLog() << Verbose(1) << "Repetition factor mus be greater than 1!" << endl;
     2077                    eLog() << Verbose(1) << "Repetition factor must be greater than 1!" << endl;
    20772078                    faktor = 1;
    20782079                  }
     
    20802081                  if (mol->AtomCount != 0) {  // if there is more than none
    20812082                    count = mol->AtomCount;   // is changed becausing of adding, thus has to be stored away beforehand
    2082                     Elements = new element *[count];
     2083                    Elements = new const element *[count];
    20832084                    vectors = new Vector *[count];
    20842085                    j = 0;
     
    21912192    char *ConfigFileName = NULL;
    21922193    int j;
     2194
    21932195    setVerbosity(0);
     2196    // need to init the history before any action is created
     2197    ActionHistory::init();
    21942198    /* structure of ParseCommandLineOptions will be refactored later */
    21952199    j = ParseCommandLineOptions(argc, argv,  World::getInstance().getMolecules(), World::getInstance().getPeriode(), *configuration, ConfigFileName);
  • src/config.cpp

    rcd032d r68d781  
    675675{
    676676  int MaxTypes = 0;
    677   element *elementhash[MAX_ELEMENTS];
     677  const element *elementhash[MAX_ELEMENTS];
    678678  char name[MAX_ELEMENTS];
    679679  char keyword[MAX_ELEMENTS];
     
    11071107  string zeile;
    11081108  string dummy;
    1109   element *elementhash[128];
     1109  const element *elementhash[128];
    11101110  int Z = -1;
    11111111  int No = -1;
  • src/defs.hpp

    rcd032d r68d781  
    3333enum Shading { white, lightgray, darkgray, black };  //!< color in Breadth-First-Search analysis
    3434
    35 // some types that can stay abstract
    36 typedef unsigned int moleculeId_t;
    37 typedef unsigned int atomId_t;
     35
    3836
    3937//enum CutCyclicBond { KeepBond,  SaturateBond }; //!< Saturation scheme either atom- or bondwise
  • src/element.cpp

    rcd032d r68d781  
    99
    1010#include "element.hpp"
     11
     12using namespace std;
    1113
    1214/************************************* Functions for class element **********************************/
     
    3537 * \param *out outstream
    3638 */
    37 bool element::Output(ofstream * const out) const
     39bool element::Output(ostream * const out) const
    3840{
    3941  if (out != NULL) {
     
    5052 * \param NoOfAtoms total number of atom of this element type
    5153 */
    52 bool element::Checkout(ofstream * const out, const int Number, const int NoOfAtoms) const
     54bool element::Checkout(ostream * const out, const int Number, const int NoOfAtoms) const
    5355{
    5456  if (out != NULL) {
     
    5860    return false;
    5961};
     62
     63atomicNumber_t element::getNumber() const{
     64  return Z;
     65}
     66
     67string element::getSymbol() const{
     68  return string(symbol);
     69}
  • src/element.hpp

    rcd032d r68d781  
    99#define ELEMENT_HPP_
    1010
    11 using namespace std;
    12 
    1311/*********************************************** includes ***********************************/
    1412
     
    1917
    2018#include <iostream>
     19#include <string>
    2120
    2221#include "defs.hpp"
     22#include "types.hpp"
    2323
    2424/********************************************** declarations *******************************/
     
    5050  ~element();
    5151
     52  // accessor functions
     53  atomicNumber_t getNumber() const;
     54  std::string getSymbol() const;
     55
    5256  //> print element entries to screen
    53   bool Output(ofstream * const out) const;
    54   bool Checkout(ofstream * const out, const int No, const int NoOfAtoms) const;
     57  bool Output(std::ostream * const out) const;
     58  bool Checkout(std::ostream * const out, const int No, const int NoOfAtoms) const;
    5559
    5660  private:
  • src/helpers.hpp

    rcd032d r68d781  
    189189#define PLURAL_S(v) (((v)==1)?"":"s")
    190190
     191// this is to allow different modes of access for
     192// maps and sets
     193template<typename Res,typename T>
     194struct _take{
     195  Res get(T value) const;
     196};
     197
     198// if we have a set,vector etc we can directly access the result
     199template<typename Res>
     200struct _take<Res,Res>{
     201  static inline Res get(Res value){
     202    return value;
     203  }
     204};
     205
     206// if we have a map we have to access the second part of
     207// the pair
     208template<typename Res,typename T1>
     209struct _take<Res,std::pair<T1,Res> >{
     210  static inline Res get(std::pair<T1,Res> value){
     211    return value.second;
     212  }
     213};
     214
    191215#endif /*HELPERS_HPP_*/
  • src/leastsquaremin.hpp

    rcd032d r68d781  
    4242  gsl_vector *x;
    4343  const molecule *mol;
    44   element *type;
     44  const element *type;
    4545};
    4646
  • src/molecule.cpp

    rcd032d r68d781  
    9999
    100100std::string molecule::calcFormula(){
    101   int Counts[MAX_ELEMENTS];
     101  std::map<atomicNumber_t,unsigned int> counts;
    102102  stringstream sstr;
    103   for (int j = 0; j<MAX_ELEMENTS;j++)
    104     Counts[j] = 0;
     103  periodentafel *periode = World::getInstance().getPeriode();
    105104  for(atom *Walker = start; Walker != end; Walker = Walker->next) {
    106     Counts[Walker->type->Z]++;
    107   }
    108   for(element* Elemental = elemente->end; Elemental != elemente->start; Elemental = Elemental->previous) {
    109     if (Counts[Elemental->Z] != 0)
    110       sstr << Elemental->symbol << Counts[Elemental->Z];
     105    counts[Walker->type->getNumber()]++;
     106  }
     107  std::map<atomicNumber_t,unsigned int>::reverse_iterator iter;
     108  for(iter = counts.rbegin(); iter != counts.rend(); ++iter) {
     109    atomicNumber_t Z = (*iter).first;
     110    sstr << periode->FindElement(Z)->symbol << (*iter).second;
    111111  }
    112112  return sstr.str();
  • src/molecule.hpp

    rcd032d r68d781  
    2929#include <string>
    3030
    31 #include "defs.hpp"
     31#include "types.hpp"
    3232#include "graph.hpp"
    3333#include "stackclass.hpp"
  • src/moleculelist.cpp

    rcd032d r68d781  
    141141void MoleculeListClass::Enumerate(ostream *out)
    142142{
    143   element* Elemental = NULL;
    144143  atom *Walker = NULL;
    145   int Counts[MAX_ELEMENTS];
     144  periodentafel *periode = World::getInstance().getPeriode();
     145  std::map<atomicNumber_t,unsigned int> counts;
    146146  double size=0;
    147147  Vector Origin;
     
    155155    Origin.Zero();
    156156    for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) {
    157       // reset element counts
    158       for (int j = 0; j<MAX_ELEMENTS;j++)
    159         Counts[j] = 0;
    160157      // count atoms per element and determine size of bounding sphere
    161158      size=0.;
     
    163160      while (Walker->next != (*ListRunner)->end) {
    164161        Walker = Walker->next;
    165         Counts[Walker->type->Z]++;
     162        counts[Walker->type->getNumber()]++;
    166163        if (Walker->x.DistanceSquared(&Origin) > size)
    167164          size = Walker->x.DistanceSquared(&Origin);
     
    169166      // output Index, Name, number of atoms, chemical formula
    170167      (*out) << ((*ListRunner)->ActiveFlag ? "*" : " ") << (*ListRunner)->IndexNr << "\t" << (*ListRunner)->name << "\t\t" << (*ListRunner)->AtomCount << "\t";
    171       Elemental = (*ListRunner)->elemente->end;
    172       while(Elemental->previous != (*ListRunner)->elemente->start) {
    173         Elemental = Elemental->previous;
    174         if (Counts[Elemental->Z] != 0)
    175           (*out) << Elemental->symbol << Counts[Elemental->Z];
     168
     169      std::map<atomicNumber_t,unsigned int>::reverse_iterator iter;
     170      for(iter=counts.rbegin(); iter!=counts.rend();++iter){
     171        atomicNumber_t Z =(*iter).first;
     172        (*out) << periode->FindElement(Z)->getSymbol() << (*iter).second;
    176173      }
    177174      // Center and size
     
    580577  stringstream line;
    581578  atom *Walker = NULL;
    582   element *runner = NULL;
     579  periodentafel *periode=World::getInstance().getPeriode();
    583580
    584581  // open file for the force factors
     
    590587    //output << prefix << "Forces" << endl;
    591588    for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) {
    592       runner = (*ListRunner)->elemente->start;
    593       while (runner->next != (*ListRunner)->elemente->end) { // go through every element
    594         runner = runner->next;
    595         if ((*ListRunner)->ElementsInMolecule[runner->Z]) { // if this element got atoms
     589      periodentafel::const_iterator elemIter;
     590      for(elemIter=periode->begin();elemIter!=periode->end();++elemIter){
     591          if ((*ListRunner)->ElementsInMolecule[(*elemIter).first]) { // if this element got atoms
    596592          Walker = (*ListRunner)->start;
    597593          while (Walker->next != (*ListRunner)->end) { // go through every atom of this element
    598594            Walker = Walker->next;
    599             if (Walker->type->Z == runner->Z) {
     595            if (Walker->type->getNumber() == (*elemIter).first) {
    600596              if ((Walker->GetTrueFather() != NULL) && (Walker->GetTrueFather() != Walker)) {// if there is a rea
    601597                //Log() << Verbose(0) << "Walker is " << *Walker << " with true father " << *( Walker->GetTrueFather()) << ", it
  • src/periodentafel.cpp

    rcd032d r68d781  
    1010#include <fstream>
    1111#include <cstring>
     12#include <cassert>
    1213
    1314#include "element.hpp"
     
    1819#include "verbose.hpp"
    1920
     21using namespace std;
     22
    2023/************************************* Functions for class periodentafel ***************************/
    2124
     
    2326 * Initialises start and end of list and resets periodentafel::checkliste to false.
    2427 */
    25 periodentafel::periodentafel() : start(new element), end(new element)
    26 {
    27   start->previous = NULL;
    28   start->next = end;
    29   end->previous = start;
    30   end->next = NULL;
    31 };
     28periodentafel::periodentafel()
     29{};
    3230
    3331/** destructor for class periodentafel
     
    3735{
    3836  CleanupPeriodtable();
    39   delete(end);
    40   delete(start);
    4137};
    4238
     
    4541 * \return true - succeeded, false - does not occur
    4642 */
    47 bool periodentafel::AddElement(element * const pointer)
    48 {
     43periodentafel::iterator periodentafel::AddElement(element * const pointer)
     44{
     45  atomicNumber_t Z = pointer->getNumber();
     46  assert(!elements.count(Z));
    4947  pointer->sort = &pointer->Z;
    50   if (pointer->Z < 1 && pointer->Z >= MAX_ELEMENTS)
     48  if (pointer->getNumber() < 1 && pointer->getNumber() >= MAX_ELEMENTS)
    5149    Log() << Verbose(0) << "Invalid Z number!\n";
    52   return add(pointer, end);
     50  pair<iterator,bool> res = elements.insert(pair<atomicNumber_t,element*>(Z,pointer));
     51  return res.first;
    5352};
    5453
     
    5756 * \return true - succeeded, false - element not found
    5857 */
    59 bool periodentafel::RemoveElement(element * const pointer)
    60 {
    61   return remove(pointer, start, end);
     58void periodentafel::RemoveElement(element * const pointer)
     59{
     60  atomicNumber_t Z = pointer->getNumber();
     61  elements.erase(Z);
    6262};
    6363
     
    6565 * \return true - succeeded, false - does not occur
    6666 */
    67 bool periodentafel::CleanupPeriodtable()
    68 {
    69   return cleanup(start,end);
     67void periodentafel::CleanupPeriodtable()
     68{
     69  for(iterator iter=elements.begin();iter!=elements.end();++iter){
     70    delete(*iter).second;
     71  }
     72  elements.clear();
    7073};
    7174
     
    7578 * \return pointer to element or NULL if not found
    7679 */
    77 element * const periodentafel::FindElement(const int Z) const
    78 {
    79   element *walker = find(&Z, start,end);
    80   return(walker);
     80const element * periodentafel::FindElement(atomicNumber_t Z) const
     81{
     82  const_iterator res = elements.find(Z);
     83  return res!=elements.end()?((*res).second):0;
    8184};
    8285
     
    8689 * \return pointer to element
    8790 */
    88 element * const periodentafel::FindElement(const char * const shorthand) const
    89 {
    90   element *walker =  periodentafel::start;
    91   while (walker->next != periodentafel::end) {
    92     walker = walker->next;
    93     if (strncmp(walker->symbol, shorthand, 3) == 0)
    94       return(walker);
    95   }
    96   return (NULL);
     91const element * periodentafel::FindElement(const char * const shorthand) const
     92{
     93  element *res = 0;
     94  for(const_iterator iter=elements.begin();iter!=elements.end();++iter) {
     95    if((*iter).second->getSymbol() == shorthand){
     96      res = (*iter).second;
     97      break;
     98    }
     99  }
     100  return res;
    97101};
    98102
    99103/** Asks for element number and returns pointer to element
    100104 */
    101 element * const periodentafel::AskElement() const
    102 {
    103   element *walker = NULL;
     105const element * periodentafel::AskElement() const
     106{
     107  const element *walker = NULL;
    104108  int Z;
    105109  do {
     
    114118 * \return pointer to either present or newly created element
    115119 */
    116 element * const periodentafel::EnterElement()
    117 {
    118   element *walker = NULL;
    119   int Z = -1;
     120const element * periodentafel::EnterElement()
     121{
     122  const element *res = NULL;
     123  atomicNumber_t Z = 0;
    120124  Log() << Verbose(0) << "Atomic number: " << Z << endl;
    121125  cin >> Z;
    122   walker = FindElement(Z);
    123   if (walker == NULL) {
     126  res = FindElement(Z);
     127  if (!res) {
     128    // TODO: make this using the constructor
     129    element *tmp;
    124130    Log() << Verbose(0) << "Element not found in database, please enter." << endl;
    125     walker = new element;
    126     walker->Z = Z;
     131    tmp = new element;
     132    tmp->Z = Z;
    127133    Log() << Verbose(0) << "Mass: " << endl;
    128     cin >> walker->mass;
     134    cin >> tmp->mass;
    129135    Log() << Verbose(0) << "Name [max 64 chars]: " << endl;
    130     cin >> walker->name;
     136    cin >> tmp->name;
    131137    Log() << Verbose(0) << "Short form [max 3 chars]: " << endl;
    132     cin >> walker->symbol;
    133     periodentafel::AddElement(walker);
    134   }
    135   return(walker);
    136 };
     138    cin >> tmp->symbol;
     139    AddElement(tmp);
     140    res = tmp;
     141  }
     142  return res;
     143};
     144
     145
     146/******************** Access to iterators ****************************/
     147periodentafel::const_iterator periodentafel::begin(){
     148  return elements.begin();
     149}
     150
     151periodentafel::const_iterator periodentafel::end(){
     152  return elements.end();
     153}
     154
     155periodentafel::reverse_iterator periodentafel::rbegin(){
     156  return reverse_iterator(elements.end());
     157}
     158
     159periodentafel::reverse_iterator periodentafel::rend(){
     160  return reverse_iterator(elements.begin());
     161}
    137162
    138163/** Prints period table to given stream.
    139164 * \param output stream
    140165 */
    141 bool periodentafel::Output(ofstream * const output) const
     166bool periodentafel::Output(ostream * const output) const
    142167{
    143168  bool result = true;
    144   element *walker = start;
    145169  if (output != NULL) {
    146     while (walker->next != end) {
    147       walker = walker->next;
    148       result = result && walker->Output(output);
     170    for(const_iterator iter=elements.begin(); iter !=elements.end();++iter){
     171      result = result && (*iter).second->Output(output);
    149172    }
    150173    return result;
     
    157180 * \param *checkliste elements table for this molecule
    158181 */
    159 bool periodentafel::Checkout(ofstream * const output, const int * const checkliste) const
    160 {
    161   element *walker = start;
     182bool periodentafel::Checkout(ostream * const output, const int * const checkliste) const
     183{
    162184  bool result = true;
    163185  int No = 1;
     
    166188    *output << "# Ion type data (PP = PseudoPotential, Z = atomic number)" << endl;
    167189    *output << "#Ion_TypeNr.\tAmount\tZ\tRGauss\tL_Max(PP)L_Loc(PP)IonMass\t# chemical name, symbol" << endl;
    168     while (walker->next != end) {
    169       walker = walker->next;
    170       if ((walker != NULL) && (walker->Z > 0) && (walker->Z < MAX_ELEMENTS) && (checkliste[walker->Z])) {
    171         walker->No = No;
    172         result = result && walker->Checkout(output, No++, checkliste[walker->Z]);
     190    for(const_iterator iter=elements.begin(); iter!=elements.end();++iter){
     191      if (((*iter).first < MAX_ELEMENTS) && (checkliste[(*iter).first])) {
     192        (*iter).second->No = No;
     193        result = result && (*iter).second->Checkout(output, No++, checkliste[(*iter).first]);
    173194      }
    174195    }
     
    184205{
    185206  ifstream infile;
    186   double tmp;
    187207  element *ptr;
     208  map<atomicNumber_t,element*> parsedElems;
    188209  bool status = true;
    189210  bool otherstatus = true;
     
    223244      //neues->Output((ofstream *)&cout);
    224245      if ((neues->Z > 0) && (neues->Z < MAX_ELEMENTS))
    225         periodentafel::AddElement(neues);
     246        parsedElems[neues->getNumber()] = neues;
    226247      else {
    227248        Log() << Verbose(0) << "Could not parse element: ";
     
    243264  if (infile != NULL) {
    244265    while (!infile.eof()) {
    245       infile >> tmp;
    246       infile >> ws;
    247       infile >> FindElement((int)tmp)->Valence;
     266      atomicNumber_t Z;
     267      infile >> Z;
     268      infile >> ws;
     269      infile >> parsedElems[Z]->Valence;
    248270      infile >> ws;
    249271      //Log() << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->Valence << " valence electrons." << endl;
     
    261283  if (infile != NULL) {
    262284    while (!infile.eof()) {
    263       infile >> tmp;
    264       infile >> ws;
    265       infile >> FindElement((int)tmp)->NoValenceOrbitals;
     285      atomicNumber_t Z;
     286      infile >> Z;
     287      infile >> ws;
     288      infile >> parsedElems[Z]->NoValenceOrbitals;
    266289      infile >> ws;
    267290      //Log() << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->NoValenceOrbitals << " number of singly occupied valence orbitals." << endl;
     
    279302  if (infile != NULL) {
    280303    while (!infile.eof()) {
    281       infile >> tmp;
    282       ptr = FindElement((int)tmp);
     304      atomicNumber_t Z;
     305      infile >> Z;
     306      ptr = parsedElems[Z];
    283307      infile >> ws;
    284308      infile >> ptr->HBondDistance[0];
     
    300324  if (infile != NULL) {
    301325    while (!infile.eof()) {
    302       infile >> tmp;
    303       ptr = FindElement((int)tmp);
     326      atomicNumber_t Z;
     327      infile >> Z;
     328      ptr = parsedElems[Z];
    304329      infile >> ws;
    305330      infile >> ptr->HBondAngle[0];
     
    313338    otherstatus = false;
    314339
    315   if (!otherstatus)
     340  if (otherstatus){
     341    map<atomicNumber_t,element*>::iterator iter;
     342    for(iter=parsedElems.begin();iter!=parsedElems.end();++iter){
     343      AddElement((*iter).second);
     344    }
     345  }
     346  else{
    316347    eLog() << Verbose(2) << "Something went wrong while parsing the other databases!" << endl;
     348    map<atomicNumber_t,element*>::iterator iter;
     349    for(iter=parsedElems.begin();iter!=parsedElems.end();++iter){
     350      AddElement((*iter).second);
     351    }
     352  }
    317353
    318354  return status;
     
    334370    f << header1 << endl;
    335371    f << header2 << endl;
    336     element *walker = periodentafel::start;
    337     while (walker->next != periodentafel::end) {
    338       walker = walker->next;
    339       result = result && walker->Output(&f);
     372    for(const_iterator iter=elements.begin();iter!=elements.end();++iter){
     373         result = result && (*iter).second->Output(&f);
    340374    }
    341375    f.close();
  • src/periodentafel.hpp

    rcd032d r68d781  
    11#ifndef PERIODENTAFEL_HPP_
    22#define PERIODENTAFEL_HPP_
    3 
    4 using namespace std;
    53
    64/*********************************************** includes ***********************************/
     
    1210
    1311#include <iostream>
     12#include <map>
     13#include <iterator>
    1414
    1515#include "defs.hpp"
     16#include "types.hpp"
    1617
    1718/****************************************** forward declarations *****************************/
     
    2526 */
    2627class periodentafel {
     28  /******* Types *********/
     29  private:
     30    typedef std::map<atomicNumber_t,element*> elementSet;
    2731  public:
    28     element *start; //!< start of element list
    29     element *end;   //!< end of element list
     32    typedef elementSet::iterator iterator;
     33    typedef elementSet::const_iterator const_iterator;
     34    typedef std::reverse_iterator<const_iterator> reverse_iterator;
     35  public:
     36
    3037    char header1[MAXSTRINGSIZE]; //!< store first header line
    3138    char header2[MAXSTRINGSIZE]; //!< store second header line
     
    3441  ~periodentafel();
    3542
    36   bool AddElement(element * const pointer);
    37   bool RemoveElement(element * const pointer);
    38   bool CleanupPeriodtable();
    39   element * const FindElement(const int Z) const;
    40   element * const FindElement(const char * const shorthand) const;
    41   element * const AskElement() const;
    42   element * const EnterElement();
    43   bool Output(ofstream * const output) const;
    44   bool Checkout(ofstream * const output, const int * const checkliste) const;
     43  iterator AddElement(element * const pointer);
     44  void RemoveElement(element * const pointer);
     45  void CleanupPeriodtable();
     46  const element *FindElement(atomicNumber_t) const;
     47  const element *FindElement(const char * const shorthand) const;
     48  const element *AskElement() const;
     49  const element *EnterElement();
     50
     51  const_iterator begin();
     52  const_iterator end();
     53  reverse_iterator rbegin();
     54  reverse_iterator rend();
     55  bool Output(std::ostream * const output) const;
     56  bool Checkout(std::ostream * const output, const int * const checkliste) const;
    4557  bool LoadPeriodentafel(const char * const path);
    4658  bool StorePeriodentafel(const char * const path) const;
    4759
    4860  private:
     61    elementSet elements;
    4962};
    5063
  • src/unittests/ActionSequenceTest.cpp

    rcd032d r68d781  
    3535  virtual ~canUndoActionStub(){}
    3636
    37   virtual void call(){}
    38   virtual void undo(){}
     37  virtual Action::state_ptr performCall(){
     38    return Action::success;
     39  }
     40  virtual Action::state_ptr performUndo(Action::state_ptr){
     41    return Action::success;
     42  }
     43  virtual Action::state_ptr performRedo(Action::state_ptr){
     44    return Action::success;
     45  }
    3946  virtual bool canUndo(){
     47    return true;
     48  }
     49  virtual bool shouldUndo(){
    4050    return true;
    4151  }
     
    4858  virtual ~cannotUndoActionStub(){}
    4959
    50   virtual void call(){}
    51   virtual void undo(){}
     60  virtual Action::state_ptr performCall(){
     61    return Action::success;
     62  }
     63  virtual Action::state_ptr performUndo(Action::state_ptr){
     64    return Action::success;
     65  }
     66  virtual Action::state_ptr performRedo(Action::state_ptr){
     67    return Action::success;
     68  }
    5269  virtual bool canUndo(){
    5370    return false;
     71  }
     72  virtual bool shouldUndo(){
     73   return true;
    5474  }
    5575};
     
    6484  virtual ~wasCalledActionStub(){}
    6585
    66   virtual void call(){
     86  virtual Action::state_ptr performCall(){
    6787    called = true;
    68   }
    69   virtual void undo(){
     88    return Action::success;
     89  }
     90  virtual Action::state_ptr performUndo(Action::state_ptr){
    7091    called = false;
     92    return Action::success;
     93  }
     94  virtual Action::state_ptr performRedo(Action::state_ptr){
     95    called = true;
     96    return Action::success;
    7197  }
    7298  virtual bool canUndo(){
     99    return true;
     100  }
     101  virtual bool shouldUndo(){
    73102    return true;
    74103  }
     
    185214  sequence->addAction(shouldCall2);
    186215
    187   sequence->callAll();
    188 
    189   sequence->removeLastAction();
    190   sequence->removeLastAction();
    191 
    192   sequence->undoAll();
     216  ActionSequence::stateSet states = sequence->callAll();
     217
     218  sequence->removeLastAction();
     219  sequence->removeLastAction();
     220
     221  sequence->undoAll(states);
    193222
    194223  CPPUNIT_ASSERT_EQUAL(true,shouldCall1->wasCalled());
  • src/unittests/AnalysisCorrelationToSurfaceUnitTest.cpp

    rcd032d r68d781  
    2727#include "World.hpp"
    2828
     29#include "Helpers/Assert.hpp"
     30
    2931#ifdef HAVE_TESTRUNNER
    3032#include "UnitTestMain.hpp"
     
    3840void AnalysisCorrelationToSurfaceUnitTest::setUp()
    3941{
     42  ASSERT_DO(Assert::Throw);
     43
    4044  atom *Walker = NULL;
    4145
  • src/unittests/AtomDescriptorTest.cpp

    rcd032d r68d781  
    140140    CPPUNIT_ASSERT_EQUAL( true , hasNoDuplicateAtoms(testAtoms));
    141141  }
    142 
    143142  // exclude and include some atoms
    144143  {
  • src/unittests/AtomDescriptorTest.hpp

    rcd032d r68d781  
    1111#include <cppunit/extensions/HelperMacros.h>
    1212
    13 #include "defs.hpp"
     13#include "types.hpp"
    1414
    1515#define ATOM_COUNT (10)
  • src/unittests/CacheableTest.cpp

    rcd032d r68d781  
    2727class threeNumbers : public Observable {
    2828public:
    29   bool hasRecalced;
    3029  int x;
    3130  int y;
    3231  int z;
     32  Cacheable<int> sum;
     33  bool hasRecalced;
    3334
    3435  void setX(int _x){
     
    5455
    5556  threeNumbers(int _x,int _y, int _z) :
     57    x(_x),y(_y),z(_z),
    5658    sum(this,boost::bind(&threeNumbers::calcSum,this)),
    57     x(_x),y(_y),z(_z),
    5859    hasRecalced(false)
    5960  {}
    60 
    61   Cacheable<int> sum;
    6261};
    6362
  • src/unittests/Makefile.am

    rcd032d r68d781  
    9292AnalysisPairCorrelationUnitTest_LDADD = ${ALLLIBS}
    9393
     94atomsCalculationTest_SOURCES = UnitTestMain.cpp atomsCalculationTest.cpp atomsCalculationTest.hpp
     95atomsCalculationTest_LDADD = ${ALLLIBS}
     96
    9497BondGraphUnitTest_SOURCES = UnitTestMain.cpp bondgraphunittest.cpp bondgraphunittest.hpp
    9598BondGraphUnitTest_LDADD = ${ALLLIBS}
     
    158161manipulateAtomsTest_LDADD = ${ALLLIBS}
    159162
    160 atomsCalculationTest_SOURCES = UnitTestMain.cpp atomsCalculationTest.cpp atomsCalculationTest.hpp
    161 atomsCalculationTest_LDADD = ${ALLLIBS}
    162 
    163163TestRunner_SOURCES = TestRunnerMain.cpp $(TESTSOURCES) $(TESTHEADERS)
    164164TestRunner_LDADD = ${ALLLIBS}
  • src/unittests/MoleculeDescriptorTest.hpp

    rcd032d r68d781  
    1111#include <cppunit/extensions/HelperMacros.h>
    1212
    13 #include "defs.hpp"
     13#include "types.hpp"
    1414
    1515#define MOLECULE_COUNT (10)
  • src/unittests/ObserverTest.cpp

    rcd032d r68d781  
    1313
    1414#include "Patterns/Observer.hpp"
     15#include "Helpers/Assert.hpp"
    1516
    1617#include <iostream>
     
    6566};
    6667
     68class BlockObservable : public Observable {
     69public:
     70  void changeMethod1(){
     71    OBSERVE;
     72    // test if we report correctly as blocked
     73    CPPUNIT_ASSERT(isBlocked());
     74  }
     75
     76  void changeMethod2(){
     77    OBSERVE;
     78    internalMethod1();
     79    internalMethod2();
     80  }
     81
     82  void internalMethod1(){
     83    // we did not block, but our caller did...
     84    // see if this is found
     85    CPPUNIT_ASSERT(isBlocked());
     86  }
     87
     88  void internalMethod2(){
     89    OBSERVE;
     90    // Both this method and the caller do block
     91    // Does the reporting still work as expected?
     92    CPPUNIT_ASSERT(isBlocked());
     93  }
     94
     95  void noChangeMethod(){
     96    // No Block introduced here
     97    // reported correctely?
     98    CPPUNIT_ASSERT(!isBlocked());
     99  }
     100};
     101
    67102class SuperObservable : public Observable {
    68103public:
     
    86121
    87122void ObserverTest::setUp() {
     123  ASSERT_DO(Assert::Throw);
    88124  simpleObservable1 = new SimpleObservable();
    89125  simpleObservable2 = new SimpleObservable();
    90126  callObservable = new CallObservable();
    91127  superObservable = new SuperObservable();
     128  blockObservable = new BlockObservable();
    92129
    93130  observer1 = new UpdateCountObserver();
     
    163200}
    164201
     202void ObserverTest::doesReportTest(){
     203  // Actual checks are in the Stub-methods for this
     204  blockObservable->changeMethod1();
     205  blockObservable->changeMethod2();
     206  blockObservable->noChangeMethod();
     207}
    165208
    166209void ObserverTest::CircleDetectionTest() {
     
    174217  // make this Observable its own subject. NEVER DO THIS IN ACTUAL CODE
    175218  simpleObservable1->signOn(simpleObservable1);
    176   simpleObservable1->changeMethod();
     219  CPPUNIT_ASSERT_THROW(simpleObservable1->changeMethod(),Assert::AssertionFailure);
    177220
    178221  // more complex test
     
    180223  simpleObservable1->signOn(simpleObservable2);
    181224  simpleObservable2->signOn(simpleObservable1);
    182   simpleObservable1->changeMethod();
     225  CPPUNIT_ASSERT_THROW(simpleObservable1->changeMethod(),Assert::AssertionFailure);
    183226  simpleObservable1->signOff(simpleObservable2);
    184227  simpleObservable2->signOff(simpleObservable1);
  • src/unittests/ObserverTest.hpp

    rcd032d r68d781  
    1616class CallObservable;
    1717class SuperObservable;
     18class BlockObservable;
    1819
    1920
     
    2425  CPPUNIT_TEST ( doesBlockUpdateTest );
    2526  CPPUNIT_TEST ( doesSubObservableTest );
     27  CPPUNIT_TEST ( doesReportTest );
    2628  CPPUNIT_TEST ( CircleDetectionTest );
    2729  CPPUNIT_TEST_SUITE_END();
     
    3436  void doesBlockUpdateTest();
    3537  void doesSubObservableTest();
     38  void doesReportTest();
    3639  void CircleDetectionTest();
    3740
     
    4548  SimpleObservable *simpleObservable2;
    4649  CallObservable *callObservable;
     50  BlockObservable *blockObservable;
    4751  SuperObservable *superObservable;
    4852};
  • src/unittests/SingletonTest.cpp

    rcd032d r68d781  
    2929    count1++;
    3030  }
     31  // explicit copy constructor to catch if this is ever called
     32  SingletonStub1(const SingletonStub1&){
     33    CPPUNIT_FAIL    ( "Copy constructor of Singleton called" );
     34  }
    3135  virtual ~SingletonStub1(){
    3236    count2++;
     
    4751  SingletonStub2(){
    4852    count1++;
     53  }
     54  // explicit copy constructor to catch if thsi is ever called
     55  SingletonStub2(const SingletonStub2&){
     56    CPPUNIT_FAIL    ( "Copy constructor of Singleton called" );
    4957  }
    5058  virtual ~SingletonStub2(){
  • src/unittests/analysisbondsunittest.cpp

    rcd032d r68d781  
    5353  strcpy(hydrogen->symbol, "H");
    5454  carbon = new element;
    55   carbon->Z = 1;
     55  carbon->Z = 2;
    5656  carbon->Valence = 4;
    5757  carbon->NoValenceOrbitals = 4;
  • src/unittests/atomsCalculationTest.cpp

    rcd032d r68d781  
    3131CPPUNIT_TEST_SUITE_REGISTRATION( atomsCalculationTest );
    3232
    33 // some stubs
    34 class AtomStub : public atom {
    35 public:
    36   AtomStub(atomId_t _id) :
    37   atom(),
    38   id(_id),
    39   manipulated(false)
    40   {}
    41 
    42   virtual atomId_t getId(){
    43     return id;
    44   }
    45 
    46   virtual void doSomething(){
    47     manipulated = true;
    48   }
    49 
    50   bool manipulated;
    51 private:
    52   atomId_t id;
    53 };
    54 
    5533// set up and tear down
    5634void atomsCalculationTest::setUp(){
    5735  World::getInstance();
    5836  for(int i=0;i<ATOM_COUNT;++i){
    59     atoms[i]= new AtomStub(i);
    60     World::getInstance().registerAtom(atoms[i]);
     37    atoms[i]= World::getInstance().createAtom();
     38    atomIds[i]= atoms[i]->getId();
    6139  }
    6240}
     
    6745
    6846// some helper functions
    69 static bool hasAll(std::vector<int> ids,int min, int max, std::set<int> excluded = std::set<int>()){
    70   for(int i=min;i<max;++i){
    71     if(!excluded.count(i)){
    72       std::vector<int>::iterator iter;
     47static bool hasAllIds(std::vector<atomId_t> atoms,atomId_t ids[ATOM_COUNT], std::set<atomId_t> excluded = std::set<atomId_t>()){
     48  for(int i=0;i<ATOM_COUNT;++i){
     49    atomId_t id = ids[i];
     50    if(!excluded.count(id)){
     51      std::vector<atomId_t>::iterator iter;
    7352      bool res=false;
    74       for(iter=ids.begin();iter!=ids.end();++iter){
    75         res |= (*iter) == i;
     53      for(iter=atoms.begin();iter!=atoms.end();++iter){
     54        res |= (*iter) == id;
    7655      }
    7756      if(!res) {
    78         cout << "Atom " << i << " missing in returned list" << endl;
     57        cout << "Atom " << id << " missing in returned list" << endl;
    7958        return false;
    8059      }
     
    8463}
    8564
    86 static bool hasNoDuplicates(std::vector<int> ids){
    87   std::set<int> found;
    88   std::vector<int>::iterator iter;
     65static bool hasNoDuplicates(std::vector<atomId_t> ids){
     66  std::set<atomId_t> found;
     67  std::vector<atomId_t>::iterator iter;
    8968  for(iter=ids.begin();iter!=ids.end();++iter){
    9069    int id = (*iter);
     
    9776
    9877void atomsCalculationTest::testCalculateSimple(){
    99   AtomsCalculation<int> *calc = World::getInstance().calcOnAtoms<int>(boost::bind(&atom::getId,_1),"FOO",AllAtoms());
    100   std::vector<int> allIds = (*calc)();
    101   CPPUNIT_ASSERT(hasAll(allIds,0,ATOM_COUNT));
     78  AtomsCalculation<atomId_t> *calc = World::getInstance().calcOnAtoms<atomId_t>(boost::bind(&atom::getId,_1),"FOO",AllAtoms());
     79  std::vector<atomId_t> allIds = (*calc)();
     80  CPPUNIT_ASSERT(hasAllIds(allIds,atomIds));
    10281  CPPUNIT_ASSERT(hasNoDuplicates(allIds));
    10382}
    10483
    10584void atomsCalculationTest::testCalculateExcluded(){
    106   int excluded = ATOM_COUNT/2;
    107   AtomsCalculation<int> *calc = World::getInstance().calcOnAtoms<int>(boost::bind(&atom::getId,_1),"FOO",AllAtoms() && !AtomById(excluded));
    108   std::vector<int> allIds = (*calc)();
    109   std::set<int> excluded_set;
     85  atomId_t excluded = atomIds[ATOM_COUNT/2];
     86  AtomsCalculation<atomId_t> *calc = World::getInstance().calcOnAtoms<atomId_t>(boost::bind(&atom::getId,_1),"FOO",AllAtoms() && !AtomById(excluded));
     87  std::vector<atomId_t> allIds = (*calc)();
     88  std::set<atomId_t> excluded_set;
    11089  excluded_set.insert(excluded);
    111   CPPUNIT_ASSERT(hasAll(allIds,0,ATOM_COUNT,excluded_set));
     90  CPPUNIT_ASSERT(hasAllIds(allIds,atomIds,excluded_set));
    11291  CPPUNIT_ASSERT(hasNoDuplicates(allIds));
    11392  CPPUNIT_ASSERT_EQUAL((size_t)(ATOM_COUNT-1),allIds.size());
  • src/unittests/atomsCalculationTest.hpp

    rcd032d r68d781  
    1212
    1313#define ATOM_COUNT (10)
     14
     15#include "types.hpp"
    1416
    1517class atom;
     
    3133private:
    3234  atom *atoms [ATOM_COUNT];
    33   int atomIds [ATOM_COUNT];
     35  atomId_t atomIds [ATOM_COUNT];
    3436};
    3537
  • src/unittests/bondgraphunittest.cpp

    rcd032d r68d781  
    5151  strcpy(hydrogen->symbol, "H");
    5252  carbon = new element;
    53   carbon->Z = 1;
     53  carbon->Z = 2;
    5454  strcpy(carbon->name, "carbon");
    5555  strcpy(carbon->symbol, "C");
  • src/unittests/manipulateAtomsTest.cpp

    rcd032d r68d781  
    1818#include "Actions/ManipulateAtomsProcess.hpp"
    1919#include "Actions/ActionRegistry.hpp"
     20#include "Actions/ActionHistory.hpp"
    2021
    2122#include "World.hpp"
     
    7071// set up and tear down
    7172void manipulateAtomsTest::setUp(){
     73  ActionHistory::init();
    7274  World::getInstance();
    7375  for(int i=0;i<ATOM_COUNT;++i){
     
    7981  World::purgeInstance();
    8082  ActionRegistry::purgeInstance();
     83  ActionHistory::purgeInstance();
    8184}
    8285
     
    102105
    103106void manipulateAtomsTest::testManipulateExcluded(){
     107
    104108  ManipulateAtomsProcess *proc = World::getInstance().manipulateAtoms(boost::bind(operation,_1),"FOO",AllAtoms() && !AtomById(ATOM_COUNT/2));
    105109  proc->call();
     
    120124  countObserver *obs = new countObserver();
    121125  World::getInstance().signOn(obs);
    122   ManipulateAtomsProcess *proc = World::getInstance().manipulateAtoms(boost::bind(operation,_1),"FOO",AllAtoms() && !AtomById(ATOM_COUNT/2));
     126  ManipulateAtomsProcess *proc = World::getInstance().manipulateAtoms(boost::bind(operation,_1),"FOO",AllAtoms());
    123127  proc->call();
    124128
Note: See TracChangeset for help on using the changeset viewer.