Panda3D
pipelineCyclerTrivialImpl.I
1 // Filename: pipelineCyclerTrivialImpl.I
2 // Created by: drose (31Jan06)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 ////////////////////////////////////////////////////////////////////
17 // Function: PipelineCyclerTrivialImpl::Constructor
18 // Access: Public
19 // Description:
20 ////////////////////////////////////////////////////////////////////
21 INLINE PipelineCyclerTrivialImpl::
22 PipelineCyclerTrivialImpl(CycleData *initial_data, Pipeline *) {
23  // In the trivial implementation, a derived class (the
24  // PipelineCycler template class) stores the CycleData object
25  // directly within itself, and since we have no data members or
26  // virtual functions, we get away with assuming the pointer is the
27  // same as the 'this' pointer.
28 
29  // If this turns out not to be true on a particular platform, we
30  // will have to store the pointer in this class, for a little bit of
31  // extra overhead.
32 #ifdef SIMPLE_STRUCT_POINTERS
33  nassertv(initial_data == (CycleData *)this);
34 #else
35  _data = initial_data;
36 #endif // SIMPLE_STRUCT_POINTERS
37 }
38 
39 ////////////////////////////////////////////////////////////////////
40 // Function: PipelineCyclerTrivialImpl::Copy Constructor
41 // Access: Private
42 // Description:
43 ////////////////////////////////////////////////////////////////////
44 INLINE PipelineCyclerTrivialImpl::
45 PipelineCyclerTrivialImpl(const PipelineCyclerTrivialImpl &) {
46  // The copy constructor for the PipelineCyclerTrivialImpl case
47  // doesn't work. Don't try to use it. The PipelineCycler template
48  // class is #ifdeffed appropriately to call the normal constructor
49  // instead.
50  nassertv(false);
51 }
52 
53 ////////////////////////////////////////////////////////////////////
54 // Function: PipelineCyclerTrivialImpl::Copy Assignment
55 // Access: Private
56 // Description:
57 ////////////////////////////////////////////////////////////////////
58 INLINE void PipelineCyclerTrivialImpl::
59 operator = (const PipelineCyclerTrivialImpl &) {
60  // The copy assignment operator for the PipelineCyclerTrivialImpl
61  // case doesn't work. Don't try to use it. The PipelineCycler
62  // template class is #ifdeffed appropriately not to call this
63  // method.
64  nassertv(false);
65 }
66 
67 ////////////////////////////////////////////////////////////////////
68 // Function: PipelineCyclerTrivialImpl::Destructor
69 // Access: Public
70 // Description:
71 ////////////////////////////////////////////////////////////////////
72 INLINE PipelineCyclerTrivialImpl::
73 ~PipelineCyclerTrivialImpl() {
74 }
75 
76 ////////////////////////////////////////////////////////////////////
77 // Function: PipelineCyclerTrivialImpl::acquire
78 // Access: Public
79 // Description: Grabs an overall lock on the cycler. Release it with
80 // a call to release(). This lock should be held while
81 // walking the list of stages.
82 ////////////////////////////////////////////////////////////////////
85 }
86 
87 ////////////////////////////////////////////////////////////////////
88 // Function: PipelineCyclerTrivialImpl::release
89 // Access: Public
90 // Description: Release the overall lock on the cycler that was
91 // grabbed via acquire().
92 ////////////////////////////////////////////////////////////////////
95 }
96 
97 ////////////////////////////////////////////////////////////////////
98 // Function: PipelineCyclerTrivialImpl::read_unlocked
99 // Access: Public
100 // Description: Returns a const CycleData pointer, filled with the
101 // data for the current stage of the pipeline as seen by
102 // this thread. No lock is made on the contents; there
103 // is no guarantee that some other thread won't modify
104 // this object's data while you are working on it.
105 // (However, the data within the returned CycleData
106 // object itself is safe from modification; if another
107 // thread modifies the data, it will perform a
108 // copy-on-write, and thereby change the pointer stored
109 // within the object.)
110 ////////////////////////////////////////////////////////////////////
113 #ifdef SIMPLE_STRUCT_POINTERS
114  return (const CycleData *)this;
115 #else
116  return _data;
117 #endif // SIMPLE_STRUCT_POINTERS
118 }
119 
120 ////////////////////////////////////////////////////////////////////
121 // Function: PipelineCyclerTrivialImpl::read
122 // Access: Public
123 // Description: Returns a const CycleData pointer, filled with the
124 // data for the current stage of the pipeline as seen by
125 // this thread. This pointer should eventually be
126 // released by calling release_read().
127 ////////////////////////////////////////////////////////////////////
129 read(Thread *) const {
130 #ifdef SIMPLE_STRUCT_POINTERS
131  return (const CycleData *)this;
132 #else
133  return _data;
134 #endif // SIMPLE_STRUCT_POINTERS
135 }
136 
137 ////////////////////////////////////////////////////////////////////
138 // Function: PipelineCyclerTrivialImpl::increment_read
139 // Access: Public
140 // Description: Increments the count on a pointer previously
141 // retrieved by read(); now the pointer will need to be
142 // released twice.
143 ////////////////////////////////////////////////////////////////////
144 INLINE void PipelineCyclerTrivialImpl::
145 increment_read(const CycleData *) const {
146 }
147 
148 ////////////////////////////////////////////////////////////////////
149 // Function: PipelineCyclerTrivialImpl::release_read
150 // Access: Public
151 // Description: Releases a pointer previously obtained via a call to
152 // read().
153 ////////////////////////////////////////////////////////////////////
154 INLINE void PipelineCyclerTrivialImpl::
155 release_read(const CycleData *) const {
156 }
157 
158 ////////////////////////////////////////////////////////////////////
159 // Function: PipelineCyclerTrivialImpl::write
160 // Access: Public
161 // Description: Returns a non-const CycleData pointer, filled with a
162 // unique copy of the data for the current stage of the
163 // pipeline as seen by this thread. This pointer may
164 // now be used to write to the data, and that copy of
165 // the data will be propagated to all later stages of the
166 // pipeline. This pointer should eventually be released
167 // by calling release_write().
168 //
169 // There may only be one outstanding write pointer on a
170 // given stage at a time, and if there is a write
171 // pointer there may be no read pointers on the same
172 // stage (but see elevate_read).
173 ////////////////////////////////////////////////////////////////////
176 #ifdef SIMPLE_STRUCT_POINTERS
177  return (CycleData *)this;
178 #else
179  return _data;
180 #endif // SIMPLE_STRUCT_POINTERS
181 }
182 
183 ////////////////////////////////////////////////////////////////////
184 // Function: PipelineCyclerTrivialImpl::write_upstream
185 // Access: Public
186 // Description: This special variant on write() will automatically
187 // propagate changes back to upstream pipeline stages.
188 // If force_to_0 is false, then it propagates back only
189 // as long as the CycleData pointers are equivalent,
190 // guaranteeing that it does not modify upstream data
191 // (other than the modification that will be performed
192 // by the code that returns this pointer). This is
193 // particularly appropriate for minor updates, where it
194 // doesn't matter much if the update is lost, such as
195 // storing a cached value.
196 //
197 // If force_to_0 is trivial, then the CycleData pointer for
198 // the current pipeline stage is propagated all the way
199 // back up to stage 0; after this call, there will be
200 // only one CycleData pointer that is duplicated in all
201 // stages between stage 0 and the current stage. This
202 // may undo some recent changes that were made
203 // independently at pipeline stage 0 (or any other
204 // upstream stage). However, it guarantees that the
205 // change that is to be applied at this pipeline stage
206 // will stick. This is slightly dangerous because of
207 // the risk of losing upstream changes; generally, this
208 // should only be done when you are confident that there
209 // are no upstream changes to be lost (for instance, for
210 // an object that has been recently created).
211 ////////////////////////////////////////////////////////////////////
214 #ifdef SIMPLE_STRUCT_POINTERS
215  return (CycleData *)this;
216 #else
217  return _data;
218 #endif // SIMPLE_STRUCT_POINTERS
219 }
220 
221 ////////////////////////////////////////////////////////////////////
222 // Function: PipelineCyclerTrivialImpl::elevate_read
223 // Access: Public
224 // Description: Elevates a currently-held read pointer into a write
225 // pointer. This may or may not change the value of the
226 // pointer. It is only valid to do this if this is the
227 // only currently-outstanding read pointer on the
228 // current stage.
229 ////////////////////////////////////////////////////////////////////
232 #ifdef SIMPLE_STRUCT_POINTERS
233  return (CycleData *)this;
234 #else
235  return _data;
236 #endif // SIMPLE_STRUCT_POINTERS
237 }
238 
239 ////////////////////////////////////////////////////////////////////
240 // Function: PipelineCyclerTrivialImpl::elevate_read_upstream
241 // Access: Public
242 // Description: Elevates a currently-held read pointer into a write
243 // pointer, like elevate_read(), but also propagates the
244 // pointer back to upstream stages, like
245 // write_upstream().
246 ////////////////////////////////////////////////////////////////////
249 #ifdef SIMPLE_STRUCT_POINTERS
250  return (CycleData *)this;
251 #else
252  return _data;
253 #endif // SIMPLE_STRUCT_POINTERS
254 }
255 
256 ////////////////////////////////////////////////////////////////////
257 // Function: PipelineCyclerTrivialImpl::increment_write
258 // Access: Public
259 // Description: Increments the count on a pointer previously
260 // retrieved by write(); now the pointer will need to be
261 // released twice.
262 ////////////////////////////////////////////////////////////////////
263 INLINE void PipelineCyclerTrivialImpl::
265 }
266 
267 ////////////////////////////////////////////////////////////////////
268 // Function: PipelineCyclerTrivialImpl::release_write
269 // Access: Public
270 // Description: Releases a pointer previously obtained via a call to
271 // write().
272 ////////////////////////////////////////////////////////////////////
273 INLINE void PipelineCyclerTrivialImpl::
275 }
276 
277 ////////////////////////////////////////////////////////////////////
278 // Function: PipelineCyclerTrivialImpl::get_num_stages
279 // Access: Public
280 // Description: Returns the number of stages in the pipeline.
281 ////////////////////////////////////////////////////////////////////
284  return 1;
285 }
286 
287 ////////////////////////////////////////////////////////////////////
288 // Function: PipelineCyclerTrivialImpl::read_stage_unlocked
289 // Access: Public
290 // Description: Returns a const CycleData pointer, filled with the
291 // data for the indicated stage of the pipeline. As in
292 // read_unlocked(), no lock is held on the returned
293 // pointer.
294 ////////////////////////////////////////////////////////////////////
297 #ifdef SIMPLE_STRUCT_POINTERS
298  return (const CycleData *)this;
299 #else
300  return _data;
301 #endif // SIMPLE_STRUCT_POINTERS
302 }
303 
304 ////////////////////////////////////////////////////////////////////
305 // Function: PipelineCyclerTrivialImpl::read_stage
306 // Access: Public
307 // Description: Returns a const CycleData pointer, filled with the
308 // data for the indicated pipeline stage. This pointer
309 // should eventually be released by calling
310 // release_read().
311 ////////////////////////////////////////////////////////////////////
313 read_stage(int, Thread *) const {
314 #ifdef SIMPLE_STRUCT_POINTERS
315  return (const CycleData *)this;
316 #else
317  return _data;
318 #endif // SIMPLE_STRUCT_POINTERS
319 }
320 
321 ////////////////////////////////////////////////////////////////////
322 // Function: PipelineCyclerTrivialImpl::release_read_stage
323 // Access: Public
324 // Description: Releases a pointer previously obtained via a call to
325 // read_stage().
326 ////////////////////////////////////////////////////////////////////
327 INLINE void PipelineCyclerTrivialImpl::
328 release_read_stage(int, const CycleData *) const {
329 }
330 
331 ////////////////////////////////////////////////////////////////////
332 // Function: PipelineCyclerTrivialImpl::write_stage
333 // Access: Public
334 // Description: Returns a pointer suitable for writing to the nth
335 // stage of the pipeline. This is for special
336 // applications that need to update the entire pipeline
337 // at once (for instance, to remove an invalid pointer).
338 // This pointer should later be released with
339 // release_write_stage().
340 ////////////////////////////////////////////////////////////////////
343 #ifdef SIMPLE_STRUCT_POINTERS
344  return (CycleData *)this;
345 #else
346  return _data;
347 #endif // SIMPLE_STRUCT_POINTERS
348 }
349 
350 ////////////////////////////////////////////////////////////////////
351 // Function: PipelineCyclerTrivialImpl::write_stage_upstream
352 // Access: Public
353 // Description: Returns a pointer suitable for writing to the nth
354 // stage of the pipeline. This is for special
355 // applications that need to update the entire pipeline
356 // at once (for instance, to remove an invalid pointer).
357 // This pointer should later be released with
358 // release_write_stage().
359 ////////////////////////////////////////////////////////////////////
362 #ifdef SIMPLE_STRUCT_POINTERS
363  return (CycleData *)this;
364 #else
365  return _data;
366 #endif // SIMPLE_STRUCT_POINTERS
367 }
368 
369 ////////////////////////////////////////////////////////////////////
370 // Function: PipelineCyclerTrivialImpl::elevate_read_stage
371 // Access: Public
372 // Description: Elevates a currently-held read pointer into a write
373 // pointer. This may or may not change the value of the
374 // pointer. It is only valid to do this if this is the
375 // only currently-outstanding read pointer on the
376 // current stage.
377 ////////////////////////////////////////////////////////////////////
380 #ifdef SIMPLE_STRUCT_POINTERS
381  return (CycleData *)this;
382 #else
383  return _data;
384 #endif // SIMPLE_STRUCT_POINTERS
385 }
386 
387 ////////////////////////////////////////////////////////////////////
388 // Function: PipelineCyclerTrivialImpl::elevate_read_stage_upstream
389 // Access: Public
390 // Description: Elevates a currently-held read pointer into a write
391 // pointer. This may or may not change the value of the
392 // pointer. It is only valid to do this if this is the
393 // only currently-outstanding read pointer on the
394 // current stage.
395 ////////////////////////////////////////////////////////////////////
398 #ifdef SIMPLE_STRUCT_POINTERS
399  return (CycleData *)this;
400 #else
401  return _data;
402 #endif // SIMPLE_STRUCT_POINTERS
403 }
404 
405 ////////////////////////////////////////////////////////////////////
406 // Function: PipelineCyclerTrivialImpl::release_write_stage
407 // Access: Public
408 // Description: Releases a pointer previously obtained via a call to
409 // write_stage().
410 ////////////////////////////////////////////////////////////////////
411 INLINE void PipelineCyclerTrivialImpl::
413 }
414 
415 ////////////////////////////////////////////////////////////////////
416 // Function: PipelineCyclerTrivialImpl::get_parent_type
417 // Access: Public
418 // Description: Returns the type of object that owns this cycler, as
419 // reported by CycleData::get_parent_type().
420 ////////////////////////////////////////////////////////////////////
423  return cheat()->get_parent_type();
424 }
425 
426 ////////////////////////////////////////////////////////////////////
427 // Function: PipelineCyclerTrivialImpl::cheat
428 // Access: Public
429 // Description: Returns a pointer without counting it. This is only
430 // intended for use as the return value for certain
431 // nassertr() functions, so the application can recover
432 // after a failure to manage the read and write pointers
433 // correctly. You should never call this function
434 // directly.
435 ////////////////////////////////////////////////////////////////////
437 cheat() const {
438 #ifdef SIMPLE_STRUCT_POINTERS
439  return (CycleData *)this;
440 #else
441  return _data;
442 #endif // SIMPLE_STRUCT_POINTERS
443 }
444 
445 ////////////////////////////////////////////////////////////////////
446 // Function: PipelineCyclerTrivialImpl::get_read_count
447 // Access: Public
448 // Description: Returns the number of handles currently outstanding
449 // to read the current stage of the data. This should
450 // only be used for debugging purposes.
451 ////////////////////////////////////////////////////////////////////
453 get_read_count() const {
454  return 0;
455 }
456 
457 ////////////////////////////////////////////////////////////////////
458 // Function: PipelineCyclerTrivialImpl::get_write_count
459 // Access: Public
460 // Description: Returns the number of handles currently outstanding
461 // to read the current stage of the data. This will
462 // normally only be either 0 or 1. This should only be
463 // used for debugging purposes.
464 ////////////////////////////////////////////////////////////////////
467  return 0;
468 }
469 
CycleData * write_stage(int pipeline_stage, Thread *current_thread)
Returns a pointer suitable for writing to the nth stage of the pipeline.
CycleData * write_upstream(bool force_to_0, Thread *current_thread)
This special variant on write() will automatically propagate changes back to upstream pipeline stages...
const CycleData * read_stage(int pipeline_stage, Thread *current_thread) const
Returns a const CycleData pointer, filled with the data for the indicated pipeline stage...
void increment_read(const CycleData *pointer) const
Increments the count on a pointer previously retrieved by read(); now the pointer will need to be rel...
A single page of data maintained by a PipelineCycler.
Definition: cycleData.h:50
virtual TypeHandle get_parent_type() const
Returns the type of the container that owns the CycleData.
Definition: cycleData.cxx:91
This is the trivial, non-threaded implementation of PipelineCyclerBase.
CycleData * elevate_read_stage(int pipeline_stage, const CycleData *pointer, Thread *current_thread)
Elevates a currently-held read pointer into a write pointer.
CycleData * write(Thread *current_thread)
Returns a non-const CycleData pointer, filled with a unique copy of the data for the current stage of...
const CycleData * read_stage_unlocked(int pipeline_stage) const
Returns a const CycleData pointer, filled with the data for the indicated stage of the pipeline...
void increment_write(CycleData *pointer) const
Increments the count on a pointer previously retrieved by write(); now the pointer will need to be re...
void release_write_stage(int pipeline_stage, CycleData *pointer)
Releases a pointer previously obtained via a call to write_stage().
CycleData * write_stage_upstream(int pipeline_stage, bool force_to_0, Thread *current_thread)
Returns a pointer suitable for writing to the nth stage of the pipeline.
void release_read_stage(int pipeline_stage, const CycleData *pointer) const
Releases a pointer previously obtained via a call to read_stage().
TypeHandle get_parent_type() const
Returns the type of object that owns this cycler, as reported by CycleData::get_parent_type().
int get_read_count() const
Returns the number of handles currently outstanding to read the current stage of the data...
CycleData * elevate_read(const CycleData *pointer, Thread *current_thread)
Elevates a currently-held read pointer into a write pointer.
This class manages a staged pipeline of data, for instance the render pipeline, so that each stage of...
Definition: pipeline.h:41
void release()
Release the overall lock on the cycler that was grabbed via acquire().
void release_write(CycleData *pointer)
Releases a pointer previously obtained via a call to write().
CycleData * cheat() const
Returns a pointer without counting it.
A thread; that is, a lightweight process.
Definition: thread.h:51
const CycleData * read(Thread *current_thread) const
Returns a const CycleData pointer, filled with the data for the current stage of the pipeline as seen...
int get_num_stages()
Returns the number of stages in the pipeline.
void acquire(Thread *current_thread=NULL)
Grabs an overall lock on the cycler.
int get_write_count() const
Returns the number of handles currently outstanding to read the current stage of the data...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
CycleData * elevate_read_stage_upstream(int pipeline_stage, const CycleData *pointer, bool force_to_0, Thread *current_thread)
Elevates a currently-held read pointer into a write pointer.
void release_read(const CycleData *pointer) const
Releases a pointer previously obtained via a call to read().
CycleData * elevate_read_upstream(const CycleData *pointer, bool force_to_0, Thread *current_thread)
Elevates a currently-held read pointer into a write pointer, like elevate_read(), but also propagates...
const CycleData * read_unlocked(Thread *current_thread) const
Returns a const CycleData pointer, filled with the data for the current stage of the pipeline as seen...