Revert "Refactor the OrderManager and world tick loop, improves input latency"

This reverts commit f642cead44.
This commit is contained in:
Matthias Mailänder
2020-07-20 17:58:48 +02:00
committed by Oliver Brakmann
parent 758b0b08d0
commit b01a534a98
2 changed files with 42 additions and 75 deletions

View File

@@ -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();

View File

@@ -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()