Skip to content

Commit 64d629b

Browse files
authored
Merge pull request #276 from baaahs/patchy-shader-editor
Patch editor now has an inline shader editor.
2 parents 4e85ef8 + fac6c7b commit 64d629b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1385
-1034
lines changed

src/commonMain/kotlin/baaahs/OpenShow.kt

-67
This file was deleted.

src/commonMain/kotlin/baaahs/ShowPlayer.kt

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import baaahs.model.ModelInfo
1010
import baaahs.show.DataSource
1111
import baaahs.show.Shader
1212
import baaahs.show.Show
13+
import baaahs.show.live.OpenShow
1314
import baaahs.show.live.ShowOpener
1415

1516
interface ShowPlayer {

src/commonMain/kotlin/baaahs/ShowRunner.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package baaahs
22

3-
import baaahs.OpenShow.OpenScene.OpenPatchSet
43
import baaahs.glshaders.AutoWirer
54
import baaahs.glshaders.Plugins
65
import baaahs.glsl.GlslRenderer
76
import baaahs.show.Show
7+
import baaahs.show.live.OpenShow
8+
import baaahs.show.live.OpenShow.OpenScene.OpenPatchSet
89

910
class ShowRunner(
1011
val show: Show,

src/commonMain/kotlin/baaahs/ShowState.kt

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package baaahs
22

3-
import baaahs.show.PatchyEditor
43
import baaahs.show.Show
5-
import baaahs.show.ShowEditor
4+
import baaahs.show.live.OpenShow
5+
import baaahs.show.mutable.MutableShow
66
import kotlinx.serialization.Serializable
77
import kotlinx.serialization.Transient
88
import kotlin.math.min
@@ -26,9 +26,9 @@ data class ShowState(
2626
return show.scenes[selectedScene]
2727
}
2828

29-
fun findSceneEditor(showEditor: ShowEditor?): ShowEditor.SceneEditor? {
29+
fun findMutableScene(mutableShow: MutableShow?): MutableShow.MutableScene? {
3030
if (selectedScene == -1) return null
31-
return showEditor?.getSceneEditor(selectedScene)
31+
return mutableShow?.getMutableScene(selectedScene)
3232
}
3333

3434
fun findPatchSet(show: OpenShow): OpenShow.OpenScene.OpenPatchSet? {
@@ -50,11 +50,11 @@ data class ShowState(
5050
return scene.patchSets[selectedPatchSet]
5151
}
5252

53-
fun findPatchSetEditor(showEditor: ShowEditor?): PatchyEditor? {
53+
fun findMutablePatchSet(mutableShow: MutableShow?): MutableShow.MutableScene.MutablePatchSet? {
5454
if (selectedPatchSet == -1) return null
5555

56-
val sceneEditor = findSceneEditor(showEditor)
57-
return sceneEditor?.getPatchSetEditor(selectedPatchSet)
56+
val mutableScene = findMutableScene(mutableShow)
57+
return mutableScene?.getMutablePatchSet(selectedPatchSet)
5858
}
5959

6060
fun selectScene(i: Int) = copy(selectedScene = i)

src/commonMain/kotlin/baaahs/glshaders/AutoWirer.kt

+79-42
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,106 @@
11
package baaahs.glshaders
22

33
import baaahs.Logger
4-
import baaahs.OpenPatch
5-
import baaahs.OpenPatchy
64
import baaahs.show.*
75
import baaahs.show.live.LiveShaderInstance
6+
import baaahs.show.live.OpenPatch
7+
import baaahs.show.live.OpenPatchHolder
8+
import baaahs.show.mutable.*
89
import baaahs.unknown
910

1011
class AutoWirer(val plugins: Plugins) {
1112
private val glslAnalyzer = GlslAnalyzer()
1213

13-
fun autoWire(vararg shaders: Shader): UnresolvedPatchEditor {
14-
return autoWire(shaders.map { glslAnalyzer.asShader(it.src) })
14+
fun autoWire(
15+
vararg shaders: Shader,
16+
focus: Shader? = null
17+
): UnresolvedPatch {
18+
val openShaders = shaders.associate { it to glslAnalyzer.asShader(it.src) }
19+
return autoWire(openShaders.values, focus?.let { openShaders[it] })
1520
}
1621

17-
fun autoWire(vararg shaders: OpenShader): UnresolvedPatchEditor {
18-
return autoWire(shaders.toList())
22+
fun autoWire(
23+
vararg shaders: OpenShader,
24+
focus: OpenShader? = null
25+
): UnresolvedPatch {
26+
return autoWire(shaders.toList(), focus)
1927
}
2028

21-
fun autoWire(shaders: List<OpenShader>, shaderChannel: ShaderChannel = ShaderChannel.Main): UnresolvedPatchEditor {
22-
val locallyAvailable: MutableMap<ContentType, MutableList<LinkEditor.Port>> = mutableMapOf()
29+
fun autoWire(
30+
shaders: Collection<OpenShader>,
31+
focus: OpenShader? = null,
32+
shaderChannel: ShaderChannel = ShaderChannel.Main
33+
): UnresolvedPatch {
34+
val locallyAvailable: MutableMap<ContentType, MutableSet<MutableLink.Port>> = mutableMapOf()
2335

2436
// First pass: gather shader output ports.
2537
val shaderInstances = shaders.associate { openShader ->
26-
val unresolvedShaderInstance = UnresolvedShaderInstanceEditor(
27-
ShaderEditor(openShader.shader),
28-
openShader.inputPorts.map { it.id }.associateWith { arrayListOf<LinkEditor.Port>() },
38+
val unresolvedShaderInstance = UnresolvedShaderInstance(
39+
MutableShader(openShader.shader),
40+
openShader.inputPorts.map { it.id }.associateWith { hashSetOf<MutableLink.Port>() },
2941
shaderChannel
3042
)
3143

32-
locallyAvailable.getOrPut(openShader.outputPort.contentType) { mutableListOf() }
33-
.add(UnresolvedShaderOutPortEditor(unresolvedShaderInstance, openShader.outputPort.id))
44+
locallyAvailable.getOrPut(openShader.outputPort.contentType) { mutableSetOf() }
45+
.add(UnresolvedShaderOutPort(unresolvedShaderInstance, openShader.outputPort.id))
3446

3547
openShader.shaderType.defaultUpstreams.forEach { (contentType, shaderChannel) ->
36-
locallyAvailable.getOrPut(contentType) { mutableListOf() }
37-
.add(ShaderChannelEditor(shaderChannel))
48+
locallyAvailable.getOrPut(contentType) { mutableSetOf() }
49+
.add(MutableShaderChannel(shaderChannel))
3850
}
3951

4052
openShader to unresolvedShaderInstance
4153
}
4254

4355
// Second pass: link datasources/output ports to input ports.
56+
val shaderInstancesOfInterest = if (focus == null) {
57+
shaderInstances
58+
} else {
59+
mapOf(focus to (shaderInstances[focus] ?: error("missing shader editor?")))
60+
}
61+
4462
val dataSources = hashSetOf<DataSource>()
45-
val unresolvedShaderInstances = shaderInstances.map { (openShader, unresolvedShaderInstance) ->
63+
val unresolvedShaderInstances = shaderInstancesOfInterest.map { (openShader, unresolvedShaderInstance) ->
4664
openShader.inputPorts.forEach { inputPort ->
47-
val localSuggestions: List<LinkEditor.Port>? = locallyAvailable[inputPort.contentType]
65+
val localSuggestions: Set<MutableLink.Port>? = locallyAvailable[inputPort.contentType]
4866
val suggestions = localSuggestions ?: plugins.suggestDataSources(inputPort).map {
4967
dataSources.add(it)
50-
DataSourceEditor(it)
68+
MutableDataSource(it)
5169
}
5270
unresolvedShaderInstance.incomingLinksOptions[inputPort.id]!!.addAll(suggestions)
5371
}
5472
unresolvedShaderInstance
5573
}
56-
return UnresolvedPatchEditor(unresolvedShaderInstances, dataSources.toList())
74+
return UnresolvedPatch(unresolvedShaderInstances, dataSources.toList())
5775
}
5876

59-
data class UnresolvedShaderOutPortEditor(
60-
val unresolvedShaderInstance: UnresolvedShaderInstanceEditor,
77+
data class UnresolvedShaderOutPort(
78+
val unresolvedShaderInstance: UnresolvedShaderInstance,
6179
val portId: String
62-
) : LinkEditor.Port {
80+
) : MutableLink.Port {
6381
override fun toRef(showBuilder: ShowBuilder): PortRef = TODO("not implemented")
6482
override fun displayName(): String = TODO("not implemented")
6583
}
6684

67-
data class UnresolvedShaderInstanceEditor(
68-
val shader: ShaderEditor,
69-
val incomingLinksOptions: Map<String, MutableList<LinkEditor.Port>>,
85+
data class UnresolvedShaderInstance(
86+
val mutableShader: MutableShader,
87+
val incomingLinksOptions: Map<String, MutableSet<MutableLink.Port>>,
7088
var shaderChannel: ShaderChannel? = null
7189
) {
7290
fun isAmbiguous() = incomingLinksOptions.values.any { it.size > 1 }
7391

92+
fun describeAmbiguity(): String {
93+
return mutableShader.title + ": " +
94+
incomingLinksOptions
95+
.filter { (_, links) -> links.size > 1 }
96+
.map { (portId, links) ->
97+
"$portId->(${links.joinToString(",") { it.displayName() }}"
98+
}
99+
}
100+
74101
fun acceptSymbolicChannelLinks() {
75102
incomingLinksOptions.values.forEach { options ->
76-
val shaderChannelOptions = options.filterIsInstance<ShaderChannelEditor>()
103+
val shaderChannelOptions = options.filterIsInstance<MutableShaderChannel>()
77104
if (options.size > 1 && shaderChannelOptions.size == 1) {
78105
options.clear()
79106
options.add(shaderChannelOptions.first())
@@ -82,10 +109,10 @@ class AutoWirer(val plugins: Plugins) {
82109
}
83110
}
84111

85-
fun merge(vararg patchies: OpenPatchy): Map<Surfaces, LinkedPatch> {
112+
fun merge(vararg patchHolders: OpenPatchHolder): Map<Surfaces, LinkedPatch> {
86113
val patchesBySurfaces = mutableMapOf<Surfaces, MutableList<OpenPatch>>()
87-
patchies.forEach { openPatchy ->
88-
openPatchy.patches.forEach { patch ->
114+
patchHolders.forEach { openPatchHolder ->
115+
openPatchHolder.patches.forEach { patch ->
89116
patchesBySurfaces.getOrPut(patch.surfaces) { arrayListOf() }
90117
.add(patch)
91118
}
@@ -119,7 +146,7 @@ class AutoWirer(val plugins: Plugins) {
119146
class PortDiagram {
120147
private var surfaces: Surfaces? = null
121148
private var level = 0
122-
private val patchEditor = PatchEditor()
149+
private val mutablePatch = MutablePatch()
123150
private val candidates = hashMapOf<Pair<ShaderChannel, ContentType>, MutableList<ChannelEntry>>()
124151
private val resolved = hashMapOf<Pair<ShaderChannel, ContentType>, LiveShaderInstance>()
125152

@@ -131,7 +158,7 @@ class AutoWirer(val plugins: Plugins) {
131158
fun add(patch: OpenPatch) {
132159
if (surfaces == null) {
133160
surfaces = patch.surfaces
134-
patchEditor.surfaces = patch.surfaces
161+
mutablePatch.surfaces = patch.surfaces
135162
} else if (surfaces != patch.surfaces) {
136163
error("Surface mismatch: $surfaces != ${patch.surfaces}")
137164
}
@@ -205,21 +232,25 @@ class AutoWirer(val plugins: Plugins) {
205232
}
206233
}
207234

208-
data class UnresolvedPatchEditor(
209-
private val unresolvedShaderInstances: List<UnresolvedShaderInstanceEditor>,
235+
data class UnresolvedPatch(
236+
private val unresolvedShaderInstances: List<UnresolvedShaderInstance>,
210237
private val dataSources: List<DataSource>
211238
) {
212239
fun isAmbiguous() = unresolvedShaderInstances.any { it.isAmbiguous() }
213240

214-
fun resolve(): PatchEditor {
241+
fun resolve(): MutablePatch {
215242
if (isAmbiguous()) {
216-
error("ambiguous! ${unresolvedShaderInstances.filter { it.isAmbiguous() }}")
243+
error("ambiguous! " +
244+
unresolvedShaderInstances
245+
.filter { it.isAmbiguous() }
246+
.map { it.describeAmbiguity() }
247+
)
217248
}
218249

219250
// First pass: create a shader instance editor for each shader.
220251
val shaderInstances = unresolvedShaderInstances.associate {
221-
it.shader.shader to ShaderInstanceEditor(
222-
it.shader,
252+
it.mutableShader.shader to MutableShaderInstance(
253+
it.mutableShader,
223254
it.incomingLinksOptions.mapValues { (_, fromPortOptions) ->
224255
fromPortOptions.first()
225256
}.toMutableMap(),
@@ -230,20 +261,26 @@ class AutoWirer(val plugins: Plugins) {
230261
// Second pass: resolve references between shaders to the correct instance editor.
231262
shaderInstances.values.forEach { shaderInstance ->
232263
shaderInstance.incomingLinks.forEach { (toPortId, fromPort) ->
233-
if (fromPort is UnresolvedShaderOutPortEditor) {
234-
val fromShader = fromPort.unresolvedShaderInstance.shader.shader
264+
if (fromPort is UnresolvedShaderOutPort) {
265+
val fromShader = fromPort.unresolvedShaderInstance.mutableShader.shader
235266
val fromShaderInstance = shaderInstances[fromShader]
236267
?: error(unknown("shader instance editor", fromShader, shaderInstances.keys))
237268
shaderInstance.incomingLinks[toPortId] =
238-
ShaderOutPortEditor(fromShaderInstance, fromPort.portId)
269+
MutableShaderOutPort(
270+
fromShaderInstance,
271+
fromPort.portId
272+
)
239273
}
240274
}
241275
}
242276

243-
return PatchEditor(shaderInstances.values.toList(), Surfaces.AllSurfaces)
277+
return MutablePatch(
278+
shaderInstances.values.toList(),
279+
Surfaces.AllSurfaces
280+
)
244281
}
245282

246-
fun acceptSymbolicChannelLinks(): UnresolvedPatchEditor {
283+
fun acceptSymbolicChannelLinks(): UnresolvedPatch {
247284
unresolvedShaderInstances.forEach { it.acceptSymbolicChannelLinks() }
248285
return this
249286
}

0 commit comments

Comments
 (0)