source: src/UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.cpp@ 04c3a3

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 04c3a3 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: 14.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 <QtCore/QMetaType>
39
40#include "UIElements/Qt4/InstanceBoard/QtObservedAtom.hpp"
41#include "UIElements/Qt4/InstanceBoard/QtObservedMolecule.hpp"
42
43#include "CodePatterns/MemDebug.hpp"
44
45#include <boost/bind.hpp>
46
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"
53#include "UIElements/Qt4/InstanceBoard/ObservedValuesContainer_impl.hpp"
54#include "World.hpp"
55
56QtObservedInstanceBoard::QtObservedInstanceBoard(QWidget * _parent) :
57 QWidget(_parent),
58 Observer("QtObservedInstanceBoard"),
59 WorldSignedOn(false),
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(
69 boost::bind(&ObservedValuesContainer<QtObservedAtom, atomId_t>::countsubjectKilled,
70 boost::ref(atomObservedValues),
71 _1)),
72 moleculeSubjectKilled(
73 boost::bind(&ObservedValuesContainer<QtObservedMolecule, moleculeId_t>::countsubjectKilled,
74 boost::ref(moleculeObservedValues),
75 _1)),
76 lastremovedatom((atomId_t)-1),
77 lastremovedatomsmolecule( std::make_pair((moleculeId_t)-1,(atomId_t)-1) ),
78 lastremovedmolecule((moleculeId_t)-1)
79{
80 qRegisterMetaType<QtObservedAtom::ptr>("QtObservedAtom::ptr");
81 qRegisterMetaType<QtObservedMolecule::ptr>("QtObservedMolecule::ptr");
82
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
91QtObservedInstanceBoard::~QtObservedInstanceBoard()
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);
109 (*iter)->signOff(this, molecule::AtomInserted);
110 (*iter)->signOff(this, molecule::AtomRemoved);
111 MoleculeSignedOn.erase(*iter); //erase all instances
112 }
113}
114
115void QtObservedInstanceBoard::update(Observable *publisher)
116{
117 ASSERT(0,
118 "QtObservedInstanceBoard::update() - we are not signed on to general updates.");
119}
120
121void QtObservedInstanceBoard::subjectKilled(Observable *publisher)
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
139void QtObservedInstanceBoard::recieveNotification(Observable *publisher, Notification_ptr notification)
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) {
153 ObservedValues_t ObservedValues(QtObservedMolecule::MAX_ObservedTypes);
154 LOG(3, "DEBUG: InformationBoard initializes ObservedValues for molecule " << _id);
155 QtObservedMolecule::initObservedValues(
156 ObservedValues,
157 _id,
158 _molecule,
159 moleculeSubjectKilled);
160 QtObservedMolecule::ptr observedmolecule(new QtObservedMolecule(ObservedValues, *this));
161#ifndef NDEBUG
162 bool status =
163#endif
164 moleculeObservedValues.insert(_id, observedmolecule);
165 ASSERT( status,
166 "QtObservedInstanceBoard::recieveNotification() - could not insert ObservedMolecule for"
167 +toString(_id)+".");
168 // we need to check for index changes
169 LOG(3, "DEBUG: InformationBoard signOn()s to molecule " << _id);
170 _molecule->signOn(this, molecule::IndexChanged);
171 MoleculeSignedOn.insert( static_cast<Observable *>(const_cast<molecule *>(_molecule)) );
172 _molecule->signOn(this, molecule::AtomInserted);
173 MoleculeSignedOn.insert( static_cast<Observable *>(const_cast<molecule *>(_molecule)) );
174 _molecule->signOn(this, molecule::AtomRemoved);
175 MoleculeSignedOn.insert( static_cast<Observable *>(const_cast<molecule *>(_molecule)) );
176
177 emit moleculeInserted(_id);
178 } else {
179 ELOG(1, "QtObservedInstanceBoard got MoleculeInserted for unknown molecule id " << _id);
180 }
181 break;
182 }
183 case World::MoleculeRemoved:
184 {
185 const moleculeId_t _id = const_cast<const World &>(World::getInstance()).lastChangedMolId();
186 LOG(3, "DEBUG: InformationBoard got MoleculeRemoved signal for molecule " << _id);
187 // note down such that ObservedValues are simply dropped
188 lastremovedmolecule = _id;
189 break;
190 }
191 case World::AtomInserted:
192 {
193 const atomId_t _id = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
194 #ifdef LOG_OBSERVER
195 observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
196 #endif
197 LOG(3, "DEBUG: InformationBoard got atomInserted signal for atom " << _id);
198 const atom * const _atom = const_cast<const World &>(World::getInstance()).
199 getAtom(AtomById(_id));
200 if (_atom!= NULL) {
201 ObservedValues_t ObservedValues(QtObservedAtom::MAX_ObservedTypes);
202 LOG(3, "DEBUG: InformationBoard initializes ObservedValues for atom " << _id);
203 QtObservedAtom::initObservedValues(
204 ObservedValues,
205 _id,
206 _atom,
207 atomSubjectKilled);
208 QtObservedAtom::ptr observedatom(new QtObservedAtom(ObservedValues, *this));
209#ifndef NDEBUG
210 bool status =
211#endif
212 atomObservedValues.insert(_id, observedatom);
213 ASSERT( status,
214 "QtObservedInstanceBoard::recieveNotification() - could not insert ObservedValues for"
215 +toString(_id)+".");
216 // we need to check for index changes
217 LOG(3, "DEBUG: InformationBoard signOn()s to atom " << _id);
218 _atom->signOn(this, atom::IndexChanged);
219 AtomSignedOn.insert( static_cast<Observable *>(const_cast<atom *>(_atom)) );
220 } else {
221 ELOG(1, "QtObservedInstanceBoard got AtomInserted for unknown atom id " << _id);
222 }
223 break;
224 }
225 case World::AtomRemoved:
226 {
227 const atomId_t _id = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
228 LOG(3, "DEBUG: InformationBoard got AtomRemoved signal for atom " << _id);
229 // note down such that ObservedValues are simply dropped
230 lastremovedatom = _id;
231 break;
232 }
233 default:
234 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here for World.");
235 break;
236 }
237 } else if (dynamic_cast<molecule *>(publisher) != NULL) {
238 const moleculeId_t molid = const_cast<const World &>(World::getInstance()).lastChangedMolId();
239 switch (notification->getChannelNo()) {
240 case molecule::AtomInserted:
241 {
242 const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
243 getMolecule(MoleculeById(molid));
244 if (_molecule != NULL) {
245 const atomId_t atomid = const_cast<const molecule *>(_molecule)->lastChangedAtomId();
246 LOG(3, "DEBUG: InformationBoard got AtomInserted signal for atom "
247 << atomid << " from molecule " << molid);
248 // check whether atom's observedvalues are present
249 ASSERT( atomObservedValues.isPresent(atomid),
250 "QtObservedInstanceBoard::recieveNotification() - ObservedValues for atom "
251 +toString(atomid)+" are not present yet.");
252 // and emit
253 emit atomInserted(molid, atomid);
254 } else {
255 ELOG(2, "QtObservedInstanceBoard::recieveNotification() - molecule "
256 << molid << " has disappeared.");
257 }
258 break;
259 }
260 case molecule::AtomRemoved:
261 {
262 const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
263 getMolecule(MoleculeById(molid));
264 if (_molecule != NULL) {
265 const atomId_t atomid = const_cast<const molecule *>(_molecule)->lastChangedAtomId();
266 LOG(3, "DEBUG: InformationBoard got AtomRemoved signal for atom "
267 << atomid << " from molecule " << molid);
268 lastremovedatomsmolecule = std::make_pair(molid, atomid);
269 }
270 break;
271 }
272 case molecule::IndexChanged:
273 {
274 // molecule has changed its index
275 const moleculeId_t newmoleculeId = dynamic_cast<molecule *>(publisher)->getId();
276 LOG(3, "DEBUG: InformationBoard got IndexChanged from molecule " << molid << " to " << newmoleculeId);
277#ifndef NDEBUG
278 bool status =
279#endif
280 moleculeObservedValues.changeIdentifier(molid, newmoleculeId);
281 ASSERT( status,
282 "QtObservedInstanceBoard::recieveNotification() - cannot change molecule's id "
283 +toString(molid)+" "+toString(newmoleculeId)+" in moleculeObservedValues.");
284 // no need update SignedOn, ref does not change
285 emit moleculeIndexChanged(molid, newmoleculeId);
286 break;
287 }
288 default:
289 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here.");
290 break;
291 }
292 } else if (dynamic_cast<atom *>(publisher) != NULL) {
293 const atomId_t oldatomId = const_cast<const World &>(World::getInstance()).lastChangedAtomId();
294 switch (notification->getChannelNo()) {
295 case AtomObservable::IndexChanged:
296 {
297 const atomId_t newatomId = dynamic_cast<atom *>(publisher)->getId();
298 LOG(3, "DEBUG: InformationBoard got IndexChanged from atom " << oldatomId << " to " << newatomId);
299 atomObservedValues.changeIdentifier(oldatomId, newatomId);
300 // no need update SignedOn, ref does not change
301 emit atomIndexChanged(oldatomId, newatomId);
302 break;
303 }
304 default:
305 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here.");
306 break;
307 }
308 } else {
309 ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - notification from unknown source.");
310 }
311}
312
313void QtObservedInstanceBoard::atomcountsubjectKilled(const atomId_t _atomid)
314{
315 if ((_atomid == lastremovedatomsmolecule.second) && (_atomid == lastremovedatom)) {
316 LOG(3, "DEBUG: InstanceBoard emits atomRemoved for " << _atomid);
317 emit atomRemoved(lastremovedatomsmolecule.first, lastremovedatomsmolecule.second);
318 } else
319 ELOG(2, "QtObservedInstanceBoard::atomcountsubjectKilled() - id " << _atomid
320 << " not fitting with " << lastremovedatomsmolecule << " or " << lastremovedatom);
321}
322
323void QtObservedInstanceBoard::moleculecountsubjectKilled(const moleculeId_t _molid)
324{
325 if (lastremovedmolecule == _molid) {
326 LOG(3, "DEBUG: InstanceBoard emits moleculeRemoved for " << _molid);
327 emit moleculeRemoved(_molid);
328 } else
329 ELOG(2, "QtObservedInstanceBoard::moleculecountsubjectKilled() - id " << _molid
330 << " not fitting with " << lastremovedmolecule);
331}
332
333QtObservedAtom::ptr QtObservedInstanceBoard::getObservedAtom(const atomId_t _id)
334{
335 return atomObservedValues.get(_id);
336}
337
338QtObservedMolecule::ptr QtObservedInstanceBoard::getObservedMolecule(const moleculeId_t _id)
339{
340 return moleculeObservedValues.get(_id);
341}
342
343void QtObservedInstanceBoard::markObservedAtomAsConnected(const atomId_t _id)
344{
345 atomObservedValues.markObservedValuesAsConnected(_id);
346}
347
348void QtObservedInstanceBoard::markObservedAtomAsDisconnected(const atomId_t _id)
349{
350 atomObservedValues.markObservedValuesAsDisconnected(_id);
351}
352
353void QtObservedInstanceBoard::markObservedMoleculeAsConnected(const moleculeId_t _id)
354{
355 moleculeObservedValues.markObservedValuesAsConnected(_id);
356}
357
358void QtObservedInstanceBoard::markObservedMoleculeAsDisconnected(const moleculeId_t _id)
359{
360 moleculeObservedValues.markObservedValuesAsDisconnected(_id);
361}
Note: See TracBrowser for help on using the repository browser.