numericproperty.h 9.75 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, all rights reserved,
schultezub's avatar
schultezub committed
6
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
7
8
9
//      Chair for Computer Aided Medical Procedures
//      Technische Universität München
//      Boltzmannstr. 3, 85748 Garching b. München, Germany
schultezub's avatar
schultezub committed
10
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
// 
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// 
// ================================================================================================

schultezub's avatar
schultezub committed
30
31
32
#ifndef NUMERICPROPERTY_H__
#define NUMERICPROPERTY_H__

33
#include "tgt/vector.h"
schultezub's avatar
schultezub committed
34
35
#include "core/properties/genericproperty.h"

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
#include <limits>

namespace {
    /**
     * Helper struct for template specialization regarding scalar/vector types.
     */
    template<typename T, bool IsScalar>
    struct NumericPropertyTraits {
    };

    /**
     * Specialized traits for scalar NumericProperties.
     */
    template<typename T>
    struct NumericPropertyTraits<T, true> {
        static T validateValue(const T& value, const T& minValue, const T& maxValue) {
            if (value >= minValue && value <= maxValue)
                return value;
            else {
                return (value < minValue) ? minValue : maxValue;
            }
        }
    };

    /**
     * Specialized traits for vector NumericProperties.
     */
    template<typename T>
    struct NumericPropertyTraits<T, false> {
        static T validateValue(const T& value, const T& minValue, const T& maxValue) {
            T toReturn(value);

            for (size_t i = 0; i < value.size; ++i) {
                if (toReturn[i] < minValue[i])
                    toReturn[i] = minValue[i];
                else if (toReturn[i] > maxValue[i])
                    toReturn[i] = maxValue[i];
            }
            return toReturn;
        }
    };

}

schultezub's avatar
schultezub committed
80
namespace campvis {
schultezub's avatar
schultezub committed
81
82
83
84
    /**
     * Interface for numeric properties.
     * Defines methods for incrementing and decrementing the property's value.
     */
85
86
    class INumericProperty {
    public:
schultezub's avatar
schultezub committed
87
        /// Increments the value of the property.
88
        virtual void increment() = 0;
schultezub's avatar
schultezub committed
89
        /// Decrements the value of the property.
90
91
92
        virtual void decrement() = 0;
    };

schultezub's avatar
schultezub committed
93
94
95
96
97
98
99
100
    /**
     * Generic class for numeric properties.
     * Numeric properties manage a minimum and maximum value and ensure, that the property's 
     * value is within these bounds.
     *
     * \tparam  T   Base type of the property's value.
     */
    template<typename T>
101
    class NumericProperty : public GenericProperty<T>, public INumericProperty {
schultezub's avatar
schultezub committed
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
    public:
        /**
         * Creates a new NumericProperty.
         * \param name      Property name
         * \param title     Property title (e.g. used for GUI)
         * \param value     Initial value of the property
         * \param minValue  Minimum value for this property
         * \param maxValue  Maximum value for this property
         * \param il        Invalidation level that this property triggers
         */
        NumericProperty(
            const std::string& name,
            const std::string& title,
            const T& value,
            const T& minValue,
            const T& maxValue,
            InvalidationLevel il = InvalidationLevel::INVALID_RESULT);

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


        /**
         * 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);

        /**
         * Returns the minimum value of this property.
         * \return _minValue
         */
        const T& getMinValue() const;

        /**
         * Returns the minimum value of this property.
         * \return _minValue
         */
        const T& getMaxValue() const;

        /**
         * Sets the minimum value if this property.
         * \param   value   New minimum value for this property.
         */
        virtual void setMinValue(const T& value);

        /**
         * Sets the minimum value if this property.
         * \param   value   New minimum value for this property.
         */
        virtual void setMaxValue(const T& value);

schultezub's avatar
schultezub committed
158
159
160
        /**
         * Increments the value of this property.
         */
161
        virtual void increment();
schultezub's avatar
schultezub committed
162
163
164
165

        /**
         * Decrements the value of this property.
         */
166
        virtual void decrement();
schultezub's avatar
schultezub committed
167

schultezub's avatar
schultezub committed
168
169
        /// Signal emitted, when the property's minimum or maximum value changes.
        sigslot::signal1<const AbstractProperty*> s_minMaxChanged;
schultezub's avatar
schultezub committed
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

    protected:

        /**
         * Checks, whether \a value is a valid value for this property.
         * Default implementation always returns true, subclasses can overwrite this method to fit their needs.
         * \param   value   value to validate.
         * \return  true if \a value is a valid value for this property.
         */
        virtual T validateValue(const T& value);

        
        T _value;                               ///< value of the property
        T _backBuffer;                          ///< back buffer for values when property is in use
        T _minValue;                            ///< Minimum value for this property
        T _maxValue;                            ///< Maximum value for this property

        static const std::string loggerCat_;
    };

schultezub's avatar
schultezub committed
190
// = Typedefs =====================================================================================
schultezub's avatar
schultezub committed
191

schultezub's avatar
schultezub committed
192
193
    typedef NumericProperty<int> IntProperty;
    typedef NumericProperty<float> FloatProperty;
schultezub's avatar
schultezub committed
194

195
196
197
198
199
200
201
    typedef NumericProperty<tgt::ivec2> IVec2Property;
    typedef NumericProperty<tgt::vec2> Vec2Property;
    typedef NumericProperty<tgt::ivec3> IVec3Property;
    typedef NumericProperty<tgt::vec3> Vec3Property;
    typedef NumericProperty<tgt::ivec4> IVec4Property;
    typedef NumericProperty<tgt::vec4> Vec4Property;

schultezub's avatar
schultezub committed
202
// = Template Implementation ======================================================================
schultezub's avatar
schultezub committed
203
204

    template<typename T>
schultezub's avatar
schultezub committed
205
    campvis::NumericProperty<T>::NumericProperty(const std::string& name, const std::string& title, const T& value, const T& minValue, const T& maxValue, InvalidationLevel il /*= InvalidationLevel::INVALID_RESULT*/)
schultezub's avatar
schultezub committed
206
207
208
209
210
211
212
213
        : GenericProperty<T>(name, title, value, il)
        , _minValue(minValue)
        , _maxValue(maxValue)
    {

    }

    template<typename T>
schultezub's avatar
schultezub committed
214
    campvis::NumericProperty<T>::~NumericProperty() {
schultezub's avatar
schultezub committed
215
216
217
    }

    template<typename T>
schultezub's avatar
schultezub committed
218
    void campvis::NumericProperty<T>::addSharedProperty(AbstractProperty* prop) {
schultezub's avatar
schultezub committed
219
220
221
222
223
224
225
226
227
228
229
        // make type check first, then call base method.
        tgtAssert(prop != 0, "Shared property must not be 0!");
        if (NumericProperty<T>* tmp = dynamic_cast< NumericProperty<T>* >(prop)) {
            AbstractProperty::addSharedProperty(prop);
            tmp->setValue(getValue());
            return;
        }
        tgtAssert(false, "Shared property must be of the same type as this property!");
    }

    template<typename T>
schultezub's avatar
schultezub committed
230
    T campvis::NumericProperty<T>::validateValue(const T& value) {
231
        return NumericPropertyTraits<T, std::numeric_limits<T>::is_specialized>::validateValue(value, _minValue, _maxValue);
schultezub's avatar
schultezub committed
232
233
234
    }

    template<typename T>
schultezub's avatar
schultezub committed
235
    const T& campvis::NumericProperty<T>::getMinValue() const {
schultezub's avatar
schultezub committed
236
237
238
239
        return _minValue;
    }

    template<typename T>
schultezub's avatar
schultezub committed
240
    const T& campvis::NumericProperty<T>::getMaxValue() const {
schultezub's avatar
schultezub committed
241
242
243
244
        return _maxValue;
    }

    template<typename T>
schultezub's avatar
schultezub committed
245
    void campvis::NumericProperty<T>::setMinValue(const T& value) {
schultezub's avatar
schultezub committed
246
247
        _minValue = value;
        setValue(validateValue(getValue()));
schultezub's avatar
schultezub committed
248
        s_minMaxChanged(this);
schultezub's avatar
schultezub committed
249
250
251
    }

    template<typename T>
schultezub's avatar
schultezub committed
252
    void campvis::NumericProperty<T>::setMaxValue(const T& value) {
schultezub's avatar
schultezub committed
253
254
        _maxValue = value;
        setValue(validateValue(getValue()));
schultezub's avatar
schultezub committed
255
        s_minMaxChanged(this);
schultezub's avatar
schultezub committed
256
257
258
    }

    template<typename T>
schultezub's avatar
schultezub committed
259
    void campvis::NumericProperty<T>::increment() {
schultezub's avatar
schultezub committed
260
261
262
263
        setValue(getValue() + T(1));
    }

    template<typename T>
schultezub's avatar
schultezub committed
264
    void campvis::NumericProperty<T>::decrement() {
schultezub's avatar
schultezub committed
265
266
267
268
269
        setValue(getValue() - T(1));
    }
}

#endif // NUMERICPROPERTY_H__