OpenWalnut  1.4.0
WFlagForwarder.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 WFLAGFORWARDER_H
00026 #define WFLAGFORWARDER_H
00027 
00028 #include <boost/shared_ptr.hpp>
00029 #include <boost/signals2/signal.hpp>
00030 
00031 #include "WFlag.h"
00032 
00033 
00034 /**
00035  * This class helps especially container module programmers to easily synchronize the value of one flag with several other
00036  * flag. Assume the following scenario: you have a container module with two isosurface modules whose isovalue-properties
00037  * need to be in sync with the isovalue-property your container module provides to the outside world. Here, WFlagForwaderd
00038  * comes into play. Add the first isosurface's isovalue-property to the container modules m_properties list and forward it to
00039  * the other isovalue-property of the second isosurface module. Now they are in sync.
00040  * Be aware, that this is not a property itself!
00041  *
00042  * \note this class is not thread-safe for performance reasons. It is possible to add further flags to the forward-list but
00043  * be yourself aware that you might miss value changes if you add the flag right between two value changes of the source flag.
00044  *
00045  * \note Also be aware that this class only forwards changes in the flag value! Changes of "hidden" in PropertyVariables
00046  * are not propagated.
00047  *
00048  * \note The template parameter is the type encapsulated inside the flag. I.e. for WFlag< bool > use T=bool
00049  *
00050  * \param T the encapsulated type inside the flag. I.e. for WFlag< int32_t > use T=int32_t
00051  */
00052 template < typename T >
00053 class WFlagForwarder // NOLINT
00054 {
00055 public:
00056     /**
00057      * Default constructor.
00058      *
00059      * \param source the property to be used as reference. All other properties will be synced with this one.
00060      */
00061     explicit WFlagForwarder( boost::shared_ptr< WFlag< T > > source );
00062 
00063     /**
00064      * Destructor.
00065      */
00066     virtual ~WFlagForwarder();
00067 
00068     /**
00069      * Forward the source property to the specified one. This ensures that the flag in "to" always has the value of the source flag.
00070      * There is no remove method.
00071      *
00072      * \param to the property to sync with source.
00073      */
00074     void forward( boost::shared_ptr< WFlag< T > > to );
00075 
00076 protected:
00077     /**
00078      * The source property to which all other properties are synced to.
00079      */
00080     boost::shared_ptr< WFlag< T > > m_source;
00081 
00082     /**
00083      * The signal fired by m_source upon value change
00084      */
00085     boost::signals2::connection m_sourceConnection;
00086 
00087     /**
00088      * Signal forwarding the new value.
00089      */
00090     boost::signals2::signal< void( T ) > signal_forward;
00091 
00092     /**
00093      * This is a callback and gets called whenever the source property has changed.
00094      */
00095     void sourceChanged();
00096 
00097 private:
00098     /**
00099      * Disallow copy construction.
00100      *
00101      * \param rhs the other forwarder.
00102      */
00103     WFlagForwarder( const WFlagForwarder& rhs );
00104 
00105     /**
00106      * Disallow copy assignment.
00107      *
00108      * \param rhs the other forwarder.
00109      * \return this.
00110      */
00111     WFlagForwarder& operator=( const WFlagForwarder& rhs );
00112 };
00113 
00114 template < typename T >
00115 WFlagForwarder< T >::WFlagForwarder( boost::shared_ptr< WFlag< T > > source ):
00116     m_source( source )
00117 {
00118     // connect the source's change signal
00119     m_sourceConnection = source->getValueChangeCondition()->subscribeSignal( boost::bind( &WFlagForwarder::sourceChanged, this ) );
00120 }
00121 
00122 template < typename T >
00123 WFlagForwarder< T >::~WFlagForwarder()
00124 {
00125     // cleanup (disconnect all)
00126     m_sourceConnection.disconnect();
00127     signal_forward.disconnect_all_slots();
00128 }
00129 
00130 template < typename T >
00131 void WFlagForwarder< T >::forward( boost::shared_ptr< WFlag< T > >  to )
00132 {
00133     to->set( m_source->get() );
00134 
00135     // NOTE: we do not need to store the signals2::connection here as the destructor disconnects ALL slots
00136     signal_forward.connect( boost::bind( &WFlag< T >::set, to.get(), _1, false ) );
00137 }
00138 
00139 template < typename T >
00140 void WFlagForwarder< T >::sourceChanged()
00141 {
00142     signal_forward( m_source->get() );
00143 }
00144 
00145 #endif  // WFLAGFORWARDER_H
00146