0 votes

I have a big problem these days.

I have one global array such as Fruit, which has all the fruits. for example:

var Fruit = [Apple, Peach, Pear, ...]

and there are one class "PLAYER", which can change this array at any time.

PLAYER.eat(Apple) # will remove the Apple from Fruit array

Then, I have ten thousand Farmers that inherits another class called "NPC". the NPC iterate the Fruit array and call the logic about each fruit, such as :


for eachfruit in Fruit:
....each
fruit.get_nutrition()

then there will be big problem: some fruit may be eaten in the for loop, so each_fruit will be null can cause an error

and i find some book that said the for lool will lock the global Fruit Array? is this true? But i find that PLAYER can always eat the fruit, so i really doubt it .

Anyone know the answer will help me a lot, thanks!

Godot version godot 3.2
in Engine by (12 points)

1 Answer

0 votes

Removing an item from an array will not replace it with null, it will just remove it and shift the indexes of the elements to the right one to the left. But if you're worried about null pointers you can just put an if statement to check if the element exists before calling the method.

As for the locking thing, I'm not sure if that's true with GDScript. Where did you read that?

by (7,166 points)

I think he is worried about item being freed in the exact moment of iteration. That can happen, will return null and crash with error. If this is it, correct check is isinstancevalid().

  1. I understand your means of using "if statement", which should be the same as @Inces said by using isinstancevalid(). But I think this is not a elegant solution. If this way , each for loop will use one isinstancevalid(), for example

    for A in Array:
    ......if isinstancevalid(A)
    ......for B in getArraysAbout(A):
    ............if B in isinstancevalid(A):
    .................do_logic(B)

    put 'isinstancevalid()' performance aside, for large number NPCs, each for loop will use isinstancevalid() ??

  2. "the locking thing" is answered by @Vintagegodotuser for this question
    https://godotengine.org/qa/18424/a-question-about-modifying-arrays-and-dictionaries
    He said 'Godot seems to work a bit strange handling arrays or dictionarys while iterating over their contents. Obviously those vars are locked (like a const!)'

Yes, for large number NPCs, sometimes will cause strange error(array change or null).
'isinstancevalid()' should be one solution, but I think this is not elegant solution with high performance as I replied

The only other option I can see is to border timing of iterating farmers and player eating. You would have to hold one until another is done, with yield() for example

Yes, this is similar to use lock when PLAYER eat and unlock it when eat is done.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.