Skip to content
This repository was archived by the owner on Oct 22, 2023. It is now read-only.

Commit aedd763

Browse files
authored
Merge pull request #22 from proepkes/develop
Develop
2 parents 0393469 + e5f656a commit aedd763

File tree

70 files changed

+1450
-406
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1450
-406
lines changed

Engine/Client/CommandBuffer.cs

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,68 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
1+
using System.Collections.Generic;
2+
using System.Linq;
43
using Lockstep.Core.Data;
54
using Lockstep.Core.Interfaces;
65

76
namespace Lockstep.Client.Implementations
87
{
98
public class CommandBuffer : ICommandBuffer
109
{
11-
private readonly Dictionary<long, List<ICommand>> _commands = new Dictionary<long, List<ICommand>>();
10+
/// <summary>
11+
/// Mapping: FrameNumber -> Commands per player(Id)
12+
/// </summary>
13+
public Dictionary<uint, Dictionary<byte, List<ICommand>>> Buffer { get; } = new Dictionary<uint, Dictionary<byte, List<ICommand>>>(5000);
1214

13-
public event Action<long, ICommand> Inserted;
15+
public uint LastInsertedFrame { get; private set; }
1416

15-
public long Count
17+
public virtual void Insert(uint frameNumber, byte commanderId, ICommand[] commands)
1618
{
17-
get
18-
{
19-
lock (_commands)
19+
lock (Buffer)
20+
{
21+
if (!Buffer.ContainsKey(frameNumber))
2022
{
21-
return _commands.LongCount();
23+
Buffer.Add(frameNumber, new Dictionary<byte, List<ICommand>>(10)); //Initial size for 10 players
2224
}
23-
}
24-
}
2525

26-
public long ItemIndex { get; private set; }
26+
if (!Buffer[frameNumber].ContainsKey(commanderId))
27+
{
28+
Buffer[frameNumber].Add(commanderId, new List<ICommand>(5)); //Initial size of 5 commands per frame
29+
}
30+
31+
//TODO: order by timestamp in case of multiple commands in the same frame => if commands intersect, the first one should win, requires !serverside! timestamp
32+
//ordering is enough, validation should take place in the simulation(core)
33+
Buffer[frameNumber][commanderId].AddRange(commands);
2734

28-
public long Remaining => Count - ItemIndex;
35+
LastInsertedFrame = frameNumber;
36+
}
37+
}
2938

30-
public virtual void Insert(long frameNumber, ICommand command)
39+
public Dictionary<byte, List<ICommand>> Get(uint frame)
3140
{
32-
lock (_commands)
41+
lock (Buffer)
3342
{
34-
if (!_commands.ContainsKey(frameNumber))
43+
//If no commands were inserted then return an empty list
44+
if (!Buffer.ContainsKey(frame))
3545
{
36-
_commands.Add(frameNumber, new List<ICommand>(10));
46+
Buffer.Add(frame, new Dictionary<byte, List<ICommand>>());
3747
}
3848

39-
_commands[frameNumber].Add(command);
40-
41-
Inserted?.Invoke(frameNumber, command);
42-
}
49+
return Buffer[frame];
50+
}
4351
}
4452

45-
public ICommand[] GetNext()
46-
{
47-
lock (_commands)
53+
public ICommand[] GetMany(uint frame)
54+
{
55+
lock (Buffer)
4856
{
4957
//If no commands were inserted then return an empty list
50-
if (!_commands.ContainsKey(ItemIndex))
58+
if (!Buffer.ContainsKey(frame))
5159
{
52-
_commands[ItemIndex] = new List<ICommand>();
60+
Buffer.Add(frame, new Dictionary<byte, List<ICommand>>());
5361
}
5462

55-
return _commands[ItemIndex++].ToArray();
56-
57-
}
63+
return Buffer[frame].SelectMany(pair => pair.Value).ToArray();
64+
}
5865
}
66+
5967
}
6068
}

Engine/Client/NetworkCommandBuffer.cs

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.IO;
3+
using System.IO;
4+
using System.Linq;
45
using Lockstep.Client.Implementations;
56
using Lockstep.Client.Interfaces;
6-
using Lockstep.Core.Data;
7+
using Lockstep.Core.Data;
8+
using Lockstep.Core.Interfaces;
79
using Lockstep.Network;
810
using Lockstep.Network.Messages;
911
using Lockstep.Network.Utils;
@@ -12,14 +14,17 @@ namespace Lockstep.Client
1214
{
1315
public class NetworkCommandBuffer : CommandBuffer
1416
{
17+
//TODO: refactor: don't receive meta information through commandbuffer
1518
public event Action<Init> InitReceived;
1619

1720
private readonly INetwork _network;
21+
private readonly ILogService _log;
1822
private readonly IDictionary<ushort, Func<ISerializableCommand>> _commandFactories = new Dictionary<ushort, Func<ISerializableCommand>>();
1923

20-
public NetworkCommandBuffer(INetwork network)
24+
public NetworkCommandBuffer(INetwork network, ILogService log)
2125
{
2226
_network = network;
27+
_log = log;
2328
_network.DataReceived += OnDataReceived;
2429
}
2530

@@ -33,20 +38,34 @@ public void RegisterCommand(Func<ISerializableCommand> commandFactory)
3338
_commandFactories.Add(tag, commandFactory);
3439
}
3540

36-
public override void Insert(long frameNumber, ICommand command)
37-
{
38-
if (command is ISerializableCommand serializable)
41+
public override void Insert(uint frameNumber, byte commanderId, ICommand[] commands)
42+
{
43+
//Tell the server
44+
var writer = new Serializer();
45+
writer.Put((byte)MessageTag.Input);
46+
writer.Put(commanderId);
47+
writer.Put(frameNumber);
48+
writer.Put(commands.Length);
49+
foreach (var command in commands)
3950
{
40-
//Tell the server
41-
var writer = new Serializer();
42-
writer.Put((byte)MessageTag.Input);
43-
writer.Put(frameNumber);
44-
writer.Put(serializable.Tag);
45-
serializable.Serialize(writer);
46-
47-
_network.Send(Compressor.Compress(writer));
51+
if (command is ISerializableCommand serializable)
52+
{
53+
writer.Put(serializable.Tag);
54+
serializable.Serialize(writer);
55+
}
4856
}
49-
}
57+
58+
_network.Send(Compressor.Compress(writer));
59+
}
60+
61+
public void Log(uint frameNumber)
62+
{
63+
var writer = new Serializer();
64+
writer.Put((byte)MessageTag.Log);
65+
writer.Put(frameNumber);
66+
67+
_network.Send(Compressor.Compress(writer));
68+
}
5069

5170
private void OnDataReceived(byte[] data)
5271
{
@@ -56,24 +75,37 @@ private void OnDataReceived(byte[] data)
5675
var messageTag = (MessageTag)reader.GetByte();
5776
switch (messageTag)
5877
{
78+
case MessageTag.Log:
79+
var n = reader.GetUInt();
80+
var count = Buffer.SelectMany(pair => pair.Value).SelectMany(pair => pair.Value).Count();
81+
if (count > 0)
82+
{
83+
_log.Warn(count.ToString());
84+
}
85+
break;
5986
case MessageTag.StartSimulation:
6087
var init = new Init();
6188
init.Deserialize(reader);
6289
InitReceived?.Invoke(init);
6390
break;
6491
case MessageTag.Input:
65-
var frameNumber = reader.GetLong();
66-
var tag = reader.GetUShort();
67-
68-
if (_commandFactories.ContainsKey(tag))
92+
var commanderId = reader.GetByte();
93+
var frameNumber = reader.GetUInt();
94+
var countCommands = reader.GetInt();
95+
var commands = new ICommand[countCommands];
96+
for (var i = 0; i < countCommands; i++)
6997
{
70-
var newCommand = _commandFactories[tag].Invoke();
71-
newCommand.Deserialize(reader);
72-
98+
var tag = reader.GetUShort();
7399

74-
base.Insert(frameNumber, newCommand);
75-
}
100+
if (_commandFactories.ContainsKey(tag))
101+
{
102+
var newCommand = _commandFactories[tag].Invoke();
103+
newCommand.Deserialize(reader);
104+
commands[i] = newCommand;
105+
}
106+
}
76107

108+
base.Insert(frameNumber, commanderId, commands);
77109
break;
78110
}
79111
}

0 commit comments

Comments
 (0)