Jack 4d94fbf54f
All checks were successful
Build and push image / Build (push) Successful in 49s
i live in spain but the S is silent
2023-09-28 00:53:27 +01:00

150 lines
5.5 KiB
C#
Executable File

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ksBroadcastingNetwork;
using ksBroadcastingNetwork.Structs;
namespace ksBroadcastingTestClient.Broadcasting
{
public class BroadcastingViewModel : KSObservableObject
{
public ObservableCollection<CarViewModel> Cars { get; } = new ObservableCollection<CarViewModel>();
public TrackViewModel TrackVM { get => Get<TrackViewModel>(); private set => Set(value); }
public KSRelayCommand RequestFocusedCarCommand { get; }
private List<BroadcastingNetworkProtocol> _clients = new List<BroadcastingNetworkProtocol>();
public BroadcastingViewModel()
{
RequestFocusedCarCommand = new KSRelayCommand(RequestFocusedCar);
}
private void RequestFocusedCar(object obj)
{
var car = obj as CarViewModel;
if (car != null)
{
foreach (var client in _clients)
{
// mssing readonly check, will skip this as the ACC client has to handle this as well
client.SetFocus(Convert.ToUInt16(car.CarIndex));
}
}
}
private void RequestHudPageChange(string requestedHudPage)
{
foreach (var client in _clients)
{
// mssing readonly check, will skip this as the ACC client has to handle this as well
client.RequestHUDPage(requestedHudPage);
}
}
private void RequestCameraChange(string camSet, string camera)
{
foreach (var client in _clients)
{
// mssing readonly check, will skip this as the ACC client has to handle this as well
client.SetCamera(camSet, camera);
}
}
internal void RegisterNewClient(ACCUdpRemoteClient newClient)
{
if (newClient.MsRealtimeUpdateInterval > 0)
{
// This client will send realtime updates, we should listen
newClient.MessageHandler.OnTrackDataUpdate += MessageHandler_OnTrackDataUpdate;
newClient.MessageHandler.OnEntrylistUpdate += MessageHandler_OnEntrylistUpdate;
newClient.MessageHandler.OnRealtimeUpdate += MessageHandler_OnRealtimeUpdate;
newClient.MessageHandler.OnRealtimeCarUpdate += MessageHandler_OnRealtimeCarUpdate;
}
_clients.Add(newClient.MessageHandler);
}
private void MessageHandler_OnTrackDataUpdate(string sender, TrackData trackUpdate)
{
if (TrackVM?.TrackId != trackUpdate.TrackId)
{
if (TrackVM != null)
{
TrackVM.OnRequestCameraChange -= RequestCameraChange;
TrackVM.OnRequestHudPageChange -= RequestHudPageChange;
}
TrackVM = new TrackViewModel(trackUpdate.TrackId, trackUpdate.TrackName, trackUpdate.TrackMeters);
TrackVM.OnRequestCameraChange += RequestCameraChange;
TrackVM.OnRequestHudPageChange += RequestHudPageChange;
}
// The track cams may update in between
TrackVM.Update(trackUpdate);
}
private void MessageHandler_OnEntrylistUpdate(string sender, CarInfo carUpdate)
{
CarViewModel vm = Cars.SingleOrDefault(x => x.CarIndex == carUpdate.CarIndex);
if (vm == null)
{
vm = new CarViewModel(carUpdate.CarIndex);
Cars.Add(vm);
}
vm.Update(carUpdate);
}
private void MessageHandler_OnRealtimeUpdate(string sender, RealtimeUpdate update)
{
if (TrackVM != null)
TrackVM.Update(update);
foreach (var carVM in Cars)
{
carVM.SetFocused(update.FocusedCarIndex);
}
try
{
if (TrackVM?.TrackMeters > 0)
{
var sortedCars = Cars.OrderBy(x => x.SplinePosition).ToArray();
for (int i = 1; i < sortedCars.Length; i++)
{
var carAhead = sortedCars[i - 1];
var carBehind = sortedCars[i];
var splineDistance = Math.Abs(carAhead.SplinePosition - carBehind.SplinePosition);
while (splineDistance > 1f)
splineDistance -= 1f;
carBehind.GapFrontMeters = splineDistance * TrackVM.TrackMeters;
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
private void MessageHandler_OnRealtimeCarUpdate(string sender, RealtimeCarUpdate carUpdate)
{
var vm = Cars.FirstOrDefault(x => x.CarIndex == carUpdate.CarIndex);
if (vm == null)
{
// Oh, we don't have this car yet. In this implementation, the Network protocol will take care of this
// so hopefully we will display this car in the next cycles
return;
}
vm.Update(carUpdate);
}
}
}