Shave two bytes off each undo entry, reduces memory usage even further.

This commit is contained in:
UnknownShadow200 2016-03-12 16:43:50 +11:00
parent 1d48c3822a
commit 9c2d3f14bf
5 changed files with 73 additions and 23 deletions

View File

@ -82,7 +82,9 @@ namespace MCGalaxy.Commands {
if (time < DateTime.UtcNow) return;
byte b = lvl.GetTile(x, y, z);
if (b == item.NewType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
byte newTile = 0, newExtTile = 0;
item.GetNewExtBlock(out newTile, out newExtTile);
if (b == newTile || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
if (b == Block.air || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava)
p.SendBlockchange(x, y, z, Block.red);
else

View File

@ -50,12 +50,11 @@ namespace MCGalaxy.Commands {
UndoCacheItem item = items[i];
ushort x, y, z;
node.Unpack(item.Index, out x, out y, out z);
byte tile, extTile;
item.GetExtBlock(out tile, out extTile);
byte type = lvl.GetTile(x, y, z), extType = 0;
if (type == Block.custom_block)
extType = lvl.GetExtTile(x, y, z);
if (lvl.DoBlockchange(p, x, y, z, item.Type, item.ExtType)) {
buffer.Add(lvl.PosToInt(x, y, z), item.Type, item.ExtType);
if (lvl.DoBlockchange(p, x, y, z, tile, extTile)) {
buffer.Add(lvl.PosToInt(x, y, z), tile, extTile);
buffer.CheckIfSend(false);
}
}

View File

@ -177,16 +177,21 @@ namespace MCGalaxy.Commands
if (time < DateTime.UtcNow) { buffer.CheckIfSend(true); return; }
byte b = lvl.GetTile(x, y, z);
if (b == item.NewType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
byte newTile = 0, newExtTile = 0;
item.GetNewExtBlock(out newTile, out newExtTile);
if (b == newTile || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
Player.UndoPos uP = default(Player.UndoPos);
uP.newtype = item.Type; uP.newExtType = item.ExtType;
byte extType = 0;
if (b == Block.custom_block) extType = lvl.GetExtTile(x, y, z);
if (lvl.DoBlockchange(p, x, y, z, item.Type, item.ExtType)) {
buffer.Add(lvl.PosToInt(x, y, z), item.Type, item.ExtType);
byte tile = 0, extTile = 0;
item.GetExtBlock(out tile, out extTile);
if (lvl.DoBlockchange(p, x, y, z, tile, extTile)) {
buffer.Add(lvl.PosToInt(x, y, z), tile, extTile);
buffer.CheckIfSend(false);
}
uP.newtype = tile; uP.newExtType = extTile;
uP.type = b; uP.extType = extType;
uP.x = x; uP.y = y; uP.z = z;
uP.mapName = node.MapName;

View File

@ -34,6 +34,8 @@ namespace MCGalaxy.Util {
/// <summary> Total number of items in the cache. </summary>
public volatile int Count;
public const int TimeDeltaMax = (1 << 13) - 1;
/// <summary> Appends an item to the cache. </summary>
public void Add(Level lvl, Player.UndoPos item) {
DateTime time = Server.StartTime.AddTicks(item.timeDelta * TimeSpan.TicksPerSecond);
@ -43,7 +45,7 @@ namespace MCGalaxy.Util {
}
if (lvl.name != Tail.MapName || lvl.Width != Tail.Width || lvl.Height != Tail.Height ||
lvl.Length != Tail.Length || Math.Abs((time - Tail.BaseTime).TotalSeconds) > 32767) {
lvl.Length != Tail.Length || Math.Abs((time - Tail.BaseTime).TotalSeconds) > TimeDeltaMax) {
UndoCacheNode node = UndoCacheNode.Make(lvl, time);
Tail.Next = node; node.Prev = Tail;
Tail = node;
@ -95,16 +97,53 @@ namespace MCGalaxy.Util {
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct UndoCacheItem {
public int Index;
public byte Type, ExtType;
public byte NewType, NewExtType;
public short TimeDelta;
public byte Type, NewType;
public ushort Flags; // upper 2 bits for 'ext' or 'physics' type, lower 14 bits for time delta.
public short TimeDelta {
get {
int delta = Flags & 0x3FFF;
return delta >= 0x2000 ? (short)(delta - 16384) : (short)delta;
}
}
public void GetExtBlock(out byte type, out byte extType) {
if ((Flags & (1 << 14)) != 0) {
type = Block.custom_block;
extType = Type;
} else {
type = Type;
extType = 0;
}
}
public void GetNewExtBlock(out byte type, out byte extType) {
if ((Flags & (1 << 15)) != 0) {
type = Block.custom_block;
extType = NewType;
} else {
type = NewType;
extType = 0;
}
}
public static UndoCacheItem Make(UndoCacheNode node, short timeDelta, ref Player.UndoPos pos) {
UndoCacheItem item = default(UndoCacheItem);
item.Index = pos.x + node.Width * (pos.z + node.Length * pos.y);
item.Type = pos.type; item.ExtType = pos.extType;
item.NewType = pos.newtype; item.NewExtType = pos.newExtType;
item.TimeDelta = timeDelta;
item.Flags = (ushort)(timeDelta & 0x3FFF);
if (pos.type == Block.custom_block) {
item.Type = pos.extType;
item.Flags |= (ushort)(1 << 14);
} else {
item.Type = pos.type;
}
if (pos.newtype == Block.custom_block) {
item.NewType = pos.newExtType;
item.Flags |= (ushort)(1 << 15);
} else {
item.NewType = pos.newtype;
}
return item;
}
}

View File

@ -70,13 +70,18 @@ namespace MCGalaxy.Util {
WriteChunkEntries(w, last.Entries, entriesPos);
last = WriteEmptyChunk(w, node.MapName, time, ref entriesPos);
}
ushort x, y, z;
node.Unpack(uP.Index, out x, out y, out z);
byte tile = 0, extTile = 0;
uP.GetExtBlock(out tile, out extTile);
byte newTile = 0, newExtTile = 0;
uP.GetNewExtBlock(out newTile, out newExtTile);
w.Write((ushort)timeDiff);
w.Write(x); w.Write(y); w.Write(z);
w.Write(uP.Type); w.Write(uP.ExtType);
w.Write(uP.NewType); w.Write(uP.NewExtType);
w.Write(tile); w.Write(extTile);
w.Write(newTile); w.Write(newExtTile);
last.Entries++;
}
if (last.Entries > 0)