/** 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);
}
}
}
}
}