Changeset 70db8f


Ignore:
Timestamp:
Apr 17, 2013, 6:56:52 PM (12 years ago)
Author:
Frederik Heber <heber@…>
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:
c8bbf2
Parents:
411202d
git-author:
Frederik Heber <heber@…> (03/18/13 18:43:08)
git-committer:
Frederik Heber <heber@…> (04/17/13 18:56:52)
Message:

FIX: Significantly simplified observer use in GLMoleculeObject_bond.

  • stored bond is now just reference. As if we store the bond::ptr, we prevent the bond from being free'd when removed.
  • we additionally store leftatom and rightatom as Observable to know when their notifications have arrived. We also store both ids for quick and safe BondRemoved signalling.
  • dstor now always calls signOff()s, elsewhere we just delete ourselves.
Location:
src/UIElements/Views/Qt4/Qt3D
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.cpp

    r411202d r70db8f  
    6060      +std::string("-")
    6161      +toString(bondref->rightatom->getId())),
    62   _bond(bondref),
     62  _bond(*bondref),
     63  leftatom(bondref->leftatom),
     64  rightatom(bondref->rightatom),
     65  leftatomId(bondref->leftatom->getId()),
     66  rightatomId(bondref->rightatom->getId()),
    6367  BondSide(side)
    6468{
    6569  // sign on as observer (obtain non-const instance before)
    66   _bond->signOn(this, BondObservable::BondRemoved);
    67   _bond->leftatom->signOn(this, AtomObservable::PositionChanged);
    68   _bond->rightatom->signOn(this, AtomObservable::PositionChanged);
     70  _bond.signOn(this, BondObservable::BondRemoved);
     71  leftatom->signOn(this, AtomObservable::PositionChanged);
     72  leftatom->signOn(this, AtomObservable::ElementChanged);
     73  rightatom->signOn(this, AtomObservable::PositionChanged);
     74  rightatom->signOn(this, AtomObservable::ElementChanged);
    6975
    7076  size_t elementno = 0;
    7177  switch (BondSide) {
    7278    case left:
    73       if (_bond->rightatom->getType() != NULL) {
    74         elementno = _bond->rightatom->getType()->getAtomicNumber();
     79      if (_bond.rightatom->getType() != NULL) {
     80        elementno = _bond.rightatom->getType()->getAtomicNumber();
    7581      } else { // if not element yet set, set to hydrogen
    7682        elementno = 1;
     
    7884      break;
    7985    case right:
    80       if (_bond->leftatom->getType() != NULL) {
    81         elementno = _bond->leftatom->getType()->getAtomicNumber();
     86      if (_bond.leftatom->getType() != NULL) {
     87        elementno = _bond.leftatom->getType()->getAtomicNumber();
    8288      } else { // if not element yet set, set to hydrogen
    8389        elementno = 1;
     
    99105GLMoleculeObject_bond::~GLMoleculeObject_bond()
    100106{
    101   // sign on as observer (obtain non-const instance before)
    102   if (_bond){
    103     _bond->signOff(this, BondObservable::BondRemoved);
    104     _bond->leftatom->signOff(this, AtomObservable::PositionChanged);
    105     _bond->rightatom->signOff(this, AtomObservable::PositionChanged);
    106     LOG(2, "INFO: Destroying  GLMoleculeObject_bond to bond " << *_bond << " and side " << BondSide << ".");
    107   }else{
    108     LOG(2, "INFO: Destroying  GLMoleculeObject_bond (bond already killed).");
    109   }
    110 }
    111 
    112 void GLMoleculeObject_bond::update(Observable *publisher)
    113 {
    114 #ifdef LOG_OBSERVER
    115   observerLog().addMessage() << "++ Update of Observer " << observerLog().getName(this) << " from bond " << *_bond << ".";
    116 #endif
    117 }
    118 
    119 void GLMoleculeObject_bond::subjectKilled(Observable *publisher)
    120 {
    121   LOG(2, "INFO: Received subjectKilled from " << *_bond << ".");
     107  // sign off
    122108  switch (BondSide) {
    123109    case left:
    124       emit BondRemoved(_bond->leftatom->getId(), _bond->rightatom->getId());
     110      emit BondRemoved(leftatomId, rightatomId);
    125111      break;
    126112    case right:
    127       emit BondRemoved(_bond->rightatom->getId(), _bond->leftatom->getId());
     113      emit BondRemoved(rightatomId, leftatomId);
    128114      break;
    129115    default:
    130116      ASSERT(0,
    131           "GLMoleculeObject_bond::subjectKilled() - side is not a valid argument: "+toString(BondSide)+".");
    132       break;
    133   }
    134 
    135   // Don't let the destructor automatically sign off from a dead bond!
    136   _bond->leftatom->signOff(this, AtomObservable::PositionChanged);
    137   _bond->rightatom->signOff(this, AtomObservable::PositionChanged);
    138   _bond.reset();
     117          "GLMoleculeObject_bond::subjectKilled() - side is not a valid argument: "
     118          +toString(BondSide)+".");
     119      break;
     120  }
     121  _bond.signOff(this, BondObservable::BondRemoved);
     122  leftatom->signOff(this, AtomObservable::PositionChanged);
     123  leftatom->signOff(this, AtomObservable::ElementChanged);
     124  rightatom->signOff(this, AtomObservable::PositionChanged);
     125  rightatom->signOff(this, AtomObservable::ElementChanged);
     126  LOG(3, "DEBUG: Destroying  GLMoleculeObject_bond to bond " << &_bond << " and side " << BondSide << ".");
     127}
     128
     129void GLMoleculeObject_bond::update(Observable *publisher)
     130{
     131#ifdef LOG_OBSERVER
     132  if (publisher == static_cast<const Observable *>(&_bond)) {
     133    observerLog().addMessage() << "++ Update of Observer "
     134        << observerLog().getName(static_cast<Observer*>(this))
     135        << " from bond.";
     136  } else if (publisher == leftatom) {
     137    observerLog().addMessage() << "++ Update of Observer "
     138        << observerLog().getName(static_cast<Observer*>(this))
     139        << " from leftatom " << _bond.leftatom->getId() << ".";
     140  } else if (publisher == rightatom) {
     141    observerLog().addMessage() << "++ Update of Observer " <<
     142        observerLog().getName(static_cast<Observer*>(this))
     143        << " from rightatom " << _bond.rightatom->getId() << ".";
     144  } else
     145    observerLog().addMessage() << "++ Update of Observer " <<
     146    observerLog().getName(static_cast<Observer*>(this)) << " from unknown source.";
     147#endif
     148}
     149
     150void GLMoleculeObject_bond::subjectKilled(Observable *publisher)
     151{
    139152  delete this;
    140153}
     
    143156{
    144157#ifdef LOG_OBSERVER
    145   observerLog().addMessage() << "++ Update of Observer "<< observerLog().getName(this)
    146       << " received notification from bond " << *_bond << " for channel "
    147       << notification->getChannelNo() << ".";
     158  if (publisher == static_cast<const Observable *>(&_bond)) {
     159    observerLog().addMessage() << "++ Update of Observer "
     160        << observerLog().getName(static_cast<Observer*>(this))
     161        << " received notification from bond for channel "
     162        << notification->getChannelNo() << ".";
     163  } else if (publisher == leftatom) {
     164    observerLog().addMessage() << "++ Update of Observer "
     165        << observerLog().getName(static_cast<Observer*>(this))
     166        << " received notification from leftatom " << _bond.leftatom->getId() << " for channel "
     167        << notification->getChannelNo() << ".";
     168  } else if (publisher == rightatom) {
     169    observerLog().addMessage() << "++ Update of Observer "
     170        << observerLog().getName(static_cast<Observer*>(this))
     171        << " received notification from rightatom " << _bond.rightatom->getId() << " for channel "
     172        << notification->getChannelNo() << ".";
     173  } else
     174    observerLog().addMessage() << "++ Update of Observer "
     175        << observerLog().getName(static_cast<Observer*>(this))
     176        << " received notification from unknown source.";
    148177#endif
    149   if (publisher == dynamic_cast<const Observable *>(_bond.get())){
    150     // from the bond
    151     switch (notification->getChannelNo()) {
    152       case BondObservable::BondRemoved:
    153         LOG(2, "INFO: Received notification of BondRemoved from " << *_bond << ".");
    154         switch (BondSide) {
    155           case left:
    156             emit BondRemoved(_bond->leftatom->getId(), _bond->rightatom->getId());
    157             break;
    158           case right:
    159             emit BondRemoved(_bond->rightatom->getId(), _bond->leftatom->getId());
    160             break;
    161           default:
    162             ASSERT(0,
    163                 "GLMoleculeObject_bond::recieveNotification() - side is not a valid argument: "+toString(BondSide)+".");
    164             break;
    165         }
    166 
    167         // Don't let the destructor automatically sign off from a dead bond!
    168         _bond->leftatom->signOff(this, AtomObservable::PositionChanged);
    169         _bond->rightatom->signOff(this, AtomObservable::PositionChanged);
    170         _bond.reset();
    171         delete this;
    172         break;
    173           default:
    174             break;
    175     }
    176   }else{
     178  if (publisher == static_cast<const Observable *>(&_bond)){
     179    delete this;
     180  } else {
     181    bool DoResetPosition = false;
    177182    // from an atom
    178183    switch (notification->getChannelNo()) {
    179       case AtomObservable::PositionChanged:
    180         LOG(2, "INFO: Received notification of PositionChanged.");
     184    case AtomObservable::PositionChanged:
     185      LOG(2, "INFO: Received notification of PositionChanged.");
     186      DoResetPosition = true;
     187      break;
     188    case AtomObservable::ElementChanged:
     189      LOG(2, "INFO: Received notification of ElementChanged.");
     190      DoResetPosition = true;
     191      break;
     192    default:
     193      break;
     194    }
     195    if (DoResetPosition) {
    181196        resetPosition();
    182197        emit changed();
     
    191206  switch (BondSide) {
    192207    case left:
    193       Position = _bond->leftatom->getPosition();
    194       OtherPosition = _bond->rightatom->getPosition();
     208      Position = _bond.leftatom->getPosition();
     209      OtherPosition = _bond.rightatom->getPosition();
    195210      break;
    196211    case right:
    197       Position = _bond->rightatom->getPosition();
    198       OtherPosition = _bond->leftatom->getPosition();
     212      Position = _bond.rightatom->getPosition();
     213      OtherPosition = _bond.leftatom->getPosition();
    199214      break;
    200215    default:
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.hpp

    r411202d r70db8f  
    2121#include "types.hpp"
    2222
     23class atom;
    2324
    2425class GLMoleculeObject_bond : public GLMoleculeObject, public Observer
     
    4142private:
    4243  void resetPosition();
    43   bond::ptr _bond;
     44  const bond& _bond;
     45  /** Observable instance inside atom_observable for left bond partner.
     46   * We require this knowledge as subjectKilled is called by Observable, not
     47   * by AtomObservable which has already been destroyed at this time.
     48   *
     49   */
     50  const Observable *leftatom;
     51  /** Observable instance inside atom_observable for right bond partner.
     52   * We require this knowledge as subjectKilled is called by Observable, not
     53   * by AtomObservable which has already been destroyed at this time.
     54   *
     55   */
     56  const Observable *rightatom;
     57  //!> id of left bond partner for safely emitting BondRemoved sigbal
     58  const atomId_t leftatomId;
     59  //!> id of right bond partner for safely emitting BondRemoved sigbal
     60  const atomId_t rightatomId;
    4461  const enum SideOfBond BondSide;
    4562};
Note: See TracChangeset for help on using the changeset viewer.