openscenegraph
OperationThread
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSG_OPERATIONTHREAD
15#define OSG_OPERATIONTHREAD 1
16
17#include <osg/observer_ptr>
18#include <osg/Object>
19
20#include <OpenThreads/Thread>
21#include <OpenThreads/Barrier>
22#include <OpenThreads/Condition>
23#include <OpenThreads/Block>
24
25#include <list>
26#include <set>
27
28namespace osg {
29
30class RefBlock : virtual public osg::Referenced, public OpenThreads::Block
31{
32 public:
33
34 RefBlock():
35 osg::Referenced(true) {}
36
37};
38
39class RefBlockCount : virtual public osg::Referenced, public OpenThreads::BlockCount
40{
41 public:
42
43 RefBlockCount(unsigned blockCount):
44 osg::Referenced(true),
45 OpenThreads::BlockCount(blockCount) {}
46
47};
48
49/** Base class for implementing graphics operations.*/
50class Operation : virtual public Referenced
51{
52 public:
53
54 Operation(const std::string& name, bool keep):
55 _name(name),
56 _keep(keep) {}
57
58
59 /** Set the human readable name of the operation.*/
60 void setName(const std::string& name) { _name = name; }
61
62 /** Get the human readable name of the operation.*/
63 const std::string& getName() const { return _name; }
64
65 /** Set whether the operation should be kept once its been applied.*/
66 void setKeep(bool keep) { _keep = keep; }
67
68 /** Get whether the operation should be kept once its been applied.*/
69 bool getKeep() const { return _keep; }
70
71 /** if this operation is a barrier then release it.*/
72 virtual void release() {}
73
74 /** Do the actual task of this operation.*/
75 virtual void operator () (Object*) = 0;
76
77protected:
78
79 Operation():
80 _keep(false) {}
81
82 virtual ~Operation() {}
83
84 std::string _name;
85 bool _keep;
86};
87
88class OperationThread;
89
90class OSG_EXPORT OperationQueue : public Referenced
91{
92 public:
93
94 OperationQueue();
95
96 /** Get the next operation from the operation queue.
97 * Return null ref_ptr<> if no operations are left in queue. */
98 osg::ref_ptr<Operation> getNextOperation(bool blockIfEmpty = false);
99
100 /** Return true if the operation queue is empty. */
101 bool empty();
102
103 /** Return the num of pending operations that are sitting in the OperationQueue.*/
104 unsigned int getNumOperationsInQueue();
105
106 /** Add operation to end of OperationQueue, this will be
107 * executed by the operation thread once this operation gets to the head of the queue.*/
108 void add(Operation* operation);
109
110 /** Remove operation from OperationQueue.*/
111 void remove(Operation* operation);
112
113 /** Remove named operation from OperationQueue.*/
114 void remove(const std::string& name);
115
116 /** Remove all operations from OperationQueue.*/
117 void removeAllOperations();
118
119 /** Run the operations. */
120 void runOperations(Object* callingObject=0);
121
122 /** Call release on all operations. */
123 void releaseAllOperations();
124
125 /** Release operations block that is used to block threads that are waiting on an empty operations queue.*/
126 void releaseOperationsBlock();
127
128 typedef std::set<OperationThread*> OperationThreads;
129
130 /** Get the set of OperationThreads that are sharing this OperationQueue. */
131 const OperationThreads& getOperationThreads() const { return _operationThreads; }
132
133 protected:
134
135 virtual ~OperationQueue();
136
137 friend class OperationThread;
138
139 void addOperationThread(OperationThread* thread);
140 void removeOperationThread(OperationThread* thread);
141
142 typedef std::list< osg::ref_ptr<Operation> > Operations;
143
144 OpenThreads::Mutex _operationsMutex;
145 osg::ref_ptr<osg::RefBlock> _operationsBlock;
146 Operations _operations;
147 Operations::iterator _currentOperationIterator;
148
149 OperationThreads _operationThreads;
150};
151
152/** OperationThread is a helper class for running Operation within a single thread.*/
153class OSG_EXPORT OperationThread : public Referenced, public OpenThreads::Thread
154{
155 public:
156 OperationThread();
157
158 void setParent(Object* parent) { _parent = parent; }
159
160 Object* getParent() { return _parent.get(); }
161
162 const Object* getParent() const { return _parent.get(); }
163
164
165 /** Set the OperationQueue. */
166 void setOperationQueue(OperationQueue* opq);
167
168 /** Get the OperationQueue. */
169 OperationQueue* getOperationQueue() { return _operationQueue.get(); }
170
171 /** Get the const OperationQueue. */
172 const OperationQueue* getOperationQueue() const { return _operationQueue.get(); }
173
174
175 /** Add operation to end of OperationQueue, this will be
176 * executed by the graphics thread once this operation gets to the head of the queue.*/
177 void add(Operation* operation);
178
179 /** Remove operation from OperationQueue.*/
180 void remove(Operation* operation);
181
182 /** Remove named operation from OperationQueue.*/
183 void remove(const std::string& name);
184
185 /** Remove all operations from OperationQueue.*/
186 void removeAllOperations();
187
188
189 /** Get the operation currently being run.*/
190 osg::ref_ptr<Operation> getCurrentOperation() { return _currentOperation; }
191
192 /** Run does the opertion thread run loop.*/
193 virtual void run();
194
195 void setDone(bool done);
196
197 bool getDone() const { return _done!=0; }
198
199 /** Cancel this graphics thread.*/
200 virtual int cancel();
201
202 protected:
203
204 virtual ~OperationThread();
205
206 observer_ptr<Object> _parent;
207
208 OpenThreads::Atomic _done;
209
210 OpenThreads::Mutex _threadMutex;
211 osg::ref_ptr<OperationQueue> _operationQueue;
212 osg::ref_ptr<Operation> _currentOperation;
213
214};
215
216typedef OperationThread OperationsThread;
217
218}
219
220#endif