From 7ae7a5822671fe9982ea4086723873dfe1ed9009 Mon Sep 17 00:00:00 2001 From: haven1433 Date: Sat, 13 Dec 2025 17:40:03 -0600 Subject: [PATCH] map editor support text, flags, and item with complex scripts --- .../Core/Autos/StubDataModel.cs | 1321 +++++++---------- .../Models/Code/ScriptParser.cs | 4 +- src/HexManiac.Core/Models/IDataModel.cs | 3 +- src/HexManiac.Core/Models/PokemonModel.cs | 2 +- .../ViewModels/Map/IEventViewModel.cs | 63 + src/HexManiac.Core/ViewModels/ViewPort.cs | 2 + src/HexManiac.WPF/Controls/MapTab.xaml | 16 + 7 files changed, 655 insertions(+), 756 deletions(-) diff --git a/src/HexManiac.Core/Core/Autos/StubDataModel.cs b/src/HexManiac.Core/Core/Autos/StubDataModel.cs index 2b9a058d..21446aa3 100644 --- a/src/HexManiac.Core/Core/Autos/StubDataModel.cs +++ b/src/HexManiac.Core/Core/Autos/StubDataModel.cs @@ -1,199 +1,155 @@ -using System; -using System.Collections.Generic; using HavenSoft.AutoImplement.Delegation; using HavenSoft.HexManiac.Core.Models.Runs; +using System; +using System.Collections.Generic; // this file was created by AutoImplement -namespace HavenSoft.HexManiac.Core.Models -{ - public class StubDataModel : IDataModel - { - public event EventHandler LogMessage; +namespace HavenSoft.HexManiac.Core.Models { + public class StubDataModel : IDataModel { + public event EventHandler LogMessage; - public Func HasChanged { get; set; } - - bool IDataModel.HasChanged(int index) - { - if (this.HasChanged != null) - { - return this.HasChanged(index); - } - else - { - return default(bool); - } - } - - public Action ResetChanges { get; set; } + public Func HasChanged { get; set; } - void IDataModel.ResetChanges() - { - if (this.ResetChanges != null) - { - this.ResetChanges(); - } - } + bool IDataModel.HasChanged(int index) { + if (this.HasChanged != null) { + return this.HasChanged(index); + } else { + return default(bool); + } + } - public int ReferenceCount { get; set; } + public Action ResetChanges { get; set; } - public bool SpartanMode { get; set; } + void IDataModel.ResetChanges() { + if (this.ResetChanges != null) { + this.ResetChanges(); + } + } - public delegate System.Collections.Generic.IEnumerable AllDelegate_() where T : Runs.IFormattedRun; - private readonly Dictionary AllDelegates_ = new Dictionary(new EnumerableEqualityComparer()); - public void ImplementAll(AllDelegate_ implementation) where T : Runs.IFormattedRun - { - var key = new Type[] { typeof(T) }; - AllDelegates_[key] = implementation; - } - public System.Collections.Generic.IEnumerable All() where T : Runs.IFormattedRun - { - var key = new Type[] { typeof(T) }; - object implementation; - if (AllDelegates_.TryGetValue(key, out implementation)) - { - return ((AllDelegate_)implementation).Invoke(); - } - else - { - return default(System.Collections.Generic.IEnumerable); - } - } - - public Func GetNextRun { get; set; } - - Runs.IFormattedRun IDataModel.GetNextRun(int dataIndex) - { - if (this.GetNextRun != null) - { - return this.GetNextRun(dataIndex); - } - else - { - return default(Runs.IFormattedRun); - } - } - - public Func GetNextAnchor { get; set; } - - Runs.IFormattedRun IDataModel.GetNextAnchor(int dataIndex) - { - if (this.GetNextAnchor != null) - { - return this.GetNextAnchor(dataIndex); - } - else - { - return default(Runs.IFormattedRun); - } - } - - public delegate bool TryGetUsefulHeaderDelegate_int_string(int address, out string header); - - public TryGetUsefulHeaderDelegate_int_string TryGetUsefulHeader_int_string { get; set; } - - bool IDataModel.TryGetUsefulHeader(int address, out string header) - { - header = default(string); - if (this.TryGetUsefulHeader_int_string != null) - { - return this.TryGetUsefulHeader_int_string(address, out header); - } - else - { - return default(bool); - } - } - - public delegate bool TryGetListDelegate_string_ValidationList(string name, out ValidationList nameArray); - - public TryGetListDelegate_string_ValidationList TryGetList_string_ValidationList { get; set; } - - bool IDataModel.TryGetList(string name, out ValidationList nameArray) - { - nameArray = default(ValidationList); - if (this.TryGetList_string_ValidationList != null) - { - return this.TryGetList_string_ValidationList(name, out nameArray); - } - else - { - return default(bool); - } - } - - public delegate bool IsAtEndOfArrayDelegate_int_Runs_ITableRun(int dataIndex, out Runs.ITableRun tableRun); - - public IsAtEndOfArrayDelegate_int_Runs_ITableRun IsAtEndOfArray_int_Runs_ITableRun { get; set; } - - bool IDataModel.IsAtEndOfArray(int dataIndex, out Runs.ITableRun tableRun) - { - tableRun = default(Runs.ITableRun); - if (this.IsAtEndOfArray_int_Runs_ITableRun != null) - { - return this.IsAtEndOfArray_int_Runs_ITableRun(dataIndex, out tableRun); - } - else - { - return default(bool); - } - } - - public Action ObserveRunWritten { get; set; } - - void IDataModel.ObserveRunWritten(ModelDelta changeToken, Runs.IFormattedRun run) - { - if (this.ObserveRunWritten != null) - { - this.ObserveRunWritten(changeToken, run); - } - } - - public Action ObserveAnchorWritten { get; set; } - - void IDataModel.ObserveAnchorWritten(ModelDelta changeToken, string anchorName, Runs.IFormattedRun run) - { - if (this.ObserveAnchorWritten != null) - { - this.ObserveAnchorWritten(changeToken, anchorName, run); - } - } - - public Action, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary> MassUpdateFromDelta { get; set; } - - void IDataModel.MassUpdateFromDelta(System.Collections.Generic.IReadOnlyDictionary runsToRemove, System.Collections.Generic.IReadOnlyDictionary runsToAdd, System.Collections.Generic.IReadOnlyDictionary namesToRemove, System.Collections.Generic.IReadOnlyDictionary namesToAdd, System.Collections.Generic.IReadOnlyDictionary unmappedPointersToRemove, System.Collections.Generic.IReadOnlyDictionary unmappedPointersToAdd, System.Collections.Generic.IReadOnlyDictionary matchedWordsToRemove, System.Collections.Generic.IReadOnlyDictionary matchedWordsToAdd, System.Collections.Generic.IReadOnlyDictionary offsetPointersToRemove, System.Collections.Generic.IReadOnlyDictionary offsetPointersToAdd, System.Collections.Generic.IReadOnlyDictionary unmappedConstantsToRemove, System.Collections.Generic.IReadOnlyDictionary unmappedConstantsToAdd, System.Collections.Generic.IReadOnlyDictionary listsToRemove, System.Collections.Generic.IReadOnlyDictionary listsToAdd) - { - if (this.MassUpdateFromDelta != null) - { - this.MassUpdateFromDelta(runsToRemove, runsToAdd, namesToRemove, namesToAdd, unmappedPointersToRemove, unmappedPointersToAdd, matchedWordsToRemove, matchedWordsToAdd, offsetPointersToRemove, offsetPointersToAdd, unmappedConstantsToRemove, unmappedConstantsToAdd, listsToRemove, listsToAdd); - } - } - - public delegate T RelocateForExpansionDelegate_ModelDelta_T_int(ModelDelta changeToken, T run, int minimumLength) where T : Runs.IFormattedRun; - public delegate T RelocateForExpansionDelegate_ModelDelta_T_int_int(ModelDelta changeToken, T run, int currentLength, int desiredLength) where T : Runs.IFormattedRun; - private readonly Dictionary RelocateForExpansionDelegates_ModelDelta_T_int = new Dictionary(new EnumerableEqualityComparer()); - private readonly Dictionary RelocateForExpansionDelegates_ModelDelta_T_int_int = new(new EnumerableEqualityComparer()); - public void ImplementRelocateForExpansion(RelocateForExpansionDelegate_ModelDelta_T_int implementation) where T : Runs.IFormattedRun - { - var key = new Type[] { typeof(T) }; - RelocateForExpansionDelegates_ModelDelta_T_int[key] = implementation; - } - public void ImplementRelocateForExpansion(RelocateForExpansionDelegate_ModelDelta_T_int_int implementation)where T : Runs.IFormattedRun { + public int ReferenceCount { get; set; } + + public bool SpartanMode { get; set; } + + public delegate System.Collections.Generic.IEnumerable AllDelegate_() where T : Runs.IFormattedRun; + private readonly Dictionary AllDelegates_ = new Dictionary(new EnumerableEqualityComparer()); + public void ImplementAll(AllDelegate_ implementation) where T : Runs.IFormattedRun { + var key = new Type[] { typeof(T) }; + AllDelegates_[key] = implementation; + } + public System.Collections.Generic.IEnumerable All() where T : Runs.IFormattedRun { + var key = new Type[] { typeof(T) }; + object implementation; + if (AllDelegates_.TryGetValue(key, out implementation)) { + return ((AllDelegate_)implementation).Invoke(); + } else { + return default(System.Collections.Generic.IEnumerable); + } + } + + public Func GetNextRun { get; set; } + + Runs.IFormattedRun IDataModel.GetNextRun(int dataIndex) { + if (this.GetNextRun != null) { + return this.GetNextRun(dataIndex); + } else { + return default(Runs.IFormattedRun); + } + } + + public Func GetNextAnchor { get; set; } + + Runs.IFormattedRun IDataModel.GetNextAnchor(int dataIndex) { + if (this.GetNextAnchor != null) { + return this.GetNextAnchor(dataIndex); + } else { + return default(Runs.IFormattedRun); + } + } + + public delegate bool TryGetUsefulHeaderDelegate_int_string(int address, out string header); + + public TryGetUsefulHeaderDelegate_int_string TryGetUsefulHeader_int_string { get; set; } + + bool IDataModel.TryGetUsefulHeader(int address, out string header) { + header = default(string); + if (this.TryGetUsefulHeader_int_string != null) { + return this.TryGetUsefulHeader_int_string(address, out header); + } else { + return default(bool); + } + } + + public delegate bool TryGetListDelegate_string_ValidationList(string name, out ValidationList nameArray); + + public TryGetListDelegate_string_ValidationList TryGetList_string_ValidationList { get; set; } + + bool IDataModel.TryGetList(string name, out ValidationList nameArray) { + nameArray = default(ValidationList); + if (this.TryGetList_string_ValidationList != null) { + return this.TryGetList_string_ValidationList(name, out nameArray); + } else { + return default(bool); + } + } + + public delegate bool IsAtEndOfArrayDelegate_int_Runs_ITableRun(int dataIndex, out Runs.ITableRun tableRun); + + public IsAtEndOfArrayDelegate_int_Runs_ITableRun IsAtEndOfArray_int_Runs_ITableRun { get; set; } + + bool IDataModel.IsAtEndOfArray(int dataIndex, out Runs.ITableRun tableRun) { + tableRun = default(Runs.ITableRun); + if (this.IsAtEndOfArray_int_Runs_ITableRun != null) { + return this.IsAtEndOfArray_int_Runs_ITableRun(dataIndex, out tableRun); + } else { + return default(bool); + } + } + + public Action ObserveRunWritten { get; set; } + + void IDataModel.ObserveRunWritten(ModelDelta changeToken, Runs.IFormattedRun run) { + if (this.ObserveRunWritten != null) { + this.ObserveRunWritten(changeToken, run); + } + } + + public Action ObserveAnchorWritten { get; set; } + + void IDataModel.ObserveAnchorWritten(ModelDelta changeToken, string anchorName, Runs.IFormattedRun run) { + if (this.ObserveAnchorWritten != null) { + this.ObserveAnchorWritten(changeToken, anchorName, run); + } + } + + public Action, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyDictionary> MassUpdateFromDelta { get; set; } + + void IDataModel.MassUpdateFromDelta(System.Collections.Generic.IReadOnlyDictionary runsToRemove, System.Collections.Generic.IReadOnlyDictionary runsToAdd, System.Collections.Generic.IReadOnlyDictionary namesToRemove, System.Collections.Generic.IReadOnlyDictionary namesToAdd, System.Collections.Generic.IReadOnlyDictionary unmappedPointersToRemove, System.Collections.Generic.IReadOnlyDictionary unmappedPointersToAdd, System.Collections.Generic.IReadOnlyDictionary matchedWordsToRemove, System.Collections.Generic.IReadOnlyDictionary matchedWordsToAdd, System.Collections.Generic.IReadOnlyDictionary offsetPointersToRemove, System.Collections.Generic.IReadOnlyDictionary offsetPointersToAdd, System.Collections.Generic.IReadOnlyDictionary unmappedConstantsToRemove, System.Collections.Generic.IReadOnlyDictionary unmappedConstantsToAdd, System.Collections.Generic.IReadOnlyDictionary listsToRemove, System.Collections.Generic.IReadOnlyDictionary listsToAdd) { + if (this.MassUpdateFromDelta != null) { + this.MassUpdateFromDelta(runsToRemove, runsToAdd, namesToRemove, namesToAdd, unmappedPointersToRemove, unmappedPointersToAdd, matchedWordsToRemove, matchedWordsToAdd, offsetPointersToRemove, offsetPointersToAdd, unmappedConstantsToRemove, unmappedConstantsToAdd, listsToRemove, listsToAdd); + } + } + + public delegate T RelocateForExpansionDelegate_ModelDelta_T_int(ModelDelta changeToken, T run, int minimumLength) where T : Runs.IFormattedRun; + public delegate T RelocateForExpansionDelegate_ModelDelta_T_int_int(ModelDelta changeToken, T run, int currentLength, int desiredLength) where T : Runs.IFormattedRun; + private readonly Dictionary RelocateForExpansionDelegates_ModelDelta_T_int = new Dictionary(new EnumerableEqualityComparer()); + private readonly Dictionary RelocateForExpansionDelegates_ModelDelta_T_int_int = new(new EnumerableEqualityComparer()); + public void ImplementRelocateForExpansion(RelocateForExpansionDelegate_ModelDelta_T_int implementation) where T : Runs.IFormattedRun { + var key = new Type[] { typeof(T) }; + RelocateForExpansionDelegates_ModelDelta_T_int[key] = implementation; + } + public void ImplementRelocateForExpansion(RelocateForExpansionDelegate_ModelDelta_T_int_int implementation) where T : Runs.IFormattedRun { var key = new Type[] { typeof(T) }; RelocateForExpansionDelegates_ModelDelta_T_int_int[key] = implementation; - } - public T RelocateForExpansion(ModelDelta changeToken, T run, int minimumLength) where T : Runs.IFormattedRun - { - var key = new Type[] { typeof(T) }; - object implementation; - if (RelocateForExpansionDelegates_ModelDelta_T_int.TryGetValue(key, out implementation)) - { - return ((RelocateForExpansionDelegate_ModelDelta_T_int)implementation).Invoke(changeToken, run, minimumLength); - } - else - { - return default(T); - } - } + } + public T RelocateForExpansion(ModelDelta changeToken, T run, int minimumLength) where T : Runs.IFormattedRun { + var key = new Type[] { typeof(T) }; + object implementation; + if (RelocateForExpansionDelegates_ModelDelta_T_int.TryGetValue(key, out implementation)) { + return ((RelocateForExpansionDelegate_ModelDelta_T_int)implementation).Invoke(changeToken, run, minimumLength); + } else { + return default(T); + } + } public T RelocateForExpansion(ModelDelta changeToken, T run, int currentLength, int desiredLength) where T : Runs.IFormattedRun { var key = new Type[] { typeof(T) }; object implementation; @@ -203,578 +159,439 @@ namespace HavenSoft.HexManiac.Core.Models return default(T); } } - - public Func FindFreeSpace { get; set; } - - int IDataModel.FindFreeSpace(int start, int length) - { - if (this.FindFreeSpace != null) - { - return this.FindFreeSpace(start, length); - } - else - { - return default(int); - } - } - - public Action ClearAnchor { get; set; } - - void IDataModel.ClearAnchor(ModelDelta changeToken, int start, int length) - { - if (this.ClearAnchor != null) - { - this.ClearAnchor(changeToken, start, length); - } - } - - public Action ClearFormat { get; set; } - - void IDataModel.ClearFormat(ModelDelta changeToken, int start, int length) - { - if (this.ClearFormat != null) - { - this.ClearFormat(changeToken, start, length); - } - } - - public Action ClearData { get; set; } - - void IDataModel.ClearData(ModelDelta changeToken, int start, int length) - { - if (this.ClearData != null) - { - this.ClearData(changeToken, start, length); - } - } - - public Action ClearFormatAndData { get; set; } - - void IDataModel.ClearFormatAndData(ModelDelta changeToken, int start, int length) - { - if (this.ClearFormatAndData != null) - { - this.ClearFormatAndData(changeToken, start, length); - } - } - - public Action, IReadOnlyDictionary, string> SetList { get; set; } - - void IDataModel.SetList(ModelDelta changeToken, string name, IEnumerable list, IReadOnlyDictionary comments, string hash) - { + + public Func FindFreeSpace { get; set; } + + int IDataModel.FindFreeSpace(int start, int length) { + if (this.FindFreeSpace != null) { + return this.FindFreeSpace(start, length); + } else { + return default(int); + } + } + + public Action ClearAnchor { get; set; } + + void IDataModel.ClearAnchor(ModelDelta changeToken, int start, int length) { + if (this.ClearAnchor != null) { + this.ClearAnchor(changeToken, start, length); + } + } + + public Action ClearFormat { get; set; } + + void IDataModel.ClearFormat(ModelDelta changeToken, int start, int length) { + if (this.ClearFormat != null) { + this.ClearFormat(changeToken, start, length); + } + } + + public Action ClearData { get; set; } + + void IDataModel.ClearData(ModelDelta changeToken, int start, int length) { + if (this.ClearData != null) { + this.ClearData(changeToken, start, length); + } + } + + public Action ClearFormatAndData { get; set; } + + void IDataModel.ClearFormatAndData(ModelDelta changeToken, int start, int length) { + if (this.ClearFormatAndData != null) { + this.ClearFormatAndData(changeToken, start, length); + } + } + + public Action, IReadOnlyDictionary, string> SetList { get; set; } + + void IDataModel.SetList(ModelDelta changeToken, string name, IEnumerable list, IReadOnlyDictionary comments, string hash) { SetList?.Invoke(changeToken, name, list, comments, hash); - } - - public Action ClearPointer { get; set; } - - void IDataModel.ClearPointer(ModelDelta currentChange, int source, int destination) - { - if (this.ClearPointer != null) - { - this.ClearPointer(currentChange, source, destination); - } - } - - public Func, int, int, bool, string> Copy { get; set; } - - string IDataModel.Copy(System.Func changeToken, int start, int length, bool deep) - { - if (this.Copy != null) - { - return this.Copy(changeToken, start, length, deep); - } - else - { - return default(string); - } - } - - public Action Load { get; set; } - - void IDataModel.Load(System.Byte[] newData, StoredMetadata metadata) - { - if (this.Load != null) - { - this.Load(newData, metadata); - } - } - - public Action ExpandData { get; set; } - - void IDataModel.ExpandData(ModelDelta changeToken, int minimumLength) - { - if (this.ExpandData != null) - { - this.ExpandData(changeToken, minimumLength); - } - } - - public Action ContractData { get; set; } - - void IDataModel.ContractData(ModelDelta changeToken, int maximumLength) - { - if (this.ContractData != null) - { - this.ContractData(changeToken, maximumLength); - } - } - - public Func> SearchForPointersToAnchor { get; set; } - - Runs.SortedSpan IDataModel.SearchForPointersToAnchor(ModelDelta changeToken, bool ignoreNoInfoPointers, System.Int32[] addresses) - { - if (this.SearchForPointersToAnchor != null) - { - return this.SearchForPointersToAnchor(changeToken, ignoreNoInfoPointers, addresses); - } - else - { - return default(Runs.SortedSpan); - } - } - - public Func WritePointer { get; set; } - - bool IDataModel.WritePointer(ModelDelta changeToken, int address, int pointerDestination) - { - if (this.WritePointer != null) - { - return this.WritePointer(changeToken, address, pointerDestination); - } - else - { - return default(bool); - } - } - - public Func WriteValue { get; set; } - - bool IDataModel.WriteValue(ModelDelta changeToken, int address, int value) - { - if (this.WriteValue != null) - { - return this.WriteValue(changeToken, address, value); - } - else - { - return default(bool); - } - } - - public Func ReadPointer { get; set; } - - int IDataModel.ReadPointer(int address) - { - if (this.ReadPointer != null) - { - return this.ReadPointer(address); - } - else - { - return default(int); - } - } - - public Func ReadValue { get; set; } - - int IDataModel.ReadValue(int address) - { - if (this.ReadValue != null) - { - return this.ReadValue(address); - } - else - { - return default(int); - } - } - - public Func> GetUnmappedSourcesToAnchor { get; set; } - - Runs.SortedSpan IDataModel.GetUnmappedSourcesToAnchor(string anchor) - { - if (this.GetUnmappedSourcesToAnchor != null) - { - return this.GetUnmappedSourcesToAnchor(anchor); - } - else - { - return default(Runs.SortedSpan); - } - } - - public Action SetUnmappedConstant { get; set; } - - void IDataModel.SetUnmappedConstant(ModelDelta changeToken, string name, int value) - { - if (this.SetUnmappedConstant != null) - { - this.SetUnmappedConstant(changeToken, name, value); - } - } - - public delegate bool TryGetUnmappedConstantDelegate_string_int(string name, out int value); - - public TryGetUnmappedConstantDelegate_string_int TryGetUnmappedConstant_string_int { get; set; } - - bool IDataModel.TryGetUnmappedConstant(string name, out int value) - { - value = default(int); - if (this.TryGetUnmappedConstant_string_int != null) - { - return this.TryGetUnmappedConstant_string_int(name, out value); - } - else - { - return default(bool); - } - } - - public Func GetAddressFromAnchor { get; set; } - - int IDataModel.GetAddressFromAnchor(ModelDelta changeToken, int requestSource, string anchor) - { - if (this.GetAddressFromAnchor != null) - { - return this.GetAddressFromAnchor(changeToken, requestSource, anchor); - } - else - { - return default(int); - } - } - - public Func GetAnchorFromAddress { get; set; } - - string IDataModel.GetAnchorFromAddress(int requestSource, int destination) - { - if (this.GetAnchorFromAddress != null) - { - return this.GetAnchorFromAddress(requestSource, destination); - } - else - { - return default(string); - } - } - - public Func> GetAutoCompleteAnchorNameOptions { get; set; } - - System.Collections.Generic.IEnumerable IDataModel.GetAutoCompleteAnchorNameOptions(string partial, int maxResults) - { - if (this.GetAutoCompleteAnchorNameOptions != null) - { - return this.GetAutoCompleteAnchorNameOptions(partial, maxResults); - } - else - { - return default(System.Collections.Generic.IEnumerable); - } - } - - public Func ExportMetadata { get; set; } - - StoredMetadata IDataModel.ExportMetadata(GameReferenceTables references, IMetadataInfo metadataInfo) - { - if (this.ExportMetadata != null) - { - return this.ExportMetadata(references, metadataInfo); - } - else - { - return default(StoredMetadata); - } - } - - public Action, int, int, int, bool> UpdateArrayPointer { get; set; } - - void IDataModel.UpdateArrayPointer(ModelDelta changeToken, Runs.ArrayRunElementSegment segment, System.Collections.Generic.IReadOnlyList segments, int parentIndex, int address, int destination, bool writeDestinationFormat) - { - if (this.UpdateArrayPointer != null) - { - this.UpdateArrayPointer(changeToken, segment, segments, parentIndex, address, destination, writeDestinationFormat); - } - } - - public Func, System.Collections.Generic.IReadOnlyList, int> ConsiderResultsAsTextRuns { get; set; } - - int IDataModel.ConsiderResultsAsTextRuns(System.Func futureChange, System.Collections.Generic.IReadOnlyList startLocations) - { - if (this.ConsiderResultsAsTextRuns != null) - { - return this.ConsiderResultsAsTextRuns(futureChange, startLocations); - } - else - { - return default(int); - } - } - - public Func> GetAutoCompleteByteNameOptions { get; set; } - - System.Collections.Generic.IEnumerable IDataModel.GetAutoCompleteByteNameOptions(string text) - { - if (this.GetAutoCompleteByteNameOptions != null) - { - return this.GetAutoCompleteByteNameOptions(text); - } - else - { - return default(System.Collections.Generic.IEnumerable); - } - } - - public Func> GetMatchedWords { get; set; } - - System.Collections.Generic.IReadOnlyList IDataModel.GetMatchedWords(string name) - { - if (this.GetMatchedWords != null) - { - return this.GetMatchedWords(name); - } - else - { - return default(System.Collections.Generic.IReadOnlyList); - } - } - - public Func> GetTableGroups { get; set; } - - System.Collections.Generic.IReadOnlyList IDataModel.GetTableGroups(string tableName) - { - if (this.GetTableGroups != null) - { - return this.GetTableGroups(tableName); - } - else - { - return default(System.Collections.Generic.IReadOnlyList); - } - } - - public Action, string> AppendTableGroup { get; set; } - - void IDataModel.AppendTableGroup(ModelDelta token, string groupName, System.Collections.Generic.IReadOnlyList tableNames, string hash) - { - if (this.AppendTableGroup != null) - { - this.AppendTableGroup(token, groupName, tableNames, hash); - } - } - - public PropertyImplementation InitializationWorkload = new PropertyImplementation(); - - System.Threading.Tasks.Task IDataModel.InitializationWorkload - { - get - { - return this.InitializationWorkload.get(); - } - } - public PropertyImplementation RawData = new PropertyImplementation(); - - System.Byte[] IDataModel.RawData - { - get - { - return this.RawData.get(); - } - } - public PropertyImplementation CurrentCacheScope = new PropertyImplementation(); - - Runs.ModelCacheScope IDataModel.CurrentCacheScope - { - get - { - return this.CurrentCacheScope.get(); - } - } - public PropertyImplementation ChangeCount = new PropertyImplementation(); - - int IDataModel.ChangeCount - { - get - { - return this.ChangeCount.get(); - } - } - public PropertyImplementation FreeSpaceStart = new PropertyImplementation(); - - int IDataModel.FreeSpaceStart - { - get - { - return this.FreeSpaceStart.get(); - } - set - { - this.FreeSpaceStart.set(value); - } - } - public PropertyImplementation FreeSpaceBuffer = new PropertyImplementation(); - - int IDataModel.FreeSpaceBuffer - { - get - { - return this.FreeSpaceBuffer.get(); - } - set - { - this.FreeSpaceBuffer.set(value); - } - } - public PropertyImplementation NextExportID = new PropertyImplementation(); - - int IDataModel.NextExportID - { - get - { - return this.NextExportID.get(); - } - set - { - this.NextExportID.set(value); - } - } - public PropertyImplementation FormatRunFactory = new PropertyImplementation(); - - Runs.Factory.IFormatRunFactory IDataModel.FormatRunFactory - { - get - { - return this.FormatRunFactory.get(); - } - } - public PropertyImplementation TextConverter = new PropertyImplementation(); - - ITextConverter IDataModel.TextConverter - { - get - { - return this.TextConverter.get(); - } - } - public Func get_Item = (index) => default(byte); - - public Action set_Item = (index, value) => {}; - - byte IDataModel.this[int index] - { - get - { - return get_Item(index); - } - set - { - set_Item(index, value); - } - } - public PropertyImplementation> ListNames = new PropertyImplementation>(); - - System.Collections.Generic.IReadOnlyList IDataModel.ListNames - { - get - { - return this.ListNames.get(); - } - } - public PropertyImplementation> Arrays = new PropertyImplementation>(); - - System.Collections.Generic.IReadOnlyList IDataModel.Arrays - { - get - { - return this.Arrays.get(); - } - } - public PropertyImplementation> Streams = new PropertyImplementation>(); - - System.Collections.Generic.IReadOnlyList IDataModel.Streams - { - get - { - return this.Streams.get(); - } - } - public PropertyImplementation> Anchors = new PropertyImplementation>(); - - System.Collections.Generic.IReadOnlyList IDataModel.Anchors - { - get - { - return this.Anchors.get(); - } - } - public PropertyImplementation> GotoShortcuts = new PropertyImplementation>(); - - System.Collections.Generic.IReadOnlyList IDataModel.GotoShortcuts - { - get - { - return this.GotoShortcuts.get(); - } - } - byte System.Collections.Generic.IReadOnlyList.this[int index] - { - get - { - return get_Item(index); - } - } - public PropertyImplementation Count = new PropertyImplementation(); - - int System.Collections.Generic.IReadOnlyCollection.Count - { - get - { - return this.Count.get(); - } - } - public Func> GetEnumerator { get; set; } - - System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() - { - if (this.GetEnumerator != null) - { - return this.GetEnumerator(); - } - else - { - return default(System.Collections.Generic.IEnumerator); - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - if (this.GetEnumerator != null) - { - return this.GetEnumerator(); - } - else - { - return default(System.Collections.IEnumerator); - } - } - - public Func Equals { get; set; } - - bool System.IEquatable.Equals(HavenSoft.HexManiac.Core.Models.IDataModel other) - { - if (this.Equals != null) - { - return this.Equals(other); - } - else - { - return default(bool); - } - } + } + + public Action ClearPointer { get; set; } + + void IDataModel.ClearPointer(ModelDelta currentChange, int source, int destination) { + if (this.ClearPointer != null) { + this.ClearPointer(currentChange, source, destination); + } + } + + public Func, int, int, bool, string> Copy { get; set; } + + string IDataModel.Copy(System.Func changeToken, int start, int length, bool deep) { + if (this.Copy != null) { + return this.Copy(changeToken, start, length, deep); + } else { + return default(string); + } + } + + public Action Load { get; set; } + + void IDataModel.Load(System.Byte[] newData, StoredMetadata metadata) { + if (this.Load != null) { + this.Load(newData, metadata); + } + } + + public Action ExpandData { get; set; } + + void IDataModel.ExpandData(ModelDelta changeToken, int minimumLength) { + if (this.ExpandData != null) { + this.ExpandData(changeToken, minimumLength); + } + } + + public Action ContractData { get; set; } + + void IDataModel.ContractData(ModelDelta changeToken, int maximumLength) { + if (this.ContractData != null) { + this.ContractData(changeToken, maximumLength); + } + } + + public Func> SearchForPointersToAnchor { get; set; } + + Runs.SortedSpan IDataModel.SearchForPointersToAnchor(ModelDelta changeToken, bool ignoreNoInfoPointers, System.Int32[] addresses) { + if (this.SearchForPointersToAnchor != null) { + return this.SearchForPointersToAnchor(changeToken, ignoreNoInfoPointers, addresses); + } else { + return default(Runs.SortedSpan); + } + } + + public Func WritePointer { get; set; } + + bool IDataModel.WritePointer(ModelDelta changeToken, int address, int pointerDestination) { + if (this.WritePointer != null) { + return this.WritePointer(changeToken, address, pointerDestination); + } else { + return default(bool); + } + } + + public Func WriteValue { get; set; } + + bool IDataModel.WriteValue(ModelDelta changeToken, int address, int value) { + if (this.WriteValue != null) { + return this.WriteValue(changeToken, address, value); + } else { + return default(bool); + } + } + + public Func ReadPointer { get; set; } + + int IDataModel.ReadPointer(int address) { + if (this.ReadPointer != null) { + return this.ReadPointer(address); + } else { + return default(int); + } + } + + public Func ReadValue { get; set; } + + int IDataModel.ReadValue(int address) { + if (this.ReadValue != null) { + return this.ReadValue(address); + } else { + return default(int); + } + } + + public Func> GetUnmappedSourcesToAnchor { get; set; } + + Runs.SortedSpan IDataModel.GetUnmappedSourcesToAnchor(string anchor) { + if (this.GetUnmappedSourcesToAnchor != null) { + return this.GetUnmappedSourcesToAnchor(anchor); + } else { + return default(Runs.SortedSpan); + } + } + + public Action SetUnmappedConstant { get; set; } + + void IDataModel.SetUnmappedConstant(ModelDelta changeToken, string name, int value) { + if (this.SetUnmappedConstant != null) { + this.SetUnmappedConstant(changeToken, name, value); + } + } + + public delegate bool TryGetUnmappedConstantDelegate_string_int(string name, out int value); + + public TryGetUnmappedConstantDelegate_string_int TryGetUnmappedConstant_string_int { get; set; } + + bool IDataModel.TryGetUnmappedConstant(string name, out int value) { + value = default(int); + if (this.TryGetUnmappedConstant_string_int != null) { + return this.TryGetUnmappedConstant_string_int(name, out value); + } else { + return default(bool); + } + } + + public Func GetAddressFromAnchor { get; set; } + + int IDataModel.GetAddressFromAnchor(ModelDelta changeToken, int requestSource, string anchor) { + if (this.GetAddressFromAnchor != null) { + return this.GetAddressFromAnchor(changeToken, requestSource, anchor); + } else { + return default(int); + } + } + + public Func GetAnchorFromAddress { get; set; } + + string IDataModel.GetAnchorFromAddress(int requestSource, int destination) { + if (this.GetAnchorFromAddress != null) { + return this.GetAnchorFromAddress(requestSource, destination); + } else { + return default(string); + } + } + + public Func> GetAutoCompleteAnchorNameOptions { get; set; } + + System.Collections.Generic.IEnumerable IDataModel.GetAutoCompleteAnchorNameOptions(string partial, int maxResults) { + if (this.GetAutoCompleteAnchorNameOptions != null) { + return this.GetAutoCompleteAnchorNameOptions(partial, maxResults); + } else { + return default(System.Collections.Generic.IEnumerable); + } + } + + public Func ExportMetadata { get; set; } + + StoredMetadata IDataModel.ExportMetadata(GameReferenceTables references, IMetadataInfo metadataInfo) { + if (this.ExportMetadata != null) { + return this.ExportMetadata(references, metadataInfo); + } else { + return default(StoredMetadata); + } + } + + public Action, int, int, int, bool> UpdateArrayPointer { get; set; } + + void IDataModel.UpdateArrayPointer(ModelDelta changeToken, Runs.ArrayRunElementSegment segment, System.Collections.Generic.IReadOnlyList segments, int parentIndex, int address, int destination, bool writeDestinationFormat) { + if (this.UpdateArrayPointer != null) { + this.UpdateArrayPointer(changeToken, segment, segments, parentIndex, address, destination, writeDestinationFormat); + } + } + + public Func, System.Collections.Generic.IReadOnlyList, int> ConsiderResultsAsTextRuns { get; set; } + + int IDataModel.ConsiderResultsAsTextRuns(System.Func futureChange, System.Collections.Generic.IReadOnlyList startLocations) { + if (this.ConsiderResultsAsTextRuns != null) { + return this.ConsiderResultsAsTextRuns(futureChange, startLocations); + } else { + return default(int); + } + } + + public Func> GetAutoCompleteByteNameOptions { get; set; } + + System.Collections.Generic.IEnumerable IDataModel.GetAutoCompleteByteNameOptions(string text) { + if (this.GetAutoCompleteByteNameOptions != null) { + return this.GetAutoCompleteByteNameOptions(text); + } else { + return default(System.Collections.Generic.IEnumerable); + } + } + + public Func> GetMatchedWords { get; set; } + + System.Collections.Generic.IReadOnlyList IDataModel.GetMatchedWords(string name) { + if (this.GetMatchedWords != null) { + return this.GetMatchedWords(name); + } else { + return default(System.Collections.Generic.IReadOnlyList); + } + } + + public Func> GetTableGroups { get; set; } + + System.Collections.Generic.IReadOnlyList IDataModel.GetTableGroups(string tableName) { + if (this.GetTableGroups != null) { + return this.GetTableGroups(tableName); + } else { + return default(System.Collections.Generic.IReadOnlyList); + } + } + + public Action, string> AppendTableGroup { get; set; } + + void IDataModel.AppendTableGroup(ModelDelta token, string groupName, System.Collections.Generic.IReadOnlyList tableNames, string hash) { + if (this.AppendTableGroup != null) { + this.AppendTableGroup(token, groupName, tableNames, hash); + } + } + + public PropertyImplementation InitializationWorkload = new PropertyImplementation(); + + System.Threading.Tasks.Task IDataModel.InitializationWorkload { + get { + return this.InitializationWorkload.get(); + } + } + public PropertyImplementation RawData = new PropertyImplementation(); + + System.Byte[] IDataModel.RawData { + get { + return this.RawData.get(); + } + } + public PropertyImplementation CurrentCacheScope = new PropertyImplementation(); + + Runs.ModelCacheScope IDataModel.CurrentCacheScope { + get { + return this.CurrentCacheScope.get(); + } + } + public void ClearCacheScope() => CurrentCacheScope.value = null; + + public PropertyImplementation ChangeCount = new PropertyImplementation(); + + int IDataModel.ChangeCount { + get { + return this.ChangeCount.get(); + } + } + public PropertyImplementation FreeSpaceStart = new PropertyImplementation(); + + int IDataModel.FreeSpaceStart { + get { + return this.FreeSpaceStart.get(); + } + set { + this.FreeSpaceStart.set(value); + } + } + public PropertyImplementation FreeSpaceBuffer = new PropertyImplementation(); + + int IDataModel.FreeSpaceBuffer { + get { + return this.FreeSpaceBuffer.get(); + } + set { + this.FreeSpaceBuffer.set(value); + } + } + public PropertyImplementation NextExportID = new PropertyImplementation(); + + int IDataModel.NextExportID { + get { + return this.NextExportID.get(); + } + set { + this.NextExportID.set(value); + } + } + public PropertyImplementation FormatRunFactory = new PropertyImplementation(); + + Runs.Factory.IFormatRunFactory IDataModel.FormatRunFactory { + get { + return this.FormatRunFactory.get(); + } + } + public PropertyImplementation TextConverter = new PropertyImplementation(); + + ITextConverter IDataModel.TextConverter { + get { + return this.TextConverter.get(); + } + } + public Func get_Item = (index) => default(byte); + + public Action set_Item = (index, value) => { }; + + byte IDataModel.this[int index] { + get { + return get_Item(index); + } + set { + set_Item(index, value); + } + } + public PropertyImplementation> ListNames = new PropertyImplementation>(); + + System.Collections.Generic.IReadOnlyList IDataModel.ListNames { + get { + return this.ListNames.get(); + } + } + public PropertyImplementation> Arrays = new PropertyImplementation>(); + + System.Collections.Generic.IReadOnlyList IDataModel.Arrays { + get { + return this.Arrays.get(); + } + } + public PropertyImplementation> Streams = new PropertyImplementation>(); + + System.Collections.Generic.IReadOnlyList IDataModel.Streams { + get { + return this.Streams.get(); + } + } + public PropertyImplementation> Anchors = new PropertyImplementation>(); + + System.Collections.Generic.IReadOnlyList IDataModel.Anchors { + get { + return this.Anchors.get(); + } + } + public PropertyImplementation> GotoShortcuts = new PropertyImplementation>(); + + System.Collections.Generic.IReadOnlyList IDataModel.GotoShortcuts { + get { + return this.GotoShortcuts.get(); + } + } + byte System.Collections.Generic.IReadOnlyList.this[int index] { + get { + return get_Item(index); + } + } + public PropertyImplementation Count = new PropertyImplementation(); + + int System.Collections.Generic.IReadOnlyCollection.Count { + get { + return this.Count.get(); + } + } + public Func> GetEnumerator { get; set; } + + System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { + if (this.GetEnumerator != null) { + return this.GetEnumerator(); + } else { + return default(System.Collections.Generic.IEnumerator); + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { + if (this.GetEnumerator != null) { + return this.GetEnumerator(); + } else { + return default(System.Collections.IEnumerator); + } + } + + public Func Equals { get; set; } + + bool System.IEquatable.Equals(HavenSoft.HexManiac.Core.Models.IDataModel other) { + if (this.Equals != null) { + return this.Equals(other); + } else { + return default(bool); + } + } public Func, int> GetScriptLength; int IDataModel.GetScriptLength(IScriptStartRun run, IDictionary destinationLengths) => GetScriptLength?.Invoke(run, destinationLengths) ?? default; public Action UpdateGotoShortcut; void IDataModel.UpdateGotoShortcut(int index, GotoShortcutModel shortcut) => UpdateGotoShortcut?.Invoke(index, shortcut); - } + } } diff --git a/src/HexManiac.Core/Models/Code/ScriptParser.cs b/src/HexManiac.Core/Models/Code/ScriptParser.cs index c307e6b8..136847c0 100644 --- a/src/HexManiac.Core/Models/Code/ScriptParser.cs +++ b/src/HexManiac.Core/Models/Code/ScriptParser.cs @@ -219,7 +219,7 @@ namespace HavenSoft.HexManiac.Core.Models.Code { private Dictionary> tableDependencyCache = new(); public IEnumerable DependsOn(string basename) { - if (tableDependencyCache.ContainsKey(basename)) return tableDependencyCache[basename]; + lock (tableDependencyCache) if (tableDependencyCache.ContainsKey(basename)) return tableDependencyCache[basename]; var matches = new List(); foreach (var line in engine) { foreach (var arg in line.Args) { @@ -229,7 +229,7 @@ namespace HavenSoft.HexManiac.Core.Models.Code { } } } - return tableDependencyCache[basename] = matches; + lock (tableDependencyCache) return tableDependencyCache[basename] = matches; } private HashSet constantCache, keywordCache; diff --git a/src/HexManiac.Core/Models/IDataModel.cs b/src/HexManiac.Core/Models/IDataModel.cs index e1ac29bb..0c736d18 100644 --- a/src/HexManiac.Core/Models/IDataModel.cs +++ b/src/HexManiac.Core/Models/IDataModel.cs @@ -88,6 +88,7 @@ namespace HavenSoft.HexManiac.Core.Models { void ClearFormat(ModelDelta changeToken, int start, int length); void ClearData(ModelDelta changeToken, int start, int length); void ClearFormatAndData(ModelDelta changeToken, int start, int length); + void ClearCacheScope(); void SetList(ModelDelta changeToken, string name, IEnumerable list, IReadOnlyDictionary comments, string hash); void UpdateGotoShortcut(int index, GotoShortcutModel shortcut); void ClearPointer(ModelDelta currentChange, int source, int destination); @@ -142,7 +143,7 @@ namespace HavenSoft.HexManiac.Core.Models { public byte[] RawData { get; private set; } private ModelCacheScope currentCacheScope; - protected void ClearCacheScope() => currentCacheScope = null; + public void ClearCacheScope() => currentCacheScope = null; public ModelCacheScope CurrentCacheScope { get { var instance = currentCacheScope; diff --git a/src/HexManiac.Core/Models/PokemonModel.cs b/src/HexManiac.Core/Models/PokemonModel.cs index ac5e8836..a6c4dfd3 100644 --- a/src/HexManiac.Core/Models/PokemonModel.cs +++ b/src/HexManiac.Core/Models/PokemonModel.cs @@ -1495,7 +1495,7 @@ namespace HavenSoft.HexManiac.Core.Models { if (existingRun == null || existingRun.Start != run.Start) { // no format starts exactly at this anchor, so clear any format that goes over this anchor. ClearFormat(changeToken, location, run.Length); - } else if (!(run is NoInfoRun)) { + } else if (run is not NoInfoRun) { // a format starts exactly at this anchor. if (existingRun.Length < run.Length) { // the new format may extend further. Clear excess space to make room for the longer format. diff --git a/src/HexManiac.Core/ViewModels/Map/IEventViewModel.cs b/src/HexManiac.Core/ViewModels/Map/IEventViewModel.cs index f9d510b7..28557a5c 100644 --- a/src/HexManiac.Core/ViewModels/Map/IEventViewModel.cs +++ b/src/HexManiac.Core/ViewModels/Map/IEventViewModel.cs @@ -1348,8 +1348,26 @@ show: ); public ObservableCollection BasicText { get; } = new(); + public ObservableCollection BasicItemAddresses { get; } = new(); + public ObservableCollection BasicFlagAddresses { get; } = new(); + private int basicFlag = -1; + public FilteringComboOptions BasicItem { get; } = new(); + public bool HasBasicItem => (BasicItem.AllOptions?.Count ?? 0) > 0; + public int BasicFlag { get => basicFlag; set => Set(ref basicFlag, value, old => NotifyPropertyChanged(nameof(HasBasicFlag))); } + public bool HasBasicFlag => basicFlag != -1; + private string basicFlagText = string.Empty; + public string BasicFlagText { + get => basicFlagText; + set => Set(ref basicFlagText, value, old => { + if (!basicFlagText.TryParseHex(out int result)) return; + foreach (var address in BasicFlagAddresses) element.Model.WriteMultiByteValue(address, 2, Token, result); + basicFlag = result; + NotifyPropertyChanged(nameof(BasicFlag)); + }); + } private void FillBasicContent() { + // text BasicText.Clear(); foreach (var spot in Flags.GetAllScriptSpots(Element.Model, parser, new[] { ScriptAddress }, 0x0F)) { var element = new EventTextViewModel() { PointerAddress = spot.Address + 2, Text = { Content = GetText(spot.Address + 2) } }; @@ -1360,11 +1378,56 @@ show: BasicText.Add(element); } + // items + BasicItemAddresses.Clear(); var filter = new List(); foreach (var line in parser.DependsOn(HardcodeTablesModel.ItemsTableName)) { if (line is MacroScriptLine macro && macro.Args[0] is SilentMatchArg silent) filter.Add(silent.ExpectedValue); if (line is ScriptLine sl) filter.Add(line.LineCode[0]); } + var spots = new List(); + var item = -1; + foreach (var spot in Flags.GetAllScriptSpots(element.Model, parser, new[] { ScriptAddress }, true, filter.ToArray())) { + var offset = spot.Address + spot.Line.Args.Until(arg => arg.EnumTableName == HardcodeTablesModel.ItemsTableName).Sum(arg => arg.Length(Element.Model, -1)) + spot.Line.LineCode.Count; + var chosenItem = Element.Model.ReadMultiByteValue(offset, 2); + if (item == -1 || item == chosenItem) { + item = chosenItem; + spots.Add(offset); + } else { + spots.Clear(); + break; + } + } + if (spots.Count > 0) { + BasicItem.Update(ComboOption.Convert(element.Model.GetOptions(HardcodeTablesModel.ItemsTableName)), item); + foreach (var address in spots.Distinct()) BasicItemAddresses.Add(address); + BasicItem.Bind(nameof(BasicItem.SelectedIndex), (sender, e) => { + foreach (var address in BasicItemAddresses) element.Model.WriteMultiByteValue(address, 2, Token, sender.SelectedIndex); + }); + } + + // flags + BasicFlagAddresses.Clear(); + spots.Clear(); + var flag = -1; + foreach (var spot in Flags.GetAllScriptSpots(element.Model, parser, new[] { ScriptAddress }, false, 0x29, 0x2A, 0x2B)) { // setflag, clearflag, checkflag + var offset = spot.Address + 1; + var chosenFlag = element.Model.ReadMultiByteValue(offset, 2); + if (flag == -1 || flag == chosenFlag) { + flag = chosenFlag; + spots.Add(offset); + } else { + spots.Clear(); + break; + } + } + if (spots.Count > 0) { + BasicFlag = flag; + foreach (var address in spots.Distinct()) BasicFlagAddresses.Add(address); + basicFlagText = flag.ToString("X4"); + } + } + #endregion private string GetText(ref string cache, int? pointer) { diff --git a/src/HexManiac.Core/ViewModels/ViewPort.cs b/src/HexManiac.Core/ViewModels/ViewPort.cs index b07f3647..4d43baa2 100644 --- a/src/HexManiac.Core/ViewModels/ViewPort.cs +++ b/src/HexManiac.Core/ViewModels/ViewPort.cs @@ -1439,6 +1439,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels { public void Refresh() { scroll.DataLength = Model.Count; + Model.ClearCacheScope(); var selectionStart = ConvertViewPointToAddress(SelectionStart); if (selectionStart > Model.Count + 1) SelectionStart = ConvertAddressToViewPoint(Model.Count + 1); scroll.UpdateHeaders(); @@ -1447,6 +1448,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels { Tools?.TableTool.DataForCurrentRunChanged(); Tools?.SpriteTool.DataForCurrentRunChanged(); Tools?.CodeTool.ClearConstantCache(); + Tools?.CodeTool.DataForCurrentRunChanged(); UpdateAnchorText(ConvertViewPointToAddress(SelectionStart)); } diff --git a/src/HexManiac.WPF/Controls/MapTab.xaml b/src/HexManiac.WPF/Controls/MapTab.xaml index a91bb327..3f111c12 100644 --- a/src/HexManiac.WPF/Controls/MapTab.xaml +++ b/src/HexManiac.WPF/Controls/MapTab.xaml @@ -762,6 +762,22 @@ + + + + + + + + + + + + + + + +