summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoryexo <yexo@openttd.org>2009-05-25 21:55:47 +0000
committeryexo <yexo@openttd.org>2009-05-25 21:55:47 +0000
commit7425bf779d8bd989d51f3844c5e70bbe352962cc (patch)
tree671c5529d9e8fb8ec5449e091b2d322e89cd5097 /src
parent9355d1d16981a7a0803aae1f1103900fea095bca (diff)
downloadopenttd-7425bf779d8bd989d51f3844c5e70bbe352962cc.tar.xz
(svn r16425) -Change [FS#2869]: Stop an AI when it takes too long to initialize or load
Diffstat (limited to 'src')
-rw-r--r--src/ai/ai_instance.cpp14
-rw-r--r--src/script/squirrel.cpp2
2 files changed, 12 insertions, 4 deletions
diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp
index 0ab577a0e..2edb7db42 100644
--- a/src/ai/ai_instance.cpp
+++ b/src/ai/ai_instance.cpp
@@ -304,9 +304,17 @@ void AIInstance::GameLoop()
AIObject::SetAllowDoCommand(false);
/* Run the constructor if it exists. Don't allow any DoCommands in it. */
if (this->engine->MethodExists(*this->instance, "constructor")) {
- if (!this->engine->CallMethod(*this->instance, "constructor")) { this->Died(); return; }
+ if (!this->engine->CallMethod(*this->instance, "constructor", 100000) || this->engine->IsSuspended()) {
+ if (this->engine->IsSuspended()) AILog::Error("This AI took too long to initialize. AI is not started.");
+ this->Died();
+ return;
+ }
+ }
+ if (!this->CallLoad() || this->engine->IsSuspended()) {
+ if (this->engine->IsSuspended()) AILog::Error("This AI took too long in the Load function. AI is not started.");
+ this->Died();
+ return;
}
- if (!this->CallLoad()) { this->Died(); return; }
AIObject::SetAllowDoCommand(true);
/* Start the AI by calling Start() */
if (!this->engine->CallMethod(*this->instance, "Start", _settings_game.ai.ai_max_opcode_till_suspend) || !this->engine->IsSuspended()) this->Died();
@@ -702,7 +710,7 @@ bool AIInstance::CallLoad()
/* Call the AI load function. sq_call removes the arguments (but not the
* function pointer) from the stack. */
- if (SQ_FAILED(sq_call(vm, 3, SQFalse, SQFalse))) return false;
+ if (SQ_FAILED(sq_call(vm, 3, SQFalse, SQFalse, 100000))) return false;
/* Pop 1) The version, 2) the savegame data, 3) the object instance, 4) the function pointer. */
sq_pop(vm, 4);
diff --git a/src/script/squirrel.cpp b/src/script/squirrel.cpp
index f31b813da..6737fd3ef 100644
--- a/src/script/squirrel.cpp
+++ b/src/script/squirrel.cpp
@@ -209,7 +209,7 @@ bool Squirrel::CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT
if (ret != NULL) sq_getstackobj(vm, -1, ret);
/* Reset the top, but don't do so for the AI main function, as we need
* a correct stack when resuming. */
- if (suspend == -1) sq_settop(this->vm, top);
+ if (!this->IsSuspended()) sq_settop(this->vm, top);
/* Restore the return-value location. */
this->vm->_suspended_target = last_target;