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

[CHANGE] - extended factory and prototype handling

[ADD] - added "stop" functionality to container
parent fe1bad05
......@@ -31,7 +31,10 @@
#include "WModuleContainer.h"
WModuleContainer::WModuleContainer(): boost::enable_shared_from_this< WModuleContainer >()
WModuleContainer::WModuleContainer( std::string name, std::string description ):
boost::enable_shared_from_this< WModuleContainer >(),
m_name( name ),
m_description( description )
{
// initialize members
}
......@@ -43,10 +46,12 @@ WModuleContainer::~WModuleContainer()
void WModuleContainer::add( boost::shared_ptr< WModule > module )
{
WLogger::getLogger()->addLogMessage( "Adding module " + module->getName() + " to container." , "ModuleContainer (" + m_name + ")", LL_DEBUG );
if ( !module->isInitialized() )
{
std::ostringstream s;
s << "Could not add module " << module->getName() << " to container. Reason: module not initialized.";
s << "Could not add module " << module->getName() << " to container " + m_name + ". Reason: module not initialized.";
throw WModuleUninitialized( s.str() );
}
......@@ -68,21 +73,26 @@ void WModuleContainer::add( boost::shared_ptr< WModule > module )
m_modules.insert( module );
lock.unlock();
module->setAssociatedContainer( shared_from_this() );
WLogger::getLogger()->addLogMessage( "Associated module " + module->getName() + " with container." , "ModuleContainer (" + m_name + ")", LL_DEBUG );
// now module->isUsable() is true
// -> so run it
// TODO(ebaum,schurade): this should be removes some days
module->connectToGui();
module->run();
}
void WModuleContainer::remove( boost::shared_ptr< WModule > module )
{
WLogger::getLogger()->addLogMessage( "Removing module " + module->getName() + " from container." , "ModuleContainer (" + m_name + ")", LL_DEBUG );
if ( module->getAssociatedContainer() != shared_from_this() )
{
return;
}
// stop module
WLogger::getLogger()->addLogMessage( "Waiting for module " + module->getName() + " to finish." , "ModuleContainer", LL_DEBUG );
WLogger::getLogger()->addLogMessage( "Waiting for module " + module->getName() + " to finish." , "ModuleContainer (" + m_name + ")", LL_DEBUG );
module->wait( true );
// get write lock
......@@ -94,3 +104,27 @@ void WModuleContainer::remove( boost::shared_ptr< WModule > module )
// TODO(ebaum): flat or deep removal? What to do with associated modules?
}
void WModuleContainer::stop()
{
WLogger::getLogger()->addLogMessage( "Stopping modules." , "ModuleContainer (" + m_name + ")", LL_DEBUG );
// read lock
boost::shared_lock<boost::shared_mutex> slock = boost::shared_lock<boost::shared_mutex>( m_moduleSetLock );
for( std::set< boost::shared_ptr< WModule > >::iterator listIter = m_modules.begin(); listIter != m_modules.end(); ++listIter )
{
WLogger::getLogger()->addLogMessage( "Waiting for module " + ( *listIter )->getName() + " to finish." , "ModuleContainer (" + m_name + ")", LL_DEBUG );
( *listIter )->wait( true );
}
slock.unlock();
}
const std::string WModuleContainer::getName() const
{
return m_name;
}
const std::string WModuleContainer::getDescription() const
{
return m_description;
}
......@@ -44,9 +44,12 @@ class WModuleContainer: public boost::enable_shared_from_this< WModuleContainer
public:
/**
* Default constructor.
* Constructor. Initializes container.
*
* \param name name of the container
* \param description short description.
*/
WModuleContainer();
WModuleContainer( std::string name, std::string description );
/**
* Destructor.
......@@ -69,6 +72,24 @@ public:
*/
virtual void remove( boost::shared_ptr< WModule > module );
/**
* Stops all modules inside this container. Note that this function could take some time, since it waits until the last module
* has quit.
*/
virtual void stop();
/**
* Gives back the name of this module.
* \return the module's name.
*/
virtual const std::string getName() const;
/**
* Gives back a description of this module.
* \return description to module.
*/
virtual const std::string getDescription() const;
protected:
/**
......@@ -81,6 +102,16 @@ protected:
*/
std::set< boost::shared_ptr< WModule > > m_modules;
/**
* Name of the module.
*/
std::string m_name;
/**
* Description of the module.
*/
std::string m_description;
private:
};
......
......@@ -36,6 +36,7 @@
#include "../modules/eegTest/WMEEGTest.h"
#include "exceptions/WPrototypeUnknown.h"
#include "exceptions/WPrototypeNotUnique.h"
#include "WModuleFactory.h"
......@@ -56,9 +57,12 @@ void WModuleFactory::load()
{
// load modules
WLogger::getLogger()->addLogMessage( "Loading Modules", "ModuleFactory", LL_INFO );
std::cout << "sdasdshallo" << std::endl;
// operation must be exclusive
std::cout << "sdasdshallo" << std::endl;
boost::unique_lock< boost::shared_mutex > lock = boost::unique_lock< boost::shared_mutex >( m_prototypesLock );
std::cout << "sdasdshallo" << std::endl;
// currently the prototypes are added by hand. This will be done automatically later.
m_prototypes.insert( boost::shared_ptr< WModule >( new WMNavSlices() ) );
......@@ -75,11 +79,20 @@ void WModuleFactory::load()
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 )
std::set< std::string > names; // helper to find duplicates
for( std::set< boost::shared_ptr< WModule > >::iterator listIter = m_prototypes.begin(); listIter != m_prototypes.end();
++listIter )
{
WLogger::getLogger()->addLogMessage( "Loading module: " + ( *list_iter )->getName(), "ModuleFactory", LL_DEBUG );
( *list_iter )->initialize();
WLogger::getLogger()->addLogMessage( "Loading module: " + ( *listIter )->getName(), "ModuleFactory", LL_DEBUG );
// that should not happen. Names should not occur multiple times since they are unique
if ( names.count( ( *listIter )->getName() ) )
{
throw WPrototypeNotUnique( "Module " + ( *listIter )->getName() + " is not unique. Modules have to have a unique name." );
}
names.insert( ( *listIter )->getName() );
( *listIter )->initialize();
}
slock.unlock();
......@@ -115,3 +128,38 @@ boost::shared_ptr< WModuleFactory > WModuleFactory::getModuleFactory()
return m_instance;
}
const boost::shared_ptr< WModule > WModuleFactory::getPrototypeByName( std::string name )
{
// for this a read lock is sufficient
boost::shared_lock< boost::shared_mutex > slock = boost::shared_lock< boost::shared_mutex >( m_prototypesLock );
// find first and only prototype (ensured during load() )
boost::shared_ptr< WModule > ret = boost::shared_ptr< WModule >();
for( std::set< boost::shared_ptr< WModule > >::iterator listIter = m_prototypes.begin(); listIter != m_prototypes.end();
++listIter )
{
if ( ( *listIter )->getName() == name )
{
ret = ( *listIter );
break;
}
}
slock.unlock();
// if not found -> throw
if ( ret == boost::shared_ptr< WModule >() )
{
throw WPrototypeUnknown( "Could not find prototype " + name + "." );
}
return ret;
}
const boost::shared_ptr< WModule > WModuleFactory::getPrototypeByInstance( boost::shared_ptr< WModule > instance )
{
// TODO(ebaum): implement
WLogger::getLogger()->addLogMessage( "Searching prototype by instance, NOT YET IMPLEMENTED", "ModuleFactory", LL_WARNING );
}
......@@ -37,6 +37,7 @@
*/
class WModuleFactory
{
friend class WModuleFactoryTest;
public:
/**
......@@ -70,6 +71,25 @@ public:
*/
static boost::shared_ptr< WModuleFactory > getModuleFactory();
/**
* Finds a prototype using the specified name.
*
* \param name the name.
*
* \return the prototype whose name is equal to the specified one.
*/
const boost::shared_ptr< WModule > getPrototypeByName( std::string name );
/**
* Finds a prototype using an instance of a module. This uses the type_info to find a proper prototype.
*
* \param instance the instance to use.
*
* \return the prototype.
* \throw WPrototypeUnknown if prototype can not be found.
*/
const boost::shared_ptr< WModule > getPrototypeByInstance( boost::shared_ptr< WModule > instance );
protected:
/**
......
//---------------------------------------------------------------------------
//
// 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 "WPrototypeNotUnique.h"
WPrototypeNotUnique::WPrototypeNotUnique( const std::string& msg ): WKernelException( msg )
{
// initialize members
}
WPrototypeNotUnique::~WPrototypeNotUnique() 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 WPROTOTYPENOTUNIQUE_H
#define WPROTOTYPENOTUNIQUE_H
#include <string>
#include "WKernelException.h"
/**
* Thrown whenever an prototype name is not unique.
* \ingroup kernel
*/
class WPrototypeNotUnique: public WKernelException
{
public:
/**
* Default constructor.
* \param msg the exception message.
*/
explicit WPrototypeNotUnique( const std::string& msg = "Prototype not unique" );
/**
* Destructor.
*/
virtual ~WPrototypeNotUnique() throw();
protected:
private:
};
#endif // WPROTOTYPENOTUNIQUE_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