Godot Version
v4.6.stable.official [89cea1439]
Question
I’m working on a task queue in GDScript. It’s a Dictionary of String keys, the tasks, and int values, their priority.
A task than has been called is taken out of the Dictionary, and put in the current_task String variable, its priority being put in the current_priority int variable.
The _process() gets the max() value from the Dictionary, compares it to the current_priority.
If the max priority in the Dictionary is higher than the current_priority, it puts the current_task back in the Dictionary with the current_priority, then .erase() the max-priority task from the Dictionary and put it in current_task, with its priority in current_priority. The documentation for .erase() specifies
Note: Do not erase entries while iterating over the dictionary. You can iterate over the keys() array instead.
but I’m not iterating over the Dictionary. I’m erasing the key directly.
Scenario :
By default, there’s one task : idle, of priority 1.
When I left click, another task is added to the Dictionary : attack, of priority 50.
extends Node
# D_tasks is a Dictionary of keys : String specifying the task
# and values : int specifying the priority
var D_tasks : Dictionary[String,int]
# vars to get a current state
var current_task : String
var current_priority : int = 0
func _process(_delta: float) -> void:
# first frame, the tasks dict is empty
if D_tasks.is_empty() :
#queue an idle
D_tasks["idle"] = 1
else:
# get the first task of the highest priority
print(D_tasks)
var max_priority : int = D_tasks.values().max()
var task : String = D_tasks.find_key(max_priority)
# a priority 0 is a null task
if max_priority == 0:
#queue an idle
D_tasks["idle"] = 1
# call the task if its priority is greater than the current one
elif max_priority > current_priority:
print("%o superior to %o" % [max_priority,current_priority])
# reenter the current task
D_tasks[current_task] = current_priority
# pop the task
D_tasks.erase(task)
# call the task
print("calling %s %o" % [str(task),max_priority])
current_task = task
current_priority = max_priority
print(task)
func _unhandled_input(event: InputEvent) -> void:
if (event is InputEventMouseButton
and event.pressed
and event.button_index == MOUSE_BUTTON_LEFT
):
D_tasks["attack"] = 50
I expect it to print the Dictionary with two tasks, idle:1 and attack:50, then print “50 is superior to 1”, then “calling attack 50”, then “attack”.
It does not :
...
{ "": 0, "idle": 1 }
{ "": 0, "idle": 1, "attack": 50 }
62 superior to 1
calling attack 62
attack
{ "": 0, "idle": 1 }
...
My questions :
- there’s a ““ (
null) key of 0 value in theDictionarywhen I.erase()a key. Why is there anull:0tuple in theDictionary? How do I erase a key:value properly ? I tried
...
for key in D_tasks.keys():
if key = task:
D_tasks.erase(key)
with the same result.
- It prints out the values of the
Dictionary: 0, 1, 50. And tells me immediately after that the.values().max()is 62. Where does 62 come from ? There’s no other line of code.