New, untested, unused sync data code+structures

This commit is contained in:
Emmanuel BENOîT 2017-10-30 10:20:09 +01:00
parent a3a8c9c0a5
commit 7b2f218d30
2 changed files with 428 additions and 47 deletions

256
sync.cc
View file

@ -2,6 +2,261 @@
#include "sync.hh" #include "sync.hh"
/*= T_SyncTime ===============================================================*/
void T_SyncTime::setDuration(
__rd__ const float uDuration ,
__rd__ const uint32_t iDuration )
{
this->uDuration = std::max( 1e-3f , uDuration );
this->iDuration = std::max( 1u , iDuration );
time = std::min( time , duration( ) );
}
/*= T_SyncCurves =============================================================*/
void T_SyncCurves::clear( )
{
curves.clear( );
positions.clear( );
}
bool T_SyncCurves::addCurve( __rd__ T_SyncCurve curve )
{
const auto p( positions.find( curve.name ) );
if ( p == positions.end( ) ) {
positions.emplace( curve.name , curves.size( ) );
curves.emplace_back( std::move( curve ) );
return true;
}
return false;
}
int32_t T_SyncCurves::indexOf( __rd__ std::string const& name )
{
const auto p( positions.find( name ) );
return p == positions.end( ) ? -1 : p->second;
}
/*= T_SyncCurveCache =========================================================*/
T_SyncCurveCache::T_SyncCurveCache(
__rd__ T_SyncTime const& time ,
__rd__ T_SyncCurves const& curves ,
__rd__ const uint32_t curve ) noexcept
: curve( curve ) , curPos( 0 )
{
auto const& c( curves.curves[ curve ] );
const auto ns( c.segments.size( ) );
assert( ns > 0 );
uint32_t s = 0;
for ( auto i = 0u ; i < ns ; i ++ ) {
auto const& v( c.segments[ 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 ++ ) {
const auto sStart( s * time.uDuration );
if ( time.time >= sStart ) {
curPos = segStarts.size( );
}
segStarts.push_back( sStart );
segRefs.push_back( std::make_pair( i , j ) );
s += v.durations[ j ];
segEnds.push_back( std::min( s , time.iDuration ) * time.uDuration );
if ( s > time.iDuration ) {
return;
}
}
}
}
/*----------------------------------------------------------------------------*/
uint32_t T_SyncCurveCache::findSegment(
__rd__ const float time ) const noexcept
{
const auto ns( segStarts.size( ) );
for ( auto i = 0u ; i < ns ; i ++ ) {
if ( segStarts[ i ] <= time && segEnds[ i ] > time ) {
return i;
}
}
return ns;
}
/*----------------------------------------------------------------------------*/
float T_SyncCurveCache::valueAt(
__rd__ T_SyncTime const& time ,
__rd__ T_SyncCurves const& curves ,
__rd__ const float position ) const noexcept
{
return segmentValue( time.time , findSegment( position ) ,
curves.curves[ curve ].segments );
}
float T_SyncCurveCache::value(
__rd__ T_SyncTime const& time ,
__rd__ T_SyncCurves const& curves ) noexcept
{
const auto t( time.time );
// Check / update curPos
const float ss0( curPos == segStarts.size( )
? time.duration( )
: segStarts[ curPos ] );
if ( ss0 > t ) {
curPos = findSegment( t );
} else {
while ( curPos < segStarts.size( ) && t >= segEnds[ curPos ] ) {
curPos ++;
}
}
// We got the actual index in curPos, now compute the value.
return segmentValue( t , curPos , curves.curves[ curve ].segments );
}
/*----------------------------------------------------------------------------*/
float T_SyncCurveCache::segmentValue(
__rd__ float time ,
__rd__ uint32_t segIndex ,
__rd__ std::vector< T_SyncSegment > const& segments ) const noexcept
{
const auto sss( segStarts.size( ) );
if ( segIndex >= sss ) {
assert( sss != 0 );
segIndex = sss - 1;
time = segEnds[ segIndex ];
}
auto const& idxp( segRefs[ segIndex ] );
auto const& seg( segments[ idxp.second ] );
// Interpolation factor
const float st( segStarts[ segIndex ] );
const float et( segEnds[ segIndex ] );
const float v0 = ( time - 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 auto pid( idxp.second );
const float sv( seg.values[ pid ] );
const float ev( seg.values[ pid + 1 ] );
return v * ( ev - sv ) + sv;
}
/*= T_SyncValues =============================================================*/
T_SyncValues::T_SyncValues( )
{
values.push_back( 0 );
}
// ---------------------------------------------------------------------
void T_SyncValues::clear( )
{
identifiers.clear( );
values.clear( );
overriden.clear( );
positions.clear( );
values.push_back( 0 );
}
bool T_SyncValues::addValue(
__rd__ std::string const& name ,
__rd__ const float initial )
{
const auto np( positions.find( name ) );
if ( np != positions.end( ) ) {
return false;
}
const auto li( values.size( ) - 1 );
positions.emplace( name , li );
identifiers.push_back( name );
values.push_back( initial );
std::swap( values[ li ] , values[ li + 1 ] );
overriden.push_back( false );
return true;
}
uint32_t T_SyncValues::indexOf(
__rd__ std::string const& name ) const
{
const auto np( positions.find( name ) );
if ( np == positions.end( ) ) {
return values.size( ) - 1;
} else {
return np->second;
}
}
/*= T_SyncManager ============================================================*/
void T_SyncManager::setDuration(
__rd__ const float uDuration ,
__rd__ const uint32_t iDuration )
{
time_.setDuration( uDuration , iDuration );
updateCurveCaches( );
}
void T_SyncManager::setTime(
__rd__ const float time )
{
time_.setTime( time );
updateValues( );
}
/*----------------------------------------------------------------------------*/
void T_SyncManager::updateCurveCaches( )
{
curveCaches_.clear( );
const uint32_t nv( values_.identifiers.size( ) );
for ( auto i = 0u ; i < nv ; i ++ ) {
auto const& id( values_.identifiers[ i ] );
const auto cp( curves_.indexOf( id ) );
if ( cp < 0 ) {
curveCaches_.emplace_back( );
} else {
curveCaches_.emplace_back( new T_SyncCurveCache(
time_ , curves_ , cp
) );
}
}
updateValues( );
}
void T_SyncManager::updateValues( )
{
const auto nv( values_.identifiers.size( ) );
assert( nv == curveCaches_.size( ) );
for ( auto i = 0u ; i < nv ; i ++ ) {
auto const& cc( curveCaches_[ i ] );
if ( !cc || values_.overriden[ i ] ) {
continue;
}
values_.values[ i ] = cc->value( time_ , curves_ );
}
}
/*============================================================================*/
#if 0
void T_SyncManager::makeUI( ) void T_SyncManager::makeUI( )
{ {
auto const& dspSize( ImGui::GetIO( ).DisplaySize ); auto const& dspSize( ImGui::GetIO( ).DisplaySize );
@ -73,6 +328,7 @@ void T_SyncManager::displayOvControls(
} }
} }
} }
#endif
/*============================================================================*/ /*============================================================================*/

219
sync.hh
View file

@ -4,6 +4,177 @@
#endif #endif
// Duration and current playing time
struct T_SyncTime
{
float uDuration = 1e-3f; // Duration - unit size
uint32_t iDuration = 1; // Duration - total units
float time = 0;
void setDuration(
__rd__ const float uDuration ,
__rd__ const uint32_t iDuration );
float duration( ) const noexcept
{ return uDuration * iDuration; }
void setTime( __rd__ const float t ) noexcept
{ time = std::max( 0.f , std::min( t , duration( ) ) ); }
};
/*============================================================================*/
// Segment of an input's curve
struct T_SyncSegment
{
enum E_SegmentType
{
LINEAR ,
RAMP ,
SMOOTH ,
//HERMITE
};
uint32_t nPoints;
E_SegmentType type;
std::vector< float > values; // nPoints items
std::vector< uint32_t > durations; // nPoints - 1 items
};
// An input curve
struct T_SyncCurve
{
std::string name;
std::vector< T_SyncSegment > segments;
};
// 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
{
std::vector< T_SyncCurve > curves;
std::map< std::string , int32_t > positions;
void clear( );
// Returns true on success, false on duplicate
bool addCurve( __rd__ T_SyncCurve curve );
// Returns -1 on lookup failure
int32_t indexOf( __rd__ std::string const& name );
};
/*----------------------------------------------------------------------------*/
// Pre-computed data for a curve
struct T_SyncCurveCache
{
using T_SegRef = std::pair< uint32_t , uint32_t >;
uint32_t curve;
std::vector< T_SegRef > segRefs;
std::vector< float > segStarts;
std::vector< float > segEnds;
uint32_t curPos;
T_SyncCurveCache(
__rd__ T_SyncTime const& time ,
__rd__ T_SyncCurves const& curves ,
__rd__ const uint32_t curve ) noexcept;
// Find the index of the segment for the specified time
uint32_t findSegment(
__rd__ const float time ) const noexcept;
// Compute the value of the curve at the specified location, ignoring
// curPos.
float valueAt(
__rd__ T_SyncTime const& time ,
__rd__ T_SyncCurves const& curves ,
__rd__ const float position ) const noexcept;
// Compute the value of the curve at the current time, using and
// updating curPos as necessary.
float value(
__rd__ T_SyncTime const& time ,
__rd__ T_SyncCurves const& curves ) noexcept;
float segmentValue(
__rd__ float time ,
__rd__ uint32_t segIndex ,
__rd__ std::vector< T_SyncSegment > const& segments ) const noexcept;
};
using P_SyncCurveCache = std::unique_ptr< T_SyncCurveCache >;
/*============================================================================*/
// Synchronization values. The values vector always contains an extra entry
// used for missing inputs.
struct T_SyncValues
{
std::vector< std::string > identifiers;
std::vector< float > values;
std::vector< bool > overriden;
std::unordered_map< std::string , uint32_t > positions;
T_SyncValues( );
void clear( );
// Returns true on success, false on duplicate
bool addValue(
__rd__ std::string const& name ,
__rd__ const float initial = 0.f );
// If the name isn't found, the last entry of values[] is returned
uint32_t indexOf(
__rd__ std::string const& name ) const;
};
/*============================================================================*/
// Synchronisation manager; handles all the synchronization data and makes it
// work together.
struct T_SyncManager
{
// ---------------------------------------------------------------------
// Duration & time controls
void setDuration(
__rd__ const float uDuration ,
__rd__ const uint32_t iDuration );
float duration( ) const noexcept
{ return time_.duration( ); }
void setTime( __rd__ const float time );
void timeDelta( __rd__ const float delta )
{ setTime( time_.time + delta ); }
float time( ) const noexcept
{ return time_.time; }
bool finished( ) const noexcept
{ return time_.time >= time_.duration( ); }
// ---------------------------------------------------------------------
void updateCurveCaches( );
void updateValues( );
private:
T_SyncTime time_;
T_SyncValues values_;
T_SyncCurves curves_;
std::vector< P_SyncCurveCache > curveCaches_;
};
/*============================================================================*/
// DISREGARD EVERYTHING BELOW, IT SUCKS!
/*============================================================================*/
#if 0
// Definition of a single input - id & range // Definition of a single input - id & range
struct T_SyncInputDfn struct T_SyncInputDfn
{ {
@ -50,53 +221,6 @@ struct T_SyncUISection
/*============================================================================*/ /*============================================================================*/
// Segment of an input's curve
struct T_SyncSegment
{
enum E_SegmentType
{
LINEAR ,
RAMP ,
SMOOTH ,
//HERMITE
};
uint32_t nPoints;
E_SegmentType type;
std::vector< float > values; // nPoints items
std::vector< uint32_t > durations; // nPoints - 1 items
};
// An input curve
struct T_SyncCurve
{
std::string name;
std::vector< T_SyncSegment > segments;
};
// Pre-computed data for a curve
struct T_SyncCurveCache
{
using T_SegRef = std::pair< uint32_t , uint32_t >;
T_SyncCurve const* variable;
std::vector< T_SegRef > segRefs;
std::vector< float > segStarts;
uint32_t curPos;
T_SyncCurveCache(
__rd__ T_SyncCurve const* const variable ,
__rd__ const uint32_t duration ,
__rd__ const uint32_t position ) noexcept;
float valueAt(
__rd__ const float position ,
__rd__ const float units ) const noexcept;
};
using P_SyncCurveCache = std::unique_ptr< T_SyncCurveCache >;
/*============================================================================*/
struct T_SyncManager struct T_SyncManager
{ {
float uDuration; // Duration - unit size float uDuration; // Duration - unit size
@ -139,6 +263,7 @@ struct T_SyncManager
void displayOvControls( void displayOvControls(
__rw__ T_SyncUIOverrides& overrides ); __rw__ T_SyncUIOverrides& overrides );
}; };
#endif
/*============================================================================*/ /*============================================================================*/