-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
enums duplicated as a dictionary should have their key/values as constants #25102
Comments
Note that currently GDScript is a bit slack on constants. For example, this works (or at least worked recently):
About dictionary of variables and list of constants.. are you sure you don't want |
I was using this behaviour until 3.1 beta not realising it was a bug. What I want is the keys to have constant values without declaring loads of constants. It's a bit lazy but it is likely to assist with code readability. At least, I am assuming that's it what I would need to do for a state machine or similar. edit: typo |
@bojidar-bg this does not work on current master, you can't reassign the constants. However, since enum is just a dictionary you are able to change its contents at will: you can add/remove keys and change any value. So the If you need to assign constants at runtime, what you want is likely "immutable variables" (see #23695). |
@vnen Immutable variables sounds like a great idea. Especially since I was populating enums at run-time for different entities via a script. This was prior to 3.1. On testing 3.1 I found that I couldn't and shouldn't be able do this. #25096 It was simply convenient to have the enum assign integers to each key rather than doing it manually with a dictionary. It is likely that my understanding of enums is incorrect. I thought that since they were constants, their keys/values would also be constants. But that doesn't appear to be the case.
If this is the case shouldn't it be possible to add key/value pairs to an empty enum:
or
both of these result in Parser Error: Cannot assign a new value to a constant in v3.1.beta1.official. I haven't tried beta 2 |
No, those are different from the example. If you do |
So, the enum identifier is constant but its contents are not constant. If this is the case then should it not be possible to duplicate an enum into a previously declared empty enum? Is that not changing the dictionary itself? so maybe
But, that would still leave the possibility of accidental assignment when doing comparisons. So if immutable variables are implemented I would still have to run a loop. So maybe setting a flag to fix the key/values of the enum could be included in the duplicate function? I get it if this is not the way it is supposed to be. In which case just having a flag for dictionaries would be cool. Then it's just a case of duplicating the enum into a dictionary with a flag setting its contents as immutable. |
With immutable variables you would not assign it to an enum, but to a variable. Somewhat like this: enum input_type {HAS_TARGET, MY_HEALTH, MY_ENERGY, DISTANCE_TO}
immutable var my_input_type
func _ready():
my_input_type = input_type.duplicate()
This would defeat the purpose of it being a constant. You are rebinding the name to a different value, which is forbidden. That is, doing The syntax sugar for populating the dictionary sounds nice in theory but breaks a lot of assumptions (people who read the code will wonder why it allows assignment to a constant) and requires runtime checks to see if the dictionary is really empty when trying to do it (meaning a performance hit to every assignment, since we can't know beforehand if it's a constant dictionary). Also, if the dictionary is emptied in the future, should it allow to be repopulated in this fashion again? If so, you are able to commit mistakes anyway, again defeating the purpose of being a constant. If not, it requires keeping track that it was done already, adding and extra performance hit. If you really want to do this, there's no need to use an The dictionary itself can always be changed, the contents are never constant. If you want constant content, you're better off creating a custom class to handle this, using |
@vnen thank you for your explanation. I think though that I haven't been clear enough in what I want. I was thinking that I want the dictionary filled with constants not the dictionary itself to be constant. This is so I don't have to declare each and every one of them, just to avoid silly mistakes. The value assigned to each key has no importance, in this case, hence why I was using an enum. For me, I can't currently envisage an accidental assignment since I am only likely to do comparisons and the parser will pick up any mistakes there. I hadn't thought of using Also, if it goes against regular programming conventions then it's probably not a good idea. This has been very helpful. |
Closing per the discussion above. |
Godot version:
3.1 beta 1
OS/device including version:
Ubuntu 18.10
Issue description:
enums are immutable but assigning an enum at run-time seems convenient to me.
However, since they are just dictionaries for constants, would it be possible to have them respect type if, for example, an enum was assigned to an empty dictionary at run-time?
result:
input_type
is essentially a dictionary of constantsmy_input_type
is a dictionary of variablesI would like
my_input_type
in this scenario to be a list of constants.In the instances where a user would want this: it would allow the ease of declaring a raft of constants as an enum and therefore maintain code readability. It would also be safer having constants rather than variables, which could be changed by accidental assignment.
I think this would be useful for state machines where entities are assigned their list of available states from global configuration file via autoload.
My use case is for a list of actions in an Utility AI, where the available actions vary for different classes of entity. These are assigned at run-time.
Steps to reproduce:
n/a
Minimal reproduction project:
3.1 Test.zip
edit: added beta version
The text was updated successfully, but these errors were encountered: