/* * 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 #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)), lastremovedatom((atomId_t)-1), lastremovedmolecule((moleculeId_t)-1) { qRegisterMetaType("QtObservedAtom::ptr"); qRegisterMetaType("QtObservedMolecule::ptr"); // 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()) { Observable * const _observable = *iter; _observable->signOff(this, molecule::IndexChanged); // remove all three remaining instances in multiset for (SignedOn_t::iterator sameiter = MoleculeSignedOn.find(_observable); sameiter != MoleculeSignedOn.end(); sameiter = MoleculeSignedOn.find(_observable)) MoleculeSignedOn.erase(*sameiter); //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) { LOG(3, "DEBUG: InformationBoard initializes QtObservedMolecule for " << _id); QtObservedMolecule::ptr observedmolecule( new QtObservedMolecule( _id, _molecule, *this)); moleculeObservedValues.insert(_id, observedmolecule); // 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)) ); emit moleculeInserted(observedmolecule); } 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) { LOG(3, "DEBUG: InformationBoard initializes QtObservedAtom for " << _id); QtObservedAtom::ptr observedatom( new QtObservedAtom(_id, _atom, *this)); atomObservedValues.insert(_id, observedatom); // 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)) ); emit atomInserted(observedatom); } 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::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); #ifndef NDEBUG bool status = #endif atomObservedValues.changeIdentifier(oldatomId, newatomId); ASSERT( status, "QtObservedInstanceBoard::recieveNotification() - cannot change atom's id " +toString(oldatomId)+" "+toString(newatomId)+" in atomObservedValues."); // 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 == lastremovedatom)) { LOG(3, "DEBUG: InstanceBoard emits atomRemoved for " << _atomid); emit atomRemoved(lastremovedatom); } else ELOG(2, "QtObservedInstanceBoard::atomcountsubjectKilled() - id " << _atomid << " not fitting with " << 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::markObservedAtomForErase(const atomId_t _id) { atomObservedValues.eraseObservedValues(_id); } void QtObservedInstanceBoard::markObservedMoleculeAsConnected(const moleculeId_t _id) { moleculeObservedValues.markObservedValuesAsConnected(_id); } void QtObservedInstanceBoard::markObservedMoleculeAsDisconnected(const moleculeId_t _id) { moleculeObservedValues.markObservedValuesAsDisconnected(_id); } void QtObservedInstanceBoard::markObservedMoleculeForErase(const moleculeId_t _id) { moleculeObservedValues.eraseObservedValues(_id); }