User selectable prediction mode (fixes #9 github issue)
This commit is contained in:
+18
-3
@@ -26,16 +26,31 @@ $|=1;
|
||||
|
||||
my $client = 'mosh-client';
|
||||
my $server = 'mosh-server';
|
||||
my $predict = 'adaptive';
|
||||
|
||||
my $usage =
|
||||
qq{Usage: $0 [options] [user@]host
|
||||
--client=PATH mosh client on local machine (default: "mosh-client")
|
||||
--server=PATH mosh server on remote machine (default: "mosh-server")\n};
|
||||
--client=PATH mosh client on local machine (default: "mosh-client")
|
||||
--server=PATH mosh server on remote machine (default: "mosh-server")
|
||||
|
||||
--predict=adaptive local echo for slower links [default]
|
||||
-a --predict=always use local echo even on fast links
|
||||
-n --predict=never never use local echo
|
||||
|
||||
Please report bugs to mosh-devel\@mit.edu.
|
||||
Mosh home page: http://mosh.mit.edu\n};
|
||||
|
||||
GetOptions( 'client=s' => \$client,
|
||||
'server=s' => \$server,
|
||||
'predict=s' => \$predict,
|
||||
'a' => sub { $predict = 'always' },
|
||||
'n' => sub { $predict = 'never' },
|
||||
'fake-proxy!' => \my $fake_proxy ) or die $usage;
|
||||
|
||||
if ( not exists { adaptive => 0, always => 0, never => 0 }->{ $predict } ) {
|
||||
die $usage;
|
||||
}
|
||||
|
||||
if ( defined $fake_proxy ) {
|
||||
use Errno qw(EINTR);
|
||||
use IO::Socket::INET;
|
||||
@@ -122,5 +137,5 @@ if ( $pid == 0 ) { # child
|
||||
|
||||
# Now start real mosh client
|
||||
$ENV{ 'MOSH_KEY' } = $key;
|
||||
exec {$client} ($client, $ip, $port);
|
||||
exec {$client} ($client, $ip, $port, $predict);
|
||||
}
|
||||
|
||||
@@ -22,14 +22,24 @@
|
||||
#include "stmclient.h"
|
||||
#include "crypto.h"
|
||||
|
||||
void usage( const char *argv0 ) {
|
||||
fprintf( stderr, "Usage: %s IP PORT [always|never|adaptive]\n", argv0 );
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
/* Get arguments */
|
||||
char *ip;
|
||||
int port;
|
||||
|
||||
if ( argc != 3 ) {
|
||||
fprintf( stderr, "Usage: %s IP PORT\n", argv[ 0 ] );
|
||||
char *predict_mode = NULL;
|
||||
|
||||
if ( argc == 4 ) {
|
||||
predict_mode = argv[ 3 ];
|
||||
} else if ( argc == 3 ) {
|
||||
/* do nothing */
|
||||
} else {
|
||||
usage( argv[ 0 ]);
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
@@ -61,7 +71,7 @@ int main( int argc, char *argv[] )
|
||||
}
|
||||
|
||||
try {
|
||||
STMClient client( ip, port, key );
|
||||
STMClient client( ip, port, key, predict_mode );
|
||||
client.init();
|
||||
|
||||
try {
|
||||
|
||||
@@ -53,7 +53,7 @@ private:
|
||||
void output_new_frame( void );
|
||||
|
||||
public:
|
||||
STMClient( const char *s_ip, int s_port, const char *s_key )
|
||||
STMClient( const char *s_ip, int s_port, const char *s_key, const char *predict_mode )
|
||||
: ip( s_ip ), port( s_port ), key( s_key ),
|
||||
saved_termios(), raw_termios(),
|
||||
winch_fd(), shutdown_signal_fd(),
|
||||
@@ -63,7 +63,20 @@ public:
|
||||
network( NULL ),
|
||||
repaint_requested( false ),
|
||||
quit_sequence_started( false )
|
||||
{}
|
||||
{
|
||||
if ( predict_mode ) {
|
||||
if ( !strcmp( predict_mode, "always" ) ) {
|
||||
overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Always );
|
||||
} else if ( !strcmp( predict_mode, "never" ) ) {
|
||||
overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Never );
|
||||
} else if ( !strcmp( predict_mode, "adaptive" ) ) {
|
||||
overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Adaptive );
|
||||
} else {
|
||||
fprintf( stderr, "Unknown prediction mode %s.\n", predict_mode );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void init( void );
|
||||
void shutdown( void );
|
||||
|
||||
@@ -315,7 +315,9 @@ void ConditionalOverlayRow::apply( Framebuffer &fb, uint64_t confirmed_epoch, bo
|
||||
|
||||
void PredictionEngine::apply( Framebuffer &fb ) const
|
||||
{
|
||||
bool show = srtt_trigger || glitch_trigger;
|
||||
bool show = (display_preference != Never) && ( srtt_trigger
|
||||
|| glitch_trigger
|
||||
|| (display_preference == Always) );
|
||||
|
||||
if ( show ) {
|
||||
for_each( cursors.begin(), cursors.end(), [&]( const ConditionalCursorMove &x ) { x.apply( fb, confirmed_epoch ); } );
|
||||
@@ -377,6 +379,10 @@ void PredictionEngine::init_cursor( const Framebuffer &fb )
|
||||
|
||||
void PredictionEngine::cull( const Framebuffer &fb )
|
||||
{
|
||||
if ( display_preference == Never ) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t now = timestamp();
|
||||
|
||||
/* control srtt_trigger with hysteresis */
|
||||
@@ -547,6 +553,10 @@ ConditionalOverlayRow & PredictionEngine::get_or_make_row( int row_num, int num_
|
||||
|
||||
void PredictionEngine::new_user_byte( char the_byte, const Framebuffer &fb )
|
||||
{
|
||||
if ( display_preference == Never ) {
|
||||
return;
|
||||
}
|
||||
|
||||
cull( fb );
|
||||
|
||||
uint64_t now = timestamp();
|
||||
|
||||
@@ -185,6 +185,18 @@ namespace Overlay {
|
||||
unsigned int send_interval;
|
||||
|
||||
public:
|
||||
enum DisplayPreference {
|
||||
Always,
|
||||
Never,
|
||||
Adaptive
|
||||
};
|
||||
|
||||
private:
|
||||
DisplayPreference display_preference;
|
||||
|
||||
public:
|
||||
void set_display_preference( DisplayPreference s_pref ) { display_preference = s_pref; }
|
||||
|
||||
void apply( Framebuffer &fb ) const;
|
||||
void new_user_byte( char the_byte, const Framebuffer &fb );
|
||||
void cull( const Framebuffer &fb );
|
||||
@@ -208,7 +220,8 @@ namespace Overlay {
|
||||
glitch_trigger( 0 ),
|
||||
last_quick_confirmation( 0 ),
|
||||
last_scheduled_timeout( 0 ),
|
||||
send_interval( 250 )
|
||||
send_interval( 250 ),
|
||||
display_preference( Adaptive )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user