@ -70,6 +70,10 @@ final class Tournament : ModelObject, Storable {
var maximumPlayerPerTeam : Int = 2
var maximumPlayerPerTeam : Int = 2
var information : String ? = nil
var information : String ? = nil
// l o c a l v a r i a b l e
var refreshInProgress : Bool = false
var refreshRanking : Bool = false
@ ObservationIgnored
@ ObservationIgnored
var navigationPath : [ Screen ] = [ ]
var navigationPath : [ Screen ] = [ ]
@ -1513,8 +1517,8 @@ defer {
}
}
}
}
func updateRank ( to newDate : Date ? ) async throws {
func updateRank ( to newDate : Date ? , forceRefreshLockWeight : Bool , providedSources : [ CSVParser ] ? ) async throws {
refreshRanking = true
#if DEBUG_TIME
#if DEBUG_TIME
let start = Date ( )
let start = Date ( )
defer {
defer {
@ -1549,16 +1553,42 @@ defer {
let lastRankMan = monthData ? . maleUnrankedValue ? ? 0
let lastRankMan = monthData ? . maleUnrankedValue ? ? 0
let lastRankWoman = monthData ? . femaleUnrankedValue ? ? 0
let lastRankWoman = monthData ? . femaleUnrankedValue ? ? 0
var chunkedParsers : [ CSVParser ] = [ ]
if let providedSources {
chunkedParsers = providedSources
} else {
// F e t c h o n l y t h e r e q u i r e d f i l e s
// F e t c h o n l y t h e r e q u i r e d f i l e s
let dataURLs = SourceFileManager . shared . allFiles . filter { $0 . dateFromPath = = newDate }
let dataURLs = SourceFileManager . shared . allFiles . filter { $0 . dateFromPath = = newDate }
guard ! dataURLs . isEmpty else { return } // E a r l y r e t u r n i f n o f i l e s f o u n d
guard ! dataURLs . isEmpty else { return } // E a r l y r e t u r n i f n o f i l e s f o u n d
let sources = dataURLs . map { CSVParser ( url : $0 ) }
let sources = dataURLs . map { CSVParser ( url : $0 ) }
chunkedParsers = try await chunkAllSources ( sources : sources , size : 10000 )
}
let players = unsortedPlayers ( )
let players = unsortedPlayers ( )
try await players . concurrentForEach { player in
try await players . concurrentForEach { player in
let lastRank = ( player . sex = = . female ) ? lastRankWoman : lastRankMan
let lastRank = ( player . sex = = . female ) ? lastRankWoman : lastRankMan
try await player . updateRank ( from : sources , lastRank : lastRank )
try await player . updateRank ( from : chunkedParsers , lastRank : lastRank )
player . setComputedRank ( in : self )
}
if providedSources = = nil {
try chunkedParsers . forEach { chunk in
try FileManager . default . removeItem ( at : chunk . url )
}
}
try tournamentStore . playerRegistrations . addOrUpdate ( contentOfs : players )
let unsortedTeams = unsortedTeams ( )
unsortedTeams . forEach { team in
team . setWeight ( from : team . players ( ) , inTournamentCategory : tournamentCategory )
if forceRefreshLockWeight {
team . lockedWeight = team . weight
}
}
}
try tournamentStore . teamRegistrations . addOrUpdate ( contentOfs : unsortedTeams )
refreshRanking = false
}
}
@ -2424,14 +2454,17 @@ defer {
func updateSeedsBracketPosition ( ) async {
func updateSeedsBracketPosition ( ) async {
await removeAllSeeds ( )
await removeAllSeeds ( saveTeamsAtTheEnd : false )
let drawLogs = drawLogs ( ) . reversed ( )
let drawLogs = drawLogs ( ) . reversed ( )
let seeds = seeds ( )
let seeds = seeds ( )
await MainActor . run {
for ( index , seed ) in seeds . enumerated ( ) {
for ( index , seed ) in seeds . enumerated ( ) {
if let drawLog = drawLogs . first ( where : { $0 . drawSeed = = index } ) {
if let drawLog = drawLogs . first ( where : { $0 . drawSeed = = index } ) {
drawLog . updateTeamBracketPosition ( seed )
drawLog . updateTeamBracketPosition ( seed )
}
}
}
}
}
do {
do {
try tournamentStore . teamRegistrations . addOrUpdate ( contentOfs : seeds )
try tournamentStore . teamRegistrations . addOrUpdate ( contentOfs : seeds )
@ -2440,11 +2473,13 @@ defer {
}
}
}
}
func removeAllSeeds ( ) async {
func removeAllSeeds ( saveTeamsAtTheEnd : Bool ) async {
let teams = unsortedTeams ( )
let teams = unsortedTeams ( )
teams . forEach ( { team in
teams . forEach ( { team in
team . bracketPosition = nil
team . bracketPosition = nil
team . _cachedRestingTime = nil
team . _cachedRestingTime = nil
team . finalRanking = nil
team . pointsEarned = nil
} )
} )
let allMatches = allRoundMatches ( )
let allMatches = allRoundMatches ( )
let ts = allMatches . flatMap { match in
let ts = allMatches . flatMap { match in
@ -2471,12 +2506,13 @@ defer {
Logger . error ( error )
Logger . error ( error )
}
}
if saveTeamsAtTheEnd {
do {
do {
try tournamentStore . teamRegistrations . addOrUpdate ( contentOfs : teams )
try tournamentStore . teamRegistrations . addOrUpdate ( contentOfs : teams )
} catch {
} catch {
Logger . error ( error )
Logger . error ( error )
}
}
updateTournamentState ( )
}
}
}
func addNewRound ( _ roundIndex : Int ) async {
func addNewRound ( _ roundIndex : Int ) async {
@ -2608,6 +2644,27 @@ defer {
return false
return false
}
}
func rankSourceShouldBeRefreshed ( ) -> Date ? {
if let mostRecentDate = SourceFileManager . shared . lastDataSourceDate ( ) , let currentRankSourceDate = rankSourceDate , currentRankSourceDate < mostRecentDate , hasEnded ( ) = = false {
return mostRecentDate
} else {
return nil
}
}
func onlineTeams ( ) -> [ TeamRegistration ] {
unsortedTeams ( ) . filter ( { $0 . hasRegisteredOnline ( ) } )
}
func refreshTeamList ( ) async throws {
guard enableOnlineRegistration , refreshInProgress = = false , hasEnded ( ) = = false else { return }
refreshInProgress = true
try await self . tournamentStore . playerRegistrations . loadDataFromServerIfAllowed ( clear : true )
try await self . tournamentStore . teamScores . loadDataFromServerIfAllowed ( clear : true )
try await self . tournamentStore . teamRegistrations . loadDataFromServerIfAllowed ( clear : true )
refreshInProgress = false
}
// MARK: -
// MARK: -
func insertOnServer ( ) throws {
func insertOnServer ( ) throws {