/* * GLMoleculeObject_molecule.hpp * * Created on: Mar 30, 2012 * Author: ankele */ #ifndef GLMOLECULEOBJECT_MOLECULE_HPP_ #define GLMOLECULEOBJECT_MOLECULE_HPP_ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "GLMoleculeObject.hpp" #include #include #include #include #include "CodePatterns/Cacheable.hpp" #include "CodePatterns/Observer/Observer.hpp" #include "CodePatterns/ObservedValue.hpp" #include "GLMoleculeObject_bond.hpp" #include "molecule.hpp" class atom; class bond; class GLMoleculeObject_atom; class GLWorldScene; class GLMoleculeObject_molecule : public GLMoleculeObject, public Observer { Q_OBJECT public: GLMoleculeObject_molecule(QObject *parent, const moleculeId_t molid); GLMoleculeObject_molecule(QGLSceneNode *mesh[], QObject *parent, const moleculeId_t molid); virtual ~GLMoleculeObject_molecule(); // Observer functions void update(Observable *publisher); void subjectKilled(Observable *publisher); void recieveNotification(Observable *publisher, Notification_ptr notification); void initialize(QGLView *view, QGLPainter *painter); void draw(QGLPainter *painter, const QVector4D &cameraPlane); typedef std::pair< atomId_t, atomId_t> BondIds; friend std::ostream &operator<<(std::ostream &ost, const BondIds &t); static BondIds getBondIds( const bond::ptr _bond, const enum GLMoleculeObject_bond::SideOfBond side); signals: void changed(); void changeOccured(); void hoverChanged(const atomId_t); void hoverChanged(const moleculeId_t, int); void indexChanged(GLMoleculeObject_molecule *, const moleculeId_t, const moleculeId_t); void atomClicked(atomId_t no); void moleculeClicked(moleculeId_t no); void TesselationHullChanged(); void BoundingBoxChanged(); void IsSelectedChanged(); void AtomInserted(const atomId_t _id); void AtomRemoved(const atomId_t _id); void IdChanged(); void InstanceRemoved(const moleculeId_t); private slots: //!> grant GLWorldScene access to private slots friend class GLWorldScene; void wasClicked(); void atomInserted(const atomId_t _id); void atomRemoved(const atomId_t _id); void bondInserted(const atomId_t, const atomId_t, const GLMoleculeObject_bond::SideOfBond side); void bondRemoved(const atomId_t leftnr, const atomId_t rightnr); void hoverChangedSignalled(GLMoleculeObject *ob); void changeAtomId(GLMoleculeObject_atom *, const atomId_t, const atomId_t); void setVisible(bool value); void activateObserver(); void deactivateObserver(); void resetTesselationHull(); void resetBoundingBox(); void resetAtoms(); void resetIndex(); void resetName(); void AtomSelected(const atomId_t _id); void AtomUnselected(const atomId_t _id); void Selected(); void Unselected(); private: static const molecule * const getMolecule(const moleculeId_t _id); private: void addAtomBonds( const bond::ptr &_bond, const GLMoleculeObject_bond::SideOfBond _side ); void addAtomBonds(const atomId_t _id); //!> typedef for the internal set of atoms typedef std::set atoms_t; static molecule::BoundingBoxInfo initBoundingBox(); QGeometryData updateTesselationHull() const; static molecule::BoundingBoxInfo updateBoundingBox( const boost::function &_getMolIndex); static moleculeId_t updateIndex(); static std::string updateName( const boost::function &_getMolIndex); //!> the Observable we are signed on, also indicates whether we are sign on (not NULL) const Observable * owner; //!> internal variable for caching molecule ref in cstor const molecule * const molref; //!> list of channels when contained atoms needs to update static const Observable::channels_t AtomsChannels; //!> list of channels when tesselation hull needs to update static const Observable::channels_t HullChannels; //!> list of channels when bounding box needs to update static const Observable::channels_t BoundingBoxChannels; //!> list of channels when the index needs to update static const Observable::channels_t IndexChannels; //!> list of channels when the name needs to update static const Observable::channels_t NameChannels; private: /** Observed Values **/ //!> enumeration of observed values to match with entries in ObservedValues enum ObservedTypes { //!> contains the current molecule index MolIndex, //!> contains the current molecule name MolName, //!> contains newest version of the bounding box on request BoundingBox, //!> contains the current live set of atoms for the molecule PresentAtoms, //!> 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 _moid molecule id * \param _molref reference to molecule * \param _subjectKilled ref to function to call on subjectKilled() */ static void initObservedValues( std::vector &_ObservedValues, const moleculeId_t _molid, const molecule * const _molref, 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 molecule index contained in \a ObservedValues. * * \return molecule's index */ moleculeId_t getMolIndex() const; /** Getter to molecule name contained in \a ObservedValues. * * \return molecule's name */ std::string getMolName() const; /** Getter to molecule's bounding box contained in \a ObservedValues. * * \return molecule's bounding box */ molecule::BoundingBoxInfo getBoundingBox() const; /** Getter to contained atoms contained in \a ObservedValues. * * \return molecule's contained atoms */ atoms_t getPresentAtoms() 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: boost::function TesselationHullUpdater; //!> contains current version of the tesselation hull on request Cacheable TesselationHull; //!> contains the set of atoms displayed atoms_t DisplayedAtoms; typedef std::map< atomId_t, GLMoleculeObject_atom* > AtomNodeMap; typedef std::map< BondIds , GLMoleculeObject_bond* > BondNodeMap; AtomNodeMap AtomsinSceneMap; BondNodeMap BondsinSceneMap; atomId_t hoverAtomId; }; std::ostream &operator<<(std::ostream &ost, const GLMoleculeObject_molecule::BondIds &t); #endif /* GLMOLECULEOBJECT_MOLECULE_HPP_ */