sclass Best_comparable {
A best;
Comparable score;
bool verboseNewBest, replaceIfSameScore;
transient O onChange;
transient O stringifier; // func(A) -> S
synchronized bool isNewBest(Comparable score) {
ret this.score == null
|| (replaceIfSameScore
? cmp(score, this.score) >= 0
: cmp(score, this.score) > 0);
}
synchronized Comparable bestScore() {
ret score;
}
Comparable score() { ret bestScore(); }
Comparable getScore() { ret bestScore(); }
synchronized float floatScoreOr(float defaultValue) {
ret best == null ? defaultValue : (float) score;
}
bool put(Pair extends A, Comparable> p) {
ret p != null && put(p.a, p.b);
}
bool put(Best extends A> b) {
ret b != null && put(b!, b.score);
}
bool put(A a, Comparable score) {
ping();
bool change;
if (a != null) synchronized(this) {
if (isNewBest(score)) {
best = a;
this.score = score;
set change;
}
}
if (change) {
if (verboseNewBest) print("New best! " + this);
pcallF(onChange);
}
ret change;
}
synchronized A get() { ret best; }
synchronized bool has() { ret best != null; }
synchronized Pair pair() { ret main pair(best, bestScore()); }
synchronized A getIfScoreAbove(Comparable x) { ret cmp(x, score()) >= 0 ? best : null; }
toString {
ret !has() ? "-" : "Score " + score + ": " + callStringifier(stringifier, best);
}
bool putAndPrintIfNewBest(A a, Comparable score) {
if (!put(a, score)) false;
ret true with print(this);
}
synchronized void clear() { best = null; score = 0; }
}