initial import of adt array natives for amb576
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401162
This commit is contained in:
parent
78d6d2b6e2
commit
8fa974961c
149
core/CellArray.h
Normal file
149
core/CellArray.h
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is not open source and may not be copied without explicit
|
||||||
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||||
|
* in whole or significant part.
|
||||||
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
class CellArray
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CellArray(size_t blocksize) : m_Data(NULL), m_BlockSize(blocksize), m_AllocSize(0), m_Size(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~CellArray()
|
||||||
|
{
|
||||||
|
free(m_Data);
|
||||||
|
}
|
||||||
|
size_t size() const
|
||||||
|
{
|
||||||
|
return m_Size;
|
||||||
|
}
|
||||||
|
cell_t *push()
|
||||||
|
{
|
||||||
|
if (!GrowIfNeeded(1))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
cell_t *arr = &m_Data[m_Size * m_BlockSize];
|
||||||
|
m_Size++;
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
cell_t *at(size_t b) const
|
||||||
|
{
|
||||||
|
return &m_Data[b * m_BlockSize];
|
||||||
|
}
|
||||||
|
size_t blocksize() const
|
||||||
|
{
|
||||||
|
return m_BlockSize;
|
||||||
|
}
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
m_Size = 0;
|
||||||
|
}
|
||||||
|
bool swap(size_t item1, size_t item2)
|
||||||
|
{
|
||||||
|
/* Make sure there is extra space available */
|
||||||
|
if (!GrowIfNeeded(1))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *pri = at(item1);
|
||||||
|
cell_t *alt = at(item2);
|
||||||
|
|
||||||
|
/* Get our temporary array 1 after the limit */
|
||||||
|
cell_t *temp = &m_Data[m_Size * m_BlockSize];
|
||||||
|
|
||||||
|
memcpy(temp, pri, sizeof(cell_t) * m_BlockSize);
|
||||||
|
memcpy(pri, alt, sizeof(cell_t) * m_BlockSize);
|
||||||
|
memcpy(alt, temp, sizeof(cell_t) * m_BlockSize);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void remove(size_t index)
|
||||||
|
{
|
||||||
|
/* If we're at the end, take the easy way out */
|
||||||
|
if (index == m_Size - 1)
|
||||||
|
{
|
||||||
|
m_Size--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, it's time to move stuff! */
|
||||||
|
size_t remaining_indexes = (m_Size - 1) - index;
|
||||||
|
cell_t *src = at(index + 1);
|
||||||
|
cell_t *dest = at(index);
|
||||||
|
memmove(dest, src, sizeof(cell_t) * m_BlockSize * remaining_indexes);
|
||||||
|
|
||||||
|
m_Size--;
|
||||||
|
}
|
||||||
|
cell_t *insert_at(size_t index)
|
||||||
|
{
|
||||||
|
/* Make sure it'll fit */
|
||||||
|
if (!GrowIfNeeded(1))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* move everything up */
|
||||||
|
cell_t *src = at(index);
|
||||||
|
cell_t *dst = at(index + 1);
|
||||||
|
memmove(dst, src, sizeof(cell_t) * m_BlockSize * m_Size);
|
||||||
|
|
||||||
|
m_Size++;
|
||||||
|
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
bool resize(size_t count)
|
||||||
|
{
|
||||||
|
if (count <= m_Size)
|
||||||
|
{
|
||||||
|
m_Size = count;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return GrowIfNeeded(m_Size - count);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
bool GrowIfNeeded(size_t count)
|
||||||
|
{
|
||||||
|
/* Shortcut out if we can store this */
|
||||||
|
if (m_Size + count <= m_AllocSize)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/* Set a base allocation size of 8 items */
|
||||||
|
if (!m_AllocSize)
|
||||||
|
{
|
||||||
|
m_AllocSize = 8;
|
||||||
|
}
|
||||||
|
/* If it's not enough, keep doubling */
|
||||||
|
while (m_Size + count > m_AllocSize)
|
||||||
|
{
|
||||||
|
m_AllocSize *= 2;
|
||||||
|
}
|
||||||
|
/* finally, allocate the new block */
|
||||||
|
if (m_Data)
|
||||||
|
{
|
||||||
|
m_Data = (cell_t *)realloc(m_Data, sizeof(cell_t) * m_BlockSize * m_AllocSize);
|
||||||
|
} else {
|
||||||
|
m_Data = (cell_t *)malloc(sizeof(cell_t) * m_BlockSize * m_AllocSize);
|
||||||
|
}
|
||||||
|
return (m_Data != NULL);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
cell_t *m_Data;
|
||||||
|
size_t m_BlockSize;
|
||||||
|
size_t m_AllocSize;
|
||||||
|
size_t m_Size;
|
||||||
|
};
|
@ -29,7 +29,7 @@ OBJECTS += smn_admin.cpp smn_bitbuffer.cpp smn_console.cpp smn_core.cpp \
|
|||||||
smn_datapacks.cpp smn_entities.cpp smn_events.cpp smn_fakenatives.cpp \
|
smn_datapacks.cpp smn_entities.cpp smn_events.cpp smn_fakenatives.cpp \
|
||||||
smn_filesystem.cpp smn_float.cpp smn_functions.cpp smn_gameconfigs.cpp smn_halflife.cpp smn_handles.cpp smn_keyvalues.cpp \
|
smn_filesystem.cpp smn_float.cpp smn_functions.cpp smn_gameconfigs.cpp smn_halflife.cpp smn_handles.cpp smn_keyvalues.cpp \
|
||||||
smn_lang.cpp smn_player.cpp smn_string.cpp smn_sorting.cpp smn_textparse.cpp smn_timers.cpp \
|
smn_lang.cpp smn_player.cpp smn_string.cpp smn_sorting.cpp smn_textparse.cpp smn_timers.cpp \
|
||||||
smn_usermsgs.cpp smn_menus.cpp smn_database.cpp smn_vector.cpp
|
smn_usermsgs.cpp smn_menus.cpp smn_database.cpp smn_vector.cpp smn_adt_array.cpp
|
||||||
OBJECTS += systems/ExtensionSys.cpp systems/ForwardSys.cpp systems/HandleSys.cpp \
|
OBJECTS += systems/ExtensionSys.cpp systems/ForwardSys.cpp systems/HandleSys.cpp \
|
||||||
systems/LibrarySys.cpp systems/PluginInfoDatabase.cpp systems/PluginSys.cpp \
|
systems/LibrarySys.cpp systems/PluginInfoDatabase.cpp systems/PluginSys.cpp \
|
||||||
systems/ShareSys.cpp vm/sp_vm_basecontext.cpp vm/sp_vm_engine.cpp \
|
systems/ShareSys.cpp vm/sp_vm_basecontext.cpp vm/sp_vm_engine.cpp \
|
||||||
|
@ -406,6 +406,10 @@
|
|||||||
RelativePath="..\CDataPack.h"
|
RelativePath="..\CDataPack.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\CellArray.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\CellRecipientFilter.h"
|
RelativePath="..\CellRecipientFilter.h"
|
||||||
>
|
>
|
||||||
@ -901,6 +905,10 @@
|
|||||||
RelativePath="..\smn_admin.cpp"
|
RelativePath="..\smn_admin.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\smn_adt_array.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\smn_bitbuffer.cpp"
|
RelativePath="..\smn_bitbuffer.cpp"
|
||||||
>
|
>
|
||||||
|
489
core/smn_adt_array.cpp
Normal file
489
core/smn_adt_array.cpp
Normal file
@ -0,0 +1,489 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is not open source and may not be copied without explicit
|
||||||
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||||
|
* in whole or significant part.
|
||||||
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
#include "sm_globals.h"
|
||||||
|
#include "sm_stringutil.h"
|
||||||
|
#include "CellArray.h"
|
||||||
|
#include "HandleSys.h"
|
||||||
|
|
||||||
|
HandleType_t htCellArray;
|
||||||
|
|
||||||
|
class CellArrayHelpers :
|
||||||
|
public SMGlobalClass,
|
||||||
|
public IHandleTypeDispatch
|
||||||
|
{
|
||||||
|
public: //SMGlobalClass
|
||||||
|
void OnSourceModAllInitialized()
|
||||||
|
{
|
||||||
|
htCellArray = g_HandleSys.CreateType("CellArray", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
||||||
|
}
|
||||||
|
void OnSourceModShutdown()
|
||||||
|
{
|
||||||
|
g_HandleSys.RemoveType(htCellArray, g_pCoreIdent);
|
||||||
|
}
|
||||||
|
public: //IHandleTypeDispatch
|
||||||
|
void OnHandleDestroy(HandleType_t type, void *object)
|
||||||
|
{
|
||||||
|
CellArray *array = (CellArray *)object;
|
||||||
|
delete array;
|
||||||
|
}
|
||||||
|
} s_CellArrayHelpers;
|
||||||
|
|
||||||
|
static cell_t CreateArray(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
if (!params[1])
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid block size (must be > 0)");
|
||||||
|
}
|
||||||
|
|
||||||
|
CellArray *array = new CellArray(params[1]);
|
||||||
|
|
||||||
|
if (params[2])
|
||||||
|
{
|
||||||
|
array->resize(params[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle_t hndl = g_HandleSys.CreateHandle(htCellArray, array, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||||
|
if (!hndl)
|
||||||
|
{
|
||||||
|
delete array;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hndl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t ClearArray(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
array->clear();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t ResizeArray(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!array->resize(params[2]))
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Unable to resize array to \"%u\"", params[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t GetArraySize(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (cell_t)array->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t PushArrayCell(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *blk = array->push();
|
||||||
|
if (!blk)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Failed to grow array");
|
||||||
|
}
|
||||||
|
|
||||||
|
*blk = params[2];
|
||||||
|
|
||||||
|
return (cell_t)(array->size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t PushArrayString(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *blk = array->push();
|
||||||
|
if (!blk)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Failed to grow array");
|
||||||
|
}
|
||||||
|
|
||||||
|
char *str;
|
||||||
|
pContext->LocalToString(params[2], &str);
|
||||||
|
|
||||||
|
strncopy((char *)blk, str, array->blocksize() * sizeof(cell_t));
|
||||||
|
|
||||||
|
return (cell_t)(array->size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t PushArrayArray(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *blk = array->push();
|
||||||
|
if (!blk)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Failed to grow array");
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *addr;
|
||||||
|
pContext->LocalToPhysAddr(params[2], &addr);
|
||||||
|
|
||||||
|
size_t indexes = array->blocksize();
|
||||||
|
if (params[3] != -1 && (size_t)params[3] <= array->blocksize())
|
||||||
|
{
|
||||||
|
indexes = params[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(blk, addr, sizeof(cell_t) * indexes);
|
||||||
|
|
||||||
|
return (cell_t)(array->size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t GetArrayCell(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = (size_t)params[2];
|
||||||
|
if (idx >= array->size())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *blk = array->at(idx);
|
||||||
|
|
||||||
|
idx = (size_t)params[3];
|
||||||
|
if (params[4] == 1)
|
||||||
|
{
|
||||||
|
if (idx >= array->blocksize())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", idx, array->blocksize());
|
||||||
|
}
|
||||||
|
return blk[idx];
|
||||||
|
} else {
|
||||||
|
if (idx >= array->blocksize() * 4)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid byte %d (blocksize: %d bytes)", idx, array->blocksize() * 4);
|
||||||
|
}
|
||||||
|
return (cell_t)*((char *)blk + idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t GetArrayString(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = (size_t)params[2];
|
||||||
|
if (idx >= array->size())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *blk = array->at(idx);
|
||||||
|
size_t numWritten = 0;
|
||||||
|
|
||||||
|
pContext->StringToLocalUTF8(params[3], params[4], (char *)blk, &numWritten);
|
||||||
|
|
||||||
|
return numWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t GetArrayArray(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = (size_t)params[2];
|
||||||
|
if (idx >= array->size())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *blk = array->at(idx);
|
||||||
|
size_t indexes = array->blocksize();
|
||||||
|
if (params[4] != -1 && (size_t)params[4] <= array->blocksize())
|
||||||
|
{
|
||||||
|
indexes = params[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *addr;
|
||||||
|
pContext->LocalToPhysAddr(params[3], &addr);
|
||||||
|
|
||||||
|
memcpy(addr, blk, sizeof(cell_t) * indexes);
|
||||||
|
|
||||||
|
return indexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t SetArrayCell(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = (size_t)params[2];
|
||||||
|
if (idx >= array->size())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *blk = array->at(idx);
|
||||||
|
|
||||||
|
idx = (size_t)params[4];
|
||||||
|
if (params[5] == 1)
|
||||||
|
{
|
||||||
|
if (idx >= array->blocksize())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", idx, array->blocksize());
|
||||||
|
}
|
||||||
|
blk[idx] = params[3];
|
||||||
|
} else {
|
||||||
|
if (idx >= array->blocksize() * 4)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid byte %d (blocksize: %d bytes)", idx, array->blocksize() * 4);
|
||||||
|
}
|
||||||
|
*((char *)blk + idx) = (char)params[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t SetArrayString(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = (size_t)params[2];
|
||||||
|
if (idx >= array->size())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *blk = array->at(idx);
|
||||||
|
|
||||||
|
char *str;
|
||||||
|
pContext->LocalToString(params[3], &str);
|
||||||
|
|
||||||
|
return strncopy((char *)blk, str, array->blocksize() * sizeof(cell_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t SetArrayArray(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = (size_t)params[2];
|
||||||
|
if (idx >= array->size())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *blk = array->at(idx);
|
||||||
|
size_t indexes = array->blocksize();
|
||||||
|
if (params[4] != -1 && (size_t)params[4] <= array->blocksize())
|
||||||
|
{
|
||||||
|
indexes = params[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *addr;
|
||||||
|
pContext->LocalToPhysAddr(params[3], &addr);
|
||||||
|
|
||||||
|
memcpy(blk, addr, sizeof(cell_t) * indexes);
|
||||||
|
|
||||||
|
return indexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t ShiftArrayUp(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = (size_t)params[2];
|
||||||
|
if (idx >= array->size())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
array->insert_at(idx);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t RemoveFromArray(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = (size_t)params[2];
|
||||||
|
if (idx >= array->size())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
array->remove(idx);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t SwapArrayItems(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
CellArray *array;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx1 = (size_t)params[2];
|
||||||
|
size_t idx2 = (size_t)params[3];
|
||||||
|
if (idx1 >= array->size())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx1, array->size());
|
||||||
|
}
|
||||||
|
if (idx2 >= array->size())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx2, array->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
array->swap(idx1, idx2);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_NATIVES(cellArrayNatives)
|
||||||
|
{
|
||||||
|
{"ClearArray", ClearArray},
|
||||||
|
{"CreateArray", CreateArray},
|
||||||
|
{"GetArrayArray", GetArrayArray},
|
||||||
|
{"GetArrayCell", GetArrayCell},
|
||||||
|
{"GetArraySize", GetArraySize},
|
||||||
|
{"GetArrayString", GetArrayString},
|
||||||
|
{"ResizeArray", ResizeArray},
|
||||||
|
{"PushArrayArray", PushArrayArray},
|
||||||
|
{"PushArrayCell", PushArrayCell},
|
||||||
|
{"PushArrayString", PushArrayString},
|
||||||
|
{"RemoveFromArray", RemoveFromArray},
|
||||||
|
{"SetArrayCell", SetArrayCell},
|
||||||
|
{"SetArrayString", SetArrayString},
|
||||||
|
{"SetArrayArray", SetArrayArray},
|
||||||
|
{"ShiftArrayUp", ShiftArrayUp},
|
||||||
|
{"SwapArrayItems", SwapArrayItems},
|
||||||
|
{NULL, NULL},
|
||||||
|
};
|
21
plugins/include/adt.inc
Normal file
21
plugins/include/adt.inc
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is part of the SourceMod/SourcePawn SDK. This file may only be used
|
||||||
|
* or modified under the Terms and Conditions of its License Agreement, which is found
|
||||||
|
* in LICENSE.txt. The Terms and Conditions for making SourceMod extensions/plugins
|
||||||
|
* may change at any time. To view the latest information, see:
|
||||||
|
* http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined _adt_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _adt_included
|
||||||
|
|
||||||
|
#include <adt_array>
|
233
plugins/include/adt_array.inc
Normal file
233
plugins/include/adt_array.inc
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is part of the SourceMod/SourcePawn SDK. This file may only be used
|
||||||
|
* or modified under the Terms and Conditions of its License Agreement, which is found
|
||||||
|
* in LICENSE.txt. The Terms and Conditions for making SourceMod extensions/plugins
|
||||||
|
* may change at any time. To view the latest information, see:
|
||||||
|
* http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined _adt_array_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _adt_array_included
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a maximum string size (including the null terminator),
|
||||||
|
* returns the number of cells required to fit that string.
|
||||||
|
*
|
||||||
|
* @param size Number of bytes.
|
||||||
|
* @return Minimum number of cells required to fit the byte count.
|
||||||
|
*/
|
||||||
|
stock ByteCountToCells(size)
|
||||||
|
{
|
||||||
|
if (!size)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (size + 3) / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a dynamic global cell array. While slower than a normal array,
|
||||||
|
* it can be used globally AND dynamically, which is otherwise impossible.
|
||||||
|
*
|
||||||
|
* The contents of the array are uniform; i.e. storing a string at index X
|
||||||
|
* and then retrieving it as an integer is NOT the same as StringToInt()!
|
||||||
|
* The "blocksize" determines how many cells each array slot has; it cannot
|
||||||
|
* be changed after creation.
|
||||||
|
*
|
||||||
|
* @param blocksize The number of cells each member of the array can
|
||||||
|
* hold. For example, 32 cells is equivalent to:
|
||||||
|
* new Array[X][32]
|
||||||
|
* @param startsize Initial size of the array. Note that data will
|
||||||
|
* NOT be auto-intialized.
|
||||||
|
* @return New Handle to the array object.
|
||||||
|
*/
|
||||||
|
native Handle:CreateArray(blocksize=1, startsize=0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears an array of all entries. This is the same as ResizeArray(0).
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native ClearArray(Handle:array);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizes an array. If the size is smaller than the current size,
|
||||||
|
* the array is truncated.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @param newsize New size.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid Handle or out of memory.
|
||||||
|
*/
|
||||||
|
native bool:ResizeArray(Handle:array, newsize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the array size.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @return Number of elements in the array.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native GetArraySize(Handle:array);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes a value onto the end of an array, adding a new index.
|
||||||
|
*
|
||||||
|
* This may safely be used even if the array has a blocksize
|
||||||
|
* greater than 1.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @param value Value to push.
|
||||||
|
* @return Index of the new entry.
|
||||||
|
* @error Invalid Handle or out of memory.
|
||||||
|
*/
|
||||||
|
native PushArrayCell(Handle:array, any:value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes a string onto the end of an array, truncating it
|
||||||
|
* if it is too big.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @param value String to push.
|
||||||
|
* @return Index of the new entry.
|
||||||
|
* @error Invalid Handle or out of memory.
|
||||||
|
*/
|
||||||
|
native PushArrayString(Handle:array, const String:value[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes an array of cells onto the end of an array. The cells
|
||||||
|
* are pushed as a block (i.e. the entire array sits at the index),
|
||||||
|
* rather than pushing each cell individually.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @param values Block of values to copy.
|
||||||
|
* @param size If not set, the number of elements copied from the array
|
||||||
|
* will be equal to the blocksize. If set higher than the
|
||||||
|
* blocksize, the operation will be truncated.
|
||||||
|
* @return Index of the new entry.
|
||||||
|
* @error Invalid Handle or out of memory.
|
||||||
|
*/
|
||||||
|
native PushArrayArray(Handle:array, const values[], size=-1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a cell value from an array.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @param index Index in the array.
|
||||||
|
* @param block Optionally specify which block to read from
|
||||||
|
* (useful if the blocksize > 0).
|
||||||
|
* @param asChar Optionally read as a byte instead of a cell.
|
||||||
|
* @return Value read.
|
||||||
|
* @error Invalid Handle, invalid index, or invalid block.
|
||||||
|
*/
|
||||||
|
native any:GetArrayCell(Handle:array, index, block=0, bool:asChar=false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a string value from an array.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @param index Index in the array.
|
||||||
|
* @param buffer Buffer to copy to.
|
||||||
|
* @param maxlength Maximum size of the buffer.
|
||||||
|
* @return Number of characters copied.
|
||||||
|
* @error Invalid Handle or invalid index.
|
||||||
|
*/
|
||||||
|
native GetArrayString(Handle:array, index, String:buffer[], maxlength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves an array of cells from an array.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @param index Index in the array.
|
||||||
|
* @param buffer Buffer to store the array in.
|
||||||
|
* @param size If not set, assumes the buffer size is equal to the
|
||||||
|
* blocksize. Otherwise, the size passed is used.
|
||||||
|
* @return Number of cells copied.
|
||||||
|
* @error Invalid Handle or invalid index.
|
||||||
|
*/
|
||||||
|
native GetArrayArray(Handle:array, index, buffer[], size=-1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a cell value in an array.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @param index Index in the array.
|
||||||
|
* @param value Cell value to set.
|
||||||
|
* @param block Optionally specify which block to write to
|
||||||
|
* (useful if the blocksize > 0).
|
||||||
|
* @param asChar Optionally set as a byte instead of a cell.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid Handle, invalid index, or invalid block.
|
||||||
|
*/
|
||||||
|
native any:SetArrayCell(Handle:array, index, any:value, block=0, bool:asChar=false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a string value in an array.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @param index Index in the array.
|
||||||
|
* @param value String value to set.
|
||||||
|
* @return Number of characters copied.
|
||||||
|
* @error Invalid Handle or invalid index.
|
||||||
|
*/
|
||||||
|
native SetArrayString(Handle:array, index, const String:buffer[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an array of cells in an array.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @param index Index in the array.
|
||||||
|
* @param buffer Array to copy.
|
||||||
|
* @param size If not set, assumes the buffer size is equal to the
|
||||||
|
* blocksize. Otherwise, the size passed is used.
|
||||||
|
* @return Number of cells copied.
|
||||||
|
* @error Invalid Handle or invalid index.
|
||||||
|
*/
|
||||||
|
native SetArrayArray(Handle:array, index, const values[], size=-1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shifts an array up. All array contents after and including the given
|
||||||
|
* index are shifted up by one, and the given index is then "free."
|
||||||
|
* After shifting, the contents of the given index is undefined.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @param index Index in the array to shift up from.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid Handle or invalid index.
|
||||||
|
*/
|
||||||
|
native ShiftArrayUp(Handle:array, index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an array index, shifting the entire array down from that position
|
||||||
|
* on. For example, if item 8 of 10 is removed, the last 3 items will then be
|
||||||
|
* (6,7,8) instead of (7,8,9), and all indexes before 8 will remain unchanged.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @param index Index in the array to remove at.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid Handle or invalid index.
|
||||||
|
*/
|
||||||
|
native RemoveFromArray(Handle:array, index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swaps two items in the array.
|
||||||
|
*
|
||||||
|
* @param array Array Handle.
|
||||||
|
* @param index1 First index.
|
||||||
|
* @param index2 Second index.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid Handle or invalid index.
|
||||||
|
*/
|
||||||
|
native SwapArrayItems(Handle:array, index1, index2);
|
@ -51,6 +51,7 @@ struct Plugin
|
|||||||
#include <keyvalues>
|
#include <keyvalues>
|
||||||
#include <menus>
|
#include <menus>
|
||||||
#include <halflife>
|
#include <halflife>
|
||||||
|
#include <adt>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare this as a struct in your plugin to expose its information.
|
* Declare this as a struct in your plugin to expose its information.
|
||||||
|
Loading…
Reference in New Issue
Block a user