trimming fat; own files; etc

This commit is contained in:
Chris Forbes
2009-12-05 11:56:16 +13:00
parent 0d81683e34
commit c171185034
22 changed files with 218 additions and 223 deletions

View File

@@ -89,12 +89,12 @@ namespace OpenRa.Game
sounds = new Cache<string, ISoundSource>(LoadSound); sounds = new Cache<string, ISoundSource>(LoadSound);
if (Replay != "") if (Replay != "")
orderManager = new OrderManager(new OrderSource[] { new ReplayOrderSource(Replay) }); orderManager = new OrderManager(new IOrderSource[] { new ReplayOrderSource(Replay) });
else else
{ {
var orderSources = (string.IsNullOrEmpty(NetworkHost)) var orderSources = (string.IsNullOrEmpty(NetworkHost))
? new OrderSource[] { new LocalOrderSource() } ? new IOrderSource[] { new LocalOrderSource() }
: new OrderSource[] { new LocalOrderSource(), new NetworkOrderSource(new TcpClient(NetworkHost, NetworkPort)) }; : new IOrderSource[] { new LocalOrderSource(), new NetworkOrderSource(new TcpClient(NetworkHost, NetworkPort)) };
orderManager = new OrderManager(orderSources, "replay.rep"); orderManager = new OrderManager(orderSources, "replay.rep");
} }

View File

@@ -0,0 +1,11 @@
using System.Collections.Generic;
namespace OpenRa.Game
{
interface IOrderSource
{
void SendLocalOrders(int localFrame, List<Order> localOrders);
List<Order> OrdersForFrame(int currentFrame);
bool IsReadyForFrame(int frameNumber);
}
}

View File

@@ -0,0 +1,28 @@
using System.Collections.Generic;
namespace OpenRa.Game
{
class LocalOrderSource : IOrderSource
{
Dictionary<int, List<Order>> orders = new Dictionary<int, List<Order>>();
public List<Order> OrdersForFrame(int currentFrame)
{
// TODO: prune `orders` based on currentFrame.
if (!orders.ContainsKey(currentFrame))
return new List<Order>();
return orders[currentFrame];
}
public void SendLocalOrders(int localFrame, List<Order> localOrders)
{
if (localFrame == 0) return;
orders[localFrame] = localOrders;
}
public bool IsReadyForFrame(int frameNumber)
{
return true;
}
}
}

View File

@@ -0,0 +1,78 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Threading;
namespace OpenRa.Game
{
class NetworkOrderSource : IOrderSource
{
TcpClient socket;
Dictionary<int, List<byte[]>> orderBuffers = new Dictionary<int, List<byte[]>>();
Dictionary<int, bool> gotEverything = new Dictionary<int, bool>();
public NetworkOrderSource(TcpClient socket)
{
this.socket = socket;
this.socket.NoDelay = true;
var reader = new BinaryReader(socket.GetStream());
new Thread(() =>
{
for (; ; )
{
var len = reader.ReadInt32();
var frame = reader.ReadInt32();
var buf = reader.ReadBytes(len - 4);
lock (orderBuffers)
{
if (len == 5 && buf[0] == 0xef) /* got everything marker */
gotEverything[frame] = true;
else
{
/* accumulate this chunk */
if (!orderBuffers.ContainsKey(frame))
orderBuffers[frame] = new List<byte[]> { buf };
else
orderBuffers[frame].Add(buf);
}
}
}
}) { IsBackground = true }.Start();
}
static List<byte[]> NoOrders = new List<byte[]>();
List<byte[]> ExtractOrders(int frame)
{
lock (orderBuffers)
{
List<byte[]> result;
if (!orderBuffers.TryGetValue(frame, out result))
result = NoOrders;
orderBuffers.Remove(frame);
gotEverything.Remove(frame);
return result;
}
}
public List<Order> OrdersForFrame(int currentFrame)
{
var orderData = ExtractOrders(currentFrame);
return orderData.SelectMany(a => a.ToOrderList()).ToList();
}
public void SendLocalOrders(int localFrame, List<Order> localOrders)
{
socket.GetStream().WriteFrameData(localOrders, localFrame);
}
public bool IsReadyForFrame(int frameNumber)
{
lock (orderBuffers)
return gotEverything.ContainsKey(frameNumber);
}
}
}

View File

@@ -82,10 +82,15 @@
<Compile Include="Exts.cs" /> <Compile Include="Exts.cs" />
<Compile Include="GameRules\GeneralInfo.cs" /> <Compile Include="GameRules\GeneralInfo.cs" />
<Compile Include="GameRules\TechTree.cs" /> <Compile Include="GameRules\TechTree.cs" />
<Compile Include="IOrderSource.cs" />
<Compile Include="LocalOrderSource.cs" />
<Compile Include="NetworkOrderSource.cs" />
<Compile Include="OrderIO.cs" />
<Compile Include="OrderManager.cs" /> <Compile Include="OrderManager.cs" />
<Compile Include="Ore.cs" /> <Compile Include="Ore.cs" />
<Compile Include="PathSearch.cs" /> <Compile Include="PathSearch.cs" />
<Compile Include="ProductionItem.cs" /> <Compile Include="ProductionItem.cs" />
<Compile Include="ReplayOrderSource.cs" />
<Compile Include="Support\Stopwatch.cs" /> <Compile Include="Support\Stopwatch.cs" />
<Compile Include="Support\PerfHistory.cs" /> <Compile Include="Support\PerfHistory.cs" />
<Compile Include="Traits\AcceptsOre.cs" /> <Compile Include="Traits\AcceptsOre.cs" />

37
OpenRa.Game/OrderIO.cs Normal file
View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace OpenRa.Game
{
static class OrderIO
{
static void Write(this Stream s, byte[] buf)
{
s.Write(buf, 0, buf.Length);
}
public static void WriteFrameData(this Stream s, IEnumerable<Order> orders, int frameNumber)
{
var ms = new MemoryStream();
ms.Write(BitConverter.GetBytes(frameNumber));
foreach (var order in orders)
ms.Write(order.Serialize());
s.Write(BitConverter.GetBytes((int)ms.Length));
ms.WriteTo(s);
}
public static List<Order> ToOrderList(this byte[] bytes)
{
var ms = new MemoryStream(bytes);
var reader = new BinaryReader(ms);
var ret = new List<Order>();
while (ms.Position < ms.Length)
ret.Add(Order.Deserialize(reader));
return ret;
}
}
}

View File

@@ -2,15 +2,13 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.Sockets;
using System.Threading;
namespace OpenRa.Game namespace OpenRa.Game
{ {
class OrderManager class OrderManager
{ {
Stream savingReplay; Stream savingReplay;
List<OrderSource> sources; List<IOrderSource> sources;
int frameNumber = 0; int frameNumber = 0;
public int FramesAhead = 3; public int FramesAhead = 3;
@@ -30,14 +28,14 @@ namespace OpenRa.Game
public int FrameNumber { get { return frameNumber; } } public int FrameNumber { get { return frameNumber; } }
public OrderManager( IEnumerable<OrderSource> sources ) public OrderManager( IEnumerable<IOrderSource> sources )
{ {
this.sources = sources.ToList(); this.sources = sources.ToList();
if (!IsNetplay) if (!IsNetplay)
StartGame(); StartGame();
} }
public OrderManager( IEnumerable<OrderSource> sources, string replayFilename ) public OrderManager( IEnumerable<IOrderSource> sources, string replayFilename )
: this( sources ) : this( sources )
{ {
savingReplay = new FileStream( replayFilename, FileMode.Create ); savingReplay = new FileStream( replayFilename, FileMode.Create );
@@ -88,180 +86,4 @@ namespace OpenRa.Game
throw new InvalidOperationException( "(OrderManager) Frame number too large" ); throw new InvalidOperationException( "(OrderManager) Frame number too large" );
} }
} }
interface OrderSource
{
void SendLocalOrders( int localFrame, List<Order> localOrders );
List<Order> OrdersForFrame( int currentFrame );
bool IsReadyForFrame( int frameNumber );
}
class LocalOrderSource : OrderSource
{
Dictionary<int, List<Order>> orders = new Dictionary<int,List<Order>>();
public List<Order> OrdersForFrame( int currentFrame )
{
// TODO: prune `orders` based on currentFrame.
if (!orders.ContainsKey(currentFrame))
return new List<Order>();
return orders[ currentFrame ];
}
public void SendLocalOrders( int localFrame, List<Order> localOrders )
{
if (localFrame == 0) return;
orders[ localFrame ] = localOrders;
}
public bool IsReadyForFrame( int frameNumber )
{
return true;
}
}
class ReplayOrderSource : OrderSource
{
BinaryReader replayReader;
public ReplayOrderSource( string replayFilename )
{
replayReader = new BinaryReader( File.Open( replayFilename, FileMode.Open ) );
}
public void SendLocalOrders( int localFrame, List<Order> localOrders ) { }
public List<Order> OrdersForFrame( int frameNumber )
{
if( frameNumber == 0 )
return new List<Order>();
try
{
var len = replayReader.ReadInt32() - 4;
var frame = replayReader.ReadInt32();
var ret = replayReader.ReadBytes( len ).ToOrderList();
if( frameNumber != frame )
throw new InvalidOperationException( "Attempted time-travel in OrdersForFrame (replay)" );
return ret;
}
catch( EndOfStreamException )
{
return new List<Order>();
}
}
public bool IsReadyForFrame( int frameNumber )
{
return true;
}
}
class NetworkOrderSource : OrderSource
{
TcpClient socket;
Dictionary<int, List<byte[]>> orderBuffers = new Dictionary<int, List<byte[]>>();
Dictionary<int, bool> gotEverything = new Dictionary<int, bool>();
public NetworkOrderSource( TcpClient socket )
{
this.socket = socket;
this.socket.NoDelay = true;
var reader = new BinaryReader( socket.GetStream() );
new Thread( () =>
{
for (; ; )
{
var len = reader.ReadInt32();
var frame = reader.ReadInt32();
var buf = reader.ReadBytes(len - 4);
lock (orderBuffers)
{
if (len == 5 && buf[0] == 0xef) /* got everything marker */
gotEverything[frame] = true;
else
{
/* accumulate this chunk */
if (!orderBuffers.ContainsKey(frame))
orderBuffers[frame] = new List<byte[]> { buf };
else
orderBuffers[frame].Add(buf);
}
}
}
} ) { IsBackground = true }.Start();
}
static List<byte[]> NoOrders = new List<byte[]>();
List<byte[]> ExtractOrders(int frame)
{
lock (orderBuffers)
{
List<byte[]> result;
if (!orderBuffers.TryGetValue(frame, out result))
result = NoOrders;
orderBuffers.Remove(frame);
gotEverything.Remove(frame);
return result;
}
}
public List<Order> OrdersForFrame( int currentFrame )
{
var orderData = ExtractOrders(currentFrame);
return orderData.SelectMany(a => a.ToOrderList()).ToList();
}
public void SendLocalOrders( int localFrame, List<Order> localOrders )
{
socket.GetStream().WriteFrameData( localOrders, localFrame );
}
public bool IsReadyForFrame( int frameNumber )
{
lock( orderBuffers )
return gotEverything.ContainsKey( frameNumber );
}
}
static class StreamExts
{
public static void Write( this Stream s, byte[] buf )
{
s.Write( buf, 0, buf.Length );
}
}
static class OrderIO
{
public static MemoryStream ToMemoryStream( this IEnumerable<Order> orders, int nextLocalOrderFrame )
{
var ms = new MemoryStream();
ms.Write( BitConverter.GetBytes( nextLocalOrderFrame ) );
foreach( var order in orders )
ms.Write( order.Serialize() );
return ms;
}
public static void WriteFrameData( this Stream s, IEnumerable<Order> orders, int frameNumber )
{
var ms = orders.ToMemoryStream( frameNumber );
s.Write( BitConverter.GetBytes( (int)ms.Length ) );
ms.WriteTo( s );
}
public static List<Order> ToOrderList( this byte[] bytes )
{
var ms = new MemoryStream( bytes );
var reader = new BinaryReader( ms );
var ret = new List<Order>();
while( ms.Position < ms.Length )
ret.Add( Order.Deserialize( reader ) );
return ret;
}
}
} }

View File

@@ -1,7 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenRa.FileFormats; using OpenRa.FileFormats;
namespace OpenRa.Game namespace OpenRa.Game

View File

@@ -1,9 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using IjwFramework.Collections;
using System.Linq; using System.Linq;
using OpenRa.FileFormats; using OpenRa.FileFormats;
using OpenRa.Game.Graphics;
using OpenRa.Game.Support; using OpenRa.Game.Support;
namespace OpenRa.Game namespace OpenRa.Game

View File

@@ -1,9 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenRa.Game.Graphics;
using IjwFramework.Collections; using IjwFramework.Collections;
using OpenRa.Game.Graphics;
namespace OpenRa.Game namespace OpenRa.Game
{ {

View File

@@ -1,7 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenRa.Game.GameRules; using OpenRa.Game.GameRules;
namespace OpenRa.Game namespace OpenRa.Game

View File

@@ -1,5 +1,5 @@
using System.Collections.Generic;
using System; using System;
using System.Collections.Generic;
namespace OpenRa.Game namespace OpenRa.Game
{ {

View File

@@ -1,7 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OpenRa.Game namespace OpenRa.Game
{ {

View File

@@ -1,6 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Text;
namespace OpenRa.Game namespace OpenRa.Game
{ {

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace OpenRa.Game
{
class ReplayOrderSource : IOrderSource
{
BinaryReader replayReader;
public ReplayOrderSource(string replayFilename)
{
replayReader = new BinaryReader(File.Open(replayFilename, FileMode.Open));
}
public void SendLocalOrders(int localFrame, List<Order> localOrders) { }
public List<Order> OrdersForFrame(int frameNumber)
{
if (frameNumber == 0)
return new List<Order>();
try
{
var len = replayReader.ReadInt32() - 4;
var frame = replayReader.ReadInt32();
var ret = replayReader.ReadBytes(len).ToOrderList();
if (frameNumber != frame)
throw new InvalidOperationException("Attempted time-travel in OrdersForFrame (replay)");
return ret;
}
catch (EndOfStreamException)
{
return new List<Order>();
}
}
public bool IsReadyForFrame(int frameNumber)
{
return true;
}
}
}

View File

@@ -1,8 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
using OpenRa.FileFormats;
using System.IO;
using OpenRa.Game.Graphics; using OpenRa.Game.Graphics;
namespace OpenRa.Game namespace OpenRa.Game

View File

@@ -1,8 +1,6 @@
using System.Drawing; using System.Drawing;
using OpenRa.Game.Graphics;
using System;
using OpenRa.Game.GameRules; using OpenRa.Game.GameRules;
using System.Linq; using OpenRa.Game.Graphics;
namespace OpenRa.Game namespace OpenRa.Game
{ {

View File

@@ -1,9 +1,7 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenRa.Game.Traits;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using OpenRa.Game.Traits;
namespace OpenRa.Game namespace OpenRa.Game
{ {

View File

@@ -1,5 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;

View File

@@ -1,9 +1,8 @@
using System; using System;
using System.Drawing;
using System.Linq; using System.Linq;
using IjwFramework.Types;
using OpenRa.Game.GameRules; using OpenRa.Game.GameRules;
using OpenRa.Game.Traits; using OpenRa.Game.Traits;
using System.Drawing;
namespace OpenRa.Game namespace OpenRa.Game
{ {

View File

@@ -1,7 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OpenRa.Game namespace OpenRa.Game
{ {

View File

@@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows.Forms;
using OpenRa.Game.Graphics; using OpenRa.Game.Graphics;
using OpenRa.Game.Traits; using OpenRa.Game.Traits;