Rewrite 'Signals' introduction to have clearer examples

Previous examples used signals in the same file which can cause confusion to
some new users (as seen in #1973). New examples follow basic framework
of existing work, but take care to explicitly show an example of
inter-instance signals.
This commit is contained in:
Neil Moore
2019-01-19 12:45:47 -05:00
parent 33d9fa5ae0
commit fb64a084cb

View File

@@ -1464,62 +1464,104 @@ freed.
Signals
~~~~~~~
It is often desired to send a notification that something happened in an
instance. GDScript supports creation of built-in Godot signals.
Declaring a signal in GDScript is easy using the `signal` keyword.
Signals are a way to send notification messages from an object that
other objects can listen to in a generic way. Create custom signals for
a class using the ``signal`` keyword.
::
# No arguments.
signal your_signal_name
# With arguments.
signal your_signal_name_with_args(a, b)
# Signal with no arguments
signal your_signal_name
These signals can be connected in the editor or from code like regular signals.
Take the instance of a class where the signal was
declared and connect it to the method of another instance:
# Signal with two arguments
signal your_signal_name_with_args(a, b)
These signals may be connected to methods in the same manner as you connect
built-in signals of nodes such as :ref:`class_Button` or :ref:`class_RigidBody`.
Here's an example that creates a custom signal in one script and connects
the custom signal to a method in a separate script, using the
:ref:`Object.connect() <class_Object_method_connect>` method:
::
func _callback_no_args():
print("Got callback!")
# your_notifier.gd
func _callback_args(a,b):
print("Got callback with args! a: ", a, " and b: ", b)
signal data_found
func _at_some_func():
instance.connect("your_signal_name", self, "_callback_no_args")
instance.connect("your_signal_name_with_args", self, "_callback_args")
It is also possible to bind arguments to a signal that lacks them with
your custom values:
var your_data = 42
::
func _at_some_func():
instance.connect("your_signal_name", self, "_callback_args", [22, "hello"])
# your_handler.gd
This is useful when a signal from many objects is connected to a
single callback and the sender must be identified:
func your_handler():
print("Your handler was called!")
::
func _button_pressed(which):
print("Button was pressed: ", which.get_name())
# your_game.gd
func _ready():
for b in get_node("buttons").get_children():
b.connect("pressed", self, "_button_pressed",[b])
func _ready():
var notifier = your_notifier.new()
var handler = your_handler.new()
Finally, emitting a custom signal is done by using the
Object.emit_signal method:
notifier.connect("data_found", handler, "your_handler")
GDScript can bind arguments to connections between a signal and a method.
When the signal is emitted, calling the connected method, the bound argument is
given to the method. These bound arguments are specific to the connection
rather than the signal or the method, meaning that each connection has
unique bindings.
Here is an example that creates a connection between a button's ``pressed`` signal and
a method, binding the button instance to the connection. The handler uses the
bound argument to print which button instance was pressed.
::
func pressed_handler(which):
print("A button was pressed! Button's name was:", which.get_name())
func _ready():
for button in get_node("buttons").get_children()
# Connect the button's 'pressed' signal to our 'pressed_handler' method
# Bind the button to the connection so we know which button was pressed
button.connect("pressed", self, "pressed_handler", [button])
Signals are generated by the :ref:`Object.emit_signal() <class_Object_method_emit_signal>`
method which broadcasts the signal and arguments.
Extending a previous example to use all the features of GDScript signals:
::
func _at_some_func():
emit_signal("your_signal_name")
emit_signal("your_signal_name_with_args", 55, 128)
some_instance.emit_signal("some_signal")
# your_notifier.gd
signal data_found(data)
var your_data = 42
func _process(delta):
if delta == your_data:
emit_signal("data_found", data)
::
# your_handler.gd
func your_handler(data, obj):
print("Your handler was called from: ", obj.get_name(), with data: ", data)
::
# your_game.gd
func _ready():
var notifier = your_notifier.new()
var handler = your_handler.new()
notifier.connect("data_found", handler, "your_handler", [notifier])
Coroutines with yield
~~~~~~~~~~~~~~~~~~~~~