2017-10-07 16:56:20 +02:00
|
|
|
#pragma once
|
2017-10-31 14:21:42 +01:00
|
|
|
#include "filewatcher.hh"
|
|
|
|
#include "utilities.hh"
|
2017-10-07 16:56:20 +02:00
|
|
|
|
2017-10-30 10:20:09 +01:00
|
|
|
// Duration and current playing time
|
|
|
|
struct T_SyncTime
|
2017-10-07 16:56:20 +02:00
|
|
|
{
|
2017-10-30 18:29:52 +01:00
|
|
|
float uDuration = 1.f / 60.f; // Duration - unit size
|
|
|
|
uint32_t iDuration = 3600; // Duration - total units
|
2017-10-30 10:20:09 +01:00
|
|
|
float time = 0;
|
2017-10-17 11:30:44 +02:00
|
|
|
|
2017-10-30 10:20:09 +01:00
|
|
|
void setDuration(
|
2017-11-03 09:08:19 +01:00
|
|
|
const float uDuration ,
|
|
|
|
const uint32_t iDuration );
|
2017-10-17 11:30:44 +02:00
|
|
|
|
2017-10-30 10:20:09 +01:00
|
|
|
float duration( ) const noexcept
|
|
|
|
{ return uDuration * iDuration; }
|
2017-10-17 11:30:44 +02:00
|
|
|
|
2017-11-03 09:08:19 +01:00
|
|
|
void setTime( const float t ) noexcept
|
2017-10-30 10:20:09 +01:00
|
|
|
{ time = std::max( 0.f , std::min( t , duration( ) ) ); }
|
2017-10-07 16:56:20 +02:00
|
|
|
};
|
|
|
|
|
2017-10-17 11:30:44 +02:00
|
|
|
/*============================================================================*/
|
|
|
|
|
|
|
|
// Segment of an input's curve
|
2017-10-07 16:56:20 +02:00
|
|
|
struct T_SyncSegment
|
|
|
|
{
|
2017-10-17 11:30:44 +02:00
|
|
|
enum E_SegmentType
|
|
|
|
{
|
|
|
|
LINEAR ,
|
|
|
|
RAMP ,
|
|
|
|
SMOOTH ,
|
|
|
|
//HERMITE
|
|
|
|
};
|
|
|
|
|
2017-10-07 16:56:20 +02:00
|
|
|
uint32_t nPoints;
|
2017-10-17 11:30:44 +02:00
|
|
|
E_SegmentType type;
|
2017-11-03 09:08:19 +01:00
|
|
|
T_Array< float > values; // nPoints items
|
|
|
|
T_Array< uint32_t > durations; // nPoints - 1 items
|
2017-10-07 16:56:20 +02:00
|
|
|
};
|
|
|
|
|
2017-10-17 11:30:44 +02:00
|
|
|
// An input curve
|
|
|
|
struct T_SyncCurve
|
|
|
|
{
|
2017-11-03 09:08:19 +01:00
|
|
|
T_String name;
|
|
|
|
T_Array< T_SyncSegment > segments;
|
|
|
|
|
|
|
|
T_SyncCurve( ) noexcept { }
|
|
|
|
|
|
|
|
T_SyncCurve( T_String const& name ) noexcept
|
|
|
|
: name( name )
|
|
|
|
{ }
|
|
|
|
|
|
|
|
T_SyncCurve( char const* name ) noexcept
|
|
|
|
: name( T_String( name ).usePool( ) )
|
|
|
|
{ }
|
2017-10-17 11:30:44 +02:00
|
|
|
};
|
|
|
|
|
2017-10-30 10:20:09 +01:00
|
|
|
// All configured curves. Some may not actually correspond to an input and may
|
|
|
|
// have been defined for inputs that have been removed temporarily (e.g.
|
|
|
|
// because some include was commented out), in which case we don't want to
|
|
|
|
// waste them.
|
|
|
|
struct T_SyncCurves
|
|
|
|
{
|
|
|
|
|
2017-11-03 09:08:19 +01:00
|
|
|
T_ObjectTable< T_String , T_SyncCurve > curves;
|
|
|
|
|
|
|
|
T_SyncCurves( )
|
|
|
|
: curves( []( T_SyncCurve const& c ) -> T_String { return c.name; } )
|
|
|
|
{ }
|
2017-10-30 10:20:09 +01:00
|
|
|
|
|
|
|
void clear( );
|
|
|
|
|
|
|
|
// Returns true on success, false on duplicate
|
2017-11-03 09:08:19 +01:00
|
|
|
void setCurve( T_SyncCurve curve );
|
2017-10-30 10:20:09 +01:00
|
|
|
|
|
|
|
// Returns -1 on lookup failure
|
2017-11-03 09:08:19 +01:00
|
|
|
int32_t indexOf( T_String const& name ) noexcept;
|
|
|
|
int32_t indexOf( char const* name ) noexcept
|
|
|
|
{
|
|
|
|
return indexOf( T_String( name ) );
|
|
|
|
}
|
2017-10-30 10:20:09 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
2017-10-17 11:30:44 +02:00
|
|
|
// Pre-computed data for a curve
|
|
|
|
struct T_SyncCurveCache
|
|
|
|
{
|
|
|
|
using T_SegRef = std::pair< uint32_t , uint32_t >;
|
2017-10-07 16:56:20 +02:00
|
|
|
|
2017-10-30 10:20:09 +01:00
|
|
|
uint32_t curve;
|
2017-11-03 09:08:19 +01:00
|
|
|
T_Array< T_SegRef > segRefs;
|
|
|
|
T_Array< float > segStarts;
|
|
|
|
T_Array< float > segEnds;
|
2017-10-23 11:03:38 +02:00
|
|
|
uint32_t curPos;
|
2017-10-07 16:56:20 +02:00
|
|
|
|
2017-10-17 11:30:44 +02:00
|
|
|
T_SyncCurveCache(
|
2017-11-03 09:08:19 +01:00
|
|
|
T_SyncTime const& time ,
|
|
|
|
T_SyncCurves const& curves ,
|
|
|
|
const uint32_t curve ) noexcept;
|
2017-10-30 10:20:09 +01:00
|
|
|
|
|
|
|
// Find the index of the segment for the specified time
|
|
|
|
uint32_t findSegment(
|
2017-11-03 09:08:19 +01:00
|
|
|
const float time ) const noexcept;
|
2017-10-17 11:30:44 +02:00
|
|
|
|
2017-10-30 10:20:09 +01:00
|
|
|
// Compute the value of the curve at the specified location, ignoring
|
|
|
|
// curPos.
|
2017-10-17 11:30:44 +02:00
|
|
|
float valueAt(
|
2017-11-03 09:08:19 +01:00
|
|
|
T_SyncTime const& time ,
|
|
|
|
T_SyncCurves const& curves ,
|
|
|
|
const float position ) const noexcept;
|
2017-10-30 10:20:09 +01:00
|
|
|
|
|
|
|
// Compute the value of the curve at the current time, using and
|
|
|
|
// updating curPos as necessary.
|
|
|
|
float value(
|
2017-11-03 09:08:19 +01:00
|
|
|
T_SyncTime const& time ,
|
|
|
|
T_SyncCurves const& curves ) noexcept;
|
2017-10-30 10:20:09 +01:00
|
|
|
|
|
|
|
float segmentValue(
|
2017-11-03 09:08:19 +01:00
|
|
|
float time ,
|
|
|
|
uint32_t segIndex ,
|
|
|
|
T_Array< T_SyncSegment > const& segments ) const noexcept;
|
2017-10-17 11:30:44 +02:00
|
|
|
};
|
2017-11-03 09:08:19 +01:00
|
|
|
using P_SyncCurveCache = T_OwnPtr< T_SyncCurveCache >;
|
2017-10-17 11:30:44 +02:00
|
|
|
|
|
|
|
/*============================================================================*/
|
|
|
|
|
2017-10-30 10:20:09 +01:00
|
|
|
// Synchronization values. The values vector always contains an extra entry
|
|
|
|
// used for missing inputs.
|
|
|
|
struct T_SyncValues
|
|
|
|
{
|
2017-11-03 09:08:19 +01:00
|
|
|
T_HashIndex index;
|
|
|
|
T_Array< T_String > identifiers;
|
|
|
|
T_Array< float > values;
|
|
|
|
T_Array< bool > overriden;
|
2017-10-30 10:20:09 +01:00
|
|
|
|
|
|
|
T_SyncValues( );
|
|
|
|
void clear( );
|
|
|
|
|
|
|
|
// Returns true on success, false on duplicate
|
|
|
|
bool addValue(
|
2017-11-03 09:08:19 +01:00
|
|
|
T_String const& name ,
|
|
|
|
const float initial = 0.f ) noexcept;
|
|
|
|
|
|
|
|
bool addValue(
|
|
|
|
char const* name ,
|
|
|
|
const float initial = 0.f ) noexcept
|
|
|
|
{
|
|
|
|
return addValue( T_String( name ) , initial );
|
|
|
|
}
|
2017-10-30 10:20:09 +01:00
|
|
|
|
|
|
|
// If the name isn't found, the last entry of values[] is returned
|
|
|
|
uint32_t indexOf(
|
2017-11-03 09:08:19 +01:00
|
|
|
T_String const& name ) const noexcept;
|
2017-10-30 10:20:09 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/*============================================================================*/
|
|
|
|
|
|
|
|
// Synchronisation manager; handles all the synchronization data and makes it
|
|
|
|
// work together.
|
|
|
|
struct T_SyncManager
|
|
|
|
{
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
// Duration & time controls
|
|
|
|
|
|
|
|
void setDuration(
|
2017-11-03 09:08:19 +01:00
|
|
|
const float uDuration ,
|
|
|
|
const uint32_t iDuration );
|
2017-10-30 10:20:09 +01:00
|
|
|
float duration( ) const noexcept
|
|
|
|
{ return time_.duration( ); }
|
|
|
|
|
2017-11-03 09:08:19 +01:00
|
|
|
void setTime( const float time );
|
|
|
|
void timeDelta( const float delta )
|
2017-10-30 10:20:09 +01:00
|
|
|
{ setTime( time_.time + delta ); }
|
|
|
|
float time( ) const noexcept
|
|
|
|
{ return time_.time; }
|
|
|
|
|
|
|
|
bool finished( ) const noexcept
|
|
|
|
{ return time_.time >= time_.duration( ); }
|
|
|
|
|
2017-10-30 18:29:52 +01:00
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
// Value access
|
|
|
|
|
2017-10-30 19:04:10 +01:00
|
|
|
void clearInputs( )
|
|
|
|
{ values_.clear( ); }
|
2017-11-03 09:08:19 +01:00
|
|
|
bool addInput( std::string const& name ,
|
|
|
|
const float initial = 0.f ) noexcept
|
|
|
|
{ return values_.addValue( name.c_str( ) , initial ); }
|
2017-10-30 19:04:10 +01:00
|
|
|
|
2017-11-03 09:08:19 +01:00
|
|
|
uint32_t inputPos( T_String const& name ) const noexcept
|
2017-10-30 18:29:52 +01:00
|
|
|
{ return values_.indexOf( name ); }
|
2017-11-03 09:08:19 +01:00
|
|
|
T_Array< float > const& inputs( ) const noexcept
|
2017-10-30 18:29:52 +01:00
|
|
|
{ return values_.values; }
|
|
|
|
|
2017-10-30 22:32:28 +01:00
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
// Curves
|
|
|
|
|
2017-10-31 14:21:42 +01:00
|
|
|
void checkCurveFile( );
|
2017-10-30 22:32:28 +01:00
|
|
|
void clearCurves( );
|
2017-11-03 09:08:19 +01:00
|
|
|
void setCurve( T_SyncCurve curve );
|
2017-10-30 22:32:28 +01:00
|
|
|
|
2017-10-31 14:21:42 +01:00
|
|
|
private:
|
|
|
|
void curvesChanged_( );
|
2017-11-03 09:08:19 +01:00
|
|
|
bool loadCurves_( bool& missing );
|
2017-10-31 14:21:42 +01:00
|
|
|
bool loadCurvesData_(
|
2017-11-03 09:08:19 +01:00
|
|
|
T_SyncCurves& curves ,
|
|
|
|
picojson::value const& root );
|
2017-10-31 14:21:42 +01:00
|
|
|
bool loadSegmentData_(
|
2017-11-03 09:08:19 +01:00
|
|
|
T_SyncSegment& segment ,
|
|
|
|
std::string const& curve ,
|
|
|
|
T_JSONObject const& sd );
|
2017-10-31 14:21:42 +01:00
|
|
|
|
2017-10-30 10:20:09 +01:00
|
|
|
// ---------------------------------------------------------------------
|
2017-10-31 14:21:42 +01:00
|
|
|
// Update
|
2017-10-30 10:20:09 +01:00
|
|
|
|
2017-10-31 14:21:42 +01:00
|
|
|
public:
|
2017-10-30 10:20:09 +01:00
|
|
|
void updateCurveCaches( );
|
|
|
|
void updateValues( );
|
|
|
|
|
|
|
|
private:
|
2017-10-31 14:21:42 +01:00
|
|
|
P_WatchedFiles watcher_;
|
2017-10-30 10:20:09 +01:00
|
|
|
T_SyncTime time_;
|
|
|
|
T_SyncValues values_;
|
|
|
|
T_SyncCurves curves_;
|
2017-11-03 09:08:19 +01:00
|
|
|
T_Array< P_SyncCurveCache > curveCaches_;
|
2017-10-30 10:20:09 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*============================================================================*/
|
|
|
|
// DISREGARD EVERYTHING BELOW, IT SUCKS!
|
|
|
|
/*============================================================================*/
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
// Definition of a single input - id & range
|
|
|
|
struct T_SyncInputDfn
|
|
|
|
{
|
|
|
|
std::string identifier;
|
|
|
|
float min = -std::numeric_limits< float >::infinity( ),
|
|
|
|
max = std::numeric_limits< float >::infinity( );
|
|
|
|
|
2017-11-03 09:08:19 +01:00
|
|
|
T_SyncInputDfn( std::string const& identifier ,
|
|
|
|
const float min ,
|
|
|
|
const float max ) noexcept
|
2017-10-30 10:20:09 +01:00
|
|
|
: identifier( identifier ) , min( min ) , max( max )
|
|
|
|
{ }
|
|
|
|
};
|
|
|
|
using P_SyncInputDfn = std::unique_ptr< T_SyncInputDfn >;
|
|
|
|
|
|
|
|
/*============================================================================*/
|
|
|
|
|
|
|
|
// Definition of UI overrides for inputs
|
|
|
|
struct T_SyncUIOverride
|
|
|
|
{
|
|
|
|
enum E_Type {
|
|
|
|
FLOAT , VEC2 , VEC3 , VEC4 , INT ,
|
|
|
|
COLOR , COLOR_GRADING , CAMERA
|
|
|
|
};
|
|
|
|
|
|
|
|
std::string title;
|
|
|
|
E_Type type;
|
|
|
|
std::vector< std::string > inputs;
|
|
|
|
bool enabled;
|
|
|
|
};
|
|
|
|
using P_SyncUIOverride = std::unique_ptr< T_SyncUIOverride >;
|
|
|
|
using T_SyncUIOverrides = std::vector< P_SyncUIOverride >;
|
|
|
|
|
|
|
|
// UI override sections
|
|
|
|
struct T_SyncUISection;
|
|
|
|
using P_SyncUISection = std::unique_ptr< T_SyncUISection >;
|
|
|
|
using T_SyncUISections = std::vector< P_SyncUISection >;
|
|
|
|
struct T_SyncUISection
|
|
|
|
{
|
|
|
|
std::string title;
|
|
|
|
T_SyncUISections subsections;
|
|
|
|
T_SyncUIOverrides overrides;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*============================================================================*/
|
|
|
|
|
2017-10-17 11:30:44 +02:00
|
|
|
struct T_SyncManager
|
|
|
|
{
|
|
|
|
float uDuration; // Duration - unit size
|
|
|
|
uint32_t iDuration; // Duration - total units
|
|
|
|
|
|
|
|
float duration( ) const noexcept
|
|
|
|
{ return uDuration * iDuration; }
|
|
|
|
|
|
|
|
// Sync manager data for an input may include a definition, a curve,
|
|
|
|
// or both. The idea behind supporting "curve only" is that a curve may
|
|
|
|
// have been defined for an input that has been removed temporarily
|
|
|
|
// (e.g. because some include was commented out), in which case we don't
|
|
|
|
// want to waste it.
|
|
|
|
struct T_Data
|
|
|
|
{
|
|
|
|
P_SyncInputDfn definition;
|
|
|
|
P_SyncCurveCache curve;
|
|
|
|
bool overriden;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Data and ID<->index map
|
|
|
|
std::vector< T_Data > data;
|
|
|
|
std::map< std::string , uint32_t > posMap;
|
|
|
|
|
|
|
|
// Current time & values
|
|
|
|
float time;
|
|
|
|
std::vector< float > values;
|
|
|
|
|
|
|
|
// Root of the UI's tree
|
|
|
|
T_SyncUISections uiRoot;
|
|
|
|
|
|
|
|
void makeUI( );
|
2017-10-23 11:03:38 +02:00
|
|
|
bool wOverrides = false;
|
|
|
|
bool wCurves = false;
|
|
|
|
|
|
|
|
private:
|
|
|
|
void displayOvSections(
|
2017-11-03 09:08:19 +01:00
|
|
|
T_SyncUISections& sections ,
|
|
|
|
const bool topLevel = false );
|
2017-10-23 11:03:38 +02:00
|
|
|
void displayOvControls(
|
2017-11-03 09:08:19 +01:00
|
|
|
T_SyncUIOverrides& overrides );
|
2017-10-17 11:30:44 +02:00
|
|
|
};
|
2017-10-30 10:20:09 +01:00
|
|
|
#endif
|