Skip to content

Commit

Permalink
AutoMapping: Don't match rules based on empty input indexes
Browse files Browse the repository at this point in the history
If an input index is entirely empty for a given rule, then this index
will no longer cause the rule to always match.

An always-matching rule can still be declared by using the special
"Ignore" tile in its input.
  • Loading branch information
bjorn committed Jan 29, 2025
1 parent ce589a1 commit 1c61f27
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 2 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
### Unreleased

* Added support for SVG 1.2 / CSS blending modes to layers (#3932)
* AutoMapping: Don't match rules based on empty input indexes
* Raised minimum supported Qt version from 5.12 to 5.15

### Tiled 1.11.2 (28 Jan 2025)
Expand Down
12 changes: 10 additions & 2 deletions src/tiled/automapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,8 @@ static bool isEmptyRegion(const TileLayer &tileLayer,

/**
* Sets up a small data structure for this rule that is optimized for matching.
*
* Returns false when the rule can never match.
*/
bool AutoMapper::compileRule(QVector<RuleInputSet> &inputSets,
const Rule &rule,
Expand Down Expand Up @@ -876,6 +878,10 @@ bool AutoMapper::compileInputSet(RuleInputSet &index,
QVector<MatchCell> &noneOf = compileContext.noneOf;
QVector<MatchCell> &inputCells = compileContext.inputCells;

// An input set will not cause a match if it was left entirely empty, but
// an Ignore tile can still be used to create an always-matching rule.
bool hasIgnore = false;

for (const InputConditions &conditions : inputSet.layers) {
inputCells.clear();
bool canMatch = true;
Expand Down Expand Up @@ -917,6 +923,7 @@ bool AutoMapper::compileInputSet(RuleInputSet &index,
negate = true;
break;
case MatchType::Ignore:
hasIgnore = true;
break;
}
}
Expand Down Expand Up @@ -949,6 +956,7 @@ bool AutoMapper::compileInputSet(RuleInputSet &index,
negate = true;
break;
case MatchType::Ignore:
hasIgnore = true;
break;
}
}
Expand Down Expand Up @@ -1012,7 +1020,7 @@ bool AutoMapper::compileInputSet(RuleInputSet &index,
index.layers.append(layer);
}

return true;
return !index.layers.isEmpty() || hasIgnore;
}

/**
Expand All @@ -1037,7 +1045,7 @@ bool AutoMapper::compileOutputSet(RuleOutputSet &index,
case Layer::ObjectGroupType: {
auto fromObjectGroup = static_cast<const ObjectGroup*>(from);

auto objects = objectsInRegion(*mRulesMapRenderer, fromObjectGroup, outputRegion);
const auto objects = objectsInRegion(*mRulesMapRenderer, fromObjectGroup, outputRegion);
if (!objects.isEmpty()) {
QVector<const MapObject*> constObjects;
for (auto object : objects)
Expand Down

0 comments on commit 1c61f27

Please sign in to comment.