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

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

All QtObserved..::update..() now use the atom or molecule ref instead of index getter.

  • the update() is called instantly by the Observable. Hence, the ref is still fully valid and always more recent than the index that needs updating. Also, it is way faster, as no lookup in the World is required and function may even get inlined.
  • Property mode set to 100644
File size: 15.0 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
145#ifdef HAVE_INLINE
146inline
147#endif
148atomId_t QtObservedAtom::updateIndex(const atom &_atomref)
149{
150 return _atomref.getId();
151}
152
153QtObservedAtom::ListOfBonds_t QtObservedAtom::updateBonds(
154 const atom &_atom)
155{
156 ListOfBonds_t ListOfBonds;
157 // make sure bonds is up-to-date
158 const BondList ListBonds = _atom.getListOfBonds();
159 for (BondList::const_iterator iter = ListBonds.begin();
160 iter != ListBonds.end();
161 ++iter)
162 ListOfBonds.insert( ListOfBonds.end(), std::make_pair(
163 (*iter)->leftatom->getId(),
164 (*iter)->rightatom->getId()) );
165 return ListOfBonds;
166}
167
168#ifdef HAVE_INLINE
169inline
170#endif
171atomicNumber_t QtObservedAtom::updateElement(
172 const atom &_atom)
173{
174 return _atom.getElementNo();
175}
176
177#ifdef HAVE_INLINE
178inline
179#endif
180QtObservedMolecule* QtObservedAtom::updateMoleculeIndex(
181 const atom &_atom)
182{
183 if (_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
195#ifdef HAVE_INLINE
196inline
197#endif
198std::string QtObservedAtom::updateName(
199 const atom &_atom)
200{
201 return _atom.getName();
202}
203
204#ifdef HAVE_INLINE
205inline
206#endif
207Vector QtObservedAtom::updatePosition(
208 const atom &_atom)
209{
210 return _atom.getPosition();
211}
212
213#ifdef HAVE_INLINE
214inline
215#endif
216bool QtObservedAtom::updateSelected(
217 const atom &_atom)
218{
219 return _atom.getSelected();
220}
221
222void QtObservedAtom::update(Observable *publisher)
223{
224 ASSERT(0, "QtObservedAtom::update() - we are not signed on for global updates.");
225}
226
227void QtObservedAtom::subjectKilled(Observable *publisher)
228{
229 ++signedOffChannels;
230
231 checkForRemoval();
232}
233
234void QtObservedAtom::countValuesSubjectKilled(const atomId_t _id)
235{
236 ASSERT( _id == getAtomIndex(),
237 "QtObservedAtom::countValuesSubjectKilled() - atom "+toString(getAtomIndex())
238 +" received countValuesSubjectKilled for atom id "+toString(_id)+".");
239
240 ++subjectKilledCount;
241
242 checkForRemoval();
243}
244
245#ifdef HAVE_INLINE
246inline
247#endif
248void QtObservedAtom::checkForRemoval()
249{
250 if ((signedOffChannels == AllsignedOnChannels) && (subjectKilledCount == MAX_ObservedTypes)) {
251 // remove owner: no more signOff needed
252 owner = NULL;
253
254 emit atomRemoved();
255
256 if (!BoardIsGone) {
257 board.markObservedAtomAsDisconnected(getAtomIndex());
258 board.markObservedAtomForErase(getAtomIndex());
259 }
260 }
261}
262
263void QtObservedAtom::recieveNotification(Observable *publisher, Notification_ptr notification)
264{
265 // ObservedValues have been updated before, hence convert updates to Qt's signals
266 switch (notification->getChannelNo()) {
267 case AtomObservable::IndexChanged:
268 {
269 const atomId_t newId = getAtomIndex();
270 emit indexChanged(oldId, newId);
271 oldId = newId;
272 break;
273 }
274 case AtomObservable::BondsAdded:
275 case AtomObservable::BondsRemoved:
276 emit bondsChanged();
277 break;
278 case AtomObservable::ElementChanged:
279 emit elementChanged();
280 break;
281 case AtomObservable::MoleculeChanged:
282 emit moleculeChanged();
283 break;
284 case AtomObservable::NameChanged:
285 emit nameChanged();
286 break;
287 case AtomObservable::PositionChanged:
288 emit positionChanged();
289 break;
290 case AtomObservable::SelectionChanged:
291 emit selectedChanged();
292 break;
293 default:
294 ASSERT(0, "QtObservedAtom::recieveNotification() - we are not signed on to channel "
295 +toString(notification->getChannelNo())+" of the atom.");
296 break;
297 }
298}
299
300void QtObservedAtom::activateObserver()
301{
302 atom * atomref = getAtom(getAtomIndex());
303 if (atomref != NULL) {
304 Observable::channels_t channels = getAllObservedChannels();
305 owner = static_cast<const Observable *>(atomref);
306 for (Observable::channels_t::const_iterator iter = channels.begin();
307 iter != channels.end(); ++iter)
308 owner->signOn(this, *iter);
309 if (!BoardIsGone)
310 board.markObservedAtomAsConnected(getAtomIndex());
311 } else
312 signedOffChannels = AllsignedOnChannels;
313}
314
315void QtObservedAtom::deactivateObserver()
316{
317 // sign Off
318 if (owner != NULL) {
319 Observable::channels_t channels = getAllObservedChannels();
320 for (Observable::channels_t::const_iterator iter = channels.begin();
321 iter != channels.end(); ++iter)
322 owner->signOff(this, *iter);
323 owner = NULL;
324 signedOffChannels = AllsignedOnChannels;
325 if (!BoardIsGone)
326 board.markObservedAtomAsDisconnected(getAtomIndex());
327 }
328}
329
330void QtObservedAtom::initObservedValues(
331 ObservedValues_t &_ObservedValues,
332 const atomId_t _id,
333 const atom * const _atomref,
334 const boost::function<void(const atomId_t)> &_subjectKilled)
335{
336 /* This is an old note from when the code was still part of cstor's initializer body.
337 * TODO: Probably does not apply anymore but has not yet been tested.
338 *
339 * We must not use boost::cref(this) as "this" has not been properly constructed and seemingly
340 * boost::cref tries to do some magic to grasp the inheritance hierarchy which fails because
341 * the class has not been fully constructed yet. "This" itself seems to be working fine.
342 */
343
344 ASSERT( _ObservedValues.size() == MAX_ObservedTypes,
345 "QtObservedAtom::initObservedValues() - given ObservedValues has not correct size.");
346
347 // fill ObservedValues: index first
348 const boost::function<atomId_t ()> AtomIndexUpdater(
349 boost::bind(&QtObservedAtom::updateIndex, boost::cref(*_atomref)));
350
351 ObservedValue_wCallback<atomId_t> * const IndexObservable =
352 new ObservedValue_wCallback<atomId_t>(
353 _atomref,
354 AtomIndexUpdater,
355 "AtomIndex_"+toString(_id),
356 _id,
357 AtomIndexChannels,
358 _subjectKilled);
359 _ObservedValues[AtomIndex] = IndexObservable;
360
361 const boost::function<const atomId_t ()> AtomIndexGetter =
362 boost::bind(&ObservedValue_wCallback<atomId_t>::get,
363 IndexObservable);
364
365 // fill ObservedValues: then all the other that need index
366 const boost::function<ListOfBonds_t ()> AtomBondsUpdater(
367 boost::bind(&QtObservedAtom::updateBonds, boost::cref(*_atomref)));
368 const boost::function<atomicNumber_t ()> AtomElementUpdater(
369 boost::bind(&QtObservedAtom::updateElement, boost::cref(*_atomref)));
370 const boost::function<QtObservedMolecule* ()> AtomMoleculeUpdater(
371 boost::bind(&QtObservedAtom::updateMoleculeIndex, this, boost::cref(*_atomref)));
372 const boost::function<std::string ()> AtomNameUpdater(
373 boost::bind(&QtObservedAtom::updateName, boost::cref(*_atomref)));
374 const boost::function<Vector ()> AtomPositionUpdater(
375 boost::bind(&QtObservedAtom::updatePosition, boost::cref(*_atomref)));
376 const boost::function<bool ()> AtomSelectedUpdater(
377 boost::bind(&QtObservedAtom::updateSelected, boost::cref(*_atomref)));
378
379 _ObservedValues[AtomBonds] = new ObservedValue_wCallback<ListOfBonds_t, atomId_t>(
380 _atomref,
381 AtomBondsUpdater,
382 "AtomBonds_"+toString(_id),
383 AtomBondsUpdater(),
384 AtomBondsChannels,
385 _subjectKilled,
386 AtomIndexGetter);
387 _ObservedValues[AtomElement] = new ObservedValue_wCallback<atomicNumber_t, atomId_t>(
388 _atomref,
389 AtomElementUpdater,
390 "AtomElement"+toString(_id),
391 AtomElementUpdater(),
392 AtomElementChannels,
393 _subjectKilled,
394 AtomIndexGetter);
395 _ObservedValues[AtomMolecule] = new ObservedValue_wCallback<QtObservedMolecule*, atomId_t>(
396 _atomref,
397 AtomMoleculeUpdater,
398 "AtomMolecule"+toString(_id),
399 AtomMoleculeUpdater(),
400 AtomMoleculeChannels,
401 _subjectKilled,
402 AtomIndexGetter);
403 _ObservedValues[AtomName] = new ObservedValue_wCallback<std::string, atomId_t>(
404 _atomref,
405 AtomNameUpdater,
406 "AtomName"+toString(_id),
407 AtomNameUpdater(),
408 AtomNameChannels,
409 _subjectKilled,
410 AtomIndexGetter);
411 _ObservedValues[AtomPosition] = new ObservedValue_wCallback<Vector, atomId_t>(
412 _atomref,
413 AtomPositionUpdater,
414 "AtomPosition_"+toString(_id),
415 AtomPositionUpdater(),
416 AtomPositionChannels,
417 _subjectKilled,
418 AtomIndexGetter);
419 _ObservedValues[AtomSelected] = new ObservedValue_wCallback<bool, atomId_t>(
420 _atomref,
421 AtomSelectedUpdater,
422 "AtomSelected_"+toString(_id),
423 AtomSelectedUpdater(),
424 AtomSelectedChannels,
425 _subjectKilled,
426 AtomIndexGetter);
427}
428
429void QtObservedAtom::destroyObservedValues(
430 std::vector<boost::any> &_ObservedValues)
431{
432 delete boost::any_cast<ObservedValue_wCallback<atomId_t> *>(_ObservedValues[AtomIndex]);
433 delete boost::any_cast<ObservedValue_wCallback<ListOfBonds_t, atomId_t> *>(_ObservedValues[AtomBonds]);
434 delete boost::any_cast<ObservedValue_wCallback<atomicNumber_t, atomId_t> *>(_ObservedValues[AtomElement]);
435 delete boost::any_cast<ObservedValue_wCallback<QtObservedMolecule*, atomId_t> *>(_ObservedValues[AtomMolecule]);
436 delete boost::any_cast<ObservedValue_wCallback<std::string, atomId_t> *>(_ObservedValues[AtomName]);
437 delete boost::any_cast<ObservedValue_wCallback<Vector, atomId_t> *>(_ObservedValues[AtomPosition]);
438 delete boost::any_cast<ObservedValue_wCallback<bool, atomId_t> *>(_ObservedValues[AtomSelected]);
439 _ObservedValues.clear();
440}
441
442const atomId_t& QtObservedAtom::getAtomIndex() const
443{
444 return boost::any_cast<ObservedValue_wCallback<atomId_t> *>(ObservedValues[AtomIndex])->get();
445}
446
447const QtObservedAtom::ListOfBonds_t& QtObservedAtom::getAtomBonds() const
448{
449 return boost::any_cast<ObservedValue_wCallback<ListOfBonds_t, atomId_t> *>(ObservedValues[AtomBonds])->get();
450}
451
452const atomicNumber_t& QtObservedAtom::getAtomElement() const
453{
454 return boost::any_cast<ObservedValue_wCallback<atomicNumber_t, atomId_t> *>(ObservedValues[AtomElement])->get();
455}
456
457QtObservedMolecule* const QtObservedAtom::getAtomMolecule() const
458{
459 return boost::any_cast<ObservedValue_wCallback<QtObservedMolecule*, atomId_t> *>(ObservedValues[AtomMolecule])->get();
460}
461
462const std::string& QtObservedAtom::getAtomName() const
463{
464 return boost::any_cast<ObservedValue_wCallback<std::string, atomId_t> *>(ObservedValues[AtomName])->get();
465}
466
467const Vector& QtObservedAtom::getAtomPosition() const
468{
469 return boost::any_cast<ObservedValue_wCallback<Vector, atomId_t> *>(ObservedValues[AtomPosition])->get();
470}
471
472const bool QtObservedAtom::getAtomSelected() const
473{
474 return boost::any_cast<ObservedValue_wCallback<bool, atomId_t> *>(ObservedValues[AtomSelected])->get();
475}
Note: See TracBrowser for help on using the repository browser.