From 6b0520b3b4d8382c59d0b11d28a8c74142c56581 Mon Sep 17 00:00:00 2001 From: yexo Date: Thu, 20 Aug 2009 10:39:39 +0000 Subject: [PATCH] (svn r17230) -Fix (r15027): don't assert when an AI uses AI*Mode objects incorrectly but crash the AI instead --- src/3rdparty/squirrel/squirrel/sqclass.h | 12 +++++++++++- src/ai/ai_instance.cpp | 2 ++ src/ai/api/ai_execmode.cpp | 11 ++++++++++- src/ai/api/ai_testmode.cpp | 11 ++++++++++- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/squirrel/squirrel/sqclass.h b/src/3rdparty/squirrel/squirrel/sqclass.h index 06f2b51e9d..895c053c24 100644 --- a/src/3rdparty/squirrel/squirrel/sqclass.h +++ b/src/3rdparty/squirrel/squirrel/sqclass.h @@ -128,7 +128,17 @@ public: } void Release() { _uiRef++; - if (_hook) { _hook(_userpointer,0);} + try { + if (_hook) { _hook(_userpointer,0);} + } catch (...) { + _uiRef--; + if (_uiRef == 0) { + SQInteger size = _memsize; + this->~SQInstance(); + SQ_FREE(this, size); + } + throw; + } _uiRef--; if(_uiRef > 0) return; SQInteger size = _memsize; diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp index a5ef5135b6..6e1ffa0c16 100644 --- a/src/ai/ai_instance.cpp +++ b/src/ai/ai_instance.cpp @@ -353,6 +353,7 @@ void AIInstance::GameLoop() this->suspend = e.GetSuspendTime(); this->callback = e.GetSuspendCallback(); } catch (AI_FatalError e) { + this->is_dead = true; this->engine->ThrowError(e.GetErrorMessage()); this->engine->ResumeError(); this->Died(); @@ -373,6 +374,7 @@ void AIInstance::GameLoop() this->suspend = e.GetSuspendTime(); this->callback = e.GetSuspendCallback(); } catch (AI_FatalError e) { + this->is_dead = true; this->engine->ThrowError(e.GetErrorMessage()); this->engine->ResumeError(); this->Died(); diff --git a/src/ai/api/ai_execmode.cpp b/src/ai/api/ai_execmode.cpp index 941718bee1..b51adfd484 100644 --- a/src/ai/api/ai_execmode.cpp +++ b/src/ai/api/ai_execmode.cpp @@ -4,6 +4,9 @@ #include "ai_execmode.hpp" #include "../../command_type.h" +#include "../../company_base.h" +#include "../../company_func.h" +#include "../ai_instance.hpp" bool AIExecMode::ModeProc(TileIndex tile, uint32 p1, uint32 p2, uint procc, CommandCost costs) { @@ -21,6 +24,12 @@ AIExecMode::AIExecMode() AIExecMode::~AIExecMode() { - assert(this->GetDoCommandModeInstance() == this); + if (this->GetDoCommandModeInstance() != this) { + AIInstance *instance = Company::Get(_current_company)->ai_instance; + /* Ignore this error if the AI already died. */ + if (!instance->IsDead()) { + throw AI_FatalError("AIExecMode object was removed while it was not the latest AI*Mode object created."); + } + } this->SetDoCommandMode(this->last_mode, this->last_instance); } diff --git a/src/ai/api/ai_testmode.cpp b/src/ai/api/ai_testmode.cpp index 484333b422..1143667221 100644 --- a/src/ai/api/ai_testmode.cpp +++ b/src/ai/api/ai_testmode.cpp @@ -4,6 +4,9 @@ #include "ai_testmode.hpp" #include "../../command_type.h" +#include "../../company_base.h" +#include "../../company_func.h" +#include "../ai_instance.hpp" bool AITestMode::ModeProc(TileIndex tile, uint32 p1, uint32 p2, uint procc, CommandCost costs) { @@ -21,6 +24,12 @@ AITestMode::AITestMode() AITestMode::~AITestMode() { - assert(this->GetDoCommandModeInstance() == this); + if (this->GetDoCommandModeInstance() != this) { + AIInstance *instance = Company::Get(_current_company)->ai_instance; + /* Ignore this error if the AI already died. */ + if (!instance->IsDead()) { + throw AI_FatalError("AITestmode object was removed while it was not the latest AI*Mode object created."); + } + } this->SetDoCommandMode(this->last_mode, this->last_instance); }