From 31f6c0cb185f5a71dd74ccc7c352a8864438b711 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 17 Nov 2021 18:19:40 -0800 Subject: [PATCH 1/2] Dedent some menu code for readability. --- core/logic/smn_menus.cpp | 167 +++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 85 deletions(-) diff --git a/core/logic/smn_menus.cpp b/core/logic/smn_menus.cpp index 9c6c130b..40926ab2 100644 --- a/core/logic/smn_menus.cpp +++ b/core/logic/smn_menus.cpp @@ -1,5 +1,5 @@ /** - * vim: set ts=4 : + * vim: set ts=4 sw=4 tw=99 noet : * ============================================================================= * SourceMod * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. @@ -141,10 +141,6 @@ public: void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style); unsigned int OnMenuDisplayItem(IBaseMenu *menu, int client, IMenuPanel *panel, unsigned int item, const ItemDrawInfo &dr); bool OnSetHandlerOption(const char *option, const void *data); -#if 0 - void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style); - void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display); -#endif private: cell_t DoAction(IBaseMenu *menu, MenuAction action, cell_t param1, cell_t param2, cell_t def_res=0); private: @@ -496,98 +492,99 @@ void CMenuHandler::OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t * unsigned int winning_votes = results->item_list[0].count; DoAction(menu, MenuAction_VoteEnd, winning_item, (total_votes << 16) | (winning_votes & 0xFFFF)); - } else { - IPluginContext *pContext = m_pVoteResults->GetParentContext(); - bool no_call = false; - int err; + return; + } - /* First array */ - cell_t client_array_address = -1; - cell_t *client_array_base = NULL; - cell_t client_array_size = results->num_clients + (results->num_clients * 2); - if (client_array_size) + IPluginContext *pContext = m_pVoteResults->GetParentContext(); + bool no_call = false; + int err; + + /* First array */ + cell_t client_array_address = -1; + cell_t *client_array_base = NULL; + cell_t client_array_size = results->num_clients + (results->num_clients * 2); + if (client_array_size) + { + if ((err = pContext->HeapAlloc(client_array_size, &client_array_address, &client_array_base)) + != SP_ERROR_NONE) { - if ((err = pContext->HeapAlloc(client_array_size, &client_array_address, &client_array_base)) - != SP_ERROR_NONE) + g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for client list.", client_array_size * sizeof(cell_t)); + no_call = true; + } else { + cell_t target_offs = sizeof(cell_t) * results->num_clients; + cell_t *cur_index = client_array_base; + cell_t *cur_array; + for (unsigned int i=0; inum_clients; i++) { - g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for client list.", client_array_size * sizeof(cell_t)); - no_call = true; - } else { - cell_t target_offs = sizeof(cell_t) * results->num_clients; - cell_t *cur_index = client_array_base; - cell_t *cur_array; - for (unsigned int i=0; inum_clients; i++) - { - /* Copy the array index */ - *cur_index = target_offs; - /* Get the current array address */ - cur_array = (cell_t *)((char *)cur_index + target_offs); - /* Store information */ - cur_array[0] = results->client_list[i].client; - cur_array[1] = results->client_list[i].item; - /* Adjust for the new target by subtracting one indirection - * and adding one array. - */ - target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t); - cur_index++; - } + /* Copy the array index */ + *cur_index = target_offs; + /* Get the current array address */ + cur_array = (cell_t *)((char *)cur_index + target_offs); + /* Store information */ + cur_array[0] = results->client_list[i].client; + cur_array[1] = results->client_list[i].item; + /* Adjust for the new target by subtracting one indirection + * and adding one array. + */ + target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t); + cur_index++; } } + } - /* Second array */ - cell_t item_array_address = -1; - cell_t *item_array_base = NULL; - cell_t item_array_size = results->num_items + (results->num_items * 2); - if (item_array_size) + /* Second array */ + cell_t item_array_address = -1; + cell_t *item_array_base = NULL; + cell_t item_array_size = results->num_items + (results->num_items * 2); + if (item_array_size) + { + if ((err = pContext->HeapAlloc(item_array_size, &item_array_address, &item_array_base)) + != SP_ERROR_NONE) { - if ((err = pContext->HeapAlloc(item_array_size, &item_array_address, &item_array_base)) - != SP_ERROR_NONE) + g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for item list.", item_array_size); + no_call = true; + } else { + cell_t target_offs = sizeof(cell_t) * results->num_items; + cell_t *cur_index = item_array_base; + cell_t *cur_array; + for (unsigned int i=0; inum_items; i++) { - g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for item list.", item_array_size); - no_call = true; - } else { - cell_t target_offs = sizeof(cell_t) * results->num_items; - cell_t *cur_index = item_array_base; - cell_t *cur_array; - for (unsigned int i=0; inum_items; i++) - { - /* Copy the array index */ - *cur_index = target_offs; - /* Get the current array address */ - cur_array = (cell_t *)((char *)cur_index + target_offs); - /* Store information */ - cur_array[0] = results->item_list[i].item; - cur_array[1] = results->item_list[i].count; - /* Adjust for the new target by subtracting one indirection - * and adding one array. - */ - target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t); - cur_index++; - } + /* Copy the array index */ + *cur_index = target_offs; + /* Get the current array address */ + cur_array = (cell_t *)((char *)cur_index + target_offs); + /* Store information */ + cur_array[0] = results->item_list[i].item; + cur_array[1] = results->item_list[i].count; + /* Adjust for the new target by subtracting one indirection + * and adding one array. + */ + target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t); + cur_index++; } } + } - /* Finally, push everything */ - if (!no_call) - { - m_pVoteResults->PushCell(menu->GetHandle()); - m_pVoteResults->PushCell(results->num_votes); - m_pVoteResults->PushCell(results->num_clients); - m_pVoteResults->PushCell(client_array_address); - m_pVoteResults->PushCell(results->num_items); - m_pVoteResults->PushCell(item_array_address); - m_pVoteResults->Execute(NULL); - } + /* Finally, push everything */ + if (!no_call) + { + m_pVoteResults->PushCell(menu->GetHandle()); + m_pVoteResults->PushCell(results->num_votes); + m_pVoteResults->PushCell(results->num_clients); + m_pVoteResults->PushCell(client_array_address); + m_pVoteResults->PushCell(results->num_items); + m_pVoteResults->PushCell(item_array_address); + m_pVoteResults->Execute(NULL); + } - /* Free what we allocated, in reverse order as required */ - if (item_array_address != -1) - { - pContext->HeapPop(item_array_address); - } - if (client_array_address != -1) - { - pContext->HeapPop(client_array_address); - } + /* Free what we allocated, in reverse order as required */ + if (item_array_address != -1) + { + pContext->HeapPop(item_array_address); + } + if (client_array_address != -1) + { + pContext->HeapPop(client_array_address); } } From 96c74651db6cb0b3308669a9f4cb8bcbabccbb68 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 17 Nov 2021 18:47:16 -0800 Subject: [PATCH 2/2] Fix vote menu handler to work with direct arrays. --- core/logic/DebugReporter.cpp | 12 ++-- core/logic/DebugReporter.h | 2 + core/logic/smn_menus.cpp | 109 ++++++++++------------------------- sourcepawn | 2 +- 4 files changed, 39 insertions(+), 86 deletions(-) diff --git a/core/logic/DebugReporter.cpp b/core/logic/DebugReporter.cpp index 5c5be839..4d733b5f 100644 --- a/core/logic/DebugReporter.cpp +++ b/core/logic/DebugReporter.cpp @@ -69,13 +69,13 @@ void DebugReport::GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, ke::SafeVsprintf(buffer, sizeof(buffer), message, ap); const char *plname = pluginsys->FindPluginByContext(ctx->GetContext())->GetFilename(); - const char *error = g_pSourcePawn2->GetErrorString(err); - if (error) - { - g_Logger.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error); - } else { - g_Logger.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err); + if (err >= 0) { + const char *error = g_pSourcePawn2->GetErrorString(err); + if (error) + g_Logger.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error); + else + g_Logger.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err); } g_Logger.LogError("[SM] %s", buffer); diff --git a/core/logic/DebugReporter.h b/core/logic/DebugReporter.h index 27b54a9b..e79b8932 100644 --- a/core/logic/DebugReporter.h +++ b/core/logic/DebugReporter.h @@ -47,6 +47,8 @@ public: // IDebugListener void ReportError(const IErrorReport &report, IFrameIterator &iter); void OnDebugSpew(const char *msg, ...); public: + // If err is -1, caller assumes the automatic reporting by SourcePawn is + // good enough, and only wants the supplemental logging provided here. void GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...); void GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, const char *message, va_list ap); void GenerateCodeError(IPluginContext *ctx, uint32_t code_addr, int err, const char *message, ...); diff --git a/core/logic/smn_menus.cpp b/core/logic/smn_menus.cpp index 40926ab2..c44d0970 100644 --- a/core/logic/smn_menus.cpp +++ b/core/logic/smn_menus.cpp @@ -496,96 +496,47 @@ void CMenuHandler::OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t * } IPluginContext *pContext = m_pVoteResults->GetParentContext(); - bool no_call = false; - int err; + AutoEnterHeapScope heap_scope(pContext); /* First array */ cell_t client_array_address = -1; - cell_t *client_array_base = NULL; - cell_t client_array_size = results->num_clients + (results->num_clients * 2); - if (client_array_size) - { - if ((err = pContext->HeapAlloc(client_array_size, &client_array_address, &client_array_base)) - != SP_ERROR_NONE) - { - g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for client list.", client_array_size * sizeof(cell_t)); - no_call = true; - } else { - cell_t target_offs = sizeof(cell_t) * results->num_clients; - cell_t *cur_index = client_array_base; - cell_t *cur_array; - for (unsigned int i=0; inum_clients; i++) - { - /* Copy the array index */ - *cur_index = target_offs; - /* Get the current array address */ - cur_array = (cell_t *)((char *)cur_index + target_offs); - /* Store information */ - cur_array[0] = results->client_list[i].client; - cur_array[1] = results->client_list[i].item; - /* Adjust for the new target by subtracting one indirection - * and adding one array. - */ - target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t); - cur_index++; - } + if (cell_t client_array_size = results->num_clients * 2) { + auto init = std::make_unique(client_array_size); + for (unsigned int i = 0; i < results->num_clients; i++) { + init[i * 2] = results->client_list[i].client; + init[i * 2 + 1] = results->client_list[i].item; + } + + if (!pContext->HeapAlloc2dArray(results->num_clients, 2, &client_array_address, init.get())) { + g_DbgReporter.GenerateError(pContext, m_fnVoteResult, -1, + "Menu callback could not allocate cells for client list."); + return; } } /* Second array */ cell_t item_array_address = -1; - cell_t *item_array_base = NULL; - cell_t item_array_size = results->num_items + (results->num_items * 2); - if (item_array_size) - { - if ((err = pContext->HeapAlloc(item_array_size, &item_array_address, &item_array_base)) - != SP_ERROR_NONE) - { - g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for item list.", item_array_size); - no_call = true; - } else { - cell_t target_offs = sizeof(cell_t) * results->num_items; - cell_t *cur_index = item_array_base; - cell_t *cur_array; - for (unsigned int i=0; inum_items; i++) - { - /* Copy the array index */ - *cur_index = target_offs; - /* Get the current array address */ - cur_array = (cell_t *)((char *)cur_index + target_offs); - /* Store information */ - cur_array[0] = results->item_list[i].item; - cur_array[1] = results->item_list[i].count; - /* Adjust for the new target by subtracting one indirection - * and adding one array. - */ - target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t); - cur_index++; - } + if (cell_t item_array_size = results->num_items * 2) { + auto init = std::make_unique(item_array_size); + for (unsigned int i = 0; i < results->num_items; i++) { + init[i * 2] = results->item_list[i].item; + init[i * 2 + 1] = results->item_list[i].count; + } + if (!pContext->HeapAlloc2dArray(results->num_items, 2, &item_array_address, init.get())) { + g_DbgReporter.GenerateError(pContext, m_fnVoteResult, -1, + "Menu callback could not allocate %d cells for item list.", + item_array_size); + return; } } - /* Finally, push everything */ - if (!no_call) - { - m_pVoteResults->PushCell(menu->GetHandle()); - m_pVoteResults->PushCell(results->num_votes); - m_pVoteResults->PushCell(results->num_clients); - m_pVoteResults->PushCell(client_array_address); - m_pVoteResults->PushCell(results->num_items); - m_pVoteResults->PushCell(item_array_address); - m_pVoteResults->Execute(NULL); - } - - /* Free what we allocated, in reverse order as required */ - if (item_array_address != -1) - { - pContext->HeapPop(item_array_address); - } - if (client_array_address != -1) - { - pContext->HeapPop(client_array_address); - } + m_pVoteResults->PushCell(menu->GetHandle()); + m_pVoteResults->PushCell(results->num_votes); + m_pVoteResults->PushCell(results->num_clients); + m_pVoteResults->PushCell(client_array_address); + m_pVoteResults->PushCell(results->num_items); + m_pVoteResults->PushCell(item_array_address); + m_pVoteResults->Execute(NULL); } bool CMenuHandler::OnSetHandlerOption(const char *option, const void *data) diff --git a/sourcepawn b/sourcepawn index 385d304e..7cb5bede 160000 --- a/sourcepawn +++ b/sourcepawn @@ -1 +1 @@ -Subproject commit 385d304ea81f1a2484b9638b275387b1e10efce2 +Subproject commit 7cb5bede74c184b9b1de4dbf6b0bfc2d23c4a17e