poll functions
authorhgn <hgodden00@gmail.com>
Mon, 16 Jan 2023 14:16:59 +0000 (14:16 +0000)
committerhgn <hgodden00@gmail.com>
Mon, 16 Jan 2023 14:16:59 +0000 (14:16 +0000)
vg_audio.h
vg_console.h
vg_input.h
vg_lines.h
vg_profiler.h

index aeb05a4f9e0926b1ca44d6c5f534362bf76c7ddf..07c4be09b2d61361c383ba695dfeff70bc674f76 100644 (file)
@@ -217,18 +217,18 @@ VG_STATIC void vg_audio_init(void)
    vg_audio.mux_sync = SDL_CreateMutex();
 
    /* TODO: Move here? */
-   vg_convar_push( (struct vg_convar){
+   vg_var_push( (struct vg_var){
       .name = "debug_audio",
       .data = &vg_audio.debug_ui,
-      .data_type = k_convar_dtype_i32,
+      .data_type = k_var_dtype_i32,
       .opt_i32 = { .min=0, .max=1, .clamp=1 },
       .persistent = 1
    });
 
-   vg_convar_push( (struct vg_convar){
+   vg_var_push( (struct vg_var){
       .name = "volume",
       .data = &vg_audio.volume_console,
-      .data_type = k_convar_dtype_f32,
+      .data_type = k_var_dtype_f32,
       .opt_f32 = { .min=0.0f, .max=2.0f, .clamp=1 },
       .persistent = 1
    });
index 8f8517cb7d41662a7afce1f31ca2e9c1d97d4fce..dbf57f72be526b3c27240110baca5953164f839a 100644 (file)
 #include "vg/vg_ui.h"
 #include "vg/vg_log.h"
 
-typedef struct vg_convar vg_convar;
+typedef struct vg_var vg_var;
 typedef struct vg_cmd vg_cmd;
 
 struct vg_console
 {
-       struct vg_convar
+       struct vg_var
        {
                void *data;
-      void (*update)(void);
                const char *name;
                
-               enum vg_convar_dtype
+               enum vg_var_dtype
                {
-                       k_convar_dtype_i32,
-                       k_convar_dtype_u32,
-                       k_convar_dtype_f32
+                       k_var_dtype_i32,
+                       k_var_dtype_u32,
+                       k_var_dtype_f32
                } 
                data_type;
                
@@ -47,11 +46,12 @@ struct vg_console
 
                int persistent; /* Should this var be stored to cfg/auto.conf? */
        } 
-       convars[ 32 ];
+       vars[ 32 ];
        
        struct vg_cmd
        {
-               int (*function)( int argc, char const *argv[] );
+               int  (*function)( int argc, char const *argv[] );
+      void (*poll_suggest)( int argc, char const *argv[] );
                const char *name;
        }
        functions[ 32 ];
@@ -69,7 +69,7 @@ struct vg_console
        suggestion_pastepos,
        suggestion_maxlen;
 
-   u32 convar_count, function_count;
+   u32 var_count, function_count;
        
        char input[96],
         input_copy[96];
@@ -82,7 +82,7 @@ struct vg_console
 }
 vg_console;
 
-VG_STATIC void  vg_convar_push( struct vg_convar cv );
+VG_STATIC void  vg_var_push( struct vg_var cv );
 VG_STATIC void  vg_function_push( struct vg_cmd cmd );
 
 VG_STATIC void _vg_console_draw( void );
@@ -116,13 +116,13 @@ VG_STATIC int _vg_console_enabled(void)
        return vg_console.enabled; 
 }
 
-VG_STATIC void vg_convar_push( vg_convar cv )
+VG_STATIC void vg_var_push( vg_var cv )
 {
-   if( vg_console.convar_count > vg_list_size(vg_console.convars) )
-      vg_fatal_exit_loop( "Too many convars registered" );
+   if( vg_console.var_count > vg_list_size(vg_console.vars) )
+      vg_fatal_exit_loop( "Too many vars registered" );
 
    vg_info( "Console variable '%s' registered\n", cv.name );
-   vg_console.convars[ vg_console.convar_count ++ ] = cv;
+   vg_console.vars[ vg_console.var_count ++ ] = cv;
 }
 
 VG_STATIC void vg_function_push( struct vg_cmd cmd )
@@ -196,10 +196,10 @@ VG_STATIC void _vg_console_draw( void )
        ui_end_down();
 
 
-
    /* suggestions */
    if( vg_console.suggestion_count )
    {
+      vg_uictx.cursor[0] += UI_GLYPH_SPACING_X * vg_console.suggestion_pastepos;
       vg_uictx.cursor[1] += 2;
       vg_uictx.cursor[3] = vg_console.suggestion_count * fh;
       vg_uictx.cursor[2] = UI_GLYPH_SPACING_X * vg_console.suggestion_maxlen;
@@ -232,9 +232,9 @@ VG_STATIC int _vg_console_list( int argc, char const *argv[] )
                vg_info( "* %s\n", cmd->name );
        }
        
-       for( int i=0; i<vg_console.convar_count; i ++ )
+       for( int i=0; i<vg_console.var_count; i ++ )
        {
-               struct vg_convar *cv = &vg_console.convars[ i ];
+               struct vg_var *cv = &vg_console.vars[ i ];
                vg_info( "%s\n", cv->name );
        }
        
@@ -288,21 +288,21 @@ VG_STATIC void _vg_console_write_persistent(void)
 {
        FILE *fp = fopen( "cfg/auto.conf", "w" );
        
-       for( int i=0; i<vg_console.convar_count; i ++ )
+       for( int i=0; i<vg_console.var_count; i ++ )
        {
-               struct vg_convar *cv = &vg_console.convars[i];
+               struct vg_var *cv = &vg_console.vars[i];
 
                if( cv->persistent )
                {
                        switch( cv->data_type )
                        {
-                               case k_convar_dtype_i32:
+                               case k_var_dtype_i32:
                                        fprintf( fp, "%s %d\n", cv->name, *(i32 *)(cv->data) );
                                break;
-                               case k_convar_dtype_u32:
+                               case k_var_dtype_u32:
                                        fprintf( fp, "%s %u\n", cv->name, *(u32 *)(cv->data) );
                                break;
-                               case k_convar_dtype_f32:
+                               case k_var_dtype_f32:
                                        fprintf( fp, "%s %.5f\n", cv->name, *(float *)(cv->data ) );
                                break;
                        }
@@ -317,115 +317,137 @@ VG_STATIC void _vg_console_free(void)
        _vg_console_write_persistent();
 }
 
-VG_STATIC void vg_execute_console_input( const char *cmd )
+/*
+ * splits src into tokens and fills out args as pointers to those tokens
+ * returns number of tokens
+ * dst must be as long as src
+ */
+VG_STATIC int vg_console_tokenize( const char *src, char *dst, 
+                                   const char *args[8] )
 {
-       char temp[512];
-       char const *args[9];
-       int arg_count = 0;
-       
-       int in_token = 0;
+       int arg_count = 0,
+       in_token = 0;
        
-       /* Split string into tokens */
-       for( int i = 0; i < vg_list_size( temp ); i ++ )
+       for( int i=0; 1; i ++ )
        {
-               if( cmd[i] )
+               if( src[i] )
                {
-                       if( cmd[i] == ' ' || cmd[i] == '\t' )
+                       if( src[i] == ' ' || src[i] == '\t' )
                        {
-                               temp[i] = '\0';
+            if( in_token )
+               dst[i] = '\0';
+
                                in_token = 0;
                                
-                               if( arg_count == vg_list_size( args ) )
+                               if( arg_count == 8 )
                                        break;
                        }
                        else
                        {
-                               temp[i] = cmd[i];
+                               dst[i] = src[i];
                                
                                if( !in_token )
                                {
-                                       args[ arg_count ++ ] = temp + i;
+                                       args[ arg_count ++ ] = &dst[i];
                                        in_token = 1;
                                }
                        }
                }
                else
                {
-                       temp[i] = '\0';
+                       dst[i] = '\0';
                        break;
                }
        }
-       
-       if( arg_count == 0 )
-               return;
-       
-       int data_int;
-   float data_float;
-       
-       for( int i=0; i<vg_console.convar_count; i ++ )
+
+   return arg_count;
+}
+
+VG_STATIC vg_var *vg_console_match_var( const char *kw )
+{
+       for( int i=0; i<vg_console.var_count; i ++ )
        {
-               struct vg_convar *cv = &vg_console.convars[ i ];
-               if( !strcmp( cv->name, args[0] ) )
+               struct vg_var *cv = &vg_console.vars[ i ];
+               if( !strcmp( cv->name, kw ) )
                {
-                       /* Cvar Matched, try get value */
-                       if( arg_count >= 2 )
-                       {
-                               switch( cv->data_type )
-                               {
-                                       case k_convar_dtype_u32:
-                                       case k_convar_dtype_i32: 
-                                               
-                                               data_int = atoi( args[1] ); 
-                  
-                                               *((int *)cv->data) = cv->opt_i32.clamp? 
-                   VG_MIN( VG_MAX(data_int, cv->opt_i32.min), cv->opt_i32.max ): 
-                   data_int;
-                                       
-                                       break;
-                                       case k_convar_dtype_f32: 
-                  data_float = atof( args[1] );
-                  *((float *)cv->data) = cv->opt_f32.clamp?
-                     vg_minf( vg_maxf( data_float, cv->opt_f32.min), 
-                              cv->opt_f32.max ):
-                     data_float;
-               break;
-                               }
+         return cv;
+      }
+   }
 
-            if( cv->update )
-               cv->update();
-                       }
-                       else
-                       {
-                               switch( cv->data_type )
-                               {
-                                       case k_convar_dtype_i32: 
-                  vg_info( "= %d\n", *((int *)cv->data) ); 
-               break;
-                                       case k_convar_dtype_u32: 
-                  vg_info( "= %u\n", *((u32 *)cv->data) );
-               break;
-                                       case k_convar_dtype_f32: 
-                  vg_info( "= %.4f\n", *((float *)cv->data) );
-               break;
-                               }
-                       }
-               
-                       return;
-               }
-       }
-       
-   /*
-    * Find and excecute command
-    */
+   return NULL;
+}
+
+VG_STATIC vg_cmd *vg_console_match_cmd( const char *kw )
+{
        for( int i=0; i<vg_console.function_count; i ++ )
        {
                struct vg_cmd *cmd = &vg_console.functions[ i ];
-               if( !strcmp( cmd->name, args[0] ) )
+               if( !strcmp( cmd->name, kw ) )
                {
-                       cmd->function( arg_count-1, args+1 );
-                       return;
-               }
+         return cmd;
+      }
+   }
+
+   return NULL;
+}
+
+VG_STATIC void vg_execute_console_input( const char *cmd )
+{
+       char temp[512];
+       char const *args[8];
+       int arg_count = vg_console_tokenize( cmd, temp, args );
+       
+       if( arg_count == 0 )
+               return;
+       
+       int data_int;
+   float data_float;
+
+   vg_var *cv = vg_console_match_var( args[0] );
+   vg_cmd *fn = vg_console_match_cmd( args[0] );
+
+   assert( !(cv && fn) );
+
+   if( cv )
+   {
+      /* Cvar Matched, try get value */
+      if( arg_count >= 2 )
+      {
+         if( (cv->data_type == k_var_dtype_u32) ||
+             (cv->data_type == k_var_dtype_i32) )
+         {
+            data_int = atoi( args[1] ); 
+            
+            *((int *)cv->data) = cv->opt_i32.clamp? 
+             VG_MIN( VG_MAX(data_int, cv->opt_i32.min), cv->opt_i32.max ): 
+             data_int;
+         }
+         else if( cv->data_type == k_var_dtype_f32 )
+         {
+            data_float = atof( args[1] );
+            *((float *)cv->data) = cv->opt_f32.clamp?
+               vg_minf( vg_maxf( data_float, cv->opt_f32.min), 
+                        cv->opt_f32.max ):
+               data_float;
+         }
+      }
+      else
+      {
+         if( cv->data_type == k_var_dtype_i32 )
+            vg_info( "= %d\n", *((int *)cv->data) ); 
+         else if( cv->data_type == k_var_dtype_u32 )
+            vg_info( "= %u\n", *((u32 *)cv->data) );
+         else if( cv->data_type == k_var_dtype_f32 )
+            vg_info( "= %.4f\n", *((float *)cv->data) );
+      }
+   
+      return;
        }
+   else if( fn )
+   {
+      fn->function( arg_count-1, args+1 );
+      return;
+   }
        
        vg_error( "No command/var named '%s'. Use 'list' to view all\n", args[0] );
 }
@@ -499,12 +521,18 @@ u32 str_lcs( const char *s1, const char *s2 )
 }
 
 /* str must not fuckoff ever! */
-VG_STATIC void console_suggest_score_text( const char *input, const char *str )
+VG_STATIC void console_suggest_score_text( const char *str, const char *input,
+                                           int minscore )
 {
+   /* filter duplicates */
+   for( int i=0; i<vg_console.suggestion_count; i++ )
+      if( !strcmp( vg_console.suggestions[i].str, str ) )
+         return;
+
    /* calc score */
    u32 score = str_lcs( str, input );
 
-   if( score < 1 )
+   if( score < minscore )
       return;
 
    int best_pos = vg_console.suggestion_count;
@@ -536,39 +564,58 @@ VG_STATIC void console_update_suggestions(void)
    vg_console.suggestion_select = -1;
    vg_console.suggestion_maxlen = 0;
 
-   /* find current term */
-   int start_index = 0;
+   /* 
+    * - must be typing something
+    * - must be at the end
+    * - prev char must not be a whitespace
+    * - cursors should match
+    */
 
-   for( int i=0; 1; i++ )
-   {
-      if( !vg_console.input[i] )
-         break;
+   if( vg_console.cursor_pos == 0 )
+      return;
 
-      if( isspace( vg_console.input[i] ) )
-      {
-         start_index = i;
+   if( vg_console.cursor_pos != vg_console.cursor_user )
+      return;
 
-         /* TODO:  not just functions
-          */
+   if( vg_console.input[ vg_console.cursor_pos ] != '\0' )
+      return;
 
-         return;
-      }
-   }
+   if(  (vg_console.input[ vg_console.cursor_pos -1 ] == ' ') ||
+        (vg_console.input[ vg_console.cursor_pos -1 ] == '\t') )
+      return;
+
+   char temp[128];
+   const char *args[8];
 
-   vg_console.suggestion_pastepos = start_index;
-   const char *input_ref = &vg_console.input[ start_index ];
+   int token_count = vg_console_tokenize( vg_console.input, temp, args );
 
-   /* Score all  our commands and cvars */
-   for( int i=0; i<vg_console.convar_count; i++ )
+   vg_console.suggestion_pastepos = args[token_count-1]-temp;
+
+   /* Score all our commands and cvars */
+   if( token_count == 1 )
    {
-      vg_convar *cvar = &vg_console.convars[i];
-      console_suggest_score_text( input_ref, cvar->name );
-   }
+      for( int i=0; i<vg_console.var_count; i++ )
+      {
+         vg_var *cvar = &vg_console.vars[i];
+         console_suggest_score_text( cvar->name, args[0], 1 );
+      }
 
-   for( int i=0; i<vg_console.function_count; i++ )
+      for( int i=0; i<vg_console.function_count; i++ )
+      {
+         vg_cmd *cmd = &vg_console.functions[i];
+         console_suggest_score_text( cmd->name, args[0], 1 );
+      }
+   }
+   else
    {
-      vg_cmd *cmd = &vg_console.functions[i];
-      console_suggest_score_text( input_ref, cmd->name );
+      vg_cmd *cmd = vg_console_match_cmd( args[0] );
+      vg_var *var = vg_console_match_var( args[0] );
+
+      assert( !( cmd && var ) );
+
+      if( cmd )
+         if( cmd->poll_suggest )
+            cmd->poll_suggest( token_count-1, &args[1] );
    }
 
    /* some post processing */
@@ -647,8 +694,6 @@ VG_STATIC int console_delete_char( int direction )
        memmove( &vg_console.input[ start ], 
             &vg_console.input[ end ], 
             remaining_length );
-
-   console_update_suggestions();
        return start;
 }
 
@@ -776,12 +821,16 @@ VG_STATIC void _console_backspace(void)
 {
    vg_console.cursor_user = console_delete_char( -1 );
    vg_console.cursor_pos = vg_console.cursor_user;
+
+   console_update_suggestions();
 }
 
 VG_STATIC void _console_delete(void)
 {
    vg_console.cursor_user = console_delete_char( 1 );
    vg_console.cursor_pos = vg_console.cursor_user;
+
+   console_update_suggestions();
 }
 
 VG_STATIC void _console_home_select(void)
@@ -853,15 +902,17 @@ VG_STATIC void _console_enter(void)
  */
 VG_STATIC void _console_fetch_suggestion(void)
 {
+   char *target = &vg_console.input[ vg_console.suggestion_pastepos ];
+
    if( vg_console.suggestion_select == -1 )
    {
-      strcpy( vg_console.input, vg_console.input_copy );
+      strcpy( target, vg_console.input_copy );
       console_move_cursor( &vg_console.cursor_user, 
                            &vg_console.cursor_pos, 10000, 1 );
    }
    else
    {
-      strncpy( vg_console.input,
+      strncpy( target,
             vg_console.suggestions[ vg_console.suggestion_select ].str,
             vg_list_size( vg_console.input )-1 );
 
@@ -874,7 +925,10 @@ VG_STATIC void _console_fetch_suggestion(void)
 VG_STATIC void _console_suggest_store_normal(void)
 {
    if( vg_console.suggestion_select == -1 )
-      strcpy( vg_console.input_copy, vg_console.input );
+   {
+      char *target = &vg_console.input[ vg_console.suggestion_pastepos ];
+      strcpy( vg_console.input_copy, target );
+   }
 }
 
 VG_STATIC void _console_suggest_next(void)
index 87109d25e777d2d2f844472ce88e3b62b44ed3ca..1052c42937f1c61ce535b8199d8857494b08e57d 100644 (file)
@@ -380,10 +380,10 @@ VG_STATIC void vg_apply_bind_str( struct input_binding *bind,
 }
 
 /* 
- * bind x jump 
- * bind a -horizontal
- * bind d +horizontal
- * bind -gp-ls-h horizontal
+ * bind  jump        x
+ * bind -horizontal  a
+ * bind +horizontal  d
+ * bind  horizontal -gp-ls-h 
  */
 
 VG_STATIC int vg_rebind_input_cmd( int argc, const char *argv[] )
@@ -422,6 +422,32 @@ VG_STATIC int vg_rebind_input_cmd( int argc, const char *argv[] )
    return 0;
 }
 
+VG_STATIC void vg_rebind_input_cmd_poll( int argc, const char *argv[] )
+{
+   if( argc == 0 )
+      return;
+
+   const char *str_bind_name = argv[0];
+
+   if( argc == 1 )
+   {
+      for( u32 i=0; i<vg_input.named_input_count; i++ )
+      {
+         struct input_binding *bind = &vg_input.named_inputs[i];
+         console_suggest_score_text( bind->name, argv[argc-1], 0 );
+      }
+   }
+
+   else if( argc == 2 )
+   {
+      for( int i=0; i<vg_list_size(vg_all_bindable_inputs); i++ )
+      {
+         struct input_en *desc = &vg_all_bindable_inputs[i];
+         console_suggest_score_text( desc->alias, argv[argc-1], 0 );
+      }
+   }
+}
+
 VG_STATIC u8 vg_getkey( SDL_Keycode kc )
 {
    SDL_Scancode sc = SDL_GetScancodeFromKey( kc );
@@ -588,13 +614,14 @@ VG_STATIC void vg_input_init(void)
    vg_function_push( (struct vg_cmd)
    {
       .name = "bind",
-      .function = vg_rebind_input_cmd
+      .function = vg_rebind_input_cmd,
+      .poll_suggest = vg_rebind_input_cmd_poll
    });
 
-   vg_convar_push( (struct vg_convar){
+   vg_var_push( (struct vg_var){
       .name = "controller_deadzone",
       .data = &g_controller_deadzone,
-      .data_type = k_convar_dtype_f32,
+      .data_type = k_var_dtype_f32,
       .opt_f32 = { .clamp = 0 },
       .persistent = 1
    });
index e71a0e7044093183c3e4f516d1524cc5f51b2856..12e8d969f6df17005a084fe101ee699a9e5092c9 100644 (file)
@@ -78,10 +78,10 @@ VG_STATIC void vg_lines_init(void)
 {
    vg_info( "vg_lines_init\n" );
 
-   vg_convar_push( (struct vg_convar){
+   vg_var_push( (struct vg_var){
       .name = "vg_lines",
       .data = &vg_lines.draw,
-      .data_type = k_convar_dtype_i32,
+      .data_type = k_var_dtype_i32,
       .opt_i32 = { .min=0, .max=1, .clamp=1 },
       .persistent = 1
    });
index 7be848aa3ee6937d930dc3f16fb7abd190594017..944a5bb2a02155e571b9e0b1781bf31e3bce7a7d 100644 (file)
@@ -136,10 +136,10 @@ VG_STATIC void vg_profile_drawn( struct vg_profile **profiles, u32 count,
 
 VG_STATIC void vg_profiler_init(void)
 {
-   vg_convar_push( (struct vg_convar){
+   vg_var_push( (struct vg_var){
       .name = "vg_profiler",
       .data = &vg_profiler,
-      .data_type = k_convar_dtype_i32,
+      .data_type = k_var_dtype_i32,
       .opt_i32 = { .min=0, .max=1, .clamp=1 },
       .persistent = 1
    });