33 #include "../common/WLogger.h"
34 #include "../common/WThreadedRunner.h"
35 #include "../common/exceptions/WSignalSubscriptionFailed.h"
36 #include "WBatchLoader.h"
37 #include "WModuleCombiner.h"
38 #include "WModuleFactory.h"
39 #include "WModuleInputConnector.h"
40 #include "WModuleOutputConnector.h"
41 #include "WModuleTypes.h"
42 #include "combiner/WApplyCombiner.h"
43 #include "exceptions/WModuleAlreadyAssociated.h"
44 #include "exceptions/WModuleUninitialized.h"
45 #include "WDataModule.h"
47 #include "WModuleContainer.h"
52 m_description( description ),
53 m_crashIfModuleCrashes( true )
86 "ModuleContainer (" +
getName() +
")", LL_INFO );
88 if( !module->isInitialized()() )
91 s <<
"Could not add module \"" << module->getName() <<
"\" to container \"" +
getName() +
"\". Reason: module not initialized.";
97 if( module->getAssociatedContainer() == shared_from_this() )
100 "ModuleContainer (" +
getName() +
")", LL_INFO );
105 if( module->isAssociated()() )
107 module->getAssociatedContainer()->remove( module );
112 wlock->get().insert( module );
115 module->setAssociatedContainer( boost::static_pointer_cast< WModuleContainer >( shared_from_this() ) );
126 boost::signals2::connection signalCon = module->subscribeSignal( WM_ERROR, func );
130 boost::shared_lock<boost::shared_mutex> slock = boost::shared_lock<boost::shared_mutex>(
m_errorNotifiersLock );
133 signalCon = module->subscribeSignal( WM_ERROR, ( *iter ) );
147 for( InputConnectorList::const_iterator ins = module->getInputConnectors().begin(); ins != module->getInputConnectors().end(); ++ins )
149 signalCon = ( *ins )->subscribeSignal( CONNECTION_ESTABLISHED, ( *iter ) );
157 for( InputConnectorList::const_iterator ins = module->getInputConnectors().begin(); ins != module->getInputConnectors().end(); ++ins )
159 signalCon = ( *ins )->subscribeSignal( CONNECTION_CLOSED, ( *iter ) );
166 signalCon = module->subscribeSignal( WM_READY, ( *iter ) );
172 subscriptionsLock.reset();
175 m_progress->addSubProgress( module->getRootProgressCombiner() );
192 module->isReady().wait();
204 if( module->getAssociatedContainer() != shared_from_this() )
210 module->disconnect();
213 m_progress->removeSubProgress( module->getRootProgressCombiner() );
219 std::pair< ModuleSubscriptionsIterator, ModuleSubscriptionsIterator > subscriptions = subscriptionsLock->get().equal_range( module );
223 ( *it ).second.disconnect();
226 subscriptionsLock->get().erase( subscriptions.first, subscriptions.second );
227 subscriptionsLock.reset();
231 wlock->get().erase( module );
234 module->setAssociatedContainer( boost::shared_ptr< WModuleContainer >() );
237 boost::shared_lock<boost::shared_mutex> slock = boost::shared_lock<boost::shared_mutex>(
m_removedNotifiersLock );
257 if( ( *iter )->getType() == MODULE_DATA )
259 boost::shared_ptr< WDataModule > dm = boost::static_pointer_cast<
WDataModule >( *iter );
262 if( dm->isReady()() )
274 const size_t nonZero = 1;
275 size_t numberOfModules = nonZero;
276 std::vector< boost::shared_ptr< WModule > > modulesToRemove;
278 while( numberOfModules != 0 )
280 modulesToRemove.clear();
284 numberOfModules = lock->get().size();
285 for(
ModuleConstIterator listIter = lock->get().begin(); listIter != lock->get().end(); ++listIter )
287 modulesToRemove.push_back( *listIter );
290 for( std::vector< boost::shared_ptr< WModule > >::iterator nameIter = modulesToRemove.begin();
291 nameIter != modulesToRemove.end();
304 boost::shared_lock<boost::shared_mutex> slock = boost::shared_lock<boost::shared_mutex>(
m_pendingThreadsLock );
308 ( *listIter )->wait(
true );
317 for(
ModuleConstIterator listIter = lock->get().begin(); listIter != lock->get().end(); ++listIter )
320 "ModuleContainer (" +
getName() +
")", LL_INFO );
321 ( *listIter )->wait(
true );
322 ( *listIter )->setAssociatedContainer( boost::shared_ptr< WModuleContainer >() );
329 wlock->get().clear();
344 boost::unique_lock<boost::shared_mutex> lock;
363 std::ostringstream s;
364 s <<
"Could not subscribe to unknown signal.";
372 boost::unique_lock<boost::shared_mutex> lock;
381 std::ostringstream s;
382 s <<
"Could not subscribe to unknown signal.";
390 boost::unique_lock<boost::shared_mutex> lock;
393 case CONNECTION_ESTABLISHED:
398 case CONNECTION_CLOSED:
404 std::ostringstream s;
405 s <<
"Could not subscribe to unknown signal.";
413 boost::shared_ptr< WModule >prototype = boost::shared_ptr< WModule >();
432 boost::shared_ptr< WModule > prototype )
435 if( applyOn->isAssociated()() && ( applyOn->getAssociatedContainer() != shared_from_this() ) )
438 std::string(
"\" is associated with another container." ) );
446 applyOn->isReadyOrCrashed().wait();
447 m->isReadyOrCrashed().wait();
458 if( !ins.empty() && !outs.empty() )
460 ( *ins.begin() )->connect( ( *outs.begin() ) );
469 boost::shared_ptr< WBatchLoader > t(
new WBatchLoader( filenames, boost::static_pointer_cast< WModuleContainer >( shared_from_this() ) ) );
470 t->setSuppressColormaps( suppressColormaps );
478 boost::shared_ptr< WBatchLoader > t(
new WBatchLoader( filenames, boost::static_pointer_cast< WModuleContainer >( shared_from_this() ) ) );
479 t->setSuppressColormaps( suppressColormaps );
487 boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>(
m_pendingThreadsLock );
494 boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>(
m_pendingThreadsLock );
501 errorLog() <<
"Error in module \"" << module->getName() <<
"\". Forwarding to nesting container.";
508 infoLog() <<
"Crash caused this container to shutdown.";
533 for(
ModuleConstIterator listIter = lock->get().begin(); listIter != lock->get().end(); ++listIter )
536 if( name == ( *listIter )->getName() )
538 result.push_back( ( *listIter ) );
547 WCombinerTypes::WCompatiblesList complist;
559 for(
ModuleConstIterator listIter = lock->get().begin(); listIter != lock->get().end(); ++listIter )
561 WCombinerTypes::WOneToOneCombiners lComp = WApplyCombiner::createCombinerList< WApplyCombiner>( module, ( *listIter ) );
563 if( lComp.size() != 0 )
565 complist.push_back( WCombinerTypes::WCompatiblesGroup( ( *listIter ), lComp ) );
570 std::sort( complist.begin(), complist.end(), WCombinerTypes::compatiblesSort );
t_ModuleErrorSignalType signal_error
Signal fired whenever a module main thread throws an exception/error.
boost::shared_ptr< WSharedObjectTicketWrite< ModuleContainerType > > WriteTicket
Type for write tickets.
Class for loading many datasets.
wlog::WStreamedLogger errorLog() const
Logger instance for comfortable error logging.
Base for all data loader modules.
WBatchLoader::SPtr loadDataSetsSynchronously(std::vector< std::string > filenames, bool suppressColormaps=false)
Loads the specified files synchronously.
WModuleContainer(std::string name="Unnamed Module Container", std::string description="Used as container for several modules.")
Constructor.
std::set< boost::shared_ptr< WThreadedRunner > > m_pendingThreads
Set of all threads that currently depend upon this container.
void ready()
Call this whenever your module is ready and can react on property changes.
std::string m_description
Description of the module.
std::list< t_GenericSignalHandlerType > m_connectorClosedNotifiers
The notifiers connected to added modules by default and fired whenever the module connectors got disc...
boost::shared_mutex m_associatedNotifiersLock
Lock for associated notifiers set.
virtual const std::string getDescription() const
Gives back a description of this module.
Class representing a single module of OpenWalnut.
boost::shared_mutex m_removedNotifiersLock
Lock for remove-notifiers set.
std::string m_name
Name of the module.
std::vector< boost::shared_ptr< WModuleOutputConnector > > OutputConnectorList
The type for the list of output connectors.
static WLogger * getLogger()
Returns pointer to the currently running logger instance.
virtual const std::string getName() const
Gives back the name of this module.
virtual WModule::SPtr createAndAdd(std::string name)
Convenience method to create a module instance with a given name and automatically add it to the cont...
void addLogMessage(std::string message, std::string source="", LogLevel level=LL_DEBUG)
Appends a log message to the logging queue.
DataModuleListType getDataModules()
Returns a vector of pointers to the loaded data modules in the container.
bool m_crashIfModuleCrashes
This flag denotes whether the whole container should be marked as crashed if one of the contained mod...
boost::shared_ptr< WProgressCombiner > m_progress
Progress indicator used as parent for all progress' of this module.
virtual ~WModuleContainer()
Destructor.
std::list< t_GenericSignalHandlerType > m_connectorEstablishedNotifiers
The notifiers connected to added modules by default and fired whenever the module connectors got conn...
General purpose exception and therefore base class for all kernel related exceptions.
ReadTicket getReadTicket() const
Returns a ticket to get read access to the contained data.
std::vector< boost::shared_ptr< WModule > > ModuleVectorType
A vector of modules.
std::list< t_ModuleErrorSignalHandlerType > m_errorNotifiers
The error notifiers connected to added modules by default.
virtual void moduleMain()
Entry point after loading the module.
ModuleContainerType::const_iterator ModuleConstIterator
The const iterator type of the container.
WriteTicket getWriteTicket(bool suppressNotify=false) const
Returns a ticket to get write access to the contained data.
ModuleSubscriptionsSharedType m_moduleSubscriptions
The module's signal subscriptions.
virtual void moduleError(boost::shared_ptr< WModule > module, const WException &exception)
This method is called whenever a module inside the container crashes.
virtual boost::shared_ptr< WModule > factory() const
Due to the prototype design pattern used to build modules, this method returns a new instance of this...
General purpose exception and therefore base class for all kernel related exceptions.
virtual boost::shared_ptr< WModule > applyModule(boost::shared_ptr< WModule > applyOn, std::string what, bool tryOnly=false)
Function combines two modules.
void finishedPendingThread(boost::shared_ptr< WThreadedRunner > thread)
The specified thread has finished and does not longer depend upon this container instance.
std::list< t_ModuleGenericSignalHandlerType > m_removedNotifiers
The notifiers connected to added modules by default and fired whenever the module got removed again...
WBoolFlag m_isCrashed
True whenever an exception is thrown during threadMain.
virtual void add(boost::shared_ptr< WModule > module, bool run=true)
Add a module to this container and start it.
WCombinerTypes::WCompatiblesList getPossibleConnections(boost::shared_ptr< WModule > module)
This method creates a list of combiner instances, for each possible connection that can be made betwe...
boost::shared_mutex m_connectorNotifiersLock
Lock for connector-notifiers set.
boost::shared_ptr< WBatchLoader > SPtr
Shared ptr abbreviation.
boost::shared_ptr< WModule > SPtr
Shared pointer to a WModule.
General purpose exception and therefore base class for all kernel related exceptions.
std::list< t_ModuleGenericSignalHandlerType > m_readyNotifiers
The ready notifiers connected to added modules by default.
boost::shared_mutex m_pendingThreadsLock
Lock for m_pendingThreads.
static SPtr getModuleFactory()
Returns instance of the module factory to use to create modules.
void addPendingThread(boost::shared_ptr< WThreadedRunner > thread)
Add the specified thread to the list of pending jobs.
std::pair< boost::shared_ptr< WModule >, boost::signals2::connection > ModuleSubscription
A type for mapping a module to all its subscriptions.
virtual void removeAll()
Removes all modules from this container.
virtual void requestStop()
This method's purpose is to request a stop without waiting for it.
virtual void remove(boost::shared_ptr< WModule > module)
Remove the given module from this container if it is associated with it.
std::vector< boost::shared_ptr< WModuleInputConnector > > InputConnectorList
The type for the list of input connectors.
boost::shared_mutex m_readyNotifiersLock
Lock for ready notifiers set.
boost::shared_mutex m_errorNotifiersLock
Lock for error notifiers set.
std::set< boost::shared_ptr< WDataModule > > DataModuleListType
Simple type for WDataModule pointer lists.
wlog::WStreamedLogger infoLog() const
Logger instance for comfortable info logging.
ModuleSubscriptionsType::iterator ModuleSubscriptionsIterator
The iterator type of the container.
ModuleSharedContainerType m_modules
The modules associated with this container.
WBatchLoader::SPtr loadDataSets(std::vector< std::string > filenames, bool suppressColormaps=false)
Load specified datasets.
boost::shared_ptr< WSharedObjectTicketRead< ModuleContainerType > > ReadTicket
Type for read tickets.
std::list< t_ModuleGenericSignalHandlerType > m_associatedNotifiers
The notifiers connected to added modules by default and fired whenever the module got associated...
void setCrashIfModuleCrashes(bool crashIfCrashed=true)
Sets a flag denoting whether the container (which also is a module) should be marked as "crashed" if ...
virtual void stop()
Stops all modules inside this container.
virtual void addDefaultNotifier(MODULE_SIGNAL signal, t_ModuleErrorSignalHandlerType notifier)
Add a specified notifier to the list of default notifiers which get connected to each added module...
ModuleSharedContainerType::ReadTicket getModules() const
Method returns a read ticket allowing read-access to the list of modules inside the container...