diff --git a/MCGalaxy/Database/Undo/UndoFormat.cs b/MCGalaxy/Database/Undo/UndoFormat.cs
index 566b7abe4..97eb97f31 100644
--- a/MCGalaxy/Database/Undo/UndoFormat.cs
+++ b/MCGalaxy/Database/Undo/UndoFormat.cs
@@ -38,7 +38,7 @@ namespace MCGalaxy.Undo {
public static UndoFormat NewFormat = new UndoFormatCBin();
/// Enumerates through all the entries in the undo file.
- public abstract IEnumerable GetEntries(Stream s, UndoFormatArgs args);
+ public abstract void EnumerateEntries(Stream s, UndoFormatArgs args);
/// File extension of undo files in this format.
protected abstract string Ext { get; }
@@ -113,15 +113,21 @@ namespace MCGalaxy.Undo {
public bool Stop;
/// First instance in time that undo data should be retrieved back to.
- internal readonly DateTime Start;
+ internal readonly DateTime Start;
- public UndoFormatArgs(string lvlName, DateTime start) {
- LevelName = lvlName; Start = start;
+ /// Last instance in time that undo data should be retrieved up to.
+ internal readonly DateTime End;
+
+ /// Performs action on the given undo format entry.
+ public Action Output;
+
+ public UndoFormatArgs(string lvlName, DateTime start, DateTime end,
+ Action output) {
+ LevelName = lvlName; Start = start; End = end; Output = output;
}
}
public struct UndoFormatEntry {
- public DateTime Time;
public ushort X, Y, Z;
public ExtBlock Block;
public ExtBlock NewBlock;
diff --git a/MCGalaxy/Database/Undo/UndoFormatBin.cs b/MCGalaxy/Database/Undo/UndoFormatBin.cs
index e2571e793..509562e88 100644
--- a/MCGalaxy/Database/Undo/UndoFormatBin.cs
+++ b/MCGalaxy/Database/Undo/UndoFormatBin.cs
@@ -28,17 +28,17 @@ namespace MCGalaxy.Undo {
protected override string Ext { get { return ".unbin"; } }
const int entrySize = 12;
- public override IEnumerable GetEntries(Stream s, UndoFormatArgs args) {
+ public override void EnumerateEntries(Stream s, UndoFormatArgs args) {
List list = new List();
UndoFormatEntry pos;
- DateTime start = args.Start;
+ DateTime time;
ReadHeaders(list, s);
for (int i = list.Count - 1; i >= 0; i--) {
ChunkHeader chunk = list[i];
// Can we safely discard the entire chunk?
- bool inRange = chunk.BaseTime.AddTicks(65536 * TimeSpan.TicksPerSecond) >= start;
- if (!inRange) { args.Stop = true; yield break; }
+ bool inRange = chunk.BaseTime.AddTicks(65536 * TimeSpan.TicksPerSecond) >= args.Start;
+ if (!inRange) { args.Stop = true; return; }
if (!args.LevelName.CaselessEq(chunk.LevelName)) continue;
s.Seek(chunk.DataPosition, SeekOrigin.Begin);
@@ -49,8 +49,9 @@ namespace MCGalaxy.Undo {
for (int j = chunk.Entries - 1; j >= 0; j-- ) {
int offset = j * entrySize;
- pos.Time = chunk.BaseTime.AddTicks(U16(temp, offset + 0) * TimeSpan.TicksPerSecond);
- if (pos.Time < start) { args.Stop = true; yield break; }
+ time = chunk.BaseTime.AddTicks(U16(temp, offset + 0) * TimeSpan.TicksPerSecond);
+ if (time < args.Start) { args.Stop = true; return; }
+ if (time > args.End) continue;
pos.X = U16(temp, offset + 2);
pos.Y = U16(temp, offset + 4);
@@ -60,11 +61,12 @@ namespace MCGalaxy.Undo {
pos.Block.ExtID = temp[offset + 9];
pos.NewBlock.BlockID = temp[offset + 10];
pos.NewBlock.ExtID = temp[offset + 11];
- yield return pos;
+ args.Output(pos);
}
}
}
+
static ushort U16(byte[] buffer, int offset) {
return (ushort)(buffer[offset + 0] | buffer[offset + 1] << 8);
}
diff --git a/MCGalaxy/Database/Undo/UndoFormatCBin.cs b/MCGalaxy/Database/Undo/UndoFormatCBin.cs
index 8f9ed09a8..9f05842e2 100644
--- a/MCGalaxy/Database/Undo/UndoFormatCBin.cs
+++ b/MCGalaxy/Database/Undo/UndoFormatCBin.cs
@@ -28,17 +28,17 @@ namespace MCGalaxy.Undo {
protected override string Ext { get { return ".uncbin"; } }
const int entrySize = 8;
- public override IEnumerable GetEntries(Stream s, UndoFormatArgs args) {
+ public override void EnumerateEntries(Stream s, UndoFormatArgs args) {
List list = new List();
UndoFormatEntry pos;
- DateTime start = args.Start;
+ DateTime time;
ReadHeaders(list, s);
for (int i = list.Count - 1; i >= 0; i--) {
ChunkHeader chunk = list[i];
// Can we safely discard the entire chunk?
- bool inRange = chunk.BaseTime.AddTicks((65536 >> 2) * TimeSpan.TicksPerSecond) >= start;
- if (!inRange) { args.Stop = true; yield break; }
+ bool inRange = chunk.BaseTime.AddTicks((65536 >> 2) * TimeSpan.TicksPerSecond) >= args.Start;
+ if (!inRange) { args.Stop = true; return; }
if (!args.LevelName.CaselessEq(chunk.LevelName)) continue;
s.Seek(chunk.DataPosition, SeekOrigin.Begin);
@@ -55,8 +55,9 @@ namespace MCGalaxy.Undo {
// TODO: should this be instead:
// int delta = Flags & 0x3FFF;
// timeDeltaSeconds = delta >= 0x2000 ? (short)(delta - 16384) : (short)delta;
- pos.Time = chunk.BaseTime.AddTicks((flags & 0x3FFF) * TimeSpan.TicksPerSecond);
- if (pos.Time < start) { args.Stop = true; yield break; }
+ time = chunk.BaseTime.AddTicks((flags & 0x3FFF) * TimeSpan.TicksPerSecond);
+ if (time < args.Start) { args.Stop = true; return; }
+ if (time > args.End) continue;
int index = I32(temp, offset + 2);
pos.X = (ushort)(index % chunk.Width);
@@ -65,11 +66,12 @@ namespace MCGalaxy.Undo {
pos.Block = ExtBlock.FromRaw(temp[offset + 6], (flags & (1 << 14)) != 0);
pos.NewBlock = ExtBlock.FromRaw(temp[offset + 7], (flags & (1 << 15)) != 0);
- yield return pos;
+ args.Output(pos);
}
}
}
+
static ushort U16(byte[] buffer, int offset) {
return (ushort)(buffer[offset + 0] | buffer[offset + 1] << 8);
}
diff --git a/MCGalaxy/Database/Undo/UndoFormatText.cs b/MCGalaxy/Database/Undo/UndoFormatText.cs
index c08a964d0..8dd23e8ea 100644
--- a/MCGalaxy/Database/Undo/UndoFormatText.cs
+++ b/MCGalaxy/Database/Undo/UndoFormatText.cs
@@ -27,18 +27,19 @@ namespace MCGalaxy.Undo {
protected override string Ext { get { return ".undo"; } }
- public override IEnumerable GetEntries(Stream s, UndoFormatArgs args) {
+ public override void EnumerateEntries(Stream s, UndoFormatArgs args) {
UndoFormatEntry pos = default(UndoFormatEntry);
string[] lines = new StreamReader(s).ReadToEnd().SplitSpaces();
- DateTime start = args.Start;
+ DateTime time;
// because we have space to end of each entry, need to subtract one otherwise we'll start at a "".
const int items = 7;
for (int i = (lines.Length - 1) / items; i > 0; i--) {
// line format: mapName x y z date oldblock newblock
string timeRaw = lines[(i * items) - 3].Replace('&', ' ');
- pos.Time = DateTime.Parse(timeRaw, CultureInfo.InvariantCulture);
- if (pos.Time < start) { args.Stop = true; yield break; }
+ time = DateTime.Parse(timeRaw, CultureInfo.InvariantCulture);
+ if (time < args.Start) { args.Stop = true; return; }
+ if (time > args.End) continue;
string map = lines[(i * items) - 7];
if (!args.LevelName.CaselessEq(map)) continue;
@@ -49,7 +50,7 @@ namespace MCGalaxy.Undo {
pos.Block.BlockID = byte.Parse(lines[(i * items) - 2]);
pos.NewBlock.BlockID = byte.Parse(lines[(i * items) - 1]);
- yield return pos;
+ args.Output(pos);
}
}
}
diff --git a/MCGalaxy/Drawing/DrawOps/HighlightDrawOp.cs b/MCGalaxy/Drawing/DrawOps/HighlightDrawOp.cs
index 1374af268..33d038fb8 100644
--- a/MCGalaxy/Drawing/DrawOps/HighlightDrawOp.cs
+++ b/MCGalaxy/Drawing/DrawOps/HighlightDrawOp.cs
@@ -67,8 +67,8 @@ namespace MCGalaxy.Drawing.Ops {
}
}
- UndoFormatArgs args = new UndoFormatArgs(Level.name, Start);
- DoOldHighlight(args);
+ UndoFormatArgs args = new UndoFormatArgs(Level.name, Start, DateTime.MaxValue, OldHighlightBlock);
+ PerformOldHighlight(args);
}
Action output;
@@ -80,8 +80,8 @@ namespace MCGalaxy.Drawing.Ops {
ExtBlock newBlock = ExtBlock.FromRaw(e.NewRaw, (e.Flags & BlockDBFlags.NewCustom) != 0);
ExtBlock highlight = (newBlock.BlockID == Block.air
- || Block.Convert(oldBlock.BlockID) == Block.water || oldBlock.BlockID == Block.waterstill
- || Block.Convert(oldBlock.BlockID) == Block.lava || oldBlock.BlockID == Block.lavastill)
+ || Block.Convert(oldBlock.BlockID) == Block.water || oldBlock.BlockID == Block.waterstill
+ || Block.Convert(oldBlock.BlockID) == Block.lava || oldBlock.BlockID == Block.lavastill)
? DeleteHighlight : PlaceHighlight;
int x = e.Index % dims.X;
@@ -95,35 +95,32 @@ namespace MCGalaxy.Drawing.Ops {
}
- void DoOldHighlight(UndoFormatArgs args) {
- List files = UndoFormat.GetUndoFiles(who.ToLower());
+ void PerformOldHighlight(UndoFormatArgs args) {
+ List files = UndoFormat.GetUndoFiles(who.ToLower());
if (files.Count == 0) return;
found = true;
foreach (string file in files) {
using (Stream s = File.OpenRead(file)) {
- DoOldHighlight(s, UndoFormat.GetFormat(file), args);
+ UndoFormat.GetFormat(file).EnumerateEntries(s, args);
if (args.Stop) break;
}
}
}
- void DoOldHighlight(Stream s, UndoFormat format, UndoFormatArgs args) {
- DrawOpBlock block;
+ void OldHighlightBlock(UndoFormatEntry P) {
+ ExtBlock old = P.Block, newBlock = P.NewBlock;
+ if (P.X < Min.X || P.Y < Min.Y || P.Z < Min.Z) return;
+ if (P.X > Max.X || P.Y > Max.Y || P.Z > Max.Z) return;
- foreach (UndoFormatEntry P in format.GetEntries(s, args)) {
- ExtBlock old = P.Block, newBlock = P.NewBlock;
- if (P.X < Min.X || P.Y < Min.Y || P.Z < Min.Z) continue;
- if (P.X > Max.X || P.Y > Max.Y || P.Z > Max.Z) continue;
-
- block.Block = (newBlock.BlockID == Block.air
- || Block.Convert(old.BlockID) == Block.water || old.BlockID == Block.waterstill
- || Block.Convert(old.BlockID) == Block.lava || old.BlockID == Block.lavastill)
- ? DeleteHighlight : PlaceHighlight;
-
- block.X = P.X; block.Y = P.Y; block.Z = P.Z;
- output(block);
- }
+ DrawOpBlock block;
+ block.Block = (newBlock.BlockID == Block.air
+ || Block.Convert(old.BlockID) == Block.water || old.BlockID == Block.waterstill
+ || Block.Convert(old.BlockID) == Block.lava || old.BlockID == Block.lavastill)
+ ? DeleteHighlight : PlaceHighlight;
+
+ block.X = P.X; block.Y = P.Y; block.Z = P.Z;
+ output(block);
}
}
}
diff --git a/MCGalaxy/Drawing/DrawOps/UndoDrawOp.cs b/MCGalaxy/Drawing/DrawOps/UndoDrawOp.cs
index 2b658be37..fb56cbd95 100644
--- a/MCGalaxy/Drawing/DrawOps/UndoDrawOp.cs
+++ b/MCGalaxy/Drawing/DrawOps/UndoDrawOp.cs
@@ -71,8 +71,8 @@ namespace MCGalaxy.Drawing.Ops {
}
}
- UndoFormatArgs args = new UndoFormatArgs(Level.name, Start);
- DoOldUndo(args);
+ UndoFormatArgs args = new UndoFormatArgs(Level.name, Start, End, OldUndoBlock);
+ PerformOldUndo(args);
}
Action output;
@@ -93,34 +93,31 @@ namespace MCGalaxy.Drawing.Ops {
}
- void DoOldUndo(UndoFormatArgs args) {
+ void PerformOldUndo(UndoFormatArgs args) {
List files = UndoFormat.GetUndoFiles(who.ToLower());
if (files.Count == 0) return;
found = true;
foreach (string file in files) {
using (Stream s = File.OpenRead(file)) {
- DoOldUndo(s, UndoFormat.GetFormat(file), args);
+ UndoFormat.GetFormat(file).EnumerateEntries(s, args);
if (args.Stop) break;
}
}
}
- void DoOldUndo(Stream s, UndoFormat format, UndoFormatArgs args) {
- DrawOpBlock block;
- foreach (UndoFormatEntry P in format.GetEntries(s, args)) {
- if (P.Time > End) continue;
- if (P.X < Min.X || P.Y < Min.Y || P.Z < Min.Z) continue;
- if (P.X > Max.X || P.Y > Max.Y || P.Z > Max.Z) continue;
+ void OldUndoBlock(UndoFormatEntry P) {
+ if (P.X < Min.X || P.Y < Min.Y || P.Z < Min.Z) return;
+ if (P.X > Max.X || P.Y > Max.Y || P.Z > Max.Z) return;
+
+ byte lvlBlock = Level.GetTile(P.X, P.Y, P.Z);
+ if (lvlBlock == P.NewBlock.BlockID || Block.Convert(lvlBlock) == Block.water
+ || Block.Convert(lvlBlock) == Block.lava || lvlBlock == Block.grass) {
- byte lvlBlock = Level.GetTile(P.X, P.Y, P.Z);
- if (lvlBlock == P.NewBlock.BlockID || Block.Convert(lvlBlock) == Block.water
- || Block.Convert(lvlBlock) == Block.lava || lvlBlock == Block.grass) {
-
- block.X = P.X; block.Y = P.Y; block.Z = P.Z;
- block.Block = P.Block;
- output(block);
- }
+ DrawOpBlock block;
+ block.X = P.X; block.Y = P.Y; block.Z = P.Z;
+ block.Block = P.Block;
+ output(block);
}
}
}