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_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_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 \
|
||||
systems/LibrarySys.cpp systems/PluginInfoDatabase.cpp systems/PluginSys.cpp \
|
||||
systems/ShareSys.cpp vm/sp_vm_basecontext.cpp vm/sp_vm_engine.cpp \
|
||||
|
@ -406,6 +406,10 @@
|
||||
RelativePath="..\CDataPack.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CellArray.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CellRecipientFilter.h"
|
||||
>
|
||||
@ -901,6 +905,10 @@
|
||||
RelativePath="..\smn_admin.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\smn_adt_array.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
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 <menus>
|
||||
#include <halflife>
|
||||
#include <adt>
|
||||
|
||||
/**
|
||||
* Declare this as a struct in your plugin to expose its information.
|
||||
|
Loading…
Reference in New Issue
Block a user