Changeset cd5047 for src/Patterns


Ignore:
Timestamp:
Jun 9, 2010, 2:30:10 PM (15 years ago)
Author:
Tillmann Crueger <crueger@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
112b09
Parents:
2c8934
Message:

Added Logging capabilities to Observer Framework

Location:
src/Patterns
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/Patterns/Cacheable.hpp

    r2c8934 rcd5047  
    3535        return busy;
    3636      }
     37    virtual std::string getName()=0;
    3738    protected:
    3839      bool busy;
     
    6465        // nothing to do when entering this
    6566      }
     67
     68      virtual std::string getName(){
     69        return "invalid";
     70      }
    6671    };
    6772
     
    9095        State::busy = false;
    9196      }
     97
     98      virtual std::string getName(){
     99        return "valid";
     100      }
    92101    private:
    93102      T content;
     
    118127        // nothing to do when entering this state
    119128      }
     129
     130      virtual std::string getName(){
     131        return "destroyed";
     132      }
    120133    };
    121134
     
    124137
    125138  public:
    126     Cacheable(Observable *_owner, boost::function<T()> _recalcMethod);
     139    Cacheable(Observable *_owner, boost::function<T()> _recalcMethod, std::string name);
    127140    virtual ~Cacheable();
    128141
     
    151164
    152165  template<typename T>
    153   Cacheable<T>::Cacheable(Observable *_owner, boost::function<T()> _recalcMethod) :
     166  Cacheable<T>::Cacheable(Observable *_owner, boost::function<T()> _recalcMethod, std::string name) :
     167    Observer(name + "(Cached)"),
    154168    owner(_owner),
    155169    recalcMethod(_recalcMethod)
     
    206220  void Cacheable<T>::switchState(state_ptr newState){
    207221    ASSERT(!state->isBusy(),"LOOP DETECTED: Cacheable state switched while recalculating.\nDid the recalculation trigger the Observable?");
     222#ifdef LOG_OBSERVER
     223    observerLog().addMessage() << "## Cacheable " << observerLog().getName(this) << " changed state (" << state->getName()
     224                               << "->" << newState->getName() << ")" << std::endl;
     225#endif
    208226    state = newState;
    209227    state->enter();
  • src/Patterns/Observer.cpp

    r2c8934 rcd5047  
    1212
    1313#include "Helpers/Assert.hpp"
     14#include "Helpers/MemDebug.hpp"
    1415
    1516using namespace std;
     
    4344  // if no entry for this observable is found, an new one is created
    4445  // by the STL and initialized to 0 (see STL documentation)
     46#ifdef LOG_OBSERVER
     47  observerLog().addMessage(depth[publisher]) << ">> Locking " << observerLog().getName(publisher) << endl;
     48#endif
    4549  depth[publisher]++;
    4650}
     
    6064  // if zero is reached all observed blocks are done and we can
    6165  // start to notify our observers
    62   if(--(depth[publisher])){}
     66  --depth[publisher];
     67#ifdef LOG_OBSERVER
     68  observerLog().addMessage(depth[publisher]) << "<< Unlocking " << observerLog().getName(publisher) << endl;
     69#endif
     70  if(depth[publisher]){}
    6371  else{
    6472    publisher->notifyAll();
     
    123131      callees_t::iterator iter;
    124132      for(iter=callees.begin();iter!=callees.end();++iter){
     133#ifdef LOG_OBSERVER
     134        observerLog().addMessage() << "-> Sending update from " << observerLog().getName(this)
     135                                   << " to " << observerLog().getName((*iter).second)
     136                                   << " (priority=" << (*iter).first << ")"<< endl;
     137#endif
    125138        (*iter).second->update(this);
    126139      }
     
    165178    // we do not need to publish all the changes at each time we are called
    166179    if(depth.find(this)==depth.end()) {
     180#ifdef LOG_OBSERVER
     181      observerLog().addMessage() << "-* Update from " << observerLog().getName(publisher)
     182                                 << " propagated by " << observerLog().getName(this) << endl;
     183#endif
    167184      notifyAll();
     185    }
     186    else{
     187#ifdef LOG_OBSERVER
     188      observerLog().addMessage() << "-| Update from " <<  observerLog().getName(publisher)
     189                                 << " not propagated by " << observerLog().getName(this) << endl;
     190#endif
    168191    }
    169192  }
     
    177200void Observable::signOn(Observer *target,int priority) {
    178201  ASSERT(priority>=-20 && priority<=+20, "Priority out of range [-20:+20] when signing on Observer");
     202#ifdef LOG_OBSERVER
     203  observerLog().addMessage() << "@@ Signing on " << observerLog().getName(target) << " to " << observerLog().getName(this) << endl;
     204#endif
    179205  bool res = false;
    180206  callees_t &callees = callTable[this];
     
    194220void Observable::signOff(Observer *target) {
    195221  ASSERT(callTable.count(this),"SignOff called for an Observable without Observers.");
     222#ifdef LOG_OBSERVER
     223  observerLog().addMessage() << "** Signing off " << observerLog().getName(target) << " from " << observerLog().getName(this) << endl;
     224#endif
    196225  callees_t &callees = callTable[this];
    197226
     
    238267/** Constructor for class Observable.
    239268 */
    240 Observable::Observable()
    241 {}
     269Observable::Observable(string name) :
     270  Observer(Observer::BaseConstructor())
     271{
     272#ifdef LOG_OBSERVER
     273  observerLog().addName(this,name);
     274  observerLog().addMessage() << "++ Creating Observable " << observerLog().getName(this) << endl;
     275#endif
     276}
    242277
    243278/** Destructor for class Observable.
     
    246281Observable::~Observable()
    247282{
     283#ifdef LOG_OBSERVER
     284  observerLog().addMessage() << "-- Destroying Observable " << observerLog().getName(this) << endl;
     285#endif
    248286  if(callTable.count(this)) {
    249287    // delete all entries for this observable
     
    259297/** Constructor for class Observer.
    260298 */
    261 Observer::Observer()
    262 {}
     299Observer::Observer(string name)
     300{
     301#ifdef LOG_OBSERVER
     302  observerLog().addName(this,name);
     303  observerLog().addMessage() << "++ Creating Observer " << observerLog().getName(this) << endl;
     304#endif
     305}
     306
     307/**
     308 * Base Constructor for class Observer
     309 *
     310 * only called from Observable Constructor
     311 */
     312Observer::Observer(Observer::BaseConstructor){
     313#ifdef LOG_OBSERVER
     314  observerLog().addObservable(this);
     315#endif
     316}
    263317
    264318/** Destructor for class Observer.
    265319 */
    266320Observer::~Observer()
    267 {}
     321{
     322#ifdef LOG_OBSERVER
     323  if(!observerLog().isObservable(this)){
     324    observerLog().addMessage() << "-- Destroying Observer " << observerLog().getName(this) << endl;
     325  }
     326#endif
     327}
    268328
    269329/**
     
    296356  }
    297357}
     358
     359#ifdef LOG_OBSERVER
     360
     361/************************* Methods to do logging of the Observer Mechanism *********/
     362
     363// The log needs to exist fairly early, so we make it construct on first use,
     364// and never destroy it
     365ObserverLog &observerLog(){
     366  // yes, this memory is never freed... we need it around for the whole programm,
     367  // so no freeing is possible
     368  static ObserverLog *theLog = Memory::ignore(new ObserverLog());
     369  return *theLog;
     370}
     371
     372
     373ObserverLog::ObserverLog() :
     374  count (0)
     375{}
     376
     377ObserverLog::~ObserverLog(){}
     378
     379string ObserverLog::getLog(){return log.str();}
     380
     381std::string ObserverLog::getName(void* obj){
     382  return names[obj];
     383}
     384
     385bool ObserverLog::isObservable(void* obj){
     386  return observables.count(obj);
     387}
     388
     389void ObserverLog::addName(void* obj , string name){
     390  stringstream sstr;
     391  sstr << name << "_" << count++;
     392  names[obj] = sstr.str();
     393}
     394
     395void ObserverLog::addObservable(void* obj){
     396  observables.insert(obj);
     397}
     398
     399void ObserverLog::deleteName(void* obj){
     400  names.erase(obj);
     401}
     402
     403void ObserverLog::deleteObservable(void* obj){
     404  observables.erase(obj);
     405}
     406
     407stringstream &ObserverLog::addMessage(int depth){
     408  for(int i=depth;i--;)
     409    log << "  ";
     410  return log;
     411}
     412
     413#endif
  • src/Patterns/Observer.hpp

    r2c8934 rcd5047  
    1111#include <map>
    1212#include <set>
     13#include <string>
     14#include <sstream>
    1315
    1416/**
     
    2830 */
    2931
     32// Deactivate any logging when we are not in debug mode
     33#ifdef NDEBUG
     34#undef LOG_OBSERVER
     35#endif
     36
    3037class Observable;
    3138class Notification;
     
    5865  template<class> friend class ObservedIterator;
    5966
    60 public:
    61   Observer();
     67  // indicates the constructor called from Observables
     68  struct BaseConstructor{};
     69
     70public:
     71  Observer(BaseConstructor);
     72  Observer(std::string);
    6273  virtual ~Observer();
    6374
     
    91102class Observable : public Observer {
    92103public:
    93   Observable();
     104  Observable(std::string _name);
    94105  virtual ~Observable();
    95106
     
    192203};
    193204
     205#ifdef LOG_OBSERVER
     206
     207/**
     208 * This class is used to log the working of the observer mechanism
     209 *
     210 * TODO: make this conditional dependent on compiler Flag.
     211 */
     212class ObserverLog{
     213  friend class Observable;
     214  friend class Observer;
     215  template <typename> friend class Cacheable;
     216public:
     217  ObserverLog();
     218  ~ObserverLog();
     219  std::string getLog();                        // get everything that has been logged
     220  std::string getName(void*);                  // get the name of an actor
     221  bool isObservable(void*);
     222private:
     223  int count;                                   // number to reference each actor in this framework
     224  std::map<void*,std::string> names;           // List of names assigned to actors
     225  std::set<void*> observables;                 // List of pointers to Observables. Needed to distinguish Observers and Observables
     226  void addName(void*, std::string);            // Assign a name to an Actor
     227  void addObservable(void*);
     228  void deleteName(void*);                      // delete the name of an Actor
     229  void deleteObservable(void*);
     230  std::stringstream &addMessage(int depth=0);  // Add a Message to the logging
     231  std::stringstream log;                       // The internal log object
     232};
     233
     234ObserverLog &observerLog();
     235
     236#endif
     237
    194238// extra macro is necessary to work with __LINE__
    195239#define PASTE(a,b) PASTE_HELPER(a,b)
Note: See TracChangeset for help on using the changeset viewer.