You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the problem or limitation you are having in your project
In my code, I need to flood-fill through the connected nodes on my custom graph data structure and assign some values, do some processing, or just grab an interconnected subset of nodes after destructible gets split in half. Since HashSet or similar collections aren't available in GDScript, I'm using a Dictionary[T, bool] to store a set of objects of type T.
I've ran into limitation that I can't just grab any element from the set - I need to call keys() first to grab all the keys and then just get one element and discard the rest.
staticfuncextract_connected_subset(remaining: Dictionary[Block, bool]) ->Dictionary[Block, bool]:
varcontained: Dictionary[Block, bool] = {}
varfront: Dictionary[Block, bool] = {}
varfirst:=remaining.keys()[0] asBlock# "get next element from set"front[first] =truewhile!front.is_empty():
varblock:=front.keys()[0] asBlock"get next element from set"front.erase(block)
contained[block] =trueremaining.erase(block)
forneighbor: Blockinblock.neighbors:
if!contained.has(neighbor):
front[neighbor] =truereturncontained
Describe the feature / enhancement and how it helps to overcome the problem or limitation
The var element := some_dict.keys()[0] as T could be replaced with var element := some_dict.get_any_key() as T.
This is not only cleaner, but also has significant performance implications because the keys() method iterates through all the dictionary keys and puts them in a freshly allocated container. In my use case most of that work is wastefully discarded afterwards.
I thought about exposing get_key_at_index() method to GDScript, but that doesn't seem to be that useful, and might be misleading to scripters because of raising assumptions on how the elements are ordered in the dict.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
dalexeev
changed the title
GDScript: Add a method for acquiring a single key from Dictionary
Add a method for acquiring a single key from Dictionary
Dec 30, 2024
But when replacing var block := front.keys()[0] as Block with var block: Block = get_first_key(front) etc. note that there's an additional cost of a function call, which might overweight the gain of faster key obtaining (in case of small key count). It should be relatively negligible but for being sure do the benchmarks.
Alternatively instead of calling a function you could inline it:
varblock: Blockforb: Blockinfront:
block=bbreak# Same as an ugly one-liner:#var block: Block; for b: Block in front: block = b; break
I think that calling dedicated method won't be slower than calling keys() as in current state. Unless calling it is handled differently?
As for the loop workaround, it's quite a novel approach, but I can't see myself riddling my code with such constructs - the legibility of GDScript goes down the drain with it.
Describe the project you are working on
A hierarchical destructible system.
Describe the problem or limitation you are having in your project
In my code, I need to flood-fill through the connected nodes on my custom graph data structure and assign some values, do some processing, or just grab an interconnected subset of nodes after destructible gets split in half. Since HashSet or similar collections aren't available in GDScript, I'm using a
Dictionary[T, bool]
to store a set of objects of type T.I've ran into limitation that I can't just grab any element from the set - I need to call
keys()
first to grab all the keys and then just get one element and discard the rest.Describe the feature / enhancement and how it helps to overcome the problem or limitation
The
var element := some_dict.keys()[0] as T
could be replaced withvar element := some_dict.get_any_key() as T
.This is not only cleaner, but also has significant performance implications because the
keys()
method iterates through all the dictionary keys and puts them in a freshly allocated container. In my use case most of that work is wastefully discarded afterwards.I thought about exposing
get_key_at_index()
method to GDScript, but that doesn't seem to be that useful, and might be misleading to scripters because of raising assumptions on how the elements are ordered in the dict.Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
alternatively:
Naturally, I'm willing to submit PR with needed code/tests/docs.
If this enhancement will not be used often, can it be worked around with a few lines of script?
It can be worked around as I did in my example code, but I don't see any performant way to get a single key from the dictionary.
Is there a reason why this should be core and not an add-on in the asset library?
I'm not sure - can addons/modules add GDScript methods to core types? Besides, it solves a problem in what appears to be a relatively common scenario.
The text was updated successfully, but these errors were encountered: