Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling emit() on an object, only seems to deliver the signal to that object not others connected to the same signal #254

Closed
pcbeard opened this issue Nov 27, 2023 · 2 comments

Comments

@pcbeard
Copy link
Contributor

pcbeard commented Nov 27, 2023

See attached project. Try running swift TestSignals and notice that if SpinningCube._input() is active, and ListenerNode._input() is commented out, that ListenerNode._on_pressed() never gets called. It also seems to be that if you try to use SpinningCube.pressed from ListenerNode._ready(), without also using the #signal() macro in the ListenerNode class, this will fail to find the signal with this error message:

ERROR: In Object of type 'ListenerNode': Attempt to connect nonexistent signal 'pressed' to callable 'ListenerNode::_on_pressed'.
at: connect (core/object/object.cpp:1282)

HelloSwiftGodotKit.zip

@pcbeard pcbeard changed the title Calling emit() on a signal defined in another class doesn't seem to deliver the signal Calling emit() on an object, only seems to deliver the signal to that object not others connected to the same signal Nov 27, 2023
@PadraigK
Copy link
Contributor

PadraigK commented Nov 27, 2023

This is behaving as expected, but its understandable why anyone would see it as a bug :/

Godot's signal mechanism connects an instance emitting the signal to another node. This is unusual for a notification pattern which normally allows another object to globally observe a notification/signal without needing to know about the emitting instance.

From the code in the zip file:

var pressedSignal = SpinningCube.pressed
@Godot
class ListenerNode: Node {
    #signal("pressed", arguments: ["event" : InputEvent.self])
    
    @Callable func _on_pressed(event: InputEvent) {
        print("event = \(event)")
    }
    
    override func _ready() {
        connect(signal: pressedSignal, to: self, method: "_on_pressed")    
    }
    
    override func _input(event: InputEvent) {
        guard event.isPressed() && !event.isEcho() else { return }
        emit(signal: pressedSignal, event)
    }
}

In _ready here, the code is attempting to connect an instance of ListenerNode to a signal which ListenerNode does not emit.

Compared with:

    func addSpinningCube(_ pos: Vector3) {
        let n = SpinningCube()
        n.position = pos
        rootNode.addChild(node: n)
        if !listening {
            n.connect(signal: pressedSignal, to: n, method: "_on_pressed")
            listening = true
        }
    }

This call to connect is correct because it's connecting an instance of SpinningCube.

@pcbeard
Copy link
Contributor Author

pcbeard commented Nov 28, 2023

Yes, I see the error of my ways now. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants