public void ClearStationAssignment() { if (Player1 != null) { Player1.ClearStationAssignment(); } if (Player2 != null) { Player2.ClearStationAssignment(); } }
public ObservableMatch(Match match, TournamentContext context) { source = match; OwningContext = context; //Round doesn't change, initialize RoundFixed var totalPlayerCount = context.Tournament.ParticipantsCount; var lowerBoundExponent = Math.Floor(Math.Log(totalPlayerCount, 2)); var lowerBound = Math.Pow(2, lowerBoundExponent); if (match.Round < 0 && totalPlayerCount > lowerBound && totalPlayerCount <= lowerBound + (lowerBound / 2)) { Round = match.Round - 1; } else { Round = match.Round; } //Check if station assignment data checks out. If not, clear the assignment var player1Station = Player1 != null ? Player1.StationAssignment : default(string); var player2Station = Player2 != null ? Player2.StationAssignment : default(string); //If stations don't match, clear. Don't check completed matches because those will frequently have mismatching stations if (State != "complete" && player1Station != player2Station) { ClearStationAssignment(); } //Listen for when properties changed to that changed events for the convenience properties can also be fired. this.PropertyChanged += (sender, e) => { switch (e.PropertyName) { case "Player1Id": this.Raise("Player1", PropertyChanged); this.Raise("PlayerCount", PropertyChanged); if (Player1 != null) { Player1.IsMissing = false; //When a player gets added to a match, clear their missing flag } break; case "Player2Id": this.Raise("Player2", PropertyChanged); this.Raise("PlayerCount", PropertyChanged); if (Player2 != null) { Player2.IsMissing = false; //When a player gets added to a match, clear their missing flag } break; case "Player1PrereqMatchId": this.Raise("Player1PreviousMatch", PropertyChanged); break; case "Player2PrereqMatchId": this.Raise("Player2PreviousMatch", PropertyChanged); break; case "StartedAt": this.Raise("TimeSinceAvailable", PropertyChanged); break; case "State": //Clear station assignments if match state changes if (Player1 != null) { Player1.ClearStationAssignment(); } if (Player2 != null) { Player2.ClearStationAssignment(); } //If match state has changed to open, execute selected new match option if (State == "open") { var option = GlobalSettings.Instance.SelectedNewMatchAction; switch (option) { case NewMatchAction.AutoAssign: //TODO: Consider using lock block here to prevent potential multithreaded assignment to the same station var highestPriorityStation = Stations.Instance.GetBestNormalStation(); if (highestPriorityStation != null) { AssignPlayersToStation(highestPriorityStation.Name); } break; case NewMatchAction.Anywhere: AssignPlayersToStation("Any"); break; } } break; } }; var propertyChangedObs = Observable.FromEventPattern <PropertyChangedEventHandler, PropertyChangedEventArgs>(h => this.PropertyChanged += h, h => this.PropertyChanged -= h); //The following will create an observable sequence that will raise an event either when player1 changes or when player1's station assignment status changes var player1ChangedOrAssignmentChanged = propertyChangedObs.Where(a => a.EventArgs.PropertyName == "Player1") .Select(_ => { if (Player1 != null) { return(Observable.FromEventPattern <PropertyChangedEventHandler, PropertyChangedEventArgs>(h => { player1Queue.Enqueue(Player1); Player1.PropertyChanged += h; }, h => { player1Queue.Dequeue().PropertyChanged -= h; }) .Where(a => a.EventArgs.PropertyName == "IsAssignedToStation" || a.EventArgs.PropertyName == "StationAssignment") .Select(_2 => EventArgs.Empty).StartWith(EventArgs.Empty)); } else { return(Observable.Return(EventArgs.Empty)); } }).Switch(); //Subscribe to above observable sequence to maintain the assignment state of the match player1ChangedOrAssignmentChanged.Subscribe(_ => { IsMatchInProgress = Player1 != null && Player1.IsAssignedToStation; StationAssignment = Player1 == null ? null : Player1.StationAssignment; }); //Forcibly raise player1 property notification to assign station status this.Raise("Player1", PropertyChanged); }