/* * QtObservedAtom.hpp * * Created on: Oct 28, 2015 * Author: heber */ #ifndef QTOBSERVEDATOM_HPP_ #define QTOBSERVEDATOM_HPP_ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "CodePatterns/Observer/Observable.hpp" #include "CodePatterns/Observer/Observer.hpp" #include "LinearAlgebra/Vector.hpp" #include "UIElements/Qt4/InstanceBoard/ObservedValue_types.hpp" #include "UIElements/Qt4/InstanceBoard/ObservedValuesContainer.hpp" #include "types.hpp" class atom; class QtObservedInstanceBoard; class QtObservedMolecule; /** This instance is the ObservedValue representation of a World's atom. * * Due to the signal/slot mechanism and its delays, lifetime of objects in the * World and their QtGui representation cannot directly be related (without * slowing down Actions just for having the representation up to speed). * Hence, the required information for displaying and representing these * objects must be contained in an extra instance. * * This is the instance for information about a particular atom. * * Essentially, this is the interface between molecuilder's World (and a * particular atom) and the QtGui part of the code. */ class QtObservedAtom : public QWidget, public Observer { Q_OBJECT public: //!> typedef for instance wrapped in shared ptr typedef boost::shared_ptr ptr; //!> typedef for instance wrapped in weak shared ptr typedef boost::weak_ptr weak_ptr; private: //!> ObservedValuesContainer needs to access private cstor and dstor friend class ObservedValuesContainer; //!> QtObservedInstanceBoard needs to access private cstor and dstor friend class QtObservedInstanceBoard; /** Cstor of QtObservedAtom. * * \param _id id of observed atom * \param _atom ref to observed atom * \param _board ref to InstanceBoard for callbacks on occasion of subjectKilled() * \param _parent Qt parent to automatically destroy when parent is destroyed */ QtObservedAtom( const atomId_t _id, const atom * const _atom, QtObservedInstanceBoard &_board, QWidget * _parent=0); public: /** Dstor of QtObservedAtom. * */ ~QtObservedAtom(); // Observer functions void update(Observable *publisher); void subjectKilled(Observable *publisher); void recieveNotification(Observable *publisher, Notification_ptr notification); /** Getter for a permanent and unique index of this instance. * * \note ALWAYS use this index if you need to store and identifier to this * instance which you might need to retrieve at some later date. * * \warning DO NOT STORE the QtObserved...:ptr directly. This will possibly * prevent their eventual destruction. Only store the ObservedValue_Index_t * as means to obtain the ptr from the QtObservedInstanceBoard. * * \return returns a unique and permanent index that can be used to retrieve this * instance from the QtObservedInstanceBoard as it must not be stored. */ ObservedValue_Index_t getIndex() const; /** Getter to atom index contained in \a ObservedValues. * * \return atom's index */ const atomId_t& getAtomIndex() const; //!> typedef for list of bonds, defined by pairs of atom ids typedef std::vector< std::pair > ListOfBonds_t; /** Getter to atom bonds contained in \a ObservedValues. * * \return atom's bonds */ const ListOfBonds_t& getAtomBonds() const; /** Getter to atom element contained in \a ObservedValues. * * \return atom's element */ const atomicNumber_t& getAtomElement() const; /** Getter to atom name contained in \a ObservedValues. * * \return atom's name */ const std::string& getAtomName() const; /** Getter to atom position contained in \a ObservedValues. * * \return atom's position */ const Vector& getAtomPosition() const; /** Getter to the observed state of the associated molecule. * * \return const ref to observed state of molecule */ const QtObservedMolecule* const getMoleculeRef() const; /** Getter to atom's selected status. * * \return true - atom selected, false - else */ const bool getAtomSelected() const; signals: void indexChanged(const atomId_t, const atomId_t); void bondsChanged(); void elementChanged(); void moleculeChanged(); void nameChanged(); void positionChanged(); void atomRemoved(); void selectedChanged(); //private slots: private: void activateObserver(); void deactivateObserver(); static const atom * const getAtomConst(const atomId_t _id); static atom * const getAtom(const atomId_t _id); private: static atomId_t updateIndex(const atom &_atomref); static ListOfBonds_t updateBonds(const atom &_atom); static atomicNumber_t updateElement(const atom &_atom); QtObservedMolecule* updateMoleculeRef(const atom &_atom); static std::string updateName(const atom &_atom); static Vector updatePosition(const atom &_atom); static bool updateSelected(const atom &_atom); //!> enumeration of observed values to match with entries in ObservedValues enum ObservedTypes { //!> contains the current atom index AtomIndex, //!> contains the current set of bonds atoms for the atom AtomBonds, //!> contains the current atom element AtomElement, //!> contains the current atom position AtomName, //!> contains the current atom position AtomPosition, //!> contains the current atom's selection status AtomSelected, //!> contains the current atom's molecule index MoleculeRef, //!> gives the size of the enumeration MAX_ObservedTypes }; /** Initializes all \a ObservedValues entries. * * \param _ObservedValues vector of ObservedValue to be filled * \param _id atom id * \param _atomref reference to atom * \param _subjectKilled ref to function to call on subjectKilled() */ void initObservedValues( ObservedValues_t &_ObservedValues, const atomId_t _id, const atom * const _atomref, const boost::function &_subjectKilled); /** Destroys all \a ObservedValues entries. * * \param _ObservedValues vector of ObservedValue to be destroyed */ void destroyObservedValues( std::vector &_ObservedValues); /** Function is called by InstanceBoard to inform about its destruction. * * \note callbacks must not be used after this */ void noteBoardIsGone() { BoardIsGone = true; } /** Counts the number of subject killed received from the observed values. * * \param _id id to check against ours */ void countValuesSubjectKilled(ObservedValue_Index_t _id); //!> counts how many ObservedValues have already been subjectKilled() mutable size_t subjectKilledCount; /** Helper function to check that all subjectKilled have been received for both * this instance and all its internal observed values. * * \param _id id to check against ours */ void checkForRemoval(ObservedValue_Index_t _id); private: //!> list of channels when index needs to update static const Observable::channels_t AtomIndexChannels; //!> list of channels when bonds needs to update static const Observable::channels_t AtomBondsChannels; //!> list of channels when element needs to update static const Observable::channels_t AtomElementChannels; //!> list of channels when molecule index needs to update static const Observable::channels_t MoleculeChangedChannels; //!> list of channels when name needs to update static const Observable::channels_t AtomNameChannels; //!> list of channels when position needs to update static const Observable::channels_t AtomPositionChannels; //!> list of channels when selection needs to update static const Observable::channels_t AtomSelectedChannels; //!> we get multiple subjectKilled(), count and call callback() only on last const unsigned int AllsignedOnChannels; unsigned int signedOffChannels; //!> the Observable we are signed on, also indicates whether we are sign on (not NULL) const Observable *owner; private: /** Internal setter for the weak shared_ptr instance that we sometimes * need to convert the ref to this instance into an shared ptr instance that * is safe to hand around. * * \param _selfref ref to shared ptr instance that is internally stored */ void setSelfRef(const weak_ptr &_selfref) { const_cast(selfref) = _selfref; } //!> reference to this instance wrapped in a shared ptr for handing around const weak_ptr selfref; public: /** Getter for this instance safely wrapped in a shared ptr instance for * handing arount. * * \return shared ptr of this instance */ ptr getRef() const { return ptr(selfref); } private: //!> contains still the old id after the index of the atom changed atomId_t oldId; //!> unique index among all observed instances const ObservedValue_Index_t index; //!> reference to InstanceBoard for callbacks on subjectKilled() QtObservedInstanceBoard & board; //!> is board still alive or not, impacts callbacks bool BoardIsGone; //!> internal reference to ObservedValues held by QtObservedInstanceBoard ObservedValues_t ObservedValues; }; #endif /* QTOBSERVEDATOM_HPP_ */