/* * GLMoleculeObject_atom.hpp * * Created on: Aug 17, 2011 * Author: heber */ #ifndef GLMOLECULEOBJECT_ATOM_HPP_ #define GLMOLECULEOBJECT_ATOM_HPP_ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "GLMoleculeObject.hpp" #include #include #include "CodePatterns/ObservedValue.hpp" #include "CodePatterns/Observer/Observer.hpp" #include "LinearAlgebra/Vector.hpp" #include "Bond/bond.hpp" #include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.hpp" #include "types.hpp" class GLWorldScene; class GLMoleculeObject_atom : public GLMoleculeObject, Observer { Q_OBJECT public: GLMoleculeObject_atom(QGLSceneNode *mesh[], QObject *parent, const atomId_t id); virtual ~GLMoleculeObject_atom(); void draw(QGLPainter *painter, const QVector4D &cameraPlane); // Observer functions void update(Observable *publisher); void subjectKilled(Observable *publisher); void recieveNotification(Observable *publisher, Notification_ptr notification); public slots: void Selected(); void Unselected(); private slots: void wasClicked(); void resetIndex(); void resetElement(); void resetPosition(); void resetBonds(); signals: void clicked(atomId_t); void BondsAdded(const atomId_t _left, const atomId_t _right, const GLMoleculeObject_bond::SideOfBond side); void BondsRemoved(const atomId_t _left, const atomId_t _right); void indexChanged(GLMoleculeObject_atom *ob, const atomId_t oldId, const atomId_t newId); void idChanged(); void positionChanged(); void elementChanged(); void bondsChanged(); void InstanceRemoved(const atomId_t); private: //!> grant GLMoleculeObject_molecule acess to reset functions friend class GLMoleculeObject_molecule; //!> typedef for list of bonds, defined by pairs of atom ids typedef std::vector< std::pair > ListOfBonds_t; static const atom * const getAtomConst(const atomId_t _id); static atom * const getAtom(const atomId_t _id); static atomId_t updateIndex(); static Vector updatePosition( const boost::function &_getAtomIndex); static atomicNumber_t updateElement( const boost::function &_getAtomIndex); static ListOfBonds_t updateBonds( const boost::function &_getAtomIndex); void activateObserver(); void deactivateObserver(); private: //!> current list of bonds to compare new onw against for changes ListOfBonds_t ListOfBonds; //!> temporary variable used in cstor atom * const atomref; private: /** Observed Values **/ //!> enumeration of observed values to match with entries in ObservedValues enum ObservedTypes { //!> contains the current atom index AtomIndex, //!> contains the current atom position AtomPosition, //!> contains the current atom element AtomElement, //!> contains the current set of bonds atoms fort the atom AtomBonds, //!> gives the size of the enumeration MAX_ObservedTypes }; //!> vector with all observed values std::vector ObservedValues; /** 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() */ static void initObservedValues( std::vector &_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 */ static void destroyObservedValues( std::vector &_ObservedValues); /** Getter to atom index contained in \a ObservedValues. * * \return atom's index */ atomId_t getAtomIndex() const; /** Getter to atom position contained in \a ObservedValues. * * \return atom's position */ Vector getAtomPosition() const; /** Getter to atom element contained in \a ObservedValues. * * \return atom's elemnt */ atomicNumber_t getAtomElement() const; /** Getter to atom bonds contained in \a ObservedValues. * * \return atom's bonds */ ListOfBonds_t getAtomBonds() const; /** Counts how many ObservedValues got subjectKilled. * * This is used to give InstanceRemoved() signal only when each and every * ObservedValue (and the instance itself) has been subjectKilled by the * monitored Observable. Only then can we safely remove the instance. * */ void countsubjectKilled(); //!> counts how many ObservedValues have already been subjectKilled() mutable size_t subjectKilledCount; private: //!> list of channels when index needs to update static const Observable::channels_t AtomIndexChannels; //!> list of channels when position needs to update static const Observable::channels_t AtomPositionChannels; //!> list of channels when element needs to update static const Observable::channels_t AtomElementChannels; //!> list of channels when bonds needs to update static const Observable::channels_t AtomBondsChannels; //!> the Observable we are signed on, also indicates whether we are sign on (not NULL) const Observable *owner; }; #endif /* GLMOLECULEOBJECT_ATOM_HPP_ */