11#include "../utility/utility.hpp"
14#include "../macros.hpp"
24namespace hi {
inline namespace v1 {
38hi_no_inline
typename T::value_type start_subsystem(
40 typename T::value_type off_value,
41 typename T::value_type (*init_function)(),
42 void (*deinit_function)())
43 requires(is_atomic_v<T>)
45 hi_assert_not_null(init_function);
46 hi_assert_not_null(deinit_function);
49 hilet old_value = check_variable.load(std::memory_order::acquire);
50 if (old_value != off_value) {
61 auto new_value = init_function();
63 if (new_value != off_value) {
65 check_variable.store(new_value, std::memory_order::release);
73 hi_assert(std::popcount(std::to_underlying(state_bit)) == 1);
74 hi_assert_not_null(init_function);
75 hi_assert_not_null(deinit_function);
77 hilet lock = std::scoped_lock(subsystem_mutex);
79 hilet old_state =
global_state.load(std::memory_order::acquire);
85 }
else if (to_bool(old_state & state_bit)) {
90 if (init_function()) {
91 subsystem_deinit_list.emplace_back(deinit_function);
118 typename T::value_type off_value,
119 typename T::value_type (*init_function)(),
120 void (*deinit_function)())
121 requires(is_atomic_v<T>)
126 hilet old_value = check_variable.load(std::memory_order::relaxed);
127 if (old_value == off_value) {
128 return detail::start_subsystem(check_variable, off_value, init_function, deinit_function);
130 [[likely]]
return old_value;
152 if (not to_bool(
global_state.load(std::memory_order::relaxed) & state_bit)) {
153 return detail::start_subsystem(state_bit, init_function, deinit_function);
155 [[likely]]
return true;
177 requires(is_atomic_v<T>)
180 typename T::value_type off_value,
181 typename T::value_type (*init_function)(),
182 void (*deinit_function)())
184 auto old_value = check_variable.load(std::memory_order::acquire);
185 if (old_value == off_value) {
186 auto tmp = detail::start_subsystem(check_variable, off_value, init_function, deinit_function);
187 hi_assert(tmp != off_value);
190 [[likely]]
return old_value;
204 hi_assert_not_null(deinit_function);
206 hilet lock = std::scoped_lock(detail::subsystem_mutex);
208 std::erase(detail::subsystem_deinit_list, deinit_function);
209 return deinit_function();
232 detail::subsystem_mutex.lock();
233 global_state |= global_state_type::system_is_shutting_down;
235 while (!detail::subsystem_deinit_list.empty()) {
236 auto deinit =
std::move(detail::subsystem_deinit_list.back());
237 hi_assert_not_null(deinit);
238 detail::subsystem_deinit_list.pop_back();
240 detail::subsystem_mutex.unlock();
242 detail::subsystem_mutex.lock();
244 detail::subsystem_mutex.unlock();
Definition of the unfair_recursive_mutex.
An atomic access global variable for quick access to state of the system.
unfair_recursive_mutex subsystem_mutex
Mutex to be held when writing to system_status or accessing system_status_deinit_list.
Definition subsystem.hpp:35
std::vector< void(*)()> subsystem_deinit_list
A list of deinit function to be called on shutdown.
Definition subsystem.hpp:29
bool global_state_enable(global_state_type subsystem, std::memory_order order=std::memory_order::seq_cst) noexcept
Enable a subsystem.
Definition global_state.hpp:260
bool is_system_running() noexcept
Check if the HikoGUI system is running.
Definition global_state.hpp:209
void shutdown_system() noexcept
Shutdown the system.
Definition subsystem.hpp:230
T::value_type start_subsystem(T &check_variable, typename T::value_type off_value, typename T::value_type(*init_function)(), void(*deinit_function)())
Start a sub-system.
Definition subsystem.hpp:116
std::atomic< global_state_type > global_state
The global state of the hikogui framework.
Definition global_state.hpp:201
T::value_type start_subsystem_or_terminate(T &check_variable, typename T::value_type off_value, typename T::value_type(*init_function)(), void(*deinit_function)())
Start a sub-system.
Definition subsystem.hpp:178
global_state_type
The flag-type used for global state.
Definition global_state.hpp:30
void stop_subsystem(void(*deinit_function)())
Stop a sub-system.
Definition subsystem.hpp:202
void start_system() noexcept
Start the system.
Definition subsystem.hpp:217
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
The HikoGUI API version 1.
Definition lookahead_iterator.hpp:6
An unfair recursive-mutex This is a fast implementation of a recursive-mutex which does not fairly ar...
Definition unfair_recursive_mutex.hpp:38