Free Electron
SurfaceAccessorCached.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __surface_SurfaceAccessorCached_h__
8 #define __surface_SurfaceAccessorCached_h__
9 
10 #define FE_SACH_DEBUG FALSE
11 #define FE_SACH_USE_INSTANCE FALSE
12 
13 namespace fe
14 {
15 namespace ext
16 {
17 
18 /**************************************************************************//**
19  @brief Accessor with Deferred Writes
20 
21  @ingroup surface
22 *//***************************************************************************/
23 class FE_DL_EXPORT SurfaceAccessorCached:
24  virtual public SurfaceAccessorBase,
25  public CastableAs<SurfaceAccessorCached>
26 {
27  public:
29 virtual ~SurfaceAccessorCached(void);
30 
31  using SurfaceAccessorBase::set;
32  using SurfaceAccessorBase::append;
33  using SurfaceAccessorBase::spatialVector;
34 
35  //* as SurfaceAccessorI
36 virtual String type(void) const
37  { return m_spAccessorChain->type(); }
38 
39 virtual U32 count(void) const
40  { return m_spAccessorChain->count(); }
41 virtual U32 subCount(U32 a_index) const
42  { return m_spAccessorChain->subCount(a_index); }
43 
44 virtual void set(U32 a_index,U32 subIndex,String a_string)
45  {
46  if(!m_changed[a_index])
47  {
48 #if FE_SACH_USE_INSTANCE
49  m_value[a_index].create<String>(typeMaster());
50 #endif
51  m_changed[a_index]=TRUE;
52  if(m_attrType==e_none)
53  {
54  m_attrType=e_string;
55 #if !FE_SACH_USE_INSTANCE
56  m_string.resize(m_size);
57 #endif
58  }
59  FEASSERT(m_attrType==e_string);
60  }
61 #if FE_SACH_USE_INSTANCE
62  m_value[a_index].cast<String>()=a_string;
63 #else
64  m_string[a_index]=a_string;
65 #endif
66  }
67 virtual String string(U32 a_index,U32 a_subIndex=0)
68  {
69  if(m_changed[a_index])
70  {
71  FEASSERT(m_attrType==e_string);
72 #if FE_SACH_USE_INSTANCE
73  return m_value[a_index].cast<String>();
74 #else
75  return m_string[a_index];
76 #endif
77  }
78  return m_spAccessorChain->string(
79  a_index,a_subIndex);
80  }
81 
82 virtual void set(U32 a_index,U32 a_subIndex,I32 a_integer)
83  {
84  if(!m_changed[a_index])
85  {
86 #if FE_SACH_USE_INSTANCE
87  m_value[a_index].create<I32>(typeMaster());
88 #endif
89  m_changed[a_index]=TRUE;
90  if(m_attrType==e_none)
91  {
92  m_attrType=e_integer;
93 #if !FE_SACH_USE_INSTANCE
94  m_integer.resize(m_size);
95 #endif
96  }
97  FEASSERT(m_attrType==e_integer);
98  }
99 #if FE_SACH_USE_INSTANCE
100  m_value[a_index].cast<I32>()=a_integer;
101 #else
102  m_integer[a_index]=a_integer;
103 #endif
104  }
105 virtual I32 integer(U32 a_index,U32 a_subIndex=0)
106  {
107  //* TODO should be able to change vertex indexes
108 
109  if(m_element!=
110  SurfaceAccessibleI::e_primitiveGroup &&
111  m_attribute!=
112  SurfaceAccessibleI::e_vertices &&
113  m_attribute!=
114  SurfaceAccessibleI::e_properties &&
115  m_changed[a_index])
116  {
117  FEASSERT(m_attrType==e_integer);
118 #if FE_SACH_USE_INSTANCE
119  return m_value[a_index].cast<I32>();
120 #else
121  return m_integer[a_index];
122 #endif
123  }
124  return m_spAccessorChain->integer(
125  a_index,a_subIndex);
126  }
127  //* DANGER
128 virtual I32 duplicate(U32 a_index,U32 a_subIndex=0)
129  { return m_spAccessorChain->duplicate(
130  a_index,a_subIndex); }
131  //* DANGER
132 virtual void append(U32 a_index,I32 a_integer)
133  { m_spAccessorChain->append(a_index,a_integer); }
134  //* DANGER
135 virtual void remove(U32 a_index,I32 a_integer)
136  { m_spAccessorChain->remove(a_index,a_integer); }
137 
138 virtual void set(U32 a_index,U32 a_subIndex,Real a_real)
139  {
140  if(!m_changed[a_index])
141  {
142 #if FE_SACH_USE_INSTANCE
143  m_value[a_index].create<Real>(typeMaster());
144 #endif
145  m_changed[a_index]=TRUE;
146  if(m_attrType==e_none)
147  {
148  m_attrType=e_real;
149 #if !FE_SACH_USE_INSTANCE
150  m_real.resize(m_size);
151 #endif
152  }
153  FEASSERT(m_attrType==e_real);
154  }
155 #if FE_SACH_USE_INSTANCE
156  m_value[a_index].cast<Real>()=a_real;
157 #else
158  m_real[a_index]=a_real;
159 #endif
160  }
161 virtual Real real(U32 a_index,U32 a_subIndex=0)
162  {
163  if(m_changed[a_index])
164  {
165  FEASSERT(m_attrType==e_real);
166 #if FE_SACH_USE_INSTANCE
167  return m_value[a_index].cast<Real>();
168 #else
169  return m_real[a_index];
170 #endif
171  }
172  return m_spAccessorChain->real(a_index,a_subIndex);
173  }
174 
175 virtual void set(U32 a_index,U32 a_subIndex,
176  const SpatialVector& a_spatialVector)
177  {
178  const U32 index=trueIndex(a_index,a_subIndex);
179 #if FE_SACH_DEBUG
180  feLog("SurfaceAccessorCached::set"
181  " \"%s\" %d %d (%d) ch %d %s\n",
182  m_attrName.c_str(),
183  a_index,a_subIndex,index,
184  I32(m_changed[index]),
185  c_print(a_spatialVector));
186 #endif
187  if(!m_changed[index])
188  {
189 #if FE_SACH_DEBUG
190  feLog(" create %d\n",index);
191 #endif
192  m_changed[index]=TRUE;
193  if(m_attrType==e_none)
194  {
195  m_attrType=e_spatialVector;
196 #if !FE_SACH_USE_INSTANCE
197  m_spatialVector.resize(m_size);
198 #endif
199  if(m_element==SurfaceAccessibleI::
200  e_primitiveGroup ||
201  m_attribute==
202  SurfaceAccessibleI::e_vertices ||
203  m_attribute==
204  SurfaceAccessibleI::e_properties)
205  {
206  m_integer.resize(m_size);
207  m_subIndex.resize(m_size);
208  }
209  }
210  FEASSERT(m_attrType==e_spatialVector);
211 #if FE_SACH_USE_INSTANCE
212  m_value[index].create<SpatialVector>(
213  typeMaster());
214 #endif
215  if(m_element==SurfaceAccessibleI::
216  e_primitiveGroup ||
217  m_attribute==
218  SurfaceAccessibleI::e_vertices ||
219  m_attribute==
220  SurfaceAccessibleI::e_properties)
221  {
222  m_integer[index]=a_index;
223  m_subIndex[index]=a_subIndex;
224  }
225  }
226 #if FE_SACH_USE_INSTANCE
227  m_value[index].cast<SpatialVector>()=
228  a_spatialVector;
229 #else
230  m_spatialVector[index]=a_spatialVector;
231 #endif
232  }
233 virtual SpatialVector spatialVector(U32 a_index,U32 a_subIndex=0)
234  {
235  const U32 index=trueIndex(a_index,a_subIndex);
236 #if FE_SACH_DEBUG
237  feLog("SurfaceAccessorCached::spatialVector"
238  " \"%s\" %d %d (%d) ch %d\n",
239  m_attrName.c_str(),
240  a_index,a_subIndex,index,
241  I32(m_changed[index]));
242 #endif
243  if(m_changed[index])
244  {
245  FEASSERT(m_attrType==e_spatialVector);
246 #if FE_SACH_DEBUG
247  feLog(" override\n");
248 #endif
249 #if FE_SACH_USE_INSTANCE
250  return m_value[index].cast<SpatialVector>();
251 #else
252  return m_spatialVector[index];
253 #endif
254  }
255  return m_spAccessorChain->spatialVector(
256  a_index,a_subIndex);
257  }
258 
259  void setAccessorChain(sp<SurfaceAccessorI> a_spAccessorI)
260  {
261  m_spAccessorChain=a_spAccessorI;
262  m_element=m_spAccessorChain->element();
263  m_attribute=m_spAccessorChain->attribute();
264  m_attrName=m_spAccessorChain->attributeName();
265  m_count=m_spAccessorChain->count();
266  m_size=m_count;
267  if(m_element==
268  SurfaceAccessibleI::e_primitiveGroup ||
269  m_attribute==SurfaceAccessibleI::e_vertices
270  || m_attribute==
271  SurfaceAccessibleI::e_properties)
272  {
273  m_size=0;
274  for(U32 index=0;index<m_count;index++)
275  {
276  m_size+=m_spAccessorChain->subCount(index);
277  }
278  m_count=0;
279  }
280  m_changed.resize(m_size);
281  for(U32 m=0;m<m_size;m++)
282  {
283  m_changed[m]=FALSE;
284  }
285 #if FE_SACH_USE_INSTANCE
286  m_value.resize(m_size);
287 #endif
288  }
289 
290  private:
291  U32 trueIndex(U32 a_index,U32 a_subIndex)
292  {
293  if(m_element==
294  SurfaceAccessibleI::e_primitiveGroup ||
295  m_attribute==SurfaceAccessibleI::e_vertices)
296  {
297  const U32 index=m_spAccessorChain->integer(
298  a_index,a_subIndex);
299  if(index>=m_count)
300  {
301  m_count=index+1;
302 
303  FEASSERT(index<m_size);
304 #if FALSE
305  if(index>=m_size)
306  {
307  //* tweak
308  const U32 newSize=index*1.1+10;
309 
310  m_value.resize(newSize);
311  m_changed.resize(newSize);
312  for(;m_size<newSize;m_size++)
313  {
314  m_changed[m_size]=FALSE;
315  }
316 
317  feLog("SurfaceAccessorCached::trueIndex"
318  " \"%s\" resized %d\n",
319  m_attrName.c_str(),m_size);
320  }
321 #endif
322  }
323  return index;
324  }
325  return a_index;
326  }
327 
328  enum AttrType
329  {
330  e_none,
331  e_string,
332  e_integer,
333  e_real,
334  e_spatialVector
335  };
336  sp<TypeMaster> typeMaster(void)
337  { return registry()->master()->typeMaster(); }
338 
339  sp<SurfaceAccessorI> m_spAccessorChain;
340 
341  AttrType m_attrType;
342  U32 m_count;
343  U32 m_size;
344  Array<I32> m_changed;
345 
346 #if FE_SACH_USE_INSTANCE
347  Array<Instance> m_value;
348 #else
349  Array<String> m_string;
350  Array<Real> m_real;
351  Array<SpatialVector> m_spatialVector;
352 #endif
353  Array<I32> m_integer; //* also primitive index
354  Array<I32> m_subIndex; //* for primitive index
355 };
356 
357 } /* namespace ext */
358 } /* namespace fe */
359 
360 #endif /* __surface_SurfaceAccessorCached_h__ */
Surface Element Access and Alteration.
Definition: SurfaceAccessibleI.h:22
Accessor with Deferred Writes.
Definition: SurfaceAccessorCached.h:23
kernel
Definition: namespace.dox:3
Common Functionality for Accessor Surface.
Definition: SurfaceAccessorBase.h:20
Automatically reference-counted string container.
Definition: String.h:128
Intrusive Smart Pointer.
Definition: src/core/ptr.h:53
sp< Master > master(void) const
Access the Master (ptr may not be valid)
Definition: Registry.cc:98
Per-class participation non-RTTI fallback dynamic casting mechanism.
Definition: Castable.h:192