Files @ r23730:3b11f535de42
Branch filter:

Location: cpp/openttd-patchpack/source/src/ai/ai_instance.cpp - annotation

Niels Martin Hansen
Change: Limit memory allocations for each Squirrel instance

This can avoid out-of-memory situations due to single scripts using up the entire address space.
Instead, scripts that go above the maximum are killed.
The maximum is default 1 GB per script, but can be configured by a setting.
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18617:524f2e0f54dc
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10768:5cefaf608914
r11702:a9dd3b59c546
r18503:2415d5323e8d
r18514:5b2abc88a36c
r18505:6589b19bd149
r18503:2415d5323e8d
r18510:9d33e9643f80
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18794:ee2a72bc7637
r18794:ee2a72bc7637
r18794:ee2a72bc7637
r10696:8dfe83e30d01
r18410:1bd03690d14c
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18561:e19e8462f369
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r23699:dd8e59969b49
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r18519:20a1d61386e6
r10696:8dfe83e30d01
r14248:a9050881acd7
r17142:9f8921b5eb4f
r12738:a48207b124c5
r21383:942c32fb8b0e
r21383:942c32fb8b0e
r18363:f8c9df886df8
r18506:b0c2bbd32450
r18506:b0c2bbd32450
r18363:f8c9df886df8
r18363:f8c9df886df8
r18363:f8c9df886df8
r18506:b0c2bbd32450
r10696:8dfe83e30d01
r18441:63bc631b2d9b
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18774:2977cce7e239
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18506:b0c2bbd32450
r18506:b0c2bbd32450
r10696:8dfe83e30d01
r15871:160137e412fc
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r12561:9dd086b8fc21
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18288:c88d987feac2
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18648:265efc219d1e
r12845:8860291369ea
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r19374:8b326f0c504b
r10696:8dfe83e30d01
r11019:05aa125fa51f
r11019:05aa125fa51f
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r19375:5e05c9787ff3
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r19376:dd573f88a83f
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r16919:3e56bcc94bb9
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18561:e19e8462f369
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r23699:dd8e59969b49
r10696:8dfe83e30d01
r11989:6b25ffd91182
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r21750:39b1b1a11c25
r21750:39b1b1a11c25
r21750:39b1b1a11c25
r21750:39b1b1a11c25
r21750:39b1b1a11c25
r21750:39b1b1a11c25
r21750:39b1b1a11c25
r21750:39b1b1a11c25
r21750:39b1b1a11c25
r21750:39b1b1a11c25
r21750:39b1b1a11c25
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18448:c2f5bd7dc1ae
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r11260:8b77925c74e7
r12982:748d96ecf4e4
r11260:8b77925c74e7
r11018:70054e4e8389
r10696:8dfe83e30d01
r11179:fb0ec074cbbc
r11179:fb0ec074cbbc
r11179:fb0ec074cbbc
r10696:8dfe83e30d01
r19539:8ff9f94e70e3
r12738:a48207b124c5
r12738:a48207b124c5
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18506:b0c2bbd32450
r11353:66f3a68f1504
r11353:66f3a68f1504
r11702:a9dd3b59c546
r19209:9bc5f0b2cb37
r23607:36c15679007d
r14635:a75264d517b7
r11779:84d29f0087f7
r23607:36c15679007d
r18501:8e3d905ea4bc
r18501:8e3d905ea4bc
r11779:84d29f0087f7
r11702:a9dd3b59c546
r10696:8dfe83e30d01
r18507:a734d5918322
r18512:1adfa053a958
r18512:1adfa053a958
r23730:3b11f535de42
r18512:1adfa053a958
r18512:1adfa053a958
r18512:1adfa053a958
r18512:1adfa053a958
r18513:8c2a4637defb
r18513:8c2a4637defb
r18513:8c2a4637defb
r18513:8c2a4637defb
r18513:8c2a4637defb
r18514:5b2abc88a36c
r18514:5b2abc88a36c
r18514:5b2abc88a36c
r18514:5b2abc88a36c
r18514:5b2abc88a36c
r18507:a734d5918322
r18507:a734d5918322
r18507:a734d5918322
r18507:a734d5918322
r18507:a734d5918322
r18507:a734d5918322
r18507:a734d5918322
r18507:a734d5918322
r18507:a734d5918322
r20236:61debbf7637d
r20236:61debbf7637d
r20236:61debbf7637d
r20236:61debbf7637d
r20236:61debbf7637d
r20236:61debbf7637d
r20236:61debbf7637d
r23607:36c15679007d
r20236:61debbf7637d
r20236:61debbf7637d
r20236:61debbf7637d
r18507:a734d5918322
r18507:a734d5918322
r18507:a734d5918322
r18507:a734d5918322
r18507:a734d5918322
r18507:a734d5918322
/* $Id$ */

/*
 * This file is part of OpenTTD.
 * OpenTTD 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, version 2.
 * OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file ai_instance.cpp Implementation of AIInstance. */

#include "../stdafx.h"
#include "../debug.h"
#include "../error.h"

#include "../script/squirrel_class.hpp"

#include "ai_config.hpp"
#include "ai_gui.hpp"
#include "ai.hpp"

#include "../script/script_storage.hpp"
#include "ai_info.hpp"
#include "ai_instance.hpp"

/* Manually include the Text glue. */
#include "../script/api/template/template_text.hpp.sq"

/* Convert all AI related classes to Squirrel data.
 * Note: this line is a marker in squirrel_export.sh. Do not change! */
#include "../script/api/ai/ai_accounting.hpp.sq"
#include "../script/api/ai/ai_airport.hpp.sq"
#include "../script/api/ai/ai_base.hpp.sq"
#include "../script/api/ai/ai_basestation.hpp.sq"
#include "../script/api/ai/ai_bridge.hpp.sq"
#include "../script/api/ai/ai_bridgelist.hpp.sq"
#include "../script/api/ai/ai_cargo.hpp.sq"
#include "../script/api/ai/ai_cargolist.hpp.sq"
#include "../script/api/ai/ai_company.hpp.sq"
#include "../script/api/ai/ai_controller.hpp.sq"
#include "../script/api/ai/ai_date.hpp.sq"
#include "../script/api/ai/ai_depotlist.hpp.sq"
#include "../script/api/ai/ai_engine.hpp.sq"
#include "../script/api/ai/ai_enginelist.hpp.sq"
#include "../script/api/ai/ai_error.hpp.sq"
#include "../script/api/ai/ai_event.hpp.sq"
#include "../script/api/ai/ai_event_types.hpp.sq"
#include "../script/api/ai/ai_execmode.hpp.sq"
#include "../script/api/ai/ai_gamesettings.hpp.sq"
#include "../script/api/ai/ai_group.hpp.sq"
#include "../script/api/ai/ai_grouplist.hpp.sq"
#include "../script/api/ai/ai_industry.hpp.sq"
#include "../script/api/ai/ai_industrylist.hpp.sq"
#include "../script/api/ai/ai_industrytype.hpp.sq"
#include "../script/api/ai/ai_industrytypelist.hpp.sq"
#include "../script/api/ai/ai_infrastructure.hpp.sq"
#include "../script/api/ai/ai_list.hpp.sq"
#include "../script/api/ai/ai_log.hpp.sq"
#include "../script/api/ai/ai_map.hpp.sq"
#include "../script/api/ai/ai_marine.hpp.sq"
#include "../script/api/ai/ai_order.hpp.sq"
#include "../script/api/ai/ai_rail.hpp.sq"
#include "../script/api/ai/ai_railtypelist.hpp.sq"
#include "../script/api/ai/ai_road.hpp.sq"
#include "../script/api/ai/ai_roadtypelist.hpp.sq"
#include "../script/api/ai/ai_sign.hpp.sq"
#include "../script/api/ai/ai_signlist.hpp.sq"
#include "../script/api/ai/ai_station.hpp.sq"
#include "../script/api/ai/ai_stationlist.hpp.sq"
#include "../script/api/ai/ai_subsidy.hpp.sq"
#include "../script/api/ai/ai_subsidylist.hpp.sq"
#include "../script/api/ai/ai_testmode.hpp.sq"
#include "../script/api/ai/ai_tile.hpp.sq"
#include "../script/api/ai/ai_tilelist.hpp.sq"
#include "../script/api/ai/ai_town.hpp.sq"
#include "../script/api/ai/ai_townlist.hpp.sq"
#include "../script/api/ai/ai_tunnel.hpp.sq"
#include "../script/api/ai/ai_vehicle.hpp.sq"
#include "../script/api/ai/ai_vehiclelist.hpp.sq"
#include "../script/api/ai/ai_waypoint.hpp.sq"
#include "../script/api/ai/ai_waypointlist.hpp.sq"

#include "../company_base.h"
#include "../company_func.h"

#include "../safeguards.h"

AIInstance::AIInstance() :
	ScriptInstance("AI")
{}

void AIInstance::Initialize(AIInfo *info)
{
	this->versionAPI = info->GetAPIVersion();

	/* Register the AIController (including the "import" command) */
	SQAIController_Register(this->engine);

	ScriptInstance::Initialize(info->GetMainScript(), info->GetInstanceName(), _current_company);
}

void AIInstance::RegisterAPI()
{
	ScriptInstance::RegisterAPI();

/* Register all classes */
	SQAIList_Register(this->engine);
	SQAIAccounting_Register(this->engine);
	SQAIAirport_Register(this->engine);
	SQAIBase_Register(this->engine);
	SQAIBaseStation_Register(this->engine);
	SQAIBridge_Register(this->engine);
	SQAIBridgeList_Register(this->engine);
	SQAIBridgeList_Length_Register(this->engine);
	SQAICargo_Register(this->engine);
	SQAICargoList_Register(this->engine);
	SQAICargoList_IndustryAccepting_Register(this->engine);
	SQAICargoList_IndustryProducing_Register(this->engine);
	SQAICargoList_StationAccepting_Register(this->engine);
	SQAICompany_Register(this->engine);
	SQAIDate_Register(this->engine);
	SQAIDepotList_Register(this->engine);
	SQAIEngine_Register(this->engine);
	SQAIEngineList_Register(this->engine);
	SQAIError_Register(this->engine);
	SQAIEvent_Register(this->engine);
	SQAIEventAircraftDestTooFar_Register(this->engine);
	SQAIEventCompanyAskMerger_Register(this->engine);
	SQAIEventCompanyBankrupt_Register(this->engine);
	SQAIEventCompanyInTrouble_Register(this->engine);
	SQAIEventCompanyMerger_Register(this->engine);
	SQAIEventCompanyNew_Register(this->engine);
	SQAIEventCompanyTown_Register(this->engine);
	SQAIEventController_Register(this->engine);
	SQAIEventDisasterZeppelinerCleared_Register(this->engine);
	SQAIEventDisasterZeppelinerCrashed_Register(this->engine);
	SQAIEventEngineAvailable_Register(this->engine);
	SQAIEventEnginePreview_Register(this->engine);
	SQAIEventExclusiveTransportRights_Register(this->engine);
	SQAIEventIndustryClose_Register(this->engine);
	SQAIEventIndustryOpen_Register(this->engine);
	SQAIEventRoadReconstruction_Register(this->engine);
	SQAIEventStationFirstVehicle_Register(this->engine);
	SQAIEventSubsidyAwarded_Register(this->engine);
	SQAIEventSubsidyExpired_Register(this->engine);
	SQAIEventSubsidyOffer_Register(this->engine);
	SQAIEventSubsidyOfferExpired_Register(this->engine);
	SQAIEventTownFounded_Register(this->engine);
	SQAIEventVehicleCrashed_Register(this->engine);
	SQAIEventVehicleLost_Register(this->engine);
	SQAIEventVehicleUnprofitable_Register(this->engine);
	SQAIEventVehicleWaitingInDepot_Register(this->engine);
	SQAIExecMode_Register(this->engine);
	SQAIGameSettings_Register(this->engine);
	SQAIGroup_Register(this->engine);
	SQAIGroupList_Register(this->engine);
	SQAIIndustry_Register(this->engine);
	SQAIIndustryList_Register(this->engine);
	SQAIIndustryList_CargoAccepting_Register(this->engine);
	SQAIIndustryList_CargoProducing_Register(this->engine);
	SQAIIndustryType_Register(this->engine);
	SQAIIndustryTypeList_Register(this->engine);
	SQAIInfrastructure_Register(this->engine);
	SQAILog_Register(this->engine);
	SQAIMap_Register(this->engine);
	SQAIMarine_Register(this->engine);
	SQAIOrder_Register(this->engine);
	SQAIRail_Register(this->engine);
	SQAIRailTypeList_Register(this->engine);
	SQAIRoad_Register(this->engine);
	SQAIRoadTypeList_Register(this->engine);
	SQAISign_Register(this->engine);
	SQAISignList_Register(this->engine);
	SQAIStation_Register(this->engine);
	SQAIStationList_Register(this->engine);
	SQAIStationList_Cargo_Register(this->engine);
	SQAIStationList_CargoPlanned_Register(this->engine);
	SQAIStationList_CargoPlannedByFrom_Register(this->engine);
	SQAIStationList_CargoPlannedByVia_Register(this->engine);
	SQAIStationList_CargoPlannedFromByVia_Register(this->engine);
	SQAIStationList_CargoPlannedViaByFrom_Register(this->engine);
	SQAIStationList_CargoWaiting_Register(this->engine);
	SQAIStationList_CargoWaitingByFrom_Register(this->engine);
	SQAIStationList_CargoWaitingByVia_Register(this->engine);
	SQAIStationList_CargoWaitingFromByVia_Register(this->engine);
	SQAIStationList_CargoWaitingViaByFrom_Register(this->engine);
	SQAIStationList_Vehicle_Register(this->engine);
	SQAISubsidy_Register(this->engine);
	SQAISubsidyList_Register(this->engine);
	SQAITestMode_Register(this->engine);
	SQAITile_Register(this->engine);
	SQAITileList_Register(this->engine);
	SQAITileList_IndustryAccepting_Register(this->engine);
	SQAITileList_IndustryProducing_Register(this->engine);
	SQAITileList_StationType_Register(this->engine);
	SQAITown_Register(this->engine);
	SQAITownEffectList_Register(this->engine);
	SQAITownList_Register(this->engine);
	SQAITunnel_Register(this->engine);
	SQAIVehicle_Register(this->engine);
	SQAIVehicleList_Register(this->engine);
	SQAIVehicleList_DefaultGroup_Register(this->engine);
	SQAIVehicleList_Depot_Register(this->engine);
	SQAIVehicleList_Group_Register(this->engine);
	SQAIVehicleList_SharedOrders_Register(this->engine);
	SQAIVehicleList_Station_Register(this->engine);
	SQAIWaypoint_Register(this->engine);
	SQAIWaypointList_Register(this->engine);
	SQAIWaypointList_Vehicle_Register(this->engine);

	if (!this->LoadCompatibilityScripts(this->versionAPI, AI_DIR)) this->Died();
}

void AIInstance::Died()
{
	ScriptInstance::Died();

	ShowAIDebugWindow(_current_company);

	const AIInfo *info = AIConfig::GetConfig(_current_company, AIConfig::SSS_FORCE_GAME)->GetInfo();
	if (info != nullptr) {
		ShowErrorMessage(STR_ERROR_AI_PLEASE_REPORT_CRASH, INVALID_STRING_ID, WL_WARNING);

		if (info->GetURL() != nullptr) {
			ScriptLog::Info("Please report the error to the following URL:");
			ScriptLog::Info(info->GetURL());
		}
	}
}

void AIInstance::LoadDummyScript()
{
	ScriptAllocatorScope alloc_scope(this->engine);
	extern void Script_CreateDummy(HSQUIRRELVM vm, StringID string, const char *type);
	Script_CreateDummy(this->engine->GetVM(), STR_ERROR_AI_NO_AI_FOUND, "AI");
}

int AIInstance::GetSetting(const char *name)
{
	return AIConfig::GetConfig(_current_company)->GetSetting(name);
}

ScriptInfo *AIInstance::FindLibrary(const char *library, int version)
{
	return (ScriptInfo *)AI::FindLibrary(library, version);
}

/**
 * DoCommand callback function for all commands executed by AIs.
 * @param result The result of the command.
 * @param tile The tile on which the command was executed.
 * @param p1 p1 as given to DoCommandPInternal.
 * @param p2 p2 as given to DoCommandPInternal.
 */
void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
{
	/*
	 * The company might not exist anymore. Check for this.
	 * The command checks are not useful since this callback
	 * is also called when the command fails, which is does
	 * when the company does not exist anymore.
	 */
	const Company *c = Company::GetIfValid(_current_company);
	if (c == nullptr || c->ai_instance == nullptr) return;

	c->ai_instance->DoCommandCallback(result, tile, p1, p2);
	c->ai_instance->Continue();
}

CommandCallback *AIInstance::GetDoCommandCallback()
{
	return &CcAI;
}