diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/public/dt_utlvector_recv.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/public/dt_utlvector_recv.cpp')
| -rw-r--r-- | mp/src/public/dt_utlvector_recv.cpp | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/mp/src/public/dt_utlvector_recv.cpp b/mp/src/public/dt_utlvector_recv.cpp new file mode 100644 index 00000000..e8d63200 --- /dev/null +++ b/mp/src/public/dt_utlvector_recv.cpp @@ -0,0 +1,157 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+
+#include "dt_utlvector_recv.h"
+
+#include "tier0/memdbgon.h"
+
+
+extern const char *s_ClientElementNames[MAX_ARRAY_ELEMENTS];
+
+
+class CRecvPropExtra_UtlVector
+{
+public:
+ DataTableRecvVarProxyFn m_DataTableProxyFn; // If it's a datatable, then this is the proxy they specified.
+ RecvVarProxyFn m_ProxyFn; // If it's a non-datatable, then this is the proxy they specified.
+ ResizeUtlVectorFn m_ResizeFn; // The function used to resize the CUtlVector.
+ EnsureCapacityFn m_EnsureCapacityFn;
+ int m_ElementStride; // Distance between each element in the array.
+ int m_Offset; // Offset of the CUtlVector from its parent structure.
+ int m_nMaxElements; // For debugging...
+};
+
+void RecvProxy_UtlVectorLength( const CRecvProxyData *pData, void *pStruct, void *pOut )
+{
+ CRecvPropExtra_UtlVector *pExtra = (CRecvPropExtra_UtlVector*)pData->m_pRecvProp->GetExtraData();
+ pExtra->m_ResizeFn( pStruct, pExtra->m_Offset, pData->m_Value.m_Int );
+}
+
+void RecvProxy_UtlVectorElement( const CRecvProxyData *pData, void *pStruct, void *pOut )
+{
+ CRecvPropExtra_UtlVector *pExtra = (CRecvPropExtra_UtlVector*)pData->m_pRecvProp->GetExtraData();
+
+ // Kind of lame overloading element stride to hold the element index,
+ // but we can easily move it into its SetExtraData stuff if we need to.
+ int iElement = pData->m_pRecvProp->GetElementStride();
+
+ // NOTE: this is cheesy, but it does the trick.
+ CUtlVector<int> *pUtlVec = (CUtlVector<int>*)((char*)pStruct + pExtra->m_Offset);
+
+ // Call through to the proxy they passed in, making pStruct=the CUtlVector.
+ // Note: there should be space here as long as the element is < the max # elements
+ // that we ensured capacity for in DataTableRecvProxy_LengthProxy.
+ pExtra->m_ProxyFn( pData, pOut, (char*)pUtlVec->Base() + iElement*pExtra->m_ElementStride );
+}
+
+void RecvProxy_UtlVectorElement_DataTable( const RecvProp *pProp, void **pOut, void *pData, int objectID )
+{
+ CRecvPropExtra_UtlVector *pExtra = (CRecvPropExtra_UtlVector*)pProp->GetExtraData();
+
+ int iElement = pProp->GetElementStride();
+ Assert( iElement < pExtra->m_nMaxElements );
+
+ // NOTE: this is cheesy, but it does the trick.
+ CUtlVector<int> *pUtlVec = (CUtlVector<int>*)((char*)pData + pExtra->m_Offset);
+
+ // Call through to the proxy they passed in, making pStruct=the CUtlVector and forcing iElement to 0.
+ pExtra->m_DataTableProxyFn( pProp, pOut, (char*)pUtlVec->Base() + iElement*pExtra->m_ElementStride, objectID );
+}
+
+
+void DataTableRecvProxy_LengthProxy( const RecvProp *pProp, void **pOut, void *pData, int objectID )
+{
+ // This is VERY important - since it calls all the datatable proxies in the tree first,
+ // particularly BEFORE it calls our array length proxy, we need to make sure we return
+ // valid pointers that aren't going to change when it starts to copy the data into
+ // the datatable elements.
+ CRecvPropExtra_UtlVector *pExtra = (CRecvPropExtra_UtlVector*)pProp->GetExtraData();
+ pExtra->m_EnsureCapacityFn( pData, pExtra->m_Offset, pExtra->m_nMaxElements );
+
+ *pOut = pData;
+}
+
+
+RecvProp RecvPropUtlVector(
+ const char *pVarName, // Use RECVINFO_UTLVECTOR to generate these 4.
+ int offset, // Used to generate pData in the function specified in varProxy.
+ int sizeofVar, // The size of each element in the utlvector.
+ ResizeUtlVectorFn fn,
+ EnsureCapacityFn ensureFn,
+ int nMaxElements, // Max # of elements in the array. Keep this as low as possible.
+ RecvProp pArrayProp
+ )
+{
+ RecvProp ret;
+
+ Assert( nMaxElements <= MAX_ARRAY_ELEMENTS );
+
+ ret.m_RecvType = DPT_DataTable;
+ ret.m_pVarName = pVarName;
+ ret.SetOffset( 0 );
+ ret.SetDataTableProxyFn( DataTableRecvProxy_StaticDataTable );
+
+ RecvProp *pProps = new RecvProp[nMaxElements+1]; // TODO free that again
+
+
+ // Extra data bound to each of the properties.
+ CRecvPropExtra_UtlVector *pExtraData = new CRecvPropExtra_UtlVector;
+
+ pExtraData->m_nMaxElements = nMaxElements;
+ pExtraData->m_ElementStride = sizeofVar;
+ pExtraData->m_ResizeFn = fn;
+ pExtraData->m_EnsureCapacityFn = ensureFn;
+ pExtraData->m_Offset = offset;
+
+ if ( pArrayProp.m_RecvType == DPT_DataTable )
+ pExtraData->m_DataTableProxyFn = pArrayProp.GetDataTableProxyFn();
+ else
+ pExtraData->m_ProxyFn = pArrayProp.GetProxyFn();
+
+
+ // The first property is datatable with an int that tells the length of the array.
+ // It has to go in a datatable, otherwise if this array holds datatable properties, it will be received last.
+ RecvProp *pLengthProp = new RecvProp;
+ *pLengthProp = RecvPropInt( AllocateStringHelper( "lengthprop%d", nMaxElements ), 0, 0, 0, RecvProxy_UtlVectorLength );
+ pLengthProp->SetExtraData( pExtraData );
+
+ char *pLengthProxyTableName = AllocateUniqueDataTableName( false, "_LPT_%s_%d", pVarName, nMaxElements );
+ RecvTable *pLengthTable = new RecvTable( pLengthProp, 1, pLengthProxyTableName );
+ pProps[0] = RecvPropDataTable( "lengthproxy", 0, 0, pLengthTable, DataTableRecvProxy_LengthProxy );
+ pProps[0].SetExtraData( pExtraData );
+
+ // The first element is a sub-datatable.
+ for ( int i = 1; i < nMaxElements+1; i++ )
+ {
+ pProps[i] = pArrayProp; // copy array element property setting
+ pProps[i].SetOffset( 0 ); // leave offset at 0 so pStructBase is always a pointer to the CUtlVector
+ pProps[i].m_pVarName = s_ClientElementNames[i-1]; // give unique name
+ pProps[i].SetExtraData( pExtraData );
+ pProps[i].SetElementStride( i-1 ); // Kind of lame overloading element stride to hold the element index,
+ // but we can easily move it into its SetExtraData stuff if we need to.
+
+ // We provide our own proxy here.
+ if ( pArrayProp.m_RecvType == DPT_DataTable )
+ {
+ pProps[i].SetDataTableProxyFn( RecvProxy_UtlVectorElement_DataTable );
+ }
+ else
+ {
+ pProps[i].SetProxyFn( RecvProxy_UtlVectorElement );
+ }
+ }
+
+ RecvTable *pTable = new RecvTable(
+ pProps,
+ nMaxElements+1,
+ AllocateUniqueDataTableName( false, "_ST_%s_%d", pVarName, nMaxElements )
+ ); // TODO free that again
+
+ ret.SetDataTable( pTable );
+ return ret;
+}
|