21.10.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

abstractprocessor.h 7.46 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"
schultezub's avatar
schultezub committed
35
36
#include "tgt/logmanager.h"
#include "core/datastructures/datacontainer.h"
schultezub's avatar
schultezub committed
37
#include "core/tools/invalidationlevel.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 {
60
61
62
63
64
65
66
67

    /**
     * We have to find a trade-off:
     * On the one hand, we want to follow the information-hiding concept and keep the processor's
     * properties private. On the other hand pipelines will usually want direct access to them
     * (e.g. in order to setup data IDs or property sharing) and the properties in the PropertyCollection
     * are not strongly typed. Hence, we declare AbstractPipeline as our friend.
     */
schultezub's avatar
schultezub committed
68
    friend class AbstractPipeline;  // TODO: this does not work as intended...
69

schultezub's avatar
schultezub committed
70
    public:
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
        /**
         * Returns the invalidation level of this processor.
schultezub's avatar
schultezub committed
105
         * \return _invalidationLevel
106
         */
schultezub's avatar
schultezub committed
107
        const InvalidationLevel& getInvalidationLevel() const;
108

109
110
111
112
113
114
        /**
         * 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;

115
116
117
118
119
120
        /**
         * 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;

schultezub's avatar
schultezub committed
121
        /**
schultezub's avatar
schultezub committed
122
123
124
125
         * Update the processor's invalidation level by \a il.
         * If \a il is VALID, the processor's invalidation level will be set to VALID.
         * If \a il is one of the INVALID_X state, the processor's corresponding flag will be set.
         * \param il    Invalidation level to apply.
schultezub's avatar
schultezub committed
126
         */
127
        void applyInvalidationLevel(InvalidationLevel il);
128
129
130
131
132
133
134
135
136
137
138
139

        /**
         * 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);
140
        
141
        /**
142
         * 
143
         * Locks all properties in the processor's PropertyCollection and marks them as "in use".
144
         * \sa  AbstractProcessor::unlockProcessor
145
         */
146
        void lockProcessor();
147
148
149

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

154
155
156
157
158
159
        /**
         * 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();
160

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

164
165
166
        /// Signal emitted when the processor has been validated.
        sigslot::signal1<AbstractProcessor*> s_validated;

schultezub's avatar
schultezub committed
167
168
169
170
171
172
173
        /**
         * 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
174
    protected:
175
176
177
178
179
        tbb::atomic<bool> _enabled;                 ///< flag whether this processor is currently enabled

        /// 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
180

schultezub's avatar
schultezub committed
181
        static const std::string loggerCat_;
182
183
184
185

    private:
        InvalidationLevel _invalidationLevel;       ///< current invalidation level of this processor

schultezub's avatar
schultezub committed
186
187
188
189
190
    };

}

#endif // PROCESSOR_H__