Skip to content

Commit bb2bb28

Browse files
committed
Add an ini property rule regarding "InstanceName", which gets a new semantic meaning in Pre7, allowing a preset name to be specified without marking the object an original preset. I believe I wanted this functionality because it allows writing an Entity which is objectively a copy of a preset, but in such a way that it neither gets marked a preset itself nor requires the existence of a preset for reference. Inline constant reference preset definitions are now left in an indeterminate state requiring user intervention if a PresetName is followed by a CopyOf, which is almost always a mistake, and will be highlighted by an assertation failure or runtime error. Now for tests.
1 parent 8559c45 commit bb2bb28

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

rules/ini_property_rules.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@
3030
"CollidesWithTerrainWhenAttached": "CollidesWithTerrainWhileAttached",
3131
"DrawWhenOpen": "DrawMaterialLayerWhenOpen",
3232
"DrawWhenClosed": "DrawMaterialLayerWhenClosed",
33-
"AffectedByPitch": "AffectedByGlobalPitch"
33+
"AffectedByPitch": "AffectedByGlobalPitch",
34+
"InstanceName": "PresetName"
3435
}

src/main.zig

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,7 @@ fn applyIniDeinliningRulesRecursivelyFolder(allocator: Allocator, file_tree: *In
14941494

14951495
// Instead of looping over all nodes, loop over the children of each node.
14961496
// Why necessary? Because some unused inis use the word "Particle" as a root property.
1497+
// This is safe, however, because there should never be any lone constant references at root property level.
14971498
for (node.children.items) |*child| {
14981499
// Deinlining a definition into the file will push the current object further forward.
14991500
const insertionApplied: bool = try applyIniDeinliningRulesRecursivelyNode(allocator, child, property, file, node.*, moduleSpace);
@@ -1521,15 +1522,17 @@ fn applyIniDeinliningRulesRecursivelyNode(allocator: Allocator, node: *Node, pro
15211522
var isOriginalPreset: bool = false;
15221523
var isCopyOf: bool = false;
15231524

1524-
// If we read a CopyOf, then whatever preset name we were going with is invalidated.
1525+
// A CopyOf changes what the constant reference will point to,
1526+
// unless it is following a PresetName, which is assumed to be a mistake.
1527+
// A PresetName always changes the pointing of the constant reference.
15251528
for (node.children.items) |*child| {
15261529
if (child.property) |childProperty| {
15271530
const readingCopyOf: bool = strEql(childProperty, "CopyOf");
15281531
const readingOriginalPreset: bool = strEql(childProperty, "PresetName");
15291532
isCopyOf = isCopyOf or readingCopyOf;
1530-
isOriginalPreset = !readingCopyOf and (isOriginalPreset or readingOriginalPreset);
1533+
isOriginalPreset = isOriginalPreset or readingOriginalPreset;
15311534

1532-
if (readingCopyOf or readingOriginalPreset) {
1535+
if ((readingCopyOf and !isOriginalPreset) or readingOriginalPreset) {
15331536
presetNameOptional = child.value;
15341537
}
15351538
}
@@ -1548,6 +1551,8 @@ fn applyIniDeinliningRulesRecursivelyNode(allocator: Allocator, node: *Node, pro
15481551
// then we're going to deinline it.
15491552
const deinliningFlag = isOriginalPreset and !strEql(rootParent.property.?, "AddLoadout");
15501553

1554+
// If we're set to deinline, then we're making a new preset definition in this module.
1555+
// This means the constant reference should certainly point to this module.
15511556
if (deinliningFlag) {
15521557
moduleName = moduleSpace.moduleName;
15531558

@@ -1562,6 +1567,7 @@ fn applyIniDeinliningRulesRecursivelyNode(allocator: Allocator, node: *Node, pro
15621567
try file.ast.insert(determinedIndex, duplicateNode);
15631568
}
15641569

1570+
// As long as we ever encountered the implication of a preset name, we can construct a constant reference.
15651571
if (presetNameOptional) |presetName| {
15661572
// If this was copied from something, and it isn't an original preset,
15671573
// then check if it is pointing to something within this module.
@@ -1581,6 +1587,8 @@ fn applyIniDeinliningRulesRecursivelyNode(allocator: Allocator, node: *Node, pro
15811587
node.children.clearRetainingCapacity();
15821588
node.comments.clearRetainingCapacity();
15831589

1590+
// In any case, this was a malformed constant reference, and it no longer has children to correct.
1591+
// We signal to the caller if a definition has been deinlined, so that it can step backwards to proofread that one as well.
15841592
return deinliningFlag;
15851593
}
15861594
}

0 commit comments

Comments
 (0)