godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.15k stars 97 forks source link

Handle infinite while-loop with error message #701

Open Error7Studios opened 4 years ago

Error7Studios commented 4 years ago

Describe the project you are working on: Godot tutorial

Describe the problem or limitation you are having in your project: If the user accidentally creates an infinite while-loop, the running scene window will become unresponsive. No error message will be generated, so there will be no indication of what caused the problem.

Describe the feature / enhancement and how it helps to overcome the problem or limitation: There could be a global while_loop_iteration_counter variable which is increased by 1 during each while-loop iteration.

If while_loop_iteration_counter ever exceeds another global variable, while_loop_iteration_limit, Godot should throw an error and force the running scene to stop instead of letting it freeze.

If while_loop_iteration_limit is a large number like 1,000, it will detect accidental infinite loops. However, the user should be able to set the while_loop_iteration_limit in the Project Settings, in case they need a while-loop that has more than 1,000 iterations.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:

var while_loop_iteration_counter := 0
var while_loop_iteration_limit := 1000

var test_condition := true

func _ready():
    while (test_condition == true):
        "< do something >"
        increment_while_loop_iteration_counter()
    reset_while_loop_iteration_counter()

func increment_while_loop_iteration_counter():
    while_loop_iteration_counter += 1
    if while_loop_iteration_counter > while_loop_iteration_limit:
        push_error("Exceeded while-loop iteration limit.")
        assert(while_loop_iteration_counter < while_loop_iteration_limit)

func reset_while_loop_iteration_counter():
    while_loop_iteration_counter = 0

If this enhancement will not be used often, can it be worked around with a few lines of script?: This would be used every time a while-loop is used. This could be done manually, using code like I provided above, but this would be tedious to have to do (and easy to forget to do) every time the user wants to use a while-loop.

Is there a reason why this should be core and not an add-on in the asset library?: The user shouldn't have to download an add-on for a safety feature like this. It should be built-in, like being able to set the limit of characters per second that can be printed to the console output. (Project Settings/Network/Limits/Max Chars Per Second)

Dragoncraft89 commented 4 years ago

To add on this: a global counter will not be enough to track loop iterations. Take this example:

In this example, your warning wouldn't get triggered at all:

func do_stuff1():
    for i in range(10):
        print(i)
    # Here when leaving the loop, the counter is resetted

func do_stuff2():
    while True:
        do_stuff1() # Because after this call, the loop counter is resetted, the next iteration will always count as first iteration

The correct way would be to keep track in a local variable for every loop:

func example():
    var counter = 0
    while condition:
        < While body here >
       counter += 1
        if counter > while_loop_iteration_limit:
            push_error("Exceeded while-loop iteration limit.")
Dragoncraft89 commented 4 years ago

By the way, I just found this