Skip to content

Commit d4cebfb

Browse files
committed
more fixes and improvements
1 parent 7649776 commit d4cebfb

File tree

7 files changed

+226
-195
lines changed

7 files changed

+226
-195
lines changed

src/desktopMain/kotlin/Main.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ import kotlinx.coroutines.FlowPreview
3535
import kotlinx.coroutines.debug.CoroutinesBlockHoundIntegration
3636
import kotlinx.coroutines.delay
3737
import kotlinx.coroutines.flow.debounce
38+
import kotlinx.coroutines.flow.distinctUntilChanged
3839
import kotlinx.coroutines.flow.flowOn
3940
import kotlinx.coroutines.flow.launchIn
41+
import kotlinx.coroutines.flow.map
4042
import kotlinx.coroutines.flow.merge
4143
import kotlinx.coroutines.flow.onEach
4244
import kotlinx.coroutines.launch
@@ -51,13 +53,17 @@ import nestdrop.loadNestdropConfig
5153
import nestdrop.setupSpriteFX
5254
import nestdrop.watchNestdropConfig
5355
import org.jetbrains.compose.resources.painterResource
56+
import osc.nestdropListenAddress
57+
import osc.nestdropSendAddress
5458
import osc.runNestDropSend
5559
import osc.startNestdropOSC
5660
import reactor.blockhound.BlockHound
5761
import tags.startTagsFileWatcher
5862
import ui.App
5963
import ui.components.verticalScroll
6064
import utils.className
65+
import java.net.InetAddress
66+
import java.net.InetSocketAddress
6167
import java.text.SimpleDateFormat
6268
import java.util.*
6369
import kotlin.time.Duration.Companion.milliseconds
@@ -177,6 +183,26 @@ object Main {
177183
loadNestdropConfig(nestdropSettings, queues, decks)
178184
}
179185
.launchIn(flowScope)
186+
187+
nestdropSettingsState.map { it.mainWindow.settingsGeneral.oscPort }
188+
.distinctUntilChanged()
189+
.onEach { oscPort ->
190+
nestdropSendAddress.value = InetSocketAddress(
191+
InetAddress.getLoopbackAddress(),
192+
oscPort
193+
)
194+
}
195+
.launchIn(flowScope)
196+
197+
nestdropSettingsState.map { it.mainWindow.settingsGeneral.oscOutputPort }
198+
.distinctUntilChanged()
199+
.onEach { oscOutputPort ->
200+
nestdropListenAddress.value = InetSocketAddress(
201+
InetAddress.getLoopbackAddress(),
202+
oscOutputPort
203+
)
204+
}
205+
.launchIn(flowScope)
180206
}
181207

182208

Lines changed: 138 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,137 +1,138 @@
1-
package nestdrop
2-
3-
import com.illposed.osc.OSCMessage
4-
import com.illposed.osc.OSCPacket
5-
import flowScope
6-
import io.github.oshai.kotlinlogging.KotlinLogging
7-
import kotlinx.coroutines.channels.Channel
8-
import kotlinx.coroutines.delay
9-
import kotlinx.coroutines.flow.StateFlow
10-
import kotlinx.coroutines.flow.combine
11-
import kotlinx.coroutines.flow.consumeAsFlow
12-
import kotlinx.coroutines.flow.filterNotNull
13-
import kotlinx.coroutines.flow.launchIn
14-
import nestdrop.deck.Deck
15-
16-
sealed interface PresetIdState {
17-
// val queue: Queue<out Preset>? get() = null
18-
val index: Int? get() = null
19-
20-
data class Data(
21-
override val index: Int,
22-
val force: Boolean = false,
23-
// val hardCut: Boolean = false,
24-
) : PresetIdState
25-
26-
data object Unset : PresetIdState
27-
}
28-
29-
30-
class NestdropSpriteQueue(
31-
private val nestdropSendChannel: Channel<OSCPacket>,
32-
private val spoutStateMap: StateFlow<Map<String, Deck.SpriteKey>>,
33-
private val queue: StateFlow<Queue<out Preset>?>,
34-
) {
35-
companion object {
36-
private val logger = KotlinLogging.logger { }
37-
}
38-
39-
private val channel: Channel<PresetIdState> = Channel()
40-
41-
suspend fun send(
42-
state: PresetIdState
43-
) {
44-
channel.send(state)
45-
}
46-
47-
private suspend fun presetId(queue: Queue<out Preset>, index: Int?, overlay: Boolean = false) {
48-
if (index == null) {
49-
logger.warn { "failed to find sprite id" }
50-
return
51-
}
52-
logger.debug { "setting index $index on ${queue.name} (/Queue/${queue.name}/ActIdx/$index)" }
53-
// logger.debug { "setting presetId $index on ${queue.name} (\"/PresetID/${queue.name}/$id\")" }
54-
nestdropSendChannel.send(
55-
OSCMessage(
56-
// /PresetID/spout_1/15879 or /Queue/spout_1/ActIdx/0
57-
"/Queue/${queue.name}/ActIdx/$index",
58-
// "/PresetID/${queue.name}/$id",
59-
// "/PresetID/$id",
60-
listOf(
61-
if (overlay) 0 else 1
62-
)
63-
)
64-
)
65-
}
66-
67-
suspend fun startFlows() {
68-
channel
69-
.consumeAsFlow()
70-
// .runningHistory(PresetIdState.Unset)
71-
// .filterNotNull()
72-
.combine(
73-
queue.filterNotNull()
74-
) { current, queue ->
75-
val currentActive = spoutStateMap.value.values.toSet()
76-
// logger.warnF { "previous: $previous" }
77-
// logger.warnF { "current: $current" }
78-
// if (previous != null) {
79-
when (current) {
80-
is PresetIdState.Unset -> {
81-
currentActive.forEach { key ->
82-
logger.debug { "unsetting previous sprite $key" }
83-
presetId(
84-
queue = queue,
85-
index = queue.presets.indexOfFirst { preset ->
86-
preset.name == key.name && when(preset) {
87-
is Preset.Sprite -> {
88-
preset.effects == key.fx
89-
}
90-
else -> true
91-
}
92-
93-
},
94-
overlay = false
95-
)
96-
}
97-
}
98-
99-
is PresetIdState.Data -> {
100-
// require(current.queue.name == queue.name) { "queue does not match" }
101-
if (current.force) {
102-
logger.debug { "force setting sprite" }
103-
presetId(
104-
queue = queue,
105-
index = (current.index + 1) % queue.presets.size,
106-
overlay = false
107-
)
108-
delay(25)
109-
presetId(queue, current.index, overlay = false)
110-
} else {
111-
val presetName = queue.presets.getOrNull(current.index)
112-
if (currentActive.any { it.id == current.index }) {
113-
logger.info { "ND: received same preset id again, doing nothing" }
114-
// logger.info { "ND: received same preset id again, resetting ${queue.name} to $presetName" }
115-
// presetId(
116-
// queue = queue,
117-
// index = (current.index + 1) % queue.presets.size,
118-
//// current.queue.presets.first { it.id != current.id }.id,
119-
// overlay = false
120-
// )
121-
// delay(50)
122-
// presetId(queue, current.index, overlay = false)
123-
} else {
124-
logger.info { "ND: switching ${queue.name} to '$presetName'" }
125-
presetId(queue, current.index, overlay = false)
126-
}
127-
128-
}
129-
}
130-
}
131-
132-
}
133-
.launchIn(flowScope)
134-
}
135-
136-
}
137-
1+
package nestdrop
2+
3+
import com.illposed.osc.OSCMessage
4+
import com.illposed.osc.OSCPacket
5+
import flowScope
6+
import io.github.oshai.kotlinlogging.KotlinLogging
7+
import kotlinx.coroutines.channels.Channel
8+
import kotlinx.coroutines.delay
9+
import kotlinx.coroutines.flow.StateFlow
10+
import kotlinx.coroutines.flow.combine
11+
import kotlinx.coroutines.flow.consumeAsFlow
12+
import kotlinx.coroutines.flow.filterNotNull
13+
import kotlinx.coroutines.flow.launchIn
14+
import nestdrop.deck.Deck
15+
16+
sealed interface PresetIdState {
17+
// val queue: Queue<out Preset>? get() = null
18+
val index: Int? get() = null
19+
20+
data class Data(
21+
override val index: Int,
22+
val force: Boolean = false,
23+
// val hardCut: Boolean = false,
24+
) : PresetIdState
25+
26+
data object Unset : PresetIdState
27+
}
28+
29+
30+
class NestdropSpriteQueue(
31+
private val nestdropSendChannel: Channel<OSCPacket>,
32+
private val spoutStateMap: StateFlow<Map<String, Deck.SpriteKey>>,
33+
private val queue: StateFlow<Queue<out Preset>?>,
34+
private val matchFx: Boolean = true,
35+
) {
36+
companion object {
37+
private val logger = KotlinLogging.logger { }
38+
}
39+
40+
private val channel: Channel<PresetIdState> = Channel()
41+
42+
suspend fun send(
43+
state: PresetIdState
44+
) {
45+
channel.send(state)
46+
}
47+
48+
private suspend fun presetId(queue: Queue<out Preset>, index: Int?, overlay: Boolean = false) {
49+
if (index == null) {
50+
logger.warn { "failed to find sprite id" }
51+
return
52+
}
53+
logger.debug { "setting index $index on ${queue.name} (/Queue/${queue.name}/ActIdx/$index)" }
54+
// logger.debug { "setting presetId $index on ${queue.name} (\"/PresetID/${queue.name}/$id\")" }
55+
nestdropSendChannel.send(
56+
OSCMessage(
57+
// /PresetID/spout_1/15879 or /Queue/spout_1/ActIdx/0
58+
"/Queue/${queue.name}/ActIdx/$index",
59+
// "/PresetID/${queue.name}/$id",
60+
// "/PresetID/$id",
61+
listOf(
62+
if (overlay) 0 else 1
63+
)
64+
)
65+
)
66+
}
67+
68+
suspend fun startFlows() {
69+
channel
70+
.consumeAsFlow()
71+
// .runningHistory(PresetIdState.Unset)
72+
// .filterNotNull()
73+
.combine(
74+
queue.filterNotNull()
75+
) { current, queue ->
76+
val currentActive = spoutStateMap.value.values.toSet()
77+
// logger.warnF { "previous: $previous" }
78+
// logger.warnF { "current: $current" }
79+
// if (previous != null) {
80+
when (current) {
81+
is PresetIdState.Unset -> {
82+
currentActive.forEach { key ->
83+
logger.debug { "unsetting previous sprite $key" }
84+
presetId(
85+
queue = queue,
86+
index = queue.presets.indexOfFirst { preset ->
87+
preset.name == key.name && if(!matchFx) true else when(preset) {
88+
is Preset.Sprite -> {
89+
preset.effects == key.fx
90+
}
91+
else -> true
92+
}
93+
94+
},
95+
overlay = false
96+
)
97+
}
98+
}
99+
100+
is PresetIdState.Data -> {
101+
// require(current.queue.name == queue.name) { "queue does not match" }
102+
if (current.force) {
103+
logger.debug { "force setting sprite" }
104+
presetId(
105+
queue = queue,
106+
index = (current.index + 1) % queue.presets.size,
107+
overlay = false
108+
)
109+
delay(25)
110+
presetId(queue, current.index, overlay = false)
111+
} else {
112+
val presetName = queue.presets.getOrNull(current.index)
113+
if (currentActive.any { it.id == current.index }) {
114+
logger.info { "ND: received same preset id again, doing nothing" }
115+
// logger.info { "ND: received same preset id again, resetting ${queue.name} to $presetName" }
116+
// presetId(
117+
// queue = queue,
118+
// index = (current.index + 1) % queue.presets.size,
119+
//// current.queue.presets.first { it.id != current.id }.id,
120+
// overlay = false
121+
// )
122+
// delay(50)
123+
// presetId(queue, current.index, overlay = false)
124+
} else {
125+
logger.info { "ND: switching ${queue.name} to '$presetName'" }
126+
presetId(queue, current.index, overlay = false)
127+
}
128+
129+
}
130+
}
131+
}
132+
133+
}
134+
.launchIn(flowScope)
135+
}
136+
137+
}
138+

src/desktopMain/kotlin/nestdrop/XmlDataClasses.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ data class NestdropSettings(
114114
@SerialName("OscPort")
115115
val oscPort: Int = 8000,
116116
@SerialName("OscOutputPort")
117-
val oscOutputPort: String,
117+
val oscOutputPort: Int,
118118
@SerialName("OscOutputIp")
119119
val oscOutputIp: String, // = "127.0.0.1",
120120
@SerialName("AutoChangeInstant")

0 commit comments

Comments
 (0)