Godot Engine C++ GDnative sleep code for 1 second "yield(get_tree().create_timer(1), "timeout")"

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By ariel

Is there a way to stop the flow of the code using C ++ with Gdnative?
I saw several old answers on the godot forums, but they don’t show the correct way to do it.

First I would like to clarify that there are libraries to sleep the code for a second

For example with the windows library.

#include <iostream>
#include <Windows.h>
#include <stdio.h>

int main()
{
    for (int i = 0; i < 5; i++)
   {
       Godot::print("IT WOULD HAVE A SECOND");
       Sleep(1000); // stop the code for a second as if it were yield (get_tree (). create_timer (1), "timeout") of godot.
       printf("hola mundo \n");
   }
    return 0;
}

For example with the chrono and thread library.

#include <iostream>
#include <stdio.h>
#include <chrono>
#include <thread>

int main()
{
    for (int i = 0; i < 5; i++)
    {
        Godot::print("IT WOULD HAVE A SECOND");
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));// stop the code for a second as if it were yield (get_tree (). create_timer (1), "timeout") of godot.
    }
    return 0;
}

#I tried to implement this with the GDnative plugin, but it doesn’t work, that is, it makes the code sleep for a second, but it doesn’t start the game until it’s finished.

Is there any way that this works? … I saw that if in the compilation we added a feature or directive to scons it could work, although I do not know if it is true.

-------------------------------------------------------------------------------------------------------------

So I tried to solve it using thread but it doesn’t start until I finish, if I use SO the same thing happens and if I use timers the code becomes complete chaos and it doesn’t seem practical.

// Using OS, it doesn’t work. Until the console does not execute all the threads it does not start the game

#include <OS.hpp>

void TestDelay::DelayWithOS() 
{
    OS *_OS = OS::get_singleton();
    for (size_t i = 0; i < 5; i++)
    {
        Godot::print("IT WOULD HAVE A SECOND");
        _OS->delay_msec(1000);
    }
}

Example using godot threads. It does not work. Until the console does not execute all the threads it does not start the game

#include <SceneTree.hpp>
#include<windows.h>
#include <chrono>
#include <thread>

void TestDelay::CreateThread() 
{
    godot::Thread *nuevoHilo = Thread()._new();//creo el thread(hilo) pero no lo inicia

    nuevoHilo->start(this,"NewThreadWithSleep",NULL,0);//ahora si que inicio el tread

    Godot::print("NEW THREAD ID = " +  nuevoHilo->get_id() );
    
    String HiloActivado = nuevoHilo->is_active() ? "TRUE" : "FALSE";//para obtener texto de un bool
    Godot::print("TREAD IS ACTIVE = " + HiloActivado );//para saber si es verdadero o falso

    Variant waitForThread = nuevoHilo->wait_to_finish();
    Godot::print("THREAD FINISH = " +  String::num_int64(waitForThread) );
    
    HiloActivado = nuevoHilo->is_active() ? "TRUE" : "FALSE";//para obtener texto de un bool
    Godot::print("TREAD IS ACTIVE = " + HiloActivado );//para saber si es verdadero o falso
}

void TestDelay::NewThreadWithSleep(godot::Variant userdata) 
{
    // OS *_OS = OS::get_singleton();
    Godot::print("I'M INSIDE A THREAD");
    for (size_t i = 0; i < 7; i++)
    {
        Godot::print("IT WOULD HAVE A SECOND");
        // _OS->delay_msec(1000); //USING OS stop the code for a second as if it were yield (get_tree (). create_timer (1), "timeout") of godot.
        // Sleep(1000); //USING Sleep WINDOWS stop the code for a second as if it were yield (get_tree (). create_timer (1), "timeout") of godot.
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));// stop the code for a second as if it were yield (get_tree (). create_timer (1), "timeout") of godot.
    }
}

// USING TIMERS, It works but it is very complicated, it is not useful to put into practice and it is not like a yield (get_tree (). Create_timer (1), “timeout”) of godot

#include <Timer.hpp>

void TestDelay::CreateTimer() 
{
    Timer* timer = Timer()._new();
    if(timer ==nullptr ) return;
    timer->set_name( "TIMER_CREATED_ON_DYNAMICALLY_SCENE" );
    timer->set_wait_time(1);
    timer->set_one_shot(true);
    add_child(timer);
    timer->connect("timeout",this,"_on_Timer_timeout");
    timer->start();
}

void TestDelay::_on_Timer_timeout() 
{
    Godot::print("IT WOULD HAVE A SECOND");
    CreateTimer();
}