Make echo ack the ONLY check for prediction expiration (closes #16 on github)
This commit is contained in:
@@ -31,15 +31,6 @@ using namespace boost::lambda;
|
|||||||
using namespace Overlay;
|
using namespace Overlay;
|
||||||
using std::max;
|
using std::max;
|
||||||
|
|
||||||
bool ConditionalOverlay::start_clock( uint64_t local_frame_acked, uint64_t now, unsigned int send_interval )
|
|
||||||
{
|
|
||||||
if ( (local_frame_acked >= expiration_frame) && (expiration_time == uint64_t(-1)) ) {
|
|
||||||
expiration_time = now + 75 + 125 * send_interval / 100;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConditionalOverlayCell::apply( Framebuffer &fb, uint64_t confirmed_epoch, int row, bool flag ) const
|
void ConditionalOverlayCell::apply( Framebuffer &fb, uint64_t confirmed_epoch, int row, bool flag ) const
|
||||||
{
|
{
|
||||||
if ( (!active)
|
if ( (!active)
|
||||||
@@ -72,8 +63,7 @@ void ConditionalOverlayCell::apply( Framebuffer &fb, uint64_t confirmed_epoch, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
Validity ConditionalOverlayCell::get_validity( const Framebuffer &fb, int row,
|
Validity ConditionalOverlayCell::get_validity( const Framebuffer &fb, int row,
|
||||||
uint64_t sent_frame, uint64_t early_ack, uint64_t late_ack,
|
uint64_t early_ack, uint64_t late_ack ) const
|
||||||
uint64_t now ) const
|
|
||||||
{
|
{
|
||||||
if ( !active ) {
|
if ( !active ) {
|
||||||
return Inactive;
|
return Inactive;
|
||||||
@@ -95,10 +85,7 @@ Validity ConditionalOverlayCell::get_validity( const Framebuffer &fb, int row,
|
|||||||
return Pending;
|
return Pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( expiration_time != uint64_t(-1) );
|
if ( late_ack >= expiration_frame ) {
|
||||||
|
|
||||||
if ( (late_ack >= expiration_frame)
|
|
||||||
|| ( (sent_frame <= early_ack) && (expiration_time <= now) ) ) {
|
|
||||||
if ( (current.contents == replacement.contents)
|
if ( (current.contents == replacement.contents)
|
||||||
|| (current.is_blank() && replacement.is_blank()) ) {
|
|| (current.is_blank() && replacement.is_blank()) ) {
|
||||||
BOOST_AUTO( it, find_if( original_contents.begin(), original_contents.end(),
|
BOOST_AUTO( it, find_if( original_contents.begin(), original_contents.end(),
|
||||||
@@ -117,7 +104,7 @@ Validity ConditionalOverlayCell::get_validity( const Framebuffer &fb, int row,
|
|||||||
return Pending;
|
return Pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
Validity ConditionalCursorMove::get_validity( const Framebuffer &fb, uint64_t sent_frame, uint64_t early_ack, uint64_t late_ack, uint64_t now ) const
|
Validity ConditionalCursorMove::get_validity( const Framebuffer &fb, uint64_t early_ack, uint64_t late_ack ) const
|
||||||
{
|
{
|
||||||
if ( !active ) {
|
if ( !active ) {
|
||||||
return Inactive;
|
return Inactive;
|
||||||
@@ -134,10 +121,7 @@ Validity ConditionalCursorMove::get_validity( const Framebuffer &fb, uint64_t se
|
|||||||
return Pending;
|
return Pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( expiration_time != uint64_t(-1) );
|
if ( late_ack >= expiration_frame ) {
|
||||||
|
|
||||||
if ( (late_ack >= expiration_frame)
|
|
||||||
|| ( (sent_frame <= early_ack) && (expiration_time <= now) ) ) {
|
|
||||||
if ( (fb.ds.get_cursor_col() == col)
|
if ( (fb.ds.get_cursor_col() == col)
|
||||||
&& (fb.ds.get_cursor_row() == row) ) {
|
&& (fb.ds.get_cursor_row() == row) ) {
|
||||||
return Correct;
|
return Correct;
|
||||||
@@ -417,12 +401,8 @@ void PredictionEngine::cull( const Framebuffer &fb )
|
|||||||
}
|
}
|
||||||
|
|
||||||
for ( BOOST_AUTO( j, i->overlay_cells.begin() ); j != i->overlay_cells.end(); j++ ) {
|
for ( BOOST_AUTO( j, i->overlay_cells.begin() ); j != i->overlay_cells.end(); j++ ) {
|
||||||
if ( j->start_clock( local_frame_acked, now, send_interval ) ) {
|
|
||||||
last_scheduled_timeout = max( last_scheduled_timeout, j->expiration_time );
|
|
||||||
}
|
|
||||||
switch ( j->get_validity( fb, i->row_num,
|
switch ( j->get_validity( fb, i->row_num,
|
||||||
local_frame_sent, local_frame_acked, local_frame_late_acked,
|
local_frame_acked, local_frame_late_acked ) ) {
|
||||||
now ) ) {
|
|
||||||
case IncorrectOrExpired:
|
case IncorrectOrExpired:
|
||||||
if ( j->tentative( confirmed_epoch ) ) {
|
if ( j->tentative( confirmed_epoch ) ) {
|
||||||
|
|
||||||
@@ -506,16 +486,9 @@ void PredictionEngine::cull( const Framebuffer &fb )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* go through cursor predictions */
|
/* go through cursor predictions */
|
||||||
for ( BOOST_AUTO( it, cursors.begin() ); it != cursors.end(); it++ ) {
|
|
||||||
if ( it->start_clock( local_frame_acked, now, send_interval ) ) {
|
|
||||||
last_scheduled_timeout = max( last_scheduled_timeout, it->expiration_time );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !cursors.empty() ) {
|
if ( !cursors.empty() ) {
|
||||||
if ( cursor().get_validity( fb,
|
if ( cursor().get_validity( fb,
|
||||||
local_frame_sent, local_frame_acked, local_frame_late_acked,
|
local_frame_acked, local_frame_late_acked ) == IncorrectOrExpired ) {
|
||||||
now ) == IncorrectOrExpired ) {
|
|
||||||
/*
|
/*
|
||||||
fprintf( stderr, "Sadly, we're predicting (%d,%d) vs. (%d,%d) [tau: %ld, expiration_time=%ld, now=%ld]\n",
|
fprintf( stderr, "Sadly, we're predicting (%d,%d) vs. (%d,%d) [tau: %ld, expiration_time=%ld, now=%ld]\n",
|
||||||
cursor().row, cursor().col,
|
cursor().row, cursor().col,
|
||||||
@@ -531,8 +504,7 @@ void PredictionEngine::cull( const Framebuffer &fb )
|
|||||||
}
|
}
|
||||||
|
|
||||||
cursors.remove_if( bind( &ConditionalCursorMove::get_validity, _1, var(fb),
|
cursors.remove_if( bind( &ConditionalCursorMove::get_validity, _1, var(fb),
|
||||||
local_frame_sent, local_frame_acked, local_frame_late_acked,
|
local_frame_acked, local_frame_late_acked ) != Pending );
|
||||||
now ) != Pending );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConditionalOverlayRow & PredictionEngine::get_or_make_row( int row_num, int num_cols )
|
ConditionalOverlayRow & PredictionEngine::get_or_make_row( int row_num, int num_cols )
|
||||||
@@ -775,3 +747,20 @@ void PredictionEngine::become_tentative( void )
|
|||||||
prediction_epoch, confirmed_epoch );
|
prediction_epoch, confirmed_epoch );
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PredictionEngine::active( void ) const
|
||||||
|
{
|
||||||
|
if ( !cursors.empty() ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( BOOST_AUTO( i, overlays.begin() ); i != overlays.end(); i++ ) {
|
||||||
|
for ( BOOST_AUTO( j, i->overlay_cells.begin() ); j != i->overlay_cells.end(); j++ ) {
|
||||||
|
if ( j->active ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -44,14 +44,13 @@ namespace Overlay {
|
|||||||
class ConditionalOverlay {
|
class ConditionalOverlay {
|
||||||
public:
|
public:
|
||||||
uint64_t expiration_frame;
|
uint64_t expiration_frame;
|
||||||
uint64_t expiration_time; /* after frame is hit */
|
|
||||||
int col;
|
int col;
|
||||||
bool active; /* represents a prediction at all */
|
bool active; /* represents a prediction at all */
|
||||||
uint64_t tentative_until_epoch; /* when to show */
|
uint64_t tentative_until_epoch; /* when to show */
|
||||||
uint64_t prediction_time; /* used to find long-pending predictions */
|
uint64_t prediction_time; /* used to find long-pending predictions */
|
||||||
|
|
||||||
ConditionalOverlay( uint64_t s_exp, int s_col, uint64_t s_tentative )
|
ConditionalOverlay( uint64_t s_exp, int s_col, uint64_t s_tentative )
|
||||||
: expiration_frame( s_exp ), expiration_time( uint64_t( -1 ) ), col( s_col ),
|
: expiration_frame( s_exp ), col( s_col ),
|
||||||
active( false ),
|
active( false ),
|
||||||
tentative_until_epoch( s_tentative ), prediction_time( uint64_t( -1 ) )
|
tentative_until_epoch( s_tentative ), prediction_time( uint64_t( -1 ) )
|
||||||
{}
|
{}
|
||||||
@@ -59,11 +58,10 @@ namespace Overlay {
|
|||||||
virtual ~ConditionalOverlay() {}
|
virtual ~ConditionalOverlay() {}
|
||||||
|
|
||||||
bool tentative( uint64_t confirmed_epoch ) const { return tentative_until_epoch > confirmed_epoch; }
|
bool tentative( uint64_t confirmed_epoch ) const { return tentative_until_epoch > confirmed_epoch; }
|
||||||
void reset( void ) { expiration_frame = expiration_time = tentative_until_epoch = -1; active = false; }
|
void reset( void ) { expiration_frame = tentative_until_epoch = -1; active = false; }
|
||||||
bool start_clock( uint64_t local_frame_acked, uint64_t now, unsigned int send_interval );
|
|
||||||
void expire( uint64_t s_exp, uint64_t now )
|
void expire( uint64_t s_exp, uint64_t now )
|
||||||
{
|
{
|
||||||
expiration_frame = s_exp; expiration_time = uint64_t(-1); prediction_time = now;
|
expiration_frame = s_exp; prediction_time = now;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -73,7 +71,7 @@ namespace Overlay {
|
|||||||
|
|
||||||
void apply( Framebuffer &fb, uint64_t confirmed_epoch ) const;
|
void apply( Framebuffer &fb, uint64_t confirmed_epoch ) const;
|
||||||
|
|
||||||
Validity get_validity( const Framebuffer &fb, uint64_t sent_frame, uint64_t early_ack, uint64_t late_ack, uint64_t now ) const;
|
Validity get_validity( const Framebuffer &fb, uint64_t early_ack, uint64_t late_ack ) const;
|
||||||
|
|
||||||
ConditionalCursorMove( uint64_t s_exp, int s_row, int s_col, uint64_t s_tentative )
|
ConditionalCursorMove( uint64_t s_exp, int s_row, int s_col, uint64_t s_tentative )
|
||||||
: ConditionalOverlay( s_exp, s_col, s_tentative ), row( s_row )
|
: ConditionalOverlay( s_exp, s_col, s_tentative ), row( s_row )
|
||||||
@@ -89,7 +87,7 @@ namespace Overlay {
|
|||||||
that match the original contents */
|
that match the original contents */
|
||||||
|
|
||||||
void apply( Framebuffer &fb, uint64_t confirmed_epoch, int row, bool flag ) const;
|
void apply( Framebuffer &fb, uint64_t confirmed_epoch, int row, bool flag ) const;
|
||||||
Validity get_validity( const Framebuffer &fb, int row, uint64_t sent_frame, uint64_t early_ack, uint64_t late_ack, uint64_t now ) const;
|
Validity get_validity( const Framebuffer &fb, int row, uint64_t early_ack, uint64_t late_ack ) const;
|
||||||
|
|
||||||
ConditionalOverlayCell( uint64_t s_exp, int s_col, uint64_t s_tentative )
|
ConditionalOverlayCell( uint64_t s_exp, int s_col, uint64_t s_tentative )
|
||||||
: ConditionalOverlay( s_exp, s_col, s_tentative ),
|
: ConditionalOverlay( s_exp, s_col, s_tentative ),
|
||||||
@@ -183,8 +181,6 @@ namespace Overlay {
|
|||||||
|
|
||||||
void init_cursor( const Framebuffer &fb );
|
void init_cursor( const Framebuffer &fb );
|
||||||
|
|
||||||
uint64_t last_scheduled_timeout;
|
|
||||||
|
|
||||||
unsigned int send_interval;
|
unsigned int send_interval;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -206,7 +202,7 @@ namespace Overlay {
|
|||||||
|
|
||||||
void reset( void );
|
void reset( void );
|
||||||
|
|
||||||
bool active( void ) { return timestamp() <= last_scheduled_timeout; }
|
bool active( void ) const;
|
||||||
|
|
||||||
void set_local_frame_sent( uint64_t x ) { local_frame_sent = x; }
|
void set_local_frame_sent( uint64_t x ) { local_frame_sent = x; }
|
||||||
void set_local_frame_acked( uint64_t x ) { local_frame_acked = x; }
|
void set_local_frame_acked( uint64_t x ) { local_frame_acked = x; }
|
||||||
@@ -222,7 +218,6 @@ namespace Overlay {
|
|||||||
srtt_trigger( false ),
|
srtt_trigger( false ),
|
||||||
glitch_trigger( 0 ),
|
glitch_trigger( 0 ),
|
||||||
last_quick_confirmation( 0 ),
|
last_quick_confirmation( 0 ),
|
||||||
last_scheduled_timeout( 0 ),
|
|
||||||
send_interval( 250 ),
|
send_interval( 250 ),
|
||||||
display_preference( Adaptive )
|
display_preference( Adaptive )
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user