datahandle.h 4.06 KB
Newer Older
schultezub's avatar
schultezub committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#ifndef datahandle_h__
#define datahandle_h__

#include "tgt/logmanager.h"
#include "datastructures/abstractdata.h"

#include <string>
#include <set>

namespace TUMVis {

    class DataContainer;

    /**
     * A DataHandle is responsible to manage the lifetime of an AbstractData instance.
     * Therefore, it holds a pointer to the managed data object as well as a set of pointers to the
     * DataContainer instances containing this very DataHandle. Each DataContainer is responsible for
     * registering itsself as owner of its DataHandles (via DataHandle::addOwner()). When removing a
     * DataHandle from a container, make sure to deregister via DataHandle::removeOwner().
     *
     * \note    For clarity: A DataHandle can have multiple owners, as soon as the owner count drops
     *          to 0 it will be destroyed. Also remember that a DataHandle takes ownership of the 
     *          given AbstractData instance. So do not delete it once it has been assigned to a 
     *          DataHandle (respectively DataContainer).
     *
     * \todo 
     */
    class DataHandle {
    
    // DataContainer is the only class allowed to access the private constructor and ownership modification methods.
    friend class DataContainer;

    public:
        /**
         * Destructor, will delete the managed AbstractData.
         */
        virtual ~DataHandle();

        /**
         * Grants const access to the managed AbstractData instance.
         * \return  _data;
         */
        const AbstractData* getData() const;

        /**
         * Grants access to the managed AbstractData instance.
         * \return  _data;
         */
        AbstractData* getData();

    private:
        /**
         * Creates a new DataHandle for \a data and takes its ownership in terms of lifetime management. 
         * The DataContainer \a owner will automatically be added to the set of owners of this DataHandle, so
         * it is NOT needed to call DataHandle::addOwner().
         *
         * \param   owner   Initial owner of this DataHandle (usually the DataContainer creating the handle)
         * \param   data    AbstractData instance to manage
         */
        DataHandle(const DataContainer* owner, AbstractData* data);

        /**
         * DO NOT USE - it is private on purpose!
         *
         * IMHO a DataHandle does not need a copy-constructor - in particular it could be a bad idea to use
         * one, because it does not exactly what you expect. If you really need a copy-constructor, please
         * make sure to implement it correctly.
         */
        DataHandle(const DataHandle& rhs);

        /**
         * DO NOT USE - it is private on purpose!
         *
         * IMHO a DataHandle does not need an assignment-operator - in particular it could be a bad idea to use
         * one, because it does not exactly what you expect. If you really need an assignment-operator, please
         * make sure to implement it correctly.
         */
        DataHandle& operator=(const DataHandle& rhs);

        /**
         * Registers \a owner as owner of the DataHandle \a handle.
         * \param   handle  DataHandle that gets another ownership.
         * \param   owner   Owner that shall be added to the owner list of \a handle.
         */
        static void addOwner(const DataHandle* handle, const DataContainer* owner);

        /**
         * Removes \a owner from the owner list of \a handle. If afterwards the number of owners is 0, \a handle will be deleted.
         * \param   handle  DataHandle of which to remove the ownership.
         * \param   owner   Owner that shall be removed from the owner list of \a handle.
         */
        static void removeOwner(const DataHandle* handle, const DataContainer* owner);


        AbstractData* _data;                                ///< managed data
        mutable std::set<const DataContainer*> _owners;     ///< set of owners of this DataHandle

        static const std::string loggerCat_;
    };

}

#endif // datahandle_h__