#pragma once #include "util/types.hpp" #include "util/atomic.hpp" #include "util/lockless.h" #include "util/shared_ptr.hpp" extern lf_array> g_progr_text_queue; struct alignas(16) progress_dialog_string_t { struct alignas(16) data_t { usz update_id = 0; u32 text_index = umax; u32 text_count = 0; }; atomic_t data{}; shared_ptr get_string_ptr() const noexcept; operator std::string() const noexcept { if (shared_ptr ptr = get_string_ptr()) { return *ptr; } return {}; } explicit operator bool() const noexcept { return data.load().text_count != 0; } }; enum system_progress_stop_state : u32 { stop_state_disabled = 0, stop_state_stopping, stop_state_continuous_savestate }; extern progress_dialog_string_t g_progr_text; extern atomic_t g_progr_ftotal; extern atomic_t g_progr_fdone; extern atomic_t g_progr_ftotal_bits; extern atomic_t g_progr_fknown_bits; extern atomic_t g_progr_ptotal; extern atomic_t g_progr_pdone; extern atomic_t g_system_progress_canceled; extern atomic_t g_system_progress_stopping; // Initialize progress dialog (can be recursive) class scoped_progress_dialog final { private: u32 m_text_index = 0; public: scoped_progress_dialog(std::string text) noexcept; scoped_progress_dialog(const scoped_progress_dialog&) = delete; scoped_progress_dialog& operator=(const scoped_progress_dialog&) = delete; scoped_progress_dialog& operator=(std::string text) noexcept; ~scoped_progress_dialog() noexcept; }; struct progress_dialog_server { void operator()(); ~progress_dialog_server(); static constexpr auto thread_name = "Progress Dialog Server"sv; }; struct progress_dialog_workaround { // We don't want to show the native dialog during gameplay. atomic_t show_overlay_message_only = false; };