-
-
Notifications
You must be signed in to change notification settings - Fork 21k
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
Support to remove, edit and store user defined signals #69243
base: master
Are you sure you want to change the base?
Conversation
Thanks for your contribution. You need to squash the commits as required by our pipeline (see docs.godotengine.org/en/latest/community/contributing/pr_workflow.html). |
3ca3030
to
516a35e
Compare
Okay, thanks for the help! I squashed the commits together now. I'm still wondering about the "Further thoughts" above: If it'd actually be better to always override (without error) an existing user signal, and thus not consume the 3rd argument for it. This way, in the future, can potentially use the 3rd arg (eg. for |
I noticed the lack of these methods to be an odd design flaw while I was making #67880, but at the same time, I'm struggling to come up with concrete examples for User Signals (the implementation of methods in the PR especially) that are not just generic use-cases, that may or may not be solvable with some code restructuring. Could this be worth of a proposal? That is not to mention, how their existence may be a misnomer of sorts. Based on the way "User Signals" work, they should have probably been called "Instance Signals", or something along those lines. |
Here is a concrete example, although highly specific to a specific system:
This is just to showcase possibilities of having user signals. By completing the features with remove & modify, the user signals are completely controllable from the GDScript side. In addition, this support could be enhanced with the "persistent" argument to automatically declare the signal (eg. when the scene is instantiated). I'm actually almost finished writing that part - with changing the |
I feel like the Persistence sounds quite useful but it requires some solid implementation across the board to avoid buggy behavior. |
@Mickeon I agree 100%. As this is my first PR, I don't know the protocol. Can I just make a new squashed commit, and update the description? |
Documentation is broken, type |
You can change the PR's intent any time without needing to reopen a new PR. Doesn't matter too much besides losing some history and context. |
0b932fe
to
f7ec699
Compare
f7ec699
to
f5ba367
Compare
Adds support to: 1. Override existing user signals. (Simply removed the check that prevented it.) 2. Use full `PropertyInfo` for the signal arguments. 3. Remove existing user signals by `remove_user_signal(name)` method. 4. Store the user signals as persistent and automatically declare them when the scene is instantiated: `add_user_signal(name, args=[], persistent=false)`. The purpose of this commit is to allow better setting up of dynamic (=user declared) signals when preparing scenes in the editor. The user may modify the signal arguments (= override) or rename the signal (remove + add) while developing the game scene, and then to use the newly generated signals to hook up to more things in the scene. Working in the scene editor, the user might likely expect the signals to be there when the scene is instantiated (on game / tool side), just like group names and meta data are - all regardless of the script of the node / object. ... To totally complete this idea of workflow, the editor could provide a way to set up user signals (just like can setup group names and meta data).
f5ba367
to
781d486
Compare
Okay, now I think the |
Sorry to bump, but could someone re-trigger the workflow tests? All should be fixed. |
What would this do? They may share the same "Dictionary structure", but most of the entries in there would be entirely unused by the engine, as they are currently (unless I'm mistaken?). Secondly, using metadata to serialise the signals is quite the workaround. It definitely should be serialised in some other, more personalised manner, but it is understandable that it would require more knowledge of the source code to implement such a thing. Do note I'm a contributor like many, so this may be more up to the maintainers to decide. |
Well, from my perspective, it seems odd that they are not included (= it's a surprising restriction) - or rather that it behaves as if they are overridden after a process frame (they are there if you ask immediately). Currently in one project I'm using a hackaround of storing the signal infos as meta data, just so that I can get full information out (it's related to that system with the screenshot above). In that context, it's very convenient to know the hints of an enum or bitflag, or perhaps the subtype of an array. So, even though the engine might not currently make use of them, they might be useful to have there as information (eg. using About the metadata, you're probably right - or, at least, I have way too little knowledge and experience with Godot's internals to argue one way or another. I consider the "persistent" feature as a secondary feature - maybe it should be another PR, and the core of this PR would be to just complete the support for 1. add and 3. remove signal (and 2. add full infos). |
I think that including all Property Info is very "overkill" here, because most users will not ever make use of the Judging by the code as I last saw it, the main reason it is theoretically possible to insert these attributes is because all signals share the same MethodInfo struct as... well, methods. This means it is possible to define a list of arguments that are formatted identically to the result of However, and at least currently, that doesn't mean that user signals need to make use of all of the attributes... nor there may ever be a justifiable reason for them to in the base engine, any time soon... ... Unless, say for example, it was possible to define and save user signals from within the Scene Editor. In that case, exposing the same "power" to more advanced users would only be fair. |
I must say I disagree with that. I don't see any overkilling harm in there - especially if would implement it in the "picky" way (but maybe even with |
I'm a little skeptical about this. Signals are more like methods than properties, right now you can't add/override/remove methods or implement I'm not saying it should never be implemented, but perhaps we should consider whether we really need it. Perhaps this should be implemented via Also note that you can use signal arguments instead of multiple homogeneous signals. Perhaps in some cases, individual signals are justified in terms of performance, but I'm not sure that empty calls can be so critical. |
I'm not 100% sure which points your skepticism (@dalexeev) extends to. But, here's my thoughts after a few months:
|
Hello! It looks like this feature has already been implemented (see #90674) |
Feature (updated)
Adds support to:
PropertyInfo
for user signal arguments - not only pickingname
andtype
.remove_user_signal(name)
method._user_signals
meta data) and auto-declare the signal when the scene is instatiated. This is done via optional 3rd argument in theadd_user_signal(name, args=[], persistent=false)
method.GDScript examples
Feature 1: Allow to modify existing user signals.
Feature 2: Full support for property infos.
Feature 3: Allow to remove an existing signal.
Feature 4: Store the signal persistently.
Implementation
The implementation for 1-3 is very straight forward:
signal_map
hashmap. If wants to prevent adding an already existing signal, should usehas_user_signal(name)
before.PropertyInfo::from_dict()
method.signal_map
.The feature for persistent user signals (4) is implemented by:
_user_signals
meta data, which is an array of dictionaries:[ { name, args }, ... ]
.Also modified the docs (in Object.xml) accordingly.
Why
The purpose of this commit is to allow better setting up of dynamic (=user declared) signals when preparing scenes in the editor. The user may modify the signal arguments (= override) or rename the signal (remove + add) while developing the game scene (eg. using some tool using these methods), and then to use the newly generated signals to hook up to more things in the scene.
Note. In general terms, the user signals feature (= scriptless signals) is very useful, for example, for cases where several different game objects share the same root script (eg. using a common modular node structure), but want to provide custom signals that are emitted from somewhere within (eg. by features of one of those modules). For example, a helpless creature with a custom "panic" signal. (In this sense user signals are a bit like meta data - independent of the script.) So this commit aims to enhance / complete the existing feature set.
Further thoughts
(feature 5:) To totally complete this idea of "user signals" feature, the editor could provide a way to edit the user signals manually - just like it provides a way to edit persistent group names and meta data.
But at minimum, I'd at least like to change 1.
add_user_signal
to override the earlier signal, 2. add suppor for hint etc., and 3. to addremove_user_signal
. If the 4. concept of persistent is "not worth it" (in larger context), or the implementation not good (eg. maybe meta data not the cleanest way(?)), then I'd like to reduce this PR to those three main aspects. (But I believe making signals as editor-editable as groups and meta data enhances flexibility of the Godot architecture.)