From ae3958f785be8e54d678140a1066a490a3ccf5ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Fri, 24 Nov 2017 14:52:56 +0100 Subject: [PATCH] Project manager - Use project path to load everything + Curves, script and shaders are loaded from the path of the project. + Main tool can be passed a parameter to specify the project's root. --- c-opcomp.hh | 25 +++++++++++++++---------- c-opmgr.cc | 26 ++++++++++++++++++++------ c-project.hh | 8 +++++++- c-sync.cc | 26 ++++++++++++++++++++++---- c-sync.hh | 11 ++++++++--- common.cc | 14 ++++++++++++-- common.hh | 4 +++- m-tool.cc | 10 +++++----- ui-opemu.cc | 3 +-- ui-shaders.cc | 17 +++++++++++------ ui-texture.cc | 10 +++++----- ui.cc | 4 ++-- ui.hh | 2 +- 13 files changed, 112 insertions(+), 48 deletions(-) diff --git a/c-opcomp.hh b/c-opcomp.hh index 423ab03..d833ee6 100644 --- a/c-opcomp.hh +++ b/c-opcomp.hh @@ -1,6 +1,7 @@ #pragma once #include "c-filewatcher.hh" #include "c-opast.hh" +#include "c-project.hh" #include @@ -52,19 +53,11 @@ class T_OpsCompiler : public ebcl::A_PrivateImplementation // The script manager watches over the demo's script, attempting to reload it if // it is changed. -class T_ScriptManager +class T_ScriptManager : public A_ProjectPathListener { - private: - T_WatchedFiles watcher_; - - T_OpsParser parser_; - T_OpsCompiler compiler_; - - ops::P_OpProgram output_; - T_Array< ebcl::T_SRDError > errors_; - public: T_ScriptManager( ) noexcept; + ~T_ScriptManager( ); bool hasNewProgram( ) const noexcept { return bool( output_ ); } @@ -76,5 +69,17 @@ class T_ScriptManager { return errors_; } private: + T_String path_; + T_WatchedFiles watcher_; + + T_OpsParser parser_; + T_OpsCompiler compiler_; + + ops::P_OpProgram output_; + T_Array< ebcl::T_SRDError > errors_; + void loadScript( ) noexcept; + + protected: + void projectPathChanged( ) noexcept override; }; diff --git a/c-opmgr.cc b/c-opmgr.cc index 33c5318..bf8fb1f 100644 --- a/c-opmgr.cc +++ b/c-opmgr.cc @@ -45,18 +45,32 @@ T_ScriptManager::T_ScriptManager( ) noexcept } ) , parser_( ) , compiler_( ) { - watcher_.watch( T_String::Pooled( "demo.srd" ) ); + Common::Project( ).addListener( this ); + projectPathChanged( ); +} + +T_ScriptManager::~T_ScriptManager( ) +{ + Common::Project( ).removeListener( this ); +} + +void T_ScriptManager::projectPathChanged( ) noexcept +{ + path_ = Common::Project( ).pathOf( "demo.srd" ); + watcher_.clear( ); + watcher_.watch( path_ ); loadScript( ); } +/*----------------------------------------------------------------------------*/ + void T_ScriptManager::loadScript( ) noexcept { output_.clear( ); errors_.clear( ); using namespace ebcl; - const T_String inputName( T_String::Pooled( "demo.srd" ) ); - T_File input( inputName , E_FileMode::READ_ONLY ); + T_File input( path_ , E_FileMode::READ_ONLY ); try { input.open( ); } catch ( X_StreamError const& e ) { @@ -66,7 +80,7 @@ void T_ScriptManager::loadScript( ) noexcept sb << " (error code " << e.systemError( ) << ")"; } errors_.addNew( std::move( sb ) , - T_SRDLocation{ inputName , 1 , 1 } ); + T_SRDLocation{ path_ , 1 , 1 } ); DumpSRDErrors( "Script not found" , errors_ ); return; } @@ -77,7 +91,7 @@ void T_ScriptManager::loadScript( ) noexcept try { T_SRDTextReader srdReader{ srdOut }; T_FileInputStream fis{ input }; - srdReader.read( inputName , fis ); + srdReader.read( path_ , fis ); } catch ( X_StreamError const& e ) { T_StringBuilder sb; sb << "could not load: " << e.what( ); @@ -85,7 +99,7 @@ void T_ScriptManager::loadScript( ) noexcept sb << " (error code " << e.systemError( ) << ")"; } errors_.addNew( std::move( sb ) , - T_SRDLocation{ inputName , 1 , 1 } ); + T_SRDLocation{ path_ , 1 , 1 } ); DumpSRDErrors( "Script not loaded" , errors_ ); return; diff --git a/c-project.hh b/c-project.hh index 2207b3e..c9683d0 100644 --- a/c-project.hh +++ b/c-project.hh @@ -5,16 +5,22 @@ #include +struct T_Project; class A_ProjectPathListener { + friend struct T_Project; public: virtual ~A_ProjectPathListener( ) = 0; + protected: virtual void projectPathChanged( ) noexcept = 0; }; struct T_Project { + explicit T_Project( T_String const& path ) noexcept + { setBasePath( path ); } + void setBasePath( T_String const& path ) noexcept; T_String const& basePath( ) const noexcept @@ -29,7 +35,7 @@ struct T_Project { listeners_.remove( listener ); } private: - T_String basePath_{ T_String::Pooled( "." ) }; + T_String basePath_; ebcl::T_Set< A_ProjectPathListener* > listeners_{ ebcl::UseTag< ebcl::ArrayBacked< 16 > >( ) }; diff --git a/c-sync.cc b/c-sync.cc index 7c1fc3c..32965ac 100644 --- a/c-sync.cc +++ b/c-sync.cc @@ -488,15 +488,23 @@ T_SyncOverrideVisitor::T_OpElement T_SyncOverrideVisitor::nodeBrowser( /*= T_SyncManager ============================================================*/ -T_SyncManager::T_SyncManager( ) +T_SyncManager::T_SyncManager( ) noexcept : pConfig_( MakeCurvesParser_( ) ) , watcher_{ Common::Watcher( ) , [this](){ curvesChanged_( ); } } , soRoot_( "*root*" ) { - watcher_.watch( "curves.srd" ); + auto& p{ Common::Project( ) }; + p.addListener( this ); + curvesFile_ = p.pathOf( "curves.srd" ); + watcher_.watch( curvesFile_ ); loadCurves( false ); } +T_SyncManager::~T_SyncManager( ) +{ + Common::Project( ).removeListener( this ); +} + /*----------------------------------------------------------------------------*/ void T_SyncManager::setDuration( @@ -576,13 +584,13 @@ bool T_SyncManager::loadCurves( try { using namespace ebcl; const T_SRDParserConfig cfg( MakeCurvesParser_( ) ); - T_File file( "curves.srd" , E_FileMode::READ_ONLY ); + T_File file( curvesFile_ , E_FileMode::READ_ONLY ); file.open( ); T_FileInputStream fis( file ); T_SRDParser parser( cfg ); T_SRDTextReader reader( parser ); - reader.read( "curves.srd" , fis ); + reader.read( curvesFile_ , fis ); p = parser.getData< T_SharedPtr< T_ParserOutput_ > >( ); } catch ( ebcl::X_StreamError const& e ) { @@ -780,3 +788,13 @@ void T_SyncManager::visitOverrides( { soVisitor_.visitor.visit( &soRoot_ , visitor ); } + +/*----------------------------------------------------------------------------*/ + +void T_SyncManager::projectPathChanged( ) noexcept +{ + curvesFile_ = Common::Project( ).pathOf( "curves.srd" ); + watcher_.clear( ); + watcher_.watch( curvesFile_ ); + loadCurves( false ); +} diff --git a/c-sync.hh b/c-sync.hh index e25862a..dadf700 100644 --- a/c-sync.hh +++ b/c-sync.hh @@ -1,5 +1,6 @@ #pragma once #include "c-filewatcher.hh" +#include "c-project.hh" #include #include @@ -272,10 +273,10 @@ struct T_SyncOverrideVisitor // Synchronisation manager; handles all the synchronization data and makes it // work together. -struct T_SyncManager +struct T_SyncManager : public virtual A_ProjectPathListener { - T_SyncManager( ); - + T_SyncManager( ) noexcept; + ~T_SyncManager( ); // --------------------------------------------------------------------- // Duration & time controls @@ -380,6 +381,7 @@ struct T_SyncManager private: ebcl::T_SRDParserConfig pConfig_; // Parser config for curves + T_String curvesFile_; // Path to the curves file T_WatchedFiles watcher_; // Curves file watcher bool saving_{ false }; // True if file is being saved bool modified_; // Locally modified @@ -396,4 +398,7 @@ struct T_SyncManager T_SyncOverrideVisitor soVisitor_; T_KeyValueTable< T_String , A_SyncOverride* > soTable_; // Table of sync overrides, by ID + + protected: + void projectPathChanged( ) noexcept; }; diff --git a/common.cc b/common.cc index 8c2928c..5492d5a 100644 --- a/common.cc +++ b/common.cc @@ -4,6 +4,7 @@ #include "c-filewatcher.hh" #include "c-opcomp.hh" #include "c-ops.hh" +#include "c-project.hh" #include "c-sync.hh" #include "c-undo.hh" @@ -12,10 +13,15 @@ namespace { struct CommonData_ { + T_Project project; T_FilesWatcher watcher; T_SyncManager sync; T_ScriptManager ops; T_UndoManager undo; + + CommonData_( T_String const& path ) noexcept + : project{ path } + {} }; std::aligned_storage_t< sizeof( CommonData_ ) , alignof( CommonData_ ) > Instance_; @@ -24,9 +30,10 @@ std::aligned_storage_t< sizeof( CommonData_ ) , alignof( CommonData_ ) > Instanc /*----------------------------------------------------------------------------*/ -void Common::Init( ) noexcept +void Common::Init( + T_String const& path ) noexcept { - new ((char*)&Instance_) CommonData_( ); + new ((char*)&Instance_) CommonData_( path ); } void Common::Shutdown( ) noexcept @@ -38,6 +45,9 @@ void Common::Shutdown( ) noexcept #define M_GET_( P ) ((CommonData_*)(char*)&Instance_)->P +T_Project& Common::Project( ) noexcept + { return M_GET_( project ); } + T_FilesWatcher& Common::Watcher( ) noexcept { return M_GET_( watcher ); } diff --git a/common.hh b/common.hh index bc9b109..dd15887 100644 --- a/common.hh +++ b/common.hh @@ -4,6 +4,7 @@ #endif +struct T_Project; struct T_FilesWatcher; struct T_SyncManager; struct T_ScriptManager; @@ -12,9 +13,10 @@ class T_UndoManager; struct Common { - static void Init( ) noexcept; + static void Init( T_String const& path = {} ) noexcept; static void Shutdown( ) noexcept; + static T_Project& Project( ) noexcept; static T_FilesWatcher& Watcher( ) noexcept; static T_SyncManager& Sync( ) noexcept; static T_ScriptManager& Ops( ) noexcept; diff --git a/m-tool.cc b/m-tool.cc index 8ac21d9..235dcc7 100644 --- a/m-tool.cc +++ b/m-tool.cc @@ -22,7 +22,7 @@ struct T_Main { static constexpr uint32_t ResizeDelay = 50; - T_Main( ); + T_Main( char const* path ); ~T_Main( ); void mainLoop( ); @@ -45,9 +45,9 @@ struct T_Main /*----------------------------------------------------------------------------*/ -T_Main::T_Main( ) +T_Main::T_Main( char const* const path ) { - UI::Init( ); + UI::Init( path ); prevSize = ImVec2( -1 , -1 ); } @@ -199,9 +199,9 @@ void T_Main::render( ) /*============================================================================*/ -int main( int , char** ) +int main( int argc , char** argv ) { - T_Main m; + T_Main m{ argc < 2 ? "." : argv[ 1 ] }; m.mainLoop( ); return 0; } diff --git a/ui-opemu.cc b/ui-opemu.cc index 580f897..7fbe27d 100644 --- a/ui-opemu.cc +++ b/ui-opemu.cc @@ -100,8 +100,7 @@ void T_OpContext::run( while ( !stack.empty( ) ) { auto const& instr{ program.ops[ instrPtr ] }; -//#define YOUR_MUM_IS_A_TRACE -#ifdef YOUR_MUM_IS_A_TRACE +#ifdef INVASIVE_TRACES GL_ASSERT( ); T_StringBuilder sb; sb << "\nEXECUTE " << instrPtr << ":\t(" << instr << ") {" diff --git a/ui-shaders.cc b/ui-shaders.cc index 5cd3958..72dc13d 100644 --- a/ui-shaders.cc +++ b/ui-shaders.cc @@ -1,5 +1,8 @@ #include "externals.hh" + #include "common.hh" +#include "c-project.hh" + #include "ui.hh" #include "ui-shaders.hh" #include "ui-utilities.hh" @@ -694,9 +697,8 @@ void T_ShaderManager::update( ) for ( auto it = missing_.keys( ).cbegin( ) ; it.valid( ) ; ++it ) { const bool exists( ([&sb] ( T_String const& name ) -> bool { struct stat buffer; - sb.clear( ); sb << "shaders/" << name << '\0'; - return ( stat( sb.data( ) , &buffer ) == 0 ); + return ( stat( Common::Project( ).pathOf( std::move( sb ) ).data( ) , &buffer ) == 0 ); })( *it ) ); if ( !exists ) { continue; @@ -878,9 +880,12 @@ T_ShaderInput const* T_ShaderManager::getInput( } T_ShaderInput ni; - T_StringBuilder sb; - sb << "shaders/" << name; - if ( !ni.load( sb ) ) { + const T_String path{ [&]() -> T_String { + T_StringBuilder sb; + sb << "shaders/" << name; + return std::move( sb ); + }() }; + if ( !ni.load( Common::Project( ).pathOf( path ) ) ) { return nullptr; } inputs_.add( name , NewOwned< T_ShaderInput >( std::move( ni ) ) ); @@ -1020,7 +1025,7 @@ void T_ShaderManager::initProgram( if ( code.files.values( )[ i ] ) { T_StringBuilder sb; sb << "shaders/" << fn; - w.watch( std::move( sb ) ); + w.watch( Common::Project( ).pathOf( std::move( sb ) ) ); } else { auto& mset( missing_.getOrCreate( fn ) ); if ( !mset.contains( name ) ) { diff --git a/ui-texture.cc b/ui-texture.cc index a000b44..309d8aa 100644 --- a/ui-texture.cc +++ b/ui-texture.cc @@ -78,7 +78,7 @@ T_Texture::T_Texture( assert( w && h ); } - GL_ASSERT( ); +// GL_ASSERT( ); } T_Texture::~T_Texture( ) @@ -141,7 +141,7 @@ T_Texture& T_Texture::wrap( T_TextureSampler::T_TextureSampler( ) { glGenSamplers( 1 , &id_ ); - GL_ASSERT( ); + //GL_ASSERT( ); } T_TextureSampler::T_TextureSampler( @@ -214,7 +214,7 @@ T_TextureSampler& T_TextureSampler::wrap( } glSamplerParameteri( id_ , GL_TEXTURE_WRAP_S , gm ); glSamplerParameteri( id_ , GL_TEXTURE_WRAP_T , gm ); - GL_ASSERT( ); + //GL_ASSERT( ); return *this; } @@ -224,7 +224,7 @@ T_TextureSampler& T_TextureSampler::lod( { glSamplerParameterf( id_ , GL_TEXTURE_MIN_LOD , min ); glSamplerParameterf( id_ , GL_TEXTURE_MAX_LOD , max ); - GL_ASSERT( ); + //GL_ASSERT( ); return *this; } @@ -260,7 +260,7 @@ void T_TextureSampler::setSamplingMode( ) const glSamplerParameteri( id_ , GL_TEXTURE_MIN_FILTER , min ); glSamplerParameteri( id_ , GL_TEXTURE_MAG_FILTER , max ); - GL_ASSERT( ); + //GL_ASSERT( ); } diff --git a/ui.cc b/ui.cc index fcf381b..aa3afb1 100644 --- a/ui.cc +++ b/ui.cc @@ -43,9 +43,9 @@ std::aligned_storage_t< sizeof( UIData_ ) , alignof( UIData_ ) > Instance_; /*----------------------------------------------------------------------------*/ -void UI::Init( ) noexcept +void UI::Init( T_String const& path ) noexcept { - Common::Init( ); + Common::Init( path ); new ((char*)&Instance_) UIData_( ); } diff --git a/ui.hh b/ui.hh index 32feefe..1f56ca2 100644 --- a/ui.hh +++ b/ui.hh @@ -15,7 +15,7 @@ struct T_UISync; struct UI { public: - static void Init( ) noexcept; + static void Init( T_String const& path = {} ) noexcept; static void Shutdown( ) noexcept; static T_UIApp& Main( ) noexcept;