Panda3D
pipelineCyclerTrivialImpl.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 pipelineCyclerTrivialImpl.I
10  * @author drose
11  * @date 2006-01-31
12  */
13 
14 /**
15  *
16  */
17 INLINE PipelineCyclerTrivialImpl::
18 PipelineCyclerTrivialImpl(CycleData *initial_data, Pipeline *) {
19  // In the trivial implementation, a derived class (the PipelineCycler
20  // template class) stores the CycleData object directly within itself, and
21  // since we have no data members or virtual functions, we get away with
22  // assuming the pointer is the same as the 'this' pointer.
23 
24  // If this turns out not to be true on a particular platform, we will have
25  // to store the pointer in this class, for a little bit of extra overhead.
26 #ifdef SIMPLE_STRUCT_POINTERS
27  nassertv(initial_data == (CycleData *)this);
28 #else
29  _data = initial_data;
30 #endif // SIMPLE_STRUCT_POINTERS
31 }
32 
33 /**
34  * Grabs an overall lock on the cycler. Release it with a call to release().
35  * This lock should be held while walking the list of stages.
36  */
39 }
40 
41 /**
42  * Release the overall lock on the cycler that was grabbed via acquire().
43  */
46 }
47 
48 /**
49  * Returns a const CycleData pointer, filled with the data for the current
50  * stage of the pipeline as seen by this thread. No lock is made on the
51  * contents; there is no guarantee that some other thread won't modify this
52  * object's data while you are working on it. (However, the data within the
53  * returned CycleData object itself is safe from modification; if another
54  * thread modifies the data, it will perform a copy-on-write, and thereby
55  * change the pointer stored within the object.)
56  */
59 #ifdef SIMPLE_STRUCT_POINTERS
60  return (const CycleData *)this;
61 #else
62  return _data;
63 #endif // SIMPLE_STRUCT_POINTERS
64 }
65 
66 /**
67  * Returns a const CycleData pointer, filled with the data for the current
68  * stage of the pipeline as seen by this thread. This pointer should
69  * eventually be released by calling release_read().
70  */
72 read(Thread *) const {
73 #ifdef SIMPLE_STRUCT_POINTERS
74  return (const CycleData *)this;
75 #else
76  return _data;
77 #endif // SIMPLE_STRUCT_POINTERS
78 }
79 
80 /**
81  * Increments the count on a pointer previously retrieved by read(); now the
82  * pointer will need to be released twice.
83  */
85 increment_read(const CycleData *) const {
86 }
87 
88 /**
89  * Releases a pointer previously obtained via a call to read().
90  */
92 release_read(const CycleData *) const {
93 }
94 
95 /**
96  * Returns a non-const CycleData pointer, filled with a unique copy of the
97  * data for the current stage of the pipeline as seen by this thread. This
98  * pointer may now be used to write to the data, and that copy of the data
99  * will be propagated to all later stages of the pipeline. This pointer
100  * should eventually be released by calling release_write().
101  *
102  * There may only be one outstanding write pointer on a given stage at a time,
103  * and if there is a write pointer there may be no read pointers on the same
104  * stage (but see elevate_read).
105  */
108 #ifdef SIMPLE_STRUCT_POINTERS
109  return (CycleData *)this;
110 #else
111  return _data;
112 #endif // SIMPLE_STRUCT_POINTERS
113 }
114 
115 /**
116  * This special variant on write() will automatically propagate changes back
117  * to upstream pipeline stages. If force_to_0 is false, then it propagates
118  * back only as long as the CycleData pointers are equivalent, guaranteeing
119  * that it does not modify upstream data (other than the modification that
120  * will be performed by the code that returns this pointer). This is
121  * particularly appropriate for minor updates, where it doesn't matter much if
122  * the update is lost, such as storing a cached value.
123  *
124  * If force_to_0 is trivial, then the CycleData pointer for the current
125  * pipeline stage is propagated all the way back up to stage 0; after this
126  * call, there will be only one CycleData pointer that is duplicated in all
127  * stages between stage 0 and the current stage. This may undo some recent
128  * changes that were made independently at pipeline stage 0 (or any other
129  * upstream stage). However, it guarantees that the change that is to be
130  * applied at this pipeline stage will stick. This is slightly dangerous
131  * because of the risk of losing upstream changes; generally, this should only
132  * be done when you are confident that there are no upstream changes to be
133  * lost (for instance, for an object that has been recently created).
134  */
137 #ifdef SIMPLE_STRUCT_POINTERS
138  return (CycleData *)this;
139 #else
140  return _data;
141 #endif // SIMPLE_STRUCT_POINTERS
142 }
143 
144 /**
145  * Elevates a currently-held read pointer into a write pointer. This may or
146  * may not change the value of the pointer. It is only valid to do this if
147  * this is the only currently-outstanding read pointer on the current stage.
148  */
151 #ifdef SIMPLE_STRUCT_POINTERS
152  return (CycleData *)this;
153 #else
154  return _data;
155 #endif // SIMPLE_STRUCT_POINTERS
156 }
157 
158 /**
159  * Elevates a currently-held read pointer into a write pointer, like
160  * elevate_read(), but also propagates the pointer back to upstream stages,
161  * like write_upstream().
162  */
165 #ifdef SIMPLE_STRUCT_POINTERS
166  return (CycleData *)this;
167 #else
168  return _data;
169 #endif // SIMPLE_STRUCT_POINTERS
170 }
171 
172 /**
173  * Increments the count on a pointer previously retrieved by write(); now the
174  * pointer will need to be released twice.
175  */
176 INLINE void PipelineCyclerTrivialImpl::
178 }
179 
180 /**
181  * Releases a pointer previously obtained via a call to write().
182  */
183 INLINE void PipelineCyclerTrivialImpl::
185 }
186 
187 /**
188  * Returns the number of stages in the pipeline.
189  */
192  return 1;
193 }
194 
195 /**
196  * Returns a const CycleData pointer, filled with the data for the indicated
197  * stage of the pipeline. As in read_unlocked(), no lock is held on the
198  * returned pointer.
199  */
202 #ifdef SIMPLE_STRUCT_POINTERS
203  return (const CycleData *)this;
204 #else
205  return _data;
206 #endif // SIMPLE_STRUCT_POINTERS
207 }
208 
209 /**
210  * Returns a const CycleData pointer, filled with the data for the indicated
211  * pipeline stage. This pointer should eventually be released by calling
212  * release_read().
213  */
215 read_stage(int, Thread *) const {
216 #ifdef SIMPLE_STRUCT_POINTERS
217  return (const CycleData *)this;
218 #else
219  return _data;
220 #endif // SIMPLE_STRUCT_POINTERS
221 }
222 
223 /**
224  * Releases a pointer previously obtained via a call to read_stage().
225  */
226 INLINE void PipelineCyclerTrivialImpl::
227 release_read_stage(int, const CycleData *) const {
228 }
229 
230 /**
231  * Returns a pointer suitable for writing to the nth stage of the pipeline.
232  * This is for special applications that need to update the entire pipeline at
233  * once (for instance, to remove an invalid pointer). This pointer should
234  * later be released with release_write_stage().
235  */
238 #ifdef SIMPLE_STRUCT_POINTERS
239  return (CycleData *)this;
240 #else
241  return _data;
242 #endif // SIMPLE_STRUCT_POINTERS
243 }
244 
245 /**
246  * Returns a pointer suitable for writing to the nth stage of the pipeline.
247  * This is for special applications that need to update the entire pipeline at
248  * once (for instance, to remove an invalid pointer). This pointer should
249  * later be released with release_write_stage().
250  */
253 #ifdef SIMPLE_STRUCT_POINTERS
254  return (CycleData *)this;
255 #else
256  return _data;
257 #endif // SIMPLE_STRUCT_POINTERS
258 }
259 
260 /**
261  * Elevates a currently-held read pointer into a write pointer. This may or
262  * may not change the value of the pointer. It is only valid to do this if
263  * this is the only currently-outstanding read pointer on the current stage.
264  */
267 #ifdef SIMPLE_STRUCT_POINTERS
268  return (CycleData *)this;
269 #else
270  return _data;
271 #endif // SIMPLE_STRUCT_POINTERS
272 }
273 
274 /**
275  * Elevates a currently-held read pointer into a write pointer. This may or
276  * may not change the value of the pointer. It is only valid to do this if
277  * this is the only currently-outstanding read pointer on the current stage.
278  */
281 #ifdef SIMPLE_STRUCT_POINTERS
282  return (CycleData *)this;
283 #else
284  return _data;
285 #endif // SIMPLE_STRUCT_POINTERS
286 }
287 
288 /**
289  * Releases a pointer previously obtained via a call to write_stage().
290  */
291 INLINE void PipelineCyclerTrivialImpl::
293 }
294 
295 /**
296  * Returns the type of object that owns this cycler, as reported by
297  * CycleData::get_parent_type().
298  */
301  return cheat()->get_parent_type();
302 }
303 
304 /**
305  * Returns a pointer without counting it. This is only intended for use as
306  * the return value for certain nassertr() functions, so the application can
307  * recover after a failure to manage the read and write pointers correctly.
308  * You should never call this function directly.
309  */
311 cheat() const {
312 #ifdef SIMPLE_STRUCT_POINTERS
313  return (CycleData *)this;
314 #else
315  return _data;
316 #endif // SIMPLE_STRUCT_POINTERS
317 }
318 
319 /**
320  * Returns the number of handles currently outstanding to read the current
321  * stage of the data. This should only be used for debugging purposes.
322  */
324 get_read_count() const {
325  return 0;
326 }
327 
328 /**
329  * Returns the number of handles currently outstanding to read the current
330  * stage of the data. This will normally only be either 0 or 1. This should
331  * only be used for debugging purposes.
332  */
335  return 0;
336 }
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:47
virtual TypeHandle get_parent_type() const
Returns the type of the container that owns the CycleData.
Definition: cycleData.cxx:76
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.
void acquire(Thread *current_thread=nullptr)
Grabs an overall lock on the cycler.
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:38
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:46
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.
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:81
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...