OpenWalnut 1.3.1
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      * Default constructor.
00054      */
00055     WPropertyObserver();
00056 
00057     /**
00058      * Destructor.
00059      */
00060     virtual ~WPropertyObserver();
00061 
00062     /**
00063      * Defines the property group whose children should be watched. You can define a list of names manually if you are not interested in updates
00064      * of ALL properties.
00065      * \note this also resets the updated flag and the list of the last fired properties.
00066      *
00067      * \param properties the group whose children should be watched.
00068      * \param names list of names. If specified, only these properties are observed.
00069      */
00070     void observe( boost::shared_ptr< WProperties > properties, std::set< std::string > names = std::set< std::string >() );
00071 
00072     /**
00073      * Is true if one observed property fired. This is reset by the \ref handled method.
00074      *
00075      * \return true if one property fired.
00076      */
00077     bool updated() const;
00078 
00079     /**
00080      * Resets the update flag and the list of fired properties.
00081      *
00082      * \return the set of properties fired until the last call of \ref handled.
00083      */
00084     PropertyNameMap handled();
00085 
00086     /**
00087      * Creates a new instance of WPropertyObserver. Useful to save some typing as it creates an shared pointer for you.
00088      *
00089      * \return the new instance.
00090      */
00091     static boost::shared_ptr< WPropertyObserver > create();
00092 
00093 protected:
00094 private:
00095     /**
00096      * Disallow copy construction.
00097      *
00098      * \param rhs the other threaded runner.
00099      */
00100     WPropertyObserver( const WPropertyObserver& rhs );
00101 
00102     /**
00103      * Disallow copy assignment.
00104      *
00105      * \param rhs the other threaded runner.
00106      * \return this.
00107      */
00108     WPropertyObserver& operator=( const WPropertyObserver& rhs );
00109 
00110     /**
00111      * Cancels all current subscriptions and cleans m_subscriptions.
00112      */
00113     void cancelSubscriptions();
00114 
00115     /**
00116      * Subscribes each property update condition which matches an entry in m_propNames.
00117      */
00118     void updateSubscriptions();
00119 
00120     /**
00121      * Gets called by the update callback of the property. The property given as parameter was the property that fired.
00122      *
00123      * \param property the property that fired.
00124      */
00125     void propertyUpdated( boost::shared_ptr< WPropertyBase > property );
00126 
00127     /**
00128      * Type for shared container with signal connections.
00129      */
00130     typedef WSharedAssociativeContainer< std::map< boost::shared_ptr< WPropertyBase >, boost::signals2::connection > > Subscriptions;
00131 
00132     /**
00133      * The subscription to each property which was subscribed.
00134      */
00135     Subscriptions m_subscriptions;
00136 
00137     /**
00138      * True if a property fired.
00139      */
00140     bool m_updated;
00141 
00142     /**
00143      * The properties handled by this observer.
00144      */
00145     boost::shared_ptr< WProperties > m_properties;
00146 
00147     /**
00148      * The names of the properties which shall be observed if they are or become available.
00149      */
00150     std::set< std::string > m_propNames;
00151 
00152     /**
00153      * The connection used to get notified about m_properties updates.
00154      */
00155     boost::signals2::scoped_connection m_updateConditionConnection;
00156 
00157     /**
00158      * Type of shared container for the list of last updated properties.
00159      */
00160     typedef WSharedAssociativeContainer< PropertyNameMap > LastUpdated;
00161 
00162     /**
00163      * The queue of properties that fired before handled() is called.
00164      */
00165     LastUpdated m_lastUpdated;
00166 };
00167 
00168 #endif  // WPROPERTYOBSERVER_H
00169