mirror of
https://github.com/haven1433/HexManiacAdvance.git
synced 2026-10-01 12:46:33 -05:00
repoint scripts based on previous script size, not computed size from model
This commit is contained in:
@@ -163,12 +163,18 @@ namespace HavenSoft.HexManiac.Core.Models
|
||||
}
|
||||
|
||||
public delegate T RelocateForExpansionDelegate_ModelDelta_T_int<T>(ModelDelta changeToken, T run, int minimumLength) where T : Runs.IFormattedRun;
|
||||
public delegate T RelocateForExpansionDelegate_ModelDelta_T_int_int<T>(ModelDelta changeToken, T run, int currentLength, int desiredLength) where T : Runs.IFormattedRun;
|
||||
private readonly Dictionary<Type[], object> RelocateForExpansionDelegates_ModelDelta_T_int = new Dictionary<Type[], object>(new EnumerableEqualityComparer<Type>());
|
||||
private readonly Dictionary<Type[], object> RelocateForExpansionDelegates_ModelDelta_T_int_int = new(new EnumerableEqualityComparer<Type>());
|
||||
public void ImplementRelocateForExpansion<T>(RelocateForExpansionDelegate_ModelDelta_T_int<T> implementation) where T : Runs.IFormattedRun
|
||||
{
|
||||
var key = new Type[] { typeof(T) };
|
||||
RelocateForExpansionDelegates_ModelDelta_T_int[key] = implementation;
|
||||
}
|
||||
public void ImplementRelocateForExpansion<T>(RelocateForExpansionDelegate_ModelDelta_T_int_int<T> implementation)where T : Runs.IFormattedRun {
|
||||
var key = new Type[] { typeof(T) };
|
||||
RelocateForExpansionDelegates_ModelDelta_T_int_int[key] = implementation;
|
||||
}
|
||||
public T RelocateForExpansion<T>(ModelDelta changeToken, T run, int minimumLength) where T : Runs.IFormattedRun
|
||||
{
|
||||
var key = new Type[] { typeof(T) };
|
||||
@@ -182,6 +188,15 @@ namespace HavenSoft.HexManiac.Core.Models
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
public T RelocateForExpansion<T>(ModelDelta changeToken, T run, int currentLength, int desiredLength) where T : Runs.IFormattedRun {
|
||||
var key = new Type[] { typeof(T) };
|
||||
object implementation;
|
||||
if (RelocateForExpansionDelegates_ModelDelta_T_int_int.TryGetValue(key, out implementation)) {
|
||||
return ((RelocateForExpansionDelegate_ModelDelta_T_int_int<T>)implementation).Invoke(changeToken, run, currentLength, desiredLength);
|
||||
} else {
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
public Func<int, int, int> FindFreeSpace { get; set; }
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ namespace HavenSoft.HexManiac.Core.Models {
|
||||
IReadOnlyDictionary<string, int> unmappedConstantsToRemove, IReadOnlyDictionary<string, int> unmappedConstantsToAdd,
|
||||
IReadOnlyDictionary<string, ValidationList> listsToRemove, IReadOnlyDictionary<string, ValidationList> listsToAdd);
|
||||
T RelocateForExpansion<T>(ModelDelta changeToken, T run, int minimumLength) where T : IFormattedRun;
|
||||
T RelocateForExpansion<T>(ModelDelta token, T run, int currentLength, int desiredLength) where T : IFormattedRun;
|
||||
int FindFreeSpace(int start, int length);
|
||||
void ClearAnchor(ModelDelta changeToken, int start, int length);
|
||||
void ClearFormat(ModelDelta changeToken, int start, int length);
|
||||
@@ -284,6 +285,7 @@ namespace HavenSoft.HexManiac.Core.Models {
|
||||
IReadOnlyDictionary<string, ValidationList> listsToAdd);
|
||||
|
||||
public abstract T RelocateForExpansion<T>(ModelDelta changeToken, T run, int minimumLength) where T : IFormattedRun;
|
||||
public abstract T RelocateForExpansion<T>(ModelDelta token, T run, int currentLength, int desiredLength) where T : IFormattedRun;
|
||||
|
||||
public abstract int FindFreeSpace(int start, int length);
|
||||
|
||||
@@ -868,6 +870,7 @@ namespace HavenSoft.HexManiac.Core.Models {
|
||||
IReadOnlyDictionary<string, int> unmappedConstantsToRemove, IReadOnlyDictionary<string, int> unmappedConstantsToAdd,
|
||||
IReadOnlyDictionary<string, ValidationList> listsToRemove, IReadOnlyDictionary<string, ValidationList> listsToAdd) { }
|
||||
public override T RelocateForExpansion<T>(ModelDelta changeToken, T run, int minimumLength) => throw new NotImplementedException();
|
||||
public override T RelocateForExpansion<T>(ModelDelta changeToken, T run, int currentLength, int desiredLength) => throw new NotImplementedException();
|
||||
public override int FindFreeSpace(int start, int length) => throw new NotImplementedException();
|
||||
public override void ClearAnchor(ModelDelta changeToken, int start, int length) { }
|
||||
public override void ClearFormat(ModelDelta changeToken, int start, int length) { }
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using HavenSoft.HexManiac.Core.Models.Runs;
|
||||
using HavenSoft.HexManiac.Core.Models.Runs.Factory;
|
||||
using HavenSoft.HexManiac.Core.Models.Runs.Sprites;
|
||||
using HavenSoft.HexManiac.Core.ViewModels;
|
||||
using HavenSoft.HexManiac.Core.ViewModels.DataFormats;
|
||||
using HavenSoft.HexManiac.Core.ViewModels.Visitors;
|
||||
using System;
|
||||
@@ -1620,6 +1621,22 @@ namespace HavenSoft.HexManiac.Core.Models {
|
||||
}
|
||||
}
|
||||
|
||||
public override T RelocateForExpansion<T>(ModelDelta token, T run, int currentLength, int desiredLength) {
|
||||
if (currentLength < 1) currentLength = 1;
|
||||
if (desiredLength <= currentLength) return run;
|
||||
if (CanSafelyUse(run.Start + currentLength, run.Start + desiredLength)) return run;
|
||||
|
||||
var freeSpace = FindFreeSpace(0x100, desiredLength);
|
||||
lock (threadlock) {
|
||||
if (freeSpace >= 0) {
|
||||
return MoveRun(token, run, currentLength, freeSpace);
|
||||
} else {
|
||||
ExpandData(token, RawData.Length + desiredLength);
|
||||
return MoveRun(token, run, currentLength, RawData.Length - desiredLength - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override int FindFreeSpace(int start, int minimumLength) {
|
||||
if (FreeSpaceStart != 0) start = FreeSpaceStart;
|
||||
if (start < EarliestAllowedAnchor) start = EarliestAllowedAnchor;
|
||||
|
||||
@@ -406,7 +406,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Tools {
|
||||
}
|
||||
} else {
|
||||
if (run is NoInfoRun) run = Construct<SERun>(run.Start, run.PointerSources);
|
||||
run = model.RelocateForExpansion(history.CurrentChange, run, code.Length);
|
||||
run = model.RelocateForExpansion(history.CurrentChange, run, body.CompiledLength, code.Length);
|
||||
if (start != run.Start) {
|
||||
ModelDataMoved?.Invoke(this, (start, run.Start));
|
||||
start = run.Start;
|
||||
|
||||
@@ -693,6 +693,19 @@ label2:;goto <000050>;end";
|
||||
Assert.IsType<TSERun>(Model.GetNextRun(0x100));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnformattedScriptWithInnerAnchor_FormatThenExpand_Repoint() {
|
||||
SetFullModel(0xFF);
|
||||
"06 00 07 00 00 08 02 02".ToByteArray().WriteInto(Model.RawData, 0);
|
||||
Model.ObserveAnchorWritten(Token, "parent", new XSERun(0));
|
||||
Tool.Mode = CodeMode.Script;
|
||||
|
||||
EventScript += " ";
|
||||
EventScript += ";end";
|
||||
|
||||
Assert.Single(Messages);
|
||||
}
|
||||
|
||||
// TODO trainer ai script change -> no auto repoint?
|
||||
|
||||
// TODO test that we get an error (not an exception) if we do auto on an unformatted pointer
|
||||
|
||||
Reference in New Issue
Block a user