public void AttachRiderProcessors(RaceProcessor rp, Race race) { try { _rideProcessLock.EnterUpgradeableReadLock(); // Is the user connection foreach (Race.Participant p in race.Participants) { if (p.Status == @"Started") { RideProcessor rideProcessor = null; if (_RideProcessors.ContainsKey(p.UserId)) { rideProcessor = _RideProcessors[p.UserId]; // Just update the timeout rideProcessor.UpdateTimeout(); } else { // Already in write lock rideProcessor = ActivateUserRider(p.UserId); } // Add the event handler rideProcessor.SpotDataEvent += rp.UpdateSpotData; rideProcessor.RiderInactiveEvent += rp.AbandonRider; } } } finally { _rideProcessLock.ExitUpgradeableReadLock(); } }
public void StartRiding(Race race, RaceProcessor rp) { _CurrentTacticIdx = -1; _messageCounter = 0; _ReviewTacticsTime = DateTime.MinValue; // Force full tactics review on first update int seed = (this.UserId + DateTime.UtcNow.Ticks.ToString()).GetHashCode(); Random rnd = new Random(seed); _RaceProcessor = rp; _Race = race; _Motor = new Motor(); double[] powerBands = new double[]{this.Power1Hr, this.Power5Min,this.Power1Min, this.Power5Sec}; double[] alphaBands = new double[]{3600, 300, 60, 5}; _Motor.Initialise(this.PowerMin, powerBands, alphaBands); // Initialise the spot _lastMessageTime = (ulong)DateTime.UtcNow.Subtract(new DateTime(1970,1,1)).TotalMilliseconds-1000; // Load up the tactics _TacticsCompendium.Clear(); // If more than one tactic has the highest score, then they'll be chosen in the order // added to the compendium // Recover is really the last thing we want to consider _TacticsCompendium.Add(new ChaseTactic(UserId, _Motor, Aggression, race)); _TacticsCompendium.Add(new WheelsuckTactic(UserId, _Motor, Aggression, race)); _TacticsCompendium.Add(new BreakTactic(UserId, _Motor, Aggression, race)); _TacticsCompendium.Add(new TimetrialTactic(UserId, _Motor, Aggression, race)); _TacticsCompendium.Add(new RecoverTactic(UserId, _Motor, Aggression, race)); _MessageTimer = new Timer(UpdateSpotData, null, 0, UPDATE_SPOT_INTERVAL_MS); }
private void ScheduleRaces(object state) { try { _rideProcessLock.EnterWriteLock(); long start = Utilities.DbTime.ToDbSecs(DateTime.UtcNow) + SCHEDULE_PRELOAD_SECS; // IMPORTANT // // This setup ensures that races are 'scheduled' between 1:15 and 1:30 seconds before they // start. By this time the user will have had they're last chance to join 15 seconds ago. // If there are no joiners, then the race should be cancelled at a later date // The minimum lead time for any saved race is three minutes, but this can be changed at any time // before the race is closed. We therefore have to deal with the case where a user could move a race back after // it's scheduled but before its 'closed' Race[] scheduledRaces = Race.ScheduleRaces(start); foreach (Race r in scheduledRaces) { // May already be added if (!_RaceProcessors.ContainsKey(r.RaceId)) { RaceProcessor raceProcessor = new RaceProcessor(r.RaceId); raceProcessor.RaceFinishedEvent += RemoveRaceProcessor; // Always refresh the timers - they may change after initial setting raceProcessor.Schedule(); _RaceProcessors.Add(r.RaceId, raceProcessor); } } } finally { _rideProcessLock.ExitWriteLock(); } }