source: src/UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.cpp@ 41e287

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 41e287 was 41e287, checked in by Frederik Heber <heber@…>, 9 years ago

Extracted functions handling refcounting of ObservedValues into ObservedValuesContainer.

  • this avoids a lot of code duplication.
  • Property mode set to 100644
File size: 15.6 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2015 Frederik Heber. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * QtObservedInstanceBoard.cpp
25 *
26 * Created on: Oct 17, 2015
27 * Author: heber
28 */
29
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include "QtObservedInstanceBoard.hpp"
37
38#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject_atom.hpp"
39#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.hpp"
40
41#include "CodePatterns/MemDebug.hpp"
42
43#include "CodePatterns/Log.hpp"
44
45#include "Atom/atom.hpp"
46#include "Descriptors/AtomIdDescriptor.hpp"
47#include "Descriptors/MoleculeIdDescriptor.hpp"
48#include "molecule.hpp"
49#include "UIElements/Qt4/InstanceBoard/ObservedValuesContainer_impl.hpp"
50#include "World.hpp"
51
52QtObservedInstanceBoard::QtObservedInstanceBoard(QWidget * _parent) :
53 QWidget(_parent),
54 Observer("QtObservedInstanceBoard"),
55 WorldSignedOn(false),
56 atomObservedValues("atom"),
57 moleculeObservedValues("molecule"),
58 atomSubjectKilled(
59 boost::bind(&QtObservedInstanceBoard::atomcountsubjectKilled, this, _1)),
60 moleculeSubjectKilled(
61 boost::bind(&QtObservedInstanceBoard::moleculecountsubjectKilled, this, _1)),
62 lastremovedatom((atomId_t)-1),
63 lastremovedatomsmolecule( std::make_pair((moleculeId_t)-1,(atomId_t)-1) ),
64 lastremovedmolecule((moleculeId_t)-1)
65{
66 // be first (besides ObservedValues to know about new insertions)
67 World::getInstance().signOn(this, World::AtomInserted, GlobalObservableInfo::PriorityLevel(int(-10)));
68 World::getInstance().signOn(this, World::AtomRemoved, GlobalObservableInfo::PriorityLevel(int(-10)));
69 World::getInstance().signOn(this, World::MoleculeInserted, GlobalObservableInfo::PriorityLevel(int(-10)));
70 World::getInstance().signOn(this, World::MoleculeRemoved, GlobalObservableInfo::PriorityLevel(int(-10)));
71 WorldSignedOn = true;
72}
73
74QtObservedInstanceBoard::~QtObservedInstanceBoard()
75{
76 if (WorldSignedOn) {
77 World::getInstance().signOff(this, World::AtomInserted);
78 World::getInstance().signOff(this, World::AtomRemoved);
79 World::getInstance().signOff(this, World::MoleculeInserted);
80 World::getInstance().signOff(this, World::MoleculeRemoved);
81 }
82 // sign off from all remaining molecules and atoms
83 for (SignedOn_t::iterator iter = AtomSignedOn.begin(); !AtomSignedOn.empty();
84 iter = AtomSignedOn.begin()) {
85 (*iter)->signOff(this, atom::IndexChanged);
86 AtomSignedOn.erase(iter);
87 }
88
89 for (SignedOn_t::iterator iter = MoleculeSignedOn.begin(); !MoleculeSignedOn.empty();
90 iter = MoleculeSignedOn.begin()) {
91 (*iter)->signOff(this, molecule::IndexChanged);
92 (*iter)->signOff(this, molecule::AtomInserted);
93 (*iter)->signOff(this, molecule::AtomRemoved);
94 MoleculeSignedOn.erase(*iter); //erase all instances
95 }
96}
97
98void QtObservedInstanceBoard::update(Observable *publisher)
99{
100 ASSERT(0,
101 "QtObservedInstanceBoard::update() - we are not signed on to general updates.");
102}
103
104void QtObservedInstanceBoard::subjectKilled(Observable *publisher)
105{
106 SignedOn_t::iterator iter = AtomSignedOn.find(publisher);
107 if ( iter != AtomSignedOn.end()) {
108 LOG(3, "DEBUG: InstanceBoard got subjectKilled() from atom " << publisher);
109 AtomSignedOn.erase(iter);
110 } else {
111 iter = MoleculeSignedOn.find(publisher);
112 if ( iter != MoleculeSignedOn.end()) {
113 LOG(3, "DEBUG: InstanceBoard got subjectKilled() from molecule " << publisher);
114 MoleculeSignedOn.erase(iter);
115 } else {
116 ASSERT(0,
117 "QtObservedInstanceBoard::subjectKilled() - could not find signedOn for atom/molecule "+toString(publisher));
118 }
119 }
120}
121
122void QtObservedInstanceBoard::recieveNotification(Observable *publisher, Notification_ptr notification)
123{
124 if (static_cast<World *>(publisher) == World::getPointer()) {
125 switch (notification->getChannelNo()) {
126 case World::MoleculeInserted:
127 {
128 const moleculeId_t _id = const_cast<const World &>(World::getInstance()).lastChangedMolId();
129 #ifdef LOG_OBSERVER
130 observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that molecule "+toString(_id)+" has been inserted.";
131 #endif
132 LOG(3, "DEBUG: InformationBoard got moleculeInserted signal for molecule " << _id);
133 const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
134 getMolecule(MoleculeById(_id));
135 if (_molecule != NULL) {
136 ObservedValues_t ObservedValues(GLMoleculeObject_molecule::MAX_ObservedTypes);
137 LOG(3, "DEBUG: InformationBoard initializes ObservedValues for molecule " << _id);
138 GLMoleculeObject_molecule::initObservedValues(
139 ObservedValues,
140 _id,
141 _molecule,
142 moleculeSubjectKilled);
143#ifndef NDEBUG
144 bool status =
145#endif
146 moleculeObservedValues.insert(_id, ObservedValues);
147 ASSERT( status,
148 "QtObservedInstanceBoard::recieveNotification() - could not insert ObservedValues for"
149 +toString(_id)+".");
150 // we need to check for index changes
151 LOG(3, "DEBUG: InformationBoard signOn()s to molecule " << _id);
152 _molecule->signOn(this, molecule::IndexChanged);
153 MoleculeSignedOn.insert( static_cast<Observable *>(const_cast<molecule *>(_molecule)) );
154 _molecule->signOn(this, molecule::AtomInserted);
155 MoleculeSignedOn.insert( static_cast<Observable *>(const_cast<molecule *>(_molecule)) );
156 _molecule->signOn(this, molecule::AtomRemoved);
157 MoleculeSignedOn.insert( static_cast<Observable *>(const_cast<molecule *>(_molecule)) );
158
159 emit moleculeInserted(_id);
160 } else {
161 ELOG(1, "QtObservedInstanceBoard got MoleculeInserted for unknown molecule id " << _id);
162 }
163 break;
164 }
165 case World::MoleculeRemoved:
166 {
167 const moleculeId_t _id = const_cast<const World &>(World::getInstance()).lastChangedMolId();
168 LOG(3, "DEBUG: InformationBoard got MoleculeRemoved signal for molecule " << _id);
169 // note down such that ObservedValues are simply dropped
170 lastremovedmolecule = _id;
171 break;
172 }
173 case World::AtomInserted:
174 {
175 const atomId_t _id = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
176 #ifdef LOG_OBSERVER
177 observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
178 #endif
179 LOG(3, "DEBUG: InformationBoard got atomInserted signal for atom " << _id);
180 const atom * const _atom = const_cast<const World &>(World::getInstance()).
181 getAtom(AtomById(_id));
182 if (_atom!= NULL) {
183 ObservedValues_t ObservedValues(GLMoleculeObject_atom::MAX_ObservedTypes);
184 LOG(3, "DEBUG: InformationBoard initializes ObservedValues for atom " << _id);
185 GLMoleculeObject_atom::initObservedValues(
186 ObservedValues,
187 _id,
188 _atom,
189 atomSubjectKilled);
190#ifndef NDEBUG
191 bool status =
192#endif
193 atomObservedValues.insert(_id, ObservedValues);
194 ASSERT( status,
195 "QtObservedInstanceBoard::recieveNotification() - could not insert ObservedValues for"
196 +toString(_id)+".");
197 // we need to check for index changes
198 LOG(3, "DEBUG: InformationBoard signOn()s to atom " << _id);
199 _atom->signOn(this, atom::IndexChanged);
200 AtomSignedOn.insert( static_cast<Observable *>(const_cast<atom *>(_atom)) );
201 } else {
202 ELOG(1, "QtObservedInstanceBoard got AtomInserted for unknown atom id " << _id);
203 }
204 break;
205 }
206 case World::AtomRemoved:
207 {
208 const atomId_t _id = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
209 LOG(3, "DEBUG: InformationBoard got AtomRemoved signal for atom " << _id);
210 // note down such that ObservedValues are simply dropped
211 lastremovedatom = _id;
212 break;
213 }
214 default:
215 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here for World.");
216 break;
217 }
218 } else if (dynamic_cast<molecule *>(publisher) != NULL) {
219 const moleculeId_t molid = const_cast<const World &>(World::getInstance()).lastChangedMolId();
220 switch (notification->getChannelNo()) {
221 case molecule::AtomInserted:
222 {
223 const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
224 getMolecule(MoleculeById(molid));
225 if (_molecule != NULL) {
226 const atomId_t atomid = const_cast<const molecule *>(_molecule)->lastChangedAtomId();
227 LOG(3, "DEBUG: InformationBoard got AtomInserted signal for atom "
228 << atomid << " from molecule " << molid);
229 // check whether atom's observedvalues are present
230 ASSERT( atomObservedValues.isPresent(atomid),
231 "QtObservedInstanceBoard::recieveNotification() - ObservedValues for atom "
232 +toString(atomid)+" are not present yet.");
233 // and emit
234 emit atomInserted(molid, atomid);
235 } else {
236 ELOG(2, "QtObservedInstanceBoard::recieveNotification() - molecule "
237 << molid << " has disappeared.");
238 }
239 break;
240 }
241 case molecule::AtomRemoved:
242 {
243 const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
244 getMolecule(MoleculeById(molid));
245 if (_molecule != NULL) {
246 const atomId_t atomid = const_cast<const molecule *>(_molecule)->lastChangedAtomId();
247 LOG(3, "DEBUG: InformationBoard got AtomRemoved signal for atom "
248 << atomid << " from molecule " << molid);
249 lastremovedatomsmolecule = std::make_pair(molid, atomid);
250 }
251 break;
252 }
253 case molecule::IndexChanged:
254 {
255 // molecule has changed its index
256 const moleculeId_t newmoleculeId = dynamic_cast<molecule *>(publisher)->getId();
257 LOG(3, "DEBUG: InformationBoard got IndexChanged from molecule " << molid << " to " << newmoleculeId);
258#ifndef NDEBUG
259 bool status =
260#endif
261 moleculeObservedValues.changeIdentifier(molid, newmoleculeId);
262 ASSERT( status,
263 "QtObservedInstanceBoard::recieveNotification() - cannot change molecule's id "
264 +toString(molid)+" "+toString(newmoleculeId)+" in moleculeObservedValues.");
265 // no need update SignedOn, ref does not change
266 emit moleculeIndexChanged(molid, newmoleculeId);
267 break;
268 }
269 default:
270 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here.");
271 break;
272 }
273 } else if (dynamic_cast<atom *>(publisher) != NULL) {
274 const atomId_t oldatomId = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
275 switch (notification->getChannelNo()) {
276 case AtomObservable::IndexChanged:
277 {
278 const atomId_t newatomId = dynamic_cast<atom *>(publisher)->getId();
279 LOG(3, "DEBUG: InformationBoard got IndexChanged from atom " << oldatomId << " to " << newatomId);
280 atomObservedValues.changeIdentifier(oldatomId, newatomId);
281 // no need update SignedOn, ref does not change
282 emit atomIndexChanged(oldatomId, newatomId);
283 break;
284 }
285 default:
286 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here.");
287 break;
288 }
289 } else {
290 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - notification from unknown source.");
291 }
292}
293
294void QtObservedInstanceBoard::atomcountsubjectKilled(const atomId_t _atomid)
295{
296 LOG(3, "DEBUG: InformationBoard got subjectKilled() for a value of atom " << _atomid);
297 atomsubjectKilledCount_t::iterator iter = atomsubjectKilledCount.find(_atomid);
298 if (iter == atomsubjectKilledCount.end()) {
299 std::pair<atomsubjectKilledCount_t::iterator, bool> inserter =
300 atomsubjectKilledCount.insert( std::make_pair(_atomid, 0) );
301 iter = inserter.first;
302 }
303 ++(iter->second);
304
305 if (iter->second > GLMoleculeObject_atom::MAX_ObservedTypes) {
306 ASSERT( atomObservedValues.getRefCount(_atomid) == 0,
307 "QtObservedInstanceBoard::atomcountsubjectKilled() - observed Values for atom "
308 +toString(_atomid)+" are still being held somewhere.");
309 if (_atomid == lastremovedatomsmolecule.second)
310 emit atomRemoved(lastremovedatomsmolecule.first, lastremovedatomsmolecule.second);
311 else
312 ELOG(2, "QtObservedInstanceBoard::atomcountsubjectKilled() - id " << _atomid
313 << " not fitting with " << lastremovedatomsmolecule);
314 atomsubjectKilledCount.erase(iter);
315 }
316}
317
318void QtObservedInstanceBoard::moleculecountsubjectKilled(const moleculeId_t _molid)
319{
320 LOG(3, "DEBUG: InformationBoard got subjectKilled() for a value of molecule " << _molid);
321 moleculesubjectKilledCount_t::iterator iter = moleculesubjectKilledCount.find(_molid);
322 if (iter == moleculesubjectKilledCount.end()) {
323 std::pair<moleculesubjectKilledCount_t::iterator, bool> inserter =
324 moleculesubjectKilledCount.insert( std::make_pair(_molid, 0) );
325 iter = inserter.first;
326 }
327 ++(iter->second);
328
329 if (iter->second > GLMoleculeObject_molecule::MAX_ObservedTypes) {
330 ASSERT( moleculeObservedValues.getRefCount(_molid) == 0,
331 "QtObservedInstanceBoard::moleculecountsubjectKilled() - observed Values for molecule "
332 +toString(_molid)+" are still being held somewhere.");
333 // then free the instance
334 emit moleculeRemoved(_molid);
335 moleculesubjectKilledCount.erase(iter);
336 }
337}
338
339QtObservedAtom::ptr QtObservedInstanceBoard::getObservedAtom(const atomId_t _id)
340{
341 return atomObservedValues.get(_id);
342}
343
344QtObservedMolecule::ptr QtObservedInstanceBoard::getObservedMolecule(const moleculeId_t _id)
345{
346 return moleculeObservedValues.get(_id);
347}
348
349void QtObservedInstanceBoard::returnObservedAtom(const atomId_t _id)
350{
351 atomObservedValues.yield(_id);
352}
353
354void QtObservedInstanceBoard::returnObservedMolecule(const moleculeId_t _id)
355{
356 moleculeObservedValues.yield(_id);
357}
358
359ObservedValues_t QtObservedInstanceBoard::getAtomObservedValues(const atomId_t _id)
360{
361 return atomObservedValues.getObservedValues(_id);
362}
363ObservedValues_t QtObservedInstanceBoard::getMoleculeObservedValues(const moleculeId_t _id)
364{
365 return moleculeObservedValues.getObservedValues(_id);
366}
367
368void QtObservedInstanceBoard::returnAtomObservedValues(
369 const atomId_t _id,
370 ObservedValues_t &_observedvalues)
371{
372 if (lastremovedatom != _id) {
373 atomObservedValues.returnObservedValues(_id, _observedvalues);
374 } else {
375 lastremovedatom = (atomId_t)-1;
376 atomObservedValues.erase(_id);
377 }
378}
379
380void QtObservedInstanceBoard::returnMoleculeObservedValues(
381 const moleculeId_t _id,
382 ObservedValues_t &_observedvalues)
383{
384 if (lastremovedmolecule != _id) {
385 moleculeObservedValues.returnObservedValues(_id, _observedvalues);
386 } else {
387 lastremovedmolecule = (moleculeId_t)-1;
388 moleculeObservedValues.erase(_id);
389 }
390}
391
Note: See TracBrowser for help on using the repository browser.