/* * 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)), bondObservedValues( "bond", *this, boost::bind(&QtObservedInstanceBoard::bondcountsubjectKilled, this, _1)), moleculeObservedValues( "molecule", *this, boost::bind(&QtObservedInstanceBoard::moleculecountsubjectKilled, this, _1)) { qRegisterMetaType("ObservedValue_Index_t"); qRegisterMetaType("QtObservedAtom::ptr"); qRegisterMetaType("QtObservedBond::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::MoleculeInserted, GlobalObservableInfo::PriorityLevel(int(-10))); WorldSignedOn = true; } QtObservedInstanceBoard::~QtObservedInstanceBoard() { if (WorldSignedOn) { World::getInstance().signOff(this, World::AtomInserted); World::getInstance().signOff(this, World::MoleculeInserted); } // sign off from all remaining molecules, bonds, and atoms for (SignedOn_t::iterator iter = AtomSignedOn.begin(); !AtomSignedOn.empty(); iter = AtomSignedOn.begin()) { (*iter)->signOff(this, atom::IndexChanged); (*iter)->signOff(this, atom::BondsAdded); AtomSignedOn.erase(*iter); } for (SignedOn_t::iterator iter = MoleculeSignedOn.begin(); !MoleculeSignedOn.empty(); iter = MoleculeSignedOn.begin()) { (*iter)->signOff(this, molecule::IndexChanged); MoleculeSignedOn.erase(iter); } } 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); // only remove one } 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)); observedmolecule->setSelfRef(observedmolecule); const ObservedValue_Index_t index = observedmolecule->getIndex(); moleculeObservedValues.insert(index, observedmolecule); moleculeids_lookup.left.insert( std::make_pair(_id, index) ); // 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::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)); observedatom->setSelfRef(observedatom); const ObservedValue_Index_t index = observedatom->getIndex(); atomObservedValues.insert(index, observedatom); atomids_lookup.left.insert( std::make_pair(_id, index) ); // we need to check for index changes LOG(3, "DEBUG: InformationBoard signOn()s to atom " << _id); _atom->signOn(this, atom::IndexChanged); _atom->signOn(this, atom::BondsAdded); AtomSignedOn.insert( static_cast(const_cast(_atom)) ); AtomSignedOn.insert( static_cast(const_cast(_atom)) ); emit atomInserted(observedatom); } else { ELOG(1, "QtObservedInstanceBoard got AtomInserted for unknown atom id " << _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); { typename IdtoIndex_t::left_iterator iter = moleculeids_lookup.left.find(molid); ASSERT( iter != moleculeids_lookup.left.end(), "QtObservedInstanceBoard::recieveNotification() - mol id " +toString(molid)+" unknown to lookup."); const ObservedValue_Index_t index = iter->second; moleculeids_lookup.left.erase(iter); moleculeids_lookup.left.insert( std::pair(newmoleculeId, index) ); } // 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); { typename IdtoIndex_t::left_iterator iter = atomids_lookup.left.find(oldatomId); ASSERT( iter != atomids_lookup.left.end(), "QtObservedInstanceBoard::recieveNotification() - atom id " +toString(oldatomId)+" unknown to lookup."); const ObservedValue_Index_t index = iter->second; atomids_lookup.left.erase(iter); atomids_lookup.left.insert( std::pair(newatomId, index) ); } // no need update SignedOn, ref does not change emit atomIndexChanged(oldatomId, newatomId); break; } case AtomObservable::BondsAdded: { const atom * _atom = dynamic_cast(publisher); const atomId_t _id = _atom->getId(); #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 bondInserted signal for atom " << _id); if (_atom != NULL) { // find the new bond by simply taking the last added to the list const BondList &ListOfBonds = _atom->getListOfBonds(); const bond::ptr bondref = ListOfBonds.back(); // check whether bond is already present, cause we get BondsAdded from both atoms const bondId_t bondid = std::make_pair( bondref->leftatom->getId(), bondref->rightatom->getId()); if (!bondids_lookup.left.count(bondid)) { const QtObservedAtom::ptr leftatom = getObservedAtom(bondref->leftatom->getId()); ASSERT( leftatom, "QtObservedInstanceBoard::recieveNotification() - QtObservedAtom leftatom to bond must exist."); const QtObservedAtom::ptr rightatom = getObservedAtom(bondref->rightatom->getId()); ASSERT( rightatom, "QtObservedInstanceBoard::recieveNotification() - QtObservedAtom leftatom to bond must exist."); LOG(3, "DEBUG: InformationBoard initializes QtObservedBond for " << bondid); QtObservedBond::ptr observedbond( new QtObservedBond(bondid, bondref, leftatom, rightatom, *this)); const ObservedValue_Index_t index = observedbond->getIndex(); bondObservedValues.insert(index, observedbond); bondids_lookup.left.insert( std::make_pair(bondid, index) ); emit bondInserted(observedbond); } } else { ELOG(1, "QtObservedInstanceBoard got BondsAdded for unknown atom id " << _id); } break; } default: ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here."); break; } } else { ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - notification from unknown source."); } } const atomId_t QtObservedInstanceBoard::getAtomIdToIndex(ObservedValue_Index_t _id) const { typename IdtoIndex_t::right_const_iterator iter = atomids_lookup.right.find(_id); if (iter != atomids_lookup.right.end()) return iter->second; else return (atomId_t)-1; } const QtObservedInstanceBoard::bondId_t QtObservedInstanceBoard::getBondIdToIndex(ObservedValue_Index_t _id) const { typename IdtoIndex_t::right_const_iterator iter = bondids_lookup.right.find(_id); if (iter != bondids_lookup.right.end()) return iter->second; else return QtObservedInstanceBoard::bondId_t(std::make_pair( (atomId_t)-1, (atomId_t)-1) ); } const moleculeId_t QtObservedInstanceBoard::getMoleculeIdToIndex(ObservedValue_Index_t _id) const { typename IdtoIndex_t::right_const_iterator iter = moleculeids_lookup.right.find(_id); if (iter != moleculeids_lookup.right.end()) return iter->second; else return (moleculeId_t)-1; } void QtObservedInstanceBoard::atomcountsubjectKilled(ObservedValue_Index_t _id) { LOG(3, "DEBUG: InstanceBoard emits atomRemoved for " << getAtomIdToIndex(_id)); emit atomRemoved(_id); } void QtObservedInstanceBoard::bondcountsubjectKilled(ObservedValue_Index_t _id) { LOG(3, "DEBUG: InstanceBoard emits bondRemoved for " << getBondIdToIndex(_id)); emit bondRemoved(_id); } void QtObservedInstanceBoard::moleculecountsubjectKilled(ObservedValue_Index_t _id) { LOG(3, "DEBUG: InstanceBoard emits moleculeRemoved for " << getMoleculeIdToIndex(_id)); emit moleculeRemoved(_id); } QtObservedAtom::ptr QtObservedInstanceBoard::getObservedAtom(const atomId_t _id) { typename IdtoIndex_t::left_iterator iter = atomids_lookup.left.find(_id); if (iter == atomids_lookup.left.end()) return QtObservedAtom::ptr(); else return atomObservedValues.get(iter->second); } QtObservedAtom::ptr QtObservedInstanceBoard::getObservedAtom(ObservedValue_Index_t _id) { return atomObservedValues.get(_id); } QtObservedBond::ptr QtObservedInstanceBoard::getObservedBond(const bondId_t _id) { typename IdtoIndex_t::left_iterator iter = bondids_lookup.left.find(_id); if (iter == bondids_lookup.left.end()) return QtObservedBond::ptr(); else return bondObservedValues.get(iter->second); } QtObservedBond::ptr QtObservedInstanceBoard::getObservedBond(ObservedValue_Index_t _id) { return bondObservedValues.get(_id); } QtObservedMolecule::ptr QtObservedInstanceBoard::getObservedMolecule(const moleculeId_t _id) { typename IdtoIndex_t::left_iterator iter = moleculeids_lookup.left.find(_id); if (iter == moleculeids_lookup.left.end()) return QtObservedMolecule::ptr(); else return moleculeObservedValues.get(iter->second); } QtObservedMolecule::ptr QtObservedInstanceBoard::getObservedMolecule(ObservedValue_Index_t _id) { return moleculeObservedValues.get(_id); } void QtObservedInstanceBoard::markObservedAtomAsConnected(ObservedValue_Index_t _id) { atomObservedValues.markObservedValuesAsConnected(_id); } void QtObservedInstanceBoard::markObservedAtomAsDisconnected(ObservedValue_Index_t _id) { atomObservedValues.markObservedValuesAsDisconnected(_id); } void QtObservedInstanceBoard::markObservedAtomForErase(ObservedValue_Index_t _id) { atomObservedValues.eraseObservedValues(_id); atomids_lookup.right.erase(_id); } void QtObservedInstanceBoard::markObservedBondAsConnected(ObservedValue_Index_t _id) { bondObservedValues.markObservedValuesAsConnected(_id); } void QtObservedInstanceBoard::markObservedBondAsDisconnected(ObservedValue_Index_t _id) { bondObservedValues.markObservedValuesAsDisconnected(_id); } void QtObservedInstanceBoard::markObservedBondForErase(ObservedValue_Index_t _id) { bondObservedValues.eraseObservedValues(_id); bondids_lookup.right.erase(_id); } void QtObservedInstanceBoard::markObservedMoleculeAsConnected(ObservedValue_Index_t _id) { moleculeObservedValues.markObservedValuesAsConnected(_id); } void QtObservedInstanceBoard::markObservedMoleculeAsDisconnected(ObservedValue_Index_t _id) { moleculeObservedValues.markObservedValuesAsDisconnected(_id); } void QtObservedInstanceBoard::markObservedMoleculeForErase(ObservedValue_Index_t _id) { moleculeObservedValues.eraseObservedValues(_id); moleculeids_lookup.right.erase(_id); }