mirror of
https://github.com/haven1433/HexManiacAdvance.git
synced 2026-10-03 05:36:34 -05:00
slight refactoring to prep for more array / pointer stuff. Added some insertion points as TODOs
This commit is contained in:
@@ -253,14 +253,6 @@ namespace HavenSoft.HexManiac.Core.Models {
|
||||
// replace / merge with existing
|
||||
// if the only thing changed was the anchor, then don't change the format, just merge the anchor
|
||||
var existingRun = runs[index];
|
||||
if (existingRun is PointerRun pointerRun1) {
|
||||
if (ReadValue(pointerRun1.Start) == 0) {
|
||||
var name = sourceToUnmappedName[pointerRun1.Start];
|
||||
sourceToUnmappedName.Remove(pointerRun1.Start);
|
||||
unmappedNameToSources[name].Remove(pointerRun1.Start);
|
||||
}
|
||||
}
|
||||
|
||||
changeToken.RemoveRun(existingRun);
|
||||
run = run.MergeAnchor(existingRun.PointerSources);
|
||||
runs[index] = run;
|
||||
@@ -285,6 +277,8 @@ namespace HavenSoft.HexManiac.Core.Models {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO if run is array run, look for pointers in the array to link
|
||||
|
||||
if (run is NoInfoRun && run.PointerSources.Count == 0 && !anchorForAddress.ContainsKey(run.Start)) {
|
||||
// this run has no useful information. Remove it.
|
||||
changeToken.RemoveRun(runs[index]);
|
||||
@@ -435,6 +429,8 @@ namespace HavenSoft.HexManiac.Core.Models {
|
||||
}
|
||||
ClearAnchorFormat(changeToken, originalStart, run);
|
||||
|
||||
// TODO if the run is an array run, look for pointers to unlink
|
||||
|
||||
if (alsoClearData) {
|
||||
for (int i = 0; i < run.Length; i++) changeToken.ChangeData(this, run.Start + i, 0xFF);
|
||||
}
|
||||
@@ -668,10 +664,13 @@ namespace HavenSoft.HexManiac.Core.Models {
|
||||
} else {
|
||||
return new ErrorInfo($"Ascii runs must include a length.");
|
||||
}
|
||||
} else if (TryParse(model, format, dataIndex, null, out var arrayRun)) {
|
||||
run = arrayRun;
|
||||
} else if (format != string.Empty) {
|
||||
return new ErrorInfo($"Format {format} was not understood.");
|
||||
} else {
|
||||
var errorInfo = TryParse(model, format, dataIndex, null, out var arrayRun);
|
||||
if (errorInfo == ErrorInfo.NoError) {
|
||||
run = arrayRun;
|
||||
} else if (format != string.Empty) {
|
||||
return new ErrorInfo($"Format {format} was not understood.");
|
||||
}
|
||||
}
|
||||
|
||||
return ErrorInfo.NoError;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
|
||||
namespace HavenSoft.HexManiac.Core.Models.Runs {
|
||||
@@ -94,11 +95,11 @@ namespace HavenSoft.HexManiac.Core.Models.Runs {
|
||||
owner = data;
|
||||
FormatString = format;
|
||||
var closeArray = format.LastIndexOf(ArrayEnd.ToString());
|
||||
if (!format.StartsWith(ArrayStart.ToString()) || closeArray == -1) throw new FormatException($"Array Content must be wrapped in {ArrayStart}{ArrayEnd}.");
|
||||
if (!format.StartsWith(ArrayStart.ToString()) || closeArray == -1) throw new ArrayRunParseException($"Array Content must be wrapped in {ArrayStart}{ArrayEnd}.");
|
||||
var segments = format.Substring(1, closeArray - 1);
|
||||
var length = format.Substring(closeArray + 1);
|
||||
ElementContent = ParseSegments(segments);
|
||||
if (ElementContent.Count == 0) throw new FormatException("Array Content must not be empty.");
|
||||
if (ElementContent.Count == 0) throw new ArrayRunParseException("Array Content must not be empty.");
|
||||
ElementLength = ElementContent.Sum(e => e.Length);
|
||||
|
||||
if (length.Length == 0) {
|
||||
@@ -132,21 +133,21 @@ namespace HavenSoft.HexManiac.Core.Models.Runs {
|
||||
Length = ElementLength * ElementCount;
|
||||
}
|
||||
|
||||
public static bool TryParse(IDataModel data, string format, int start, IReadOnlyList<int> pointerSources, out ArrayRun self) {
|
||||
public static ErrorInfo TryParse(IDataModel data, string format, int start, IReadOnlyList<int> pointerSources, out ArrayRun self) {
|
||||
try {
|
||||
self = new ArrayRun(data, format, start, pointerSources);
|
||||
} catch {
|
||||
} catch (ArrayRunParseException e) {
|
||||
self = null;
|
||||
return false;
|
||||
return new ErrorInfo(e.Message);
|
||||
}
|
||||
|
||||
return true;
|
||||
return ErrorInfo.NoError;
|
||||
}
|
||||
|
||||
public static bool TrySearch(IDataModel data, string format, out ArrayRun self) {
|
||||
self = null;
|
||||
var closeArray = format.LastIndexOf(ArrayEnd.ToString());
|
||||
if (!format.StartsWith(ArrayStart.ToString()) || closeArray == -1) throw new FormatException($"Array Content must be wrapped in {ArrayStart}{ArrayEnd}");
|
||||
if (!format.StartsWith(ArrayStart.ToString()) || closeArray == -1) throw new ArrayRunParseException($"Array Content must be wrapped in {ArrayStart}{ArrayEnd}");
|
||||
var segments = format.Substring(1, closeArray - 1);
|
||||
var length = format.Substring(closeArray + 1);
|
||||
var elementContent = ParseSegments(segments);
|
||||
@@ -208,6 +209,7 @@ namespace HavenSoft.HexManiac.Core.Models.Runs {
|
||||
}
|
||||
|
||||
if (currentSegment.Type == ElementContentType.Pointer) {
|
||||
// TODO display the pointer in red if it points to outside the data
|
||||
var destination = data.ReadPointer(offsets.SegmentStart);
|
||||
var destinationName = data.GetAnchorFromAddress(offsets.SegmentStart, destination);
|
||||
return new Pointer(offsets.SegmentStart, index - offsets.SegmentStart, destination, destinationName);
|
||||
@@ -261,7 +263,7 @@ namespace HavenSoft.HexManiac.Core.Models.Runs {
|
||||
int nameEnd = 0;
|
||||
while (nameEnd < segments.Length && char.IsLetterOrDigit(segments[nameEnd])) nameEnd++;
|
||||
var name = segments.Substring(0, nameEnd);
|
||||
if (name == string.Empty) throw new FormatException("expected name, but none was found: " + segments);
|
||||
if (name == string.Empty) throw new ArrayRunParseException("expected name, but none was found: " + segments);
|
||||
segments = segments.Substring(nameEnd);
|
||||
var format = ElementContentType.Unknown;
|
||||
int formatLength = 0;
|
||||
@@ -283,7 +285,7 @@ namespace HavenSoft.HexManiac.Core.Models.Runs {
|
||||
(format, formatLength, segmentLength) = (ElementContentType.Pointer, 2, 4);
|
||||
}
|
||||
|
||||
if (format == ElementContentType.Unknown) throw new FormatException($"Could not parse format '{segments}'");
|
||||
if (format == ElementContentType.Unknown) throw new ArrayRunParseException($"Could not parse format '{segments}'");
|
||||
segments = segments.Substring(formatLength).Trim();
|
||||
list.Add(new ArrayRunElementSegment(name, format, segmentLength));
|
||||
}
|
||||
@@ -339,4 +341,8 @@ namespace HavenSoft.HexManiac.Core.Models.Runs {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ArrayRunParseException : Exception {
|
||||
public ArrayRunParseException(string message) : base(message) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -971,6 +971,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels {
|
||||
if (fullValue == Pointer.NULL || (0 <= fullValue && fullValue < Model.Count)) {
|
||||
Model.WritePointer(history.CurrentChange, index, fullValue);
|
||||
if (!inArray) Model.ObserveRunWritten(history.CurrentChange, new PointerRun(index));
|
||||
// TODO do something amazing here... we don't need to observe the run being written, but there's still pointer updates to be done
|
||||
ClearEdits(point);
|
||||
SilentScroll(index + 4);
|
||||
} else {
|
||||
|
||||
@@ -28,9 +28,9 @@ namespace HavenSoft.HexManiac.Tests {
|
||||
[Fact]
|
||||
public void ArrayElementsMustHaveNames() {
|
||||
var model = new PokemonModel(new byte[0x200]);
|
||||
var success = ArrayRun.TryParse(model, "[\"\"10]13", 12, null, out var arrayRun); // no name given for the format member
|
||||
var errorInfo = ArrayRun.TryParse(model, "[\"\"10]13", 12, null, out var arrayRun); // no name given for the format member
|
||||
|
||||
Assert.False(success);
|
||||
Assert.NotEqual(ErrorInfo.NoError, errorInfo);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user