source: src/UIElements/Qt4/InstanceBoard/QtObservedAtom.cpp@ c44763

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

FIX: QtObserved... did not destroyObservedValues() so far.

  • Property mode set to 100644
File size: 15.7 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 * QtObservedAtom.cpp
25 *
26 * Created on: Oct 28, 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 "QtObservedAtom.hpp"
37
38#include "UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp"
39
40#include "CodePatterns/MemDebug.hpp"
41
42#include <boost/assign.hpp>
43
44#include "Atom/atom.hpp"
45#include "Bond/bond.hpp"
46#include "Descriptors/AtomIdDescriptor.hpp"
47#include "Element/element.hpp"
48#include "World.hpp"
49
50#include "UIElements/Qt4/InstanceBoard/ObservedValue_wCallback.hpp"
51
52using namespace boost::assign;
53
54static const Observable::channels_t getAtomBondsChannels()
55{
56 Observable::channels_t channels;
57 channels += AtomObservable::BondsAdded, AtomObservable::BondsRemoved;
58 return channels;
59}
60
61static const Observable::channels_t getAllObservedChannels()
62{
63 Observable::channels_t channels;
64 channels +=
65 AtomObservable::IndexChanged,
66 AtomObservable::BondsAdded,
67 AtomObservable::BondsRemoved,
68 AtomObservable::MoleculeChanged,
69 AtomObservable::NameChanged,
70 AtomObservable::ElementChanged,
71 AtomObservable::PositionChanged,
72 AtomObservable::SelectionChanged;
73 return channels;
74}
75
76// static entities
77const Observable::channels_t
78QtObservedAtom::AtomIndexChannels(1, AtomObservable::IndexChanged);
79const Observable::channels_t
80QtObservedAtom::AtomBondsChannels(getAtomBondsChannels());
81const Observable::channels_t
82QtObservedAtom::AtomElementChannels(1, AtomObservable::ElementChanged);
83const Observable::channels_t
84QtObservedAtom::AtomMoleculeChannels(1, AtomObservable::MoleculeChanged);
85const Observable::channels_t
86QtObservedAtom::AtomNameChannels(1, AtomObservable::NameChanged);
87const Observable::channels_t
88QtObservedAtom::AtomPositionChannels(1, AtomObservable::PositionChanged);
89const Observable::channels_t
90QtObservedAtom::AtomSelectedChannels(1, AtomObservable::SelectionChanged);
91
92QtObservedAtom::QtObservedAtom(
93 const atomId_t _id,
94 const atom * const _atom,
95 QtObservedInstanceBoard &_board,
96 QWidget * _parent) :
97 QWidget(_parent),
98 Observer("QtObservedAtom"),
99 subjectKilledCount(0),
100 AllsignedOnChannels(getAllObservedChannels().size()),
101 signedOffChannels(0),
102 owner(NULL),
103 oldId(_id),
104 board(_board),
105 BoardIsGone(false),
106 ObservedValues(QtObservedAtom::MAX_ObservedTypes)
107{
108 boost::function<void (const atomId_t)> atomSubjectKilled(
109 boost::bind(&QtObservedAtom::countValuesSubjectKilled,
110 boost::ref(*this),
111 _1));
112 initObservedValues( ObservedValues, _id, _atom, atomSubjectKilled);
113
114 // activating Observer is done by ObservedValueContainer when it's inserted
115}
116
117QtObservedAtom::~QtObservedAtom()
118{
119 boost::any_cast<ObservedValue_wCallback<atomId_t> *>(ObservedValues[AtomIndex])->noteCallBackIsGone();
120 boost::any_cast<ObservedValue_wCallback<ListOfBonds_t, atomId_t> *>(ObservedValues[AtomBonds])->noteCallBackIsGone();
121 boost::any_cast<ObservedValue_wCallback<atomicNumber_t, atomId_t> *>(ObservedValues[AtomElement])->noteCallBackIsGone();
122 boost::any_cast<ObservedValue_wCallback<QtObservedMolecule*, atomId_t> *>(ObservedValues[AtomMolecule])->noteCallBackIsGone();
123 boost::any_cast<ObservedValue_wCallback<std::string, atomId_t> *>(ObservedValues[AtomName])->noteCallBackIsGone();
124 boost::any_cast<ObservedValue_wCallback<Vector, atomId_t> *>(ObservedValues[AtomPosition])->noteCallBackIsGone();
125 boost::any_cast<ObservedValue_wCallback<bool, atomId_t> *>(ObservedValues[AtomSelected])->noteCallBackIsGone();
126
127 deactivateObserver();
128
129 destroyObservedValues(ObservedValues);
130}
131
132const atom * const QtObservedAtom::getAtomConst(const atomId_t _id)
133{
134 const atom * const _atom = const_cast<const World &>(World::getInstance()).
135 getAtom(AtomById(_id));
136 return _atom;
137}
138
139atom * const QtObservedAtom::getAtom(const atomId_t _id)
140{
141 atom * const _atom = World::getInstance().getAtom(AtomById(_id));
142 return _atom;
143}
144
145atomId_t QtObservedAtom::updateIndex()
146{
147 return const_cast<const World &>(World::getInstance()).lastChangedAtomId();
148}
149
150QtObservedAtom::ListOfBonds_t QtObservedAtom::updateBonds(
151 const boost::function<const atomId_t ()> &_getAtomIndex)
152{
153 ListOfBonds_t ListOfBonds;
154 const atom * const _atom = getAtomConst(_getAtomIndex());
155 if (_atom != NULL) {
156 // make sure bonds is up-to-date
157 const BondList ListBonds = _atom->getListOfBonds();
158 for (BondList::const_iterator iter = ListBonds.begin();
159 iter != ListBonds.end();
160 ++iter)
161 ListOfBonds.insert( ListOfBonds.end(), std::make_pair(
162 (*iter)->leftatom->getId(),
163 (*iter)->rightatom->getId()) );
164 }
165 return ListOfBonds;
166}
167
168atomicNumber_t QtObservedAtom::updateElement(
169 const boost::function<const atomId_t ()> &_getAtomIndex)
170{
171 const atom * const _atom = getAtomConst(_getAtomIndex());
172 if (_atom != NULL) {
173 return _atom->getElementNo();
174 } else {
175 return (atomicNumber_t)-1;
176 }
177}
178
179QtObservedMolecule* QtObservedAtom::updateMoleculeIndex(
180 const boost::function<const atomId_t ()> &_getAtomIndex)
181{
182 const atom * const _atom = getAtomConst(_getAtomIndex());
183 if ((_atom != NULL) && (_atom->getMolecule() != NULL)) {
184 const moleculeId_t molid = _atom->getMolecule()->getId();
185 QtObservedMolecule* mol = board.getObservedMolecule(molid).get();
186 if (mol != NULL)
187 return mol;
188 else
189 return (QtObservedMolecule*)NULL;
190 } else {
191 return (QtObservedMolecule*)NULL;
192 }
193}
194
195std::string QtObservedAtom::updateName(
196 const boost::function<const atomId_t ()> &_getAtomIndex)
197{
198 const atom * const _atom = getAtomConst(_getAtomIndex());
199 if (_atom != NULL) {
200 return _atom->getName();
201 } else {
202 return std::string("");
203 }
204}
205
206Vector QtObservedAtom::updatePosition(
207 const boost::function<const atomId_t ()> &_getAtomIndex)
208{
209 const atom * const _atom = getAtomConst(_getAtomIndex());
210 if (_atom != NULL) {
211 return _atom->getPosition();
212 } else {
213 return zeroVec;
214 }
215}
216
217bool QtObservedAtom::updateSelected(
218 const boost::function<const atomId_t ()> &_getAtomIndex)
219{
220 const atom * const _atom = getAtomConst(_getAtomIndex());
221 if (_atom != NULL) {
222 return _atom->getSelected();
223 } else {
224 return false;
225 }
226}
227
228void QtObservedAtom::update(Observable *publisher)
229{
230 ASSERT(0, "QtObservedAtom::update() - we are not signed on for global updates.");
231}
232
233void QtObservedAtom::subjectKilled(Observable *publisher)
234{
235 ++signedOffChannels;
236
237 checkForRemoval();
238}
239
240void QtObservedAtom::countValuesSubjectKilled(const atomId_t _id)
241{
242 ASSERT( _id == getAtomIndex(),
243 "QtObservedAtom::countValuesSubjectKilled() - atom "+toString(getAtomIndex())
244 +" received countValuesSubjectKilled for atom id "+toString(_id)+".");
245
246 ++subjectKilledCount;
247
248 checkForRemoval();
249}
250
251#ifdef HAVE_INLINE
252inline
253#endif
254void QtObservedAtom::checkForRemoval()
255{
256 if ((signedOffChannels == AllsignedOnChannels) && (subjectKilledCount == MAX_ObservedTypes)) {
257 // remove owner: no more signOff needed
258 owner = NULL;
259
260 emit atomRemoved();
261
262 if (!BoardIsGone) {
263 board.markObservedAtomAsDisconnected(getAtomIndex());
264 board.markObservedAtomForErase(getAtomIndex());
265 }
266 }
267}
268
269void QtObservedAtom::recieveNotification(Observable *publisher, Notification_ptr notification)
270{
271 // ObservedValues have been updated before, hence convert updates to Qt's signals
272 switch (notification->getChannelNo()) {
273 case AtomObservable::IndexChanged:
274 {
275 const atomId_t newId = getAtomIndex();
276 emit indexChanged(oldId, newId);
277 oldId = newId;
278 break;
279 }
280 case AtomObservable::BondsAdded:
281 case AtomObservable::BondsRemoved:
282 emit bondsChanged();
283 break;
284 case AtomObservable::ElementChanged:
285 emit elementChanged();
286 break;
287 case AtomObservable::MoleculeChanged:
288 emit moleculeChanged();
289 break;
290 case AtomObservable::NameChanged:
291 emit nameChanged();
292 break;
293 case AtomObservable::PositionChanged:
294 emit positionChanged();
295 break;
296 case AtomObservable::SelectionChanged:
297 emit selectedChanged();
298 break;
299 default:
300 ASSERT(0, "QtObservedAtom::recieveNotification() - we are not signed on to channel "
301 +toString(notification->getChannelNo())+" of the atom.");
302 break;
303 }
304}
305
306void QtObservedAtom::activateObserver()
307{
308 atom * atomref = getAtom(getAtomIndex());
309 if (atomref != NULL) {
310 Observable::channels_t channels = getAllObservedChannels();
311 owner = static_cast<const Observable *>(atomref);
312 for (Observable::channels_t::const_iterator iter = channels.begin();
313 iter != channels.end(); ++iter)
314 owner->signOn(this, *iter);
315 if (!BoardIsGone)
316 board.markObservedAtomAsConnected(getAtomIndex());
317 } else
318 signedOffChannels = AllsignedOnChannels;
319}
320
321void QtObservedAtom::deactivateObserver()
322{
323 // sign Off
324 if (owner != NULL) {
325 Observable::channels_t channels = getAllObservedChannels();
326 for (Observable::channels_t::const_iterator iter = channels.begin();
327 iter != channels.end(); ++iter)
328 owner->signOff(this, *iter);
329 owner = NULL;
330 signedOffChannels = AllsignedOnChannels;
331 if (!BoardIsGone)
332 board.markObservedAtomAsDisconnected(getAtomIndex());
333 }
334}
335
336void QtObservedAtom::initObservedValues(
337 ObservedValues_t &_ObservedValues,
338 const atomId_t _id,
339 const atom * const _atomref,
340 const boost::function<void(const atomId_t)> &_subjectKilled)
341{
342 /* This is an old note from when the code was still part of cstor's initializer body.
343 * TODO: Probably does not apply anymore but has not yet been tested.
344 *
345 * We must not use boost::cref(this) as "this" has not been properly constructed and seemingly
346 * boost::cref tries to do some magic to grasp the inheritance hierarchy which fails because
347 * the class has not been fully constructed yet. "This" itself seems to be working fine.
348 */
349
350 ASSERT( _ObservedValues.size() == MAX_ObservedTypes,
351 "QtObservedAtom::initObservedValues() - given ObservedValues has not correct size.");
352
353 // fill ObservedValues: index first
354 const boost::function<atomId_t ()> AtomIndexUpdater(
355 boost::bind(&QtObservedAtom::updateIndex));
356
357 ObservedValue_wCallback<atomId_t> * const IndexObservable =
358 new ObservedValue_wCallback<atomId_t>(
359 _atomref,
360 boost::bind(&QtObservedAtom::updateIndex),
361 "AtomIndex_"+toString(_id),
362 _id,
363 AtomIndexChannels,
364 _subjectKilled);
365 _ObservedValues[AtomIndex] = IndexObservable;
366
367 const boost::function<const atomId_t ()> AtomIndexGetter =
368 boost::bind(&ObservedValue_wCallback<atomId_t>::get,
369 IndexObservable);
370
371 // fill ObservedValues: then all the other that need index
372 const boost::function<ListOfBonds_t ()> AtomBondsUpdater(
373 boost::bind(&QtObservedAtom::updateBonds, AtomIndexGetter));
374 const boost::function<atomicNumber_t ()> AtomElementUpdater(
375 boost::bind(&QtObservedAtom::updateElement, AtomIndexGetter));
376 const boost::function<QtObservedMolecule* ()> AtomMoleculeUpdater(
377 boost::bind(&QtObservedAtom::updateMoleculeIndex, this, AtomIndexGetter));
378 const boost::function<std::string ()> AtomNameUpdater(
379 boost::bind(&QtObservedAtom::updateName, AtomIndexGetter));
380 const boost::function<Vector ()> AtomPositionUpdater(
381 boost::bind(&QtObservedAtom::updatePosition, AtomIndexGetter));
382 const boost::function<bool ()> AtomSelectedUpdater(
383 boost::bind(&QtObservedAtom::updateSelected, AtomIndexGetter));
384
385 _ObservedValues[AtomBonds] = new ObservedValue_wCallback<ListOfBonds_t, atomId_t>(
386 _atomref,
387 AtomBondsUpdater,
388 "AtomBonds_"+toString(_id),
389 AtomBondsUpdater(),
390 AtomBondsChannels,
391 _subjectKilled,
392 AtomIndexGetter);
393 _ObservedValues[AtomElement] = new ObservedValue_wCallback<atomicNumber_t, atomId_t>(
394 _atomref,
395 AtomElementUpdater,
396 "AtomElement"+toString(_id),
397 AtomElementUpdater(),
398 AtomElementChannels,
399 _subjectKilled,
400 AtomIndexGetter);
401 _ObservedValues[AtomMolecule] = new ObservedValue_wCallback<QtObservedMolecule*, atomId_t>(
402 _atomref,
403 AtomMoleculeUpdater,
404 "AtomMolecule"+toString(_id),
405 AtomMoleculeUpdater(),
406 AtomMoleculeChannels,
407 _subjectKilled,
408 AtomIndexGetter);
409 _ObservedValues[AtomName] = new ObservedValue_wCallback<std::string, atomId_t>(
410 _atomref,
411 AtomNameUpdater,
412 "AtomName"+toString(_id),
413 AtomNameUpdater(),
414 AtomNameChannels,
415 _subjectKilled,
416 AtomIndexGetter);
417 _ObservedValues[AtomPosition] = new ObservedValue_wCallback<Vector, atomId_t>(
418 _atomref,
419 AtomPositionUpdater,
420 "AtomPosition_"+toString(_id),
421 AtomPositionUpdater(),
422 AtomPositionChannels,
423 _subjectKilled,
424 AtomIndexGetter);
425 _ObservedValues[AtomSelected] = new ObservedValue_wCallback<bool, atomId_t>(
426 _atomref,
427 AtomSelectedUpdater,
428 "AtomSelected_"+toString(_id),
429 AtomSelectedUpdater(),
430 AtomSelectedChannels,
431 _subjectKilled,
432 AtomIndexGetter);
433}
434
435void QtObservedAtom::destroyObservedValues(
436 std::vector<boost::any> &_ObservedValues)
437{
438 delete boost::any_cast<ObservedValue_wCallback<atomId_t> *>(_ObservedValues[AtomIndex]);
439 delete boost::any_cast<ObservedValue_wCallback<ListOfBonds_t, atomId_t> *>(_ObservedValues[AtomBonds]);
440 delete boost::any_cast<ObservedValue_wCallback<atomicNumber_t, atomId_t> *>(_ObservedValues[AtomElement]);
441 delete boost::any_cast<ObservedValue_wCallback<QtObservedMolecule*, atomId_t> *>(_ObservedValues[AtomMolecule]);
442 delete boost::any_cast<ObservedValue_wCallback<std::string, atomId_t> *>(_ObservedValues[AtomName]);
443 delete boost::any_cast<ObservedValue_wCallback<Vector, atomId_t> *>(_ObservedValues[AtomPosition]);
444 delete boost::any_cast<ObservedValue_wCallback<bool, atomId_t> *>(_ObservedValues[AtomSelected]);
445 _ObservedValues.clear();
446}
447
448const atomId_t& QtObservedAtom::getAtomIndex() const
449{
450 return boost::any_cast<ObservedValue_wCallback<atomId_t> *>(ObservedValues[AtomIndex])->get();
451}
452
453const QtObservedAtom::ListOfBonds_t& QtObservedAtom::getAtomBonds() const
454{
455 return boost::any_cast<ObservedValue_wCallback<ListOfBonds_t, atomId_t> *>(ObservedValues[AtomBonds])->get();
456}
457
458const atomicNumber_t& QtObservedAtom::getAtomElement() const
459{
460 return boost::any_cast<ObservedValue_wCallback<atomicNumber_t, atomId_t> *>(ObservedValues[AtomElement])->get();
461}
462
463QtObservedMolecule* const QtObservedAtom::getAtomMolecule() const
464{
465 return boost::any_cast<ObservedValue_wCallback<QtObservedMolecule*, atomId_t> *>(ObservedValues[AtomMolecule])->get();
466}
467
468const std::string& QtObservedAtom::getAtomName() const
469{
470 return boost::any_cast<ObservedValue_wCallback<std::string, atomId_t> *>(ObservedValues[AtomName])->get();
471}
472
473const Vector& QtObservedAtom::getAtomPosition() const
474{
475 return boost::any_cast<ObservedValue_wCallback<Vector, atomId_t> *>(ObservedValues[AtomPosition])->get();
476}
477
478const bool QtObservedAtom::getAtomSelected() const
479{
480 return boost::any_cast<ObservedValue_wCallback<bool, atomId_t> *>(ObservedValues[AtomSelected])->get();
481}
Note: See TracBrowser for help on using the repository browser.