public PersistedCityStatistics( int timeCode, IPowerGridStatistics powerGridStatistics, IGrowthZoneStatistics growthZoneStatistics, IMiscCityStatistics miscCityStatistics ) : this() { if (timeCode == default(int)) { throw new ArgumentOutOfRangeException(nameof(timeCode)); } if (powerGridStatistics == null) { throw new ArgumentNullException(nameof(powerGridStatistics)); } if (growthZoneStatistics == null) { throw new ArgumentNullException(nameof(growthZoneStatistics)); } if (miscCityStatistics == null) { throw new ArgumentNullException(nameof(miscCityStatistics)); } TimeCode = timeCode; CrimeNumbers = new PersistedNumberSummary(miscCityStatistics.CrimeNumbers); FireHazardNumbers = new PersistedNumberSummary(miscCityStatistics.FireHazardNumbers); PollutionNumbers = new PersistedNumberSummary(miscCityStatistics.PollutionNumbers); LandValueNumbers = new PersistedNumberSummary(miscCityStatistics.LandValueNumbers); TrafficNumbers = new PersistedNumberSummary(growthZoneStatistics.RoadInfrastructureStatistics.TrafficNumbers); NumberOfRoadZones = growthZoneStatistics.RoadInfrastructureStatistics.NumberOfRoadZones; AverageTravelDistanceStatistics = new PersistedNumberSummary(miscCityStatistics.TravelDistanceNumbers); NumberOfRailRoadZones = growthZoneStatistics.RailroadInfrastructureStatistics.NumberOfRailRoadZones; NumberOfTrainStations = growthZoneStatistics.RailroadInfrastructureStatistics.NumberOfTrainStations; PowerAmountOfConsumers = powerGridStatistics.PowerGridNetworkStatistics.Sum(x => x.AmountOfConsumers); PowerAmountOfSuppliers = powerGridStatistics.PowerGridNetworkStatistics.Sum(x => x.AmountOfSuppliers); PowerConsumptionInUnits = powerGridStatistics.PowerGridNetworkStatistics.Sum(x => x.ConsumptionInUnits); PowerSupplyInUnits = powerGridStatistics.PowerGridNetworkStatistics.Sum(x => x.SupplyInUnits); CommercialZonePopulationStatistics = new PersistedNumberSummary(growthZoneStatistics.CommercialZonePopulationNumbers); IndustrialZonePopulationStatistics = new PersistedNumberSummary(growthZoneStatistics.IndustrialZonePopulationNumbers); ResidentialZonePopulationStatistics = new PersistedNumberSummary(growthZoneStatistics.ResidentialZonePopulationNumbers); GlobalZonePopulationStatistics = new PersistedNumberSummary(growthZoneStatistics.GlobalZonePopulationNumbers); NumberOfStadiums = growthZoneStatistics.CityServicesStatistics.NumberOfStadiums; NumberOfAirports = growthZoneStatistics.CityServicesStatistics.NumberOfAirports; NumberOfSeaPorts = growthZoneStatistics.CityServicesStatistics.NumberOfSeaports; NumberOfPoliceStations = growthZoneStatistics.CityServicesStatistics.NumberOfPoliceStations; NumberOfFireStations = growthZoneStatistics.CityServicesStatistics.NumberOfFireStations; TimeCode = TimeCode; }
public SimulationSession(SimulationOptions simulationOptions) { _simulationOptions = simulationOptions; _area = new Area(simulationOptions.GetAreaOptions(() => _cityBudgetConfiguration, () => new LandValueCalculator(_cityBudgetConfiguration))); _area.OnAreaConsumptionResult += HandleAreaConsumptionResult; _area.OnAreaMessage += (s, e) => RaiseAreaMessageEvent(e.Message); PersistedCityBudgetConfiguration persistedCityBudgetConfiguration = null; simulationOptions.WithPersistedSimulation(persistedSimulation => { if (persistedSimulation.PersistedCityStatistics == null) { return; } foreach (var x in persistedSimulation.PersistedCityStatistics) { _persistedCityStatisticsCollection.Add(x); } var last = persistedSimulation.PersistedCityStatistics.OrderByDescending( x => x.PersistedCityStatistics.TimeCode).First(); _yearAndMonth.LoadTimeCode(last.PersistedCityStatistics.TimeCode); _yearAndMonth.AddWeek(); _cityBudget.RestoreFrom(last); persistedCityBudgetConfiguration = persistedSimulation.PersistedCityBudgetConfiguration; }); _cityBudgetConfiguration = persistedCityBudgetConfiguration ?? new PersistedCityBudgetConfiguration(); _growthSimulationTask = new NeverEndingTask("Growth simulation", async() => { if (!PowerAndMiscStatisticsLoaded) { return; } var growthZoneStatistics = await _area.PerformGrowthSimulationCycle(_cancellationTokenSource.Token); _persistedCityStatisticsCollection.Add( _cityBudget.ProcessFinances(new PersistedCityStatistics( timeCode: _yearAndMonth.TimeCode, powerGridStatistics: _lastPowerGridStatistics, growthZoneStatistics: growthZoneStatistics, miscCityStatistics: _lastMiscCityStatistics ), _cityBudgetConfiguration ) ); OnYearAndOrMonthChanged?.Invoke(this, new EventArgsWithData <IYearAndMonth>(_yearAndMonth)); CityStatisticsUpdated?.Invoke(this, new CityStatisticsUpdatedEventArgs(_persistedCityStatisticsCollection.GetMostRecentPersistedCityStatistics().MatchingObject)); _yearAndMonth.AddWeek(); if (_yearAndMonth.IsAtBeginningOfNewYear) { _cityBudget.AddProjectedIncomeToCurrentAmount(); } _cancellationTokenSource.Token.ThrowIfCancellationRequested(); }, _cancellationTokenSource.Token); _powerTask = new NeverEndingTask("Power grid scan", async() => { _cancellationTokenSource.Token.ThrowIfCancellationRequested(); _lastPowerGridStatistics = _area.CalculatePowergridStatistics(); await Task.FromResult(true); }, _cancellationTokenSource.Token); _crimeAndPollutionTask = new NeverEndingTask("Crime and pollution calculation", async() => { _cancellationTokenSource.Token.ThrowIfCancellationRequested(); _lastMiscCityStatistics = _area.CalculateMiscCityStatistics(_cancellationTokenSource.Token); await Task.FromResult(true); }, _cancellationTokenSource.Token); _cityBudget.OnCityBudgetValueChanged += (sender, e) => { OnCityBudgetValueChanged?.Invoke(this, e); }; _yearAndMonth.OnWeekElapsed += OnWeekPass; }