Panda3D
cycleDataWriter.I
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file cycleDataWriter.I
10  * @author drose
11  * @date 2002-02-21
12  */
13 
14 #ifndef CPPPARSER
15 
16 #ifdef DO_PIPELINING
17 // This is the implementation for full support of pipelining (as well as the
18 // sanity-check only implementation).
19 
20 /**
21  *
22  */
23 template<class CycleDataType>
25 CycleDataWriter(PipelineCycler<CycleDataType> &cycler, Thread *current_thread) :
26  _cycler(&cycler),
27  _current_thread(current_thread)
28 {
29  _pointer = _cycler->write(_current_thread);
30  nassertv(_pointer != nullptr);
31 }
32 
33 /**
34  * This two-parameter constructor, with a bool parameter for the second
35  * parameter, automatically propagates the CycleData pointer upstream from the
36  * current stage, either stopping at the first pointer encountered that's
37  * different, going or all the way to stage 0, according to force_to_0. See
38  * PipelineCycler::write_upstream().
39  */
40 template<class CycleDataType>
42 CycleDataWriter(PipelineCycler<CycleDataType> &cycler, bool force_to_0,
43  Thread *current_thread) :
44  _cycler(&cycler),
45  _current_thread(current_thread)
46 {
47  _pointer = _cycler->write_upstream(force_to_0, _current_thread);
48  nassertv(_pointer != nullptr);
49 }
50 
51 /**
52  * This special constructor "steals" a reference count from the already-locked
53  * cdata object. It does not increment the lock count of this object, but
54  * will release it when the destructor is called.
55  *
56  * This is designed for special functions that return an already-locked cdata
57  * object and expect the caller to unlock it.
58  */
59 template<class CycleDataType>
61 CycleDataWriter(PipelineCycler<CycleDataType> &cycler, CycleDataType *locked_cdata,
62  Thread *current_thread) :
63  _cycler(&cycler),
64  _current_thread(current_thread)
65 {
66  _pointer = locked_cdata;
67  nassertv(_pointer != nullptr);
68 }
69 
70 /**
71  *
72  */
73 template<class CycleDataType>
76  _cycler(copy._cycler),
77  _current_thread(copy._current_thread),
78  _pointer(copy._pointer)
79 {
80  nassertv(_pointer != nullptr);
81  _cycler->increment_write(_pointer);
82 }
83 
84 /**
85  *
86  */
87 template<class CycleDataType>
90  nassertv(_pointer == nullptr);
91  nassertv(_current_thread == copy._current_thread);
92 
93  _cycler = copy._cycler;
94  _pointer = copy._pointer;
95 
96  nassertv(_pointer != nullptr);
97  _cycler->increment_write(_pointer);
98 }
99 
100 /**
101  * This flavor of the constructor elevates the pointer from the
102  * CycleDataLockedReader from a read to a write pointer (and invalidates the
103  * reader).
104  */
105 template<class CycleDataType>
109  _cycler(&cycler),
110  _current_thread(take_from.get_current_thread())
111 {
112  _pointer = _cycler->elevate_read(take_from.take_pointer(), _current_thread);
113 }
114 
115 /**
116  * This flavor of the constructor elevates the pointer from the
117  * CycleDataLockedReader from a read to a write pointer (and invalidates the
118  * reader). It also propagates the pointer back upstream; see
119  * PipelineCycler::write_upstream().
120  */
121 template<class CycleDataType>
125  bool force_to_0) :
126  _cycler(&cycler),
127  _current_thread(take_from.get_current_thread())
128 {
129  _pointer = _cycler->elevate_read_upstream(take_from.take_pointer(),
130  force_to_0, _current_thread);
131 }
132 
133 /**
134  *
135  */
136 template<class CycleDataType>
139  _cycler(from._cycler),
140  _current_thread(from._current_thread),
141  _pointer(from._pointer)
142 {
143  from._pointer = nullptr;
144 }
145 
146 /**
147  *
148  */
149 template<class CycleDataType>
152  nassertv(_pointer == nullptr);
153  nassertv(_current_thread == from._current_thread);
154 
155  _cycler = from._cycler;
156  _pointer = from._pointer;
157 
158  from._pointer = nullptr;
159 }
160 
161 /**
162  *
163  */
164 template<class CycleDataType>
167  if (_pointer != nullptr) {
168  _cycler->release_write(_pointer);
169  }
170 }
171 
172 /**
173  * This provides an indirect member access to the actual CycleData data.
174  */
175 template<class CycleDataType>
176 INLINE CycleDataType *CycleDataWriter<CycleDataType>::
177 operator -> () {
178  nassertr(_pointer != nullptr, _cycler->cheat());
179  return _pointer;
180 }
181 
182 /**
183  * This provides an indirect member access to the actual CycleData data.
184  */
185 template<class CycleDataType>
186 INLINE const CycleDataType *CycleDataWriter<CycleDataType>::
187 operator -> () const {
188  nassertr(_pointer != nullptr, _cycler->cheat());
189  return _pointer;
190 }
191 
192 /**
193  * This allows the CycleDataWriter to be passed to any function that expects a
194  * CycleDataType pointer.
195  */
196 template<class CycleDataType>
198 operator CycleDataType * () {
199  nassertr(_pointer != nullptr, _cycler->cheat());
200  return _pointer;
201 }
202 
203 /**
204  * Returns the Thread pointer of the currently-executing thread, as passed to
205  * the constructor of this object.
206  */
207 template<class CycleDataType>
209 get_current_thread() const {
210  return _current_thread;
211 }
212 
213 #else // !DO_PIPELINING
214 // This is the trivial, do-nothing implementation.
215 
216 /**
217  *
218  */
219 template<class CycleDataType>
222  _pointer = cycler.cheat();
223 }
224 
225 /**
226  *
227  */
228 template<class CycleDataType>
231  _pointer = cycler.cheat();
232 }
233 
234 /**
235  *
236  */
237 template<class CycleDataType>
239 CycleDataWriter(PipelineCycler<CycleDataType> &, CycleDataType *locked_cdata,
240  Thread *) {
241  _pointer = locked_cdata;
242 }
243 
244 /**
245  *
246  */
247 template<class CycleDataType>
250  _pointer(copy._pointer)
251 {
252 }
253 
254 /**
255  *
256  */
257 template<class CycleDataType>
260  _pointer = copy._pointer;
261 }
262 
263 /**
264  * This flavor of the constructor elevates the pointer from the
265  * CycleDataLockedReader from a read to a write pointer (and invalidates the
266  * reader).
267  */
268 template<class CycleDataType>
272  _pointer((CycleDataType *)take_from.take_pointer())
273 {
274 }
275 
276 /**
277  * This flavor of the constructor elevates the pointer from the
278  * CycleDataLockedReader from a read to a write pointer (and invalidates the
279  * reader). It also propagates the pointer back upstream; see
280  * PipelineCycler::write_upstream().
281  */
282 template<class CycleDataType>
286  bool force_to_0) :
287  _pointer((CycleDataType *)take_from.take_pointer())
288 {
289 }
290 
291 /**
292  *
293  */
294 template<class CycleDataType>
297 }
298 
299 /**
300  * This provides an indirect member access to the actual CycleData data.
301  */
302 template<class CycleDataType>
303 INLINE CycleDataType *CycleDataWriter<CycleDataType>::
305  return _pointer;
306 }
307 
308 /**
309  * This provides an indirect member access to the actual CycleData data.
310  */
311 template<class CycleDataType>
312 INLINE const CycleDataType *CycleDataWriter<CycleDataType>::
313 operator -> () const {
314  return _pointer;
315 }
316 
317 /**
318  * This allows the CycleDataWriter to be passed to any function that expects a
319  * CycleDataType pointer.
320  */
321 template<class CycleDataType>
323 operator CycleDataType * () {
324  return _pointer;
325 }
326 
327 /**
328  * Returns the Thread pointer of the currently-executing thread, as passed to
329  * the constructor of this object.
330  */
331 template<class CycleDataType>
334  return Thread::get_current_thread();
335 }
336 
337 #endif // DO_PIPELINING
338 #endif // CPPPARSER
This class maintains different copies of a page of data between stages of the graphics pipeline (or a...
Thread * get_current_thread() const
Returns the Thread pointer of the currently-executing thread, as passed to the constructor of this ob...
CycleDataType * cheat() const
Returns a pointer without counting it.
const CycleDataType * take_pointer()
This is intended to be called only from CycleDataWriter when it elevates the pointer from read to wri...
This template class calls PipelineCycler::read() in the constructor and PipelineCycler::release_read(...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
CycleDataType * operator ->()
This provides an indirect member access to the actual CycleData data.
A thread; that is, a lightweight process.
Definition: thread.h:46