Skip to content

Commit 2299ccd

Browse files
committed
Add some simulation database loaders, do refactoring, do some important work around event series system, add user algorithm types.
1 parent ab231dd commit 2299ccd

File tree

127 files changed

+1600
-873
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

127 files changed

+1600
-873
lines changed

lib/bloc/database_editing/copied_local_db_cubit.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@ class CopiedLocalDbCubit extends Cubit<LocalDbRepo?> {
4444
}
4545

4646
Future<void> _saveChangesByType<T>(BuildContext context) async {
47-
originalDb.editableByGenericType<T>().set(state!.editableByGenericType<T>().last);
48-
final file = databaseFile(
49-
context.read(), context.read<DbFileSystemEntityNames>().byGenericType<T>());
47+
originalDb
48+
.editableByGenericType<T>()
49+
.set(state!.editableByGenericType<T>().last);
50+
final file = databaseFile(context.read(),
51+
context.read<DbFileSystemEntityNames>().byGenericType<T>());
5052
await _saveItemsToJsonByType<T>(
5153
context: context,
5254
file: file,

lib/bloc/database_editing/local_db_filtered_items_cubit.dart

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,21 @@ class LocalDbFilteredItemsCubit extends Cubit<LocalDbFilteredItemsState> {
2929
_maleJumperChangesSubscription = maleStream.listen((event) {
3030
final jumpers = event.$1.toList();
3131
final filters = event.$2;
32-
emit(state.copyWith(maleJumpers: Filter.filterAll(jumpers, filters).cast()));
32+
emit(state.copyWith(
33+
maleJumpers: Filter.filterAll(jumpers, filters).cast()));
3334
});
3435

3536
final femaleStream = Rx.combineLatest2(itemsRepo.femaleJumpers.items,
3637
filtersRepo.femaleJumpersFilters, (items, filters) => (items, filters));
3738
_femaleJumperChangesSubscription = femaleStream.listen((event) {
3839
final jumpers = event.$1.toList();
3940
final filters = event.$2;
40-
emit(state.copyWith(femaleJumpers: Filter.filterAll(jumpers, filters).cast()));
41+
emit(state.copyWith(
42+
femaleJumpers: Filter.filterAll(jumpers, filters).cast()));
4143
});
4244

43-
final hillsStream = Rx.combineLatest2(itemsRepo.hills.items, filtersRepo.hillsFilters,
44-
(items, filters) => (items, filters));
45+
final hillsStream = Rx.combineLatest2(itemsRepo.hills.items,
46+
filtersRepo.hillsFilters, (items, filters) => (items, filters));
4547
_hillChangesSubscription = hillsStream.listen((event) {
4648
final hills = event.$1.toList();
4749
final filters = event.$2;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import 'package:sj_manager/bloc/simulation_db_loading/simulation_db_part_loader.dart';
2+
import 'package:sj_manager/json/json_types.dart';
3+
import 'package:sj_manager/models/db/event_series/classification/classification.dart';
4+
import 'package:sj_manager/models/db/event_series/competition/competition.dart';
5+
import 'package:sj_manager/models/db/event_series/event_series_calendar.dart';
6+
import 'package:sj_manager/repositories/generic/ids_repo.dart';
7+
import 'package:sj_manager/utils/id_generator.dart';
8+
9+
class CalendarLoader implements SimulationDbPartLoader<EventSeriesCalendar> {
10+
const CalendarLoader({
11+
required this.idsRepo,
12+
required this.idGenerator,
13+
required this.eventSeriesId,
14+
required this.competitionLoader,
15+
required this.classificationLoader,
16+
});
17+
18+
final IdsRepo idsRepo;
19+
final IdGenerator idGenerator;
20+
final String eventSeriesId;
21+
final SimulationDbPartLoader<Competition> competitionLoader;
22+
final SimulationDbPartLoader<Classification> classificationLoader;
23+
24+
@override
25+
EventSeriesCalendar load(Json json) {
26+
final competitionsJson = json['competitions'] as List<Json>;
27+
final competitions = competitionsJson.map((json) {
28+
final competition = competitionLoader.load(json);
29+
idsRepo.register(competition, id: idGenerator.generate());
30+
return competition;
31+
});
32+
final classificationsJson = json['classifications'] as List<Json>;
33+
final classifications = classificationsJson.map((json) {
34+
final classification = classificationLoader.load(json);
35+
idsRepo.register(classification, id: idGenerator.generate());
36+
return classification;
37+
});
38+
final qualificationsJson = json['qualifications'] as Json;
39+
final qualifications = qualificationsJson.map((competitionId, qualifiactionsId) {
40+
return MapEntry(idsRepo.get<Competition>(competitionId),
41+
idsRepo.get<Competition>(qualifiactionsId));
42+
});
43+
return EventSeriesCalendar(
44+
competitions: competitions.toList(),
45+
classifications: classifications.toList(),
46+
qualifications: qualifications,
47+
);
48+
}
49+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import 'package:sj_manager/bloc/simulation_db_loading/simulation_db_part_loader.dart';
2+
import 'package:sj_manager/bloc/simulation_db_loading/standings_loader.dart';
3+
import 'package:sj_manager/json/json_types.dart';
4+
import 'package:sj_manager/models/db/country/country.dart';
5+
import 'package:sj_manager/models/db/event_series/classification/classification.dart';
6+
import 'package:sj_manager/models/db/event_series/competition/rules/user_algorithms/concrete/classification_score_creator.dart';
7+
import 'package:sj_manager/repositories/generic/ids_repo.dart';
8+
import 'package:sj_manager/utils/id_generator.dart';
9+
10+
class ClassificationLoader implements SimulationDbPartLoader<Classification> {
11+
const ClassificationLoader({
12+
required this.idsRepo,
13+
required this.idGenerator,
14+
required this.languageCode,
15+
required this.scoringDelegateLoader,
16+
});
17+
18+
final IdsRepo idsRepo;
19+
final IdGenerator idGenerator;
20+
final String languageCode;
21+
final SimulationDbPartLoader<ClassificationScoreCreator> scoringDelegateLoader;
22+
23+
@override
24+
Classification load(Json json) {
25+
final name = stringFromMultilingualJson(json,
26+
languageCode: languageCode, parameterName: 'name');
27+
final standings = StandingsLoader(idsRepo: idsRepo, idGenerator: idGenerator).load(
28+
json['standings'],
29+
);
30+
final scoreCreator = idsRepo.get<ClassificationScoreCreator>(json['scoreCreatorId']);
31+
return Classification(
32+
name: name,
33+
standings: standings,
34+
scoreCreator: scoreCreator,
35+
);
36+
}
37+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import 'package:sj_manager/bloc/simulation_db_loading/simulation_db_part_loader.dart';
2+
import 'package:sj_manager/json/json_types.dart';
3+
import 'package:sj_manager/models/db/event_series/competition/competition.dart';
4+
import 'package:sj_manager/models/db/event_series/competition/competition_type.dart';
5+
import 'package:sj_manager/models/db/event_series/competition/rules/competition_rules/competition_rules.dart';
6+
import 'package:sj_manager/models/db/event_series/standings/standings_repo.dart';
7+
import 'package:sj_manager/models/db/hill/hill.dart';
8+
import 'package:sj_manager/repositories/generic/ids_repo.dart';
9+
10+
class CompetitionLoader implements SimulationDbPartLoader<Competition> {
11+
const CompetitionLoader({
12+
required this.idsRepo,
13+
required this.rulesLoader,
14+
required this.standingsLoader,
15+
});
16+
17+
final IdsRepo idsRepo;
18+
final SimulationDbPartLoader<CompetitionRules> rulesLoader;
19+
final SimulationDbPartLoader<StandingsRepo> standingsLoader;
20+
21+
@override
22+
Competition load(Json json) {
23+
final labelsJson = json['labels'] as List<String>?;
24+
Set<Object>? labels;
25+
if (labelsJson != null) {
26+
labels = labelsJson.map((json) => _label(json)).toSet();
27+
}
28+
final standings = standingsLoader.load(json);
29+
30+
return Competition(
31+
// TODO: Maybe preserve the type?
32+
hill: idsRepo.get<Hill>(json['hillId']),
33+
date: DateTime.parse(json['date']),
34+
rules: rulesLoader.load(json['rules']),
35+
labels: labels ?? const {},
36+
standings: standings,
37+
);
38+
}
39+
40+
Object _label(String jsonString) {
41+
return switch (jsonString) {
42+
'competition' => CompetitionType.competition,
43+
'qualifications' => CompetitionType.qualifications,
44+
'trialRound' => CompetitionType.trialRound,
45+
'training' => CompetitionType.training,
46+
_ => throw ArgumentError('Invalid competition label ID ($jsonString)'),
47+
};
48+
}
49+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import 'package:sj_manager/bloc/simulation_db_loading/simulation_db_part_loader.dart';
2+
import 'package:sj_manager/json/json_types.dart';
3+
import 'package:sj_manager/models/db/event_series/competition/rules/competition_round_rules/competition_round_rules.dart';
4+
import 'package:sj_manager/models/db/event_series/competition/rules/competition_round_rules/group_rules/team_competition_group_rules.dart';
5+
import 'package:sj_manager/models/db/event_series/competition/rules/competition_round_rules/individual_competition_round_rules.dart';
6+
import 'package:sj_manager/models/db/event_series/competition/rules/competition_round_rules/team_competition_round_rules.dart';
7+
import 'package:sj_manager/models/db/event_series/competition/rules/entities_limit.dart';
8+
import 'package:sj_manager/models/db/event_series/standings/standings_positions_map_creator/standings_positions_creator.dart';
9+
import 'package:sj_manager/models/db/jumper/jumper.dart';
10+
import 'package:sj_manager/models/db/team/team.dart';
11+
import 'package:sj_manager/repositories/generic/ids_repo.dart';
12+
13+
class CompetitionRoundRulesLoader
14+
implements SimulationDbPartLoader<CompetitionRoundRules> {
15+
const CompetitionRoundRulesLoader({
16+
required this.idsRepo,
17+
required this.entitiesLimitLoader,
18+
required this.positionsCreatorLoader,
19+
required this.teamCompetitionGroupRulesLoader,
20+
});
21+
22+
final IdsRepo idsRepo;
23+
final SimulationDbPartLoader<EntitiesLimit> entitiesLimitLoader;
24+
final SimulationDbPartLoader<StandingsPositionsCreator> positionsCreatorLoader;
25+
final SimulationDbPartLoader<TeamCompetitionGroupRules> teamCompetitionGroupRulesLoader;
26+
27+
@override
28+
CompetitionRoundRules load(Json json) {
29+
final type = json['type'] as String;
30+
return switch (type) {
31+
'individual' => _loadIndividual(json),
32+
'team' => _loadTeam(json),
33+
_ => throw ArgumentError(
34+
'Invalid competition round rules type: $type (it can be only \'individual\' or \'team\')',
35+
),
36+
};
37+
}
38+
39+
CompetitionRoundRules<Jumper> _loadIndividual(Json json) {
40+
return IndividualCompetitionRoundRules(
41+
limit: entitiesLimitLoader.load(json['entitiesLimit']),
42+
bibsAreReassigned: json['bibsAreReassigned'],
43+
gateCanChange: json['gateCanChange'],
44+
windAverager: idsRepo.get(json['windAveragerId']),
45+
inrunLightsEnabled: json['inrunLightsEnabled'],
46+
dsqEnabled: json['dsqEnabled'],
47+
positionsCreator: positionsCreatorLoader.load(json['positionsCreator']),
48+
canBeCancelledByWind: json['dsqEnabled'],
49+
ruleOf95HsFallEnabled: json['dsqEnabled'],
50+
judgesCount: json['judgesCount'],
51+
competitionScoreCreator: idsRepo.get(json['competitionScoreCreatorId']),
52+
jumpScoreCreator: idsRepo.get(json['jumpScoreCreatorId']),
53+
significantJudgesChooser: idsRepo.get(json['significantJudgesChooserId']),
54+
);
55+
}
56+
57+
CompetitionRoundRules<Team> _loadTeam(Json json) {
58+
final groupsJson = json['groups'] as List<Json>;
59+
final groups = groupsJson
60+
.map(
61+
(json) => teamCompetitionGroupRulesLoader.load(json),
62+
)
63+
.toList();
64+
65+
return TeamCompetitionRoundRules(
66+
limit: entitiesLimitLoader.load(json['entitiesLimit']),
67+
bibsAreReassigned: json['bibsAreReassigned'],
68+
gateCanChange: json['gateCanChange'],
69+
windAverager: idsRepo.get(json['windAveragerId']),
70+
inrunLightsEnabled: json['inrunLightsEnabled'],
71+
dsqEnabled: json['dsqEnabled'],
72+
positionsCreator: positionsCreatorLoader.load(json['positionsCreator']),
73+
canBeCancelledByWind: json['dsqEnabled'],
74+
ruleOf95HsFallEnabled: json['dsqEnabled'],
75+
judgesCount: json['judgesCount'],
76+
competitionScoreCreator: idsRepo.get(json['competitionScoreCreatorId']),
77+
jumpScoreCreator: idsRepo.get(json['jumpScoreCreatorId']),
78+
significantJudgesChooser: idsRepo.get(json['significantJudgesChooserId']),
79+
groups: groups,
80+
teamSize: json['teamSize'],
81+
);
82+
}
83+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import 'package:sj_manager/bloc/simulation_db_loading/simulation_db_part_loader.dart';
2+
import 'package:sj_manager/json/json_types.dart';
3+
import 'package:sj_manager/models/db/event_series/competition/rules/competition_round_rules/competition_round_rules.dart';
4+
import 'package:sj_manager/models/db/event_series/competition/rules/competition_rules/competition_rules.dart';
5+
import 'package:sj_manager/repositories/generic/ids_repo.dart';
6+
7+
class CompetitionRulesLoader implements SimulationDbPartLoader<CompetitionRules> {
8+
const CompetitionRulesLoader({
9+
required this.idsRepo,
10+
required this.roundRulesLoader,
11+
});
12+
13+
final IdsRepo idsRepo;
14+
final SimulationDbPartLoader<CompetitionRoundRules> roundRulesLoader;
15+
16+
@override
17+
CompetitionRules load(Json json) {
18+
final type = json['type'] as String;
19+
if (type == 'raw') {
20+
return _loadRaw(json);
21+
} else if (type == 'fromPreset') {
22+
return _loadFromPreset(json);
23+
} else {
24+
throw ArgumentError(
25+
'Invalid competition rules type: $type (It can be only \'raw\' and \'fromPreset\')',
26+
);
27+
}
28+
}
29+
30+
CompetitionRules _loadRaw(Json json) {
31+
final roundsJson = json['rounds'] as List<Json>;
32+
final rounds = roundsJson.map((json) {
33+
return roundRulesLoader.load(json);
34+
}).toList();
35+
return CompetitionRules(rounds: rounds);
36+
}
37+
38+
CompetitionRules _loadFromPreset(Json json) {
39+
final presetId = json['presetId'] as String;
40+
final preset = idsRepo.get<CompetitionRules>(presetId); // TODO: Competition preset
41+
return preset;
42+
}
43+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import 'package:sj_manager/bloc/simulation_db_loading/simulation_db_part_loader.dart';
2+
import 'package:sj_manager/json/json_types.dart';
3+
import 'package:sj_manager/models/db/event_series/competition/rules/entities_limit.dart';
4+
import 'package:sj_manager/repositories/generic/ids_repo.dart';
5+
6+
class EntitiesLimitLoader implements SimulationDbPartLoader<EntitiesLimit> {
7+
const EntitiesLimitLoader({
8+
required this.idsRepo,
9+
});
10+
11+
final IdsRepo idsRepo;
12+
13+
@override
14+
EntitiesLimit load(Json json) {
15+
final type = json['type'] as String;
16+
final count = json['count'] as int;
17+
return switch (type) {
18+
'exact' => EntitiesLimit(type: EntitiesLimitType.exact, count: count),
19+
'soft' => EntitiesLimit(type: EntitiesLimitType.soft, count: count),
20+
_ => throw ArgumentError(
21+
'Invalid entities limit type: $type (it can be only \'exact\' and \'soft\')',
22+
),
23+
};
24+
}
25+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import 'package:sj_manager/bloc/simulation_db_loading/simulation_db_part_loader.dart';
2+
import 'package:sj_manager/json/json_types.dart';
3+
import 'package:sj_manager/models/db/event_series/event_series_facts.dart';
4+
import 'package:sj_manager/repositories/generic/ids_repo.dart';
5+
6+
class EventSeriesFactsLoader implements SimulationDbPartLoader<EventSeriesFacts> {
7+
const EventSeriesFactsLoader({
8+
required this.idsRepo,
9+
});
10+
11+
final IdsRepo idsRepo;
12+
13+
@override
14+
EventSeriesFacts load(Json json) {
15+
return EventSeriesFacts(
16+
priority: json['priority'],
17+
);
18+
}
19+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import 'package:sj_manager/bloc/simulation_db_loading/simulation_db_part_loader.dart';
2+
import 'package:sj_manager/json/json_types.dart';
3+
import 'package:sj_manager/models/db/country/country.dart';
4+
import 'package:sj_manager/models/db/event_series/event_series.dart';
5+
import 'package:sj_manager/models/db/event_series/event_series_calendar.dart';
6+
import 'package:sj_manager/models/db/event_series/event_series_facts.dart';
7+
import 'package:sj_manager/repositories/generic/ids_repo.dart';
8+
9+
class EventSeriesLoader implements SimulationDbPartLoader<EventSeries> {
10+
const EventSeriesLoader({
11+
required this.idsRepo,
12+
required this.languageCode,
13+
required this.calendarLoader,
14+
required this.factsLoader,
15+
});
16+
17+
final IdsRepo idsRepo;
18+
final String languageCode;
19+
final SimulationDbPartLoader<EventSeriesCalendar> calendarLoader;
20+
final SimulationDbPartLoader<EventSeriesFacts> factsLoader;
21+
22+
@override
23+
EventSeries load(Json json) {
24+
final name = stringFromMultilingualJson(json,
25+
languageCode: languageCode, parameterName: 'name');
26+
final id = json['id'] as String;
27+
final calendar = calendarLoader.load(json);
28+
29+
return EventSeries(
30+
id: id,
31+
name: name,
32+
calendar: calendar,
33+
facts: factsLoader.load(json['facts']),
34+
);
35+
}
36+
}

0 commit comments

Comments
 (0)