From cbcc91cc09e166231192e8b789382ecf1cfdee19 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 22 Nov 2005 04:14:07 +0000 Subject: [PATCH] BETA optimizations --- amxmodx/CLang.cpp | 54 +++++------ amxmodx/CTask.cpp | 164 +++++++++++++++++++-------------- amxmodx/CTask.h | 21 +++-- amxmodx/amxmodx.cpp | 6 ++ amxmodx/msvc/amxmodx_mm.vcproj | 24 ++++- amxmodx/sh_list.h | 53 ++++++++++- amxmodx/string.cpp | 12 +-- 7 files changed, 213 insertions(+), 121 deletions(-) diff --git a/amxmodx/CLang.cpp b/amxmodx/CLang.cpp index cd81bd8f..68ecff52 100755 --- a/amxmodx/CLang.cpp +++ b/amxmodx/CLang.cpp @@ -328,6 +328,14 @@ int CLangMngr::GetKeyEntry(String &key) * FORMATTING ROUTINES */ +#define FMTPM_NEXTPARAM() \ + if (*param > numParams) { \ + LogError(amx, AMX_ERR_PARAMS, "String formatted incorrectly - parameter %d (total %d)", *param, numParams); \ + return 0; \ + } \ + _addr = params[*param]; \ + addr = get_amxaddr(amx, _addr); \ + (*param)++; #define MAX_LEVELS 4 @@ -342,14 +350,7 @@ size_t do_amx_format_parameter(AMX *amx, cell *params, const char **fmtstr, int const char *fmtsrc = *fmtstr; char ctrl_code; int numParams = params[0] / sizeof(cell); - if (*param > numParams) - { - LogError(amx, AMX_ERR_PARAMS, "String formatted incorrectly - parameter %d (total %d)", *param, numParams); - return 0; - } - cell _addr = params[*param]; - cell *addr = get_amxaddr(amx, _addr); - (*param)++; + cell _addr, *addr; if (level >= MAX_LEVELS) { @@ -382,6 +383,7 @@ size_t do_amx_format_parameter(AMX *amx, cell *params, const char **fmtstr, int { case 's': { + FMTPM_NEXTPARAM(); get_amxstring_r(amx, _addr, tmp_buf, 2047); return _snprintf(output, maxlen, fmtptr, tmp_buf); break; @@ -389,6 +391,7 @@ size_t do_amx_format_parameter(AMX *amx, cell *params, const char **fmtstr, int case 'g': case 'f': { + FMTPM_NEXTPARAM(); return _snprintf(output, maxlen, fmtptr, *(REAL *)addr); break; } @@ -396,11 +399,13 @@ size_t do_amx_format_parameter(AMX *amx, cell *params, const char **fmtstr, int case 'd': case 'c': { + FMTPM_NEXTPARAM(); return _snprintf(output, maxlen, fmtptr, (int)addr[0]); break; } case 'L': { + FMTPM_NEXTPARAM(); const char *pLangName = NULL; const char *def = NULL, *key = NULL; int status; @@ -428,8 +433,7 @@ size_t do_amx_format_parameter(AMX *amx, cell *params, const char **fmtstr, int if (!pLangName || !isalpha(pLangName[0])) pLangName = "en"; //next parameter! - _addr = params[*param]; - (*param)++; + FMTPM_NEXTPARAM(); key = get_amxstring(amx, _addr, 1, tmpLen); def = g_langMngr.GetDef(pLangName, key, status); @@ -467,27 +471,14 @@ size_t do_amx_format_parameter(AMX *amx, cell *params, const char **fmtstr, int } } -#define DUMP_CP_BUFFER(expr) \ - if (sofar > 0) { \ - if (sofar <= (int)maxlen) { \ - memcpy(output, save, sofar); \ - output += sofar; \ - maxlen -= sofar; \ - sofar = 0; \ - } else { \ - expr; \ - } \ - } - size_t do_amx_format(AMX *amx, cell *params, int *param, const char **lex, char *output, size_t maxlen, int level) -{ - int sofar = 0; +{ size_t written; size_t orig_maxlen = maxlen; const char *save = *lex; register const char *lexptr = save; - while (*lexptr) + while (*lexptr && maxlen) { switch (*lexptr) { @@ -496,13 +487,13 @@ size_t do_amx_format(AMX *amx, cell *params, int *param, const char **lex, char lexptr++; if (*lexptr == '%' || *lexptr == '\0') { - sofar+=2; + *output++ = *lexptr++; + *output++ = *lexptr++; + maxlen -= 2; } else { - DUMP_CP_BUFFER(break); written = do_amx_format_parameter(amx, params, &lexptr, param, output, maxlen, level + 1); output += written; maxlen -= written; - save = lexptr; } break; } @@ -510,7 +501,6 @@ size_t do_amx_format(AMX *amx, cell *params, int *param, const char **lex, char { if (level) { - DUMP_CP_BUFFER(break); lexptr++; switch (*lexptr) { @@ -532,18 +522,16 @@ size_t do_amx_format(AMX *amx, cell *params, int *param, const char **lex, char } lexptr++; maxlen--; - save = lexptr; break; } } default: { - lexptr++; - sofar++; + *output++ = *lexptr++; + maxlen--; } } } - DUMP_CP_BUFFER(;); *output = '\0'; *lex = lexptr; diff --git a/amxmodx/CTask.cpp b/amxmodx/CTask.cpp index 7e266769..c63654a4 100755 --- a/amxmodx/CTask.cpp +++ b/amxmodx/CTask.cpp @@ -68,8 +68,11 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, m_iRepeat = iRepeat; } - m_bAfterStart = (iFlags & 4) ? true : false; - m_bBeforeEnd = (iFlags & 8) ? true : false; + type = 0; + if (iFlags & 4) + type = 1; + if (iFlags & 8) + type = 2; m_fNextExecTime = fCurrentTime + m_fBase; @@ -80,12 +83,25 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, { 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); + cell *dest = m_pParams; + __asm + { + push esi; + push edi; + push ecx; + mov esi, pParams; + mov edi, dest; + mov ecx, iParamsLen; + rep movsd; + pop esi; + pop edi; + pop ecx; + }; + //memcpy(m_pParams, pParams, sizeof(cell) * iParamsLen); m_pParams[iParamsLen] = 0; } else { m_iParamLen = 0; @@ -102,18 +118,7 @@ void CTaskMngr::CTask::clear() m_iFunc = -1; } - m_iParamLen = 0; - - m_pPlugin = NULL; m_iId = 0; - m_fBase = 0.0f; - - m_iRepeat = 0; - m_bLoop = false; - m_bAfterStart = false; - m_bBeforeEnd = false; - m_iParamLen = 0; - m_fNextExecTime = 0.0f; } @@ -132,24 +137,29 @@ void CTaskMngr::CTask::resetNextExecTime(float fCurrentTime) m_fNextExecTime = fCurrentTime + m_fBase; } -void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft) +bool CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft) { bool execute = false; bool done = false; - - if (m_bAfterStart) + + switch (type) { - if (fCurrentTime - fTimeLeft + 1.0f >= m_fBase) - execute = true; - } - else if (m_bBeforeEnd) - { - if (fTimeLimit != 0.0f && (fTimeLeft + fTimeLimit * 60.0f) - fCurrentTime - 1.0f <= m_fBase) - execute = true; - } - else if (m_fNextExecTime <= fCurrentTime) - { - execute = true; + case 1: + { + if (fCurrentTime - fTimeLeft + 1.0f >= m_fBase) + execute = true; + break; + } + case 2: + { + if (fTimeLimit != 0.0f && (fTimeLeft + fTimeLimit * 60.0f) - fCurrentTime - 1.0f <= m_fBase) + execute = true; + break; + } + default: + { + execute = (m_fNextExecTime <= fCurrentTime) ? true : false; + } } if (execute) @@ -165,9 +175,6 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f executeForwards(m_iFunc, m_iId); } } - - if (isFree()) - return; // set new exec time OR remove the task if needed if (m_bLoop) @@ -178,14 +185,11 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f done = true; } - if (done) - { - clear(); - g_FreeTasks->push(this); - } else { + if (!done) m_fNextExecTime += m_fBase; - } } + + return done; } CTaskMngr::CTask::CTask() @@ -199,8 +203,7 @@ CTaskMngr::CTask::CTask() m_iRepeat = 0; m_bLoop = false; - m_bAfterStart = false; - m_bBeforeEnd = false; + type = 0; m_fNextExecTime = 0.0f; @@ -233,11 +236,9 @@ CTaskMngr::CTaskMngr() CTaskMngr::~CTaskMngr() { - while (!g_FreeTasks->empty()) - g_FreeTasks->pop(); + clear(); delete g_FreeTasks; - - m_Tasks.clear(); + g_FreeTasks = NULL; } void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft) @@ -256,30 +257,32 @@ void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlag CTask *pTmp = g_FreeTasks->front(); g_FreeTasks->pop(); pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime); + m_Tasks.unshift(pTmp); } else { // not found: make a new one CTask *pTmp = new CTask; pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime); - m_Tasks.put(pTmp); + m_Tasks.unshift(pTmp); } } int CTaskMngr::removeTasks(int iId, AMX *pAmx) { CTaskDescriptor descriptor(iId, pAmx); - TaskListIter iter = m_Tasks.find(descriptor); + List::iterator iter, end=m_Tasks.end(); int i = 0; - - while (iter) + + for (iter=m_Tasks.begin(); iter!=end; ) { - if (!iter->isFree()) + if ( descriptor == (*iter) ) { - iter->clear(); - g_FreeTasks->push(iter->getTask()); + g_FreeTasks->push( (*iter) ); + iter = m_Tasks.erase(iter); + ++i; + } else { + iter++; } - ++i; - iter = m_Tasks.find(++iter, descriptor); } return i; @@ -288,15 +291,17 @@ int CTaskMngr::removeTasks(int iId, AMX *pAmx) int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase) { CTaskDescriptor descriptor(iId, pAmx); - TaskListIter iter = m_Tasks.find(descriptor); + List::iterator iter, end=m_Tasks.end(); int i = 0; - while (iter) + for (iter=m_Tasks.begin(); iter!=end; iter++) { - iter->changeBase(fNewBase); - iter->resetNextExecTime(*m_pTmr_CurrentTime); - ++i; - iter = m_Tasks.find(++iter, descriptor); + if ( descriptor == (*iter) ) + { + (*iter)->changeBase(fNewBase); + (*iter)->resetNextExecTime(*m_pTmr_CurrentTime); + ++i; + } } return i; @@ -304,24 +309,49 @@ int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase) bool CTaskMngr::taskExists(int iId, AMX *pAmx) { - return m_Tasks.find(CTaskDescriptor(iId, pAmx)); + CTaskDescriptor descriptor(iId, pAmx); + List::iterator iter, end=m_Tasks.end(); + + for (iter=m_Tasks.begin(); iter!=end; iter++) + { + if ( descriptor == (*iter) ) + return true; + } + + return false; } void CTaskMngr::startFrame() { - for (TaskListIter iter = m_Tasks.begin(); iter; ++iter) + List::iterator iter, end=m_Tasks.end(); + CTask *pTask; + int ignored=0, used=0; + for (TaskListIter iter = m_Tasks.begin(); iter!=end;) { - if (iter->isFree()) - continue; - iter->executeIfRequired(*m_pTmr_CurrentTime, *m_pTmr_TimeLimit, *m_pTmr_TimeLeft); + pTask = (*iter); + if (pTask->executeIfRequired(*m_pTmr_CurrentTime, *m_pTmr_TimeLimit, *m_pTmr_TimeLeft)) + { + pTask->clear(); + iter = m_Tasks.erase(iter); + g_FreeTasks->push(pTask); + used++; + } else { + iter++; + ignored++; + } } } void CTaskMngr::clear() { - for (TaskListIter iter = m_Tasks.begin(); iter; ++iter) + while (!g_FreeTasks->empty()) { - if (!iter->isFree()) - iter->clear(); + delete g_FreeTasks->front(); + g_FreeTasks->pop(); } + + List::iterator iter, end=m_Tasks.end(); + for (iter=m_Tasks.begin(); iter!=end; iter++) + delete (*iter); + m_Tasks.clear(); } diff --git a/amxmodx/CTask.h b/amxmodx/CTask.h index b026cd9e..7629685b 100755 --- a/amxmodx/CTask.h +++ b/amxmodx/CTask.h @@ -32,6 +32,8 @@ #ifndef CTASK_H #define CTASK_H +#include "sh_list.h" + class CTaskMngr { public: @@ -45,18 +47,19 @@ public: int m_iFunc; int m_iRepeat; - bool m_bLoop; - bool m_bAfterStart; - bool m_bBeforeEnd; + int type; float m_fBase; // for normal tasks, stores the interval, for the others, stores the amount of time before start / after end int m_iParamLen; cell *m_pParams; cell m_ParamSize; - bool m_bFree; // execution float m_fNextExecTime; + + bool m_bFree; + bool m_bLoop; + public: void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime); void clear(); @@ -65,7 +68,7 @@ public: CPluginMngr::CPlugin *getPlugin() const; int getTaskId() const; - void executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft); // also removes the task if needed + bool executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft); // also removes the task if needed void changeBase(float fNewBase); void resetNextExecTime(float fCurrentTime); @@ -91,17 +94,17 @@ public: m_bFree = bFree; } - friend bool operator == (const CTask &left, const CTaskDescriptor &right) + friend bool operator == (const CTaskDescriptor &right, const CTask *left) { if (right.m_bFree) - return left.isFree(); + return left->isFree(); - return !left.isFree() && (right.m_pAmx ? left.getPlugin()->getAMX() == right.m_pAmx : true) && left.getTaskId() == right.m_iId; + return !left->isFree() && (right.m_pAmx ? left->getPlugin()->getAMX() == right.m_pAmx : true) && left->getTaskId() == right.m_iId; } }; /*** CTaskMngr priv members ***/ - typedef CList TaskList; + typedef List TaskList; typedef TaskList::iterator TaskListIter; TaskList m_Tasks; diff --git a/amxmodx/amxmodx.cpp b/amxmodx/amxmodx.cpp index d484d8d5..1774140b 100755 --- a/amxmodx/amxmodx.cpp +++ b/amxmodx/amxmodx.cpp @@ -3591,6 +3591,11 @@ static cell AMX_NATIVE_CALL amx_abort(AMX *amx, cell *params) return 1; } +static cell AMX_NATIVE_CALL get_tick_count(AMX *amx, cell *params) +{ + return GetTickCount(); +} + static cell AMX_NATIVE_CALL module_exists(AMX *amx, cell *params) { int len; @@ -3807,5 +3812,6 @@ AMX_NATIVE_INFO amxmodx_Natives[] = {"write_short", write_short}, {"write_string", write_string}, {"xvar_exists", xvar_exists}, + {"get_tick_count", get_tick_count}, {NULL, NULL} }; diff --git a/amxmodx/msvc/amxmodx_mm.vcproj b/amxmodx/msvc/amxmodx_mm.vcproj index dfa63e11..83e24a47 100755 --- a/amxmodx/msvc/amxmodx_mm.vcproj +++ b/amxmodx/msvc/amxmodx_mm.vcproj @@ -164,7 +164,7 @@ AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST" BasicRuntimeChecks="3" - RuntimeLibrary="5" + RuntimeLibrary="3" StructMemberAlignment="3" UsePrecompiledHeader="2" PrecompiledHeaderThrough="amxmodx.h" @@ -183,7 +183,7 @@ AdditionalOptions="/MACHINE:I386" AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj" OutputFile="memtestdebug/amxmodx_mm.dll" - Version="0.1" + Version="1.6.5.0" LinkIncremental="2" SuppressStartupBanner="TRUE" AdditionalLibraryDirectories="..\extra\lib_win32" @@ -372,10 +372,13 @@ CharacterSet="2"> @@ -404,8 +408,8 @@ IgnoreDefaultLibraryNames="MSVCRT" ModuleDefinitionFile="" GenerateDebugInformation="TRUE" - ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb" - GenerateMapFile="FALSE" + ProgramDatabaseFile=".\jitrelease/amxmodx_mm.pdb" + GenerateMapFile="TRUE" ImportLibrary=".\jitrelease/amxx_mm.lib"/> + + + @@ -684,6 +694,12 @@ + + + diff --git a/amxmodx/sh_list.h b/amxmodx/sh_list.h index 95884fce..aa1f93e3 100644 --- a/amxmodx/sh_list.h +++ b/amxmodx/sh_list.h @@ -11,6 +11,8 @@ #ifndef _INCLUDE_SMM_LIST_H #define _INCLUDE_SMM_LIST_H +#include "sh_stack.h" + //namespace SourceHook //{ //This class is from CSDM for AMX Mod X @@ -25,6 +27,7 @@ public: public: ListNode(const T & o) : obj(o) { }; ListNode() { }; + void Set(const T & o) { obj = o; } ~ListNode() { }; @@ -59,9 +62,49 @@ public: m_Head = NULL; } } + void unshift(const T &obj) + { + if (!m_Head->next) + { + push_back(obj); + return; + } + + ListNode *node; + if (m_FreeStack.empty()) + { + node = new ListNode(obj); + } else { + node = m_FreeStack.front(); + m_FreeStack.pop(); + node->Set(obj); + } + + //is the list one item circular? + /*bool realign = false; + if (m_Head->next == m_Head->prev) + { + m_Head->next->next = + }*/ + + node->next = m_Head->next; + node->prev = m_Head; + m_Head->next->prev = node; + m_Head->next = node; + + m_Size++; + } void push_back(const T &obj) { - ListNode *node = new ListNode(obj); + ListNode *node; + if (m_FreeStack.empty()) + { + node = new ListNode(obj); + } else { + node = m_FreeStack.front(); + m_FreeStack.pop(); + node->Set(obj); + } if (!m_Head->prev) { @@ -95,6 +138,11 @@ public: node = temp; } m_Size = 0; + while (!m_FreeStack.empty()) + { + delete m_FreeStack.front(); + m_FreeStack.pop(); + } } bool empty() { @@ -105,6 +153,7 @@ public: return m_Head->prev->obj; } private: + typename CStack m_FreeStack; ListNode *m_Head; size_t m_Size; public: @@ -225,7 +274,7 @@ public: pNode->next->prev = pNode->prev; } - delete pNode; + m_FreeStack.push(pNode); m_Size--; return iter; diff --git a/amxmodx/string.cpp b/amxmodx/string.cpp index 43b7c04b..7d592454 100755 --- a/amxmodx/string.cpp +++ b/amxmodx/string.cpp @@ -76,8 +76,8 @@ cell* get_amxaddr(AMX *amx, cell amx_addr) int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max) { - cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr)); - cell* start = dest; + register cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr)); + register cell* start = dest; while (max-- && *source) *dest++ = (cell)*source++; @@ -93,12 +93,12 @@ size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, int maxlen) register char *dest = destination; char *start = dest; - while (*source && maxlen-- > 0) + while (maxlen-- && *source) *dest++=(char)(*source++); - if (dest) - *dest = '\0'; - return --dest - start; + *dest = '\0'; + + return dest - start; } char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len)