source: src/UIElements/Qt4/InstanceBoard/QtObservedBond.cpp@ 273c8a

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

QtObservedAtom only offers direct access to associated const QtObservedMolecule ref.

  • the molecule index is not part of the atom's state, hence cannot be directly observed. The only thing we observe is the association to the molecule. For this a O/O-signal is available and we may actively change the ref when getting this signal without breaking anything as it occurs in the same thread, hence the board can be safely accessed.
  • QtObservedBond now needs to access mol index through the molecule ref.
  • QtInfoBox may now conveniently access atom'smol ref directly.
  • FIX: Removed static QtObservedBond::getMolecule().
  • Property mode set to 100644
File size: 12.2 KB
RevLine 
[b4bd0e]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
54template <class T>
55Observable * const getObservable(const T * _ptr)
56{
57 return static_cast<Observable * const>(
58 const_cast<T * const>(_ptr));
59}
60
61static QtObservedBond::ObservableCount_t initAllsignedOnChannels(const bond::ptr _bond)
62{
63 const QtObservedBond::ObservableCount_t returnlist =
64 boost::assign::list_of< QtObservedBond::ObservableCount_t::value_type >
[273c8a]65 ( getObservable(_bond.get()), 1);
[b4bd0e]66 return returnlist;
67}
68
69// static entities
70const Observable::channels_t
71QtObservedBond::BondDegreeChannels(1, BondObservable::DegreeChanged);
72
73
74QtObservedBond::QtObservedBond(
75 const bondId_t _id,
76 const bond::ptr _bond,
[4112691]77 const QtObservedAtom::ptr &_leftatom,
78 const QtObservedAtom::ptr &_rightatom,
[b4bd0e]79 QtObservedInstanceBoard &_board,
80 QWidget * _parent) :
81 QWidget(_parent),
82 Observer("QtObservedBond"),
83 AllsignedOnChannels(initAllsignedOnChannels(_bond)),
84 bondowner(NULL),
85 oldbondId(_id),
[4112691]86 leftatom(_leftatom),
87 rightatom(_rightatom),
[b4bd0e]88 board(_board),
89 BoardIsGone(false),
90 ObservedValues(QtObservedBond::MAX_ObservedTypes)
91{
92 qRegisterMetaType<bondId_t>("bondId_t");
93
94 typedef boost::function<ObservableCount_t::mapped_type& (const ObservableCount_t::key_type&)> map_accessor_t;
95 const map_accessor_t accessor =
96 boost::bind<ObservableCount_t::mapped_type&>(
97 &ObservableCount_t::at,
98 boost::ref(subjectKilledCount), _1);
99
[d48a16]100 const boost::function<void ()> bondSubjectKilled(
[b4bd0e]101 boost::bind(&QtObservedBond::countValuesSubjectKilled,
102 boost::ref(*this),
103 boost::bind(&QtObservedBond::getIndex, boost::cref(*this)),
104 boost::bind(accessor,
105 getObservable(_bond.get()))));
[4112691]106 initObservedValues( ObservedValues, _id, _bond, bondSubjectKilled);
[b4bd0e]107
108 // activating Observer is done by ObservedValueContainer when it's inserted
109}
110
111QtObservedBond::~QtObservedBond()
112{
113 boost::any_cast<ObservedValue_wCallback<int, ObservedValue_Index_t> *>(ObservedValues[BondDegree])->noteCallBackIsGone();
114
115 deactivateObserver();
116
117 destroyObservedValues(ObservedValues);
118}
119
120#ifdef HAVE_INLINE
121inline
122#endif
123int QtObservedBond::updateDegree(const bond &_bond)
124{
125 return _bond.getDegree();
126}
127
128void QtObservedBond::update(Observable *publisher)
129{
130 ASSERT(0, "QtObservedBond::update() - we are not signed on for global updates.");
131}
132
133void QtObservedBond::subjectKilled(Observable *publisher)
134{
135 ++(signedOffChannels[publisher]);
136
137 checkForRemoval(getIndex());
138}
139
140void QtObservedBond::countValuesSubjectKilled(
141 ObservedValue_Index_t _id,
142 unsigned int &_counter)
143{
144 ASSERT( _id == getIndex(),
145 "QtObservedBond::countValuesSubjectKilled() - bond "+toString(getIndex())
146 +" received countValuesSubjectKilled for bond id "+toString(_id)+".");
147
148 ++_counter;
149
150 checkForRemoval(_id);
151}
152
153void QtObservedBond::checkForRemoval(ObservedValue_Index_t _id)
154{
155 if (bondowner != NULL) {
156 // only bond needs to be destroyed to signal removal
157 const ObservableCount_t::const_iterator subjectkillediter =
158 subjectKilledCount.find(const_cast<Observable *>(bondowner));
159 const ObservableCount_t::const_iterator allsignediter =
160 AllsignedOnChannels.find(const_cast<Observable *>(bondowner));
161 const ObservableCount_t::const_iterator signedoffiter =
162 signedOffChannels.find(const_cast<Observable *>(bondowner));
163 ASSERT( (subjectkillediter != subjectKilledCount.end())
164 && (allsignediter != AllsignedOnChannels.end())
165 && (signedoffiter != signedOffChannels.end()),
166 "QtObservedBond::checkForRemoval() - something is wrong here.");
167 if ((signedoffiter->second == allsignediter->second)
168 && (subjectkillediter->second == allsignediter->second)) {
169 // remove owner: no more signOff needed
170 bondowner = NULL;
171
172 emit bondRemoved();
173
174 if (!BoardIsGone) {
175 board.markObservedBondAsDisconnected(_id);
176 board.markObservedBondForErase(_id);
177 }
178 }
179 }
180}
181
182void QtObservedBond::recieveNotification(Observable *publisher, Notification_ptr notification)
183{
184 // ObservedValues have been updated before, hence convert updates to Qt's signals
[4112691]185 if (publisher == bondowner) {
[b4bd0e]186 switch (notification->getChannelNo()) {
187 case BondObservable::DegreeChanged:
188 emit degreeChanged();
189 break;
190 default:
191 ASSERT(0, "QtObservedBond::recieveNotification() - we are not signed on to channel "
192 +toString(notification->getChannelNo())+" of the bond "
193 +toString(getBondIndex())+".");
194 break;
195 }
196 } else
197 ASSERT(0,
198 "QtObservedBond::recieveNotification() - received signal from unknown source.");
199}
200
201static QtObservedBond::ObservableCount_t::mapped_type getObservableCountValue(
202 const QtObservedBond::ObservableCount_t &_map,
203 const Observable *_obs)
204{
205 Observable * const obs_const = const_cast<Observable * const>(_obs);
206 QtObservedBond::ObservableCount_t::const_iterator iter = _map.find(obs_const);
207 ASSERT( iter != _map.end(),
208 "getObservableCount_tValue");
209 return iter->second;
210}
211
212static void assignObservableCountValue(
213 QtObservedBond::ObservableCount_t &_map,
214 const Observable *_obs,
215 const QtObservedBond::ObservableCount_t::mapped_type &_value)
216{
217 Observable * const obs_const = const_cast<Observable * const>(_obs);
218 QtObservedBond::ObservableCount_t::iterator iter = _map.find(obs_const);
219 ASSERT( iter != _map.end(),
220 "getObservableCount_tValue");
221 iter->second = _value;
222}
223
224void QtObservedBond::activateObserver()
225{
226 signedOffChannels.clear();
227 subjectKilledCount.clear();
228
[4112691]229 atom * leftatomref = getAtom(getLeftAtomIndex());
230 atom * rightatomref = getAtom(getRightAtomIndex());
231 bond::ptr bondref = leftatomref->getBond(rightatomref);
232 if (bondref != NULL) {
233 // bond
234 {
235 bondowner = static_cast<const Observable *>(bondref.get());
236 bondowner->signOn(this, BondObservable::DegreeChanged);
237 subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(bondowner), 0));
238 signedOffChannels.insert( std::make_pair(const_cast<Observable * const>(bondowner), 0));
[b4bd0e]239 }
240
[4112691]241 // and mark as connected
242 if (!BoardIsGone)
243 board.markObservedBondAsConnected(getIndex());
244 } else {
245 subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(bondowner), 1));
246 assignObservableCountValue(signedOffChannels, bondowner,
247 getObservableCountValue(AllsignedOnChannels, bondowner));
[b4bd0e]248 }
[4112691]249
250 // pass thru to signals from both atoms
251 connect( leftatom.get(), SIGNAL(indexChanged(const atomId_t, const atomId_t)),
[7f185f9]252 this, SIGNAL(leftAtomIndexChanged(atomId_t, atomId_t)));
[4112691]253 connect( leftatom.get(), SIGNAL(elementChanged()), this, SIGNAL(leftAtomElementChanged()));
254 connect( leftatom.get(), SIGNAL(positionChanged()), this, SIGNAL(leftAtomPositionChanged()));
[7f185f9]255 connect( leftatom.get(), SIGNAL(moleculeChanged()), this, SIGNAL(leftmoleculeChanged()));
[4112691]256 connect( rightatom.get(), SIGNAL(indexChanged(const atomId_t, const atomId_t)),
[7f185f9]257 this, SIGNAL(rightAtomIndexChanged(atomId_t, atomId_t)));
[4112691]258 connect( rightatom.get(), SIGNAL(elementChanged()), this, SIGNAL(rightAtomElementChanged()));
259 connect( rightatom.get(), SIGNAL(positionChanged()), this, SIGNAL(rightAtomPositionChanged()));
[7f185f9]260 connect( rightatom.get(), SIGNAL(moleculeChanged()), this, SIGNAL(rightmoleculeChanged()));
[b4bd0e]261}
262
263void QtObservedBond::deactivateObserver()
264{
265 if (bondowner != NULL) {
266 const ObservableCount_t::iterator subjectkilledbonditer =
267 subjectKilledCount.find(const_cast<Observable *>(bondowner));
268 ASSERT( (subjectkilledbonditer != subjectKilledCount.end()),
269 "QtObservedBond::deactivateObserver() - no entry in subjectKilledCount for bond"
270 +toString(bondowner)+","
271 +" has activateObserver() been called?");
272 if (subjectkilledbonditer->second == 0)
273 bondowner->signOff(this, BondObservable::DegreeChanged);
274 subjectkilledbonditer->second = 1;
275 bondowner = NULL;
276 signedOffChannels.clear();
277 signedOffChannels.insert(AllsignedOnChannels.begin(), AllsignedOnChannels.end());
278
279 if (!BoardIsGone)
280 board.markObservedBondAsDisconnected(getIndex());
281 }
282}
283
284const atom * const QtObservedBond::getAtomConst(const atomId_t _id)
285{
286 const atom * const _atom = const_cast<const World &>(World::getInstance()).
287 getAtom(AtomById(_id));
288 return _atom;
289}
290
291atom * const QtObservedBond::getAtom(const atomId_t _id)
292{
293 atom * const _atom = World::getInstance().getAtom(AtomById(_id));
294 return _atom;
295}
296
297void QtObservedBond::initObservedValues(
298 ObservedValues_t &_ObservedValues,
299 const bondId_t _id,
300 const bond::ptr _bondref,
[4112691]301 const boost::function<void()> &_bondsubjectKilled)
[b4bd0e]302{
303 // fill ObservedValues: index first
304 const boost::function<ObservedValue_Index_t ()> BondIndexGetter =
305 boost::bind(&QtObservedBond::getIndex,
306 boost::cref(*this));
307
308 // fill ObservedValues: then all the other that need index
309 const boost::function<int ()> BondDegreeUpdater(
310 boost::bind(&QtObservedBond::updateDegree, boost::cref(*_bondref)));
311
312 _ObservedValues[BondDegree] = new ObservedValue_wCallback<int, ObservedValue_Index_t>(
313 _bondref.get(),
314 BondDegreeUpdater,
315 "BondDegree_bond"+toString(_id),
316 BondDegreeUpdater(),
317 BondDegreeChannels,
[d48a16]318 _bondsubjectKilled);
[b4bd0e]319}
320
321void QtObservedBond::destroyObservedValues(
322 std::vector<boost::any> &_ObservedValues)
323{
324 delete boost::any_cast<ObservedValue_wCallback<int, ObservedValue_Index_t> *>(_ObservedValues[BondDegree]);
325 _ObservedValues.clear();
326}
327
328ObservedValue_Index_t QtObservedBond::getIndex() const
329{
330 ASSERT( bondowner != NULL,
331 "QtObservedBond::getIndex() - index is NULL");
332 return bondowner;
333}
334
335const QtObservedBond::bondId_t QtObservedBond::getBondIndex() const
336{
337 return QtObservedBond::bondId_t(getLeftAtomIndex(), getRightAtomIndex());
338}
339
340const int& QtObservedBond::getBondDegree() const
341{
342 return boost::any_cast<ObservedValue_wCallback<int, ObservedValue_Index_t> *>(ObservedValues[BondDegree])->get();
343}
344
345const atomId_t& QtObservedBond::getLeftAtomIndex() const
346{
[4112691]347 return leftatom->getAtomIndex();
[b4bd0e]348}
349
350const atomicNumber_t& QtObservedBond::getLeftAtomElement() const
351{
[4112691]352 return leftatom->getAtomElement();
[b4bd0e]353}
354
355const Vector& QtObservedBond::getLeftAtomPosition() const
356{
[4112691]357 return leftatom->getAtomPosition();
[b4bd0e]358}
359
[7f185f9]360const moleculeId_t QtObservedBond::getLeftMoleculeIndex() const
361{
[273c8a]362 if (leftatom->getMoleculeRef() != NULL)
363 return leftatom->getMoleculeRef()->getMolIndex();
364 else
365 return (moleculeId_t)-1;
[7f185f9]366}
367
[b4bd0e]368const atomId_t& QtObservedBond::getRightAtomIndex() const
369{
[4112691]370 return rightatom->getAtomIndex();
[b4bd0e]371}
372
373const atomicNumber_t& QtObservedBond::getRightAtomElement() const
374{
[4112691]375 return rightatom->getAtomElement();
[b4bd0e]376}
377
378const Vector& QtObservedBond::getRightAtomPosition() const
379{
[4112691]380 return rightatom->getAtomPosition();
[b4bd0e]381}
382
[7f185f9]383const moleculeId_t QtObservedBond::getRightMoleculeIndex() const
[b4bd0e]384{
[273c8a]385 if (rightatom->getMoleculeRef() != NULL)
386 return rightatom->getMoleculeRef()->getMolIndex();
387 else
388 return (moleculeId_t)-1;
[b4bd0e]389}
Note: See TracBrowser for help on using the repository browser.