Allow shallow-removing conditional blocks by use of ctrl+click.
This commit is contained in:
@@ -2466,7 +2466,7 @@ STR_TRACE_RESTRICT_UNSHARE :{BLACK}Unshare
|
|||||||
STR_TRACE_RESTRICT_SELECT_TARGET :{BLACK}Select Target
|
STR_TRACE_RESTRICT_SELECT_TARGET :{BLACK}Select Target
|
||||||
STR_TRACE_RESTRICT_SELECT_SIGNAL :{BLACK}Select Signal
|
STR_TRACE_RESTRICT_SELECT_SIGNAL :{BLACK}Select Signal
|
||||||
STR_TRACE_RESTRICT_INSERT_TOOLTIP :{BLACK}Insert an instruction
|
STR_TRACE_RESTRICT_INSERT_TOOLTIP :{BLACK}Insert an instruction
|
||||||
STR_TRACE_RESTRICT_REMOVE_TOOLTIP :{BLACK}Remove the selected instruction
|
STR_TRACE_RESTRICT_REMOVE_TOOLTIP :{BLACK}Remove the selected instruction{}Ctrl+Click to remove the selected conditional instruction but retain its contents
|
||||||
STR_TRACE_RESTRICT_RESET_TOOLTIP :{BLACK}Reset the current signal (without affecting shared programs)
|
STR_TRACE_RESTRICT_RESET_TOOLTIP :{BLACK}Reset the current signal (without affecting shared programs)
|
||||||
STR_TRACE_RESTRICT_COPY_TOOLTIP :{BLACK}Copy program from another signal
|
STR_TRACE_RESTRICT_COPY_TOOLTIP :{BLACK}Copy program from another signal
|
||||||
STR_TRACE_RESTRICT_SHARE_TOOLTIP :{BLACK}Share program with another signal
|
STR_TRACE_RESTRICT_SHARE_TOOLTIP :{BLACK}Share program with another signal
|
||||||
@@ -2481,6 +2481,7 @@ STR_TRACE_RESTRICT_ERROR_NO_PROGRAM :No trace restri
|
|||||||
STR_TRACE_RESTRICT_ERROR_OFFSET_TOO_LARGE :Offset too large
|
STR_TRACE_RESTRICT_ERROR_OFFSET_TOO_LARGE :Offset too large
|
||||||
STR_TRACE_RESTRICT_ERROR_CAN_T_CHANGE_CONDITIONALITY :Can't change conditionality
|
STR_TRACE_RESTRICT_ERROR_CAN_T_CHANGE_CONDITIONALITY :Can't change conditionality
|
||||||
STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ENDIF :Can't remove an 'end if'
|
STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ENDIF :Can't remove an 'end if'
|
||||||
|
STR_TRACE_RESTRICT_ERROR_CAN_T_SHALLOW_REMOVE_IF_ELIF :Can't shallow remove an 'if' block with one or more 'else if', 'or if' or 'else' blocks
|
||||||
STR_TRACE_RESTRICT_ERROR_VALIDATE_END_CONDSTACK :Validation failed: condstack non-empty at exit
|
STR_TRACE_RESTRICT_ERROR_VALIDATE_END_CONDSTACK :Validation failed: condstack non-empty at exit
|
||||||
STR_TRACE_RESTRICT_ERROR_VALIDATE_NO_IF :Validation failed: else/endif without opening if
|
STR_TRACE_RESTRICT_ERROR_VALIDATE_NO_IF :Validation failed: else/endif without opening if
|
||||||
STR_TRACE_RESTRICT_ERROR_VALIDATE_DUP_ELSE :Validation failed: duplicate else
|
STR_TRACE_RESTRICT_ERROR_VALIDATE_DUP_ELSE :Validation failed: duplicate else
|
||||||
|
@@ -844,6 +844,85 @@ static uint32 GetDualInstructionInitialValue(TraceRestrictItem item)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandCost TraceRestrictProgramRemoveItemAt(std::vector<TraceRestrictItem> &items, uint32 offset, bool shallow_mode)
|
||||||
|
{
|
||||||
|
TraceRestrictItem old_item = *TraceRestrictProgram::InstructionAt(items, offset);
|
||||||
|
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) {
|
||||||
|
// this is an end if, can't remove these
|
||||||
|
return_cmd_error(STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ENDIF);
|
||||||
|
} else {
|
||||||
|
// this is an opening if
|
||||||
|
remove_whole_block = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 recursion_depth = 1;
|
||||||
|
std::vector<TraceRestrictItem>::iterator remove_start = TraceRestrictProgram::InstructionAt(items, offset);
|
||||||
|
std::vector<TraceRestrictItem>::iterator remove_end = remove_start + 1;
|
||||||
|
|
||||||
|
// iterate until matching end block found
|
||||||
|
for (; remove_end != items.end(); ++remove_end) {
|
||||||
|
TraceRestrictItem current_item = *remove_end;
|
||||||
|
if (IsTraceRestrictConditional(current_item)) {
|
||||||
|
if (GetTraceRestrictCondFlags(current_item) == 0) {
|
||||||
|
if (GetTraceRestrictType(current_item) == TRIT_COND_ENDIF) {
|
||||||
|
// this is an end if
|
||||||
|
recursion_depth--;
|
||||||
|
if (recursion_depth == 0) {
|
||||||
|
if (remove_whole_block) {
|
||||||
|
// inclusively remove up to here
|
||||||
|
++remove_end;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// exclusively remove up to here
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// this is an opening if
|
||||||
|
recursion_depth++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// this is an else/or type block
|
||||||
|
if (recursion_depth == 1 && !remove_whole_block) {
|
||||||
|
// exclusively remove up to here
|
||||||
|
recursion_depth = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (recursion_depth == 1 && remove_whole_block && shallow_mode) {
|
||||||
|
// shallow-removing whole if block, and it contains an else/or if, bail out
|
||||||
|
return_cmd_error(STR_TRACE_RESTRICT_ERROR_CAN_T_SHALLOW_REMOVE_IF_ELIF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (IsTraceRestrictDoubleItem(current_item)) {
|
||||||
|
// this is a double-item, jump over the next item as well
|
||||||
|
++remove_end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (recursion_depth != 0) return CMD_ERROR; // ran off the end
|
||||||
|
if (shallow_mode) {
|
||||||
|
// must erase endif first, as it is later in the vector
|
||||||
|
if (remove_whole_block) items.erase(remove_end - 1);
|
||||||
|
items.erase(remove_start);
|
||||||
|
} else {
|
||||||
|
items.erase(remove_start, remove_end);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::vector<TraceRestrictItem>::iterator remove_start = TraceRestrictProgram::InstructionAt(items, offset);
|
||||||
|
std::vector<TraceRestrictItem>::iterator remove_end = remove_start + 1;
|
||||||
|
|
||||||
|
if (IsTraceRestrictDoubleItem(old_item)) {
|
||||||
|
// this is a double-item, remove the next item as well
|
||||||
|
++remove_end;
|
||||||
|
}
|
||||||
|
items.erase(remove_start, remove_end);
|
||||||
|
}
|
||||||
|
return CommandCost();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main command for editing a signal tracerestrict program.
|
* The main command for editing a signal tracerestrict program.
|
||||||
* @param tile The tile which contains the signal.
|
* @param tile The tile which contains the signal.
|
||||||
@@ -928,71 +1007,10 @@ CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, u
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TRDCT_REMOVE_ITEM: {
|
case TRDCT_REMOVE_ITEM:
|
||||||
TraceRestrictItem old_item = *TraceRestrictProgram::InstructionAt(items, offset);
|
case TRDCT_SHALLOW_REMOVE_ITEM: {
|
||||||
if (IsTraceRestrictConditional(old_item) && GetTraceRestrictCondFlags(old_item) != TRCF_OR) {
|
CommandCost res = TraceRestrictProgramRemoveItemAt(items, offset, type == TRDCT_SHALLOW_REMOVE_ITEM);
|
||||||
bool remove_whole_block = false;
|
if (res.Failed()) return res;
|
||||||
if (GetTraceRestrictCondFlags(old_item) == 0) {
|
|
||||||
if (GetTraceRestrictType(old_item) == TRIT_COND_ENDIF) {
|
|
||||||
// this is an end if, can't remove these
|
|
||||||
return_cmd_error(STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ENDIF);
|
|
||||||
} else {
|
|
||||||
// this is an opening if
|
|
||||||
remove_whole_block = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 recursion_depth = 1;
|
|
||||||
std::vector<TraceRestrictItem>::iterator remove_start = TraceRestrictProgram::InstructionAt(items, offset);
|
|
||||||
std::vector<TraceRestrictItem>::iterator remove_end = remove_start + 1;
|
|
||||||
|
|
||||||
// iterate until matching end block found
|
|
||||||
for (; remove_end != items.end(); ++remove_end) {
|
|
||||||
TraceRestrictItem current_item = *remove_end;
|
|
||||||
if (IsTraceRestrictConditional(current_item)) {
|
|
||||||
if (GetTraceRestrictCondFlags(current_item) == 0) {
|
|
||||||
if (GetTraceRestrictType(current_item) == TRIT_COND_ENDIF) {
|
|
||||||
// this is an end if
|
|
||||||
recursion_depth--;
|
|
||||||
if (recursion_depth == 0) {
|
|
||||||
if (remove_whole_block) {
|
|
||||||
// inclusively remove up to here
|
|
||||||
++remove_end;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// exclusively remove up to here
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// this is an opening if
|
|
||||||
recursion_depth++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// this is an else/or type block
|
|
||||||
if (recursion_depth == 1 && !remove_whole_block) {
|
|
||||||
// exclusively remove up to here
|
|
||||||
recursion_depth = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (IsTraceRestrictDoubleItem(current_item)) {
|
|
||||||
// this is a double-item, jump over the next item as well
|
|
||||||
++remove_end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (recursion_depth != 0) return CMD_ERROR; // ran off the end
|
|
||||||
items.erase(remove_start, remove_end);
|
|
||||||
} else {
|
|
||||||
std::vector<TraceRestrictItem>::iterator remove_start = TraceRestrictProgram::InstructionAt(items, offset);
|
|
||||||
std::vector<TraceRestrictItem>::iterator remove_end = remove_start + 1;
|
|
||||||
|
|
||||||
if (IsTraceRestrictDoubleItem(old_item)) {
|
|
||||||
// this is a double-item, remove the next item as well
|
|
||||||
++remove_end;
|
|
||||||
}
|
|
||||||
items.erase(remove_start, remove_end);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -622,6 +622,7 @@ enum TraceRestrictDoCommandType {
|
|||||||
TRDCT_MODIFY_ITEM, ///< modify instruction at offset field to given value
|
TRDCT_MODIFY_ITEM, ///< modify instruction at offset field to given value
|
||||||
TRDCT_MODIFY_DUAL_ITEM, ///< modify second item of dual-part instruction at offset field to given value
|
TRDCT_MODIFY_DUAL_ITEM, ///< modify second item of dual-part instruction at offset field to given value
|
||||||
TRDCT_REMOVE_ITEM, ///< remove instruction at offset field
|
TRDCT_REMOVE_ITEM, ///< remove instruction at offset field
|
||||||
|
TRDCT_SHALLOW_REMOVE_ITEM, ///< shallow remove instruction at offset field, does not delete contents of block
|
||||||
|
|
||||||
TRDCT_PROG_COPY, ///< copy program operation. Do not re-order this with respect to other values
|
TRDCT_PROG_COPY, ///< copy program operation. Do not re-order this with respect to other values
|
||||||
TRDCT_PROG_SHARE, ///< share program operation
|
TRDCT_PROG_SHARE, ///< share program operation
|
||||||
@@ -645,6 +646,8 @@ inline void TraceRestrictProgMgmtDoCommandP(TileIndex tile, Track track, TraceRe
|
|||||||
CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
|
CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
|
||||||
CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
|
CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
|
||||||
|
|
||||||
|
CommandCost TraceRestrictProgramRemoveItemAt(std::vector<TraceRestrictItem> &items, uint32 offset, bool shallow_mode);
|
||||||
|
|
||||||
void ShowTraceRestrictProgramWindow(TileIndex tile, Track track);
|
void ShowTraceRestrictProgramWindow(TileIndex tile, Track track);
|
||||||
|
|
||||||
void TraceRestrictRemoveDestinationID(TraceRestrictOrderCondAuxField type, uint16 index);
|
void TraceRestrictRemoveDestinationID(TraceRestrictOrderCondAuxField type, uint16 index);
|
||||||
|
@@ -1006,7 +1006,8 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceRestrictDoCommandP(tile, track, TRDCT_REMOVE_ITEM, this->selected_instruction - 1, 0, STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ITEM);
|
TraceRestrictDoCommandP(tile, track, _ctrl_pressed ? TRDCT_SHALLOW_REMOVE_ITEM : TRDCT_REMOVE_ITEM,
|
||||||
|
this->selected_instruction - 1, 0, STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ITEM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user