Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
OpenWalnut
OpenWalnut Core
Commits
1a5e9dae
Commit
1a5e9dae
authored
Apr 20, 2010
by
Sebastian Eichelbaum
Browse files
[CHANGE] - extended module deletion. Now the item is deleted after the module has finished
parent
f8bb790f
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
337 additions
and
39 deletions
+337
-39
src/common/WThreadedRunner.cpp
src/common/WThreadedRunner.cpp
+2
-2
src/common/WThreadedRunner.h
src/common/WThreadedRunner.h
+5
-5
src/gui/qt4/WQt4Gui.cpp
src/gui/qt4/WQt4Gui.cpp
+7
-0
src/gui/qt4/WQt4Gui.h
src/gui/qt4/WQt4Gui.h
+8
-1
src/gui/qt4/datasetbrowser/WQtDatasetBrowser.cpp
src/gui/qt4/datasetbrowser/WQtDatasetBrowser.cpp
+41
-9
src/gui/qt4/datasetbrowser/WQtTreeItem.cpp
src/gui/qt4/datasetbrowser/WQtTreeItem.cpp
+37
-1
src/gui/qt4/datasetbrowser/WQtTreeItem.h
src/gui/qt4/datasetbrowser/WQtTreeItem.h
+17
-2
src/gui/qt4/events/WEventTypes.h
src/gui/qt4/events/WEventTypes.h
+3
-0
src/gui/qt4/events/WModuleDeleteEvent.cpp
src/gui/qt4/events/WModuleDeleteEvent.cpp
+45
-0
src/gui/qt4/events/WModuleDeleteEvent.h
src/gui/qt4/events/WModuleDeleteEvent.h
+68
-0
src/kernel/WModule.cpp
src/kernel/WModule.cpp
+11
-2
src/kernel/WModule.h
src/kernel/WModule.h
+18
-5
src/kernel/WModuleContainer.cpp
src/kernel/WModuleContainer.cpp
+27
-11
src/kernel/WModuleContainer.h
src/kernel/WModuleContainer.h
+48
-1
No files found.
src/common/WThreadedRunner.cpp
View file @
1a5e9dae
...
...
@@ -25,12 +25,13 @@
#include <iostream>
#include "WConditionOneShot.h"
#include "WCondition.h"
#include "WLogger.h"
#include "WThreadedRunner.h"
WThreadedRunner
::
WThreadedRunner
()
:
m_shutdownFlag
(
new
WConditionOneShot
,
false
)
m_shutdownFlag
(
new
WConditionOneShot
()
,
false
)
{
// initialize members
}
...
...
@@ -61,7 +62,6 @@ void WThreadedRunner::wait( bool requestFinish )
m_thread
.
join
();
}
void
WThreadedRunner
::
requestStop
()
{
// first notify
...
...
src/common/WThreadedRunner.h
View file @
1a5e9dae
...
...
@@ -75,6 +75,11 @@ public:
*/
void
wait
(
bool
requestFinish
=
false
);
/**
* This method's purpose is to request a stop without waiting for it.
*/
virtual
void
requestStop
();
protected:
/**
...
...
@@ -88,11 +93,6 @@ protected:
*/
virtual
void
notifyStop
();
/**
* This method's purpose is to request a stop without waiting for it.
*/
virtual
void
requestStop
();
/**
* Thread instance.
*/
...
...
src/gui/qt4/WQt4Gui.cpp
View file @
1a5e9dae
...
...
@@ -51,6 +51,8 @@
#include "events/WModuleCrashEvent.h"
#include "events/WUpdateTextureSorterEvent.h"
WMainWindow
*
WQt4Gui
::
m_mainWindow
=
NULL
;
WQt4Gui
::
WQt4Gui
(
int
argc
,
char
**
argv
)
:
WGUI
(
argc
,
argv
)
{
...
...
@@ -104,6 +106,11 @@ void WQt4Gui::moduleError( boost::shared_ptr< WModule > module, const WException
QCoreApplication
::
postEvent
(
m_mainWindow
,
new
WModuleCrashEvent
(
module
,
exception
.
what
()
)
);
}
WMainWindow
*
WQt4Gui
::
getMainWindow
()
{
return
m_mainWindow
;
}
int
WQt4Gui
::
run
()
{
bool
parsingSuccessful
=
parseOptions
();
...
...
src/gui/qt4/WQt4Gui.h
View file @
1a5e9dae
...
...
@@ -131,6 +131,13 @@ public:
*/
virtual
void
closeCustomWidget
(
std
::
string
title
);
/**
* Returns the current main window instance or NULL if not existent.
*
* \return the main window instance.
*/
static
WMainWindow
*
getMainWindow
();
protected:
/**
...
...
@@ -146,7 +153,7 @@ private:
/**
* Main window containing all needed widgets.
*/
WMainWindow
*
m_mainWindow
;
static
WMainWindow
*
m_mainWindow
;
/**
* Graphics Engine instance.
...
...
src/gui/qt4/datasetbrowser/WQtDatasetBrowser.cpp
View file @
1a5e9dae
...
...
@@ -44,6 +44,7 @@
#include "../events/WRoiAssocEvent.h"
#include "../events/WRoiRemoveEvent.h"
#include "../events/WModuleReadyEvent.h"
#include "../events/WModuleDeleteEvent.h"
#include "../events/WEventTypes.h"
#include "../guiElements/WQtApplyModulePushButton.h"
#include "../WMainWindow.h"
...
...
@@ -199,6 +200,35 @@ bool WQtDatasetBrowser::event( QEvent* event )
return
true
;
}
// a module tree item should be deleted
if
(
event
->
type
()
==
WQT_MODULE_REMOVE_EVENT
)
{
WModuleDeleteEvent
*
e
=
dynamic_cast
<
WModuleDeleteEvent
*
>
(
event
);
// NOLINT
if
(
!
e
)
{
// this should never happen, since the type is set to WQT_Ready_EVENT.
WLogger
::
getLogger
()
->
addLogMessage
(
"Event is not an WModuleRemoveEvent although its type claims it. Ignoring event."
,
"DatasetBrowser"
,
LL_WARNING
);
return
true
;
}
// grab the module reference and print some info
boost
::
shared_ptr
<
WModule
>
module
=
e
->
getTreeItem
()
->
getModule
();
WLogger
::
getLogger
()
->
addLogMessage
(
"Removing module
\"
"
+
module
->
getName
()
+
"
\"
from Tree."
,
"DatasetBrowser"
,
LL_DEBUG
);
// remove it from the tree and free last ref count
m_moduleTreeWidget
->
deleteItem
(
e
->
getTreeItem
()
);
// ref count != 1?
if
(
module
.
use_count
()
!=
1
)
{
wlog
::
warn
(
"DatasetBrowser"
)
<<
"Removed module has strange usage count: "
<<
module
.
use_count
()
<<
". Should be 1 here. "
<<
"Module reference is held by someone else."
;
}
return
true
;
}
// a module changed its state to "ready" -> activate it in dataset browser
if
(
event
->
type
()
==
WQT_READY_EVENT
)
{
...
...
@@ -209,6 +239,8 @@ bool WQtDatasetBrowser::event( QEvent* event )
// this should never happen, since the type is set to WQT_Ready_EVENT.
WLogger
::
getLogger
()
->
addLogMessage
(
"Event is not an WModueReadyEvent although its type claims it. Ignoring event."
,
"DatasetBrowser"
,
LL_WARNING
);
return
true
;
}
WLogger
::
getLogger
()
->
addLogMessage
(
"Activating module "
+
e
->
getModule
()
->
getName
()
+
" in dataset browser."
,
...
...
@@ -640,17 +672,17 @@ boost::shared_ptr< WRMROIRepresentation > WQtDatasetBrowser::getFirstRoiInSelect
void
WQtDatasetBrowser
::
deleteModuleTreeItem
()
{
// TODO(ebaum): test whether the item is a module/dataset
if
(
m_moduleTreeWidget
->
selectedItems
().
count
()
>
0
)
{
boost
::
shared_ptr
<
WModule
>
module
=
dynamic_cast
<
WQtTreeItem
*
>
(
m_moduleTreeWidget
->
selectedItems
().
at
(
0
)
)
->
getModule
();
m_moduleTreeWidget
->
deleteItem
(
m_moduleTreeWidget
->
selectedItems
().
at
(
0
)
)
;
// instruct the kernel to remove module
WKernel
::
getRunningKernel
()
->
getRootContainer
()
->
remove
(
module
);
// DEBUG:
int
count
=
module
.
use_count
();
std
::
cout
<<
"COUNT DMTI "
<<
count
<<
std
::
endl
;
if
(
(
m_moduleTreeWidget
->
selectedItems
().
at
(
0
)
->
type
()
==
MODULE
)
||
(
m_moduleTreeWidget
->
selectedItems
().
at
(
0
)
->
type
()
==
DATASET
)
)
{
// instead of deleting the tree item directly -> inform the tree item and let it do the job:
static_cast
<
WQtTreeItem
*
>
(
m_moduleTreeWidget
->
selectedItems
().
at
(
0
)
)
->
deleteSelf
();
// select another item
m_moduleTreeWidget
->
setCurrentItem
(
m_moduleTreeWidget
->
topLevelItem
(
0
)
);
}
}
}
...
...
src/gui/qt4/datasetbrowser/WQtTreeItem.cpp
View file @
1a5e9dae
...
...
@@ -25,17 +25,27 @@
#include <set>
#include <string>
#include <QtGui/QApplication>
#include "../../../kernel/WKernel.h"
#include "../../../common/WProgressCombiner.h"
#include "../../../common/WProgress.h"
#include "../../../kernel/WModuleInputConnector.h"
#include "../../../kernel/WModuleOutputConnector.h"
#include "../events/WModuleDeleteEvent.h"
#include "../WQt4Gui.h"
#include "../WMainWindow.h"
#include "WTreeItemTypes.h"
#include "WQtTreeItem.h"
WQtTreeItem
::
WQtTreeItem
(
QTreeWidgetItem
*
parent
,
WTreeItemType
type
,
boost
::
shared_ptr
<
WModule
>
module
)
:
QTreeWidgetItem
(
parent
,
type
)
QTreeWidgetItem
(
parent
,
type
),
m_deleteInProgress
(
false
),
m_needPostDeleteEvent
(
true
)
{
m_module
=
module
;
m_name
=
module
->
getName
();
...
...
@@ -148,7 +158,33 @@ void WQtTreeItem::updateState()
setText
(
0
,
m_name
.
c_str
()
);
}
// if the user requested it to be deleted: disable and color it
if
(
m_deleteInProgress
)
{
setForeground
(
0
,
QBrush
(
QColor
::
fromRgb
(
255
,
0
,
0
)
)
);
setDisabled
(
true
);
}
// is finished?
if
(
!
m_module
->
isRunning
().
get
()
&&
m_needPostDeleteEvent
)
{
m_needPostDeleteEvent
=
false
;
// this ensures the event is only posted once
QCoreApplication
::
postEvent
(
WQt4Gui
::
getMainWindow
()
->
getDatasetBrowser
(),
new
WModuleDeleteEvent
(
this
)
);
}
// update tooltip
updateTooltip
(
progress
);
}
void
WQtTreeItem
::
deleteSelf
()
{
// instruct the kernel to remove module
WKernel
::
getRunningKernel
()
->
getRootContainer
()
->
remove
(
m_module
);
// update tree item state
m_deleteInProgress
=
true
;
// instruct the module to finish
m_module
->
requestStop
();
}
src/gui/qt4/datasetbrowser/WQtTreeItem.h
View file @
1a5e9dae
...
...
@@ -50,7 +50,7 @@ public:
* \param module The represented module
* \param type the type used for the treeitem. Used to identify the items.
*/
WQtTreeItem
(
QTreeWidgetItem
*
parent
,
WTreeItemType
type
,
boost
::
shared_ptr
<
WModule
>
module
);
WQtTreeItem
(
QTreeWidgetItem
*
parent
,
WTreeItemType
type
,
boost
::
shared_ptr
<
WModule
>
module
);
/**
* Destructor.
...
...
@@ -62,7 +62,7 @@ public:
*
* \return the pointer to the module associated with this item.
*/
boost
::
shared_ptr
<
WModule
>
getModule
();
boost
::
shared_ptr
<
WModule
>
getModule
();
/**
* Returns the name used for this tree item.
...
...
@@ -71,6 +71,11 @@ public:
*/
std
::
string
getName
();
/**
* Initiates the item to delete itself from the tree. It also removes the underlying module to be deleted from the module graph.
*/
virtual
void
deleteSelf
();
public
slots
:
/**
...
...
@@ -102,6 +107,16 @@ protected:
*/
void
updateTooltip
(
std
::
string
progress
);
/**
* True if the treeitem and the module gets deleted currently.
*/
bool
m_deleteInProgress
;
/**
* True if no delete event has been posted yet.
*/
bool
m_needPostDeleteEvent
;
private:
/**
...
...
src/gui/qt4/events/WEventTypes.h
View file @
1a5e9dae
...
...
@@ -54,4 +54,7 @@
// when a roi got removed
#define WQT_ROI_REMOVE_EVENT QEvent::User + 7
// when a module got deleted
#define WQT_MODULE_REMOVE_EVENT QEvent::User + 8
#endif // WEVENTTYPES_H
src/gui/qt4/events/WModuleDeleteEvent.cpp
0 → 100644
View file @
1a5e9dae
//---------------------------------------------------------------------------
//
// 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 "WEventTypes.h"
#include "WModuleDeleteEvent.h"
WModuleDeleteEvent
::
WModuleDeleteEvent
(
WQtTreeItem
*
treeItem
)
:
QEvent
(
static_cast
<
QEvent
::
Type
>
(
WQT_MODULE_REMOVE_EVENT
)
),
m_item
(
treeItem
)
{
// initialize members
}
WModuleDeleteEvent
::~
WModuleDeleteEvent
()
{
// cleanup
}
WQtTreeItem
*
WModuleDeleteEvent
::
getTreeItem
()
{
return
m_item
;
}
src/gui/qt4/events/WModuleDeleteEvent.h
0 → 100644
View file @
1a5e9dae
//---------------------------------------------------------------------------
//
// 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 WMODULEDELETEEVENT_H
#define WMODULEDELETEEVENT_H
#include <QtCore/QEvent>
#include "../datasetbrowser/WQtTreeItem.h"
/**
* Event signalling a module item should be deleted.
*/
class
WModuleDeleteEvent
:
public
QEvent
{
public:
/**
* Creates a new event instance denoting that the specified module got deleted in the root container.
*
* \param treeItem the tree item that switched its state.
*/
explicit
WModuleDeleteEvent
(
WQtTreeItem
*
treeItem
);
/**
* Destructor.
*/
virtual
~
WModuleDeleteEvent
();
/**
* Getter for the tree item that got outdated.
*
* \return the tree item
*/
WQtTreeItem
*
getTreeItem
();
protected:
/**
* The tree item sent this event.
*/
WQtTreeItem
*
m_item
;
private:
};
#endif // WMODULEDELETEEVENT_H
src/kernel/WModule.cpp
View file @
1a5e9dae
...
...
@@ -60,6 +60,7 @@ WModule::WModule():
m_isReady
(
new
WConditionOneShot
(),
false
),
m_isCrashed
(
new
WConditionOneShot
(),
false
),
m_isReadyOrCrashed
(
new
WConditionSet
(),
false
),
m_isRunning
(
new
WCondition
(),
false
),
m_readyProgress
(
boost
::
shared_ptr
<
WProgress
>
(
new
WProgress
(
"Initializing Module"
)
)
),
m_moduleState
()
{
...
...
@@ -102,7 +103,7 @@ void WModule::addConnector( boost::shared_ptr< WModuleOutputConnector > con )
m_outputConnectors
.
insert
(
con
);
}
void
WModule
::
disconnect
All
()
void
WModule
::
disconnect
()
{
// remove connections and their signals
for
(
std
::
set
<
boost
::
shared_ptr
<
WModuleInputConnector
>
>::
iterator
listIter
=
m_inputConnectors
.
begin
();
...
...
@@ -123,7 +124,7 @@ void WModule::removeConnectors()
m_isUsable
(
m_initialized
()
&&
m_isAssociated
()
);
// remove connections and their signals, this is flat removal. The module container can do deep removal
disconnect
All
();
disconnect
();
// clean up list
// this should delete the connector since nobody else *should* have another shared_ptr to them
...
...
@@ -302,6 +303,11 @@ const WBoolFlag& WModule::isReadyOrCrashed() const
return
m_isReadyOrCrashed
;
}
const
WBoolFlag
&
WModule
::
isRunning
()
const
{
return
m_isRunning
;
}
void
WModule
::
notifyConnectionEstablished
(
boost
::
shared_ptr
<
WModuleConnector
>
/*here*/
,
boost
::
shared_ptr
<
WModuleConnector
>
/*there*/
)
{
...
...
@@ -366,6 +372,7 @@ void WModule::threadMain()
WLogger
::
getLogger
()
->
addLogMessage
(
"Starting module main method."
,
"Module ("
+
getName
()
+
")"
,
LL_INFO
);
// call main thread function
m_isRunning
(
true
);
moduleMain
();
}
catch
(
const
WException
&
e
)
...
...
@@ -392,6 +399,8 @@ void WModule::threadMain()
// hopefully, all waiting threads use isReadyOrCrashed to wait.
m_isCrashed
(
true
);
}
m_isRunning
(
false
);
}
wlog
::
WStreamedLogger
WModule
::
infoLog
()
const
...
...
src/kernel/WModule.h
View file @
1a5e9dae
...
...
@@ -173,6 +173,13 @@ public:
*/
const
WBoolFlag
&
isReadyOrCrashed
()
const
;
/**
* Returns a flag denoting whether the thread currently is running or nor. It is also useful to get a callback whenever a module stops.
*
* \return the flag
*/
const
WBoolFlag
&
isRunning
()
const
;
/**
* The container this module is associated with.
*
...
...
@@ -232,6 +239,12 @@ public:
*/
virtual
MODULE_TYPE
getType
()
const
;
/**
* Completely disconnects all connected connectors of this module. This is useful to isolate a module (for deletion, removal from a container
* and so on.)
*/
void
disconnect
();
protected:
/**
...
...
@@ -301,11 +314,6 @@ protected:
*/
void
removeConnectors
();
/**
* Completely disconnects all connected connectors of this module.
*/
void
disconnectAll
();
/**
* Callback for m_active. Overwrite this in your modules to handle m_active changes separately.
*/
...
...
@@ -440,6 +448,11 @@ protected:
*/
WBoolFlag
m_isReadyOrCrashed
;
/**
* True if the module currently is running.
*/
WBoolFlag
m_isRunning
;
/**
* Progress indicator for the "ready" state.
*/
...
...
src/kernel/WModuleContainer.cpp
View file @
1a5e9dae
...
...
@@ -51,7 +51,8 @@ WModuleContainer::WModuleContainer( std::string name, std::string description ):
m_moduleAccess
(
m_modules
.
getAccessObject
()
),
m_name
(
name
),
m_description
(
description
),
m_crashIfModuleCrashes
(
true
)
m_crashIfModuleCrashes
(
true
),
m_moduleSubscriptionsAccess
(
m_moduleSubscriptions
.
getAccessObject
()
)
{
WLogger
::
getLogger
()
->
addLogMessage
(
"Constructing module container."
,
"ModuleContainer ("
+
getName
()
+
")"
,
LL_INFO
);
// initialize members
...
...
@@ -110,17 +111,21 @@ void WModuleContainer::add( boost::shared_ptr< WModule > module, bool run )
LL_INFO
);
// now module->isUsable() is true
// -> so run it
// Connect the error handler and all default handlers:
m_moduleSubscriptionsAccess
->
beginWrite
();
// connect the containers signal handler explicitly
t_ModuleErrorSignalHandlerType
func
=
boost
::
bind
(
&
WModuleContainer
::
moduleError
,
this
,
_1
,
_2
);
module
->
subscribeSignal
(
WM_ERROR
,
func
);
boost
::
signals2
::
connection
signalCon
=
module
->
subscribeSignal
(
WM_ERROR
,
func
);
m_moduleSubscriptionsAccess
->
get
().
insert
(
ModuleSubscription
(
module
,
signalCon
)
);
// connect default ready/error notifiers
boost
::
shared_lock
<
boost
::
shared_mutex
>
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
(
WM_ERROR
,
(
*
iter
)
);
signalCon
=
module
->
subscribeSignal
(
WM_ERROR
,
(
*
iter
)
);
m_moduleSubscriptionsAccess
->
get
().
insert
(
ModuleSubscription
(
module
,
signalCon
)
);
}
slock
=
boost
::
shared_lock
<
boost
::
shared_mutex
>
(
m_associatedNotifiersLock
);
for
(
std
::
list
<
t_ModuleGenericSignalHandlerType
>::
iterator
iter
=
m_associatedNotifiers
.
begin
();
iter
!=
m_associatedNotifiers
.
end
();
++
iter
)
...
...
@@ -131,9 +136,11 @@ void WModuleContainer::add( boost::shared_ptr< WModule > module, bool run )
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
(
WM_READY
,
(
*
iter
)
);
signalCon
=
module
->
subscribeSignal
(
WM_READY
,
(
*
iter
)
);
m_moduleSubscriptionsAccess
->
get
().
insert
(
ModuleSubscription
(
module
,
signalCon
)
);
}
slock
.
unlock
();
m_moduleSubscriptionsAccess
->
endWrite
();
// add the modules progress to local progress combiner
m_progress
->
addSubProgress
(
module
->
getRootProgressCombiner
()
);
...
...
@@ -157,15 +164,25 @@ void WModuleContainer::remove( boost::shared_ptr< WModule > module )
return
;
}
// stop module
WLogger
::
getLogger
()
->
addLogMessage
(
"Waiting for module
\"
"
+
module
->
getName
()
+
"
\"
to finish."
,
"ModuleContainer ("
+
getName
()
+
")"
,
LL_DEBUG
);
module
->
wait
(
true
);
// remove connections inside this container
module
->
disconnect
();
// remove progress combiner
m_progress
->
removeSubProgress
(
module
->
getRootProgressCombiner
()
);
// remove signal subscriptions
// remove signal subscriptions to this containers default notifiers
m_moduleSubscriptionsAccess
->
beginWrite
();
// find all subscriptions for this module
std
::
pair
<
ModuleSubscriptionsIterator
,
ModuleSubscriptionsIterator
>
subscriptions
=
m_moduleSubscriptionsAccess
->
get
().
equal_range
(
module
);
for
(
ModuleSubscriptionsIterator
it
=
subscriptions
.
first
;
it
!=
subscriptions
.
second
;
++
it
)
{
// disconnect subscription.
(
*
it
).
second
.
disconnect
();
}
// erase them
m_moduleSubscriptionsAccess
->
get
().
erase
(
subscriptions
.
first
,
subscriptions
.
second
);
m_moduleSubscriptionsAccess
->
endWrite
();
// get write lock
m_moduleAccess
->
beginWrite
();
...
...
@@ -173,7 +190,6 @@ void WModuleContainer::remove( boost::shared_ptr< WModule > module )
m_moduleAccess
->
endWrite
();
module
->
setAssociatedContainer
(
boost
::
shared_ptr
<
WModuleContainer
>
()
);
}
WModuleContainer
::
DataModuleListType
WModuleContainer
::
getDataModules
()
...
...
src/kernel/WModuleContainer.h
View file @
1a5e9dae
...
...
@@ -27,6 +27,7 @@
#include <list>
#include <set>
#include <map>
#include <vector>
#include <string>
...
...
@@ -107,7 +108,10 @@ public:
virtual
void
add
(
boost
::
shared_ptr
<
WModule
>
module
,
bool
run
=
true
);
/**
* Remove the given module from this container if it is associated with it. TODO(ebaum): deep removal? flat removal?
* Remove the given module from this container if it is associated with it. It only provides flat removal. It does not remove depending
* modules. Please be aware that this method does NOT stop the module. It just removes it from the container. If you release the shared
* pointer after removing from the container, the instance gets freed although it still might run. To also wait for the module to quit, use
* module->wait( true ).
*
* \param module the module to remove.
*/
...
...
@@ -325,6 +329,49 @@ protected:
bool
m_crashIfModuleCrashes
;
private:
// the following typedefs are for convenience; to help accessing the container in a thread safe way.
/**
* A type for mapping a module to all its subscriptions
*/
typedef
std
::
pair
<
boost
::
shared_ptr
<
WModule
>
,
boost
::
signals2
::
connection
>
ModuleSubscription
;
/**