source: src/UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.cpp@ 5aec20

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 5aec20 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: 15.4 KB
RevLine 
[15c8a9]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/*
[2f7988]24 * QtObservedInstanceBoard.cpp
[15c8a9]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
[2f7988]36#include "QtObservedInstanceBoard.hpp"
[15c8a9]37
[04c3a3]38#include <QtCore/QMetaType>
39
[65c323]40#include "UIElements/Qt4/InstanceBoard/QtObservedAtom.hpp"
[494478]41#include "UIElements/Qt4/InstanceBoard/QtObservedMolecule.hpp"
[15c8a9]42
43#include "CodePatterns/MemDebug.hpp"
44
[68418e]45#include <boost/bind.hpp>
46
[15c8a9]47#include "CodePatterns/Log.hpp"
48
49#include "Atom/atom.hpp"
50#include "Descriptors/AtomIdDescriptor.hpp"
51#include "Descriptors/MoleculeIdDescriptor.hpp"
52#include "molecule.hpp"
[41e287]53#include "UIElements/Qt4/InstanceBoard/ObservedValuesContainer_impl.hpp"
[15c8a9]54#include "World.hpp"
55
[2f7988]56QtObservedInstanceBoard::QtObservedInstanceBoard(QWidget * _parent) :
[15c8a9]57 QWidget(_parent),
[2f7988]58 Observer("QtObservedInstanceBoard"),
[15c8a9]59 WorldSignedOn(false),
[68418e]60 atomObservedValues(
61 "atom",
62 *this,
63 boost::bind(&QtObservedInstanceBoard::atomcountsubjectKilled, this, _1)),
64 moleculeObservedValues(
65 "molecule",
66 *this,
67 boost::bind(&QtObservedInstanceBoard::moleculecountsubjectKilled, this, _1)),
68 atomSubjectKilled(
[90821d]69 boost::bind(&ObservedValuesContainer<QtObservedAtom, atomId_t>::countsubjectKilled,
70 boost::ref(atomObservedValues),
[68418e]71 _1)),
72 moleculeSubjectKilled(
[90821d]73 boost::bind(&ObservedValuesContainer<QtObservedMolecule, moleculeId_t>::countsubjectKilled,
74 boost::ref(moleculeObservedValues),
[68418e]75 _1)),
76 lastremovedatom((atomId_t)-1),
77 lastremovedatomsmolecule( std::make_pair((moleculeId_t)-1,(atomId_t)-1) ),
78 lastremovedmolecule((moleculeId_t)-1)
79{
[04c3a3]80 qRegisterMetaType<QtObservedAtom::ptr>("QtObservedAtom::ptr");
81 qRegisterMetaType<QtObservedMolecule::ptr>("QtObservedMolecule::ptr");
82
[15c8a9]83 // be first (besides ObservedValues to know about new insertions)
84 World::getInstance().signOn(this, World::AtomInserted, GlobalObservableInfo::PriorityLevel(int(-10)));
85 World::getInstance().signOn(this, World::AtomRemoved, GlobalObservableInfo::PriorityLevel(int(-10)));
86 World::getInstance().signOn(this, World::MoleculeInserted, GlobalObservableInfo::PriorityLevel(int(-10)));
87 World::getInstance().signOn(this, World::MoleculeRemoved, GlobalObservableInfo::PriorityLevel(int(-10)));
88 WorldSignedOn = true;
89}
90
[2f7988]91QtObservedInstanceBoard::~QtObservedInstanceBoard()
[15c8a9]92{
93 if (WorldSignedOn) {
94 World::getInstance().signOff(this, World::AtomInserted);
95 World::getInstance().signOff(this, World::AtomRemoved);
96 World::getInstance().signOff(this, World::MoleculeInserted);
97 World::getInstance().signOff(this, World::MoleculeRemoved);
98 }
99 // sign off from all remaining molecules and atoms
100 for (SignedOn_t::iterator iter = AtomSignedOn.begin(); !AtomSignedOn.empty();
101 iter = AtomSignedOn.begin()) {
102 (*iter)->signOff(this, atom::IndexChanged);
103 AtomSignedOn.erase(iter);
104 }
105
106 for (SignedOn_t::iterator iter = MoleculeSignedOn.begin(); !MoleculeSignedOn.empty();
107 iter = MoleculeSignedOn.begin()) {
108 (*iter)->signOff(this, molecule::IndexChanged);
[8d5fbf1]109 (*iter)->signOff(this, molecule::AtomInserted);
110 (*iter)->signOff(this, molecule::AtomRemoved);
111 MoleculeSignedOn.erase(*iter); //erase all instances
[15c8a9]112 }
113}
114
[2f7988]115void QtObservedInstanceBoard::update(Observable *publisher)
[15c8a9]116{
117 ASSERT(0,
[2f7988]118 "QtObservedInstanceBoard::update() - we are not signed on to general updates.");
[15c8a9]119}
120
[2f7988]121void QtObservedInstanceBoard::subjectKilled(Observable *publisher)
[15c8a9]122{
123 SignedOn_t::iterator iter = AtomSignedOn.find(publisher);
124 if ( iter != AtomSignedOn.end()) {
125 LOG(3, "DEBUG: InstanceBoard got subjectKilled() from atom " << publisher);
126 AtomSignedOn.erase(iter);
127 } else {
128 iter = MoleculeSignedOn.find(publisher);
129 if ( iter != MoleculeSignedOn.end()) {
130 LOG(3, "DEBUG: InstanceBoard got subjectKilled() from molecule " << publisher);
131 MoleculeSignedOn.erase(iter);
132 } else {
133 ASSERT(0,
134 "QtObservedInstanceBoard::subjectKilled() - could not find signedOn for atom/molecule "+toString(publisher));
135 }
136 }
137}
138
[2f7988]139void QtObservedInstanceBoard::recieveNotification(Observable *publisher, Notification_ptr notification)
[15c8a9]140{
141 if (static_cast<World *>(publisher) == World::getPointer()) {
142 switch (notification->getChannelNo()) {
143 case World::MoleculeInserted:
144 {
145 const moleculeId_t _id = const_cast<const World &>(World::getInstance()).lastChangedMolId();
146 #ifdef LOG_OBSERVER
147 observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that molecule "+toString(_id)+" has been inserted.";
148 #endif
149 LOG(3, "DEBUG: InformationBoard got moleculeInserted signal for molecule " << _id);
150 const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
151 getMolecule(MoleculeById(_id));
152 if (_molecule != NULL) {
[494478]153 ObservedValues_t ObservedValues(QtObservedMolecule::MAX_ObservedTypes);
[15c8a9]154 LOG(3, "DEBUG: InformationBoard initializes ObservedValues for molecule " << _id);
[494478]155 QtObservedMolecule::initObservedValues(
[15c8a9]156 ObservedValues,
157 _id,
158 _molecule,
159 moleculeSubjectKilled);
[68418e]160 QtObservedMolecule::ptr observedmolecule(new QtObservedMolecule(ObservedValues, *this));
[0af22d]161 moleculeObservedValues.insert(_id, observedmolecule);
[15c8a9]162 // we need to check for index changes
163 LOG(3, "DEBUG: InformationBoard signOn()s to molecule " << _id);
164 _molecule->signOn(this, molecule::IndexChanged);
165 MoleculeSignedOn.insert( static_cast<Observable *>(const_cast<molecule *>(_molecule)) );
[8d5fbf1]166 _molecule->signOn(this, molecule::AtomInserted);
167 MoleculeSignedOn.insert( static_cast<Observable *>(const_cast<molecule *>(_molecule)) );
168 _molecule->signOn(this, molecule::AtomRemoved);
169 MoleculeSignedOn.insert( static_cast<Observable *>(const_cast<molecule *>(_molecule)) );
[15c8a9]170
171 emit moleculeInserted(_id);
172 } else {
[2f7988]173 ELOG(1, "QtObservedInstanceBoard got MoleculeInserted for unknown molecule id " << _id);
[15c8a9]174 }
175 break;
176 }
177 case World::MoleculeRemoved:
178 {
179 const moleculeId_t _id = const_cast<const World &>(World::getInstance()).lastChangedMolId();
180 LOG(3, "DEBUG: InformationBoard got MoleculeRemoved signal for molecule " << _id);
181 // note down such that ObservedValues are simply dropped
182 lastremovedmolecule = _id;
183 break;
184 }
185 case World::AtomInserted:
186 {
187 const atomId_t _id = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
188 #ifdef LOG_OBSERVER
189 observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
190 #endif
191 LOG(3, "DEBUG: InformationBoard got atomInserted signal for atom " << _id);
192 const atom * const _atom = const_cast<const World &>(World::getInstance()).
193 getAtom(AtomById(_id));
194 if (_atom!= NULL) {
[65c323]195 ObservedValues_t ObservedValues(QtObservedAtom::MAX_ObservedTypes);
[15c8a9]196 LOG(3, "DEBUG: InformationBoard initializes ObservedValues for atom " << _id);
[65c323]197 QtObservedAtom::initObservedValues(
[15c8a9]198 ObservedValues,
199 _id,
200 _atom,
201 atomSubjectKilled);
[68418e]202 QtObservedAtom::ptr observedatom(new QtObservedAtom(ObservedValues, *this));
[0af22d]203 atomObservedValues.insert(_id, observedatom);
[15c8a9]204 // we need to check for index changes
205 LOG(3, "DEBUG: InformationBoard signOn()s to atom " << _id);
206 _atom->signOn(this, atom::IndexChanged);
207 AtomSignedOn.insert( static_cast<Observable *>(const_cast<atom *>(_atom)) );
[6d4925]208 emit atomInserted(observedatom->getAtomMoleculeIndex(), observedatom->getAtomIndex());
[15c8a9]209 } else {
[2f7988]210 ELOG(1, "QtObservedInstanceBoard got AtomInserted for unknown atom id " << _id);
[15c8a9]211 }
212 break;
213 }
214 case World::AtomRemoved:
215 {
216 const atomId_t _id = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
217 LOG(3, "DEBUG: InformationBoard got AtomRemoved signal for atom " << _id);
218 // note down such that ObservedValues are simply dropped
219 lastremovedatom = _id;
220 break;
221 }
222 default:
[2f7988]223 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here for World.");
[15c8a9]224 break;
225 }
226 } else if (dynamic_cast<molecule *>(publisher) != NULL) {
227 const moleculeId_t molid = const_cast<const World &>(World::getInstance()).lastChangedMolId();
228 switch (notification->getChannelNo()) {
229 case molecule::AtomInserted:
230 {
231 const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
232 getMolecule(MoleculeById(molid));
233 if (_molecule != NULL) {
234 const atomId_t atomid = const_cast<const molecule *>(_molecule)->lastChangedAtomId();
235 LOG(3, "DEBUG: InformationBoard got AtomInserted signal for atom "
236 << atomid << " from molecule " << molid);
237 // check whether atom's observedvalues are present
[41e287]238 ASSERT( atomObservedValues.isPresent(atomid),
[2f7988]239 "QtObservedInstanceBoard::recieveNotification() - ObservedValues for atom "
[15c8a9]240 +toString(atomid)+" are not present yet.");
241 // and emit
242 emit atomInserted(molid, atomid);
243 } else {
[2f7988]244 ELOG(2, "QtObservedInstanceBoard::recieveNotification() - molecule "
[15c8a9]245 << molid << " has disappeared.");
246 }
247 break;
248 }
249 case molecule::AtomRemoved:
250 {
251 const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
252 getMolecule(MoleculeById(molid));
253 if (_molecule != NULL) {
254 const atomId_t atomid = const_cast<const molecule *>(_molecule)->lastChangedAtomId();
255 LOG(3, "DEBUG: InformationBoard got AtomRemoved signal for atom "
256 << atomid << " from molecule " << molid);
[8d5fbf1]257 lastremovedatomsmolecule = std::make_pair(molid, atomid);
[15c8a9]258 }
259 break;
260 }
261 case molecule::IndexChanged:
262 {
263 // molecule has changed its index
264 const moleculeId_t newmoleculeId = dynamic_cast<molecule *>(publisher)->getId();
265 LOG(3, "DEBUG: InformationBoard got IndexChanged from molecule " << molid << " to " << newmoleculeId);
[41e287]266#ifndef NDEBUG
267 bool status =
268#endif
269 moleculeObservedValues.changeIdentifier(molid, newmoleculeId);
270 ASSERT( status,
271 "QtObservedInstanceBoard::recieveNotification() - cannot change molecule's id "
272 +toString(molid)+" "+toString(newmoleculeId)+" in moleculeObservedValues.");
[15c8a9]273 // no need update SignedOn, ref does not change
274 emit moleculeIndexChanged(molid, newmoleculeId);
275 break;
276 }
277 default:
[2f7988]278 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here.");
[15c8a9]279 break;
280 }
281 } else if (dynamic_cast<atom *>(publisher) != NULL) {
282 const atomId_t oldatomId = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
283 switch (notification->getChannelNo()) {
284 case AtomObservable::IndexChanged:
285 {
286 const atomId_t newatomId = dynamic_cast<atom *>(publisher)->getId();
287 LOG(3, "DEBUG: InformationBoard got IndexChanged from atom " << oldatomId << " to " << newatomId);
[6d4925]288#ifndef NDEBUG
289 bool status =
290#endif
[41e287]291 atomObservedValues.changeIdentifier(oldatomId, newatomId);
[6d4925]292 ASSERT( status,
293 "QtObservedInstanceBoard::recieveNotification() - cannot change atom's id "
294 +toString(oldatomId)+" "+toString(newatomId)+" in atomObservedValues.");
295 // changed insertion delayed
296 atomInsertionDelayed_t::iterator iter = atomInsertionDelayed.find(oldatomId);
297 if (iter != atomInsertionDelayed.end()) {
298 const moleculeId_t molid = iter->second;
299 atomInsertionDelayed.erase(iter);
300#ifndef NDEBUG
301 std::pair<atomInsertionDelayed_t::iterator, bool> inserter =
302#endif
303 atomInsertionDelayed.insert( std::make_pair(newatomId, molid) );
304 ASSERT( inserter.second,
305 "QtObservedInstanceBoard::recieveNotification() - id "
306 +toString(newatomId)+" already present in atomInsertionDelayed.");
307 }
[15c8a9]308 // no need update SignedOn, ref does not change
309 emit atomIndexChanged(oldatomId, newatomId);
310 break;
311 }
312 default:
[2f7988]313 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here.");
[15c8a9]314 break;
315 }
316 } else {
[2f7988]317 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - notification from unknown source.");
[15c8a9]318 }
319}
320
[2f7988]321void QtObservedInstanceBoard::atomcountsubjectKilled(const atomId_t _atomid)
[15c8a9]322{
[68418e]323 if ((_atomid == lastremovedatomsmolecule.second) && (_atomid == lastremovedatom)) {
324 LOG(3, "DEBUG: InstanceBoard emits atomRemoved for " << _atomid);
[90821d]325 emit atomRemoved(lastremovedatomsmolecule.first, lastremovedatomsmolecule.second);
[68418e]326 } else
[90821d]327 ELOG(2, "QtObservedInstanceBoard::atomcountsubjectKilled() - id " << _atomid
[68418e]328 << " not fitting with " << lastremovedatomsmolecule << " or " << lastremovedatom);
[15c8a9]329}
330
[2f7988]331void QtObservedInstanceBoard::moleculecountsubjectKilled(const moleculeId_t _molid)
[15c8a9]332{
[68418e]333 if (lastremovedmolecule == _molid) {
334 LOG(3, "DEBUG: InstanceBoard emits moleculeRemoved for " << _molid);
335 emit moleculeRemoved(_molid);
336 } else
337 ELOG(2, "QtObservedInstanceBoard::moleculecountsubjectKilled() - id " << _molid
338 << " not fitting with " << lastremovedmolecule);
[15c8a9]339}
340
[41e287]341QtObservedAtom::ptr QtObservedInstanceBoard::getObservedAtom(const atomId_t _id)
[15c8a9]342{
[41e287]343 return atomObservedValues.get(_id);
[15c8a9]344}
345
[41e287]346QtObservedMolecule::ptr QtObservedInstanceBoard::getObservedMolecule(const moleculeId_t _id)
[15c8a9]347{
[41e287]348 return moleculeObservedValues.get(_id);
[15c8a9]349}
350
[68418e]351void QtObservedInstanceBoard::markObservedAtomAsConnected(const atomId_t _id)
[15c8a9]352{
[68418e]353 atomObservedValues.markObservedValuesAsConnected(_id);
[15c8a9]354}
355
[68418e]356void QtObservedInstanceBoard::markObservedAtomAsDisconnected(const atomId_t _id)
[15c8a9]357{
[68418e]358 atomObservedValues.markObservedValuesAsDisconnected(_id);
[15c8a9]359}
[98c35c]360
[4e6ffe]361void QtObservedInstanceBoard::markObservedAtomForErase(const atomId_t _id)
362{
363 atomObservedValues.eraseObservedValues(_id);
364}
365
[68418e]366void QtObservedInstanceBoard::markObservedMoleculeAsConnected(const moleculeId_t _id)
[98c35c]367{
[68418e]368 moleculeObservedValues.markObservedValuesAsConnected(_id);
[98c35c]369}
370
[68418e]371void QtObservedInstanceBoard::markObservedMoleculeAsDisconnected(const moleculeId_t _id)
[98c35c]372{
[68418e]373 moleculeObservedValues.markObservedValuesAsDisconnected(_id);
[98c35c]374}
[4e6ffe]375
376void QtObservedInstanceBoard::markObservedMoleculeForErase(const moleculeId_t _id)
377{
378 moleculeObservedValues.eraseObservedValues(_id);
379}
Note: See TracBrowser for help on using the repository browser.