Index: src/Patterns/Observer.cpp
===================================================================
--- src/Patterns/Observer.cpp	(revision f8879dd41341e9b0285c43f7d9eec41d28414400)
+++ src/Patterns/Observer.cpp	(revision f8879dd41341e9b0285c43f7d9eec41d28414400)
@@ -0,0 +1,142 @@
+/*
+ * Observer.cpp
+ *
+ *  Created on: Jan 19, 2010
+ *      Author: crueger
+ */
+
+#include "Observer.hpp"
+
+
+#include <iostream>
+
+using namespace std;
+
+/****************** Static stuff for the observer mechanism ************/
+
+// All infrastructure for the observer-pattern is bundled at a central place
+// this is more efficient if many objects can be observed (inherit from observable)
+// but only few are actually coupled with observers. E.g. TMV has over 500.000 Atoms,
+// which might become observable. Handling Observerable infrastructure in each of
+// these would use memory for each atom. By handling Observer-infrastructure
+// here we only need memory for objects that actually are observed.
+// See [Gamma et al, 1995] p. 297
+
+map<Observable*, int> Observable::depth;
+multimap<Observable*,Observer*> Observable::callTable;
+set<Observable*> Observable::busyObservables;
+
+// The two functions start_observer_internal and finish_observer_internal
+// have to be used together at all time. Never use these functions directly
+// START_OBSERVER and FINISH_OBSERVER also construct a bogus while(0) loop
+// thus producing compiler-errors whenever only one is used
+
+void Observable::start_observer_internal(Observable *publisher){
+  // increase the count for this observable by one
+  // if no entry for this observable is found, an new one is created
+  // by the STL and initialized to 0 (see STL documentation)
+  depth[publisher]++;
+}
+
+void Observable::finish_observer_internal(Observable *publisher){
+  // decrease the count for this observable
+  // if zero is reached all observed blocks are done and we can
+  // start to notify our observers
+  if(--(depth[publisher])){}
+  else{
+    publisher->notifyAll();
+    // this item is done, so we don't have to keep the count with us
+    // save some memory by erasing it
+    depth.erase(publisher);
+  }
+}
+
+/************* Notification mechanism for observables **************/
+
+typedef multimap<Observable*,Observer*>::iterator callIterator;
+typedef pair<callIterator, callIterator> iteratorRange;
+
+void Observable::notifyAll() {
+  // we are busy notifying others right now
+  // add ourselves to the list of busy subjects to enable circle detection
+  busyObservables.insert(this);
+  // see if anyone has signed up for observation
+  // and call all observers
+  if(callTable.count(this)) {
+     iteratorRange callerRange = callTable.equal_range(this);
+     callIterator iter;
+     for(iter=callerRange.first;iter!=callerRange.second;iter++){
+       (*iter).second->update(this);
+     }
+  }
+  // done with notification, we can leave the set of busy subjects
+  busyObservables.erase(this);
+}
+
+// this handles passing on updates from sub-Observables
+void Observable::update(Observable *publisher) {
+  // circle detection
+  if(busyObservables.find(this)!=busyObservables.end()) {
+    // somehow a circle was introduced... we were busy notifying our
+    // observers, but still we are called by one of our sub-Observables
+    // we cannot be sure observation will still work at this point
+    cerr << "Circle detected in observation-graph." << endl;
+    cerr << "Observation-graph always needs to be a DAG to work correctly!" << endl;
+    cerr << "Please check your observation code and fix this!" << endl;
+    return;
+  }
+  else {
+    // see if we are in the process of changing ourselves
+    // if we are changing ourselves at the same time our sub-observables change
+    // we do not need to publish all the changes at each time we are called
+    if(depth.find(this)==depth.end()) {
+      notifyAll();
+    }
+  }
+}
+
+// methods to sign-on and off
+void Observable::signOn(Observer *target) {
+  bool res = false;
+  iteratorRange callerRange = callTable.equal_range(this);
+  callIterator iter;
+  for(iter=callerRange.first;iter!=callerRange.second;iter++){
+    res |= ((*iter).second == target);
+  }
+  if(!res)
+    callTable.insert(pair<Observable*,Observer*>(this,target));
+}
+
+void Observable::signOff(Observer *target) {
+  iteratorRange callerRange = callTable.equal_range(this);
+  callIterator iter;
+  for(iter=callerRange.first;iter!=callerRange.second;iter++) {
+    if((*iter).second == target)
+      callTable.erase(iter);
+  }
+}
+
+// when an sub-observerable dies we usually don't need to do anything
+void Observable::subjectKilled(Observable *publisher){
+}
+
+Observable::Observable()
+{}
+
+// when an observable is deleted, we let all our observers know
+Observable::~Observable()
+{
+  // delete all entries for this observable
+  iteratorRange callerRange = callTable.equal_range(this);
+  callIterator iter;
+  for(iter=callerRange.first;iter!=callerRange.second;iter++){
+    (*iter).second->subjectKilled(this);
+  }
+  callTable.erase(callerRange.first,callerRange.second);
+}
+
+Observer::Observer()
+{}
+
+Observer::~Observer()
+{}
Index: src/Patterns/Observer.hpp
===================================================================
--- src/Patterns/Observer.hpp	(revision f8879dd41341e9b0285c43f7d9eec41d28414400)
+++ src/Patterns/Observer.hpp	(revision f8879dd41341e9b0285c43f7d9eec41d28414400)
@@ -0,0 +1,78 @@
+/*
+ * Observer.hpp
+ *
+ *  Created on: Jan 19, 2010
+ *      Author: crueger
+ */
+
+#ifndef OBSERVER_HPP_
+#define OBSERVER_HPP_
+
+#include <map>
+#include <set>
+
+/**
+ * Basic structure for the observer pattern
+ *
+ * Observers register themselves with the observables to be notified when something changes.
+ * In the Observable code that changes attributes should be wrapped in
+ * START_OBSERVER ... END_OBSERVER blocks. If other methods are called that also contain
+ * Observation blocks from there, these functions wont trigger notifications. Only the end
+ * of the final observation block triggers the update of Observers.
+ *
+ * Each observerable can have sub-observables. When one of these sub-observables changes and
+ * notifies its observers the observable that contains them will also notify its observers.
+ * This passing on of updates is blocked, when the main-observable is in the process of
+ * updating many of its internal sub-observables. This means the update is not passed, if
+ * it is produced while the main-observable itself is within any Observation block.
+ */
+
+class Observable;
+
+class Observer
+{
+public:
+  Observer();
+  virtual ~Observer();
+
+  virtual void update(Observable *publisher)=0;
+  virtual void subjectKilled(Observable *publisher)=0;
+};
+
+class Observable : public Observer {
+public:
+  Observable();
+  virtual ~Observable();
+
+  virtual void signOn(Observer *target);
+  virtual void signOff(Observer *target);
+
+  virtual void update(Observable *publisher);
+  virtual void subjectKilled(Observable *publisher);
+
+private:
+  virtual void notifyAll();
+protected:
+// Observer mechanismen is done from a static central place
+  /**
+   * Internal method.
+   * Do not call directly. Use START_OBSERVER macro instead
+   */
+  static void start_observer_internal(Observable *publisher);
+  /**
+   * Internal method.
+   * Do not call directly. Use FINISH_OBSERVER macro instead
+   */
+  static void finish_observer_internal(Observable *publisher);
+
+private:
+  static std::map<Observable*, int> depth;
+  static std::multimap<Observable*,Observer*> callTable;
+  static std::set<Observable*> busyObservables;
+};
+
+
+
+#define START_OBSERVER Observable::start_observer_internal(this);do{do{}while(0)
+#define FINISH_OBSERVER }while(0);Observable::finish_observer_internal(this)
+#endif /* OBSERVER_HPP_ */
