Improve insertion and removal of 'or if' conditionals.

Allow inserting an 'or if' immediately after 'if', 'else if', 'or if'.
Removing an 'or if' no longer removes the associated block.
This commit is contained in:
Jonathan G Rennison 2015-09-01 22:39:15 +01:00
parent 38aaf8a921
commit 06cc930e47
2 changed files with 20 additions and 12 deletions

View File

@ -807,7 +807,7 @@ CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, u
case TRDCT_REMOVE_ITEM: {
TraceRestrictItem old_item = *TraceRestrictProgram::InstructionAt(items, offset);
if (IsTraceRestrictConditional(old_item)) {
if (IsTraceRestrictConditional(old_item) && GetTraceRestrictCondFlags(old_item) != TRCF_OR) {
bool remove_whole_block = false;
if (GetTraceRestrictCondFlags(old_item) == 0) {
if (GetTraceRestrictType(old_item) == TRIT_COND_ENDIF) {

View File

@ -115,18 +115,20 @@ struct TraceRestrictDropDownListSet {
static const StringID _program_insert_str[] = {
STR_TRACE_RESTRICT_CONDITIONAL_IF,
STR_TRACE_RESTRICT_CONDITIONAL_ELIF,
STR_TRACE_RESTRICT_CONDITIONAL_ORIF,
STR_TRACE_RESTRICT_CONDITIONAL_ELSE,
STR_TRACE_RESTRICT_PF_DENY,
STR_TRACE_RESTRICT_PF_PENALTY,
INVALID_STRING_ID
};
static const uint _program_insert_else_flag = 0x100; ///< flag to indicate that TRCF_ELSE should be set
static const uint32 _program_insert_else_hide_mask = 4; ///< disable bitmask for else
static const uint32 _program_insert_else_hide_mask = 8; ///< disable bitmask for else
static const uint32 _program_insert_or_if_hide_mask = 4; ///< disable bitmask for elif
static const uint32 _program_insert_else_if_hide_mask = 2; ///< disable bitmask for elif
static const uint _program_insert_val[] = {
TRIT_COND_UNDEFINED, // if block
TRIT_COND_UNDEFINED | _program_insert_else_flag, // elif block
TRIT_COND_ENDIF | _program_insert_else_flag, // else block
TRIT_COND_UNDEFINED | (TRCF_ELSE << 16), // elif block
TRIT_COND_UNDEFINED | (TRCF_OR << 16), // orif block
TRIT_COND_ENDIF | (TRCF_ELSE << 16), // else block
TRIT_PF_DENY, // deny
TRIT_PF_PENALTY, // penalty
};
@ -732,7 +734,7 @@ public:
return;
}
uint32 disabled = 0;
uint32 disabled = _program_insert_or_if_hide_mask;
TraceRestrictItem item = this->GetSelected();
if (GetTraceRestrictType(item) == TRIT_COND_ENDIF ||
(IsTraceRestrictConditional(item) && GetTraceRestrictCondFlags(item) != 0)) {
@ -744,6 +746,15 @@ public:
// can't insert else/end if here
disabled |= _program_insert_else_hide_mask | _program_insert_else_if_hide_mask;
}
if (this->selected_instruction > 1) {
TraceRestrictItem prev_item = this->GetItem(this->GetProgram(), this->selected_instruction - 1);
if (IsTraceRestrictConditional(prev_item) && GetTraceRestrictType(prev_item) != TRIT_COND_ENDIF) {
// previous item is either: an if, or an else/or if
// else if has same validation rules as or if, use it instead of creating another test function
if (ElseIfInsertionDryRun(false)) disabled &= ~_program_insert_or_if_hide_mask;
}
}
this->ShowDropDownListWithValue(&_program_insert, 0, true, TR_WIDGET_INSERT, disabled, 0, 0);
break;
@ -914,13 +925,10 @@ public:
case TR_WIDGET_INSERT: {
TraceRestrictItem insert_item = 0;
bool have_else = false;
if (value & _program_insert_else_flag) {
value &= ~_program_insert_else_flag;
have_else = true;
}
TraceRestrictCondFlags cond_flags = static_cast<TraceRestrictCondFlags>(value >> 16);
value &= 0xFFFF;
SetTraceRestrictTypeAndNormalise(insert_item, static_cast<TraceRestrictItemType>(value));
if (have_else) SetTraceRestrictCondFlags(insert_item, TRCF_ELSE); // this needs to happen after calling SetTraceRestrictTypeAndNormalise
SetTraceRestrictCondFlags(insert_item, cond_flags); // this needs to happen after calling SetTraceRestrictTypeAndNormalise
this->expecting_inserted_item = insert_item;
TraceRestrictDoCommandP(this->tile, this->track, TRDCT_INSERT_ITEM, this->selected_instruction - 1, insert_item, STR_TRACE_RESTRICT_ERROR_CAN_T_INSERT_ITEM);