source: src/UIElements/Qt4/InstanceBoard/ObservedValue_wCallback.hpp@ 0af22d

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
Last change on this file since 0af22d was 04c3a3, checked in by Frederik Heber <heber@…>, 9 years ago

QtObservedAtom, ..Molecule, and ObservedValue_wCallback have flag to indicate invalid callback.

  • due to Qt's signal/slot destruction, which follows no proper order, we need to invalidate callback when their owners are destroyed. Each has a note-function() that flips the boolean to show the callbacks invalidity.
  • TODO: So far this is not nice, especially w.r.t to ObservedValue_wCallback because of templatization. We cannot place them in a loop and this makes this very error-prone once more Values are added ...
  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * ObservedValue_wCallback.hpp
3 *
4 * Created on: Oct 16, 2015
5 * Author: heber
6 */
7
8
9#ifndef OBSERVEDVALUE_WCALLBACK_HPP_
10#define OBSERVEDVALUE_WCALLBACK_HPP_
11
12// include config.h
13#ifdef HAVE_CONFIG_H
14#include <config.h>
15#endif
16
17#include "CodePatterns/Assert.hpp"
18#include "CodePatterns/ObservedValue.hpp"
19#include "CodePatterns/Observer/Observable.hpp"
20
21#include <algorithm>
22#include <string>
23
24#include <boost/bind.hpp>
25#include <boost/function.hpp>
26
27/** We derive from ObservedValue in order to tell owning instance about
28 * subjectKilled() having been called.
29 */
30template <class T, class id=T>
31class ObservedValue_wCallback : public ObservedValue<T>
32{
33public:
34 ObservedValue_wCallback(
35 const Observable * const _owner,
36 const boost::function<T()> &_recalcMethod,
37 const std::string &_name,
38 const T &_initialvalue,
39 const Observable::channels_t &_channels,
40 const boost::function<void(const id)> &_callback,
41 const boost::function<const id()> &_getId) :
42 ObservedValue<T>(_owner, _recalcMethod, _name, _initialvalue, _channels),
43 signedOnChannels(std::max((size_t)1,_channels.size())),
44 callback(_callback),
45 CallbackIsGone(false),
46 getId(_getId)
47 {}
48 virtual ~ObservedValue_wCallback()
49 {}
50
51 /** Function is called by callback owner to inform about its destruction.
52 *
53 * \note callback must not be used after this
54 */
55 void noteCallBackIsGone()
56 { CallbackIsGone = true; }
57
58protected:
59 virtual void subjectKilled(Observable *publisher)
60 {
61 ASSERT(signedOnChannels > 0,
62 "ObservedValue_wCallback::subjectKilled() - signedOnChannels is already zero.");
63 if ((--signedOnChannels) == 0) {
64 ObservedValue<T>::subjectKilled(publisher);
65 if (!CallbackIsGone)
66 callback(getId());
67 }
68 }
69
70private:
71 //!> if we are signOn() to multiple channels, count down before callback
72 size_t signedOnChannels;
73 //!> callback function to tell other entity about subjectKilled
74 const boost::function<void(const id)> callback;
75 //!> is callback still alive or not
76 bool CallbackIsGone;
77 //!> callback function to get id
78 const boost::function<const id()> getId;
79};
80
81/** Specialization of ObservedValue_wCallback for the index ObservedValue.
82 *
83 * The index serves as the unique identifier for the object instance whose
84 * properties are monitored in ObservedValue. Hence, how to give a subjectKilled()
85 * with an external getId() function? For the index the ObservedValue::get() is
86 * the getId() we need to call! Hence, we may simply connect these internally
87 * in this partial template specialization.
88 *
89 * Because atomicNumber_t, atomId_t and moleculeId_t are not unique types but
90 * -- at the writing of this class -- just typedefs, we have to resort to the
91 * trick with two constructors, one taking an external getId(), the other
92 * routing the getId() internally by binding to ObservedValue<T>::get().
93 */
94template <class T>
95class ObservedValue_wCallback<T,T> : public ObservedValue<T>
96{
97public:
98 ObservedValue_wCallback(
99 const Observable * const _owner,
100 const boost::function<T()> &_recalcMethod,
101 const std::string &_name,
102 const T &_initialvalue,
103 const Observable::channels_t &_channels,
104 const boost::function<void(const T)> &_callback,
105 const boost::function<const T()> &_getId) :
106 ObservedValue<T>(_owner, _recalcMethod, _name, _initialvalue, _channels),
107 signedOnChannels(std::max((size_t)1,_channels.size())),
108 callback(_callback),
109 CallbackIsGone(false),
110 getId(_getId)
111 {}
112 ObservedValue_wCallback(
113 const Observable * const _owner,
114 const boost::function<T()> &_recalcMethod,
115 const std::string &_name,
116 const T &_initialvalue,
117 const Observable::channels_t &_channels,
118 const boost::function<void(const T)> &_callback) :
119 ObservedValue<T>(_owner, _recalcMethod, _name, _initialvalue, _channels),
120 signedOnChannels(std::max((size_t)1,_channels.size())),
121 callback(_callback),
122 CallbackIsGone(false),
123 getId(boost::bind(&ObservedValue<T>::get, this))
124 {}
125 virtual ~ObservedValue_wCallback()
126 {}
127
128 /** Function is called by callback owner to inform about its destruction.
129 *
130 * \note callback must not be used after this
131 */
132 void noteCallBackIsGone()
133 { CallbackIsGone = true; }
134
135protected:
136 virtual void subjectKilled(Observable *publisher)
137 {
138 ObservedValue<T>::subjectKilled(publisher);
139 ASSERT(signedOnChannels > 0,
140 "ObservedValue_wCallback::subjectKilled() - signedOnChannels is already zero.");
141 if ((--signedOnChannels) == 0)
142 ObservedValue<T>::subjectKilled(publisher);
143 if (!CallbackIsGone)
144 callback(getId());
145 }
146
147private:
148 //!> if we are signOn() to multiple channels, count down before callback
149 size_t signedOnChannels;
150 //!> callback function to tell other entity about subjectKilled
151 const boost::function<void(const T)> callback;
152 //!> is callback still alive or not
153 bool CallbackIsGone;
154 //!> callback function to get id
155 const boost::function<const T()> getId;
156};
157
158#endif /* OBSERVEDVALUE_WCALLBACK_HPP_ */
Note: See TracBrowser for help on using the repository browser.