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.
This commit is contained in:
Emmanuel BENOîT 2017-11-24 14:52:56 +01:00
parent 97478cf1e8
commit ae3958f785
13 changed files with 112 additions and 48 deletions

View file

@ -1,6 +1,7 @@
#pragma once
#include "c-filewatcher.hh"
#include "c-opast.hh"
#include "c-project.hh"
#include <ebcl/SRDData.hh>
@ -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;
};

View file

@ -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;

View file

@ -5,16 +5,22 @@
#include <ebcl/Sets.hh>
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 > >( )
};

View file

@ -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 );
}

View file

@ -1,5 +1,6 @@
#pragma once
#include "c-filewatcher.hh"
#include "c-project.hh"
#include <ebcl/SRDParserConfig.hh>
#include <ebcl/Sets.hh>
@ -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;
};

View file

@ -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 ); }

View file

@ -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;

View file

@ -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;
}

View file

@ -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 << ") {"

View file

@ -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;
const T_String path{ [&]() -> T_String {
T_StringBuilder sb;
sb << "shaders/" << name;
if ( !ni.load( sb ) ) {
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 ) ) {

View file

@ -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( );
}

4
ui.cc
View file

@ -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_( );
}

2
ui.hh
View file

@ -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;