/* * QtObservedBond.hpp * * Created on: Mar 03, 2016 * Author: heber */ #ifndef QTOBSERVEDBOND_HPP_ #define QTOBSERVEDBOND_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 "Bond/bond.hpp" #include "UIElements/Qt4/InstanceBoard/ObservedValue_types.hpp" #include "UIElements/Qt4/InstanceBoard/ObservedValuesContainer.hpp" #include "types.hpp" class atom; class molecule; class QtObservedInstanceBoard; class QtObservedMolecule; /** This instance is the ObservedValue representation of a World's bond. * * 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 bond. * * Essentially, this is the interface between molecuilder's World (and a * particular bond) and the QtGui part of the code. */ class QtObservedBond : public QWidget, public Observer { Q_OBJECT public: typedef std::pair bondId_t; //!> 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 QtObservedBond. * * \param _id id of observed bond * \param _bond ref to observed bond * \param _board ref to InstanceBoard for callbacks on occasion of subjectKilled() * \param _parent Qt parent to automatically destroy when parent is destroyed */ QtObservedBond( const bondId_t _id, const bond::ptr _bond, QtObservedInstanceBoard &_board, QWidget * _parent=0); public: /** Dstor of QtObservedBond. * */ ~QtObservedBond(); // 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 bond's index pair contained in \a ObservedValues. * * \return bond's index pair */ const bondId_t getBondIndex() const; /** Getter to bond's degree contained in \a ObservedValues. * * \return bond's degree */ const int& getBondDegree() const; /** Getter to bond's left atom index contained in \a ObservedValues. * * \return bond's left atom index */ const atomId_t& getLeftAtomIndex() const; /** Getter to bond's left atom element contained in \a ObservedValues. * * \return bond's left atom element */ const atomicNumber_t& getLeftAtomElement() const; /** Getter to bond's right atom position contained in \a ObservedValues. * * \return bond's left atom position */ const Vector& getLeftAtomPosition() const; /** Getter to bond's right atom index contained in \a ObservedValues. * * \return bond's right atom index */ const atomId_t& getRightAtomIndex() const; /** Getter to bond's right atom element contained in \a ObservedValues. * * \return bond's right atom element */ const atomicNumber_t& getRightAtomElement() const; /** Getter to bond's right atom position contained in \a ObservedValues. * * \return bond's right atom position */ const Vector& getRightAtomPosition() const; /** Getter to bond's molecule index contained in \a ObservedValues. * * \return bond's molecule index */ const moleculeId_t& getMoleculeIndex() const; //!> typedef for internal observable counter maps typedef std::map ObservableCount_t; signals: void indexChanged(bondId_t, bondId_t); void degreeChanged(); void leftAtomIndexChanged(atomId_t, atomId_t); void leftAtomElementChanged(); void leftAtomPositionChanged(); void rightAtomIndexChanged(atomId_t, atomId_t); void rightAtomElementChanged(); void rightAtomPositionChanged(); void moleculeIndexChanged(moleculeId_t, moleculeId_t); void bondRemoved(); //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 int updateDegree(const bond &_bond); static atomId_t updateLeftAtomIndex(const atom &_atomref); static atomicNumber_t updateLeftAtomElement(const atom &_atomref); static Vector updateLeftAtomPosition(const atom &_atomref); static atomId_t updateRightAtomIndex(const atom &_atomref); static atomicNumber_t updateRightAtomElement(const atom &_atomref); static Vector updateRightAtomPosition(const atom &_atomref); static moleculeId_t updateMoleculeIndex(const molecule &_molref); //!> enumeration of observed values to match with entries in ObservedValues enum ObservedTypes { //!> contains the current bond degree BondDegree, //!> contains the index of the left atom leftAtomIndex, //!> contains the position of the left atom leftAtomPosition, //!> contains the element of the left atom leftAtomElement, //!> contains the index of the right atom rightAtomIndex, //!> contains the position of the right atom rightAtomPosition, //!> contains the element of the right atom rightAtomElement, //!> contains the id of the molecule this bond is associated with moleculeIndex, //!> gives the size of the enumeration MAX_ObservedTypes }; /** Initializes all \a ObservedValues entries. * * \param _ObservedValues vector of ObservedValue to be filled * \param _id bond id * \param _bondref reference to bond * \param _bondsubjectKilled ref to function to call on subjectKilled() from bond * \param _leftatomsubjectKilled ref to function to call on subjectKilled() from leftatom * \param _rightatomsubjectKilled ref to function to call on subjectKilled() from rightatom * \param _moleculesubjectKilled ref to function to call on subjectKilled() from molecule */ void initObservedValues( ObservedValues_t &_ObservedValues, const bondId_t _id, const bond::ptr _bondref, const boost::function &_bondsubjectKilled, const boost::function &_leftatomsubjectKilled, const boost::function &_rightatomsubjectKilled, const boost::function &_moleculesubjectKilled); /** Destroys all \a ObservedValues entries. * * \param _ObservedValues vector of ObservedValue to be destroyed */ static 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 * \param _counter counter to decrease */ void countValuesSubjectKilled(ObservedValue_Index_t _id, unsigned int &_counter); //!> counts how many ObservedValues have already been subjectKilled() for a given observable mutable ObservableCount_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 BondDegreeChannels; //!> we get multiple subjectKilled(), count and call callback() only on last const ObservableCount_t AllsignedOnChannels; ObservableCount_t signedOffChannels; //!> the Observable we are signed on, also indicates whether we are sign on (not NULL) const Observable *bondowner; const Observable *leftatomowner; const Observable *rightatomowner; const Observable *moleculeowner; 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 bond changed bondId_t oldbondId; //!> contains still the old id after the index of the left atom changed atomId_t oldleftatomId; //!> contains still the old id after the index of the right atom changed atomId_t oldrightatomId; //!> contains still the old id after the index of the molecule changed moleculeId_t oldmoleculeId; //!> 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 /* QTOBSERVEDBOND_HPP_ */