gwnavruntime/blob/baseblobbuilder.h Source File

baseblobbuilder.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 
8 #pragma once
9 
10 
13 #include <assert.h>
14 
15 
16 namespace Kaim
17 {
18 
19 
26 template<class T>
27 class BaseBlobBuilder : public NewOverrideBase<MemStat_BlobBuilder>
28 {
29 public:
30  typedef T BlobType;
31 
32  BaseBlobBuilder(KyInt32 memStat = Stat_Default_Mem, MemoryHeap* heap = nullptr)
33  : m_blobBuffer(nullptr)
34  , m_blob(nullptr)
35  , m_buildingPart(BUILDING_SHALLOW_PART)
36  , m_shallowBlobSize(0)
37  , m_memStat(memStat)
38  , m_heap(heap)
39  {}
40 
43  bool IsWriteMode() { return m_blobBuffer->IsWriteMode(); }
44 
49  T* Build(BlobHandler<T>& blobHandler);
50 
53 
55  void BuildFlatBlob(T& blob);
56 
57  virtual ~BaseBlobBuilder() {}
58 
59 private:
68  virtual void DoBuild() = 0;
69 
70 public:
72  void DoBuildAllocatedBlob(BlobBuffer* blobBuffer, T* blob);
73 
75  void DoAllocAndBuildReferencedBlob(BlobBuffer* blobBuffer, BlobRef<T>* blobRef);
76 
79  {
80  const bool isBuildingShallowPart = (m_buildingPart == BUILDING_SHALLOW_PART);
81 
82  KY_DEBUG_ASSERTN(isBuildingShallowPart,
83  ("In BaseBlobBuilder::DoBuild(), BUILD_REFERENCED_BLOB must be called after all calls to BLOB_ARRAY, BLOB_ARRAY_COPY, BLOB_STRING, BLOB_BUILD"));
84 
85  return (isBuildingShallowPart) ? m_blobBuffer : nullptr;
86  }
87 
88  BlobBuffer* GetBlobBufferToBuildReference()
89  {
90  EndShallowPart();
91  m_buildingPart = BUILDING_DEEP_PART;
92  return m_blobBuffer;
93  }
94 
95  void EndShallowPart()
96  {
97  if (m_buildingPart == BUILDING_SHALLOW_PART)
98  {
99  assert(m_shallowBlobSize == 0); // should not be called twice
100  m_shallowBlobSize = m_blobBuffer->m_offset;
101  }
102  else // (m_buildingPart == BUILDING_DEEP_PART)
103  {
104  m_blobBuffer->SetBlobRefInfoFromCurrentOffset();
105  }
106  }
107 
108 public:
110  BlobBuffer* m_blobBuffer;
111 
113  T* m_blob;
114 
115  enum BuildingPart { BUILDING_SHALLOW_PART = 0, BUILDING_DEEP_PART = 1 };
116  BuildingPart m_buildingPart;
117 
118  KyUInt32 m_shallowBlobSize;
119 
120  KyInt32 m_memStat;
121  MemoryHeap* m_heap;
122 };
123 
124 
130 #define BLOB_SET(blob, value) \
131 if (this->IsWriteMode()) (blob) = (value)
132 
139 #define BLOB_ARRAY(blobArray, count) \
140 this->GetBlobBufferToBuildThis()->AllocArray(this->IsWriteMode() ? &(blobArray) : nullptr, count)
141 
151 #define BLOB_ARRAY_COPY(blobArray, src, count) \
152 this->GetBlobBufferToBuildThis()->AllocAndCopyArray(this->IsWriteMode() ? &(blobArray) : nullptr, (count) != 0 ? (src) : nullptr, (KyUInt32)(count))
153 
155 #define BLOB_ARRAY_COPY_2(blobArray, ky_array) \
156 BLOB_ARRAY_COPY(blobArray, ky_array.GetDataPtr(), ky_array.GetSize())
157 
166 #define BLOB_STRING(str, src) \
167 this->GetBlobBufferToBuildThis()->AllocAndCopyArray(this->IsWriteMode() ? &(str) : nullptr, src, (KyUInt32)Kaim::SFstrlen(src) + 1)
168 
175 #define BLOB_BUILD(blob, builder) \
176 builder.DoBuildAllocatedBlob(this->GetBlobBufferToBuildThis(), this->IsWriteMode() ? &(blob) : nullptr)
177 // alias
178 #define BUILD_BLOB(blob, builder) BLOB_BUILD(blob, builder)
179 
182 #define BUILD_REFERENCED_BLOB(blobRef, builder) \
183 builder.DoAllocAndBuildReferencedBlob(this->GetBlobBufferToBuildReference(), this->IsWriteMode() ? &(blobRef) : nullptr)
184 
187 #define COPY_REFERENCED_BLOB(blobRef, srcBlob, srcBlobDeepSize, srcBlobShallowSize) \
188 this->GetBlobBufferToBuildReference()->AllocAndCopyReferencedBlob( \
189  this->IsWriteMode() ? &(blobRef) : nullptr, srcBlob, srcBlobDeepSize, srcBlobShallowSize)
190 
191 #define COPY_REFERENCED_BLOB_FROM_HANDLER(blobRef, blobHandler) \
192 this->GetBlobBufferToBuildReference()->AllocAndCopyReferencedBlobFromBlobHandler( \
193  this->IsWriteMode() ? &(blobRef) : nullptr, blobHandler)
194 
195 
196 // --------------------------------- inline implementation ---------------------------------
197 
198 template<class T>
200 {
201  BlobBuffer blobBuffer;
202  m_blobBuffer = &blobBuffer;
203 
204  // COUNT
205  m_blobBuffer->Alloc<T>();
206  m_buildingPart = BUILDING_SHALLOW_PART;
207  m_shallowBlobSize = 0;
208  DoBuild();
209 
210  // ALLOCATE
211  m_blobBuffer->SwitchToWriteMode(blobHandler, m_shallowBlobSize, m_heap, m_memStat);
212 
213  // WRITE
214  m_blob = m_blobBuffer->Alloc<T>();
215  m_buildingPart = BUILDING_SHALLOW_PART;
216  m_shallowBlobSize = 0;
217  DoBuild();
218 
219  return (T*)m_blob;
220 }
221 
222 template<class T>
224 {
225  BlobBuffer blobBuffer;
226  m_blobBuffer = &blobBuffer;
227 
228  // COUNT
229  m_blobBuffer->m_offset += sizeof(T); // what m_blobBuffer->Alloc<T>(); does in COUNT mode
230  m_buildingPart = BUILDING_SHALLOW_PART;
231  m_shallowBlobSize = 0;
232  DoBuild();
233 
234  m_shallowBlobSize = 0;
235 
236  return m_blobBuffer->m_offset;
237 }
238 
239 
240 template<class T>
242 {
243  m_blob = &blob;
244  DoBuild();
245 }
246 
247 
248 template<class T>
249 void BaseBlobBuilder<T>::DoBuildAllocatedBlob(BlobBuffer* blobBuffer, T* blob)
250 {
251  m_blobBuffer = blobBuffer;
252  m_blob = blob;
253  DoBuild();
254 }
255 
256 
257 template<class T>
258 void BaseBlobBuilder<T>::DoAllocAndBuildReferencedBlob(BlobBuffer* blobBuffer, BlobRef<T>* blobRef)
259 {
260  m_blobBuffer = blobBuffer;
261 
262  m_blobBuffer->BeginBlobRefBuffer(blobRef);
263 
264  m_blob = m_blobBuffer->Alloc<T>();
265  DoBuild();
266 
267  m_blobBuffer->SetBlobRefInfoFromCurrentOffset();
268 }
269 
270 
271 }
272 
273 
void DoAllocAndBuildReferencedBlob(BlobBuffer *blobBuffer, BlobRef< T > *blobRef)
For internal use. Use BUILD_REFERENCED_BLOB instead.
Definition: baseblobbuilder.h:258
std::uint32_t KyUInt32
uint32_t
Definition: types.h:29
KyUInt32 ComputeBlobSize()
Simply Compute BlobSize.
Definition: baseblobbuilder.h:223
BlobBuffer * GetBlobBufferToBuildThis()
For internal use. Check if m_buildingPart == BUILDING_SHALLOW_PART and return this.
Definition: baseblobbuilder.h:78
The BlobHandler class is a top-level mechanism for serializing blobs between objects in memory and fi...
Definition: blobhandler.h:40
void DoBuildAllocatedBlob(BlobBuffer *blobBuffer, T *blob)
For internal use. Use BLOB_BUILD instead.
Definition: baseblobbuilder.h:249
A BlobRef is a type of reference that is compatible with the blob serialization framework.
Definition: blobref.h:51
BlobBuffer * m_blobBuffer
For internal use. Use BLOB_SET and BLOB_ARRAY instead.
Definition: baseblobbuilder.h:110
T * m_blob
The blob maintained by this builder. Only modify using the macros listed under DoBuild().
Definition: baseblobbuilder.h:113
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
bool IsWriteMode()
Indicates whether the builder is operating in COUNT mode or in WRITE mode.
Definition: baseblobbuilder.h:43
void BuildFlatBlob(T &blob)
Simple way to use DoBuild in case of flat blob (that is, a blob that does not have a BlobArray or Blo...
Definition: baseblobbuilder.h:241
BaseBlobBuilder is an abstract base class that builds a blob within a contiguous block of memory...
Definition: baseblobbuilder.h:27
std::int32_t KyInt32
int32_t
Definition: types.h:24
virtual void DoBuild()=0
Implement this function in any class that derives from BaseBlobBuilder.
T * Build(BlobHandler< T > &blobHandler)
This method:Calls DoBuild() in COUNT mode to determine the amount of memory needed for the blob to be...
Definition: baseblobbuilder.h:199