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