internal void PlayerInputs(PlayerInputs item) { recieved .GetOrAdd(item.Id, new ConcurrentLinkedList <PlayerInputs>()) .Add(item); if (Interlocked.CompareExchange(ref going, 1, 0) == 0) { while (recieved.Sum(x => x.Value.Count) >= game2.gameState.players.Count) { var inputs = new Dictionary <Guid, PlayerInputs>(); foreach (var pair in recieved) { if (pair.Value.TryGetFirst(out var first)) { // TODO TryGetFirst and RemoveStart should be combined pair.Value.RemoveStart(); inputs[pair.Key] = first; } } game2.ApplyInputs(inputs); } var update = new Node(game2.gameState.GetGameStateUpdate()); lastUpdate.next.SetResult(update); lastUpdate = update; going = 0; } }
// assumed to be run on the main thread private async void MainLoop() { var sw = new Stopwatch(); sw.Start(); while (sending) { game.ApplyInputs( (await Task.WhenAll(localPlayers.Read().Select(x => (x.input.Next())).ToArray())).ToDictionary(x => x.Id, x => x)); await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync( CoreDispatcherPriority.Normal, () => { CanvasLeft.Invalidate(); CanvasRight.Invalidate(); }); frame.thing++; while ((1000.0 * frame.thing / 60.0) > sw.ElapsedMilliseconds) { } //await Task.Delay(1); // let someone else have a go //await Task.Delay((int)Math.Max(0, (1000.0 * frame.frame / 60.0) - sw.ElapsedMilliseconds)); } StoppedSending.SetResult(true); }