public string ApianSerialized(object args = null) { SerialArgs sArgs = args as SerialArgs; // create array index lookups for peers, bikes to replace actual IDs (which are long) in serialized data Dictionary <string, int> peerIndicesDict = Players.Values.OrderBy(p => p.PeerId) .Select((p, idx) => new { p.PeerId, idx }).ToDictionary(x => x.PeerId, x => x.idx); Dictionary <string, int> bikeIndicesDict = Bikes.Values.OrderBy(b => b.bikeId) .Select((b, idx) => new { b.bikeId, idx }).ToDictionary(x => x.bikeId, x => x.idx); // State data string[] peersData = Players.Values.OrderBy(p => p.PeerId) .Select(p => p.ApianSerialized()).ToArray(); string[] bikesData = Bikes.Values.OrderBy(ib => ib.bikeId) .Select(ib => ib.ApianSerialized(new BaseBike.SerialArgs(peerIndicesDict, sArgs.apianTime, sArgs.timeStamp))).ToArray(); // Note: it's possible for an expired place to still be on the local active list 'cause of timeslice differences // when the Checkpoint command is fielded (it would get expired during the next loop) so we want to explicitly // filter out any that are expired as of the command timestamp string[] placesData = activePlaces.Values .Where(p => p.expirationTimeMs > sArgs.timeStamp) // not expired as of command timestamp .Where(p => Bikes.ContainsKey(p.bike.bikeId)) // just to make sure the bike hasn;t gone away .OrderBy(p => p.expirationTimeMs).ThenBy(p => p.PosHash) .Select(p => p.ApianSerialized(new BeamPlace.SerialArgs(bikeIndicesDict))).ToArray(); return(JsonConvert.SerializeObject(new object[] { CommandSequenceNumber, peersData, bikesData, placesData })); }
public string ApianSerialized(object args) { SerialArgs sArgs = args as SerialArgs; // args.peerIdxDict is a dictionary to map peerIds to array indices in the Json for the peers // It makes this Json a lot smaller // We can deal (mostly) with time differences from one machine to another by // replacing the bike's position with the position of the last gridpoint crossed // and the apianTime when it was there (assuming current speed.) Or it's // actual position and 0 if the bike's not moving. // // WHile I'm debugging. These are in grid-index space (tomake it easier to compare withthe places list) // float indexX = (position.x - Ground.minX) / Ground.gridSize; // float indexZ = (position.y - Ground.minZ) / Ground.gridSize; return(JsonConvert.SerializeObject(new object[] { bikeId, sArgs.peerIdxDict[peerId], name, team.TeamID, ctrlType, (long)(basePosition.x * 1000f), // integer mm (long)(basePosition.y * 1000f), baseTime, // Do I need to round this? Shouldn't have to, but: _RoundToNearest(100, timeAtPoint); baseHeading, speed, score, basePendingTurn })); }
public string ApianSerialized(object args) { SerialArgs sArgs = args as SerialArgs; // args.bikeIdxDict is a dictionary to map bikeIds to array indices in the Json for the bikes // It makes this Json a lot smaller return(JsonConvert.SerializeObject(new object[] { sArgs.bikeIdxDict[bike.bikeId], xIdx, zIdx, expirationTimeMs })); }