PatchOperationTest as part of a PatchOperationSequence

Started by Moogie, March 26, 2020, 12:21:19 PM

Previous topic - Next topic

Moogie

I'm very new to this--please bear with me. :)

I'd like to use a PatchOperationTest at the beginning of a PatchOperationSequence to check for the existence of a node, but I'm not sure if the test runs once, or once per thing it matches. I want it to do the latter. Would this be correct?

<Operation Class="PatchOperationSequence">
<success>Always</success>
<operations>
<li Class="PatchOperationTest">
<xpath>Defs/ThingDef[contains (text(),"Example")]/ExampleNode</xpath>
<success>Invert</success>
</li>
<li Class="PatchOperationInsert">
<xpath>Defs/ThingDef[contains (text(),"Example")]/SiblingNode</xpath>
<value>
<ExampleNode />
</value>
</li>
<li Class="PatchOperationAdd">
<xpath>Defs/ThingDef[contains (text(),"Example")]/ExampleNode</xpath>
<value>
<ExampleAttribute>1</ExampleAttribute>
</value>
</li>
</operations>
</Operation>


What I would expect from the above: If multiple things are selected with the text search, then for each of them, test the existence of ExampleNode, and then for each of them that test successfully, add the new child node and value. Will it work that way, or do I need to add more tests in the sequence to stop it testing once at the start and then just assuming the rest?

Also, is there a way to reduce how many times this example uses "contains"? I get a distinct feeling this would be slow, but I don't know of any way for a sequence of operations to remember the current xpath in order to avoid running the same base search over and over.

Thanks in advance for any help or tips!

LWM

xpath will happily match against multiple nodes, and the patch will happily (and mindlessly) apply to every one of them.
FWIW, "/Defs/..." is slightly faster than "Defs/..." - I ran a bunch of tests, you can find my methodology on github.

Also, if that's your example....what it says is (I think):
Start Sequence.
If it doesn't have:

<ThingDef>somethingWithExample<ExampleNode>[...]</ExampleNode></ThingDef>

then continue the sequence:
Add <ExampleNode /> to SiblingNode.
IF SiblingNode existed, continue the sequence:
Add ExampleAttibute (attributes, by the way, are <tag attribute="thisThing">?) to Defs/ThingDef&c/ExampleNode - which does not exist (because if it exists, the sequence stopped in step one).

I think I got that right.

FWIW, if you're looking for a mod, <PatchOperationFindMod> is much faster than searching the entire set of Defs for a certain defname.

The wiki has a good rundown on the patch operations, and feel free to keep asking questions here :)  We might even give you correct answers!

Hope that helps,

--LWM


Moogie

Thank you! That was very helpful, and I'll definitely keep in mind the /Defs/ speedup. That's a great tip. :)