datacontainer.h 7.12 KB
Newer Older
1
2
// ================================================================================================
// 
schultezub's avatar
schultezub committed
3
// This file is part of the CAMPVis Software Framework.
4
// 
5
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
schultezub's avatar
schultezub committed
6
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
7
//      Chair for Computer Aided Medical Procedures
8
9
//      Technische Universitaet Muenchen
//      Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
10
// 
schultezub's avatar
schultezub committed
11
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
12
// 
13
14
15
16
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 
// except in compliance with the License. You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
17
// 
18
19
20
21
// Unless required by applicable law or agreed to in writing, software distributed under the 
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
// either express or implied. See the License for the specific language governing permissions 
// and limitations under the License.
22
23
24
// 
// ================================================================================================

schultezub's avatar
schultezub committed
25
26
#ifndef DATACONTAINER_H__
#define DATACONTAINER_H__
schultezub's avatar
schultezub committed
27

schultezub's avatar
schultezub committed
28
#include "sigslot/sigslot.h"
29
#include <tbb/concurrent_hash_map.h>
30
#include <tbb/spin_mutex.h>
31
32

#include "core/coreapi.h"
schultezub's avatar
schultezub committed
33
#include "core/datastructures/datahandle.h"
schultezub's avatar
schultezub committed
34
35
36

#include <string>
#include <map>
37
38
#include <utility>
#include <vector>
schultezub's avatar
schultezub committed
39

schultezub's avatar
schultezub committed
40
namespace campvis {
schultezub's avatar
schultezub committed
41
42
    class AbstractData;
    
schultezub's avatar
schultezub committed
43
44
45
46
    /**
     * A DataContainer manages instances of AbstractData and offers access to them via string identifiers (names/keys).
     * Therefore, it stores them in DataHandles which take ownership of the AbstractData instance. Hence,
     * as soon as an AbstractData instance is added to a DataContainer via DataContainer::addData(), its 
47
     * lifetime is managed by the wrapping DataHandle instance and its reference counting mechanism.
schultezub's avatar
schultezub committed
48
     * Because the DataHandles are stored as const handles, the underlying data cannot be changed anymore. This
49
     * also ensures (hopefully) that nobody can do messy things, such as changing the data while some other 
50
51
     * thread is reading it. Theoretically this should be possible, but a correct implementation would require
     * some brain fuck.
schultezub's avatar
schultezub committed
52
     */
53
    class CAMPVIS_CORE_API DataContainer {
schultezub's avatar
schultezub committed
54
55
56
    public:
        /**
         * Creates a new empty DataContainer
57
         * \param   name    The name of the new DataContainer
schultezub's avatar
schultezub committed
58
         */
59
        DataContainer(const std::string& name);
schultezub's avatar
schultezub committed
60
61
62
63
64
65
66
67
68
69

        /**
         * Destructor of the DataContainer. Will disconnect all DataHandles from this container.
         */
        ~DataContainer();


        /**
         * Adds the given AbstractData instance \a data, accessible by the key \name, to this DataContainer.
         * In doing so, the DataContainer (respectively the created DataHandle) takes ownership of \a data
schultezub's avatar
schultezub committed
70
         * and will manage its lifetime. So don't even think about deleting \a data yourself!
schultezub's avatar
schultezub committed
71
         *
72
73
         * \param   name    Key for accessing the DataHandle within this DataContainer.
         * \param   data    The data to wrap in a DataHandle and add to this DataContainer, must not be 0.
74
         * \return  A DataHandle containing \a data.
schultezub's avatar
schultezub committed
75
         */
76
        DataHandle addData(const std::string& name, AbstractData* data);
schultezub's avatar
schultezub committed
77
78
79
80
81
82
83
84

        /**
         * Adds the given DataHandle \a data, accessible by the key \name, to this DataContainer.
         * Already existing DataHandles with the same key will be removed from this DataContainer.
         *
         * \param   name    Key for accessing the DataHandle within this DataContainer
         * \param   data    DataHandle to add.
         */
85
        void addDataHandle(const std::string& name, const DataHandle& dh);
schultezub's avatar
schultezub committed
86
87
88
89
90
91
92
93
94
95
96

        /**
         * Checks whether this DataContainer contains a DataHandle with the given name.
         *
         * \param   name    Key of the DataHandle to search for
         * \return  true, if this DataContainer contains a DataHandle with the given name.
         */
        bool hasData(const std::string& name) const;

        /**
         * Returns the DataHandle with the given name from this container.
97
         * If no such DataHandle exists, this method returns an empty DataHandle.
schultezub's avatar
schultezub committed
98
99
         *
         * \param   name    Key of the DataHandle to search for
100
         * \return  The stored DataHandle with the given name, an empty DataHandle if no such DataHandle exists.
schultezub's avatar
schultezub committed
101
         */
102
        DataHandle getData(const std::string& name) const;
schultezub's avatar
schultezub committed
103

schultezub's avatar
schultezub committed
104
105
106
107
108
109
        /**
         * Removes the DataHandle with the given name from this container.
         * If no such DataHandle exists, nothing happens.
         * \param   name    Key of the DataHandle to remove.
         */
        void removeData(const std::string& name);
schultezub's avatar
schultezub committed
110

111
112
113
114
115
116
        /**
         * Removes all DataHandles from this DataContainer.
         * \note    This method is \b NOT thread-safe!
         */
        void clear();

117
118
119
120
121
122
        /**
         * Returns a copy of the current list of DataHandles.
         * \note    Use with caution, this method is to be considered as slow, as it includes several 
         *          copies and locks the whole DataContainer during execution.
         * \return  A list of pairs (name, DataHandle). The caller has to take ownership of the passed pointers!
         */
123
        std::vector< std::pair< std::string, DataHandle> > getDataHandlesCopy() const;
124

125
126
127
128
129
130
131
132
133
134
135
136
        /**
         * Returns the name of this DataContainer.
         * \return  _name
         */
        const std::string& getName() const;

        /**
         * Sets the name of this DataContainer.
         * \param   name    The new name of this DataContainer
         */
        void setName(const std::string& name);

137
138
139
140
141
142
        /**
         * Returns a copy of the current map of DataHandles.
         * \note    Use with caution, this method is to be considered as slow, as it includes several 
         *          copies and locks the whole DataContainer during execution.
         * \return  A copy of the current handles map. The caller has to take ownership of the passed pointers!
         */
143
        //std::map<std::string, DataHandle> getHandlesCopy() const;
144

schultezub's avatar
schultezub committed
145
146
147
148
        /**
         * Signal emitted when data has been added to this DataContainer (this includes also data being replaced).
         * First parameter is the name of the added data, second parameter contains a DataHandle to the new data.
         */
149
        sigslot::signal2<const std::string&, const DataHandle&> s_dataAdded;
schultezub's avatar
schultezub committed
150

151
152
153
        /// Signal emitted when list of DataHandles has changed.
        sigslot::signal0<> s_changed;

schultezub's avatar
schultezub committed
154
    private:
155
        /// Map of the DataHandles in this collection and their IDs. The DataHandles contain valid data.
156
        //std::map<std::string, DataHandle> _handles;
157
        mutable tbb::spin_mutex _localMutex;
schultezub's avatar
schultezub committed
158

159
        tbb::concurrent_hash_map<std::string, DataHandle> _handles;
160

161
162
        std::string _name;

schultezub's avatar
schultezub committed
163
164
165
166
        static const std::string loggerCat_;
    };

}
schultezub's avatar
schultezub committed
167
168

#endif // DATACONTAINER_H__