2016-08-05 15 views
1

Lassen Sie uns sagen, dass wir in einer Funktion, die aufgerufen wird, wenn eine MaustasteC++ - verzögerte Ausführung von Code

static inline LRESULT CALLBACK WndProc(const int code, const WPARAM wParam, const LPARAM lParam){ 


} 

gedrückt möchte ich nun einige Code auszuführen, nachdem keine Taste für 5 Sekunden gedrückt wurde. Wenn der Benutzer nach 2 Sekunden eine Maustaste drückt, sollte der "Timer" zurückgesetzt werden und weitere 5 Sekunden warten.

Kann das sogar in C++ gemacht werden? Wenn ich Sleep(5000) verwende, kann ich nicht verhindern, dass der Code ausgeführt wird, wenn eine andere Taste dazwischen gedrückt wird.

+0

1. Blockieren Sie die Ausführung nicht. 2. Starten/Zurücksetzen des Zählers nach dem Mausklick. 3. Wenn die Taste gedrückt wird, prüfen Sie, ob der Zähler unter fünf Sekunden ist und reagieren Sie entsprechend. 4. Nach 5 Sekunden Zähler stoppen und auf Null stellen. Wäre dieser Ansatz nicht angemessener? – Mars

+0

Verwenden Sie SetTimer(). –

Antwort

0

Hier ist meine Klasse (es ist nicht perfekt, aber Sie können sehen, wie es getan werden könnte), um den Herzschlag des Programms hinter dem Sockel zu steuern. Wenn die Methode beat() aufgerufen wird, wird der Timer zurückgesetzt.

class HeartbeatController 
    { 
    private: 
     using ms = std::chrono::milliseconds; 
    public: 
     HeartbeatController(std::function<void()> &heartbeatLostCallback, 
          const ms &panicTime = ms{5000}, //time in milliseconds, after which panic code will be executed 
          const ms &checkDuration = ms{ 1000 }) noexcept : 
      heartbeatLostCallback{ heartbeatLostCallback } 
     {} 

     ~HeartbeatController() = default; 

     HeartbeatController(HeartbeatController &&other) : 
      heartbeatLostCallback{ std::move(other.heartbeatLostCallback) }, 
      loopThread{ std::move(other.loopThread) }, 
      lastBeat{ std::move(other.lastBeat) }, 
      panicTime{ std::move(other.panicTime) }, 
      checkDuration{ std::move(other.checkDuration) } 
     {} 

     HeartbeatController& operator=(HeartbeatController &&other) 
     { 
      heartbeatLostCallback = std::move(other.heartbeatLostCallback); 
      loopThread = std::move(other.loopThread); 
      lastBeat = std::move(other.lastBeat); 
      panicTime = std::move(other.panicTime); 
      checkDuration = std::move(other.checkDuration); 

      return *this; 
     } 

     HeartbeatController(const HeartbeatController&) = delete; 
     HeartbeatController& operator=(const HeartbeatController&) = delete; 

     void interrupt() noexcept 
     { 
      interrupted = true; 
     } 

     void beat() noexcept 
     { 
      lastBeat = Clock::now(); 
     } 

     void start() 
     { 
      auto loop = [this] 
      { 
       while (!interrupted) 
       { 
        if (Clock::now() - lastBeat > panicTime) 
         heartbeatLostCallback(); //here you can insert some your code which you wanna execute after no beat() for panicTime duration 

        std::this_thread::sleep_for(checkDuration); 
       } 
      }; 

      lastBeat = Clock::now(); 

      loopThread = std::thread{ loop }; 
     } 

    private: 
     using Clock = std::chrono::system_clock; 

     std::reference_wrapper<std::function<void()>> heartbeatLostCallback; 
     std::thread loopThread; 

     std::chrono::time_point<Clock> lastBeat; 
     std::chrono::milliseconds panicTime; 
     std::chrono::milliseconds checkDuration; 

     bool interrupted = false; 
    };