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 {
20 class GAIA_API Event final {
21#if GAIA_USE_MT_STD
22 GAIA_PROF_MUTEX(std::mutex, m_mtx);
23 std::condition_variable m_cv;
24 bool m_set = false;
25#else
26 pthread_cond_t m_hCondHandle;
27 pthread_mutex_t m_hMutexHandle;
28 bool m_set = false;
29#endif
30
31 public:
32#if !GAIA_USE_MT_STD
35 [[maybe_unused]] int ret = pthread_mutex_init(&m_hMutexHandle, nullptr);
36 GAIA_ASSERT(ret == 0);
37 if (ret == 0) {
38 ret = pthread_cond_init(&m_hCondHandle, nullptr);
39 GAIA_ASSERT(ret == 0);
40 }
41 }
42
45 [[maybe_unused]] int ret = pthread_cond_destroy(&m_hCondHandle);
46 GAIA_ASSERT(ret == 0);
47
48 ret = pthread_mutex_destroy(&m_hMutexHandle);
49 GAIA_ASSERT(ret == 0);
50 }
51#endif
52
54 void set() {
55#if GAIA_USE_MT_STD
56 auto& mtx = GAIA_PROF_EXTRACT_MUTEX(m_mtx);
57 std::unique_lock lock(mtx);
58 GAIA_PROF_LOCK_MARK(m_mtx);
59 m_set = true;
60 m_cv.notify_one();
61#else
62 [[maybe_unused]] int ret = pthread_mutex_lock(&m_hMutexHandle);
63 GAIA_ASSERT(ret == 0);
64 m_set = true;
65
66 // Depending on the event type, we either trigger everyone waiting or just one
67 ret = pthread_cond_signal(&m_hCondHandle);
68 GAIA_ASSERT(ret == 0);
69
70 ret = pthread_mutex_unlock(&m_hMutexHandle);
71 GAIA_ASSERT(ret == 0);
72#endif
73 }
74
76 void reset() {
77#if GAIA_USE_MT_STD
78 auto& mtx = GAIA_PROF_EXTRACT_MUTEX(m_mtx);
79 std::unique_lock lock(mtx);
80 GAIA_PROF_LOCK_MARK(m_mtx);
81 m_set = false;
82#else
83 [[maybe_unused]] int ret = pthread_mutex_lock(&m_hMutexHandle);
84 GAIA_ASSERT(ret == 0);
85 m_set = false;
86 ret = pthread_mutex_unlock(&m_hMutexHandle);
87 GAIA_ASSERT(ret == 0);
88#endif
89 }
90
93 GAIA_NODISCARD bool is_set() {
94#if GAIA_USE_MT_STD
95 auto& mtx = GAIA_PROF_EXTRACT_MUTEX(m_mtx);
96 std::unique_lock lock(mtx);
97 GAIA_PROF_LOCK_MARK(m_mtx);
98 return m_set;
99#else
100 bool set{};
101 [[maybe_unused]] int ret = pthread_mutex_lock(&m_hMutexHandle);
102 GAIA_ASSERT(ret == 0);
103 set = m_set;
104 ret = pthread_mutex_unlock(&m_hMutexHandle);
105 GAIA_ASSERT(ret == 0);
106 return set;
107#endif
108 }
109
111 void wait() {
112#if GAIA_USE_MT_STD
113 auto& mtx = GAIA_PROF_EXTRACT_MUTEX(m_mtx);
114 std::unique_lock lock(mtx);
115 GAIA_PROF_LOCK_MARK(m_mtx);
116 m_cv.wait(lock, [&] {
117 return m_set;
118 });
119#else
120 [[maybe_unused]] int ret{};
121 auto wait = [&]() {
122 if (!m_set) {
123 do {
124 ret = pthread_cond_wait(&m_hCondHandle, &m_hMutexHandle);
125 } while (!ret && !m_set);
126
127 GAIA_ASSERT(ret != EINVAL);
128 if (!ret)
129 m_set = false;
130 } else {
131 ret = 0;
132 }
133
134 return ret;
135 };
136
137 ret = pthread_mutex_lock(&m_hMutexHandle);
138 GAIA_ASSERT(ret == 0);
139
140 int res = wait(); // true: signaled, false: timeout or error
141 (void)res;
142
143 ret = pthread_mutex_unlock(&m_hMutexHandle);
144 GAIA_ASSERT(ret == 0);
145#endif
146 }
147 }; // namespace mt
148 } // namespace mt
149} // namespace gaia
Manual-reset style synchronization primitive for waking a waiting thread. The event stays signaled un...
Definition event.h:20
void wait()
Blocks the calling thread until the event becomes signaled.
Definition event.h:111
void set()
Sets the event to the signaled state and wakes one waiting thread.
Definition event.h:54
Event()
Creates an unsignaled event and initializes the underlying pthread objects.
Definition event.h:34
void reset()
Resets the event to the unsignaled state.
Definition event.h:76
GAIA_NODISCARD bool is_set()
Checks whether the event currently is in the signaled state.
Definition event.h:93
~Event()
Destroys the underlying pthread synchronization objects.
Definition event.h:44
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9