|
5 | 5 | using Microsoft.CodeAnalysis.CSharp.Syntax; |
6 | 6 | using Microsoft.CodeAnalysis.Text; |
7 | 7 |
|
8 | | -// TODO: |
9 | | -// Determine a proper way to emit the signal. |
10 | | -// 'Emit(nameof(TheEvent))' creates a StringName every time and has the overhead of string marshaling. |
11 | | -// I haven't decided on the best option yet. Some possibilities: |
12 | | -// - Expose the generated StringName fields to the user, for use with 'Emit(...)'. |
13 | | -// - Generate a 'EmitSignalName' method for each event signal. |
14 | | - |
15 | 8 | namespace Godot.SourceGenerators |
16 | 9 | { |
17 | 10 | [Generator] |
@@ -288,6 +281,43 @@ void AppendPartialContainingTypeDeclarations(INamedTypeSymbol? containingType) |
288 | 281 | .Append(signalName) |
289 | 282 | .Append(" -= value;\n") |
290 | 283 | .Append("}\n"); |
| 284 | + |
| 285 | + // Generate On{EventName} method to raise the event |
| 286 | + |
| 287 | + var invokeMethodSymbol = signalDelegate.InvokeMethodData.Method; |
| 288 | + int paramCount = invokeMethodSymbol.Parameters.Length; |
| 289 | + |
| 290 | + string raiseMethodModifiers = signalDelegate.DelegateSymbol.ContainingType.IsSealed ? |
| 291 | + "private" : |
| 292 | + "protected"; |
| 293 | + |
| 294 | + source.Append($" {raiseMethodModifiers} void On{signalName}("); |
| 295 | + for (int i = 0; i < paramCount; i++) |
| 296 | + { |
| 297 | + var paramSymbol = invokeMethodSymbol.Parameters[i]; |
| 298 | + source.Append($"{paramSymbol.Type.FullQualifiedNameIncludeGlobal()} {paramSymbol.Name}"); |
| 299 | + if (i < paramCount - 1) |
| 300 | + { |
| 301 | + source.Append(", "); |
| 302 | + } |
| 303 | + } |
| 304 | + source.Append(")\n"); |
| 305 | + source.Append(" {\n"); |
| 306 | + source.Append($" EmitSignal(SignalName.{signalName}"); |
| 307 | + foreach (var paramSymbol in invokeMethodSymbol.Parameters) |
| 308 | + { |
| 309 | + // Enums must be converted to the underlying type before they can be implicitly converted to Variant |
| 310 | + if (paramSymbol.Type.TypeKind == TypeKind.Enum) |
| 311 | + { |
| 312 | + var underlyingType = ((INamedTypeSymbol)paramSymbol.Type).EnumUnderlyingType; |
| 313 | + source.Append($", ({underlyingType.FullQualifiedNameIncludeGlobal()}){paramSymbol.Name}"); |
| 314 | + continue; |
| 315 | + } |
| 316 | + |
| 317 | + source.Append($", {paramSymbol.Name}"); |
| 318 | + } |
| 319 | + source.Append(");\n"); |
| 320 | + source.Append(" }\n"); |
291 | 321 | } |
292 | 322 |
|
293 | 323 | // Generate RaiseGodotClassSignalCallbacks |
|
0 commit comments