Gaia-ECS v0.9.3
A simple and powerful entity component system
Loading...
Searching...
No Matches
event.h
1#pragma once
2#include "gaia/config/config.h"
3#include "gaia/config/profiler.h"
4
5#if GAIA_PLATFORM_WINDOWS
6 #define GAIA_USE_MT_STD 1
7#endif
8
9#if GAIA_USE_MT_STD
10 #include <condition_variable>
11 #include <mutex>
12#else
13 #include <pthread.h>
14#endif
15
16namespace gaia {
17 namespace mt {
18 class GAIA_API Event final {
19#if GAIA_USE_MT_STD
20 GAIA_PROF_MUTEX(std::mutex, m_mtx);
21 std::condition_variable m_cv;
22 bool m_set = false;
23#else
24 pthread_cond_t m_hCondHandle;
25 pthread_mutex_t m_hMutexHandle;
26 bool m_set = false;
27#endif
28
29 public:
30#if !GAIA_USE_MT_STD
31 Event() {
32 [[maybe_unused]] int ret = pthread_mutex_init(&m_hMutexHandle, nullptr);
33 GAIA_ASSERT(ret == 0);
34 if (ret == 0) {
35 ret = pthread_cond_init(&m_hCondHandle, nullptr);
36 GAIA_ASSERT(ret == 0);
37 }
38 }
39
40 ~Event() {
41 [[maybe_unused]] int ret = pthread_cond_destroy(&m_hCondHandle);
42 GAIA_ASSERT(ret == 0);
43
44 ret = pthread_mutex_destroy(&m_hMutexHandle);
45 GAIA_ASSERT(ret == 0);
46 }
47#endif
48
49 void set() {
50#if GAIA_USE_MT_STD
51 auto& mtx = GAIA_PROF_EXTRACT_MUTEX(m_mtx);
52 std::unique_lock lock(mtx);
53 GAIA_PROF_LOCK_MARK(m_mtx);
54 m_set = true;
55 m_cv.notify_one();
56#else
57 [[maybe_unused]] int ret = pthread_mutex_lock(&m_hMutexHandle);
58 GAIA_ASSERT(ret == 0);
59 m_set = true;
60
61 // Depending on the event type, we either trigger everyone waiting or just one
62 ret = pthread_cond_signal(&m_hCondHandle);
63 GAIA_ASSERT(ret == 0);
64
65 ret = pthread_mutex_unlock(&m_hMutexHandle);
66 GAIA_ASSERT(ret == 0);
67#endif
68 }
69
70 void reset() {
71#if GAIA_USE_MT_STD
72 auto& mtx = GAIA_PROF_EXTRACT_MUTEX(m_mtx);
73 std::unique_lock lock(mtx);
74 GAIA_PROF_LOCK_MARK(m_mtx);
75 m_set = false;
76#else
77 [[maybe_unused]] int ret = pthread_mutex_lock(&m_hMutexHandle);
78 GAIA_ASSERT(ret == 0);
79 m_set = false;
80 ret = pthread_mutex_unlock(&m_hMutexHandle);
81 GAIA_ASSERT(ret == 0);
82#endif
83 }
84
85 GAIA_NODISCARD bool is_set() {
86#if GAIA_USE_MT_STD
87 auto& mtx = GAIA_PROF_EXTRACT_MUTEX(m_mtx);
88 std::unique_lock lock(mtx);
89 GAIA_PROF_LOCK_MARK(m_mtx);
90 return m_set;
91#else
92 bool set{};
93 [[maybe_unused]] int ret = pthread_mutex_lock(&m_hMutexHandle);
94 GAIA_ASSERT(ret == 0);
95 set = m_set;
96 ret = pthread_mutex_unlock(&m_hMutexHandle);
97 GAIA_ASSERT(ret == 0);
98 return set;
99#endif
100 }
101
102 void wait() {
103#if GAIA_USE_MT_STD
104 auto& mtx = GAIA_PROF_EXTRACT_MUTEX(m_mtx);
105 std::unique_lock lock(mtx);
106 GAIA_PROF_LOCK_MARK(m_mtx);
107 m_cv.wait(lock, [&] {
108 return m_set;
109 });
110#else
111 [[maybe_unused]] int ret{};
112 auto wait = [&]() {
113 if (!m_set) {
114 do {
115 ret = pthread_cond_wait(&m_hCondHandle, &m_hMutexHandle);
116 } while (!ret && !m_set);
117
118 GAIA_ASSERT(ret != EINVAL);
119 if (!ret)
120 m_set = false;
121 } else {
122 ret = 0;
123 }
124
125 return ret;
126 };
127
128 ret = pthread_mutex_lock(&m_hMutexHandle);
129 GAIA_ASSERT(ret == 0);
130
131 int res = wait(); // true: signaled, false: timeout or error
132 (void)res;
133
134 ret = pthread_mutex_unlock(&m_hMutexHandle);
135 GAIA_ASSERT(ret == 0);
136#endif
137 }
138 }; // namespace mt
139 } // namespace mt
140} // namespace gaia
Definition event.h:18
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9