#include "externals.hh" #include "common.hh" #include "ui.hh" #include "ui-app.hh" #include "ui-odbg.hh" #include "ui-profiling.hh" #include "ui-shaders.hh" #include "ui-sync.hh" #include "ui-texture.hh" namespace { const char FullscreenShader_[] = { # include "bs-fullscreen.inl" , 0 }; const char CopyShader_[] = { # include "bs-copy.inl" , 0 }; struct UIData_ { Common common; T_UIApp window; T_Profiler profiler; T_TextureManager textures; T_ShaderManager shaders; T_ShaderProgram fsShader{ shaders.program( "*fullscreen" , E_ShaderType::VERTEX , FullscreenShader_ ) }; T_ShaderProgram copyShader{ shaders.program( "*copy" , E_ShaderType::FRAGMENT , CopyShader_ ) }; T_OutputDebugger odbg; T_UISync sync; UIData_( T_FSPath const& path ) noexcept : common{ path } {} }; uint32_t Initialised_{ 0 }; std::aligned_storage_t< sizeof( UIData_ ) , alignof( UIData_ ) > Instance_; } // namespace /*----------------------------------------------------------------------------*/ UI::UI( T_FSPath const& path ) noexcept { if ( !Initialised_ ++ ) { new ((char*)&Instance_) UIData_( path ); } } UI::~UI( ) noexcept { assert( Initialised_ ); if ( !-- Initialised_ ) { ((UIData_*)(char*)&Instance_)->~UIData_( ); } } /*----------------------------------------------------------------------------*/ #define M_GET_( P ) ((UIData_*)(char*)&Instance_)->P T_UIApp& UI::Main( ) noexcept { return M_GET_( window ); } T_Profiler& UI::Profiler( ) noexcept { return M_GET_( profiler ); } T_TextureManager& UI::Textures( ) noexcept { return M_GET_( textures ); } T_ShaderManager& UI::Shaders( ) noexcept { return M_GET_( shaders ); } T_ShaderProgram& UI::FullscreenShader( ) noexcept { return M_GET_( fsShader ); } T_ShaderProgram& UI::CopyShader( ) noexcept { return M_GET_( copyShader ); } T_OutputDebugger& UI::ODbg( ) noexcept { return M_GET_( odbg ); } T_UISync& UI::Sync( ) noexcept { return M_GET_( sync ); }