Commit 68502844 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[ADD] - added exceptions

[CHANGE] - extended prototype/factory classes
[CHANGE] - container extened
parent fd745683
......@@ -34,6 +34,7 @@
#include "WModuleContainer.h"
#include "exceptions/WModuleSignalUnknown.h"
#include "exceptions/WModuleConnectorInitFailed.h"
#include "exceptions/WModuleUninitialized.h"
#include "WModule.h"
......@@ -130,6 +131,11 @@ boost::shared_ptr< WModuleContainer > WModule::getAssociatedContainer() const
return m_container;
}
void WModule::setAssociatedContainer( boost::shared_ptr< WModuleContainer > container )
{
m_container = container;
}
const std::set<boost::shared_ptr< WModuleInputConnector > >& WModule::getInputConnectors() const
{
return m_inputConnectors;
......@@ -166,7 +172,12 @@ bool WModule::isInitialized() const
bool WModule::isAssociated() const
{
// true if the pointer is set
return m_container;
return ( m_container == boost::shared_ptr< WModuleContainer >() );
}
bool WModule::isUseable() const
{
return isInitialized() && isAssociated();
}
void WModule::notifyConnectionEstablished( boost::shared_ptr< WModuleConnector > /*here*/,
......
......@@ -56,6 +56,7 @@ class WModule: public WThreadedRunner,
friend class WModuleConnector; // requires access to notify members
friend class WModuleFactory; // for proper creation of module instaces, the factory needs access to protected functions.
// (especially initialize)
friend class WModuleContainer; // for proper management of m_container WModuleContainer needs access.
public:
......@@ -105,21 +106,28 @@ public:
*
* \return true if properly initialized.
*/
bool isInitialized() const;
bool isInitialized() const;
/**
* Checks whether the module instance is ready to be used. This is the case if isInitialized && isAssociated.
*
* \return isInitialized && isAssociated
*/
bool isUseable() const;
/**
* Checks whether this module is associated with an container.
*
* \return true if associated.
*/
bool isAssociated() const;
bool isAssociated() const;
/**
* The container this module is associated with.
*
* \return the container.
*/
boost::shared_ptr< WModuleContainer > getAssociatedContainer() const;
boost::shared_ptr< WModuleContainer > getAssociatedContainer() const;
/**
* Due to the prototype design pattern used to build modules, this method returns a new instance of this method. NOTE: it
......@@ -142,6 +150,13 @@ protected:
*/
virtual void threadMain() = 0;
/**
* Sets the container this module is associated with.
*
* \param container the container to associate with.
*/
void setAssociatedContainer( boost::shared_ptr< WModuleContainer > container );
// **************************************************************************************************************************
//
// Connector Management
......
......@@ -27,6 +27,7 @@
#include "WModule.h"
#include "exceptions/WModuleUninitialized.h"
#include "../common/WLogger.h"
#include "WModuleContainer.h"
......@@ -66,6 +67,11 @@ void WModuleContainer::add( boost::shared_ptr< WModule > module )
boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>( m_moduleSetLock );
m_modules.insert( module );
lock.unlock();
module->setAssociatedContainer( shared_from_this() );
// now module->isUsable() is true
// -> so run it
module->run();
}
void WModuleContainer::remove( boost::shared_ptr< WModule > module )
......@@ -75,10 +81,15 @@ void WModuleContainer::remove( boost::shared_ptr< WModule > module )
return;
}
// stop module
WLogger::getLogger()->addLogMessage( "Waiting for module " + module->getName() + " to finish." , "ModuleContainer", LL_DEBUG );
module->wait( true );
// get write lock
boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>( m_moduleSetLock );
m_modules.erase( module );
lock.unlock();
module->setAssociatedContainer( boost::shared_ptr< WModuleContainer >() );
// TODO(ebaum): flat or deep removal? What to do with associated modules?
}
......
......@@ -54,8 +54,8 @@ public:
virtual ~WModuleContainer();
/**
* Add a module to this container. Please note, that a module can be added only once. If it already is associated with this
* container nothing happens.
* Add a module to this container and start it. Please note, that a module can be added only once. If it already is
* associated with this container nothing happens.
*
* \param module the module to add.
* \throw WModuleUninitialized thrown whenever someone wants to add a module not yet initialized.
......
......@@ -22,6 +22,21 @@
//
//---------------------------------------------------------------------------
#include <set>
#include "../common/WLogger.h"
#include "../modules/data/WMData.hpp"
#include "../modules/navSlices/WMNavSlices.h"
#include "../modules/coordinateSystem/WMCoordinateSystem.h"
#include "../modules/fiberDisplay/WMFiberDisplay.h"
#include "../modules/fiberCulling/WMFiberCulling.h"
#include "../modules/fiberClustering/WMFiberClustering.h"
#include "../modules/marchingCubes/WMMarchingCubes.h"
#include "../modules/eegTest/WMEEGTest.h"
#include "exceptions/WPrototypeUnknown.h"
#include "WModuleFactory.h"
// factory instance as singleton
......@@ -37,8 +52,52 @@ WModuleFactory::~WModuleFactory()
// cleanup
}
void WModuleFactory::load()
{
// load modules
WLogger::getLogger()->addLogMessage( "Loading Modules", "ModuleFactory", LL_INFO );
// operation must be exclusive
boost::unique_lock< boost::shared_mutex > lock = boost::unique_lock< boost::shared_mutex >( m_prototypesLock );
// currently the prototypes are added by hand. This will be done automatically later.
m_prototypes.insert( boost::shared_ptr< WModule >( new WMNavSlices() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMFiberDisplay() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMFiberCulling() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMFiberClustering() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMCoordinateSystem() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMEEGTest() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMMarchingCubes() ) );
lock.unlock();
// for this a read lock is sufficient
boost::shared_lock< boost::shared_mutex > slock = boost::shared_lock< boost::shared_mutex >( m_prototypesLock );
// initialize every module in the set
for( std::set< boost::shared_ptr< WModule > >::iterator list_iter = m_prototypes.begin(); list_iter != m_prototypes.end();
++list_iter )
{
WLogger::getLogger()->addLogMessage( "Loading module: " + ( *list_iter )->getName(), "ModuleFactory", LL_DEBUG );
( *list_iter )->initialize();
}
slock.unlock();
}
boost::shared_ptr< WModule > WModuleFactory::create( boost::shared_ptr< WModule > prototype )
{
// for this a read lock is sufficient
boost::shared_lock< boost::shared_mutex > slock = boost::shared_lock< boost::shared_mutex >( m_prototypesLock );
// ensure this one is a prototype and nothing else
if ( m_prototypes.count( prototype ) == 0 )
{
throw WPrototypeUnknown( "Could not clone module " + prototype->getName() + " since it is no prototype." );
}
slock.unlock();
// call prototypes factory function
boost::shared_ptr< WModule > clone = boost::shared_ptr< WModule >( prototype->factory() );
clone->initialize();
......
......@@ -25,7 +25,10 @@
#ifndef WMODULEFACTORY_H
#define WMODULEFACTORY_H
#include <set>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include "WModule.h"
......@@ -46,6 +49,11 @@ public:
*/
virtual ~WModuleFactory();
/**
* Loads the modules and creates prototypes.
*/
void load();
/**
* Create a new and initialized module using the specified prototype.
*
......@@ -64,6 +72,16 @@ public:
protected:
/**
* The module prototypes available.
*/
std::set< boost::shared_ptr< WModule > > m_prototypes;
/**
* The lock for the prototypes set.
*/
boost::shared_mutex m_prototypesLock;
private:
/**
* Singleton instance of WModuleFactory.
......
//---------------------------------------------------------------------------
//
// 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/>.
//
//---------------------------------------------------------------------------
#include <string>
#include "WPrototypeUnknown.h"
WPrototypeUnknown::WPrototypeUnknown( const std::string& msg ): WKernelException( msg )
{
// initialize members
}
WPrototypeUnknown::~WPrototypeUnknown() throw()
{
// cleanup
}
//---------------------------------------------------------------------------
//
// 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 WPROTOTYPEUNKNOWN_H
#define WPROTOTYPEUNKNOWN_H
#include <string>
#include "WKernelException.h"
/**
* Thrown whenever an unknown prototype is specified.
* \ingroup kernel
*/
class WPrototypeUnknown: public WKernelException
{
public:
/**
* Default constructor.
* \param msg the exception message.
*/
explicit WPrototypeUnknown( const std::string& msg = "Prototype unknown" );
/**
* Destructor.
*/
virtual ~WPrototypeUnknown() throw();
protected:
private:
};
#endif // WPROTOTYPEUNKNOWN_H
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