/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2015 Frederik Heber. All rights reserved. * * * This file is part of MoleCuilder. * * MoleCuilder is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * MoleCuilder is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MoleCuilder. If not, see . */ /* * QtObservedInstanceBoard.cpp * * Created on: Oct 17, 2015 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "QtObservedInstanceBoard.hpp" #include "UIElements/Qt4/InstanceBoard/QtObservedAtom.hpp" #include "UIElements/Qt4/InstanceBoard/QtObservedMolecule.hpp" #include "CodePatterns/MemDebug.hpp" #include #include "CodePatterns/Log.hpp" #include "Atom/atom.hpp" #include "Descriptors/AtomIdDescriptor.hpp" #include "Descriptors/MoleculeIdDescriptor.hpp" #include "molecule.hpp" #include "UIElements/Qt4/InstanceBoard/ObservedValuesContainer_impl.hpp" #include "World.hpp" QtObservedInstanceBoard::QtObservedInstanceBoard(QWidget * _parent) : QWidget(_parent), Observer("QtObservedInstanceBoard"), WorldSignedOn(false), atomObservedValues( "atom", *this, boost::bind(&QtObservedInstanceBoard::atomcountsubjectKilled, this, _1)), moleculeObservedValues( "molecule", *this, boost::bind(&QtObservedInstanceBoard::moleculecountsubjectKilled, this, _1)), atomSubjectKilled( boost::bind(&ObservedValuesContainer::countsubjectKilled, boost::ref(atomObservedValues), _1)), moleculeSubjectKilled( boost::bind(&ObservedValuesContainer::countsubjectKilled, boost::ref(moleculeObservedValues), _1)), lastremovedatom((atomId_t)-1), lastremovedatomsmolecule( std::make_pair((moleculeId_t)-1,(atomId_t)-1) ), lastremovedmolecule((moleculeId_t)-1) { // be first (besides ObservedValues to know about new insertions) World::getInstance().signOn(this, World::AtomInserted, GlobalObservableInfo::PriorityLevel(int(-10))); World::getInstance().signOn(this, World::AtomRemoved, GlobalObservableInfo::PriorityLevel(int(-10))); World::getInstance().signOn(this, World::MoleculeInserted, GlobalObservableInfo::PriorityLevel(int(-10))); World::getInstance().signOn(this, World::MoleculeRemoved, GlobalObservableInfo::PriorityLevel(int(-10))); WorldSignedOn = true; } QtObservedInstanceBoard::~QtObservedInstanceBoard() { if (WorldSignedOn) { World::getInstance().signOff(this, World::AtomInserted); World::getInstance().signOff(this, World::AtomRemoved); World::getInstance().signOff(this, World::MoleculeInserted); World::getInstance().signOff(this, World::MoleculeRemoved); } // sign off from all remaining molecules and atoms for (SignedOn_t::iterator iter = AtomSignedOn.begin(); !AtomSignedOn.empty(); iter = AtomSignedOn.begin()) { (*iter)->signOff(this, atom::IndexChanged); AtomSignedOn.erase(iter); } for (SignedOn_t::iterator iter = MoleculeSignedOn.begin(); !MoleculeSignedOn.empty(); iter = MoleculeSignedOn.begin()) { (*iter)->signOff(this, molecule::IndexChanged); (*iter)->signOff(this, molecule::AtomInserted); (*iter)->signOff(this, molecule::AtomRemoved); MoleculeSignedOn.erase(*iter); //erase all instances } } void QtObservedInstanceBoard::update(Observable *publisher) { ASSERT(0, "QtObservedInstanceBoard::update() - we are not signed on to general updates."); } void QtObservedInstanceBoard::subjectKilled(Observable *publisher) { SignedOn_t::iterator iter = AtomSignedOn.find(publisher); if ( iter != AtomSignedOn.end()) { LOG(3, "DEBUG: InstanceBoard got subjectKilled() from atom " << publisher); AtomSignedOn.erase(iter); } else { iter = MoleculeSignedOn.find(publisher); if ( iter != MoleculeSignedOn.end()) { LOG(3, "DEBUG: InstanceBoard got subjectKilled() from molecule " << publisher); MoleculeSignedOn.erase(iter); } else { ASSERT(0, "QtObservedInstanceBoard::subjectKilled() - could not find signedOn for atom/molecule "+toString(publisher)); } } } void QtObservedInstanceBoard::recieveNotification(Observable *publisher, Notification_ptr notification) { if (static_cast(publisher) == World::getPointer()) { switch (notification->getChannelNo()) { case World::MoleculeInserted: { const moleculeId_t _id = const_cast(World::getInstance()).lastChangedMolId(); #ifdef LOG_OBSERVER observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast(this)) << " received notification that molecule "+toString(_id)+" has been inserted."; #endif LOG(3, "DEBUG: InformationBoard got moleculeInserted signal for molecule " << _id); const molecule * const _molecule = const_cast(World::getInstance()). getMolecule(MoleculeById(_id)); if (_molecule != NULL) { ObservedValues_t ObservedValues(QtObservedMolecule::MAX_ObservedTypes); LOG(3, "DEBUG: InformationBoard initializes ObservedValues for molecule " << _id); QtObservedMolecule::initObservedValues( ObservedValues, _id, _molecule, moleculeSubjectKilled); QtObservedMolecule::ptr observedmolecule(new QtObservedMolecule(ObservedValues, *this)); #ifndef NDEBUG bool status = #endif moleculeObservedValues.insert(_id, observedmolecule); ASSERT( status, "QtObservedInstanceBoard::recieveNotification() - could not insert ObservedMolecule for" +toString(_id)+"."); // we need to check for index changes LOG(3, "DEBUG: InformationBoard signOn()s to molecule " << _id); _molecule->signOn(this, molecule::IndexChanged); MoleculeSignedOn.insert( static_cast(const_cast(_molecule)) ); _molecule->signOn(this, molecule::AtomInserted); MoleculeSignedOn.insert( static_cast(const_cast(_molecule)) ); _molecule->signOn(this, molecule::AtomRemoved); MoleculeSignedOn.insert( static_cast(const_cast(_molecule)) ); emit moleculeInserted(_id); } else { ELOG(1, "QtObservedInstanceBoard got MoleculeInserted for unknown molecule id " << _id); } break; } case World::MoleculeRemoved: { const moleculeId_t _id = const_cast(World::getInstance()).lastChangedMolId(); LOG(3, "DEBUG: InformationBoard got MoleculeRemoved signal for molecule " << _id); // note down such that ObservedValues are simply dropped lastremovedmolecule = _id; break; } case World::AtomInserted: { const atomId_t _id = const_cast(World::getInstance()).lastChangedAtomId(); #ifdef LOG_OBSERVER observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast(this)) << " received notification that atom "+toString(_id)+" has been inserted."; #endif LOG(3, "DEBUG: InformationBoard got atomInserted signal for atom " << _id); const atom * const _atom = const_cast(World::getInstance()). getAtom(AtomById(_id)); if (_atom!= NULL) { ObservedValues_t ObservedValues(QtObservedAtom::MAX_ObservedTypes); LOG(3, "DEBUG: InformationBoard initializes ObservedValues for atom " << _id); QtObservedAtom::initObservedValues( ObservedValues, _id, _atom, atomSubjectKilled); QtObservedAtom::ptr observedatom(new QtObservedAtom(ObservedValues, *this)); #ifndef NDEBUG bool status = #endif atomObservedValues.insert(_id, observedatom); ASSERT( status, "QtObservedInstanceBoard::recieveNotification() - could not insert ObservedValues for" +toString(_id)+"."); // we need to check for index changes LOG(3, "DEBUG: InformationBoard signOn()s to atom " << _id); _atom->signOn(this, atom::IndexChanged); AtomSignedOn.insert( static_cast(const_cast(_atom)) ); } else { ELOG(1, "QtObservedInstanceBoard got AtomInserted for unknown atom id " << _id); } break; } case World::AtomRemoved: { const atomId_t _id = const_cast(World::getInstance()).lastChangedAtomId(); LOG(3, "DEBUG: InformationBoard got AtomRemoved signal for atom " << _id); // note down such that ObservedValues are simply dropped lastremovedatom = _id; break; } default: ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here for World."); break; } } else if (dynamic_cast(publisher) != NULL) { const moleculeId_t molid = const_cast(World::getInstance()).lastChangedMolId(); switch (notification->getChannelNo()) { case molecule::AtomInserted: { const molecule * const _molecule = const_cast(World::getInstance()). getMolecule(MoleculeById(molid)); if (_molecule != NULL) { const atomId_t atomid = const_cast(_molecule)->lastChangedAtomId(); LOG(3, "DEBUG: InformationBoard got AtomInserted signal for atom " << atomid << " from molecule " << molid); // check whether atom's observedvalues are present ASSERT( atomObservedValues.isPresent(atomid), "QtObservedInstanceBoard::recieveNotification() - ObservedValues for atom " +toString(atomid)+" are not present yet."); // and emit emit atomInserted(molid, atomid); } else { ELOG(2, "QtObservedInstanceBoard::recieveNotification() - molecule " << molid << " has disappeared."); } break; } case molecule::AtomRemoved: { const molecule * const _molecule = const_cast(World::getInstance()). getMolecule(MoleculeById(molid)); if (_molecule != NULL) { const atomId_t atomid = const_cast(_molecule)->lastChangedAtomId(); LOG(3, "DEBUG: InformationBoard got AtomRemoved signal for atom " << atomid << " from molecule " << molid); lastremovedatomsmolecule = std::make_pair(molid, atomid); } break; } case molecule::IndexChanged: { // molecule has changed its index const moleculeId_t newmoleculeId = dynamic_cast(publisher)->getId(); LOG(3, "DEBUG: InformationBoard got IndexChanged from molecule " << molid << " to " << newmoleculeId); #ifndef NDEBUG bool status = #endif moleculeObservedValues.changeIdentifier(molid, newmoleculeId); ASSERT( status, "QtObservedInstanceBoard::recieveNotification() - cannot change molecule's id " +toString(molid)+" "+toString(newmoleculeId)+" in moleculeObservedValues."); // no need update SignedOn, ref does not change emit moleculeIndexChanged(molid, newmoleculeId); break; } default: ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here."); break; } } else if (dynamic_cast(publisher) != NULL) { const atomId_t oldatomId = const_cast(World::getInstance()).lastChangedAtomId(); switch (notification->getChannelNo()) { case AtomObservable::IndexChanged: { const atomId_t newatomId = dynamic_cast(publisher)->getId(); LOG(3, "DEBUG: InformationBoard got IndexChanged from atom " << oldatomId << " to " << newatomId); atomObservedValues.changeIdentifier(oldatomId, newatomId); // no need update SignedOn, ref does not change emit atomIndexChanged(oldatomId, newatomId); break; } default: ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here."); break; } } else { ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - notification from unknown source."); } } void QtObservedInstanceBoard::atomcountsubjectKilled(const atomId_t _atomid) { if ((_atomid == lastremovedatomsmolecule.second) && (_atomid == lastremovedatom)) { LOG(3, "DEBUG: InstanceBoard emits atomRemoved for " << _atomid); emit atomRemoved(lastremovedatomsmolecule.first, lastremovedatomsmolecule.second); } else ELOG(2, "QtObservedInstanceBoard::atomcountsubjectKilled() - id " << _atomid << " not fitting with " << lastremovedatomsmolecule << " or " << lastremovedatom); } void QtObservedInstanceBoard::moleculecountsubjectKilled(const moleculeId_t _molid) { if (lastremovedmolecule == _molid) { LOG(3, "DEBUG: InstanceBoard emits moleculeRemoved for " << _molid); emit moleculeRemoved(_molid); } else ELOG(2, "QtObservedInstanceBoard::moleculecountsubjectKilled() - id " << _molid << " not fitting with " << lastremovedmolecule); } QtObservedAtom::ptr QtObservedInstanceBoard::getObservedAtom(const atomId_t _id) { return atomObservedValues.get(_id); } QtObservedMolecule::ptr QtObservedInstanceBoard::getObservedMolecule(const moleculeId_t _id) { return moleculeObservedValues.get(_id); } void QtObservedInstanceBoard::markObservedAtomAsConnected(const atomId_t _id) { atomObservedValues.markObservedValuesAsConnected(_id); } void QtObservedInstanceBoard::markObservedAtomAsDisconnected(const atomId_t _id) { atomObservedValues.markObservedValuesAsDisconnected(_id); } void QtObservedInstanceBoard::markObservedMoleculeAsConnected(const moleculeId_t _id) { moleculeObservedValues.markObservedValuesAsConnected(_id); } void QtObservedInstanceBoard::markObservedMoleculeAsDisconnected(const moleculeId_t _id) { moleculeObservedValues.markObservedValuesAsDisconnected(_id); }