Skip to content

Commit

Permalink
Enable library mode in cds module
Browse files Browse the repository at this point in the history
  • Loading branch information
kunyavskiy committed Sep 8, 2023
1 parent 0d8ccc6 commit bc68e59
Show file tree
Hide file tree
Showing 22 changed files with 213 additions and 208 deletions.
4 changes: 4 additions & 0 deletions src/cds/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ tasks {
}
}

kotlin {
explicitApi()
}

dependencies {
api(libs.kotlinx.collections.immutable)
implementation(projects.common)
Expand Down
14 changes: 7 additions & 7 deletions src/cds/src/main/kotlin/org/icpclive/api/Analytics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,31 @@ import org.icpclive.util.UnixMillisecondsSerializer
import kotlin.time.Duration

@Serializable
data class AnalyticsCompanionPreset(
public data class AnalyticsCompanionPreset(
val presetId: Int,
@SerialName("expirationTimeUnixMs")
@Serializable(with = UnixMillisecondsSerializer::class)
val expirationTime: Instant?,
)

@Serializable
data class AnalyticsCompanionRun(
public data class AnalyticsCompanionRun(
@SerialName("expirationTimeUnixMs")
@Serializable(with = UnixMillisecondsSerializer::class)
val expirationTime: Instant?,
val mediaType: MediaType,
)

@Serializable
sealed class AnalyticsMessage {
abstract val id: String
abstract val time: Instant
abstract val relativeTime: Duration
public sealed class AnalyticsMessage {
public abstract val id: String
public abstract val time: Instant
public abstract val relativeTime: Duration
}

@Serializable
@SerialName("commentary")
data class AnalyticsCommentaryEvent(
public data class AnalyticsCommentaryEvent(
override val id: String,
val message: String,
@SerialName("timeUnixMs")
Expand Down
62 changes: 31 additions & 31 deletions src/cds/src/main/kotlin/org/icpclive/api/ContestInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,25 @@ import java.awt.Color
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes

enum class MedalTiebreakMode {
public enum class MedalTiebreakMode {
NONE,
ALL
}

@Serializable
data class MedalType(
public data class MedalType(
val name: String,
val count: Int,
val minScore: Double = Double.MIN_VALUE,
val tiebreakMode: MedalTiebreakMode = MedalTiebreakMode.ALL
)

@Serializable
enum class ContestResultType {
public enum class ContestResultType {
ICPC, IOI
}

enum class ScoreMergeMode {
public enum class ScoreMergeMode {
/**
* For each tests group in the problem, get maximum score over all submissions.
*/
Expand Down Expand Up @@ -54,7 +54,7 @@ enum class ScoreMergeMode {
}

@Serializable
data class ProblemInfo(
public data class ProblemInfo(
@SerialName("letter") val displayName: String,
@SerialName("name") val fullName: String,
val id: Int,
Expand All @@ -65,13 +65,13 @@ data class ProblemInfo(
@Serializable(ColorSerializer::class) val color: Color? = null,
val scoreMergeMode: ScoreMergeMode? = null,
) {
companion object {
internal companion object {
val logger = getLogger(ProblemInfo::class)
}
}

@Serializable
enum class ContestStatus {
public enum class ContestStatus {
BEFORE, RUNNING, OVER, FINALIZED;

internal companion object {
Expand All @@ -88,36 +88,36 @@ enum class ContestStatus {


@Serializable
sealed class MediaType {
abstract val isMedia: Boolean
public sealed class MediaType {
public abstract val isMedia: Boolean

@Serializable
@SerialName("Photo")
data class Photo(val url: String, override val isMedia: Boolean = true) : MediaType()
public data class Photo(val url: String, override val isMedia: Boolean = true) : MediaType()

@Serializable
@SerialName("Object")
data class Object(val url: String, override val isMedia: Boolean = true) : MediaType()
public data class Object(val url: String, override val isMedia: Boolean = true) : MediaType()

@Serializable
@SerialName("Video")
data class Video(val url: String, override val isMedia: Boolean = true) : MediaType()
public data class Video(val url: String, override val isMedia: Boolean = true) : MediaType()

/**
* WebRTC proxy connection
* @see <a href="https://github.com/kbats183/webrtc-proxy">https://github.com/kbats183/webrtc-proxy</a>
*/
@Serializable
@SerialName("WebRTCProxyConnection")
data class WebRTCProxyConnection(val url: String, val audioUrl: String? = null, override val isMedia: Boolean = true) : MediaType()
public data class WebRTCProxyConnection(val url: String, val audioUrl: String? = null, override val isMedia: Boolean = true) : MediaType()

/**
* WebRTC grabber connection
* https://github.com/irdkwmnsb/webrtc-grabber
*/
@Serializable
@SerialName("WebRTCGrabberConnection")
data class WebRTCGrabberConnection(
public data class WebRTCGrabberConnection(
val url: String,
val peerName: String,
val streamType: String,
Expand All @@ -128,11 +128,11 @@ sealed class MediaType {

@Serializable
@SerialName("TaskStatus")
data class TaskStatus(val teamId: Int) : MediaType() {
override val isMedia = false
public data class TaskStatus(val teamId: Int) : MediaType() {
override val isMedia: Boolean = false
}

fun noMedia(): MediaType = when (this) {
public fun noMedia(): MediaType = when (this) {
is Photo -> copy(isMedia = false)
is Video -> copy(isMedia = false)
is Object -> copy(isMedia = false)
Expand All @@ -143,7 +143,7 @@ sealed class MediaType {
}

@Serializable
enum class TeamMediaType {
public enum class TeamMediaType {
@SerialName("camera")
CAMERA,

Expand All @@ -164,7 +164,7 @@ enum class TeamMediaType {
}

@Serializable
data class TeamInfo(
public data class TeamInfo(
val id: Int,
@SerialName("name") val fullName: String,
@SerialName("shortName") val displayName: String,
Expand All @@ -179,21 +179,21 @@ data class TeamInfo(
)

@Serializable
data class GroupInfo(
public data class GroupInfo(
val name: String,
val isHidden: Boolean,
val isOutOfContest: Boolean,
)

@Serializable
data class OrganizationInfo(
public data class OrganizationInfo(
val cdsId: String,
val displayName: String,
val fullName: String,
)

@Serializable
enum class PenaltyRoundingMode {
public enum class PenaltyRoundingMode {
@SerialName("each_submission_down_to_minute")
/**
* Round time of all submissions from the beginning of the contest down to whole minute, and then sum them
Expand Down Expand Up @@ -228,11 +228,11 @@ enum class PenaltyRoundingMode {

@Target(AnnotationTarget.PROPERTY)
@RequiresOptIn(level = RequiresOptIn.Level.ERROR, message = "This api is not efficient in most cases, consider using corresponding map instead")
annotation class InefficientContestInfoApi
public annotation class InefficientContestInfoApi

@Serializable
@OptIn(InefficientContestInfoApi::class)
data class ContestInfo(
public data class ContestInfo(
val name: String,
val status: ContestStatus,
val resultType: ContestResultType,
Expand All @@ -259,16 +259,16 @@ data class ContestInfo(
@Transient
val cdsSupportsFinalization: Boolean = false,
) {
val currentContestTime
public val currentContestTime: Duration
get() = when (status) {
ContestStatus.BEFORE -> Duration.ZERO
ContestStatus.RUNNING -> (Clock.System.now() - startTime) * emulationSpeed
ContestStatus.OVER, ContestStatus.FINALIZED -> contestLength
}
val groups by lazy { groupList.associateBy { it.name } }
val teams by lazy { teamList.associateBy { it.id } }
val cdsTeams by lazy { teamList.associateBy { it.contestSystemId } }
val organizations by lazy { organizationList.associateBy { it.cdsId } }
val problems by lazy { problemList.associateBy { it.id } }
val scoreboardProblems by lazy { problemList.sortedBy { it.ordinal } }
val groups: Map<String, GroupInfo> by lazy { groupList.associateBy { it.name } }
val teams: Map<Int, TeamInfo> by lazy { teamList.associateBy { it.id } }
val cdsTeams: Map<String, TeamInfo> by lazy { teamList.associateBy { it.contestSystemId } }
val organizations: Map<String, OrganizationInfo> by lazy { organizationList.associateBy { it.cdsId } }
val problems: Map<Int, ProblemInfo> by lazy { problemList.associateBy { it.id } }
val scoreboardProblems: List<ProblemInfo> by lazy { problemList.sortedBy { it.ordinal } }
}
56 changes: 28 additions & 28 deletions src/cds/src/main/kotlin/org/icpclive/api/RunInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import org.icpclive.util.DurationInMillisecondsSerializer
import kotlin.time.Duration

@Serializable
data class RunInfo(
public data class RunInfo(
val id: Int,
val result: RunResult?,
val percentage: Double,
Expand All @@ -21,39 +21,37 @@ data class RunInfo(
)

@Serializable
sealed class RunResult
public sealed class RunResult

@Serializable(with = VerdictSerializer::class)
sealed class Verdict(val shortName: String, val isAddingPenalty: Boolean, val isAccepted: Boolean) {
object Accepted: Verdict("AC", false, true)
object Rejected: Verdict("RJ", true, false)
object Fail: Verdict("FL", false, true)
object CompilationError: Verdict("CE", false, false)
object CompilationErrorWithPenalty: Verdict("CE", true, false)
object PresentationError: Verdict("PE", true, false)
object RuntimeError: Verdict("RE", true, false)
object TimeLimitExceeded: Verdict("TL", true, false)
object MemoryLimitExceeded: Verdict("ML", true, false)
object OutputLimitExceeded: Verdict("OL", true, false)
object IdlenessLimitExceeded: Verdict("IL", true, false)
object SecurityViolation: Verdict("SV", true, false)
object Ignored: Verdict("IG", false, false)
object Challenged: Verdict("CH", true, false)
object WrongAnswer: Verdict("WA", true, false)

// We have a separate object here to delay initialization until the function call.
// This allows first fully initialize Verdict subclasses, which is required by LookupHolder constructor
companion object {
val all get() = LookupHolder.all
fun lookup(shortName: String, isAddingPenalty: Boolean, isAccepted: Boolean) =
public sealed class Verdict(public val shortName: String, public val isAddingPenalty: Boolean, public val isAccepted: Boolean) {
public data object Accepted: Verdict("AC", false, true)
public data object Rejected: Verdict("RJ", true, false)
public data object Fail: Verdict("FL", false, true)
public data object CompilationError: Verdict("CE", false, false)
public data object CompilationErrorWithPenalty: Verdict("CE", true, false)
public data object PresentationError: Verdict("PE", true, false)
public data object RuntimeError: Verdict("RE", true, false)
public data object TimeLimitExceeded: Verdict("TL", true, false)
public data object MemoryLimitExceeded: Verdict("ML", true, false)
public data object OutputLimitExceeded: Verdict("OL", true, false)
public data object IdlenessLimitExceeded: Verdict("IL", true, false)
public data object SecurityViolation: Verdict("SV", true, false)
public data object Ignored: Verdict("IG", false, false)
public data object Challenged: Verdict("CH", true, false)
public data object WrongAnswer: Verdict("WA", true, false)

public companion object {
public val all: List<Verdict> get() = LookupHolder.all
public fun lookup(shortName: String, isAddingPenalty: Boolean, isAccepted: Boolean): Verdict =
LookupHolder.lookup(shortName, isAddingPenalty, isAccepted)
}

fun toRunResult() = ICPCRunResult(this, false)
internal fun toRunResult() = ICPCRunResult(this, false)
}


class VerdictSerializer : KSerializer<Verdict> {
internal class VerdictSerializer : KSerializer<Verdict> {
@Serializable
@SerialName("Verdict")
private class VerdictSurrogate(val shortName: String, val isAddingPenalty: Boolean, val isAccepted: Boolean)
Expand All @@ -70,6 +68,8 @@ class VerdictSerializer : KSerializer<Verdict> {
}
}

// We have a separate object here to delay initialization until the function call.
// This allows first fully initializing Verdict subclasses, which is required by LookupHolder constructor
private object LookupHolder {
val all = Verdict::class.sealedSubclasses.map { it.objectInstance!! }

Expand Down Expand Up @@ -106,14 +106,14 @@ private object LookupHolder {

@Serializable
@SerialName("ICPC")
data class ICPCRunResult(
public data class ICPCRunResult(
val verdict: Verdict,
val isFirstToSolveRun: Boolean,
) : RunResult()

@Serializable
@SerialName("IOI")
data class IOIRunResult(
public data class IOIRunResult(
val score: List<Double>,
val wrongVerdict: Verdict? = null,
val difference: Double = 0.0,
Expand Down
12 changes: 6 additions & 6 deletions src/cds/src/main/kotlin/org/icpclive/api/Scoreboard.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import org.icpclive.util.*
import kotlin.time.Duration

@Serializable
enum class OptimismLevel {
public enum class OptimismLevel {
@SerialName("normal")
NORMAL,

Expand All @@ -18,10 +18,10 @@ enum class OptimismLevel {
}

@Serializable
sealed class ProblemResult
public sealed class ProblemResult

@Serializable
data class ScoreboardRow(
public data class ScoreboardRow(
val teamId: Int,
val rank: Int,
val totalScore: Double,
Expand All @@ -37,7 +37,7 @@ data class ScoreboardRow(
//TODO: custom string, maybe something else
@Serializable
@SerialName("ICPC")
data class ICPCProblemResult(
public data class ICPCProblemResult(
val wrongAttempts: Int,
val pendingAttempts: Int,
val isSolved: Boolean,
Expand All @@ -49,7 +49,7 @@ data class ICPCProblemResult(

@Serializable
@SerialName("IOI")
data class IOIProblemResult(
public data class IOIProblemResult(
val score: Double?,
@SerialName("lastSubmitTimeMs")
@Serializable(with = DurationInMillisecondsSerializer::class)
Expand All @@ -58,7 +58,7 @@ data class IOIProblemResult(
) : ProblemResult()

@Serializable
data class Scoreboard(
public data class Scoreboard(
@Serializable(with = DurationInMillisecondsSerializer::class)
val lastSubmitTime: Duration,
val rows: List<ScoreboardRow>
Expand Down
Loading

0 comments on commit bc68e59

Please sign in to comment.