Skip to content

Commit 33ec62c

Browse files
committed
Refactor the models and repositories of classifications system. Add Score class, new StandingsRepo class, add creators of positions maps. Close the issues #44 and #48
1 parent eee1844 commit 33ec62c

23 files changed

+558
-185
lines changed
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import 'package:sj_manager/models/db/event_series/classification/classification_scoring_delegate.dart';
2-
import 'package:sj_manager/models/db/event_series/classification/classification_standings_repo.dart';
1+
import 'package:sj_manager/models/db/event_series/classification/classification_scoring_delegate/classification_scoring_delegate.dart';
2+
import 'package:sj_manager/models/db/event_series/standings/score/score.dart';
3+
import 'package:sj_manager/models/db/event_series/standings/standings_record.dart';
4+
import 'package:sj_manager/models/db/event_series/standings/standings_repo.dart';
35
import 'package:sj_manager/models/db/event_series/competition/competition.dart';
46
import 'package:sj_manager/repositories/generic/items_repo.dart';
57

6-
class Classification<T> {
8+
class Classification<E, S extends Score, R extends StandingsRecord<E, S>> {
79
const Classification({
810
required this.name,
911
required this.competitions,
@@ -13,6 +15,6 @@ class Classification<T> {
1315

1416
final String name;
1517
final ItemsRepo<Competition> competitions;
16-
final ClassificationStandingsRepo<T> standings;
18+
final StandingsRepo<E, S, R> standings;
1719
final ClassificationScoringDelegate scoringDelegate; // TODO: embrace type parameters
1820
}

lib/models/db/event_series/classification/classification_result.dart

Lines changed: 0 additions & 32 deletions
This file was deleted.

lib/models/db/event_series/classification/classification_scoring_delegate.dart

Lines changed: 0 additions & 21 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import 'package:sj_manager/models/db/event_series/classification/classification_scoring_delegate/classification_scoring_delegate.dart';
2+
import 'package:sj_manager/models/db/event_series/event_series.dart';
3+
4+
class CallbackClassificationScoringDelegateByEventSeries<S, T>
5+
implements ClassificationScoringDelegate<S, T, EventSeries> {
6+
const CallbackClassificationScoringDelegateByEventSeries({
7+
required this.compute,
8+
});
9+
10+
final S Function(T entity, EventSeries series) compute;
11+
12+
@override
13+
S calculateScore({required T entity, required EventSeries input}) {
14+
return compute(entity, input);
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
abstract interface class ClassificationScoringDelegate<S, E, I> {
2+
const ClassificationScoringDelegate();
3+
4+
S calculateScore({required E entity, required I input});
5+
}

lib/models/db/event_series/classification/classification_standings_repo.dart

Lines changed: 0 additions & 65 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import 'package:sj_manager/models/db/event_series/standings/score/score.dart';
2+
3+
abstract class SingleValueScore<T> extends Score {
4+
const SingleValueScore(this.value);
5+
6+
final T value;
7+
8+
@override
9+
List<Object?> get props => [value];
10+
}
11+
12+
class PointsScore extends SingleValueScore<double> {
13+
const PointsScore(super.value);
14+
15+
@override
16+
bool operator >(covariant PointsScore other) {
17+
return value > other.value;
18+
}
19+
20+
@override
21+
bool operator <(covariant PointsScore other) {
22+
return value < other.value;
23+
}
24+
25+
@override
26+
int compareTo(covariant PointsScore other) {
27+
return value.compareTo(other.value);
28+
}
29+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import 'package:equatable/equatable.dart';
2+
3+
abstract class Score with EquatableMixin implements Comparable {
4+
const Score();
5+
6+
bool operator <(Score other);
7+
bool operator >(Score other);
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import 'package:sj_manager/models/db/event_series/standings/standings_record.dart';
2+
3+
abstract interface class StandingsPositionsCreator<T extends StandingsRecord> {
4+
Map<int, List<T>> create(List<T> records);
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import 'package:sj_manager/models/db/event_series/standings/standings_positions_map_creator/standings_positions_creator.dart';
2+
import 'package:sj_manager/models/db/event_series/standings/standings_record.dart';
3+
4+
class StandingsPositionsWithExAequoCreator<T extends StandingsRecord>
5+
implements StandingsPositionsCreator<T> {
6+
@override
7+
Map<int, List<T>> create(List<T> records) {
8+
_sortRecords(records);
9+
return _generatePositionsMap(records);
10+
}
11+
12+
void _sortRecords(List<T> records) {
13+
records.sort((a, b) => b.compareTo(a));
14+
}
15+
16+
Map<int, List<T>> _generatePositionsMap(List<T> records) {
17+
Map<int, List<T>> positionsMap = {};
18+
int currentPosition = 1;
19+
int currentRank = 1;
20+
21+
for (int i = 0; i < records.length; i++) {
22+
if (i > 0 && records[i].score != records[i - 1].score) {
23+
currentRank = currentPosition;
24+
}
25+
26+
positionsMap.putIfAbsent(currentRank, () => []).add(records[i]);
27+
currentPosition++;
28+
}
29+
30+
return positionsMap;
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import 'package:sj_manager/models/db/event_series/standings/standings_positions_map_creator/standings_positions_creator.dart';
2+
import 'package:sj_manager/models/db/event_series/standings/standings_record.dart';
3+
4+
class StandingsPositionsWithNoExAequoCreator<T extends StandingsRecord>
5+
implements StandingsPositionsCreator<T> {
6+
@override
7+
Map<int, List<T>> create(List<T> records) {
8+
_sortRecords(records);
9+
return _generatePositionsMap(records);
10+
}
11+
12+
void _sortRecords(List<T> records) {
13+
records.sort((a, b) => a.score > b.score ? -1 : 1);
14+
}
15+
16+
Map<int, List<T>> _generatePositionsMap(List<T> records) {
17+
Map<int, List<T>> positionsMap = {};
18+
int currentPosition = 1;
19+
20+
for (T record in records) {
21+
positionsMap[currentPosition] = [record];
22+
currentPosition++;
23+
}
24+
25+
return positionsMap;
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import 'dart:math';
2+
3+
import 'package:sj_manager/models/db/event_series/standings/standings_positions_map_creator/standings_positions_creator.dart';
4+
import 'package:sj_manager/models/db/event_series/standings/standings_record.dart';
5+
6+
class StandingsPositionsWithShuffleOnEqualsCreator<T extends StandingsRecord>
7+
implements StandingsPositionsCreator<T> {
8+
final Random _random = Random();
9+
10+
@override
11+
Map<int, List<T>> create(List<T> records) {
12+
_sortRecords(records);
13+
return _generatePositionsMap(records);
14+
}
15+
16+
void _sortRecords(List<T> records) {
17+
records.sort((a, b) => a.score > b.score ? -1 : 1);
18+
}
19+
20+
Map<int, List<T>> _generatePositionsMap(List<T> records) {
21+
Map<int, List<T>> positionsMap = {};
22+
int currentPosition = 1;
23+
int currentRank = 1;
24+
25+
for (int i = 0; i < records.length; i++) {
26+
if (i > 0 && records[i].score < records[i - 1].score) {
27+
currentRank = currentPosition;
28+
}
29+
30+
positionsMap.putIfAbsent(currentRank, () => []).add(records[i]);
31+
currentPosition++;
32+
}
33+
34+
// Shuffle the records with the same score
35+
for (var position in positionsMap.keys) {
36+
positionsMap[position]!.shuffle(_random);
37+
}
38+
39+
return positionsMap;
40+
}
41+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:sj_manager/models/db/event_series/standings/score/score.dart';
3+
4+
class StandingsRecord<E, S extends Score> with EquatableMixin implements Comparable {
5+
const StandingsRecord({
6+
required this.entity,
7+
required this.score,
8+
});
9+
10+
final E entity;
11+
final S score;
12+
13+
StandingsRecord<E, S> copyWith({
14+
E? entity,
15+
S? score,
16+
}) {
17+
return StandingsRecord<E, S>(
18+
entity: entity ?? this.entity,
19+
score: score ?? this.score,
20+
);
21+
}
22+
23+
bool operator >(StandingsRecord<E, S> other) {
24+
return score > other.score;
25+
}
26+
27+
bool operator <(StandingsRecord<E, S> other) {
28+
return score > other.score;
29+
}
30+
31+
@override
32+
int compareTo(covariant StandingsRecord other) {
33+
return score.compareTo(other.score);
34+
}
35+
36+
@override
37+
List<Object?> get props => [entity, score];
38+
}

0 commit comments

Comments
 (0)