@@ -58,6 +58,7 @@ import utils.className
5858import utils.runningHistory
5959import utils.runningHistoryNotNull
6060import kotlin.math.roundToInt
61+ import kotlin.random.Random
6162import kotlin.time.Duration.Companion.milliseconds
6263import kotlin.time.Duration.Companion.seconds
6364
@@ -318,6 +319,7 @@ class Deck(
318319
319320 val presetSwitching = PresetSwitching ()
320321
322+ private val random = Random (42 )
321323
322324 suspend fun startFlows () {
323325 logger.info { " starting coroutines for $deckName " }
@@ -360,7 +362,8 @@ class Deck(
360362 inner class Search {
361363
362364 val label = MutableStateFlow <String ?>(null )
363- // val enabledFragments = MutableStateFlow<Set<String>>(emptySet())
365+
366+ // val enabledFragments = MutableStateFlow<Set<String>>(emptySet())
364367 private val currentMutable = MutableStateFlow <PresetPlaylist ?>(null )
365368 val current = currentMutable.asStateFlow()
366369
@@ -450,63 +453,102 @@ class Deck(
450453 val score = search.score(tags)
451454// val preset = presets[key]
452455 if (score > 0.0 ) {
453- preset to ( score)
456+ preset to score
454457 } else {
455458 null
456459 }
457- }.toMap()
460+ }// .toMap()
458461
459- val folder = queueFolder.resolve(" deck_$id " ).also {
462+ queueFolder.resolve(" deck_$id " ).also {
460463 it.mkdirs()
461- }
462- folder.listFiles()?.forEach { it.deleteRecursively() }
463-
464- filtered.mapValues { it.value }.forEach { (location, weight) ->
465- val presetFile = presetsFolder.resolve(location.path)
466- val previewFile = presetsFolder.resolve(location.previewPath)
467- if (weight == 1 ) {
468- val targetFolder = folder.resolve(location.path).parentFile!!
469- targetFolder.mkdirs()
470- targetFolder.resolve(presetFile.name).also {
471- presetFile.copyTo(it)
472- }
473- targetFolder.resolve(previewFile.name).also {
474- previewFile.copyTo(it)
475- }
476- } else {
477- repeat(weight) { i ->
478- val targetFolder = folder
479- .resolve(location.path).parentFile!!
480- .resolve(" ${location.name} _$i " )
464+ }.let { folder ->
465+
466+ folder.listFiles()?.forEach { it.deleteRecursively() }
467+
468+ filtered
469+ .toList()
470+ .ifEmpty {
471+ logger.warn { " $deckName search resulted in empty result, falling back to default presets to avoid bugs" }
472+ presets.values.filter {
473+ it.categoryPath.last() == " ! Transition"
474+ }.map { it to 1 }
475+ }.forEach { (location, weight) ->
476+ val presetFile = presetsFolder.resolve(location.path)
477+ val previewFile = presetsFolder.resolve(location.previewPath)
478+ if (weight == 1 ) {
479+ val targetFolder = folder.resolve(location.path).parentFile!!
481480 targetFolder.mkdirs()
482481 targetFolder.resolve(presetFile.name).also {
483482 presetFile.copyTo(it)
484483 }
485484 targetFolder.resolve(previewFile.name).also {
486485 previewFile.copyTo(it)
487486 }
487+ } else {
488+ repeat(weight) { i ->
489+ val targetFolder = folder
490+ .resolve(location.path).parentFile!!
491+ .resolve(" ${location.name} _$i " )
492+ targetFolder.mkdirs()
493+ targetFolder.resolve(presetFile.name).also {
494+ presetFile.copyTo(it)
495+ }
496+ targetFolder.resolve(previewFile.name).also {
497+ previewFile.copyTo(it)
498+ }
499+ }
488500 }
489501 }
502+ nestdropPortSend(
503+ OSCMessage (" /Queue/<${folder.name} >/Refresh" , 1 )
504+ )
490505 }
491- if (filtered.isEmpty()) {
492- presets.values.filter {
493- it.categoryPath.last() == " ! Transition "
494- }.forEach { location ->
495- val presetFile = presetsFolder.resolve(location.path)
496- val previewFile = presetsFolder.resolve(location.previewPath)
497- val targetFolder = folder.resolve(location.path).parentFile !!
498- targetFolder.mkdirs ()
499- targetFolder.resolve(presetFile.name). also {
500- presetFile.copyTo(it)
506+
507+ queueFolder.resolve( " deck_ ${id} _randomized " ). also {
508+ it.mkdirs()
509+ }. let { folder ->
510+ folder.listFiles()?.forEach { it.deleteRecursively() }
511+
512+ val randomizedPresets = filtered
513+ .toList ()
514+ .flatMap { (location, weight) ->
515+ List (weight) { location }
501516 }
502- targetFolder.resolve(previewFile.name).also {
503- previewFile.copyTo(it)
517+ .ifEmpty {
518+ logger.warn { " $deckName search resulted in empty result, falling back to default presets to avoid bugs" }
519+ presets.values.filter {
520+ it.categoryPath.last() == " ! Transition"
521+ }
504522 }
523+ .shuffled(random)
524+
525+ val prefixLength = when (randomizedPresets.size) {
526+ in 0 .. 9 -> 1
527+ in 10 .. 99 -> 2
528+ in 100 .. 999 -> 3
529+ in 1000 .. 9999 -> 4
530+ else -> 5
505531 }
532+ randomizedPresets
533+ .forEachIndexed { i, location ->
534+ val presetFile = presetsFolder.resolve(location.path)
535+ val previewFile = presetsFolder.resolve(location.previewPath)
536+ val prefix = i.toString().padStart(prefixLength, ' 0' )
537+ val targetFolder = folder.resolve(" $prefix - ${location.name} " )
538+
539+ targetFolder.mkdirs()
540+ targetFolder.resolve(presetFile.name).also {
541+ presetFile.copyTo(it)
542+ }
543+ targetFolder.resolve(previewFile.name).also {
544+ previewFile.copyTo(it)
545+ }
546+ }
547+
548+ nestdropPortSend(
549+ OSCMessage (" /Queue/<${folder.name} >/Refresh" , 1 )
550+ )
506551 }
507- nestdropPortSend(
508- OSCMessage (" /Queue/<${folder.name} >/Refresh" , 1 )
509- )
510552 }
511553 .flowOn(Dispatchers .IO )
512554 .launchIn(flowScope)
0 commit comments