genericproperty.h 7.21 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
27
#ifndef GENERICPROPERTY_H__
#define GENERICPROPERTY_H__

28
#include <tbb/spin_mutex.h>
schultezub's avatar
   
schultezub committed
29
#include "tgt/logmanager.h"
schultezub's avatar
schultezub committed
30
#include "core/properties/abstractproperty.h"
schultezub's avatar
   
schultezub committed
31

schultezub's avatar
schultezub committed
32
namespace campvis {
schultezub's avatar
   
schultezub committed
33
34

    /**
schultezub's avatar
schultezub committed
35
36
37
     * Generic class for value-based properties.
     *
     * \tparam  T   Base type of the property's value.
schultezub's avatar
   
schultezub committed
38
39
     */
    template<typename T>
schultezub's avatar
schultezub committed
40
    class GenericProperty : public AbstractProperty {
schultezub's avatar
   
schultezub committed
41
42
    public:
        /**
schultezub's avatar
schultezub committed
43
44
45
46
         * Creates a new GenericProperty.
         * \param name      Property name
         * \param title     Property title (e.g. used for GUI)
         * \param value     Initial value of the property
schultezub's avatar
   
schultezub committed
47
         */
schultezub's avatar
schultezub committed
48
49
50
        GenericProperty(
            const std::string& name,
            const std::string& title,
51
            const T& value);
schultezub's avatar
   
schultezub committed
52
53
54
55
56
57
58

        /**
         * Virtual Destructor
         **/
        virtual ~GenericProperty();


59
60
61
62
63
64
65
66
        /**
         * Adds the given property \a prop to the set of shared properties.
         * All shared properties will be changed when this property changes.
         * \note        Make sure not to build circular sharing or you will encounter endless loops!
         * \param prop  Property to add, must be of the same type as this property.
         */
        virtual void addSharedProperty(AbstractProperty* prop);

schultezub's avatar
schultezub committed
67
68
69
70
        /**
         * Returns the current value of this property.
         * \return _value
         */
schultezub's avatar
schultezub committed
71
        const T& getValue() const;
schultezub's avatar
   
schultezub committed
72

schultezub's avatar
schultezub committed
73
        /**
74
         * On successful validation it sets the property value to \a value and notifies all observers.
75
         * Depending on the current lock state of the property, the value will either be written to the front or back buffer.
76
         * \sa GenericProperty::validateValue
schultezub's avatar
schultezub committed
77
78
         * \param value     New value for this property.
         */
79
        virtual void setValue(const T& value);
schultezub's avatar
   
schultezub committed
80
81


82
83
84
85
86
        /**
         * Unlocks the property. If the back buffer has changed, the changes will be written to the front
         * buffer and all observers will be notified.
         * \sa  GenericProperty::lock
         */
schultezub's avatar
schultezub committed
87
        virtual void unlock();
88
89


schultezub's avatar
schultezub committed
90
    protected:
91
92
93
94
95
96
97
98

        /**
         * Adapts \a value, so that is is a valid value for this property.
         * Default implementation does nothing and always returns \a value, subclasses can overwrite this method to fit their needs.
         * \param   value   value to validate.
         */
        virtual T validateValue(const T& value);

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
        /**
         * Sets the property value to \a value and notifies all observers.
         * \note    _localMutex has to be acquired before calling!
         * \param   value   New value for _value.
         */
        void setFrontValue(const T& value);

        /**
         * Sets the property's back buffer value to \a value.
         * \note    _localMutex has to be acquired before calling!
         * \param   value   New value for _backBuffer.
         */
        void setBackValue(const T& value);

        
        T _value;                               ///< value of the property
        T _backBuffer;                          ///< back buffer for values when property is in use
116

schultezub's avatar
schultezub committed
117
118
        static const std::string loggerCat_;
    };
schultezub's avatar
   
schultezub committed
119

schultezub's avatar
schultezub committed
120
121
// = Typedefs =====================================================================================

122
    typedef GenericProperty<bool> BoolProperty;
schultezub's avatar
schultezub committed
123
124

// = Template Implementation ======================================================================
schultezub's avatar
   
schultezub committed
125

schultezub's avatar
schultezub committed
126
    template<typename T>
127
128
    campvis::GenericProperty<T>::GenericProperty(const std::string& name, const std::string& title, const T& value) 
        : AbstractProperty(name, title)
schultezub's avatar
schultezub committed
129
        , _value(value)
130
        , _backBuffer(value)
schultezub's avatar
schultezub committed
131
132
    {
    }
schultezub's avatar
   
schultezub committed
133

schultezub's avatar
schultezub committed
134
    template<typename T>
schultezub's avatar
schultezub committed
135
    campvis::GenericProperty<T>::~GenericProperty() {
schultezub's avatar
   
schultezub committed
136

schultezub's avatar
schultezub committed
137
    }
schultezub's avatar
   
schultezub committed
138

139
    template<typename T>
schultezub's avatar
schultezub committed
140
    void campvis::GenericProperty<T>::addSharedProperty(AbstractProperty* prop) {
141
142
        // make type check first, then call base method.
        tgtAssert(prop != 0, "Shared property must not be 0!");
schultezub's avatar
schultezub committed
143
144
145
        if (GenericProperty<T>* tmp = dynamic_cast< GenericProperty<T>* >(prop)) {
            AbstractProperty::addSharedProperty(prop);
            tmp->setValue(getValue());
146
147
            return;
        }
schultezub's avatar
schultezub committed
148
        tgtAssert(false, "Shared property must be of the same type as this property!");
149
150
    }

schultezub's avatar
schultezub committed
151
    template<typename T>
schultezub's avatar
schultezub committed
152
    const T& campvis::GenericProperty<T>::getValue() const {
schultezub's avatar
schultezub committed
153
154
        return _value;
    }
schultezub's avatar
   
schultezub committed
155

schultezub's avatar
schultezub committed
156
    template<typename T>
schultezub's avatar
schultezub committed
157
    void campvis::GenericProperty<T>::setValue(const T& value) {
158
        T vv = validateValue(value);
schultezub's avatar
schultezub committed
159
        tbb::spin_mutex::scoped_lock lock(_localMutex);
160

161
        if (_inUse != 0)
162
            setBackValue(vv);
schultezub's avatar
schultezub committed
163
        else {
164
165
            setFrontValue(vv);
            setBackValue(vv);
schultezub's avatar
schultezub committed
166
        }
167
168
169
    }

    template<typename T>
schultezub's avatar
schultezub committed
170
    void campvis::GenericProperty<T>::unlock() {
schultezub's avatar
schultezub committed
171
        tbb::spin_mutex::scoped_lock lock(_localMutex);
172
173
174

        if (_backBuffer != _value)
            setFrontValue(_backBuffer);
175
        AbstractProperty::unlock();
176
177
178
    }

    template<typename T>
schultezub's avatar
schultezub committed
179
    void campvis::GenericProperty<T>::setFrontValue(const T& value) {
schultezub's avatar
schultezub committed
180
        _value = value;
181
182
        for (std::set<AbstractProperty*>::iterator it = _sharedProperties.begin(); it != _sharedProperties.end(); ++it) {
            // We ensure all shared properties to be of type GenericProperty<T> in the addSharedProperty overload.
183
            // Hence, static_cast is safe.
184
185
186
            GenericProperty<T>* child = static_cast< GenericProperty<T>* >(*it);
            child->setValue(value);
        }
schultezub's avatar
schultezub committed
187
        s_changed(this);
schultezub's avatar
schultezub committed
188
    }
schultezub's avatar
   
schultezub committed
189

190
    template<typename T>
schultezub's avatar
schultezub committed
191
    void campvis::GenericProperty<T>::setBackValue(const T& value) {
192
193
194
        _backBuffer = value;
    }

195
    template<typename T>
schultezub's avatar
schultezub committed
196
    T campvis::GenericProperty<T>::validateValue(const T& value) {
197
198
199
        return value;
    }

schultezub's avatar
schultezub committed
200
    template<typename T>
schultezub's avatar
schultezub committed
201
    const std::string campvis::GenericProperty<T>::loggerCat_ = "CAMPVis.core.datastructures.GenericProperty";
schultezub's avatar
   
schultezub committed
202
203
204
}

#endif // GENERICPROPERTY_H__