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
RevLine 
[41e287]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
[65c323]21template <class T, typename id>
22ObservedValuesContainer<T,id>::ObservedValuesContainer(
23 const std::string _name,
[68418e]24 QtObservedInstanceBoard &_board,
25 const onDestroy_t _onDestroy) :
[65c323]26 NameOfType(_name),
[68418e]27 board(_board),
28 onDestroy(_onDestroy)
[65c323]29{}
30
[04c3a3]31template <class T, typename id>
32ObservedValuesContainer<T,id>::~ObservedValuesContainer()
33{
34 for (typename CountedObservedValues_t::iterator iter = ObservedValues.begin();
[0af22d]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 }
[04c3a3]44}
45
[41e287]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));
[0af22d]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;
[65c323]57
[68418e]58 return obsvalues;
[65c323]59}
60
[41e287]61template <class T, typename id>
[68418e]62void ObservedValuesContainer<T,id>::markObservedValuesAsConnected(
63 const id _id)
[41e287]64{
[4e6ffe]65 LOG(3, "DEBUG: ObservedValuesContainer got markObservedValuesAsConnected() for an observed value of "
66 << NameOfType << " " << _id);
67 typename CountedObservedValues_t::iterator iter = ObservedValues.find(_id);
[68418e]68 ASSERT (iter != ObservedValues.end(),
69 "ObservedValuesContainer<T,id>::markObservedValuesAsConnected() - Observed value of "
70 +NameOfType+" "+toString(_id)+" is not present yet.");
[0af22d]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);
[41e287]75}
76
77template <class T, typename id>
[68418e]78bool ObservedValuesContainer<T,id>::checkRefCount(
79 const id _id) const
80{
81 typename CountedObservedValues_t::const_iterator iter = ObservedValues.find(_id);
[0af22d]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));
[68418e]86}
87
88template <class T, typename id>
89void ObservedValuesContainer<T,id>::markObservedValuesAsDisconnected(
90 const id _id)
[41e287]91{
[4e6ffe]92 LOG(3, "DEBUG: ObservedValuesContainer got markObservedValuesAsDisconnected() for an observed value of "
93 << NameOfType << " " << _id);
[41e287]94 typename CountedObservedValues_t::iterator iter = ObservedValues.find(_id);
[68418e]95 ASSERT (iter != ObservedValues.end(),
96 "ObservedValuesContainer<T,id>::markObservedValuesAsDisconnected() - Observed value of "
97 +NameOfType+" "+toString(_id)+" is not present yet.");
[0af22d]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,
[68418e]102 "ObservedValuesContainer<T,id>::markObservedValuesAsDisconnected() - Observed value of "
103 +NameOfType+" "+toString(_id)+" is already signOff() from all.");
[0af22d]104 --(iter->second.front().second);
[68418e]105
[4e6ffe]106 if (checkRefCount(_id) && checksubjectKilled(_id) && checkMarkedForErase(_id))
[68418e]107 removeObservedValues(_id);
[41e287]108}
109
110template <class T, typename id>
[68418e]111bool ObservedValuesContainer<T,id>::checksubjectKilled(
112 const id _id) const
[41e287]113{
[68418e]114 typename subjectKilledCount_t::const_iterator iter = subjectKilledCount.find(_id);
115 return ((iter != subjectKilledCount.end()) && (iter->second == T::MAX_ObservedTypes));
[41e287]116}
117
[90821d]118template <class T, typename id>
[68418e]119void ObservedValuesContainer<T,id>::countsubjectKilled(const id _id)
[90821d]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 }
[68418e]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.");
[90821d]132 ++(iter->second);
133
[4e6ffe]134 if (checkRefCount(_id) && checksubjectKilled(_id) && checkMarkedForErase(_id))
[68418e]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);
[0af22d]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 }
[4e6ffe]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);
[90821d]177}
178
[41e287]179template <class T, typename id>
[0af22d]180void ObservedValuesContainer<T,id>::insert(const id _id, const typename T::ptr &_obsvalues)
[41e287]181{
182 std::pair<typename CountedObservedValues_t::iterator, bool> inserter =
183 ObservedValues.insert(
[0af22d]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 }
[68418e]189 _obsvalues->activateObserver();
[41e287]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);
[90821d]197 const typename subjectKilledCount_t::iterator Solditer = subjectKilledCount.find(_oldid);
198 const typename subjectKilledCount_t::iterator Snewiter = subjectKilledCount.find(_newid);
[4e6ffe]199 const typename MarkedForErase_t::iterator Eolditer = MarkedForErase.find(_oldid);
200 const typename MarkedForErase_t::iterator Enewiter = MarkedForErase.find(_newid);
[41e287]201 bool status = ((Colditer != ObservedValues.end()) && (Cnewiter == ObservedValues.end()));
[90821d]202 status &= ((Solditer != subjectKilledCount.end()) && (Snewiter == subjectKilledCount.end()));
[4e6ffe]203 status &= ((Eolditer != MarkedForErase.end()) && (Enewiter == MarkedForErase.end()));
[41e287]204 // change id here only if still present
205 if (status) {
206 {
[0af22d]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.
[41e287]212 RefCountedObservedValues_t obsvalues = Colditer->second;
213 ObservedValues.erase(Colditer);
214 ObservedValues.insert( std::make_pair(_newid, obsvalues) );
215 }
[90821d]216 {
217 const size_t countvalue = Solditer->second;
218 subjectKilledCount.erase(Solditer);
219 subjectKilledCount.insert( std::make_pair(_newid, countvalue) );
220 }
[4e6ffe]221 {
222 MarkedForErase.erase(Eolditer);
223 MarkedForErase.insert(_newid);
224 }
[41e287]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.