/** Finish a cycle of a measured element and store the measurement taken. */ PerformanceMeasurer::~PerformanceMeasurer() { if (this->elem == PFE_ALLSCRIPTS) { /* Hack to not record scripts total when no scripts are active */ bool any_active = _pf_data[PFE_GAMESCRIPT].num_valid > 0; for (uint e = PFE_AI0; e < PFE_MAX; e++) any_active |= _pf_data[e].num_valid > 0; if (!any_active) { PerformanceMeasurer::SetInactive(PFE_ALLSCRIPTS); return; } } _pf_data[this->elem].Add(this->start_time, GetPerformanceTimer()); /* Self-adjust max opcodes for active scripts */ if (this->elem >= PFE_GAMESCRIPT && this->elem <= PFE_AI14) { uint active_scripts = Game::GetInstance() != NULL && !Game::GetInstance()->IsDead() && !Game::GetInstance()->IsPaused(); Company *c; FOR_ALL_COMPANIES(c) { if (Company::IsValidAiID(c->index) && Company::Get(c->index)->ai_instance != NULL && !Company::Get(c->index)->ai_instance->IsDead() && !Company::Get(c->index)->ai_instance->IsPaused()) { active_scripts++; } } if (active_scripts != 0 && (this->elem == PFE_GAMESCRIPT ? Game::GetInstance() != NULL && !Game::GetInstance()->IsDead() && !Game::GetInstance()->IsPaused() : Company::IsValidAiID((CompanyID)(this->elem - PFE_AI0)) && Company::Get((CompanyID)(this->elem - PFE_AI0))->ai_instance != NULL && !Company::Get((CompanyID)(this->elem - PFE_AI0))->ai_instance->IsDead() && !Company::Get((CompanyID)(this->elem - PFE_AI0))->ai_instance->IsPaused())) { uint dummy; // unused const SettingDesc *sd = GetSettingFromName("script_max_opcode_till_suspend", &dummy); assert(sd != NULL); uint opcodes = this->elem == PFE_GAMESCRIPT ? Game::GetMaxOpCodes() : AI::GetMaxOpCodes((CompanyID)(this->elem - PFE_AI0)); uint value = opcodes; double avg = min(9999.99, _pf_data[this->elem].GetAverageDurationMilliseconds(GL_RATE)); double all = min(9999.99, _pf_data[PFE_ALLSCRIPTS].GetAverageDurationMilliseconds(GL_RATE)); if (avg * active_scripts > GL_RATE && all > GL_RATE) { value = Clamp(opcodes - (avg * active_scripts - GL_RATE) * (avg * active_scripts - GL_RATE), sd->desc.min, GetGameSettings().script.script_max_opcode_till_suspend); } else if (avg > 0 && avg < GL_RATE / 3 || all < GL_RATE / 3) { value = Clamp(opcodes + GL_RATE / 3 - avg, sd->desc.min, GetGameSettings().script.script_max_opcode_till_suspend); } if (value != opcodes) { if (this->elem == PFE_GAMESCRIPT) { Game::SetMaxOpCodes(value); } else { AI::SetMaxOpCodes((CompanyID)(this->elem - PFE_AI0), value); } } } } }