mirror of https://github.com/OpenTTD/OpenTTD
(svn r25052) -Fix [FS#5490]: Refactor Script Debug GUI to only set widget states in OnInvalidateData.
parent
0c582e409e
commit
9b06e79765
|
@ -1000,6 +1000,43 @@ struct AIDebugWindow : public Window {
|
||||||
return !Company::IsValidAiID(ai_debug_company) || Company::Get(ai_debug_company)->ai_instance->IsDead();
|
return !Company::IsValidAiID(ai_debug_company) || Company::Get(ai_debug_company)->ai_instance->IsDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a company is a valid AI company or GS.
|
||||||
|
* @param company Company to check for validity.
|
||||||
|
* @return true if company is valid for debugging.
|
||||||
|
*/
|
||||||
|
bool IsValidDebugCompany(CompanyID company) const
|
||||||
|
{
|
||||||
|
switch (company) {
|
||||||
|
case INVALID_COMPANY: return false;
|
||||||
|
case OWNER_DEITY: return Game::GetInstance() != NULL;
|
||||||
|
default: return Company::IsValidAiID(company);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that \c ai_debug_company refers to a valid AI company or GS, or is set to #INVALID_COMPANY.
|
||||||
|
* If no valid company is selected, it selects the first valid AI or GS if any.
|
||||||
|
*/
|
||||||
|
void SelectValidDebugCompany()
|
||||||
|
{
|
||||||
|
/* Check if the currently selected company is still active. */
|
||||||
|
if (this->IsValidDebugCompany(ai_debug_company)) return;
|
||||||
|
|
||||||
|
ai_debug_company = INVALID_COMPANY;
|
||||||
|
|
||||||
|
const Company *c;
|
||||||
|
FOR_ALL_COMPANIES(c) {
|
||||||
|
if (c->is_ai) {
|
||||||
|
ChangeToAI(c->index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no AI is available, see if there is a game script. */
|
||||||
|
if (Game::GetInstance() != NULL) ChangeToAI(OWNER_DEITY);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for the window.
|
* Constructor for the window.
|
||||||
* @param desc The description of the window.
|
* @param desc The description of the window.
|
||||||
|
@ -1014,14 +1051,6 @@ struct AIDebugWindow : public Window {
|
||||||
this->FinishInitNested(desc, number);
|
this->FinishInitNested(desc, number);
|
||||||
|
|
||||||
if (!this->show_break_box) break_check_enabled = false;
|
if (!this->show_break_box) break_check_enabled = false;
|
||||||
/* Disable the companies who are not active or not an AI */
|
|
||||||
for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
|
|
||||||
this->SetWidgetDisabledState(i + WID_AID_COMPANY_BUTTON_START, !Company::IsValidAiID(i));
|
|
||||||
}
|
|
||||||
this->EnableWidget(WID_AID_SCRIPT_GAME);
|
|
||||||
this->DisableWidget(WID_AID_RELOAD_TOGGLE);
|
|
||||||
this->DisableWidget(WID_AID_SETTINGS);
|
|
||||||
this->DisableWidget(WID_AID_CONTINUE_BTN);
|
|
||||||
|
|
||||||
this->last_vscroll_pos = 0;
|
this->last_vscroll_pos = 0;
|
||||||
this->autoscroll = true;
|
this->autoscroll = true;
|
||||||
|
@ -1032,17 +1061,8 @@ struct AIDebugWindow : public Window {
|
||||||
/* Restore the break string value from static variable */
|
/* Restore the break string value from static variable */
|
||||||
this->break_editbox.text.Assign(this->break_string);
|
this->break_editbox.text.Assign(this->break_string);
|
||||||
|
|
||||||
/* Restore button state from static class variables */
|
this->SelectValidDebugCompany();
|
||||||
if (ai_debug_company == OWNER_DEITY) {
|
this->InvalidateData(-1);
|
||||||
this->LowerWidget(WID_AID_SCRIPT_GAME);
|
|
||||||
this->SetWidgetDisabledState(WID_AID_CONTINUE_BTN, !Game::IsPaused());
|
|
||||||
} else if (ai_debug_company != INVALID_COMPANY) {
|
|
||||||
this->LowerWidget(ai_debug_company + WID_AID_COMPANY_BUTTON_START);
|
|
||||||
this->SetWidgetDisabledState(WID_AID_CONTINUE_BTN, !AI::IsPaused(ai_debug_company));
|
|
||||||
}
|
|
||||||
this->SetWidgetLoweredState(WID_AID_BREAK_STR_ON_OFF_BTN, this->break_check_enabled);
|
|
||||||
this->SetWidgetLoweredState(WID_AID_MATCH_CASE_BTN, this->case_sensitive_break_check);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||||
|
@ -1055,67 +1075,31 @@ struct AIDebugWindow : public Window {
|
||||||
|
|
||||||
virtual void OnPaint()
|
virtual void OnPaint()
|
||||||
{
|
{
|
||||||
/* Check if the currently selected company is still active. */
|
this->SelectValidDebugCompany();
|
||||||
if (ai_debug_company == INVALID_COMPANY || (ai_debug_company != OWNER_DEITY && !Company::IsValidAiID(ai_debug_company))) {
|
|
||||||
if (ai_debug_company != INVALID_COMPANY) {
|
|
||||||
/* Raise the widget for the previous selection. */
|
|
||||||
this->RaiseWidget(ai_debug_company + WID_AID_COMPANY_BUTTON_START);
|
|
||||||
|
|
||||||
ai_debug_company = INVALID_COMPANY;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Company *c;
|
|
||||||
FOR_ALL_COMPANIES(c) {
|
|
||||||
if (c->is_ai) {
|
|
||||||
/* Lower the widget corresponding to this company. */
|
|
||||||
this->LowerWidget(c->index + WID_AID_COMPANY_BUTTON_START);
|
|
||||||
|
|
||||||
ai_debug_company = c->index;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If no AI is available, see if there is a game script. */
|
|
||||||
if (ai_debug_company == INVALID_COMPANY && Game::GetInstance() != NULL) {
|
|
||||||
/* Lower the widget corresponding to the game script. */
|
|
||||||
this->LowerWidget(WID_AID_SCRIPT_GAME);
|
|
||||||
|
|
||||||
ai_debug_company = OWNER_DEITY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update "Reload AI" and "AI settings" buttons */
|
|
||||||
this->SetWidgetDisabledState(WID_AID_SETTINGS, ai_debug_company == INVALID_COMPANY);
|
|
||||||
this->SetWidgetDisabledState(WID_AID_RELOAD_TOGGLE, ai_debug_company == INVALID_COMPANY || ai_debug_company == OWNER_DEITY);
|
|
||||||
this->SetWidgetDisabledState(WID_AID_SCRIPT_GAME, Game::GetGameInstance() == NULL);
|
|
||||||
|
|
||||||
/* Draw standard stuff */
|
/* Draw standard stuff */
|
||||||
this->DrawWidgets();
|
this->DrawWidgets();
|
||||||
|
|
||||||
if (this->IsShaded()) return; // Don't draw anything when the window is shaded.
|
if (this->IsShaded()) return; // Don't draw anything when the window is shaded.
|
||||||
|
|
||||||
|
bool dirty = false;
|
||||||
|
|
||||||
/* Paint the company icons */
|
/* Paint the company icons */
|
||||||
for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
|
for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
|
||||||
NWidgetCore *button = this->GetWidget<NWidgetCore>(i + WID_AID_COMPANY_BUTTON_START);
|
NWidgetCore *button = this->GetWidget<NWidgetCore>(i + WID_AID_COMPANY_BUTTON_START);
|
||||||
bool dirty = false;
|
|
||||||
|
|
||||||
bool valid = Company::IsValidAiID(i);
|
bool valid = Company::IsValidAiID(i);
|
||||||
bool disabled = !valid;
|
|
||||||
if (button->IsDisabled() != disabled) {
|
/* Check whether the validity of the company changed */
|
||||||
/* Invalid/non-AI companies have button disabled */
|
dirty |= (button->IsDisabled() == valid);
|
||||||
button->SetDisabled(disabled);
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mark dead/paused AIs by setting the background colour. */
|
/* Mark dead/paused AIs by setting the background colour. */
|
||||||
bool dead = valid && Company::Get(i)->ai_instance->IsDead();
|
bool dead = valid && Company::Get(i)->ai_instance->IsDead();
|
||||||
bool paused = valid && Company::Get(i)->ai_instance->IsPaused();
|
bool paused = valid && Company::Get(i)->ai_instance->IsPaused();
|
||||||
/* Re-paint if the button was updated.
|
/* Re-paint if the button was updated.
|
||||||
* (note that it is intentional that SetScriptButtonColour is always called) */
|
* (note that it is intentional that SetScriptButtonColour is always called) */
|
||||||
dirty = SetScriptButtonColour(*button, dead, paused) || dirty;
|
dirty |= SetScriptButtonColour(*button, dead, paused);
|
||||||
|
|
||||||
/* Do we need a repaint? */
|
|
||||||
if (dirty) this->SetDirty();
|
|
||||||
/* Draw company icon only for valid AI companies */
|
/* Draw company icon only for valid AI companies */
|
||||||
if (!valid) continue;
|
if (!valid) continue;
|
||||||
|
|
||||||
|
@ -1125,13 +1109,14 @@ struct AIDebugWindow : public Window {
|
||||||
|
|
||||||
/* Set button colour for Game Script. */
|
/* Set button colour for Game Script. */
|
||||||
GameInstance *game = Game::GetInstance();
|
GameInstance *game = Game::GetInstance();
|
||||||
bool dead = game != NULL && game->IsDead();
|
bool valid = game != NULL;
|
||||||
bool paused = game != NULL && game->IsPaused();
|
bool dead = valid && game->IsDead();
|
||||||
|
bool paused = valid && game->IsPaused();
|
||||||
|
|
||||||
NWidgetCore *button = this->GetWidget<NWidgetCore>(WID_AID_SCRIPT_GAME);
|
NWidgetCore *button = this->GetWidget<NWidgetCore>(WID_AID_SCRIPT_GAME);
|
||||||
if (SetScriptButtonColour(*button, dead, paused)) {
|
dirty |= (button->IsDisabled() == valid) || SetScriptButtonColour(*button, dead, paused);
|
||||||
/* Re-paint if the button was updated. */
|
|
||||||
this->SetWidgetDirty(WID_AID_SCRIPT_GAME);
|
if (dirty) this->InvalidateData(-1);
|
||||||
}
|
|
||||||
|
|
||||||
/* If there are no active companies, don't display anything else. */
|
/* If there are no active companies, don't display anything else. */
|
||||||
if (ai_debug_company == INVALID_COMPANY) return;
|
if (ai_debug_company == INVALID_COMPANY) return;
|
||||||
|
@ -1233,30 +1218,19 @@ struct AIDebugWindow : public Window {
|
||||||
*/
|
*/
|
||||||
void ChangeToAI(CompanyID show_ai)
|
void ChangeToAI(CompanyID show_ai)
|
||||||
{
|
{
|
||||||
if (ai_debug_company == OWNER_DEITY) {
|
if (!this->IsValidDebugCompany(show_ai)) return;
|
||||||
this->RaiseWidget(WID_AID_SCRIPT_GAME);
|
|
||||||
} else {
|
|
||||||
this->RaiseWidget(ai_debug_company + WID_AID_COMPANY_BUTTON_START);
|
|
||||||
}
|
|
||||||
ai_debug_company = show_ai;
|
ai_debug_company = show_ai;
|
||||||
|
|
||||||
ScriptLog::LogData *log = this->GetLogPointer();
|
|
||||||
this->vscroll->SetCount((log == NULL) ? 0 : log->used);
|
|
||||||
|
|
||||||
if (ai_debug_company == OWNER_DEITY) {
|
|
||||||
this->LowerWidget(WID_AID_SCRIPT_GAME);
|
|
||||||
this->SetWidgetDisabledState(WID_AID_CONTINUE_BTN, !Game::IsPaused());
|
|
||||||
} else {
|
|
||||||
this->LowerWidget(ai_debug_company + WID_AID_COMPANY_BUTTON_START);
|
|
||||||
this->SetWidgetDisabledState(WID_AID_CONTINUE_BTN, !AI::IsPaused(ai_debug_company));
|
|
||||||
}
|
|
||||||
|
|
||||||
this->highlight_row = -1; // The highlight of one AI make little sense for another AI.
|
this->highlight_row = -1; // The highlight of one AI make little sense for another AI.
|
||||||
this->autoscroll = true;
|
|
||||||
this->last_vscroll_pos = this->vscroll->GetPosition();
|
|
||||||
this->SetDirty();
|
|
||||||
/* Close AI settings window to prevent confusion */
|
/* Close AI settings window to prevent confusion */
|
||||||
DeleteWindowByClass(WC_AI_SETTINGS);
|
DeleteWindowByClass(WC_AI_SETTINGS);
|
||||||
|
|
||||||
|
this->InvalidateData(-1);
|
||||||
|
|
||||||
|
this->autoscroll = true;
|
||||||
|
this->last_vscroll_pos = this->vscroll->GetPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnClick(Point pt, int widget, int click_count)
|
virtual void OnClick(Point pt, int widget, int click_count)
|
||||||
|
@ -1287,25 +1261,21 @@ struct AIDebugWindow : public Window {
|
||||||
|
|
||||||
case WID_AID_BREAK_STR_ON_OFF_BTN:
|
case WID_AID_BREAK_STR_ON_OFF_BTN:
|
||||||
this->break_check_enabled = !this->break_check_enabled;
|
this->break_check_enabled = !this->break_check_enabled;
|
||||||
this->SetWidgetLoweredState(WID_AID_BREAK_STR_ON_OFF_BTN, this->break_check_enabled);
|
this->InvalidateData(-1);
|
||||||
this->SetWidgetDirty(WID_AID_BREAK_STR_ON_OFF_BTN);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WID_AID_MATCH_CASE_BTN:
|
case WID_AID_MATCH_CASE_BTN:
|
||||||
this->case_sensitive_break_check = !this->case_sensitive_break_check;
|
this->case_sensitive_break_check = !this->case_sensitive_break_check;
|
||||||
this->SetWidgetLoweredState(WID_AID_MATCH_CASE_BTN, this->case_sensitive_break_check);
|
this->InvalidateData(-1);
|
||||||
this->SetWidgetDirty(WID_AID_MATCH_CASE_BTN);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WID_AID_CONTINUE_BTN:
|
case WID_AID_CONTINUE_BTN:
|
||||||
/* Unpause current AI / game script and mark the corresponding script button dirty. */
|
/* Unpause current AI / game script and mark the corresponding script button dirty. */
|
||||||
if (!IsDead()) {
|
if (!this->IsDead()) {
|
||||||
if (ai_debug_company == OWNER_DEITY) {
|
if (ai_debug_company == OWNER_DEITY) {
|
||||||
Game::Unpause();
|
Game::Unpause();
|
||||||
this->SetWidgetDirty(WID_AID_SCRIPT_GAME);
|
|
||||||
} else {
|
} else {
|
||||||
AI::Unpause(ai_debug_company);
|
AI::Unpause(ai_debug_company);
|
||||||
this->SetWidgetDirty(WID_AID_COMPANY_BUTTON_START + ai_debug_company);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1328,8 +1298,7 @@ struct AIDebugWindow : public Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
this->highlight_row = -1;
|
this->highlight_row = -1;
|
||||||
this->SetWidgetDirty(WID_AID_LOG_PANEL);
|
this->InvalidateData(-1);
|
||||||
this->DisableWidget(WID_AID_CONTINUE_BTN);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1363,15 +1332,14 @@ struct AIDebugWindow : public Window {
|
||||||
/**
|
/**
|
||||||
* Some data on this window has become invalid.
|
* Some data on this window has become invalid.
|
||||||
* @param data Information about the changed data.
|
* @param data Information about the changed data.
|
||||||
|
* This is the company ID of the AI/GS which wrote a new log message, or -1 in other cases.
|
||||||
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
||||||
*/
|
*/
|
||||||
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||||
{
|
{
|
||||||
if (data == -1 || ai_debug_company == data) this->SetDirty();
|
|
||||||
|
|
||||||
/* If the log message is related to the active company tab, check the break string.
|
/* If the log message is related to the active company tab, check the break string.
|
||||||
* This needs to be done in gameloop-scope, so the AI is suspended immediately. */
|
* This needs to be done in gameloop-scope, so the AI is suspended immediately. */
|
||||||
if (!gui_scope && data == ai_debug_company && this->break_check_enabled && !this->break_string_filter.IsEmpty()) {
|
if (!gui_scope && data == ai_debug_company && this->IsValidDebugCompany(ai_debug_company) && this->break_check_enabled && !this->break_string_filter.IsEmpty()) {
|
||||||
/* Get the log instance of the active company */
|
/* Get the log instance of the active company */
|
||||||
ScriptLog::LogData *log = this->GetLogPointer();
|
ScriptLog::LogData *log = this->GetLogPointer();
|
||||||
|
|
||||||
|
@ -1380,7 +1348,7 @@ struct AIDebugWindow : public Window {
|
||||||
this->break_string_filter.AddLine(log->lines[log->pos]);
|
this->break_string_filter.AddLine(log->lines[log->pos]);
|
||||||
if (this->break_string_filter.GetState()) {
|
if (this->break_string_filter.GetState()) {
|
||||||
/* Pause execution of script. */
|
/* Pause execution of script. */
|
||||||
if (!IsDead()) {
|
if (!this->IsDead()) {
|
||||||
if (ai_debug_company == OWNER_DEITY) {
|
if (ai_debug_company == OWNER_DEITY) {
|
||||||
Game::Pause();
|
Game::Pause();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1393,15 +1361,35 @@ struct AIDebugWindow : public Window {
|
||||||
DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
|
DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make it possible to click on the continue button */
|
|
||||||
this->EnableWidget(WID_AID_CONTINUE_BTN);
|
|
||||||
this->SetWidgetDirty(WID_AID_CONTINUE_BTN);
|
|
||||||
|
|
||||||
/* Highlight row that matched */
|
/* Highlight row that matched */
|
||||||
this->highlight_row = log->pos;
|
this->highlight_row = log->pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gui_scope) return;
|
||||||
|
|
||||||
|
this->SelectValidDebugCompany();
|
||||||
|
|
||||||
|
ScriptLog::LogData *log = ai_debug_company != INVALID_COMPANY ? this->GetLogPointer() : NULL;
|
||||||
|
this->vscroll->SetCount((log == NULL) ? 0 : log->used);
|
||||||
|
|
||||||
|
/* Update company buttons */
|
||||||
|
for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
|
||||||
|
this->SetWidgetDisabledState(i + WID_AID_COMPANY_BUTTON_START, !Company::IsValidAiID(i));
|
||||||
|
this->SetWidgetLoweredState(i + WID_AID_COMPANY_BUTTON_START, ai_debug_company == i);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->SetWidgetDisabledState(WID_AID_SCRIPT_GAME, Game::GetGameInstance() == NULL);
|
||||||
|
this->SetWidgetLoweredState(WID_AID_SCRIPT_GAME, ai_debug_company == OWNER_DEITY);
|
||||||
|
|
||||||
|
this->SetWidgetLoweredState(WID_AID_BREAK_STR_ON_OFF_BTN, this->break_check_enabled);
|
||||||
|
this->SetWidgetLoweredState(WID_AID_MATCH_CASE_BTN, this->case_sensitive_break_check);
|
||||||
|
|
||||||
|
this->SetWidgetDisabledState(WID_AID_SETTINGS, ai_debug_company == INVALID_COMPANY);
|
||||||
|
this->SetWidgetDisabledState(WID_AID_RELOAD_TOGGLE, ai_debug_company == INVALID_COMPANY || ai_debug_company == OWNER_DEITY);
|
||||||
|
this->SetWidgetDisabledState(WID_AID_CONTINUE_BTN, ai_debug_company == INVALID_COMPANY ||
|
||||||
|
(ai_debug_company == OWNER_DEITY ? !Game::IsPaused() : !AI::IsPaused(ai_debug_company)));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnResize()
|
virtual void OnResize()
|
||||||
|
|
Loading…
Reference in New Issue