From 59128de38f9b45304b898cb9e44616d53c60dfab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= <tseeker@nocternity.net>
Date: Mon, 30 Oct 2017 18:29:52 +0100
Subject: [PATCH] Use the new sync code

---
 control.cc |   4 +-
 demo.cc    |  12 ++---
 demo.hh    |   2 -
 dof.cc     |   7 ++-
 dof.hh     |   4 +-
 globals.cc |   3 ++
 globals.hh |   3 ++
 main.cc    |  11 +++--
 sync.cc    | 142 +----------------------------------------------------
 sync.hh    |  68 ++++---------------------
 10 files changed, 36 insertions(+), 220 deletions(-)

diff --git a/control.cc b/control.cc
index 5e1be37..50f4914 100644
--- a/control.cc
+++ b/control.cc
@@ -1,5 +1,6 @@
 #include "externals.hh"
 #include "control.hh"
+#include "globals.hh"
 #include "sync.hh"
 
 using namespace cops;
@@ -124,7 +125,8 @@ OPLoadInput::OPLoadInput(
 void OPLoadInput::execute(
 		__rw__ T_Context& ctx ) const
 {
-	ctx.opStack.push_back( ctx.sync->valueOf( input , *( ctx.time ) ) );
+	const auto i( Globals::Sync( ).inputPos( input ) );
+	ctx.opStack.push_back( Globals::Sync( ).inputs( )[ i ] );
 }
 
 
diff --git a/demo.cc b/demo.cc
index 3c62500..513aafe 100644
--- a/demo.cc
+++ b/demo.cc
@@ -1,5 +1,7 @@
 #include "externals.hh"
 #include "demo.hh"
+#include "sync.hh"
+#include "globals.hh"
 
 
 T_Demo::T_Demo( __rd__ const uint32_t width ,
@@ -43,21 +45,19 @@ void T_Demo::makeUI( )
 
 void T_Demo::render( )
 {
+	auto& sync( Globals::Sync( ) );
 	if ( playing ) {
 		const float time = SDL_GetTicks( ) * 1e-3;
 		if ( playingPrevious ) {
-			const float adv = time - lastFrame;
-			position = std::min( adv + position , sync.duration( ) );
-			if ( position >= sync.duration( ) ) {
-				playing = false;
-			}
+			sync.timeDelta( time - lastFrame );
+			playing = !sync.finished( );
 		}
 		lastFrame = time;
 	}
 	playingPrevious = playing;
 
 	raymarcher->render( );
-	dof->render( position , sync );
+	dof->render( );
 	bloom->render( );
 	combine->render( );
 	fxaa->render( );
diff --git a/demo.hh b/demo.hh
index e3dec2c..ecb0652 100644
--- a/demo.hh
+++ b/demo.hh
@@ -41,8 +41,6 @@ struct T_Demo
 	const uint32_t width;
 	const uint32_t height;
 
-	T_SyncData sync;
-	float position = 0;
 	bool playing = false;
 
 	std::unique_ptr< T_Raymarcher > raymarcher;
diff --git a/dof.cc b/dof.cc
index 437758a..9cd506e 100644
--- a/dof.cc
+++ b/dof.cc
@@ -3,6 +3,7 @@
 #include "profiling.hh"
 #include "globals.hh"
 #include "odbg.hh"
+#include "sync.hh"
 
 
 namespace {
@@ -37,9 +38,7 @@ T_DoFPass::T_DoFPass(
 			"fullscreen.v.glsl" , "dof-pass2.f.glsl" });
 }
 
-void T_DoFPass::render(
-		__rd__ const float position ,
-		__rd__ T_SyncData const& )
+void T_DoFPass::render( )
 {
 	PSTART( );
 	enum {
@@ -112,7 +111,7 @@ void T_DoFPass::render(
 	} );
 
 	T_Context ctx;
-	ctx.store( "time" , position );
+	ctx.store( "time" , Globals::Sync( ).time( ) );
 	ctx.store( "width" , imageInput_.width( ) );
 	ctx.store( "height" , imageInput_.height( ) );
 	program.execute( ctx );
diff --git a/dof.hh b/dof.hh
index 7c5164d..ffd74ce 100644
--- a/dof.hh
+++ b/dof.hh
@@ -16,9 +16,7 @@ struct T_DoFPass
 	T_DoFPass( __rw__ T_Texture& imageInput ,
 			__rw__ T_Texture& depthInput );
 
-	void render(
-		__rd__ const float position ,
-		__rd__ T_SyncData const& sync );
+	void render( );
 	void makeUI( );
 
 	T_Texture& output( ) { return txOutput_; }
diff --git a/globals.cc b/globals.cc
index b776ba1..a9e41c1 100644
--- a/globals.cc
+++ b/globals.cc
@@ -7,11 +7,13 @@
 #include "shaders.hh"
 #include "window.hh"
 #include "odbg.hh"
+#include "sync.hh"
 
 
 std::unique_ptr< T_FilesWatcher > Globals::watcher_;
 std::unique_ptr< T_Window > Globals::window_;
 std::unique_ptr< T_Profiler > Globals::profiler_;
+std::unique_ptr< T_SyncManager > Globals::sync_;
 std::unique_ptr< T_TextureManager > Globals::textures_;
 std::unique_ptr< T_ShaderManager > Globals::shaders_;
 std::unique_ptr< T_OutputDebugger > Globals::odbg_;
@@ -22,6 +24,7 @@ void Globals::Init( )
 	watcher_ = std::make_unique< T_FilesWatcher >( );
 	window_ = std::make_unique< T_Window >( );
 	profiler_ = std::make_unique< T_Profiler >( );
+	sync_ = std::make_unique< T_SyncManager >( );
 	textures_ = std::make_unique< T_TextureManager >( );
 	shaders_ = std::make_unique< T_ShaderManager >( );
 	odbg_ = std::make_unique< T_OutputDebugger >( );
diff --git a/globals.hh b/globals.hh
index 4b567e4..d67f3f0 100644
--- a/globals.hh
+++ b/globals.hh
@@ -10,6 +10,7 @@ struct T_Profiler;
 struct T_TextureManager;
 struct T_ShaderManager;
 struct T_OutputDebugger;
+struct T_SyncManager;
 
 
 struct Globals
@@ -20,6 +21,7 @@ struct Globals
 	static T_FilesWatcher& Watcher( )	{ return *watcher_; }
 	static T_Window& Window( )		{ return *window_; }
 	static T_Profiler& Profiler( )		{ return *profiler_; }
+	static T_SyncManager& Sync( )		{ return *sync_; }
 	static T_TextureManager& Textures( )	{ return *textures_; }
 	static T_ShaderManager& Shaders( )	{ return *shaders_; }
 	static T_OutputDebugger& ODbg( )	{ return *odbg_; }
@@ -28,6 +30,7 @@ struct Globals
 	static std::unique_ptr< T_FilesWatcher > watcher_;
 	static std::unique_ptr< T_Window > window_;
 	static std::unique_ptr< T_Profiler > profiler_;
+	static std::unique_ptr< T_SyncManager > sync_;
 	static std::unique_ptr< T_ShaderManager > shaders_;
 	static std::unique_ptr< T_TextureManager > textures_;
 	static std::unique_ptr< T_OutputDebugger > odbg_;
diff --git a/main.cc b/main.cc
index 2137092..20a3a53 100644
--- a/main.cc
+++ b/main.cc
@@ -182,11 +182,12 @@ void T_Main::makeUI( )
 
 	if ( demo ) {
 		ImGui::Separator( );
-		const float duration( demo->sync.duration( ) );
-		if ( ImGui::SliderFloat( "" , &demo->position , 0 , duration , "%.1fs" )
-				&& demo->position > duration ) {
-			demo->position = duration;
-			demo->playing = false;
+		auto& sync( Globals::Sync( ) );
+		const float duration( sync.duration( ) );
+		float time( sync.time( ) );
+		if ( ImGui::SliderFloat( "" , &time , 0 , duration , "%.1fs" ) ) {
+			sync.setTime( time );
+			demo->playing = demo->playing && ! sync.finished( );
 		}
 		ImGui::SameLine( );
 		if ( ImGui::Button( demo->playing ? "Stop" : "Play" ) ) {
diff --git a/sync.cc b/sync.cc
index 84b2543..48717d9 100644
--- a/sync.cc
+++ b/sync.cc
@@ -13,6 +13,7 @@ void T_SyncTime::setDuration(
 	time = std::min( time , duration( ) );
 }
 
+
 /*= T_SyncCurves =============================================================*/
 
 void T_SyncCurves::clear( )
@@ -329,144 +330,3 @@ void T_SyncManager::displayOvControls(
 	}
 }
 #endif
-
-/*============================================================================*/
-
-const T_SyncVariable T_SyncData::MissingVariable_{ };
-
-T_SyncData::T_SyncData( )
-	: T_SyncData( 60 * 60 , 1. / 60 )
-{ }
-
-T_SyncData::T_SyncData(
-		__rd__ const uint32_t duration ,
-		__rd__ const float units ) noexcept
-	: duration_( duration ) , units_( units )
-{ }
-
-
-T_SyncData::T_VarHelper_::T_VarHelper_(
-		__rw__ T_SyncVariable&& v ,
-		__rd__ const uint32_t duration ,
-		__rd__ const uint32_t position ) noexcept
-	: variable( std::move( v ) ) , position( position )
-{
-	const auto n( variable.size( ) );
-	uint32_t s = 0;
-	for ( auto i = 0u ; i < n ; i ++ ) {
-		auto const& v( variable[ i ] );
-		assert( v.nPoints >= 2 );
-		assert( v.durations.size( ) == v.nPoints - 1 );
-
-		const auto nd( v.nPoints - 1 );
-		for ( auto j = 0u ; j < nd ; j ++ ) {
-			segStarts.push_back( s );
-			segRefs.push_back( std::make_pair( i , j ) );
-			s += v.durations[ j ];
-			if ( s > duration ) {
-				return;
-			}
-		}
-	}
-}
-
-
-float T_SyncData::T_VarHelper_::valueAt(
-		__rd__ const float position ,
-		__rd__ const float units ) const noexcept
-{
-	// Find segment
-	const auto tu( uint32_t( floor( position / units ) ) );
-	uint32_t s( 0 );
-	for ( auto ss : segStarts ) {
-		if ( ss > tu ) {
-			break;
-		}
-		s ++;
-	}
-	assert( s > 0 );
-	s --;
-	const auto sid( segRefs[ s ].first );
-	auto const& seg( variable[ sid ] );
-	const auto pid( segRefs[ s ].second );
-	
-	// Interpolation factor
-	const float st( segStarts[ s ] * units );
-	const float et( ( segStarts[ s ] + seg.durations[ pid ] ) * units );
-	const float v0 = ( position - st ) / ( et - st );
-	float v = v0;
-	if ( seg.type != T_SyncSegment::LINEAR ) {
-		v *= v0;
-		if ( seg.type == T_SyncSegment::SMOOTH ) {
-			v *= 3 - 2 * v0;
-		}
-	}
-
-	const float sv( seg.values[ pid ] );
-	const float ev( seg.values[ pid + 1 ] );
-	return v * ( ev - sv ) + sv;
-}
-
-
-void T_SyncData::setSyncVariable(
-		__rd__ std::string const& name ,
-		__rw__ T_SyncVariable&& variable ) noexcept
-{
-	variables_.erase( name );
-	if ( !variable.empty( ) ) {
-		variables_.emplace( name , T_VarHelper_{
-			std::move( variable ) , duration_ ,
-			uint32_t( variables_.size( ) )
-		} );
-	}
-}
-
-
-T_SyncVariable const& T_SyncData::variable(
-	__rd__ std::string const& name ) const noexcept
-{
-	auto pos( variables_.find( name ) );
-	if ( pos == variables_.end( ) ) {
-		return MissingVariable_;
-	}
-	return pos->second.variable;
-}
-
-uint32_t T_SyncData::offsetOf(
-	__rd__ std::string const& name ) const noexcept
-{
-	auto pos( variables_.find( name ) );
-	if ( pos == variables_.end( ) ) {
-		return 0xffffffff;
-	}
-	return pos->second.position;
-}
-
-
-float T_SyncData::valueOf(
-	__rd__ std::string const& name ,
-	__rd__ const float time ) const noexcept
-{
-	assert( time >= 0 );
-
-	auto pos( variables_.find( name ) );
-	if ( pos == variables_.end( ) ) {
-		return 0;
-	}
-	return pos->second.valueAt( std::min( duration_ * units_ , time ) , units_ );
-}
-
-
-void T_SyncData::computeValues(
-	__rd__ const float time ,
-	__wr__ std::vector< float >& values ) const noexcept
-{
-	assert( time >= 0 );
-	values.resize( variables_.size( ) );
-	auto vit( values.begin( ) );
-	const float t( std::min( duration_ * units_ , time ) );
-	for ( auto const& var : variables_ ) {
-		*vit = var.second.valueAt( t , units_ );
-		vit ++;
-	}
-}
diff --git a/sync.hh b/sync.hh
index 08f04f5..93f2d11 100644
--- a/sync.hh
+++ b/sync.hh
@@ -7,8 +7,8 @@
 // Duration and current playing time
 struct T_SyncTime
 {
-	float uDuration = 1e-3f;	// Duration - unit size
-	uint32_t iDuration = 1;		// Duration - total units
+	float uDuration = 1.f / 60.f;	// Duration - unit size
+	uint32_t iDuration = 3600;	// Duration - total units
 	float time = 0;
 
 	void setDuration(
@@ -157,6 +157,14 @@ struct T_SyncManager
 	bool finished( ) const noexcept
 		{ return time_.time >= time_.duration( ); }
 
+	// ---------------------------------------------------------------------
+	// Value access
+
+	uint32_t inputPos( __rd__ std::string const& name ) const noexcept
+		{ return values_.indexOf( name ); }
+	std::vector< float > const& inputs( ) const noexcept
+		{ return values_.values; }
+
 	// ---------------------------------------------------------------------
 
 	void updateCurveCaches( );
@@ -264,59 +272,3 @@ struct T_SyncManager
 			__rw__ T_SyncUIOverrides& overrides );
 };
 #endif
-
-/*============================================================================*/
-
-using T_SyncVariable = std::vector< T_SyncSegment >;
-struct T_SyncData
-{
-	T_SyncData( );
-	T_SyncData(
-		__rd__ const uint32_t duration ,
-		__rd__ const float units ) noexcept;
-
-	float duration( ) const noexcept
-		{ return duration_ * units_; }
-
-	void setSyncVariable(
-		__rd__ std::string const& name ,
-		__rw__ T_SyncVariable&& variable ) noexcept;
-
-	T_SyncVariable const& variable(
-		__rd__ std::string const& name ) const noexcept;
-	uint32_t offsetOf(
-		__rd__ std::string const& name ) const noexcept;
-
-	float valueOf(
-		__rd__ std::string const& variable ,
-		__rd__ const float time ) const noexcept;
-
-	void computeValues(
-		__rd__ const float time ,
-		__wr__ std::vector< float >& values ) const noexcept;
-
-    private:
-	static const T_SyncVariable MissingVariable_;
-
-	// Caching structure used to access segments
-	using T_SegRef_ = std::pair< uint32_t , uint32_t >;
-	struct T_VarHelper_
-	{
-		T_SyncVariable variable;
-		std::vector< T_SegRef_ > segRefs;
-		std::vector< float > segStarts;
-		uint32_t position;
-
-		T_VarHelper_(
-			__rw__ T_SyncVariable&& variable ,
-			__rd__ const uint32_t duration ,
-			__rd__ const uint32_t position ) noexcept;
-		float valueAt(
-			__rd__ const float position ,
-			__rd__ const float units ) const noexcept;
-	};
-
-	uint32_t duration_;
-	float units_;
-	std::unordered_map< std::string , T_VarHelper_ > variables_;
-};