Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated CPos struct to use bit field for all properties. #15464

Merged
merged 1 commit into from Oct 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 24 additions & 7 deletions OpenRA.Game/CPos.cs
Expand Up @@ -18,11 +18,28 @@ namespace OpenRA
{
public struct CPos : IScriptBindable, ILuaAdditionBinding, ILuaSubtractionBinding, ILuaEqualityBinding, ILuaTableBinding, IEquatable<CPos>
{
public readonly int X, Y;
public readonly byte Layer;
// Coordinates are packed in a 32 bit signed int
// X and Y are 12 bits (signed): -2048...2047
// Layer is an unsigned byte
// Packing is XXXX XXXX XXXX YYYY YYYY YYYY LLLL LLLL
public readonly int Bits;

// X is padded to MSB, so bit shift does the correct sign extension
public int X { get { return Bits >> 20; } }

// Align Y with a short, cast, then shift the rest of the way
// The signed short bit shift does the correct sign extension
public int Y { get { return ((short)(Bits >> 4)) >> 4; } }

public byte Layer { get { return (byte)Bits; } }

public CPos(int bits) { Bits = bits; }
public CPos(int x, int y) : this(x, y, 0) { }
public CPos(int x, int y, byte layer)
{
Bits = (x & 0xFFF) << 20 | (y & 0xFFF) << 8 | layer;
}

public CPos(int x, int y) { X = x; Y = y; Layer = 0; }
public CPos(int x, int y, byte layer) { X = x; Y = y; Layer = layer; }
public static readonly CPos Zero = new CPos(0, 0, 0);

public static explicit operator CPos(int2 a) { return new CPos(a.X, a.Y); }
Expand All @@ -32,12 +49,12 @@ public struct CPos : IScriptBindable, ILuaAdditionBinding, ILuaSubtractionBindin
public static CPos operator -(CPos a, CVec b) { return new CPos(a.X - b.X, a.Y - b.Y, a.Layer); }
public static CVec operator -(CPos a, CPos b) { return new CVec(a.X - b.X, a.Y - b.Y); }

public static bool operator ==(CPos me, CPos other) { return me.X == other.X && me.Y == other.Y && me.Layer == other.Layer; }
public static bool operator ==(CPos me, CPos other) { return me.Bits == other.Bits; }
public static bool operator !=(CPos me, CPos other) { return !(me == other); }

public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode() ^ Layer.GetHashCode(); }
public override int GetHashCode() { return Bits.GetHashCode(); }

public bool Equals(CPos other) { return X == other.X && Y == other.Y && Layer == other.Layer; }
public bool Equals(CPos other) { return Bits == other.Bits; }
public override bool Equals(object obj) { return obj is CPos && Equals((CPos)obj); }

public override string ToString() { return X + "," + Y; }
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Game/Map/MapPreview.cs
Expand Up @@ -56,7 +56,7 @@ public class RemoteMapData
public readonly string[] categories;
public readonly int players;
public readonly Rectangle bounds;
public readonly int[] spawnpoints = { };
public readonly short[] spawnpoints = { };
public readonly MapGridType map_grid_type;
public readonly string minimap;
public readonly bool downloading;
Expand Down
4 changes: 2 additions & 2 deletions OpenRA.Game/Network/Order.cs
Expand Up @@ -128,7 +128,7 @@ public static Order Deserialize(World world, BinaryReader r)
{
if (flags.HasField(OrderFields.TargetIsCell))
{
var cell = new CPos(r.ReadInt32(), r.ReadInt32(), r.ReadByte());
var cell = new CPos(r.ReadInt32());
var subCell = (SubCell)r.ReadByte();
if (world != null)
target = Target.FromCell(world, cell, subCell);
Expand All @@ -146,7 +146,7 @@ public static Order Deserialize(World world, BinaryReader r)

var targetString = flags.HasField(OrderFields.TargetString) ? r.ReadString() : null;
var queued = flags.HasField(OrderFields.Queued);
var extraLocation = flags.HasField(OrderFields.ExtraLocation) ? new CPos(r.ReadInt32(), r.ReadInt32(), r.ReadByte()) : CPos.Zero;
var extraLocation = flags.HasField(OrderFields.ExtraLocation) ? new CPos(r.ReadInt32()) : CPos.Zero;
var extraData = flags.HasField(OrderFields.ExtraData) ? r.ReadUInt32() : 0;

if (world == null)
Expand Down
4 changes: 1 addition & 3 deletions OpenRA.Game/Network/OrderIO.cs
Expand Up @@ -58,9 +58,7 @@ public static void Write(this BinaryWriter w, int2 p)

public static void Write(this BinaryWriter w, CPos cell)
{
w.Write(cell.X);
w.Write(cell.Y);
w.Write(cell.Layer);
w.Write(cell.Bits);
}

public static void Write(this BinaryWriter w, WPos pos)
Expand Down
31 changes: 31 additions & 0 deletions OpenRA.Test/OpenRA.Game/CPosTest.cs
@@ -0,0 +1,31 @@
using System.Runtime.Remoting.Metadata;
using NUnit.Framework;

namespace OpenRA.Test
{
[TestFixture]
public class CPosTest
{
[TestCase(TestName = "Packing x,y and layer into int")]
public void PackUnpackBits()
{
var values = new int[] { -2048, -1024, 0, 1024, 2047 };
var layerValues = new byte[] { 0, 128, 255 };

foreach (var x in values)
{
foreach (var y in values)
{
foreach (var layer in layerValues)
{
var cell = new CPos(x, y, layer);

Assert.AreEqual(x, cell.X);
Assert.AreEqual(y, cell.Y);
Assert.AreEqual(layer, cell.Layer);
}
}
}
}
}
}
2 changes: 1 addition & 1 deletion OpenRA.Test/OpenRA.Game/OrderTest.cs
Expand Up @@ -64,7 +64,7 @@ public void SerializeExtra()
var o = new Order("Test", null, Target.Invalid, true)
{
TargetString = "TargetString",
ExtraLocation = new CPos(int.MinValue, int.MaxValue, 128),
ExtraLocation = new CPos(2047, 2047, 128),
ExtraData = uint.MaxValue,
IsImmediate = true,
}.Serialize();
Expand Down
1 change: 1 addition & 0 deletions OpenRA.Test/OpenRA.Test.csproj
Expand Up @@ -46,6 +46,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="OpenRA.Game\ActionQueueTest.cs" />
<Compile Include="OpenRA.Game\CPosTest.cs" />
<Compile Include="OpenRA.Game\MiniYamlTest.cs" />
<Compile Include="OpenRA.Game\ActorInfoTest.cs" />
<Compile Include="OpenRA.Game\CoordinateTest.cs" />
Expand Down