OpenWalnut  1.4.0
WPropertyObserver.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WPROPERTYOBSERVER_H
00026 #define WPROPERTYOBSERVER_H
00027 
00028 #include <map>
00029 #include <string>
00030 #include <set>
00031 
00032 #include <boost/signals2/signal.hpp>
00033 #include <boost/thread.hpp>
00034 
00035 #include "WCondition.h"
00036 #include "WProperties.h"
00037 
00038 
00039 /**
00040  * This class can observe properties inside a property group. The property group to observer can simply be set and replaced comfortably. Whenever
00041  * one of the child properties updates, the observer fires too. If the observed property group itself
00042  * changes (added properties, removed properties and so on), the observer gets updated automatically.
00043  */
00044 class WPropertyObserver: public WCondition
00045 {
00046 public:
00047     /**
00048      * Convenience type for a set of property instances.
00049      */
00050     typedef std::map< std::string, boost::shared_ptr< WPropertyBase > > PropertyNameMap;
00051 
00052     /**
00053      * Convenience type for a shared pointer on property observers.
00054      */
00055     typedef boost::shared_ptr< WPropertyObserver > SPtr;
00056 
00057     /**
00058      * Default constructor.
00059      */
00060     WPropertyObserver();
00061 
00062     /**
00063      * Destructor.
00064      */
00065     virtual ~WPropertyObserver();
00066 
00067     /**
00068      * Defines the property group whose children should be watched. You can define a list of names manually if you are not interested in updates
00069      * of ALL properties.
00070      * \note this also resets the updated flag and the list of the last fired properties.
00071      *
00072      * \param properties the group whose children should be watched.
00073      * \param names list of names. If specified, only these properties are observed.
00074      */
00075     void observe( boost::shared_ptr< WProperties > properties, std::set< std::string > names = std::set< std::string >() );
00076 
00077     /**
00078      * Is true if one observed property fired. This is reset by the \ref handled method.
00079      *
00080      * \return true if one property fired.
00081      */
00082     bool updated() const;
00083 
00084     /**
00085      * Resets the update flag and the list of fired properties.
00086      *
00087      * \return the set of properties fired until the last call of \ref handled.
00088      */
00089     PropertyNameMap handled();
00090 
00091     /**
00092      * Creates a new instance of WPropertyObserver. Useful to save some typing as it creates an shared pointer for you.
00093      *
00094      * \return the new instance.
00095      */
00096     static boost::shared_ptr< WPropertyObserver > create();
00097 
00098 protected:
00099 private:
00100     /**
00101      * Disallow copy construction.
00102      *
00103      * \param rhs the other threaded runner.
00104      */
00105     WPropertyObserver( const WPropertyObserver& rhs );
00106 
00107     /**
00108      * Disallow copy assignment.
00109      *
00110      * \param rhs the other threaded runner.
00111      * \return this.
00112      */
00113     WPropertyObserver& operator=( const WPropertyObserver& rhs );
00114 
00115     /**
00116      * Cancels all current subscriptions and cleans m_subscriptions.
00117      */
00118     void cancelSubscriptions();
00119 
00120     /**
00121      * Subscribes each property update condition which matches an entry in m_propNames.
00122      */
00123     void updateSubscriptions();
00124 
00125     /**
00126      * Gets called by the update callback of the property. The property given as parameter was the property that fired.
00127      *
00128      * \param property the property that fired.
00129      */
00130     void propertyUpdated( boost::shared_ptr< WPropertyBase > property );
00131 
00132     /**
00133      * Type for shared container with signal connections.
00134      */
00135     typedef WSharedAssociativeContainer< std::map< boost::shared_ptr< WPropertyBase >, boost::signals2::connection > > Subscriptions;
00136 
00137     /**
00138      * The subscription to each property which was subscribed.
00139      */
00140     Subscriptions m_subscriptions;
00141 
00142     /**
00143      * True if a property fired.
00144      */
00145     bool m_updated;
00146 
00147     /**
00148      * The properties handled by this observer.
00149      */
00150     boost::shared_ptr< WProperties > m_properties;
00151 
00152     /**
00153      * The names of the properties which shall be observed if they are or become available.
00154      */
00155     std::set< std::string > m_propNames;
00156 
00157     /**
00158      * The connection used to get notified about m_properties updates.
00159      */
00160     boost::signals2::scoped_connection m_updateConditionConnection;
00161 
00162     /**
00163      * Type of shared container for the list of last updated properties.
00164      */
00165     typedef WSharedAssociativeContainer< PropertyNameMap > LastUpdated;
00166 
00167     /**
00168      * The queue of properties that fired before handled() is called.
00169      */
00170     LastUpdated m_lastUpdated;
00171 };
00172 
00173 #endif  // WPROPERTYOBSERVER_H
00174