source: src/UIElements/Qt4/InstanceBoard/QtObservedBond.cpp@ b4bd0e

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

Added QtObservedBond, managed by QtObservedInstanceBoard.

  • QtObservedBond is special because it observes not only a bond, but also two atoms and a molecule in total.
  • but the general idea is to rather have information duplicate, i.e. the left atom's position is also available via the QtObservedAtom. But in this way QtObservedBond does not depend on the QtObservedAtom being still or already present.
  • Property mode set to 100644
File size: 28.3 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2016 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 * QtObservedBond.cpp
25 *
26 * Created on: Mar 03, 2016
27 * Author: heber
28 */
29
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include "QtObservedBond.hpp"
37
38#include <QtCore/QMetaType>
39
40#include "UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp"
41
42#include "CodePatterns/MemDebug.hpp"
43
44#include <boost/assign.hpp>
45
46#include "Atom/atom.hpp"
47#include "Bond/bond.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 getAllObservedAtomChannels()
55{
56 Observable::channels_t channels;
57 channels +=
58 AtomObservable::IndexChanged,
59 AtomObservable::ElementChanged,
60 AtomObservable::PositionChanged;
61 return channels;
62}
63
64static const molecule * getMolecule(const bond::ptr _bond)
65{
66 ASSERT( _bond->leftatom->getMolecule() == _bond->rightatom->getMolecule(),
67 "getMolecule() - leftatom and rightatom belong to different molecules.");
68 return _bond->leftatom->getMolecule();
69}
70
71static const molecule * const getMoleculeConst(const bond::ptr _bond)
72{
73 ASSERT( _bond->leftatom->getMolecule() == _bond->rightatom->getMolecule(),
74 "getMolecule() - leftatom and rightatom belong to different molecules.");
75 return _bond->leftatom->getMolecule();
76}
77
78template <class T>
79Observable * const getObservable(const T * _ptr)
80{
81 return static_cast<Observable * const>(
82 const_cast<T * const>(_ptr));
83}
84
85static QtObservedBond::ObservableCount_t initAllsignedOnChannels(const bond::ptr _bond)
86{
87 const QtObservedBond::ObservableCount_t returnlist =
88 boost::assign::list_of< QtObservedBond::ObservableCount_t::value_type >
89 ( getObservable(_bond.get()), 1)
90 ( getObservable(_bond->leftatom), getAllObservedAtomChannels().size())
91 ( getObservable(_bond->rightatom), getAllObservedAtomChannels().size())
92 ( getObservable(getMolecule(_bond)), 1);
93 return returnlist;
94}
95
96
97// static entities
98const Observable::channels_t
99QtObservedBond::BondDegreeChannels(1, BondObservable::DegreeChanged);
100
101
102QtObservedBond::QtObservedBond(
103 const bondId_t _id,
104 const bond::ptr _bond,
105 QtObservedInstanceBoard &_board,
106 QWidget * _parent) :
107 QWidget(_parent),
108 Observer("QtObservedBond"),
109 AllsignedOnChannels(initAllsignedOnChannels(_bond)),
110 bondowner(NULL),
111 leftatomowner(NULL),
112 rightatomowner(NULL),
113 moleculeowner(NULL),
114 oldbondId(_id),
115 oldleftatomId(_id.first),
116 oldrightatomId(_id.second),
117 oldmoleculeId(getMolecule(_bond)->getId()),
118 board(_board),
119 BoardIsGone(false),
120 ObservedValues(QtObservedBond::MAX_ObservedTypes)
121{
122 qRegisterMetaType<bondId_t>("bondId_t");
123
124 typedef boost::function<ObservableCount_t::mapped_type& (const ObservableCount_t::key_type&)> map_accessor_t;
125 const map_accessor_t accessor =
126 boost::bind<ObservableCount_t::mapped_type&>(
127 &ObservableCount_t::at,
128 boost::ref(subjectKilledCount), _1);
129
130 const boost::function<void (const ObservedValue_Index_t)> bondSubjectKilled(
131 boost::bind(&QtObservedBond::countValuesSubjectKilled,
132 boost::ref(*this),
133 boost::bind(&QtObservedBond::getIndex, boost::cref(*this)),
134 boost::bind(accessor,
135 getObservable(_bond.get()))));
136 const boost::function<void (const ObservedValue_Index_t)> leftatomSubjectKilled(
137 boost::bind(&QtObservedBond::countValuesSubjectKilled,
138 boost::ref(*this),
139 boost::bind(&QtObservedBond::getIndex, boost::cref(*this)),
140 boost::bind(accessor,
141 getObservable(_bond->leftatom))));
142 const boost::function<void (const ObservedValue_Index_t)> rightatomSubjectKilled(
143 boost::bind(&QtObservedBond::countValuesSubjectKilled,
144 boost::ref(*this),
145 boost::bind(&QtObservedBond::getIndex, boost::cref(*this)),
146 boost::bind(accessor,
147 getObservable(_bond->rightatom))));
148 const boost::function<void (const ObservedValue_Index_t)> moleculeSubjectKilled(
149 boost::bind(&QtObservedBond::countValuesSubjectKilled,
150 boost::ref(*this),
151 boost::bind(&QtObservedBond::getIndex, boost::cref(*this)),
152 boost::bind(accessor,
153 getObservable(getMolecule(_bond)))));
154 initObservedValues( ObservedValues, _id, _bond,
155 bondSubjectKilled, leftatomSubjectKilled, rightatomSubjectKilled, moleculeSubjectKilled);
156
157 // activating Observer is done by ObservedValueContainer when it's inserted
158}
159
160QtObservedBond::~QtObservedBond()
161{
162 boost::any_cast<ObservedValue_wCallback<int, ObservedValue_Index_t> *>(ObservedValues[BondDegree])->noteCallBackIsGone();
163 boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(ObservedValues[leftAtomIndex])->noteCallBackIsGone();
164 boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(ObservedValues[leftAtomElement])->noteCallBackIsGone();
165 boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(ObservedValues[leftAtomPosition])->noteCallBackIsGone();
166 boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(ObservedValues[rightAtomIndex])->noteCallBackIsGone();
167 boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(ObservedValues[rightAtomElement])->noteCallBackIsGone();
168 boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(ObservedValues[rightAtomPosition])->noteCallBackIsGone();
169 boost::any_cast<ObservedValue_wCallback<moleculeId_t, ObservedValue_Index_t> *>(ObservedValues[moleculeIndex])->noteCallBackIsGone();
170
171 deactivateObserver();
172
173 destroyObservedValues(ObservedValues);
174}
175
176#ifdef HAVE_INLINE
177inline
178#endif
179int QtObservedBond::updateDegree(const bond &_bond)
180{
181 return _bond.getDegree();
182}
183
184#ifdef HAVE_INLINE
185inline
186#endif
187atomId_t QtObservedBond::updateLeftAtomIndex(const atom &_atom)
188{
189 return _atom.getId();
190}
191
192#ifdef HAVE_INLINE
193inline
194#endif
195atomicNumber_t QtObservedBond::updateLeftAtomElement(const atom &_atom)
196{
197 return _atom.getElementNo();
198}
199
200#ifdef HAVE_INLINE
201inline
202#endif
203Vector QtObservedBond::updateLeftAtomPosition(const atom &_atom)
204{
205 return _atom.getPosition();
206}
207
208#ifdef HAVE_INLINE
209inline
210#endif
211atomId_t QtObservedBond::updateRightAtomIndex(const atom &_atom)
212{
213 return _atom.getId();
214}
215
216#ifdef HAVE_INLINE
217inline
218#endif
219atomicNumber_t QtObservedBond::updateRightAtomElement(const atom &_atom)
220{
221 return _atom.getElementNo();
222}
223
224#ifdef HAVE_INLINE
225inline
226#endif
227Vector QtObservedBond::updateRightAtomPosition(const atom &_atom)
228{
229 return _atom.getPosition();
230}
231
232#ifdef HAVE_INLINE
233inline
234#endif
235moleculeId_t QtObservedBond::updateMoleculeIndex(const molecule &_mol)
236{
237 return _mol.getId();
238}
239
240void QtObservedBond::update(Observable *publisher)
241{
242 ASSERT(0, "QtObservedBond::update() - we are not signed on for global updates.");
243}
244
245void QtObservedBond::subjectKilled(Observable *publisher)
246{
247 ++(signedOffChannels[publisher]);
248
249 checkForRemoval(getIndex());
250}
251
252void QtObservedBond::countValuesSubjectKilled(
253 ObservedValue_Index_t _id,
254 unsigned int &_counter)
255{
256 ASSERT( _id == getIndex(),
257 "QtObservedBond::countValuesSubjectKilled() - bond "+toString(getIndex())
258 +" received countValuesSubjectKilled for bond id "+toString(_id)+".");
259
260 ++_counter;
261
262 checkForRemoval(_id);
263}
264
265void QtObservedBond::checkForRemoval(ObservedValue_Index_t _id)
266{
267 if (leftatomowner != NULL) {
268 // left atom gone?
269 const ObservableCount_t::const_iterator subjectkilledleftiter =
270 subjectKilledCount.find(const_cast<Observable *>(leftatomowner));
271 ASSERT( (subjectkilledleftiter != subjectKilledCount.end()),
272 "QtObservedBond::checkForRemoval() - leftatomowner not present in subjectKilledCount.");
273 if (subjectkilledleftiter->second == 3) {
274 leftatomowner = NULL;
275 }
276 }
277
278 if (rightatomowner != NULL) {
279 // right atom gone?
280 const ObservableCount_t::const_iterator subjectkilledrightiter =
281 subjectKilledCount.find(const_cast<Observable *>(rightatomowner));
282 ASSERT( (subjectkilledrightiter != subjectKilledCount.end()),
283 "QtObservedBond::checkForRemoval() - rightatomowner not present in subjectKilledCount.");
284 if (subjectkilledrightiter->second == 3) {
285 rightatomowner = NULL;
286 }
287 }
288
289 if (moleculeowner != NULL) {
290 // molecule gone?
291 const ObservableCount_t::const_iterator subjectkilledmoliter =
292 subjectKilledCount.find(const_cast<Observable *>(moleculeowner));
293 ASSERT( (subjectkilledmoliter != subjectKilledCount.end()),
294 "QtObservedBond::checkForRemoval() - moleculeowner not present in subjectKilledCount.");
295 if (subjectkilledmoliter->second == 3) {
296 moleculeowner = NULL;
297 }
298 }
299
300 if (bondowner != NULL) {
301 // only bond needs to be destroyed to signal removal
302 const ObservableCount_t::const_iterator subjectkillediter =
303 subjectKilledCount.find(const_cast<Observable *>(bondowner));
304 const ObservableCount_t::const_iterator allsignediter =
305 AllsignedOnChannels.find(const_cast<Observable *>(bondowner));
306 const ObservableCount_t::const_iterator signedoffiter =
307 signedOffChannels.find(const_cast<Observable *>(bondowner));
308 ASSERT( (subjectkillediter != subjectKilledCount.end())
309 && (allsignediter != AllsignedOnChannels.end())
310 && (signedoffiter != signedOffChannels.end()),
311 "QtObservedBond::checkForRemoval() - something is wrong here.");
312 if ((signedoffiter->second == allsignediter->second)
313 && (subjectkillediter->second == allsignediter->second)) {
314 // remove owner: no more signOff needed
315 bondowner = NULL;
316
317 emit bondRemoved();
318
319 if (!BoardIsGone) {
320 board.markObservedBondAsDisconnected(_id);
321 board.markObservedBondForErase(_id);
322 }
323 }
324 }
325}
326
327void QtObservedBond::recieveNotification(Observable *publisher, Notification_ptr notification)
328{
329 // ObservedValues have been updated before, hence convert updates to Qt's signals
330 if (publisher == leftatomowner) {
331 switch (notification->getChannelNo()) {
332 case AtomObservable::IndexChanged:
333 {
334 const atomId_t newId = getLeftAtomIndex();
335 emit leftAtomIndexChanged(oldleftatomId, newId);
336 oldleftatomId = newId;
337 break;
338 }
339 case AtomObservable::ElementChanged:
340 {
341 emit leftAtomElementChanged();
342 break;
343 }
344 case AtomObservable::PositionChanged:
345 {
346 emit leftAtomPositionChanged();
347 break;
348 }
349 default:
350 ASSERT(0, "QtObservedBond::recieveNotification() - we are not signed on to channel "
351 +toString(notification->getChannelNo())+" of the left atom "
352 +toString(getLeftAtomIndex())+".");
353 break;
354 }
355 } else if (publisher == rightatomowner) {
356 switch (notification->getChannelNo()) {
357 case AtomObservable::IndexChanged:
358 {
359 const atomId_t newId = getRightAtomIndex();
360 emit rightAtomIndexChanged(oldrightatomId, newId);
361 oldrightatomId = newId;
362 break;
363 }
364 case AtomObservable::ElementChanged:
365 {
366 emit rightAtomElementChanged();
367 break;
368 }
369 case AtomObservable::PositionChanged:
370 {
371 emit rightAtomPositionChanged();
372 break;
373 }
374 default:
375 ASSERT(0, "QtObservedBond::recieveNotification() - we are not signed on to channel "
376 +toString(notification->getChannelNo())+" of the right atom "
377 +toString(getRightAtomIndex())+".");
378 break;
379 }
380 } else if (publisher == bondowner) {
381 switch (notification->getChannelNo()) {
382 case BondObservable::DegreeChanged:
383 emit degreeChanged();
384 break;
385 default:
386 ASSERT(0, "QtObservedBond::recieveNotification() - we are not signed on to channel "
387 +toString(notification->getChannelNo())+" of the bond "
388 +toString(getBondIndex())+".");
389 break;
390 }
391 } else if (publisher == moleculeowner) {
392 switch (notification->getChannelNo()) {
393 case molecule::IndexChanged:
394 {
395 const moleculeId_t newId = getMoleculeIndex();
396 emit moleculeIndexChanged(oldmoleculeId, newId);
397 oldmoleculeId = newId;
398 break;
399 }
400 default:
401 ASSERT(0, "QtObservedBond::recieveNotification() - we are not signed on to channel "
402 +toString(notification->getChannelNo())+" of the molecule #"
403 +toString(getMoleculeIndex())+".");
404 break;
405 }
406 } else
407 ASSERT(0,
408 "QtObservedBond::recieveNotification() - received signal from unknown source.");
409}
410
411static QtObservedBond::ObservableCount_t::mapped_type getObservableCountValue(
412 const QtObservedBond::ObservableCount_t &_map,
413 const Observable *_obs)
414{
415 Observable * const obs_const = const_cast<Observable * const>(_obs);
416 QtObservedBond::ObservableCount_t::const_iterator iter = _map.find(obs_const);
417 ASSERT( iter != _map.end(),
418 "getObservableCount_tValue");
419 return iter->second;
420}
421
422static void assignObservableCountValue(
423 QtObservedBond::ObservableCount_t &_map,
424 const Observable *_obs,
425 const QtObservedBond::ObservableCount_t::mapped_type &_value)
426{
427 Observable * const obs_const = const_cast<Observable * const>(_obs);
428 QtObservedBond::ObservableCount_t::iterator iter = _map.find(obs_const);
429 ASSERT( iter != _map.end(),
430 "getObservableCount_tValue");
431 iter->second = _value;
432}
433
434void QtObservedBond::activateObserver()
435{
436 signedOffChannels.clear();
437 subjectKilledCount.clear();
438
439 const atom * rightatom = getAtom(getRightAtomIndex());
440 {
441 const Observable::channels_t channels = getAllObservedAtomChannels();
442 if (rightatom != NULL) {
443 rightatomowner = static_cast<const Observable *>(rightatom);
444 for (Observable::channels_t::const_iterator iter = channels.begin();
445 iter != channels.end(); ++iter)
446 rightatomowner->signOn(this, *iter);
447 subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(rightatomowner), 0));
448 signedOffChannels.insert( std::make_pair(const_cast<Observable * const>(rightatomowner), 0));
449 } else {
450 subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(rightatomowner), channels.size()));
451 assignObservableCountValue(signedOffChannels, rightatomowner,
452 getObservableCountValue(AllsignedOnChannels, rightatomowner));
453 }
454 }
455
456 {
457 const atom * leftatom = getAtom(getLeftAtomIndex());
458 const Observable::channels_t channels = getAllObservedAtomChannels();
459 if (leftatom != NULL) {
460 leftatomowner = static_cast<const Observable *>(leftatom);
461 for (Observable::channels_t::const_iterator iter = channels.begin();
462 iter != channels.end(); ++iter)
463 leftatomowner->signOn(this, *iter);
464 subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(leftatomowner), 0));
465 signedOffChannels.insert( std::make_pair(const_cast<Observable * const>(leftatomowner), 0));
466
467 bond::ptr bondref = leftatom->getBond(rightatom);
468 if (bondref != NULL) {
469 // bond
470 {
471 bondowner = static_cast<const Observable *>(bondref.get());
472 bondowner->signOn(this, BondObservable::DegreeChanged);
473 subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(bondowner), 0));
474 signedOffChannels.insert( std::make_pair(const_cast<Observable * const>(bondowner), 0));
475 }
476
477 const molecule * mol = leftatom->getMolecule();
478 if (mol != NULL) {
479 // molecule
480 moleculeowner = static_cast<const Observable *>(mol);
481 moleculeowner->signOn(this, molecule::IndexChanged);
482 subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(moleculeowner), 0));
483 signedOffChannels.insert( std::make_pair(const_cast<Observable * const>(moleculeowner), 0));
484 } else {
485 subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(moleculeowner), 1));
486 assignObservableCountValue(signedOffChannels, moleculeowner,
487 getObservableCountValue(AllsignedOnChannels, moleculeowner));
488 }
489
490 // and mark as connected
491 if (!BoardIsGone)
492 board.markObservedBondAsConnected(getIndex());
493 } else {
494 subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(bondowner), 1));
495 assignObservableCountValue(signedOffChannels, bondowner,
496 getObservableCountValue(AllsignedOnChannels, bondowner));
497 }
498 } else {
499 subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(leftatomowner), channels.size()));
500 assignObservableCountValue(signedOffChannels, leftatomowner,
501 getObservableCountValue(AllsignedOnChannels, leftatomowner));
502 }
503 }
504}
505
506void QtObservedBond::deactivateObserver()
507{
508 // sign Off
509 if (leftatomowner != NULL) {
510 const ObservableCount_t::iterator subjectkilledleftiter =
511 subjectKilledCount.find(const_cast<Observable *>(leftatomowner));
512 ASSERT( (subjectkilledleftiter != subjectKilledCount.end()),
513 "QtObservedBond::deactivateObserver() - no entry in subjectKilledCount for left atom "
514 +toString(leftatomowner)+", has activateObserver() been called?");
515 ASSERT( (subjectkilledleftiter->second == 3) || (subjectkilledleftiter->second == 0),
516 "QtObservedBond::deactivateObserver() - cannot deal with partially signed off left atom.");
517 if (subjectkilledleftiter->second == 0) {
518 Observable::channels_t channels = getAllObservedAtomChannels();
519 for (Observable::channels_t::const_iterator iter = channels.begin();
520 iter != channels.end(); ++iter)
521 leftatomowner->signOff(this, *iter);
522 subjectkilledleftiter->second = 3;
523 }
524 leftatomowner = NULL;
525 }
526 if (rightatomowner != NULL) {
527 const ObservableCount_t::iterator subjectkilledrightiter =
528 subjectKilledCount.find(const_cast<Observable *>(rightatomowner));
529 ASSERT( (subjectkilledrightiter != subjectKilledCount.end()),
530 "QtObservedBond::deactivateObserver() - no entry in subjectKilledCount for right atom"
531 +toString(rightatomowner)+", has activateObserver() been called?");
532 ASSERT( (subjectkilledrightiter->second == 3) || (subjectkilledrightiter->second == 0),
533 "QtObservedBond::deactivateObserver() - cannot deal with partially signed off right atom .");
534 if (subjectkilledrightiter->second == 0) {
535 Observable::channels_t channels = getAllObservedAtomChannels();
536 for (Observable::channels_t::const_iterator iter = channels.begin();
537 iter != channels.end(); ++iter)
538 rightatomowner->signOff(this, *iter);
539 subjectkilledrightiter->second = 3;
540 }
541 rightatomowner = NULL;
542 }
543 if (moleculeowner != NULL) {
544 const ObservableCount_t::iterator subjectkilledmoliter =
545 subjectKilledCount.find(const_cast<Observable *>(moleculeowner));
546 ASSERT( (subjectkilledmoliter != subjectKilledCount.end()),
547 "QtObservedBond::deactivateObserver() - no entry in subjectKilledCount for molecule"
548 +toString(moleculeowner)+", has activateObserver() been called?");
549 if (subjectkilledmoliter->second == 0)
550 moleculeowner->signOff(this, molecule::IndexChanged);
551 subjectkilledmoliter->second = 1;
552 moleculeowner = NULL;
553 }
554 if (bondowner != NULL) {
555 const ObservableCount_t::iterator subjectkilledbonditer =
556 subjectKilledCount.find(const_cast<Observable *>(bondowner));
557 ASSERT( (subjectkilledbonditer != subjectKilledCount.end()),
558 "QtObservedBond::deactivateObserver() - no entry in subjectKilledCount for bond"
559 +toString(bondowner)+","
560 +" has activateObserver() been called?");
561 if (subjectkilledbonditer->second == 0)
562 bondowner->signOff(this, BondObservable::DegreeChanged);
563 subjectkilledbonditer->second = 1;
564 bondowner = NULL;
565 signedOffChannels.clear();
566 signedOffChannels.insert(AllsignedOnChannels.begin(), AllsignedOnChannels.end());
567
568 if (!BoardIsGone)
569 board.markObservedBondAsDisconnected(getIndex());
570 }
571}
572
573const atom * const QtObservedBond::getAtomConst(const atomId_t _id)
574{
575 const atom * const _atom = const_cast<const World &>(World::getInstance()).
576 getAtom(AtomById(_id));
577 return _atom;
578}
579
580atom * const QtObservedBond::getAtom(const atomId_t _id)
581{
582 atom * const _atom = World::getInstance().getAtom(AtomById(_id));
583 return _atom;
584}
585
586void QtObservedBond::initObservedValues(
587 ObservedValues_t &_ObservedValues,
588 const bondId_t _id,
589 const bond::ptr _bondref,
590 const boost::function<void(const ObservedValue_Index_t)> &_bondsubjectKilled,
591 const boost::function<void(const ObservedValue_Index_t)> &_leftatomsubjectKilled,
592 const boost::function<void(const ObservedValue_Index_t)> &_rightatomsubjectKilled,
593 const boost::function<void(const ObservedValue_Index_t)> &_moleculesubjectKilled)
594{
595 // fill ObservedValues: index first
596 const boost::function<ObservedValue_Index_t ()> BondIndexGetter =
597 boost::bind(&QtObservedBond::getIndex,
598 boost::cref(*this));
599
600 // fill ObservedValues: then all the other that need index
601 const boost::function<int ()> BondDegreeUpdater(
602 boost::bind(&QtObservedBond::updateDegree, boost::cref(*_bondref)));
603 const boost::function<atomId_t ()> leftAtomIndexUpdater(
604 boost::bind(&QtObservedBond::updateLeftAtomIndex, boost::cref(*_bondref->leftatom)));
605 const boost::function<atomicNumber_t ()> leftAtomElementUpdater(
606 boost::bind(&QtObservedBond::updateLeftAtomElement, boost::cref(*_bondref->leftatom)));
607 const boost::function<Vector ()> leftAtomPositionUpdater(
608 boost::bind(&QtObservedBond::updateLeftAtomPosition, boost::cref(*_bondref->leftatom)));
609 const boost::function<atomId_t ()> rightAtomIndexUpdater(
610 boost::bind(&QtObservedBond::updateRightAtomIndex, boost::cref(*_bondref->rightatom)));
611 const boost::function<atomicNumber_t ()> rightAtomElementUpdater(
612 boost::bind(&QtObservedBond::updateRightAtomElement, boost::cref(*_bondref->rightatom)));
613 const boost::function<Vector ()> rightAtomPositionUpdater(
614 boost::bind(&QtObservedBond::updateRightAtomPosition, boost::cref(*_bondref->rightatom)));
615 const boost::function<moleculeId_t ()> MoleculeIndexUpdater(
616 boost::bind(&QtObservedBond::updateMoleculeIndex, boost::cref(*_bondref->leftatom->getMolecule())));
617
618 _ObservedValues[BondDegree] = new ObservedValue_wCallback<int, ObservedValue_Index_t>(
619 _bondref.get(),
620 BondDegreeUpdater,
621 "BondDegree_bond"+toString(_id),
622 BondDegreeUpdater(),
623 BondDegreeChannels,
624 _bondsubjectKilled,
625 BondIndexGetter);
626 _ObservedValues[leftAtomIndex] = new ObservedValue_wCallback<atomId_t, ObservedValue_Index_t>(
627 _bondref->leftatom,
628 leftAtomIndexUpdater,
629 "LeftAtomIndex_bond"+toString(_id),
630 leftAtomIndexUpdater(),
631 Observable::channels_t(1, AtomObservable::IndexChanged),
632 _leftatomsubjectKilled,
633 BondIndexGetter);
634 _ObservedValues[leftAtomElement] = new ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t>(
635 _bondref->leftatom,
636 leftAtomElementUpdater,
637 "LeftAtomElement_bond"+toString(_id),
638 leftAtomElementUpdater(),
639 Observable::channels_t(1, AtomObservable::ElementChanged),
640 _leftatomsubjectKilled,
641 BondIndexGetter);
642 _ObservedValues[leftAtomPosition] = new ObservedValue_wCallback<Vector, ObservedValue_Index_t>(
643 _bondref->leftatom,
644 leftAtomPositionUpdater,
645 "LeftAtomPosition_bond"+toString(_id),
646 leftAtomPositionUpdater(),
647 Observable::channels_t(1, AtomObservable::PositionChanged),
648 _leftatomsubjectKilled,
649 BondIndexGetter);
650 _ObservedValues[rightAtomIndex] = new ObservedValue_wCallback<atomId_t, ObservedValue_Index_t>(
651 _bondref->rightatom,
652 rightAtomIndexUpdater,
653 "RightAtomIndex_bond"+toString(_id),
654 rightAtomIndexUpdater(),
655 Observable::channels_t(1, AtomObservable::IndexChanged),
656 _rightatomsubjectKilled,
657 BondIndexGetter);
658 _ObservedValues[rightAtomElement] = new ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t>(
659 _bondref->rightatom,
660 rightAtomElementUpdater,
661 "RightAtomElement_bond"+toString(_id),
662 rightAtomElementUpdater(),
663 Observable::channels_t(1, AtomObservable::ElementChanged),
664 _rightatomsubjectKilled,
665 BondIndexGetter);
666 _ObservedValues[rightAtomPosition] = new ObservedValue_wCallback<Vector, ObservedValue_Index_t>(
667 _bondref->rightatom,
668 rightAtomPositionUpdater,
669 "RightAtomPosition_bond"+toString(_id),
670 rightAtomPositionUpdater(),
671 Observable::channels_t(1, AtomObservable::PositionChanged),
672 _rightatomsubjectKilled,
673 BondIndexGetter);
674 _ObservedValues[moleculeIndex] = new ObservedValue_wCallback<moleculeId_t, ObservedValue_Index_t>(
675 _bondref->leftatom->getMolecule(),
676 MoleculeIndexUpdater,
677 "MoleculeIndex_bond"+toString(_id),
678 MoleculeIndexUpdater(),
679 Observable::channels_t(1, AtomObservable::PositionChanged),
680 _moleculesubjectKilled,
681 BondIndexGetter);
682}
683
684void QtObservedBond::destroyObservedValues(
685 std::vector<boost::any> &_ObservedValues)
686{
687 delete boost::any_cast<ObservedValue_wCallback<int, ObservedValue_Index_t> *>(_ObservedValues[BondDegree]);
688 delete boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(_ObservedValues[leftAtomIndex]);
689 delete boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(_ObservedValues[leftAtomElement]);
690 delete boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(_ObservedValues[leftAtomPosition]);
691 delete boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(_ObservedValues[rightAtomIndex]);
692 delete boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(_ObservedValues[rightAtomElement]);
693 delete boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(_ObservedValues[rightAtomPosition]);
694 delete boost::any_cast<ObservedValue_wCallback<moleculeId_t, ObservedValue_Index_t> *>(_ObservedValues[moleculeIndex]);
695 _ObservedValues.clear();
696}
697
698ObservedValue_Index_t QtObservedBond::getIndex() const
699{
700 ASSERT( bondowner != NULL,
701 "QtObservedBond::getIndex() - index is NULL");
702 return bondowner;
703}
704
705const QtObservedBond::bondId_t QtObservedBond::getBondIndex() const
706{
707 return QtObservedBond::bondId_t(getLeftAtomIndex(), getRightAtomIndex());
708}
709
710const int& QtObservedBond::getBondDegree() const
711{
712 return boost::any_cast<ObservedValue_wCallback<int, ObservedValue_Index_t> *>(ObservedValues[BondDegree])->get();
713}
714
715const atomId_t& QtObservedBond::getLeftAtomIndex() const
716{
717 return boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(ObservedValues[leftAtomIndex])->get();
718}
719
720const atomicNumber_t& QtObservedBond::getLeftAtomElement() const
721{
722 return boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(ObservedValues[leftAtomElement])->get();
723}
724
725const Vector& QtObservedBond::getLeftAtomPosition() const
726{
727 return boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(ObservedValues[leftAtomPosition])->get();
728}
729
730const atomId_t& QtObservedBond::getRightAtomIndex() const
731{
732 return boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(ObservedValues[rightAtomIndex])->get();
733}
734
735const atomicNumber_t& QtObservedBond::getRightAtomElement() const
736{
737 return boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(ObservedValues[rightAtomElement])->get();
738}
739
740const Vector& QtObservedBond::getRightAtomPosition() const
741{
742 return boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(ObservedValues[rightAtomPosition])->get();
743}
744
745const moleculeId_t& QtObservedBond::getMoleculeIndex() const
746{
747 return boost::any_cast<ObservedValue_wCallback<moleculeId_t, ObservedValue_Index_t> *>(ObservedValues[moleculeIndex])->get();
748}
Note: See TracBrowser for help on using the repository browser.