abstractprocessor.h 10.1 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 PROCESSOR_H__
#define PROCESSOR_H__

schultezub's avatar
schultezub committed
33
#include "sigslot/sigslot.h"
schultezub's avatar
schultezub committed
34
#include "tbb/atomic.h"
35
#include "tbb/concurrent_queue.h"
schultezub's avatar
schultezub committed
36
37
#include "tgt/logmanager.h"
#include "core/datastructures/datacontainer.h"
schultezub's avatar
schultezub committed
38
39
40
41
#include "core/properties/propertycollection.h"

#include <string>
#include <vector>
schultezub's avatar
schultezub committed
42

schultezub's avatar
schultezub committed
43
namespace campvis {
schultezub's avatar
schultezub committed
44
45
    class AbstractProperty;

schultezub's avatar
schultezub committed
46
    /**
schultezub's avatar
schultezub committed
47
     * Abstract base class for CAMPVis Processors.
48
49
50
51
52
53
54
55
     * A processor implements a specific task, which it performs on the DataCollection passed
     * during process(). Properties provide a transparent layer for adjusting the processor's 
     * behaviour.
     * Once a processor has finished it sets it should set its invalidation level to valid. As
     * soon as one of its properties changes, the processor will be notified and possibliy
     * change its invalidation level. Observing pipelines will be notified of this and can
     * and have to decide which part of the pipeline has to be re-evaluated wrt. the processor's
     * invalidation level.
schultezub's avatar
schultezub committed
56
57
58
     * 
     * \sa AbstractPipeline
     */
schultezub's avatar
schultezub committed
59
    class AbstractProcessor : public HasPropertyCollection {
schultezub's avatar
schultezub committed
60
    public:
61
62
63
64
65
66
67
68
69
70
        /**
         * Available invalidation levels
         */
        enum InvalidationLevel {
            VALID               = 0,        ///< Valid
            INVALID_RESULT      = 1 << 0,   ///< Need to rerun the process() method
            INVALID_SHADER      = 1 << 1,   ///< Need to recompile the shader
            INVALID_FILE        = 1 << 2,   ///< Need to reread the file
            INVALID_PROPERTIES  = 1 << 3    ///< Need to update the properties
        };
71

schultezub's avatar
schultezub committed
72
73
74
75
76
77
78
79
80
81
82
        /**
         * Creates a AbstractProcessor.
         */
        AbstractProcessor();

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


schultezub's avatar
schultezub committed
83
        /**
84
85
86
         * Initializes the processor.
         * Everything that requires a valid OpenGL context or is otherwise expensive gets in here.
         * 
schultezub's avatar
schultezub committed
87
88
89
         * \note    When overwriting this method, make sure to call the base class version first.
         */
        virtual void init();
90
91
        
        /**
schultezub's avatar
schultezub committed
92
         * Deinitializes this processor.
93
         * \note    When overwriting this method, make sure to call the base class version at the end.
94
95
         */
        virtual void deinit();
schultezub's avatar
schultezub committed
96

schultezub's avatar
schultezub committed
97
98
        /**
         * Execute this processor.
99
         * \param data      DataContainer to work on.
schultezub's avatar
schultezub committed
100
         **/
101
        virtual void process(DataContainer& data) = 0;
schultezub's avatar
schultezub committed
102

103
104
105
106
107
108
        /**
         * Gets the name of this very processor. To be defined by every subclass.
         * \return  The name of this processor.
         */
        virtual const std::string getName() const = 0;

109
110
111
112
113
114
        /**
         * Gets a description of this processor. To be defined by every subclass.
         * \return  A description what this processor does.
         */
        virtual const std::string getDescription() const = 0;

115
116
117
118
119
120
121
122
123
124
125
        /**
         * Gets the flag whether this processor is currently enabled.
         * \return _enabled
         */
        bool getEnabled() const;

        /**
         * Sets the flag whether this processor is currently enabled.
         * \param   enabled     New flag whether this processor is currently enabled.
         */
        void setEnabled(bool enabled);
126
127
128
129
130
131
132
133
134
135
136
137

        /**
         * Returns whether to measure the execution time of this processor.
         * \return  _clockExecutionTime
         */
        bool getClockExecutionTime() const;

        /**
         * Sets whether to measure the execution time of this processor.
         * \param   value   The new flag vlaue whether to measure the execution time of this processor.
         */
        void setClockExecutionTime(bool value);
138
        
139
        /**
140
         * 
141
         * Locks all properties in the processor's PropertyCollection and marks them as "in use".
142
         * \sa  AbstractProcessor::unlockProcessor
143
         */
144
        void lockProcessor();
145
146
147

        /**
         * Unlocks all properties in the processor's PropertyCollection and marks them as "not in use".
148
         * \sa  AbstractProcessor::lockProcessor
149
         */
150
        void unlockProcessor();
151

152
153
154
155
156
157
        /**
         * Returns the current lockProcessor status of this processor.
         * If a processor is locked, all of its properties are locked and its process method must not be called.
         * \return  _locked != 0
         */
        bool isLocked();
158

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
// = Invalidation Level related stuff =============================================================

        /**
         * Returns the current invalidation level.
         * \return _level
         */
        int getInvalidationLevel() const {
            return _level;
        }

        /**
         * Returns wheter the invalidation level is valid (i.e. no invalid flag is set).
         * \return _level == VALID
         */
        bool isValid() const {
            return _level == static_cast<int>(VALID);
        }

        /**
         * Returns wheter the the INVALID_RESULT flag is set.
         * \return _level & INVALID_RESULT
         */
        bool hasInvalidResult() const {
            return (_level & static_cast<int>(INVALID_RESULT)) != 0;
        }

        /**
         * Returns wheter the the INVALID_SHADER flag is set.
         * \return _level & INVALID_SHADER
         */
        bool hasInvalidShader() const {
            return (_level & static_cast<int>(INVALID_SHADER)) != 0;
        }

        /**
         * Returns wheter the the INVALID_FILE flag is set.
         * \return _level & INVALID_FILE
         */
        bool hasInvalidFile() const {
            return (_level & static_cast<int>(INVALID_FILE)) != 0;
        }

        /**
         * Returns wheter the the INVALID_PROPERTIES flag is set.
         * \return _level & INVALID_PROPERTIES
         */
        bool hasInvalidProperties() const {
            return (_level & static_cast<int>(INVALID_PROPERTIES)) != 0;
        }

        /**
         * Sets the invalidation level to valid (i.e. clears all invalidation flags).
         */
        void setValid() {
            _level = static_cast<int>(VALID);
        }

        /**
         * Sets all invalidation flags specified in \a level.
         * \param   level   Flags to set to invalid.
         */
        void invalidate(int level);

        /**
         * Sets all invalidation flags specified in \a il's level.
         * \param   il  Flags to set to invalid.
         */
        void invalidate(InvalidationLevel il) {
            invalidate(static_cast<int>(il));
        }

        /**
         * Clears all invalidation flags specified in \a level.
         * \param   level   Flags to set to valid.
         */
        void validate(int level);

        /**
         * Clears all invalidation flags specified in \a il's level.
         * \param   il  Flags to set to valid.
         */
        void validate(InvalidationLevel il) {
            validate(static_cast<int>(il));
        }

schultezub's avatar
schultezub committed
244
        /// Signal emitted when the processor has been invalidated.
245
        sigslot::signal1<AbstractProcessor*> s_invalidated;
schultezub's avatar
schultezub committed
246

247
248
249
        /// Signal emitted when the processor has been validated.
        sigslot::signal1<AbstractProcessor*> s_validated;

250
251
// = Slots ========================================================================================

schultezub's avatar
schultezub committed
252
253
254
255
256
257
        /**
         * Slot getting called when one of the observed properties changed and notifies its observers.
         * \param   prop    Property that emitted the signal
         */
        virtual void onPropertyChanged(const AbstractProperty* prop);

schultezub's avatar
schultezub committed
258
    protected:
259
        tbb::atomic<bool> _enabled;                 ///< flag whether this processor is currently enabled
260
        tbb::atomic<bool> _clockExecutionTime;      ///< flag whether to measure the execution time of this processor
261
262
263
264

        /// Flag whether this processor is currently locked
        /// (This implies, that all properties are locked and it is not valid to call process())
        tbb::atomic<bool> _locked;
schultezub's avatar
schultezub committed
265

266
    private:
267
268
        tbb::atomic<int> _level;            ///< current invalidation level
        tbb::concurrent_queue<int> _queuedInvalidations;
269

270
        static const std::string loggerCat_;
schultezub's avatar
schultezub committed
271
272
273
274
275
    };

}

#endif // PROCESSOR_H__