1
1
using AngleSharp . Dom ;
2
2
using KristofferStrube . Blazor . SVGEditor ;
3
- using KristofferStrube . Blazor . SVGEditor . Extensions ;
4
3
using Microsoft . AspNetCore . Components . Web ;
5
4
6
5
namespace KristofferStrube . Blazor . WebAudio . WasmExample . AudioEditor ;
@@ -20,111 +19,111 @@ public Connector(IElement element, SVGEditor.SVGEditor svg) : base(element, svg)
20
19
21
20
public override string StateRepresentation => base . StateRepresentation + IsHovered . ToString ( ) ;
22
21
23
- private ( Node node , ulong port ) ? from ;
24
- public ( Node node , ulong port ) ? From
22
+ private Node ? from ;
23
+ public Node ? From
25
24
{
26
25
get
27
26
{
27
+ // If not previous loaded, then load from attributes and connect node-node or node-audioparam pairs that it connects.
28
28
if ( from is null )
29
29
{
30
30
var fromNode = ( Node ? ) SVG . Elements . FirstOrDefault ( e => e is Node && e . Id == Element . GetAttribute ( "data-from-node" ) ) ;
31
- ulong fromPort = ( ulong ) Element . GetAttributeOrZero ( "data-from-port" ) ;
32
- _ = fromNode ? . OutgoingConnectors . Add ( ( this , fromPort ) ) ;
31
+ _ = fromNode ? . OutgoingConnectors . Add ( this ) ;
33
32
if ( fromNode is null )
34
33
{
35
34
return null ;
36
35
}
37
36
38
- if ( To is { } to )
39
- {
40
- QueuedTasks . Enqueue ( async context => await ( await fromNode . AudioNode ( context ) ) . ConnectAsync ( await to . node . AudioNode ( context ) , fromPort , to . port ) ) ;
41
- }
42
- from = ( fromNode , fromPort ) ;
37
+ QueueConnect ( fromNode , To ) ;
38
+
39
+ from = fromNode ;
43
40
}
44
41
return from ;
45
42
}
46
43
set
47
44
{
48
- if ( from is { } previousValue )
49
- {
50
- _ = previousValue . node . OutgoingConnectors . Remove ( ( this , previousValue . port ) ) ;
51
- QueuedTasks . Enqueue ( async context => await ( await previousValue . node . AudioNode ( context ) ) . DisconnectAsync ( previousValue . port ) ) ;
52
- }
45
+ // We don't support updating the from-node to some new value.
46
+
47
+ // If the new value if null then remove its attribute
53
48
if ( value is null )
54
49
{
55
50
_ = Element . RemoveAttribute ( "data-from-node" ) ;
56
- _ = Element . RemoveAttribute ( "data-from-port" ) ;
57
51
from = null ;
58
52
}
59
- else
53
+ else // If it is actually a new value
60
54
{
61
- Element . SetAttribute ( "data-from-node" , value . Value . node . Id ) ;
62
- Element . SetAttribute ( "data-from-port" , value . Value . port . ToString ( ) ) ;
55
+ Element . SetAttribute ( "data-from-node" , value . Id ) ;
63
56
from = value ;
64
- _ = value . Value . node . OutgoingConnectors . Add ( ( this , value . Value . port ) ) ;
65
- if ( To is { } to )
57
+ if ( value is { } newNode )
66
58
{
67
- QueuedTasks . Enqueue ( async context => await ( await value . Value . node . AudioNode ( context ) ) . ConnectAsync ( await to . node . AudioNode ( context ) , value . Value . port , to . port ) ) ;
59
+ _ = value . OutgoingConnectors . Add ( this ) ;
60
+
61
+ QueueConnect ( newNode , To ) ;
68
62
}
69
63
}
70
64
Changed ? . Invoke ( this ) ;
71
65
}
72
66
}
73
67
74
- private ( Node node , ulong port , AudioParam ? param ) ? to ;
75
- public ( Node node , ulong port , AudioParam ? param ) ? To
68
+ private ( Node node , string ? audioParamIdentifier ) ? to ;
69
+ public ( Node node , string ? audioParamIdentifier ) ? To
76
70
{
77
71
get
78
72
{
73
+ // If not previous loaded, then load from attributes.
79
74
if ( to is null )
80
75
{
81
76
var toNode = ( Node ? ) SVG . Elements . FirstOrDefault ( e => e is Node && e . Id == Element . GetAttribute ( "data-to-node" ) ) ;
82
- ulong toPort = ( ulong ) Element . GetAttributeOrZero ( "data-to-port" ) ;
83
- AudioParam ? toAudioParam = null ;
84
- if ( Element . GetAttribute ( "data-to-audioparam" ) is { } toAttribute )
85
- {
86
- _ = ( toNode ? . AudioParams . TryGetValue ( toAttribute , out toAudioParam ) ) ;
87
- }
88
- _ = toNode ? . OutgoingConnectors . Add ( ( this , toPort ) ) ;
89
- to = toNode is null ? null : ( toNode , toPort , toAudioParam ) ;
77
+
78
+ string ? audioParamIdentifier = Element . GetAttribute ( "data-to-audioparam" ) ;
79
+
80
+ _ = toNode ? . IngoingConnectors . Add ( this ) ;
81
+
82
+ to = toNode is null ? null : ( toNode , audioParamIdentifier ) ;
90
83
}
91
84
return to ;
92
85
}
93
86
set
94
87
{
95
- if ( to is { } previousValue )
88
+ // We don't support updating the to-node to some new value.
89
+
90
+ if ( value is { } newValue ) // If it is actually a new value
96
91
{
97
- _ = previousValue . node . IngoingConnectors . Remove ( ( this , previousValue . port ) ) ;
98
- if ( from is { } previouvFromValue )
92
+ Element . SetAttribute ( "data-to-node" , newValue . node . Id ) ;
93
+
94
+ if ( newValue . audioParamIdentifier is not null )
95
+ {
96
+ Element . SetAttribute ( "data-to-audioparam" , newValue . audioParamIdentifier ) ;
97
+ }
98
+
99
+ to = value ;
100
+ _ = newValue . node . IngoingConnectors . Add ( this ) ;
101
+ if ( From is not null )
99
102
{
100
- QueuedTasks . Enqueue ( async context => await ( await previouvFromValue . node . AudioNode ( context ) ) . DisconnectAsync ( previouvFromValue . port ) ) ;
103
+ QueueConnect ( From , newValue ) ;
101
104
}
102
105
}
103
- if ( value is null )
106
+ else // If the new value if null then remove its attribute
104
107
{
105
108
_ = Element . RemoveAttribute ( "data-to-node" ) ;
106
- _ = Element . RemoveAttribute ( "data-to-port" ) ;
107
109
to = null ;
108
110
}
111
+ Changed ? . Invoke ( this ) ;
112
+ }
113
+ }
114
+
115
+ private void QueueConnect ( Node fromNode , ( Node node , string ? audioParamIdentifier ) ? to )
116
+ {
117
+ if ( to is { node : { } toNode } )
118
+ {
119
+ if ( to is { audioParamIdentifier : { } paramIdentifier } )
120
+ {
121
+ QueuedTasks . Enqueue ( async context => await ( await fromNode . AudioNode ( context ) ) . ConnectAsync ( await toNode . AudioParams [ paramIdentifier ] ( context ) ) ) ;
122
+ }
109
123
else
110
124
{
111
- Element . SetAttribute ( "data-to-node" , value . Value . node . Id ) ;
112
- Element . SetAttribute ( "data-to-port" , value . Value . port . ToString ( ) ) ;
113
- to = value ;
114
- _ = value . Value . node . IngoingConnectors . Add ( ( this , value . Value . port ) ) ;
115
- if ( From is { } from )
116
- {
117
- if ( value . Value . param is not null )
118
- {
119
- QueuedTasks . Enqueue ( async context => await ( await from . node . AudioNode ( context ) ) . ConnectAsync ( value . Value . param , from . port ) ) ;
120
- }
121
- else
122
- {
123
- QueuedTasks . Enqueue ( async context => await ( await from . node . AudioNode ( context ) ) . ConnectAsync ( await value . Value . node . AudioNode ( context ) , from . port , value . Value . port ) ) ;
124
- }
125
- }
125
+ QueuedTasks . Enqueue ( async context => await ( await fromNode . AudioNode ( context ) ) . ConnectAsync ( await toNode . AudioNode ( context ) ) ) ;
126
126
}
127
- Changed ? . Invoke ( this ) ;
128
127
}
129
128
}
130
129
@@ -133,27 +132,24 @@ public override void HandlePointerMove(PointerEventArgs eventArgs)
133
132
if ( SVG . EditMode is EditMode . Add )
134
133
{
135
134
( X2 , Y2 ) = SVG . LocalDetransform ( ( eventArgs . OffsetX , eventArgs . OffsetY ) ) ;
136
- double fromX = From ! . Value . node . X + From ! . Value . node . Width ;
137
- double fromY = From ! . Value . node . Y + ( From ! . Value . port * 20 ) + 20 ;
135
+ double fromX = From ! . X + From ! . Width ;
136
+ double fromY = From ! . Y + 1 * 20 ;
138
137
SetStart ( ( fromX , fromY ) , ( X2 , Y2 ) ) ;
139
138
}
140
139
}
141
140
142
141
public override void HandlePointerUp ( PointerEventArgs eventArgs )
143
142
{
144
143
if ( SVG . EditMode is EditMode . Add
145
- && SVG . SelectedShapes . FirstOrDefault ( s => s is Node node && node != From ? . node ) is Node { } to )
144
+ && SVG . SelectedShapes . FirstOrDefault ( s => s is Node node && node != From ) is Node { } to )
146
145
{
147
- if ( to . IngoingConnectors . Any ( c => c . connector . To ? . node == From ? . node || c . connector . From ? . node == From ? . node ) )
146
+ if ( to . IngoingConnectors . Any ( c => c . To ? . node == From || c . From == From ) )
148
147
{
149
148
Complete ( ) ;
150
149
}
151
150
else
152
151
{
153
- if ( to . CurrentActivePort is { } port )
154
- {
155
- To = ( to , port , to . CurrentActiveAudioParam ) ;
156
- }
152
+ To = ( to , to . CurrentActiveAudioParamIdentifier ) ;
157
153
SVG . EditMode = EditMode . None ;
158
154
UpdateLine ( ) ;
159
155
}
@@ -169,7 +165,7 @@ public override void Complete()
169
165
}
170
166
}
171
167
172
- public static void AddNew ( SVGEditor . SVGEditor SVG , Node fromNode , ulong fromPort )
168
+ public static void AddNew ( SVGEditor . SVGEditor SVG , Node fromNode )
173
169
{
174
170
IElement element = SVG . Document . CreateElement ( "LINE" ) ;
175
171
element . SetAttribute ( "data-elementtype" , "connector" ) ;
@@ -179,7 +175,7 @@ public static void AddNew(SVGEditor.SVGEditor SVG, Node fromNode, ulong fromPort
179
175
Changed = SVG . UpdateInput ,
180
176
Stroke = "black" ,
181
177
StrokeWidth = "5" ,
182
- From = ( fromNode , fromPort )
178
+ From = fromNode
183
179
} ;
184
180
SVG . EditMode = EditMode . Add ;
185
181
@@ -209,10 +205,10 @@ public void UpdateLine()
209
205
return ;
210
206
}
211
207
212
- double fromX = From ! . Value . node . X + From ! . Value . node . Width ;
213
- double fromY = From ! . Value . node . Y + ( From ! . Value . port * 20 ) + 20 ;
208
+ double fromX = From ! . X + From ! . Width ;
209
+ double fromY = From ! . Y + 20 ;
214
210
double toX = To ! . Value . node . X ;
215
- double toY = To ! . Value . node . Y + ( To ! . Value . port * 20 ) + 20 ;
211
+ double toY = To ! . Value . node . Y + ( To ? . node . Offset ( To ? . audioParamIdentifier ) ?? 20 ) ;
216
212
double differenceX = toX - fromX ;
217
213
double differenceY = toY - fromY ;
218
214
double distance = Math . Sqrt ( ( differenceX * differenceX ) + ( differenceY * differenceY ) ) ;
@@ -233,12 +229,12 @@ public override void BeforeBeingRemoved()
233
229
{
234
230
if ( From is { } from )
235
231
{
236
- _ = from . node . OutgoingConnectors . Remove ( ( this , from . port ) ) ;
237
- from . node . QueuedTasks . Enqueue ( async context => await ( await from . node . AudioNode ( context ) ) . DisconnectAsync ( from . port ) ) ;
232
+ _ = from . OutgoingConnectors . Remove ( this ) ;
233
+ from . QueuedTasks . Enqueue ( async context => await ( await from . AudioNode ( context ) ) . DisconnectAsync ( ) ) ;
238
234
}
239
235
if ( To is { } to )
240
236
{
241
- _ = to . node . IngoingConnectors . Remove ( ( this , to . port ) ) ;
237
+ _ = to . node . IngoingConnectors . Remove ( this ) ;
242
238
}
243
239
}
244
240
}
0 commit comments