source: src/UIElements/Qt4/InstanceBoard/ObservedValuesContainer_impl.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 0af22d, checked in by Frederik Heber <heber@…>, 9 years ago

FIX: ObservedValuesContainer uses deque for internal observed values.

  • it may happen that an atom is created before the _visual representation_ got destroyed (and hence it's QtObserved... would be destroyed). In that case the QtObservedInstanceBoard fails with an assertion.
  • Now, we use a deque. At the front end, we have all the observedvalues that have not yet been deleted, on the back end we have the observedvalues to the currently active instance.
  • removed unused getRefCount().
  • Property mode set to 100644
File size: 8.9 KB
Line 
1/*
2 * ObservedValuesContainer_impl.hpp
3 *
4 * Created on: Oct 29, 2015
5 * Author: heber
6 */
7
8
9#ifndef OBSERVEDVALUESCONTAINER_IMPL_HPP_
10#define OBSERVEDVALUESCONTAINER_IMPL_HPP_
11
12// include config.h
13#ifdef HAVE_CONFIG_H
14#include <config.h>
15#endif
16
17#include "ObservedValuesContainer.hpp"
18
19#include "CodePatterns/Assert.hpp"
20
21template <class T, typename id>
22ObservedValuesContainer<T,id>::ObservedValuesContainer(
23 const std::string _name,
24 QtObservedInstanceBoard &_board,
25 const onDestroy_t _onDestroy) :
26 NameOfType(_name),
27 board(_board),
28 onDestroy(_onDestroy)
29{}
30
31template <class T, typename id>
32ObservedValuesContainer<T,id>::~ObservedValuesContainer()
33{
34 for (typename CountedObservedValues_t::iterator iter = ObservedValues.begin();
35 iter != ObservedValues.end(); ++iter) {
36 ASSERT( !iter->second.empty(),
37 "~ObservedValuesContainer() of "+NameOfType+" "+toString(iter->first)
38 +" has an empty list in ObservedValues.");
39 for (typename RefCountedObservedValues_t::iterator listiter = iter->second.begin();
40 listiter != iter->second.end(); ++listiter) {
41 listiter->first->noteBoardIsGone();
42 }
43 }
44}
45
46template <class T, typename id>
47typename T::ptr ObservedValuesContainer<T,id>::get(const id _id)
48{
49 typename CountedObservedValues_t::iterator iter = ObservedValues.find(_id);
50 ASSERT( iter != ObservedValues.end(),
51 "ObservedValuesContainer::getObservedValues() - no observed values present for "
52 +NameOfType+" "+toString(_id));
53 ASSERT( !iter->second.empty(),
54 "ObservedValuesContainer<T,id>::get() of "+NameOfType+" "+toString(_id)
55 +" has an empty list in ObservedValues.");
56 const typename T::ptr &obsvalues = iter->second.back().first;
57
58 return obsvalues;
59}
60
61template <class T, typename id>
62void ObservedValuesContainer<T,id>::markObservedValuesAsConnected(
63 const id _id)
64{
65 LOG(3, "DEBUG: ObservedValuesContainer got markObservedValuesAsConnected() for an observed value of "
66 << NameOfType << " " << _id);
67 typename CountedObservedValues_t::iterator iter = ObservedValues.find(_id);
68 ASSERT (iter != ObservedValues.end(),
69 "ObservedValuesContainer<T,id>::markObservedValuesAsConnected() - Observed value of "
70 +NameOfType+" "+toString(_id)+" is not present yet.");
71 ASSERT( !iter->second.empty(),
72 "ObservedValuesContainer<T,id>::markObservedValuesAsConnected() of "+NameOfType
73 +" "+toString(_id)+" has an empty list in ObservedValues.");
74 ++(iter->second.back().second);
75}
76
77template <class T, typename id>
78bool ObservedValuesContainer<T,id>::checkRefCount(
79 const id _id) const
80{
81 typename CountedObservedValues_t::const_iterator iter = ObservedValues.find(_id);
82 ASSERT( !iter->second.empty(),
83 "ObservedValuesContainer<T,id>::checkRefCount() of "+NameOfType
84 +" "+toString(_id)+" has an empty list in ObservedValues.");
85 return ((iter != ObservedValues.end()) && (iter->second.front().second == 0));
86}
87
88template <class T, typename id>
89void ObservedValuesContainer<T,id>::markObservedValuesAsDisconnected(
90 const id _id)
91{
92 LOG(3, "DEBUG: ObservedValuesContainer got markObservedValuesAsDisconnected() for an observed value of "
93 << NameOfType << " " << _id);
94 typename CountedObservedValues_t::iterator iter = ObservedValues.find(_id);
95 ASSERT (iter != ObservedValues.end(),
96 "ObservedValuesContainer<T,id>::markObservedValuesAsDisconnected() - Observed value of "
97 +NameOfType+" "+toString(_id)+" is not present yet.");
98 ASSERT( !iter->second.empty(),
99 "ObservedValuesContainer<T,id>::markObservedValuesAsDisconnected() of "+NameOfType
100 +" "+toString(_id)+" has an empty list in ObservedValues.");
101 ASSERT (iter->second.front().second != 0,
102 "ObservedValuesContainer<T,id>::markObservedValuesAsDisconnected() - Observed value of "
103 +NameOfType+" "+toString(_id)+" is already signOff() from all.");
104 --(iter->second.front().second);
105
106 if (checkRefCount(_id) && checksubjectKilled(_id) && checkMarkedForErase(_id))
107 removeObservedValues(_id);
108}
109
110template <class T, typename id>
111bool ObservedValuesContainer<T,id>::checksubjectKilled(
112 const id _id) const
113{
114 typename subjectKilledCount_t::const_iterator iter = subjectKilledCount.find(_id);
115 return ((iter != subjectKilledCount.end()) && (iter->second == T::MAX_ObservedTypes));
116}
117
118template <class T, typename id>
119void ObservedValuesContainer<T,id>::countsubjectKilled(const id _id)
120{
121 LOG(3, "DEBUG: ObservedValuesContainer got subjectKilled() for an observed value of "
122 << NameOfType << " " << _id);
123 typename subjectKilledCount_t::iterator iter = subjectKilledCount.find(_id);
124 if (iter == subjectKilledCount.end()) {
125 std::pair<typename subjectKilledCount_t::iterator, bool> inserter =
126 subjectKilledCount.insert( std::make_pair(_id, 0) );
127 iter = inserter.first;
128 }
129 ASSERT (iter->second < T::MAX_ObservedTypes,
130 "ObservedValuesContainer<T,id>::countsubjectKilled() - all subjectKilled() for "
131 +NameOfType+" "+toString(_id)+" for each observed channel came in already.");
132 ++(iter->second);
133
134 if (checkRefCount(_id) && checksubjectKilled(_id) && checkMarkedForErase(_id))
135 removeObservedValues(_id);
136}
137
138template <class T, typename id>
139void ObservedValuesContainer<T,id>::removeObservedValues(const id _id)
140{
141 LOG(3, "DEBUG: ObservedValuesContainer removes " << NameOfType << " " << _id);
142 // call callback function
143 onDestroy(_id);
144 subjectKilledCount.erase(_id);
145 typename CountedObservedValues_t::iterator iter = ObservedValues.find(_id);
146 ASSERT( !iter->second.empty(),
147 "ObservedValuesContainer<T,id>::removeObservedValues() of "+NameOfType
148 +" for "+toString(_id)+" has an empty list in ObservedValues.");
149 if (iter->second.size() == 1)
150 ObservedValues.erase(iter);
151 else {
152 //if more than one, erase always the first one
153 iter->second.pop_front();
154 }
155 MarkedForErase.erase(_id);
156}
157
158template <class T, typename id>
159void ObservedValuesContainer<T,id>::eraseObservedValues(const id _id)
160{
161#ifndef NDEBUG
162 std::pair< typename std::set<id>::iterator, bool > inserter =
163#endif
164 MarkedForErase.insert(_id);
165 ASSERT( inserter.second,
166 "ObservedValuesContainer<T,id>::eraseObservedValues() - received twice for "
167 +NameOfType+" "+toString(_id)+".");
168
169 if (checkRefCount(_id) && checksubjectKilled(_id) && checkMarkedForErase(_id))
170 removeObservedValues(_id);
171}
172
173template <class T, typename id>
174bool ObservedValuesContainer<T,id>::checkMarkedForErase(const id _id) const
175{
176 return MarkedForErase.count(_id);
177}
178
179template <class T, typename id>
180void ObservedValuesContainer<T,id>::insert(const id _id, const typename T::ptr &_obsvalues)
181{
182 std::pair<typename CountedObservedValues_t::iterator, bool> inserter =
183 ObservedValues.insert(
184 std::make_pair( _id, RefCountedObservedValues_t(1,std::make_pair(_obsvalues,0)) ) );
185 if (!inserter.second) {
186 // already an entry present? add to deque
187 inserter.first->second.push_back( std::make_pair(_obsvalues,0) );
188 }
189 _obsvalues->activateObserver();
190}
191
192template <class T, typename id>
193bool ObservedValuesContainer<T,id>::changeIdentifier(const id _oldid, const id _newid)
194{
195 const typename CountedObservedValues_t::iterator Colditer = ObservedValues.find(_oldid);
196 const typename CountedObservedValues_t::iterator Cnewiter = ObservedValues.find(_newid);
197 const typename subjectKilledCount_t::iterator Solditer = subjectKilledCount.find(_oldid);
198 const typename subjectKilledCount_t::iterator Snewiter = subjectKilledCount.find(_newid);
199 const typename MarkedForErase_t::iterator Eolditer = MarkedForErase.find(_oldid);
200 const typename MarkedForErase_t::iterator Enewiter = MarkedForErase.find(_newid);
201 bool status = ((Colditer != ObservedValues.end()) && (Cnewiter == ObservedValues.end()));
202 status &= ((Solditer != subjectKilledCount.end()) && (Snewiter == subjectKilledCount.end()));
203 status &= ((Eolditer != MarkedForErase.end()) && (Enewiter == MarkedForErase.end()));
204 // change id here only if still present
205 if (status) {
206 {
207 // TODO: Actually, we need to think whether we do not have to to split the
208 // deque in two parts: the last entry having the newid, while all other
209 // ones retain the old one until they get removed. But we need to check
210 // whether changing ids "there" is possible when the QtObserved... is under
211 // removal.
212 RefCountedObservedValues_t obsvalues = Colditer->second;
213 ObservedValues.erase(Colditer);
214 ObservedValues.insert( std::make_pair(_newid, obsvalues) );
215 }
216 {
217 const size_t countvalue = Solditer->second;
218 subjectKilledCount.erase(Solditer);
219 subjectKilledCount.insert( std::make_pair(_newid, countvalue) );
220 }
221 {
222 MarkedForErase.erase(Eolditer);
223 MarkedForErase.insert(_newid);
224 }
225 return true;
226 } else
227 return false;
228}
229
230template <class T, typename id>
231bool ObservedValuesContainer<T,id>::isPresent(const id _id) const
232{
233 typename CountedObservedValues_t::const_iterator iter = ObservedValues.find(_id);
234 return (iter != ObservedValues.end());
235}
236
237#endif /* OBSERVEDVALUESCONTAINER_IMPL_HPP_ */
Note: See TracBrowser for help on using the repository browser.