mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-26 06:45:37 +03:00
Added optimizations to the task system
Added optimizations to the forward system Fixed some debugger errors
This commit is contained in:
parent
0be7540637
commit
10a64737b5
@ -46,6 +46,8 @@
|
|||||||
#ifndef FORWARD_H
|
#ifndef FORWARD_H
|
||||||
#define FORWARD_H
|
#define FORWARD_H
|
||||||
|
|
||||||
|
#include "sh_stack.h"
|
||||||
|
|
||||||
const int FORWARD_MAX_PARAMS = 32;
|
const int FORWARD_MAX_PARAMS = 32;
|
||||||
|
|
||||||
enum ForwardExecType
|
enum ForwardExecType
|
||||||
@ -171,7 +173,7 @@ class CForwardMngr
|
|||||||
{
|
{
|
||||||
typedef CVector<CForward*> ForwardVec;
|
typedef CVector<CForward*> ForwardVec;
|
||||||
typedef CVector<CSPForward*> SPForwardVec;
|
typedef CVector<CSPForward*> SPForwardVec;
|
||||||
typedef CQueue<int> FreeSPVec; // Free SP Forwards
|
typedef CStack<int> FreeSPVec; // Free SP Forwards
|
||||||
|
|
||||||
ForwardVec m_Forwards;
|
ForwardVec m_Forwards;
|
||||||
|
|
||||||
|
105
amxmodx/CStack.h
105
amxmodx/CStack.h
@ -1,105 +0,0 @@
|
|||||||
/* AMX Mod X
|
|
||||||
*
|
|
||||||
* by the AMX Mod X Development Team
|
|
||||||
* originally developed by OLO
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the
|
|
||||||
* Free Software Foundation; either version 2 of the License, or (at
|
|
||||||
* your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
* In addition, as a special exception, the author gives permission to
|
|
||||||
* link the code of this program with the Half-Life Game Engine ("HL
|
|
||||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
|
||||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
|
||||||
* respects for all of the code used other than the HL Engine and MODs
|
|
||||||
* from Valve. If you modify this file, you may extend this exception
|
|
||||||
* to your version of the file, but you are not obligated to do so. If
|
|
||||||
* you do not wish to do so, delete this exception statement from your
|
|
||||||
* version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//by David "BAILOPAN" Anderson
|
|
||||||
#ifndef _INCLUDE_CSTACK_H
|
|
||||||
#define _INCLUDE_CSTACK_H
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
class CStack
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct CStackItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
T item;
|
|
||||||
CStackItem *prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
CStack()
|
|
||||||
{
|
|
||||||
mSize = 0;
|
|
||||||
mStack = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
~CStack()
|
|
||||||
{
|
|
||||||
CStackItem *p, *t;
|
|
||||||
p = mStack;
|
|
||||||
|
|
||||||
while (p)
|
|
||||||
{
|
|
||||||
t = p->prev;
|
|
||||||
delete p;
|
|
||||||
p = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
mStack = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty()
|
|
||||||
{
|
|
||||||
return (mSize == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void push(const T & v)
|
|
||||||
{
|
|
||||||
CStackItem *p = new CStackItem;
|
|
||||||
p->item = v;
|
|
||||||
p->prev = mStack;
|
|
||||||
mStack = p;
|
|
||||||
mSize++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop()
|
|
||||||
{
|
|
||||||
CStackItem *p = mStack;
|
|
||||||
mStack = p->prev;
|
|
||||||
delete p;
|
|
||||||
mSize--;
|
|
||||||
}
|
|
||||||
|
|
||||||
T & top()
|
|
||||||
{
|
|
||||||
return mStack->item;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size()
|
|
||||||
{
|
|
||||||
return mSize;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
CStackItem *mStack;
|
|
||||||
size_t mSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //_INCLUDE_CQUEUE_H
|
|
@ -31,6 +31,9 @@
|
|||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
#include "CTask.h"
|
#include "CTask.h"
|
||||||
|
#include "sh_stack.h"
|
||||||
|
|
||||||
|
CStack<CTaskMngr::CTask *> *g_FreeTasks;
|
||||||
|
|
||||||
/*********************** CTask ***********************/
|
/*********************** CTask ***********************/
|
||||||
|
|
||||||
@ -73,12 +76,19 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
|
|||||||
if (iParamsLen)
|
if (iParamsLen)
|
||||||
{
|
{
|
||||||
m_iParamLen = iParamsLen + 1;
|
m_iParamLen = iParamsLen + 1;
|
||||||
m_pParams = new cell[m_iParamLen];
|
if (m_ParamSize < m_iParamLen)
|
||||||
|
{
|
||||||
|
m_ParamSize = m_iParamLen;
|
||||||
|
cell *temp = new cell[m_ParamSize];
|
||||||
|
memset(temp, 0, sizeof(cell) * m_ParamSize);
|
||||||
|
if (m_pParams != NULL)
|
||||||
|
delete [] m_pParams;
|
||||||
|
m_pParams = temp;
|
||||||
|
}
|
||||||
memcpy(m_pParams, pParams, sizeof(cell)*iParamsLen);
|
memcpy(m_pParams, pParams, sizeof(cell)*iParamsLen);
|
||||||
m_pParams[iParamsLen] = 0;
|
m_pParams[iParamsLen] = 0;
|
||||||
} else {
|
} else {
|
||||||
m_iParamLen = 0;
|
m_iParamLen = 0;
|
||||||
m_pParams = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,11 +102,7 @@ void CTaskMngr::CTask::clear()
|
|||||||
m_iFunc = -1;
|
m_iFunc = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pParams)
|
m_iParamLen = 0;
|
||||||
{
|
|
||||||
delete [] m_pParams;
|
|
||||||
m_pParams = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pPlugin = NULL;
|
m_pPlugin = NULL;
|
||||||
m_iId = 0;
|
m_iId = 0;
|
||||||
@ -106,6 +112,7 @@ void CTaskMngr::CTask::clear()
|
|||||||
m_bLoop = false;
|
m_bLoop = false;
|
||||||
m_bAfterStart = false;
|
m_bAfterStart = false;
|
||||||
m_bBeforeEnd = false;
|
m_bBeforeEnd = false;
|
||||||
|
m_iParamLen = 0;
|
||||||
|
|
||||||
m_fNextExecTime = 0.0f;
|
m_fNextExecTime = 0.0f;
|
||||||
}
|
}
|
||||||
@ -174,6 +181,7 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
|
|||||||
if (done)
|
if (done)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
g_FreeTasks->push(this);
|
||||||
} else {
|
} else {
|
||||||
m_fNextExecTime += m_fBase;
|
m_fNextExecTime += m_fBase;
|
||||||
}
|
}
|
||||||
@ -197,12 +205,19 @@ CTaskMngr::CTask::CTask()
|
|||||||
m_fNextExecTime = 0.0f;
|
m_fNextExecTime = 0.0f;
|
||||||
|
|
||||||
m_iParamLen = 0;
|
m_iParamLen = 0;
|
||||||
|
m_ParamSize = 0;
|
||||||
m_pParams = NULL;
|
m_pParams = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CTaskMngr::CTask::~CTask()
|
CTaskMngr::CTask::~CTask()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
|
if (m_pParams)
|
||||||
|
{
|
||||||
|
delete [] m_pParams;
|
||||||
|
m_pParams = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************** CTaskMngr ***********************/
|
/*********************** CTaskMngr ***********************/
|
||||||
@ -212,11 +227,17 @@ CTaskMngr::CTaskMngr()
|
|||||||
m_pTmr_CurrentTime = NULL;
|
m_pTmr_CurrentTime = NULL;
|
||||||
m_pTmr_TimeLimit = NULL;
|
m_pTmr_TimeLimit = NULL;
|
||||||
m_pTmr_TimeLeft = NULL;
|
m_pTmr_TimeLeft = NULL;
|
||||||
|
|
||||||
|
g_FreeTasks = new CStack<CTaskMngr::CTask *>();
|
||||||
}
|
}
|
||||||
|
|
||||||
CTaskMngr::~CTaskMngr()
|
CTaskMngr::~CTaskMngr()
|
||||||
{
|
{
|
||||||
clear();
|
while (!g_FreeTasks->empty())
|
||||||
|
g_FreeTasks->pop();
|
||||||
|
delete g_FreeTasks;
|
||||||
|
|
||||||
|
m_Tasks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft)
|
void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft)
|
||||||
@ -229,19 +250,16 @@ void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pT
|
|||||||
void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat)
|
void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat)
|
||||||
{
|
{
|
||||||
// first, search for free tasks
|
// first, search for free tasks
|
||||||
TaskListIter iter = m_Tasks.find(CTaskDescriptor(0, NULL, true));
|
if (!g_FreeTasks->empty())
|
||||||
|
|
||||||
if (iter)
|
|
||||||
{
|
{
|
||||||
// found: reuse it
|
// found: reuse it
|
||||||
iter->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
|
CTask *pTmp = g_FreeTasks->front();
|
||||||
|
g_FreeTasks->pop();
|
||||||
|
pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
|
||||||
} else {
|
} else {
|
||||||
// not found: make a new one
|
// not found: make a new one
|
||||||
CTask *pTmp = new CTask;
|
CTask *pTmp = new CTask;
|
||||||
|
|
||||||
if (!pTmp)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
|
pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
|
||||||
m_Tasks.put(pTmp);
|
m_Tasks.put(pTmp);
|
||||||
}
|
}
|
||||||
@ -254,8 +272,12 @@ int CTaskMngr::removeTasks(int iId, AMX *pAmx)
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while (iter)
|
while (iter)
|
||||||
|
{
|
||||||
|
if (!iter->isFree())
|
||||||
{
|
{
|
||||||
iter->clear();
|
iter->clear();
|
||||||
|
g_FreeTasks->push(iter->getTask());
|
||||||
|
}
|
||||||
++i;
|
++i;
|
||||||
iter = m_Tasks.find(++iter, descriptor);
|
iter = m_Tasks.find(++iter, descriptor);
|
||||||
}
|
}
|
||||||
@ -297,5 +319,9 @@ void CTaskMngr::startFrame()
|
|||||||
|
|
||||||
void CTaskMngr::clear()
|
void CTaskMngr::clear()
|
||||||
{
|
{
|
||||||
m_Tasks.clear();
|
for (TaskListIter iter = m_Tasks.begin(); iter; ++iter)
|
||||||
|
{
|
||||||
|
if (!iter->isFree())
|
||||||
|
iter->clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
class CTaskMngr
|
class CTaskMngr
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
/*** class CTask ***/
|
/*** class CTask ***/
|
||||||
class CTask
|
class CTask
|
||||||
{
|
{
|
||||||
@ -52,6 +52,7 @@ private:
|
|||||||
int m_iParamLen;
|
int m_iParamLen;
|
||||||
|
|
||||||
cell *m_pParams;
|
cell *m_pParams;
|
||||||
|
cell m_ParamSize;
|
||||||
bool m_bFree;
|
bool m_bFree;
|
||||||
|
|
||||||
// execution
|
// execution
|
||||||
@ -70,6 +71,7 @@ private:
|
|||||||
void resetNextExecTime(float fCurrentTime);
|
void resetNextExecTime(float fCurrentTime);
|
||||||
|
|
||||||
bool shouldRepeat();
|
bool shouldRepeat();
|
||||||
|
CTask *getTask() { return this; }
|
||||||
|
|
||||||
CTask();
|
CTask();
|
||||||
~CTask();
|
~CTask();
|
||||||
|
@ -936,6 +936,8 @@ int Handler::HandleModule(const char *module)
|
|||||||
|
|
||||||
cell hea_addr, *phys_addr, retval;
|
cell hea_addr, *phys_addr, retval;
|
||||||
|
|
||||||
|
DisableDebugHandler(m_pAmx);
|
||||||
|
|
||||||
//temporarily set prenit
|
//temporarily set prenit
|
||||||
m_pAmx->flags |= AMX_FLAG_PRENIT;
|
m_pAmx->flags |= AMX_FLAG_PRENIT;
|
||||||
amx_PushString(m_pAmx, &hea_addr, &phys_addr, module, 0, 0);
|
amx_PushString(m_pAmx, &hea_addr, &phys_addr, module, 0, 0);
|
||||||
@ -943,6 +945,8 @@ int Handler::HandleModule(const char *module)
|
|||||||
amx_Release(m_pAmx, hea_addr);
|
amx_Release(m_pAmx, hea_addr);
|
||||||
m_pAmx->flags &= ~AMX_FLAG_PRENIT;
|
m_pAmx->flags &= ~AMX_FLAG_PRENIT;
|
||||||
|
|
||||||
|
EnableDebugHandler(m_pAmx);
|
||||||
|
|
||||||
if (err != AMX_ERR_NONE)
|
if (err != AMX_ERR_NONE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -966,6 +970,8 @@ int Handler::HandleNative(const char *native, int index, int trap)
|
|||||||
|
|
||||||
if (pDebugger && trap)
|
if (pDebugger && trap)
|
||||||
pDebugger->BeginExec();
|
pDebugger->BeginExec();
|
||||||
|
else if (pDebugger && !trap)
|
||||||
|
DisableDebugHandler(m_pAmx);
|
||||||
|
|
||||||
cell hea_addr, *phys_addr, retval;
|
cell hea_addr, *phys_addr, retval;
|
||||||
|
|
||||||
@ -1005,6 +1011,8 @@ int Handler::HandleNative(const char *native, int index, int trap)
|
|||||||
m_pAmx->flags &= ~AMX_FLAG_PRENIT;
|
m_pAmx->flags &= ~AMX_FLAG_PRENIT;
|
||||||
if (pDebugger && trap)
|
if (pDebugger && trap)
|
||||||
pDebugger->EndExec();
|
pDebugger->EndExec();
|
||||||
|
else if (pDebugger && !trap)
|
||||||
|
EnableDebugHandler(m_pAmx);
|
||||||
|
|
||||||
amx_Release(m_pAmx, hea_addr);
|
amx_Release(m_pAmx, hea_addr);
|
||||||
|
|
||||||
|
@ -454,6 +454,8 @@ int set_amxnatives(AMX* amx, char error[128])
|
|||||||
int idx, err;
|
int idx, err;
|
||||||
cell retval;
|
cell retval;
|
||||||
|
|
||||||
|
DisableDebugHandler(amx);
|
||||||
|
|
||||||
if (amx_FindPublic(amx, "plugin_natives", &idx) == AMX_ERR_NONE)
|
if (amx_FindPublic(amx, "plugin_natives", &idx) == AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
if ((err = amx_Exec(amx, &retval, idx)) != AMX_ERR_NONE)
|
if ((err = amx_Exec(amx, &retval, idx)) != AMX_ERR_NONE)
|
||||||
@ -463,6 +465,8 @@ int set_amxnatives(AMX* amx, char error[128])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EnableDebugHandler(amx);
|
||||||
|
|
||||||
amx->flags &= ~(AMX_FLAG_PRENIT);
|
amx->flags &= ~(AMX_FLAG_PRENIT);
|
||||||
|
|
||||||
return (amx->error = AMX_ERR_NONE);
|
return (amx->error = AMX_ERR_NONE);
|
||||||
@ -1689,6 +1693,22 @@ void *Module_ReqFnptr(const char *funcName)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisableDebugHandler(AMX *amx)
|
||||||
|
{
|
||||||
|
amx_SetDebugHook(amx, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnableDebugHandler(AMX *amx)
|
||||||
|
{
|
||||||
|
if (amx->flags & AMX_FLAG_DEBUG)
|
||||||
|
{
|
||||||
|
if (amx->userdata[UD_DEBUGGER] != NULL)
|
||||||
|
{
|
||||||
|
amx_SetDebugHook(amx, &Debugger::DebugHook);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined MEMORY_TEST && !defined WIN32
|
#if !defined MEMORY_TEST && !defined WIN32
|
||||||
void * ::operator new(size_t size)
|
void * ::operator new(size_t size)
|
||||||
{
|
{
|
||||||
|
@ -50,5 +50,7 @@
|
|||||||
|
|
||||||
int CheckModules(AMX *amx, char error[128]);
|
int CheckModules(AMX *amx, char error[128]);
|
||||||
const char *StrCaseStr(const char *as, const char *bs);
|
const char *StrCaseStr(const char *as, const char *bs);
|
||||||
|
void DisableDebugHandler(AMX *amx);
|
||||||
|
void EnableDebugHandler(AMX *amx);
|
||||||
|
|
||||||
#endif // __MODULES_H__
|
#endif // __MODULES_H__
|
||||||
|
@ -786,9 +786,6 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\CQueue.h">
|
RelativePath="..\CQueue.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\CStack.h">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\CString.h">
|
RelativePath="..\CString.h">
|
||||||
</File>
|
</File>
|
||||||
@ -825,6 +822,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\resource.h">
|
RelativePath="..\resource.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sh_stack.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\zlib\zconf.h">
|
RelativePath="..\zlib\zconf.h">
|
||||||
</File>
|
</File>
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
#include "CStack.h"
|
#include "sh_stack.h"
|
||||||
#include "natives.h"
|
#include "natives.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
@ -146,7 +146,7 @@ static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.top();
|
regnative *pNative = g_NativeStack.front();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -167,7 +167,7 @@ static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.top();
|
regnative *pNative = g_NativeStack.front();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -190,7 +190,7 @@ static cell AMX_NATIVE_CALL get_param(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.top();
|
regnative *pNative = g_NativeStack.front();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -209,7 +209,7 @@ static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.top();
|
regnative *pNative = g_NativeStack.front();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -230,7 +230,7 @@ static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.top();
|
regnative *pNative = g_NativeStack.front();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -253,7 +253,7 @@ static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.top();
|
regnative *pNative = g_NativeStack.front();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -279,7 +279,7 @@ static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.top();
|
regnative *pNative = g_NativeStack.front();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -308,7 +308,7 @@ static cell AMX_NATIVE_CALL param_convert(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.top();
|
regnative *pNative = g_NativeStack.front();
|
||||||
if (pNative->style != 1)
|
if (pNative->style != 1)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
|
219
amxmodx/sh_stack.h
Executable file
219
amxmodx/sh_stack.h
Executable file
@ -0,0 +1,219 @@
|
|||||||
|
/* ======== SourceMM ========
|
||||||
|
* Copyright (C) 2004-2005 Metamod:Source Development Team
|
||||||
|
* No warranties of any kind
|
||||||
|
*
|
||||||
|
* License: zlib/libpng
|
||||||
|
*
|
||||||
|
* Author(s): Pavol "PM OnoTo" Marko
|
||||||
|
* ============================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SH_STACK_H__
|
||||||
|
#define __SH_STACK_H__
|
||||||
|
|
||||||
|
#define SH_STACK_DEFAULT_SIZE 4
|
||||||
|
|
||||||
|
//namespace SourceHook
|
||||||
|
//{/
|
||||||
|
// Vector
|
||||||
|
template <class T> class CStack
|
||||||
|
{
|
||||||
|
T *m_Elements;
|
||||||
|
size_t m_AllocatedSize;
|
||||||
|
size_t m_UsedSize;
|
||||||
|
public:
|
||||||
|
friend class iterator;
|
||||||
|
class iterator
|
||||||
|
{
|
||||||
|
CStack<T> *m_pParent;
|
||||||
|
size_t m_Index;
|
||||||
|
public:
|
||||||
|
iterator(CStack<T> *pParent, size_t id) : m_pParent(pParent), m_Index(id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator(CStack<T> *pParent) : m_pParent(pParent), m_Index(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator() : m_pParent(NULL), m_Index(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
T &operator *()
|
||||||
|
{
|
||||||
|
return m_pParent->m_Elements[m_Index];
|
||||||
|
}
|
||||||
|
const T &operator *() const
|
||||||
|
{
|
||||||
|
return m_pParent->m_Elements[m_Index];
|
||||||
|
}
|
||||||
|
|
||||||
|
T * operator->()
|
||||||
|
{
|
||||||
|
return m_pParent->m_Elements + m_Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T * operator->() const
|
||||||
|
{
|
||||||
|
return m_pParent->m_Elements + m_Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator & operator++() // preincrement
|
||||||
|
{
|
||||||
|
++m_Index;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator operator++(int) // postincrement
|
||||||
|
{
|
||||||
|
iterator tmp = *this;
|
||||||
|
++m_Index;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator & operator--() // predecrement
|
||||||
|
{
|
||||||
|
--m_Index;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator operator--(int) // postdecrememnt
|
||||||
|
{
|
||||||
|
iterator tmp = *this;
|
||||||
|
--m_Index;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const iterator & right) const
|
||||||
|
{
|
||||||
|
return (m_pParent == right.m_pParent && m_Index == right.m_Index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const iterator & right) const
|
||||||
|
{
|
||||||
|
return !(*this == right);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
CStack() : m_Elements(new T[SH_STACK_DEFAULT_SIZE]),
|
||||||
|
m_AllocatedSize(SH_STACK_DEFAULT_SIZE),
|
||||||
|
m_UsedSize(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
CStack(size_t size) : m_Elements(new T[size]),
|
||||||
|
m_AllocatedSize(size),
|
||||||
|
m_UsedSize(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CStack(const CStack &other) : m_Elements(NULL),
|
||||||
|
m_AllocatedSize(0),
|
||||||
|
m_UsedSize(0)
|
||||||
|
{
|
||||||
|
reserve(other.m_AllocatedSize);
|
||||||
|
m_UsedSize = other.m_UsedSize;
|
||||||
|
for (size_t i = 0; i < m_UsedSize; ++i)
|
||||||
|
m_Elements[i] = other.m_Elements[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
~CStack()
|
||||||
|
{
|
||||||
|
if (m_Elements)
|
||||||
|
delete [] m_Elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator=(const CStack &other)
|
||||||
|
{
|
||||||
|
if (m_AllocatedSize < other.m_AllocatedSize)
|
||||||
|
{
|
||||||
|
if (m_Elements)
|
||||||
|
delete [] m_Elements;
|
||||||
|
m_Elements = new T[other.m_AllocatedSize];
|
||||||
|
m_AllocatedSize = other.m_AllocatedSize;
|
||||||
|
}
|
||||||
|
m_UsedSize = other.m_UsedSize;
|
||||||
|
for (size_t i = 0; i < m_UsedSize; ++i)
|
||||||
|
m_Elements[i] = other.m_Elements[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool push(const T &val)
|
||||||
|
{
|
||||||
|
if (m_UsedSize + 1 == m_AllocatedSize)
|
||||||
|
{
|
||||||
|
// zOHNOES! REALLOCATE!
|
||||||
|
m_AllocatedSize *= 2;
|
||||||
|
T *newElements = new T[m_AllocatedSize];
|
||||||
|
if (!newElements)
|
||||||
|
{
|
||||||
|
m_AllocatedSize /= 2;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (m_Elements)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < m_UsedSize; ++i)
|
||||||
|
newElements[i] = m_Elements[i];
|
||||||
|
delete [] m_Elements;
|
||||||
|
}
|
||||||
|
m_Elements = newElements;
|
||||||
|
}
|
||||||
|
m_Elements[m_UsedSize++] = val;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void pop()
|
||||||
|
{
|
||||||
|
--m_UsedSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
T &front()
|
||||||
|
{
|
||||||
|
return m_Elements[m_UsedSize - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
const T &front() const
|
||||||
|
{
|
||||||
|
return m_Elements[m_UsedSize - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator begin()
|
||||||
|
{
|
||||||
|
return iterator(this, 0);
|
||||||
|
}
|
||||||
|
iterator end()
|
||||||
|
{
|
||||||
|
return iterator(this, m_UsedSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size()
|
||||||
|
{
|
||||||
|
return m_UsedSize;
|
||||||
|
}
|
||||||
|
size_t capacity()
|
||||||
|
{
|
||||||
|
return m_AllocatedSize;
|
||||||
|
}
|
||||||
|
bool empty()
|
||||||
|
{
|
||||||
|
return m_UsedSize == 0 ? true : false;
|
||||||
|
}
|
||||||
|
bool reserve(size_t size)
|
||||||
|
{
|
||||||
|
if (size > m_AllocatedSize)
|
||||||
|
{
|
||||||
|
T *newElements = new T[size];
|
||||||
|
if (!newElements)
|
||||||
|
return false;
|
||||||
|
if (m_Elements)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < m_UsedSize; ++i)
|
||||||
|
newElements[i] = m_Elements[i];
|
||||||
|
delete [] m_Elements;
|
||||||
|
}
|
||||||
|
m_Elements = newElements;
|
||||||
|
m_AllocatedSize = size;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//}; //namespace SourceHook
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user