Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent to window.setTimeout() for C++

In javascript there's this sweet, sweet function window.setTimeout( func, 1000 ) ; which will asynchronously invoke func after 1000 ms.

I want to do something similar in C++ (without multithreading), so I put together a sample loop like:

    #include <stdio.h>

    struct Callback
    {
      // The _time_ this function will be executed.
      double execTime ;

      // The function to execute after execTime has passed
      void* func ;
    } ;

    // Sample function to execute
    void go()
    {
      puts( "GO" ) ;
    }

    // Global program-wide sense of time
    double time ;

    int main()
    {
      // start the timer
      time = 0 ;

      // Make a sample callback
      Callback c1 ;
      c1.execTime = 10000 ;
      c1.func = go ;

      while( 1 )
      {
        // its time to execute it
        if( time > c1.execTime )
        {
          c1.func ; // !! doesn't work!
        }

        time++;
      }
    }

How can I make something like this work?

like image 823
bobobobo Avatar asked Mar 20 '10 22:03

bobobobo


People also ask

What can I use instead of setTimeout?

The setTimeout() is executed only once. If you need repeated executions, use setInterval() instead. Use the clearTimeout() method to prevent the function from starting.

What is Windows setTimeout?

setTimeout() The global setTimeout() method sets a timer which executes a function or specified piece of code once the timer expires.

Which is correct syntax of window setTimeout () method method?

The syntax is: setTimeout(function, milliseconds, parameter1, .... paramenterN); When you pass additional parameters to the setTimeout() method, these parameters ( parameter1 , parameter2 , etc.) will be passed to the specified function.

What is the difference between setTimeout and window setTimeout?

Assuming we're talking about browser-based JavaScript: No difference. setTimeout() simply omits the window. , which is implied. The effect they have is exactly the same. It's a choice of coding style and preference.


2 Answers

After C++11 came out, and if your are using c++11 supported compiler, you can use lambda, variadic template function and asynchronous thread to simulate javascript function in c++ easily.

Here is the code I wrote for setTimeOut, it is fully tested:

setTimeOut funtion's definition:

    #include <windows.h>//different header file in linux
    #include <future>
    using namespace std;

    template <typename... ParamTypes>
    void setTimeOut(int milliseconds,std::function<void(ParamTypes...)> func,ParamTypes... parames)
    {   
        std::async(std::launch::async,[=]()
        {       
            Sleep(milliseconds);
            func(parames...); 
        });
     };

This function accepts variable arguments by using c+11's variadic template, The code can show you how to use it:

    #include <iostream>
    #include <thread>
    #include <string>
    #include <functional>
    #include <windows.h>

    #include <future>
    using namespace std;
    int main() 
    {
        std::mutex locker;
        std::function<void()> func1 = [&]()
        {
            std::unique_lock<std::mutex> lk(locker);
            std::cout << "func 1 is trigged:" << "   no parameter" << std::endl;
            lk.unlock();
        };      
        std::function<void(int)> func2 = [&](int param)
        {
            std::unique_lock<std::mutex> lk(locker);
            std::cout << "func 2 is trigged:" << "   int: " << param <<std::endl;
            lk.unlock();
        };
        std::function<void(int,std::string)> func3 = [&](int param1,std::string param2)
        {
            std::unique_lock<std::mutex> lk(locker);
            std::cout << "func 3 is trigged:" << "   int: " << param1 << ";  string: " << param2 << std::endl;
            lk.unlock();
        };

        for(int index=0;index<100;index++)
        {
            std::unique_lock<std::mutex> lk1(locker);
            std::cout << "set timer for func  1" << std::endl;
            lk1.unlock();
            setTimeOut<>(1000,func1);

            std::unique_lock<std::mutex> lk2(locker);
            std::cout << "set timer for func  2" << std::endl;
            lk2.unlock();
            setTimeOut<int>(2000,func2,10000);

            std::unique_lock<std::mutex> lk3(locker);
            std::cout << "set timer for func  3" << std::endl;
            lk3.unlock();
            setTimeOut<int,std::string>(5000,func3,10000,"ddddd");
        }
        Sleep(10000000);
    }
like image 137
www.diwatu.com Avatar answered Sep 26 '22 20:09

www.diwatu.com


Make Callback::func of type void (*)(), i.e.

struct Callback
{
    double execTime;
    void (*func)();
};

You can call the function this way:

c1.func();

Also, don't busy-wait. Use ualarm on Linux or CreateWaitableTimer on Windows.

like image 40
avakar Avatar answered Sep 24 '22 20:09

avakar