2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit c96d2310 authored by schultezub's avatar schultezub
Browse files

completed proper reference counting implementation for DataHandles:

 * introduced DataContainer::ScopedTypedData<T> for transparent  strongly-typed access to the data of a DataContainer while preserving the reference counting

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@202 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent c1785d9d
......@@ -64,7 +64,8 @@ namespace TUMVis {
glViewport(0, 0, size.x, size.y);
// try get Data
const ImageDataRenderTarget* image = _pipeline->getRenderTarget();
DataContainer::ScopedTypedData<ImageDataRenderTarget> image(_pipeline->getDataContainer(), _pipeline->getRenderTargetID());
//const ImageDataRenderTarget* image = _pipeline->getRenderTarget();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (image != 0) {
// activate shader
......
#include "datacontainer.h"
#include "tgt/assert.h"
namespace TUMVis {
const std::string DataContainer::loggerCat_ = "TUMVis.core.datastructures.DataContainer";
......@@ -22,6 +23,7 @@ namespace TUMVis {
}
void DataContainer::addDataHandle(const std::string& name, const DataHandle* dh) {
tgtAssert(dh != 0, "DataHandle must not be 0.");
{
tbb::spin_mutex::scoped_lock lock(_localMutex);
std::map<std::string, const DataHandle*>::iterator it = _handles.lower_bound(name);
......@@ -47,6 +49,6 @@ namespace TUMVis {
if (it == _handles.end())
return 0;
else
return it->second;
return new DataHandle(*it->second);
}
}
\ No newline at end of file
......@@ -28,6 +28,66 @@ namespace TUMVis {
*/
class DataContainer {
public:
/**
* Proxy class for scoped strongly-typed access to the data of a DataContainer.
* From the outside ScopedTypedData<T> behaves exactly like a const T*, but internally it preserves the
* reference counting of a DataHandle. Use this class when you want temporary access to a strongly-typed
* data item in a DataContainer but don't want to to the dynamic_cast yourself.
*
* \tparam T Base class of the DataHandle data to test for
*/
template<typename T>
struct ScopedTypedData {
/**
* Creates a new DataHandle to the data item with the key \a name in \a dc, that behaves like a T*.
* \param dc DataContainer to grab data from
* \param name Key of the DataHandle to search for
*/
ScopedTypedData(const DataContainer& dc, const std::string& name)
: dh(dc.getData(name))
, data(0)
{
if (dh != 0 && dh->getData() != 0) {
data = dynamic_cast<const T*>(dh->getData());
}
};
/**
* Destructor, deletes the internal DataHandle.
*/
~ScopedTypedData() {
if (dh) {
delete dh;
}
};
/**
* Implicit conversion operator to const T*.
* \return The data in the DataHandle, may be 0 when no DataHandle was found, or the data is of the wrong type.
*/
operator const T*() {
return data;
}
/**
* Implicit arrow operator to const T*.
* \return The data in the DataHandle, may be 0 when no DataHandle was found, or the data is of the wrong type.
*/
const T* operator->() const {
return data;
}
private:
/// Not copy-constructable
ScopedTypedData(const ScopedTypedData& rhs);
/// Not assignable
ScopedTypedData& operator=(const ScopedTypedData& rhs);
const DataHandle* dh; ///< DataHandle, may be 0
const T* data; ///< strongly-typed pointer to data, may be 0
};
/**
* Creates a new empty DataContainer
*/
......@@ -76,17 +136,6 @@ namespace TUMVis {
*/
const DataHandle* getData(const std::string& name) const;
/**
* Get the DataHandle with the given name from this container and tries to dynamic_cast it to const T*.
* If no such DataHandle exists or the dynamic_cast fails, this method returns 0.
*
* \param name Key of the DataHandle to search for
* \tparam T Target type of data for dynamic_cast.
* \return The stored DataHandle with the given name, casted to const T*, 0 if no such DataHandle exists or conversion failed.
*/
template<typename T>
inline const T* getTypedData(const std::string& name) const;
sigslot::signal2<const std::string&, const DataHandle*> s_dataAdded;
......@@ -97,14 +146,6 @@ namespace TUMVis {
static const std::string loggerCat_;
};
template<typename T>
const T* TUMVis::DataContainer::getTypedData(const std::string& name) const {
const DataHandle* dh = getData(name);
if (dh != 0)
return dynamic_cast<const T*>(dh->getData());
return 0;
}
}
#endif // DATACONTAINER_H__
......@@ -11,7 +11,6 @@ namespace TUMVis {
DataHandle::DataHandle(AbstractData* data)
: _data(data)
{
tgtAssert(_data != 0, "Provided data must not be 0!");
init();
}
......@@ -35,7 +34,8 @@ namespace TUMVis {
}
DataHandle::~DataHandle() {
_data->removeReference();
if (_data)
_data->removeReference();
}
......@@ -52,6 +52,9 @@ namespace TUMVis {
}
void DataHandle::init() {
if (_data == 0)
return;
if (! _data->isShareable())
_data = _data->clone();
_data->addReference();
......
......@@ -60,8 +60,8 @@ namespace TUMVis {
}
}
const ImageDataRenderTarget* VisualizationPipeline::getRenderTarget() const {
return _data.getTypedData<ImageDataRenderTarget>(_renderTargetID.getValue());
const std::string& VisualizationPipeline::getRenderTargetID() const {
return _renderTargetID.getValue();
}
void VisualizationPipeline::setRenderTargetSize(const tgt::ivec2& size) {
......
......@@ -76,14 +76,10 @@ namespace TUMVis {
const tgt::ivec2& getRenderTargetSize() const;
/**
* Returns the DataHandle with the render target of this VisualizationPipeline in its current state.
*
* \todo This is not thread-safe, the object might be destroyed at any time.
* Time for implementing reference counting?
*
* Returns the ID of the render target image to be rendered to the canvas
* \return The DataHandle named _renderTargetID in the pipeline's DataContainer, 0 if no such handle exists.
*/
const ImageDataRenderTarget* getRenderTarget() const;
const std::string& getRenderTargetID() const;
/**
* Gets called when the data collection of this pipeline has changed and thus has notified its observers.
......
......@@ -47,7 +47,7 @@ namespace TUMVis {
executeProcessor(_imageReader);
// convert data
const ImageData* img = _data.getTypedData<ImageData>("reader.output");
DataContainer::ScopedTypedData<ImageData> img(_data, "reader.output");
ImageDataLocal* local = ImageDataConverter::tryConvert<ImageDataLocal>(img);
if (local != 0) {
_data.addData("se.input", local);
......
......@@ -41,7 +41,7 @@ namespace TUMVis {
}
void SliceExtractor::process(DataContainer& data) {
const ImageDataLocal* img = data.getTypedData<ImageDataLocal>(_sourceImageID.getValue());
DataContainer::ScopedTypedData<ImageDataLocal> img(data, _sourceImageID.getValue());
if (img != 0) {
if (img->getDimensionality() == 3) {
......
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