11using System ;
2- using Lockstep . Client . Interfaces ;
3- using Lockstep . Core . Data ;
2+ using System . Collections . Generic ;
3+ using System . IO ;
4+ using Lockstep . Client . Implementations ;
5+ using Lockstep . Client . Interfaces ;
46using Lockstep . Core . Interfaces ;
7+ using Lockstep . Network ;
58using Lockstep . Network . Messages ;
9+ using Lockstep . Network . Utils ;
610
711namespace Lockstep . Client
812{
913 public class Simulation
1014 {
11- public event Action < uint > Ticked ;
15+ public event Action < ulong > Ticked ;
1216
1317 public bool Running { get ; set ; }
18+
19+ private readonly ISystems _systems ;
20+ private readonly INetwork _network ;
1421
15- public IFrameBuffer FrameBuffer { get ; } = new FrameBuffer ( ) ;
22+ public float _tickDt ;
23+ public float _accumulatedTime ;
1624
17- private readonly ISystems _systems ;
25+ public ulong CurrentTick { get ; private set ; }
1826
19- private readonly IDataReceiver _dataReceiver ;
27+ private readonly CommandBuffer _networkCommandBuffer ;
28+ private readonly IDictionary < ushort , Func < ISerializableCommand > > _commandFactories = new Dictionary < ushort , Func < ISerializableCommand > > ( ) ;
2029
21- public float _tickDt ;
22- public float _accumulatedTime ;
2330
24- public Simulation ( ISystems systems , IDataReceiver dataReceiver )
31+ public Simulation ( ISystems systems , INetwork network )
2532 {
2633 _systems = systems ;
27- _systems . SetFrameBuffer ( FrameBuffer ) ;
34+ _systems . CommandBuffer = new CommandBuffer ( ) ;
2835
29- _dataReceiver = dataReceiver ;
36+ _networkCommandBuffer = new CommandBuffer ( ) ;
3037
31- _dataReceiver . InitReceived += OnInitReceived ;
32- _dataReceiver . FrameReceived += OnFrameReceived ;
38+ _network = network ;
39+ _network . DataReceived += OnDataReceived ;
3340 }
3441
35- public void Execute ( ICommand command )
42+
43+ public void RegisterCommand ( Func < ISerializableCommand > commandFactory )
3644 {
37- _dataReceiver . Receive ( command ) ;
45+ var tag = commandFactory . Invoke ( ) . Tag ;
46+ if ( _commandFactories . ContainsKey ( tag ) )
47+ {
48+ throw new InvalidDataException ( "The command tag " + tag + " is already registered. Every command tag must be unique." ) ;
49+ }
50+ _commandFactories . Add ( tag , commandFactory ) ;
51+ }
52+
53+ public void Execute ( ISerializableCommand command )
54+ {
55+ //Execute the command locally in the next tick
56+ _systems . CommandBuffer . Insert ( CurrentTick + 1 , command ) ;
57+
58+ //Tell the server
59+ var writer = new Serializer ( ) ;
60+ writer . Put ( ( byte ) MessageTag . Input ) ;
61+ writer . Put ( CurrentTick + 1 ) ;
62+ writer . Put ( command . Tag ) ;
63+ command . Serialize ( writer ) ;
64+
65+ _network . Send ( Compressor . Compress ( writer ) ) ;
3866 }
3967
4068 public void Update ( float deltaTime )
@@ -45,36 +73,59 @@ public void Update(float deltaTime)
4573 }
4674
4775 _accumulatedTime += deltaTime ;
48-
49- //TODO: adjust _tickDt depending on buffersize
76+
5077 while ( _accumulatedTime >= _tickDt )
5178 {
52- // Tick();
79+ Tick ( ) ;
5380
5481 _accumulatedTime -= _tickDt ;
5582 }
5683 }
5784
58- private void OnInitReceived ( object sender , Init init )
85+ private void StartSimulation ( int targetFps )
5986 {
60- _tickDt = 1000f / init . TargetFPS ;
87+ _tickDt = 1000f / targetFps ;
6188
6289 _systems . Initialize ( ) ;
6390
6491 Running = true ;
92+ }
93+
94+ private void Tick ( )
95+ {
96+ _systems . Tick ( ) ;
97+ Ticked ? . Invoke ( CurrentTick ) ;
98+
99+ CurrentTick ++ ;
65100 }
66101
67- private void OnFrameReceived ( object sender , Frame e )
102+ private void OnDataReceived ( byte [ ] data )
68103 {
69- FrameBuffer . Insert ( e ) ;
104+ data = Compressor . Decompress ( data ) ;
70105
71- Tick ( ) ;
106+ var reader = new Deserializer ( data ) ;
107+ var messageTag = ( MessageTag ) reader . GetByte ( ) ;
108+ switch ( messageTag )
109+ {
110+ case MessageTag . StartSimulation :
111+ var init = new Init ( ) ;
112+ init . Deserialize ( reader ) ;
113+ StartSimulation ( init . TargetFPS ) ;
114+ break ;
115+ case MessageTag . Input :
116+ var frameNumber = reader . GetULong ( ) ;
117+ var tag = reader . GetUShort ( ) ;
118+
119+ if ( _commandFactories . ContainsKey ( tag ) )
120+ {
121+ var newCommand = _commandFactories [ tag ] . Invoke ( ) ;
122+ newCommand . Deserialize ( reader ) ;
123+
124+ _networkCommandBuffer . Insert ( frameNumber , newCommand ) ;
125+ }
126+
127+ break ;
128+ }
72129 }
73-
74- private void Tick ( )
75- {
76- _systems . Tick ( ) ;
77- Ticked ? . Invoke ( FrameBuffer . ItemIndex ) ;
78- }
79130 }
80131}
0 commit comments