Revert "Refactor the OrderManager and world tick loop, improves input latency"
This reverts commit f642cead44.
This commit is contained in:
committed by
Oliver Brakmann
parent
758b0b08d0
commit
b01a534a98
@@ -579,22 +579,26 @@ namespace OpenRA
|
|||||||
orderManager.LastTickTime += integralTickTimestep >= TimestepJankThreshold ? integralTickTimestep : worldTimestep;
|
orderManager.LastTickTime += integralTickTimestep >= TimestepJankThreshold ? integralTickTimestep : worldTimestep;
|
||||||
|
|
||||||
Sound.Tick();
|
Sound.Tick();
|
||||||
|
Sync.RunUnsynced(Settings.Debug.SyncCheckUnsyncedCode, world, orderManager.TickImmediate);
|
||||||
|
|
||||||
if (world == null)
|
if (world == null)
|
||||||
{
|
|
||||||
orderManager.TickPreGame();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Collect orders first, we will dispatch them if we can this frame
|
var isNetTick = LocalTick % NetTickScale == 0;
|
||||||
Sync.RunUnsynced(Settings.Debug.SyncCheckUnsyncedCode, world, () =>
|
|
||||||
{
|
|
||||||
world.OrderGenerator.Tick(world);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (orderManager.TryTick())
|
if (!isNetTick || orderManager.SendNetFrameOrdersAndCheckReady())
|
||||||
{
|
{
|
||||||
Log.Write("debug", "--Tick: {0} ({1})", LocalTick, orderManager.IsNetTick ? "net" : "local");
|
++orderManager.LocalFrameNumber;
|
||||||
|
|
||||||
|
Log.Write("debug", "--Tick: {0} ({1})", LocalTick, isNetTick ? "net" : "local");
|
||||||
|
|
||||||
|
if (isNetTick)
|
||||||
|
orderManager.Tick();
|
||||||
|
|
||||||
|
Sync.RunUnsynced(Settings.Debug.SyncCheckUnsyncedCode, world, () =>
|
||||||
|
{
|
||||||
|
world.OrderGenerator.Tick(world);
|
||||||
|
});
|
||||||
|
|
||||||
world.Tick();
|
world.Tick();
|
||||||
|
|
||||||
|
|||||||
@@ -35,10 +35,10 @@ namespace OpenRA.Network
|
|||||||
public bool AuthenticationFailed = false;
|
public bool AuthenticationFailed = false;
|
||||||
public ExternalMod ServerExternalMod = null;
|
public ExternalMod ServerExternalMod = null;
|
||||||
|
|
||||||
public bool IsNetTick { get { return LocalFrameNumber % Game.NetTickScale == 0; } }
|
|
||||||
public int NetFrameNumber { get; private set; }
|
public int NetFrameNumber { get; private set; }
|
||||||
public int LocalFrameNumber;
|
public int LocalFrameNumber;
|
||||||
public int FramesAhead = 0;
|
public int FramesAhead = 0;
|
||||||
|
bool isReadyForNextFrame;
|
||||||
int lastFrameSent;
|
int lastFrameSent;
|
||||||
|
|
||||||
public long LastTickTime = Game.RunTime;
|
public long LastTickTime = Game.RunTime;
|
||||||
@@ -49,11 +49,10 @@ namespace OpenRA.Network
|
|||||||
internal int GameSaveLastFrame = -1;
|
internal int GameSaveLastFrame = -1;
|
||||||
internal int GameSaveLastSyncFrame = -1;
|
internal int GameSaveLastSyncFrame = -1;
|
||||||
|
|
||||||
readonly List<Order> localOrders = new List<Order>();
|
List<Order> localOrders = new List<Order>();
|
||||||
readonly List<Order> localImmediateOrders = new List<Order>();
|
List<Order> localImmediateOrders = new List<Order>();
|
||||||
readonly List<Pair<int, byte[]>> receivedImmediateOrders = new List<Pair<int, byte[]>>();
|
|
||||||
|
|
||||||
readonly List<ChatLine> chatCache = new List<ChatLine>();
|
List<ChatLine> chatCache = new List<ChatLine>();
|
||||||
|
|
||||||
public readonly ReadOnlyList<ChatLine> ChatCache;
|
public readonly ReadOnlyList<ChatLine> ChatCache;
|
||||||
|
|
||||||
@@ -79,6 +78,7 @@ namespace OpenRA.Network
|
|||||||
|
|
||||||
// Technically redundant since we will attempt to send orders before the next frame
|
// Technically redundant since we will attempt to send orders before the next frame
|
||||||
SendOrders();
|
SendOrders();
|
||||||
|
isReadyForNextFrame = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OrderManager(ConnectionTarget endpoint, string password, IConnection conn)
|
public OrderManager(ConnectionTarget endpoint, string password, IConnection conn)
|
||||||
@@ -111,15 +111,14 @@ namespace OpenRA.Network
|
|||||||
chatCache.Add(new ChatLine(name, nameColor, text, textColor));
|
chatCache.Add(new ChatLine(name, nameColor, text, textColor));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendImmediateOrders()
|
public void TickImmediate()
|
||||||
{
|
{
|
||||||
if (localImmediateOrders.Count != 0 && GameSaveLastFrame < NetFrameNumber)
|
if (localImmediateOrders.Count != 0 && GameSaveLastFrame < NetFrameNumber + FramesAhead)
|
||||||
Connection.SendImmediate(localImmediateOrders.Select(o => o.Serialize()));
|
Connection.SendImmediate(localImmediateOrders.Select(o => o.Serialize()));
|
||||||
localImmediateOrders.Clear();
|
localImmediateOrders.Clear();
|
||||||
}
|
|
||||||
|
|
||||||
void ReceiveAllOrdersAndCheckSync()
|
var immediatePackets = new List<Pair<int, byte[]>>();
|
||||||
{
|
|
||||||
Connection.Receive(
|
Connection.Receive(
|
||||||
(clientId, packet) =>
|
(clientId, packet) =>
|
||||||
{
|
{
|
||||||
@@ -129,15 +128,12 @@ namespace OpenRA.Network
|
|||||||
else if (packet.Length >= 5 && packet[4] == (byte)OrderType.SyncHash)
|
else if (packet.Length >= 5 && packet[4] == (byte)OrderType.SyncHash)
|
||||||
CheckSync(packet);
|
CheckSync(packet);
|
||||||
else if (frame == 0)
|
else if (frame == 0)
|
||||||
receivedImmediateOrders.Add(Pair.New(clientId, packet));
|
immediatePackets.Add(Pair.New(clientId, packet));
|
||||||
else
|
else
|
||||||
frameData.AddFrameOrders(clientId, frame, packet);
|
frameData.AddFrameOrders(clientId, frame, packet);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
void ProcessImmediateOrders()
|
foreach (var p in immediatePackets)
|
||||||
{
|
|
||||||
foreach (var p in receivedImmediateOrders)
|
|
||||||
{
|
{
|
||||||
foreach (var o in p.Second.ToOrderList(World))
|
foreach (var o in p.Second.ToOrderList(World))
|
||||||
{
|
{
|
||||||
@@ -148,8 +144,6 @@ namespace OpenRA.Network
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
receivedImmediateOrders.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<int, byte[]> syncForFrame = new Dictionary<int, byte[]>();
|
Dictionary<int, byte[]> syncForFrame = new Dictionary<int, byte[]>();
|
||||||
@@ -171,7 +165,7 @@ namespace OpenRA.Network
|
|||||||
syncForFrame.Add(frame, packet);
|
syncForFrame.Add(frame, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<Session.Client> GetClientsNotReadyForNextFrame
|
public IEnumerable<Session.Client> GetClientsNotReadyForNextFrame
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -198,12 +192,26 @@ namespace OpenRA.Network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SendNetFrameOrdersAndCheckReady()
|
||||||
|
{
|
||||||
|
// Send our frame orders if we should
|
||||||
|
SendOrders();
|
||||||
|
|
||||||
|
if (!isReadyForNextFrame)
|
||||||
|
isReadyForNextFrame = NetFrameNumber >= 1 && frameData.IsReadyForFrame(NetFrameNumber);
|
||||||
|
|
||||||
|
return isReadyForNextFrame;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only available if TickImmediate() is called first and we are ready to dispatch received orders locally.
|
* Only available if TickImmediate() is called first and we are ready to dispatch received orders locally.
|
||||||
* Process all incoming orders for this frame, handle sync hashes and step our net frame.
|
* Process all incoming orders for this frame, handle sync hashes and step our net frame.
|
||||||
*/
|
*/
|
||||||
void ProcessOrders()
|
public void Tick()
|
||||||
{
|
{
|
||||||
|
if (!isReadyForNextFrame)
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
|
||||||
foreach (var order in frameData.OrdersForFrame(World, NetFrameNumber))
|
foreach (var order in frameData.OrdersForFrame(World, NetFrameNumber))
|
||||||
UnitOrders.ProcessOrder(this, World, order.Client, order.Order);
|
UnitOrders.ProcessOrder(this, World, order.Client, order.Order);
|
||||||
|
|
||||||
@@ -217,52 +225,7 @@ namespace OpenRA.Network
|
|||||||
syncReport.UpdateSyncReport();
|
syncReport.UpdateSyncReport();
|
||||||
|
|
||||||
++NetFrameNumber;
|
++NetFrameNumber;
|
||||||
}
|
isReadyForNextFrame = false;
|
||||||
|
|
||||||
public void TickPreGame()
|
|
||||||
{
|
|
||||||
SendImmediateOrders();
|
|
||||||
|
|
||||||
ReceiveAllOrdersAndCheckSync();
|
|
||||||
|
|
||||||
Sync.RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, World, ProcessImmediateOrders);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryTick()
|
|
||||||
{
|
|
||||||
var shouldTick = true;
|
|
||||||
|
|
||||||
if (IsNetTick)
|
|
||||||
{
|
|
||||||
// Check whether or not we will be ready for a tick next frame
|
|
||||||
// We don't need to include ourselves in the equation because we can always generate orders this frame
|
|
||||||
shouldTick = !GetClientsNotReadyForNextFrame.Except(new[] { LocalClient }).Any();
|
|
||||||
|
|
||||||
// Send orders only if we are currently ready, this prevents us sending orders too soon if we are
|
|
||||||
// stalling
|
|
||||||
if (shouldTick)
|
|
||||||
SendOrders();
|
|
||||||
}
|
|
||||||
|
|
||||||
SendImmediateOrders();
|
|
||||||
|
|
||||||
ReceiveAllOrdersAndCheckSync();
|
|
||||||
|
|
||||||
// Always send immediate orders
|
|
||||||
Sync.RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, World, ProcessImmediateOrders);
|
|
||||||
|
|
||||||
var willTick = shouldTick;
|
|
||||||
if (willTick && IsNetTick)
|
|
||||||
{
|
|
||||||
willTick = frameData.IsReadyForFrame(NetFrameNumber);
|
|
||||||
if (willTick)
|
|
||||||
ProcessOrders();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (willTick)
|
|
||||||
LocalFrameNumber++;
|
|
||||||
|
|
||||||
return willTick;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
Reference in New Issue
Block a user