Connecting to Signals
Part of the Object Oriented Programming section of Coddy's GDScript journey. Lesson 37 of 65.
connect() takes the function to run, as a Callable. Name a method without parentheses, or write a lambda:
chest.opened.connect(_on_chest_opened) # a method of this script
chest.opened.connect(quest_log.add_entry) # a method of another object
chest.opened.connect(func(): print("Creak!")) # a lambdaGodot names a listening method _on_, then the emitter, then the signal: _on_chest_opened. A signal can have many connected functions, and they run in the order they were connected.
An object that listens usually connects itself, in a method that receives the emitter:
# quest_log.gd
class_name QuestLog
extends RefCounted
var chests_opened := 0
func track(chest: Chest) -> void:
if not chest.opened.is_connected(_on_chest_opened):
chest.opened.connect(_on_chest_opened)
func untrack(chest: Chest) -> void:
if chest.opened.is_connected(_on_chest_opened):
chest.opened.disconnect(_on_chest_opened)
func _on_chest_opened() -> void:
chests_opened += 1Connecting the same function to the same signal twice is an error, and so is disconnecting a function that is not connected. is_connected() checks first. disconnect() stops listening, and the next emit no longer runs that function.
Pass CONNECT_ONE_SHOT as the second argument and the connection removes itself after its first call: chest.opened.connect(_on_first_open, CONNECT_ONE_SHOT).
A lambda keeps the value a local variable had when the lambda was created. count += 1 inside a connected lambda changes that copy, and count in _ready() stays 0. Keep a counter in a member variable of a listener object, as QuestLog does.
Challenge
EasyA shooting range has targets that emit hit when they are shot. Write the ScoreBoard that listens to them:
watch(target)connects the target'shitsignal to_on_target_hit. Watching a target that is already watched changes nothing.ignore(target)disconnects it. Ignoring a target that is not watched changes nothing._on_target_hit()adds10topointsand printsHit! Score: N.
Watching twice or ignoring an unwatched target must not cause an error, because any error fails the test. target.gd is complete.
The supplied code reads the number of targets, then commands such as watch 0, ignore 0 and shoot 0, and prints the final score. For two targets and the commands watch 0, shoot 0, shoot 1, watch 1, watch 1, shoot 1, ignore 0, shoot 0 it prints:
Shot target 0
Hit! Score: 10
Shot target 1
Shot target 1
Hit! Score: 20
Shot target 0
Final score: 20Your code goes in score_board.gd and target.gd. main.gd holds the supplied input/output code and cannot be edited.
Try it yourself
extends Node
func _ready():
# Supplied input/output code: keep it as it is
var board := ScoreBoard.new()
var targets: Array[Target] = []
for i in int(OS.read_string_from_stdin()):
targets.append(Target.new())
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
var target := targets[int(parts[1])]
if parts[0] == "watch":
board.watch(target)
elif parts[0] == "ignore":
board.ignore(target)
else:
print("Shot target ", parts[1])
target.shoot()
print("Final score: ", board.points)
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe self KeywordMethodsPropertiesConstructor (_init)Recap - Simple Calculator4Polymorphism
Method Overriding RevisitedDuck TypingAbstract Classes and MethodsInterface DesignRecap - Shape Calculator7Signals
What is a Signal?Declaring and EmittingConnecting to SignalsSignals with ArgumentsRecap - Health System2Class Properties
Instance vs Static VariablesStatic FunctionsProperty SettersProperty GettersPrivate by ConventionRecap - Bank Account Manager5Encapsulation
Public and Private MembersValidation with SettersInformation HidingRead-Only PropertiesRecap - Student Records System8Advanced OOP Concepts
Composition vs InheritanceInner ClassesNodes as ComponentsRefCounted vs NodeEnums in Classes11Project: Library Management
Project OverviewBook and User Classes3Inheritance
Basic InheritanceThe super KeywordMethod OverridingInheritance ChainsType Checks with isRecap - Employee Hierarchy6Special Methods
Virtual Methods IntroductionThe _to_string MethodCustom IteratorsRecap - Custom List9Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy PatternPractice on your own: Online GDScript compiler