Panda3D
Loading...
Searching...
No Matches
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 */
17INLINE PipelineCyclerTrivialImpl::
18PipelineCyclerTrivialImpl(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 */
40
41/**
42 * Release the overall lock on the cycler that was grabbed via acquire().
43 */
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 */
58read_unlocked(Thread *) const {
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 */
72read(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 */
85increment_read(const CycleData *) const {
86}
87
88/**
89 * Releases a pointer previously obtained via a call to read().
90 */
92release_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 */
107write(Thread *) {
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 */
136write_upstream(bool, Thread *) {
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 */
150elevate_read(const CycleData *, Thread *) {
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 */
164elevate_read_upstream(const CycleData *, bool, Thread *) {
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 */
179
180/**
181 * Releases a pointer previously obtained via a call to write().
182 */
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 */
201read_stage_unlocked(int) const {
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 */
215read_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 */
227release_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 */
237write_stage(int, Thread *) {
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 */
252write_stage_upstream(int, bool, Thread *) {
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 */
266elevate_read_stage(int, const CycleData *, Thread *) {
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 */
280elevate_read_stage_upstream(int, const CycleData *, bool, Thread *) {
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 */
294
295/**
296 * Returns the type of object that owns this cycler, as reported by
297 * CycleData::get_parent_type().
298 */
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 */
311cheat() 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 */
324get_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 */
334get_write_count() const {
335 return 0;
336}
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:76
This class manages a staged pipeline of data, for instance the render pipeline, so that each stage of...
Definition pipeline.h:38
A thread; that is, a lightweight process.
Definition thread.h:46
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
CycleData * cheat() const
Returns a pointer without counting it.
void release_write_stage(int pipeline_stage, CycleData *pointer)
Releases a pointer previously obtained via a call to write_stage().
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.
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 release()
Release the overall lock on the cycler that was grabbed via acquire().
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...
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...
void release_write(CycleData *pointer)
Releases a pointer previously obtained via a call to write().
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...
int get_num_stages()
Returns the number of stages in 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...
void release_read_stage(int pipeline_stage, const CycleData *pointer) const
Releases a pointer previously obtained via a call to read_stage().
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 increment_read(const CycleData *pointer) const
Increments the count on a pointer previously retrieved by read(); now the pointer will need to be rel...
int get_write_count() const
Returns the number of handles currently outstanding to read the current stage of the data.
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 acquire(Thread *current_thread=nullptr)
Grabs an overall lock on the cycler.
int get_read_count() const
Returns the number of handles currently outstanding to read the current stage of the data.
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...
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.
TypeHandle get_parent_type() const
Returns the type of object that owns this cycler, as reported by CycleData::get_parent_type().
CycleData * elevate_read(const CycleData *pointer, 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 * write_stage(int pipeline_stage, Thread *current_thread)
Returns a pointer suitable for writing to the nth stage of the pipeline.