instead of just preferring to match the lowest possible ID that counts as a partial match, add some extra criteria to make it act closer to how people expect.
* prefer entries where no letters are skipped
* prefer entries where the start of the partial matches the start of the full
* pressing escape should close the script tip
* fix automatic inclusion of <auto> behavior
* Fix possible crash when looking for closing } when there isn't one
* Only update TextEditor layers if they've changed (performance)
* creating a new event script should include lock/faceplayer/release
* adjust focus when switching tabs (close open tips)
* only try to access list coments if the list isn't null
* Avoid using foreach/enumorables in `MacroScriptLine.Matches` since it's called so often.
* Use Span<char> to reduce string allocations in `ArrayRun.ctor` and `ArrayRunEnumSegment.GetOptions`
* don't store the delta object used for initial setup
* avoid making lambdas in `ScriptLine.Matches`, which is called very often.
* use use List<int> instead of SortedSpan<int> for building the initial DestinationToSource cache, since we're already guaranteed that they'll be added in order and without duplicates. This greatly reduces the number of int[] arrays created during startup.
* allow `ArrayRunPointerSegment` to cache the table content results from parsing its InnerFormat, so it doesn't have to re-parse each time. This greatly reduces the number of string allocations.
* Use `ThreadSafeDictionary` for `TryGetValueCaseInsensitive` so we don't need to create a new collection of keys each time we call the method. Also add key caching to `ThreadSafeDictionary` so we don't need to make a new collection each time it's requested.
* Make `GetOptions` return a readonly list. We already know it's unique, this means we don't have to make a new collection every time we parse segments.
* limit the number of undo tokens we store (default 100) to save memory
* Use `byte[]` and `Array.Copy` instead of `List<byte>` and `AddRange` to reduce byte array allocations when loading a file.
* Freeze geometries in the `Icons` collection.
* add option for running garbage collection from the developer menu
* use a custom `AutomationPeer` to prevent WPF from holding memory after controls have been closed.
when generating data for a new stream and the pointer is to freespace, be aware that we're creating a stream starting from length zero, rather than whatever the model data parses as the length. The parsed length doesn't matter, because we're pointing at freespace.
* In sky attack, after the two-turn-animation command, the `end` command is pointed to by other pieces of script. Since its address actually matters, don't combine things together into a single script.
* Both CollectScripts and FindLength have script aggregation logic that needs to be limited.
For script performance:
* call data.GetGameCode() less often, using a cached value for the ScriptParser
* use a 4-byte game code instead of string parsing for the game code
For map previews in the table tool performance
* Don't use dispatcher foreground/background thread swapping, it's safe to add the previews to the collection from the background thread.
* Check the exit condition more often
For drawing performance:
* Use Array.Copy when we don't need to worry about Transparency, since it's much faster.
* Make `Darken` faster, we call it a lot
* Reuse DarkenRect utility in HighlightCollision
Other performance changes
* Protototype for ObserableList<T> for a more configurable version of ObservableCollection
Situation:
* Script A refers to B and C. B and C occur right after eachother.
* Scirpt B does not refer to script C, so C doesn't get included in the same body.
-> when editing B, B needs to know that its length does not include C. So the script-length-cache that B uses shouldn't know about C, since B doesn't refer to C.
-> Therefore, B can't use the same cache as A.
* track length caches based on the code body start, not based on the entire model. This lets each code body have its own cache.
We previously had code that tried to find lengths of sub-scripts from scripts, but only followed pointers forward, not backward, to prevent infinite loops. But it didn't properly handle scripts that _do_ have backwards pointers: it was returning a length of 1 for those, which is wrong.
* don't allow streams to have <section> labels
* update the <auto> algorithm to allow stream pointers to be picked up in the middle of a script. This will get changed if the script is recompiled to put the streams at the end, but it allows longer scripts to be read no matter where the streams were placed.
also fix possible race condition when refreshing border render while drawing the map
also fix condition where writing script data content formats shouldn't write empty runs if the token doesn't allow changes.
* better for experts because they can more easily parse a handful of section headers compared to random hex addresses
* Better for new users because it helps them learn that they can use whatever names they want for the headers of scripts and for pointers.
doing <??????> auto-included a new {} block, which is cool. But that block needs to not be included when calculating the new cursor position, because the cursor position should remain _before_ the new {}, so it's still on the same line in case you're writing `trainerbattle` or something with multiple pointers in the line.
note that this could be dangerous, since we're writing an end token to an arbitrary address that is still being decided on. A couple things mitigate this problem:
* the user can use <auto> pointers in scripts
* addresses won't be checked/used unless the user has both an open < and a close >.
* submit failing tests
* Grab failing trainer test from remote branch (#121)
* Updated flash constants
* Fixed flash constant locations
I originally supplied anchor references, not locations of the constants themselves. That's been fixed. Also, I changed the field name for flash.radius, so it's hopefully clearer.
* Fixed some other pointer issues with RAM addresses in script commands
RAM addresses can't be encased in <> nicely. Some commands still needed their RAM-address pointers to have the ::|h formatting instead.
* Fixing some parameter formats in the script reference file.
There were a few other commands that needed RAM-address parameters set to their correct format so that typing "2024284" doesn't auto format to 0xA024284, etc.
* update script reference (again)
* Added a failing test for duplicating trainer data
Bug report in query: https://discord.com/channels/538022037718040588/538022038376415234/1083215729177931877
---------
Co-authored-by: ShinyTillDawn <80070404+ShinyTillDawn@users.noreply.github.com>
* Fix test
ExportTilesetWithPalette2_EditTileset_ImportTilesetWithPalette2_DataMatches
-> fix formatting in LzSpriteRun
-> fix overflow error in SpriteRun
-> fix default palette detection in SpriteTool
-> improve test so it gives better failure info
* fix trainer duplication assert
fix test name / remove unneeded comments
handle Trainer team runs specially
update assertion error message
* Improve pointer error logic
Pointers are allowed to point into the middle of an existing run. Such a pointer is an error, but is not a metadata inconsistency. Update metadata checking for new logic. Update pointer logic to display pointer as an error.
* improve handling of `auto`
allow <auto> to be used if there's a one-byte gap
* improve interruptingSourceRun logic
an interrupting table is not always valid.
It's only valid if the source is at an index that would make it a pointer.
* don't clear bytes, clear anchors
If you have a custom anchor name in the middle of a script and then edit the script, that custom anchor name will be lost. But anything pointing to it will still point to it.
---------
Co-authored-by: ShinyTillDawn <80070404+ShinyTillDawn@users.noreply.github.com>
When scripts get merged together, some inner-scripts no longer appear to be real scripts. These were showing up as orphans when the scripts get formatted, since that causes scripts to get merged. But the pointers are still there, so they're not actually orphans.
Fix the orphan-naming logic so that it won't name things as orphans if they're inner scripts that still have pointers
ai script children should appear as ai scripts
editing an AI script shouldn't make a bunch of orphans
introduce a light caching system for noticing when scripts don't need to be loaded again.
script edits that don't change any compiled bytes should be capable of skipping the metadata update in situations where the metadata is already correct