Commit b5ab6de0 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum

[ADD] - new class to utilize some kind of observable flags

parent a1dadd49
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WFLAG_H
#define WFLAG_H
#include "WCondition.h"
/**
* Class to have a simple notification/condition system for simple flags. This is somewhat similar to the observer design pattern.
* The type of the flag is specified by the template parameter. Per default, it is of type bool.
*/
template < typename T >
class WFlag
{
public:
/**
* Constructor. Uses a given condition to realize the wait/notify functionality.
*
* \param condition the condition to use. NOTE: can also be a WConditionOneShot.
* \param initial the initial value of this flag
*/
WFlag( WCondition* condition, T initial );
/**
* Destructor. It deletes the instance of WCondition specified on construction.
*/
virtual ~WFlag();
/**
* Operator returns value of the flag.
*
* \return the value.
*/
virtual const T get() const;
/**
* Operator returns value of the flag.
*
* \return the value.
*/
virtual const T operator()() const;
/**
* Wait for the flag to change its value.
*/
virtual void wait() const;
/**
* Sets the new value for this flag. Also notifies waiting threads.
*
* \param value the new value
*/
virtual void set( T value );
/**
* Sets the new value for this flag. Also notifies waiting threads.
*
* \param value the new value
*/
virtual void operator()( T value );
protected:
/**
* The condition to be used for waiting/notifying. Please note, that it gets deleted during destruction.
*/
WCondition* m_condition;
/**
* The flag value.
*/
T m_flag;
private:
};
template < typename T >
WFlag< T >::WFlag( WCondition* condition, T initial )
{
m_condition = condition;
m_flag = initial;
}
template < typename T >
WFlag< T >::~WFlag()
{
delete m_condition;
}
template < typename T >
const T WFlag< T >::operator()() const
{
return get();
}
template < typename T >
const T WFlag< T >::get() const
{
return m_flag;
}
template < typename T >
void WFlag< T >::wait() const
{
m_condition->wait();
}
template < typename T >
void WFlag< T >::operator()( T value )
{
set( value );
}
template < typename T >
void WFlag< T >::set( T value )
{
if ( m_flag == value )
return;
m_flag = value;
m_condition->notify();
}
#endif // WFLAG_H
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WFLAG_TEST_H
#define WFLAG_TEST_H
#include <iostream>
#include <boost/thread.hpp>
#include <cxxtest/TestSuite.h>
#include "../WFlag.hpp"
#include "../WConditionOneShot.h"
/**
* Helper class.
*/
class Callable
{
public:
WFlag<bool>* flag;
bool finished;
Callable()
{
finished = false;
flag = new WFlag< bool >( new WConditionOneShot(), false );
}
void threadMain()
{
flag->wait();
finished = true;
};
};
/**
* Test WFlag
*/
class WFlagTest : public CxxTest::TestSuite
{
public:
/**
* An instantiation should never throw an exception, as well as tear down.
*/
void testInstantiation( void )
{
WFlag< bool >* flag;
TS_ASSERT_THROWS_NOTHING( flag = new WFlag< bool >( new WConditionOneShot(), false ) );
TS_ASSERT_THROWS_NOTHING( delete flag );
}
/**
* Test whether notification is working.
*/
void testWaitNotify()
{
Callable t;
// the flag should be false now
// NOTE: the syntax to get the value of the flag looks ugly here, but you normally do not use pointers
TS_ASSERT( !( *t.flag )() );
// start a thread
boost::thread thread = boost::thread( boost::bind( &Callable::threadMain, &t ) );
// set value equal to the one already set
( *t.flag )( false );
// this should NOT notify the thread since the set value is not different to the initial one
TS_ASSERT( !t.finished );
// notify
( *t.flag )( true );
thread.join();
TS_ASSERT( ( *t.flag )() );
}
};
#endif // WFLAG_TEST_H
......@@ -23,13 +23,13 @@
//---------------------------------------------------------------------------
#include "../common/WConditionOneShot.h"
#include "../common/WFlag.hpp"
#include "WGUI.h"
WGUI::WGUI( int argc, char** argv ): boost::enable_shared_from_this< WGUI >()
WGUI::WGUI( int argc, char** argv ): boost::enable_shared_from_this< WGUI >(),
m_isInitialized( new WConditionOneShot(), false )
{
m_isInitialized = false;
this->argc = argc;
this->argv = argv;
}
......@@ -38,16 +38,11 @@ WGUI::~WGUI()
{
}
bool WGUI::isInitialized() const
const WFlag< bool >& WGUI::isInitialized() const
{
return m_isInitialized;
}
const WCondition& WGUI::waitInitialized() const
{
return m_isInitializedCondition;
}
void WGUI::slotAddDatasetToBrowser( boost::shared_ptr< WModule > module )
{
addDatasetToBrowser( module, 0 );
......
......@@ -31,8 +31,7 @@
#include <boost/shared_ptr.hpp>
#include "../common/WThreadedRunner.h"
#include "../common/WCondition.h"
#include "../common/WConditionOneShot.h"
#include "../common/WFlag.hpp"
#include "../kernel/WModule.h"
#include "qt4/signalslib.hpp"
......@@ -68,19 +67,12 @@ public:
*/
virtual ~WGUI();
/**
* Determines whether the GUI is properly initialized.
*
* \return true if initialized.
*/
virtual bool isInitialized() const;
/**
* Gives other threads the possibility to wait for this condition to come true.
* Returns the init flag..
*
* \return Reference to the condition.
* \return Reference to the flag.
*/
virtual const WCondition& waitInitialized() const;
virtual const WFlag< bool >& isInitialized() const;
/**
* Runs the GUI. All initialization should be done here.
......@@ -121,12 +113,7 @@ protected:
/**
* Flag determining whether the GUI is properly initialized.
*/
bool m_isInitialized;
/**
* Condition should be fired when "isInitialized" got true.
*/
WConditionOneShot m_isInitializedCondition;
WFlag< bool > m_isInitialized;
/**
* Number of command line arguments given.
......
......@@ -69,8 +69,7 @@ int WQt4Gui::run()
m_kernel->getRootContainer()->addDefaultNotifier( READY, f );
// now we are initialized
m_isInitialized = true;
m_isInitializedCondition.notify();
m_isInitialized( true );
// run
// NOTE: kernel shutdown is implemented in WMainWindow
......
......@@ -127,7 +127,7 @@ void WKernel::threadMain()
WLogger::getLogger()->addLogMessage( "Starting Kernel", "Kernel", LL_DEBUG );
// wait for GUI to be initialized properly
m_gui->waitInitialized().wait();
m_gui->isInitialized().wait();
// default modules
m_moduleContainer->add( m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "Navigation Slice Module" ) ) , true );
......
......@@ -142,7 +142,7 @@ void WMCoordinateSystem::updateGeometry()
boost::shared_lock< boost::shared_mutex > slock;
slock = boost::shared_lock< boost::shared_mutex >( m_updateLock );
// *******************************************************************************************************
if ( !m_properties->getValue< bool > ( "textureChanged" ) || !WKernel::getRunningKernel()->getGui()->isInitialized() )
if ( !m_properties->getValue< bool > ( "textureChanged" ) || !WKernel::getRunningKernel()->getGui()->isInitialized()() )
{
return;
}
......
......@@ -294,7 +294,7 @@ void WMNavSlices::updateTextures()
boost::shared_lock<boost::shared_mutex> slock;
slock = boost::shared_lock<boost::shared_mutex>( m_updateLock );
if ( m_properties->getValue< bool >( "textureChanged" ) && WKernel::getRunningKernel()->getGui()->isInitialized() )
if ( m_properties->getValue< bool >( "textureChanged" ) && WKernel::getRunningKernel()->getGui()->isInitialized()() )
{
m_properties->setValue( "textureChanged", false );
std::vector< boost::shared_ptr< WModule > > datasetList = WKernel::getRunningKernel()->getGui()->getDataSetList( 0 );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment