Skip to content

Commit 04b42dc

Browse files
committed
Elaborate on C# Connect/Disconnect
1 parent 946fc52 commit 04b42dc

File tree

2 files changed

+81
-4
lines changed

2 files changed

+81
-4
lines changed

tutorials/scripting/c_sharp/c_sharp_signals.rst

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ C# signals
66
For a detailed explanation of signals in general, see the :ref:`doc_signals` section in the step
77
by step tutorial.
88

9-
While it is still possible to use signals through the ``Connect``/``Disconnect`` API, C# gives us
10-
a more idiomatic way to implement the :ref:`observer pattern<doc_key_concepts_signals>`.
9+
Signals are implemented using C# events, the idiomatic way to represent
10+
:ref:`the observer pattern<doc_key_concepts_signals>` in C#. This is the
11+
recommended way to use signals in C# and the focus of this page.
12+
13+
In some cases it's necessary to use the older
14+
:ref:`Connect()<class_object_method_connect>` and
15+
:ref:`Disconnect()<class_object_method_disconnect>` APIs.
16+
See :ref:`using_connect_and_disconnect` for more details.
1117

1218
Signals as C# events
1319
--------------------
@@ -30,8 +36,13 @@ In addition, you can always access signal names associated with a node type thro
3036
.. warning::
3137

3238
While all engine signals connected as events are automatically disconnected when nodes are freed, custom
33-
signals aren't. Meaning that: you will need to manually disconnect (using ``-=``) all the custom signals you
34-
connected as C# events (using ``+=``).
39+
signals connected using ``+=`` aren't. Meaning that: you will need to manually disconnect (using ``-=``)
40+
all the custom signals you connected as C# events (using ``+=``).
41+
42+
An alternative to manually disconnecting using ``-=`` is to
43+
:ref:`use Connect <using_connect_and_disconnect>` rather than ``+=``.
44+
45+
See `Godot issue #70414 <https://github.com/godotengine/godot/issues/70414>`_.
3546

3647
Custom signals as C# events
3748
---------------------------
@@ -146,3 +157,32 @@ connecting to them or emitting them). Also, note that signals created this way w
146157
AddUserSignal("MyCustomSignal");
147158
EmitSignal("MyCustomSignal");
148159
}
160+
161+
.. _using_connect_and_disconnect:
162+
163+
Using Connect and Disconnect
164+
----------------------------
165+
166+
In general, it isn't recommended to use
167+
:ref:`Connect()<class_object_method_connect>` and
168+
:ref:`Disconnect()<class_object_method_disconnect>`. These APIs don't provide as
169+
much type safety as the events. However, they're necessary for
170+
:ref:`connecting to signals defined by GDScript <connecting_to_signals_cross_language>`
171+
and passing :ref:`ConnectFlags<enum_Object_ConnectFlags>`.
172+
173+
In the following example, pressing the button for the first time prints
174+
``Greetings!``. ``OneShot`` disconnects the signal, so pressing the button again
175+
does nothing.
176+
177+
.. code-block:: csharp
178+
179+
public override void _Ready()
180+
{
181+
Button button = GetNode<Button>("GreetButton");
182+
button.Connect(Button.SignalName.Pressed, Callable.From(OnButtonPressed), (uint)GodotObject.ConnectFlags.OneShot);
183+
}
184+
185+
public void OnButtonPressed()
186+
{
187+
GD.Print("Greetings!");
188+
}

tutorials/scripting/cross_language_scripting.rst

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ The following two scripts will be used as references throughout this page.
1818

1919
var my_field: String = "foo"
2020

21+
signal my_signal
22+
2123
func print_node_name(node: Node) -> void:
2224
print(node.get_name())
2325

@@ -29,6 +31,9 @@ The following two scripts will be used as references throughout this page.
2931
for i in range(n):
3032
print(msg)
3133

34+
func my_signal_handler():
35+
print("The signal handler was called!")
36+
3237
.. code-tab:: csharp
3338

3439
using Godot;
@@ -37,6 +42,8 @@ The following two scripts will be used as references throughout this page.
3742
{
3843
public string myField = "bar";
3944

45+
[Signal] public delegate void MySignal();
46+
4047
public void PrintNodeName(Node node)
4148
{
4249
GD.Print(node.Name);
@@ -57,6 +64,11 @@ The following two scripts will be used as references throughout this page.
5764
GD.Print(msg);
5865
}
5966
}
67+
68+
public void MySignalHandler()
69+
{
70+
GD.Print("The signal handler was called!");
71+
}
6072
}
6173

6274
Instantiating nodes
@@ -186,6 +198,31 @@ to said method.
186198
Otherwise, each element of your array will be treated as a single argument
187199
and the function signature won't match.
188200

201+
.. _connecting_to_signals_cross_language:
202+
203+
Connecting to signals
204+
---------------------
205+
206+
Connecting to C# signals from GDScript
207+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
208+
209+
Connecting to a C# signal from GDScript is the same as connecting to a signal
210+
defined in GDScript:
211+
212+
.. code-block:: gdscript
213+
214+
my_csharp_node.MySignal.connect(my_signal_handler)
215+
216+
Connecting to GDScript signals from C#
217+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
218+
219+
Connecting to a GDScript signal from C# only works with the ``Connect`` method
220+
because no C# static types exist for signals defined by GDScript:
221+
222+
.. code-block:: csharp
223+
224+
myGDScriptNode.Connect("my_signal", Callable.From(mySignalHandler));
225+
189226
Inheritance
190227
-----------
191228

0 commit comments

Comments
 (0)