Commit 0a8b5fbe authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[CHANGE] - switched to signals2

parent 11781091
......@@ -24,6 +24,9 @@
#include <iostream>
#include <boost/signals2/signal.hpp>
#include <boost/function.hpp>
#include "common/WException.h"
#include "common/WSegmentationFault.h"
#include "common/WLogger.h"
......@@ -32,6 +35,7 @@
#include "gui/qt4/WQt4Gui.h"
#include "kernel/WKernel.h"
#include "kernel/WModuleSignals.h"
/**
* The main routine starting up the whole application.
......@@ -64,7 +68,11 @@ int main( int argc, char* argv[] )
// init the kernel
WKernel kernel = WKernel( argc, argv, gui );
kernel.getRootContainer()->getModuleReadySignal()->connect( boost::bind( &WGUI::slotAddDatasetToBrowser, gui, _1 ) );
// bind the GUI's slot with the ready signal
t_ModuleGenericSignalHandlerType f = boost::bind( &WGUI::slotAddDatasetToBrowser, gui, _1 );
kernel.getRootContainer()->addDefaultNotifier( READY, f );
return kernel.run();
}
......@@ -33,6 +33,7 @@
#include "WModuleConnectorSignals.h"
#include "WModuleContainer.h"
#include "exceptions/WModuleSignalUnknown.h"
#include "exceptions/WModuleSignalSubscriptionFailed.h"
#include "exceptions/WModuleConnectorInitFailed.h"
#include "exceptions/WModuleUninitialized.h"
......@@ -145,9 +146,32 @@ const std::set<boost::shared_ptr< WModuleOutputConnector > >& WModule::getOutput
return m_outputConnectors;
}
boost::signal1< void, boost::shared_ptr< WModule > >* WModule::getReadySignal()
boost::signals2::connection WModule::subscribeSignal( MODULE_SIGNAL signal, t_ModuleGenericSignalHandlerType notifier )
{
return &m_readySignal;
switch (signal)
{
case READY:
return signal_ready.connect( notifier );
default:
std::ostringstream s;
s << "Could not subscribe to unknown signal.";
throw WModuleSignalSubscriptionFailed( s.str() );
break;
}
}
boost::signals2::connection WModule::subscribeSignal( MODULE_SIGNAL signal, t_ModuleErrorSignalHandlerType notifier )
{
switch (signal)
{
case ERROR:
signal_error.connect( notifier );
default:
std::ostringstream s;
s << "Could not subscribe to unknown signal.";
throw WModuleSignalSubscriptionFailed( s.str() );
break;
}
}
const t_GenericSignalHandlerType WModule::getSignalHandler( MODULE_CONNECTOR_SIGNAL signal )
......@@ -209,7 +233,7 @@ boost::shared_ptr< WProperties > WModule::getProperties() const
void WModule::ready()
{
m_readySignal( shared_from_this() );
signal_ready( shared_from_this() );
}
void WModule::connectToGui()
......
......@@ -27,12 +27,16 @@
#include <set>
#include <string>
#include <typeinfo>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/signals2/signal.hpp>
#include <boost/function.hpp>
#include "../common/WThreadedRunner.h"
#include "WModuleConnectorSignals.h"
#include "WModuleSignals.h"
#include "../dataHandler/WDataSet.h"
#include "../dataHandler/WDataSetSingle.h"
......@@ -143,12 +147,18 @@ public:
*/
virtual void connectToGui();
/**
* Signal fired whenever a module main thread is ready.
/**
* Connects a specified notify function with a signal this module instance is offering.
*
* \return the signal.
* \exception WModuleSignalSubscriptionFailed thrown if the signal can't be connected.
*
* \param signal the signal to connect to.
* \param notifier the notifier function to bind.
*
* \return connection descriptor.
*/
virtual boost::signal1< void, boost::shared_ptr< WModule > >* getReadySignal();
virtual boost::signals2::connection subscribeSignal( MODULE_SIGNAL signal, t_ModuleGenericSignalHandlerType notifier );
virtual boost::signals2::connection subscribeSignal( MODULE_SIGNAL signal, t_ModuleErrorSignalHandlerType notifier );
protected:
......@@ -314,7 +324,12 @@ private:
/**
* Signal fired whenever a module main thread is ready.
*/
boost::signal1< void, boost::shared_ptr< WModule> > m_readySignal;
t_ModuleGenericSignalType signal_ready;
/**
* Signal fired whenever a module main thread throws an exception/error.
*/
t_ModuleErrorSignalType signal_error;
};
#endif // WMODULE_H
......
......@@ -22,13 +22,16 @@
//
//---------------------------------------------------------------------------
#include <list>
#include <set>
#include <string>
#include <sstream>
#include "WModule.h"
#include "exceptions/WModuleUninitialized.h"
#include "exceptions/WModuleSignalSubscriptionFailed.h"
#include "../common/WLogger.h"
#include "WKernel.h"
#include "WModuleContainer.h"
......@@ -80,8 +83,22 @@ void WModuleContainer::add( boost::shared_ptr< WModule > module )
// now module->isUsable() is true
// -> so run it
// connect default ready/error notifiers
boost::shared_lock<boost::shared_mutex> slock = boost::shared_lock<boost::shared_mutex>( m_readyNotifiersLock );
for ( std::list< t_ModuleGenericSignalHandlerType >::iterator iter = m_readyNotifiers.begin(); iter != m_readyNotifiers.end(); ++iter)
{
module->subscribeSignal( READY, ( *iter ) );
}
slock.unlock();
slock = boost::shared_lock<boost::shared_mutex>( m_errorNotifiersLock );
for ( std::list< t_ModuleErrorSignalHandlerType >::iterator iter = m_errorNotifiers.begin(); iter != m_errorNotifiers.end(); ++iter)
{
module->subscribeSignal( ERROR, ( *iter ) );
}
slock.unlock();
// TODO(ebaum,schurade): this should be removes some days
module->getReadySignal()->connect( boost::bind( &WModuleContainer::slotModuleReady, this, _1 ) );
module->connectToGui();
module->run();
}
......@@ -135,13 +152,39 @@ const std::string WModuleContainer::getDescription() const
return m_description;
}
boost::signal1< void, boost::shared_ptr< WModule > >* WModuleContainer::getModuleReadySignal()
void WModuleContainer::addDefaultNotifier( MODULE_SIGNAL signal, t_ModuleGenericSignalHandlerType notifier )
{
return &m_moduleReadySignal;
boost::unique_lock<boost::shared_mutex> lock;
switch (signal)
{
case READY:
lock = boost::unique_lock<boost::shared_mutex>( m_readyNotifiersLock );
m_readyNotifiers.push_back( notifier );
lock.unlock();
break;
default:
std::ostringstream s;
s << "Could not subscribe to unknown signal.";
throw WModuleSignalSubscriptionFailed( s.str() );
break;
}
}
void WModuleContainer::slotModuleReady( boost::shared_ptr< WModule > module )
void WModuleContainer::addDefaultNotifier( MODULE_SIGNAL signal, t_ModuleErrorSignalHandlerType notifier )
{
m_moduleReadySignal( module );
boost::unique_lock<boost::shared_mutex> lock;
switch (signal)
{
case ERROR:
lock = boost::unique_lock<boost::shared_mutex>( m_errorNotifiersLock );
m_errorNotifiers.push_back( notifier );
lock.unlock();
break;
default:
std::ostringstream s;
s << "Could not subscribe to unknown signal.";
throw WModuleSignalSubscriptionFailed( s.str() );
break;
}
}
......@@ -25,6 +25,7 @@
#ifndef WMODULECONTAINER_H
#define WMODULECONTAINER_H
#include <list>
#include <set>
#include <string>
......@@ -91,11 +92,13 @@ public:
virtual const std::string getDescription() const;
/**
* Signal fired whenever a module main thread is ready.
* Add a specified notifier to the list of default notifiers which get connected to each added module.
*
* \return the signal.
* \param signal the signal the notifier should get connected to
* \param notifier the notifier function
*/
virtual boost::signal1< void, boost::shared_ptr< WModule > >* getModuleReadySignal();
virtual void addDefaultNotifier( MODULE_SIGNAL signal, t_ModuleErrorSignalHandlerType notifier );
virtual void addDefaultNotifier( MODULE_SIGNAL signal, t_ModuleGenericSignalHandlerType notifier );
protected:
......@@ -120,16 +123,24 @@ protected:
std::string m_description;
/**
* Signal fired whenever a module main thread is ready.
* Lock for error notifiers set.
*/
boost::signal1< void, boost::shared_ptr< WModule> > m_moduleReadySignal;
boost::shared_mutex m_errorNotifiersLock;
/**
* Gets called whenever a module has finished.
*
* \param module the module which is now ready.
* The error notifiers connected to added modules by default.
*/
std::list< t_ModuleErrorSignalHandlerType > m_errorNotifiers;
/**
* Lock for ready notifiers set.
*/
boost::shared_mutex m_readyNotifiersLock;
/**
* The ready notifiers connected to added modules by default.
*/
virtual void slotModuleReady( boost::shared_ptr< WModule > module );
std::list< t_ModuleGenericSignalHandlerType > m_readyNotifiers;
private:
};
......
......@@ -24,6 +24,8 @@
#include <set>
#include <string>
#include <iostream>
#include <typeinfo>
#include "../common/WLogger.h"
......
......@@ -91,6 +91,17 @@ public:
*/
const boost::shared_ptr< WModule > getPrototypeByInstance( boost::shared_ptr< WModule > instance );
/**
* Checks whether the first instance can be casted to the second one.
*
* \param module1 the module to check.
* \param module2 the module to check against.
*
* \return
*/
template <typename T>
static bool isA( boost::shared_ptr< WModule > module );
protected:
/**
......@@ -110,5 +121,13 @@ private:
static boost::shared_ptr< WModuleFactory > m_instance;
};
template <typename T>
bool WModuleFactory::isA( boost::shared_ptr< WModule > module )
{
// NOTE: this is RTTI. Everybody says: do not use it but nearly nobody says in which cases and why. So we ignore them and use
// it.
return ( dynamic_cast< T* >( module.get() ) ); // NOLINT
}
#endif // WMODULEFACTORY_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 WMODULESIGNALS_H
#define WMODULESIGNALS_H
#include <boost/signals2/signal.hpp>
#include <boost/function.hpp>
class WModule;
class WException;
/**
* Enum of all possible signals WModule instances can emit.
*/
typedef enum
{
READY, // module ready
ERROR // error during execution
}
MODULE_SIGNAL;
// **************************************************************************************************************************
// Types
// **************************************************************************************************************************
/**
* Signal for generic events like "READY".
*
* \param module The module emitting the signal.
*
*/
typedef boost::function< void ( boost::shared_ptr< WModule > ) > t_ModuleGenericSignalHandlerType;
/**
* Generic signal type used in the most signals involving just the emitting signal.
*
* \param module The module emitting the signal.
*/
typedef boost::signals2::signal< void ( boost::shared_ptr< WModule > ) > t_ModuleGenericSignalType;
/**
* Signal for error events like "ERROR".
*
* \param module The module emitting the signal.
*
*/
typedef boost::function< void ( boost::shared_ptr< WModule >, WException& ) > t_ModuleErrorSignalHandlerType;
/**
* Signal type used in the most signals involving exceptions.
*
* \param module The module emitting the signal.
*/
typedef boost::signals2::signal< void ( boost::shared_ptr< WModule >, WException& ) > t_ModuleErrorSignalType;
#endif // WMODULESIGNALS_H
......@@ -44,7 +44,7 @@ WMCoordinateSystem::~WMCoordinateSystem()
boost::shared_ptr< WModule > WMCoordinateSystem::factory() const
{
return boost::shared_ptr< WModule >( new WMCoordinateSystem() );
return boost::shared_ptr< WMCoordinateSystem >( new WMCoordinateSystem() );
}
void WMCoordinateSystem::threadMain()
......
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