aboutsummaryrefslogtreecommitdiff
path: root/src/platform/gui/win/TimerManager.h
blob: 21c00690ed4c735c79cb9c0fa635281db4062189 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#pragma once
#include "cru/common/Event.h"
#include "cru/platform/win/WinPreConfig.h"

#include "cru/common/Base.h"
#include "cru/platform/gui/win/GodWindow.h"
#include "cru/platform/gui/win/WindowNativeMessageEventArgs.h"

#include <chrono>
#include <functional>
#include <optional>
#include <unordered_map>

namespace cru::platform::gui::win {
enum class TimerType { Immediate, Timeout, Interval };

struct TimerInfo {
  TimerInfo(long long id, TimerType type, int period,
            std::function<void()> action, UINT_PTR native_timer_id = 0)
      : id(id),
        type(type),
        period(period),
        action(std::move(action)),
        native_timer_id(native_timer_id) {}

  long long id;
  TimerType type;
  int period;  // in milliseconds
  std::function<void()> action;
  UINT_PTR native_timer_id;
};

class TimerManager : public Object {
 public:
  TimerManager(GodWindow* god_window);

  CRU_DELETE_COPY(TimerManager)
  CRU_DELETE_MOVE(TimerManager)

  ~TimerManager() override = default;

  // Period is in milliseconds. When type is immediate, it is not checked and
  // used.
  long long SetTimer(TimerType type, int period, std::function<void()> action);
  void CancelTimer(long long id);

 private:
  void HandleGodWindowMessage(WindowNativeMessageEventArgs& args);

  void CreateNativeTimer(TimerInfo* info);
  void KillNativeTimer(TimerInfo* info);

 private:
  GodWindow* god_window_;

  EventRevokerListGuard event_guard_;

  long long next_id_ = 1;
  std::unordered_map<long long, TimerInfo> info_map_;
};
}  // namespace cru::platform::gui::win