Fix major overstep with last commit
[vg.git] / src / vg / vg_console.h
index 6ef2d7837774fc01f29331915e0a148e46fbd6a2..fc2775ca49115efeb343b8207f5e70ba2e1ed592 100644 (file)
@@ -6,7 +6,6 @@
 #include "vg/vg_ui.h"
 #include "vg/vg_log.h"
 
-
 struct vg_console
 {
        struct vg_convar
@@ -49,6 +48,9 @@ struct vg_console
                const char *name;
        }
        *functions;
+
+   u32 convar_count, convar_cap,
+       function_count, function_cap;
        
        char input[96];
        int cursor_user, cursor_pos, string_length;
@@ -99,12 +101,24 @@ static int vg_console_enabled(void)
 
 static void vg_convar_push( struct vg_convar cv )
 {
-       arrpush( vg_console.convars, cv ); 
+   vg_info( "Console variable '%s' registered\n", cv.name );
+   vg_console.convars = buffer_reserve( vg_console.convars, 
+                                        vg_console.convar_count,
+                                        &vg_console.convar_cap, 1,
+                                        sizeof( struct vg_convar ) );
+
+   vg_console.convars[ vg_console.convar_count ++ ] = cv;
 }
 
 static void vg_function_push( struct vg_cmd cmd )
 {
-       arrpush( vg_console.functions, cmd );
+   vg_info( "Console command '%s' registered\n", cmd.name );
+   vg_console.functions = buffer_reserve( vg_console.functions,
+                                          vg_console.function_count,
+                                          &vg_console.function_cap, 1,
+                                          sizeof( struct vg_cmd ) );
+
+   vg_console.functions[ vg_console.function_count ++ ] = cmd;
 }
 
 static void vg_console_draw( void )
@@ -170,7 +184,7 @@ static void vg_console_draw( void )
 
 static int vg_console_list( int argc, char const *argv[] )
 {
-       for( int i = 0; i < arrlen( vg_console.functions ); i ++ )
+       for( int i=0; i<vg_console.function_count; i ++ )
        {
                struct vg_cmd *cmd = &vg_console.functions[ i ];
                vg_info( "* %s\n", cmd->name );
@@ -178,7 +192,7 @@ static int vg_console_list( int argc, char const *argv[] )
        
        vg_info( "* snowsound\n" );
        
-       for( int i = 0; i < arrlen( vg_console.convars ); i ++ )
+       for( int i=0; i<vg_console.convar_count; i ++ )
        {
                struct vg_convar *cv = &vg_console.convars[ i ];
                vg_info( "%s\n", cv->name );
@@ -203,6 +217,12 @@ vg_info("            '        ' '--' [] '----- '----- '     ' '---'  "
    return 0;
 }
 
+static int _test_break( int argc, const char *argv[] )
+{
+   vg_fatal_exit_loop( "Test crash from main, after loading (console)" );
+   return 0;
+}
+
 static void vg_console_init(void)
 {
        vg_convar_push( (struct vg_convar)
@@ -224,6 +244,12 @@ static void vg_console_init(void)
       .name = "chartest",
       .function = vg_console_chartest
    });
+
+   vg_function_push( (struct vg_cmd)
+   {
+      .name = "crash",
+      .function = _test_break
+   });
 }
 
 static void vg_console_load_autos(void)
@@ -252,7 +278,7 @@ static void vg_console_write_persistent(void)
 {
        FILE *fp = fopen( "cfg/auto.conf", "w" );
        
-       for( int i = 0; i < arrlen( vg_console.convars ); i ++ )
+       for( int i=0; i<vg_console.convar_count; i ++ )
        {
                struct vg_convar *cv = &vg_console.convars[i];
 
@@ -280,8 +306,8 @@ static void vg_console_free(void)
 {
        vg_console_write_persistent();
 
-       arrfree( vg_console.convars );
-       arrfree( vg_console.functions );
+   vg_free( vg_console.convars );
+   vg_free( vg_console.functions );
 }
 
 static void execute_console_input( const char *cmd )
@@ -329,7 +355,7 @@ static void execute_console_input( const char *cmd )
        int data_int;
    float data_float;
        
-       for( int i = 0; i < arrlen( vg_console.convars ); i ++ )
+       for( int i=0; i<vg_console.convar_count; i ++ )
        {
                struct vg_convar *cv = &vg_console.convars[ i ];
                if( !strcmp( cv->name, args[0] ) )
@@ -383,7 +409,7 @@ static void execute_console_input( const char *cmd )
    /*
     * Find and excecute command
     */
-       for( int i = 0; i < arrlen( vg_console.functions ); i ++ )
+       for( int i=0; i<vg_console.function_count; i ++ )
        {
                struct vg_cmd *cmd = &vg_console.functions[ i ];
                if( !strcmp( cmd->name, args[0] ) )
@@ -511,166 +537,199 @@ static void console_history_get( char* buf, int entry_num )
        strcpy( buf, vg_console.history[ pick ] );
 }
 
+/* Receed secondary cursor */
+static void _console_left_select(void)
+{
+   console_move_cursor( &vg_console.cursor_user, NULL, -1, 0 );
+}
+
+/* Match and receed both cursors */
+static void _console_left(void)
+{
+   int cursor_diff = vg_console.cursor_pos - vg_console.cursor_user? 0: 1;
+
+   console_move_cursor( &vg_console.cursor_user, 
+                        &vg_console.cursor_pos, -cursor_diff, 1 );
+}
+
+static void _console_right_select(void)
+{
+   console_move_cursor( &vg_console.cursor_user, NULL, 1, 0 );
+}
+
+static void _console_right(void)
+{
+   int cursor_diff = vg_console.cursor_pos - vg_console.cursor_user? 0: 1;
+
+   console_move_cursor( &vg_console.cursor_user, 
+                        &vg_console.cursor_pos, +cursor_diff, 1 );
+}
+
+static void _console_down(void)
+{
+   vg_console.history_pos = VG_MAX( 0, vg_console.history_pos-1 );
+   console_history_get( vg_console.input, vg_console.history_pos );
+
+   console_move_cursor( &vg_console.cursor_user, 
+                        &vg_console.cursor_pos, 
+                        vg_list_size( vg_console.input ), 1 );
+}
+
+static void _console_up(void)
+{
+   vg_console.history_pos = VG_MAX
+   ( 
+      0, 
+      VG_MIN
+      (
+         vg_console.history_pos+1, 
+         VG_MIN
+         ( 
+            vg_list_size( vg_console.history ), 
+            vg_console.history_count - 1 
+         )
+      )
+   );
+   
+   console_history_get( vg_console.input, vg_console.history_pos );
+   console_move_cursor( &vg_console.cursor_user, 
+                        &vg_console.cursor_pos, 
+                        vg_list_size( vg_console.input ), 1);
+}
+
+static void _console_backspace(void)
+{
+   vg_console.cursor_user = console_delete_char( -1 );
+   vg_console.cursor_pos = vg_console.cursor_user;
+}
+
+static void _console_delete(void)
+{
+   vg_console.cursor_user = console_delete_char( 1 );
+   vg_console.cursor_pos = vg_console.cursor_user;
+}
+
+static void _console_home_select(void)
+{
+   console_move_cursor( &vg_console.cursor_user, NULL, -10000, 0 );
+}
+
+static void _console_home(void)
+{
+   console_move_cursor( &vg_console.cursor_user, 
+                        &vg_console.cursor_pos, -10000, 1 );
+}
+
+static void _console_end_select(void)
+{
+   console_move_cursor( &vg_console.cursor_user, NULL, 10000, 0 );
+}
+
+static void _console_end(void)
+{
+   console_move_cursor( &vg_console.cursor_user, 
+                        &vg_console.cursor_pos, 
+                        vg_list_size( vg_console.input ), 1 );
+}
+
+static void _console_select_all(void)
+{
+   console_move_cursor( &vg_console.cursor_user, NULL, 10000, 0);
+   console_move_cursor( &vg_console.cursor_pos, NULL, -10000, 0);
+}
+
+static void _console_cut(void)
+{
+   console_to_clipboard();
+   vg_console.cursor_user = console_delete_char(0);
+   vg_console.cursor_pos = vg_console.cursor_user;
+}
+
+static void _console_enter(void)
+{
+   if( !strlen( vg_console.input ) ) 
+      return;
+
+   vg_info( "%s\n", vg_console.input );
+
+   if( strcmp( vg_console.input, 
+            vg_console.history[ vg_console.history_last ]) )
+   {
+      vg_console.history_last = ( vg_console.history_last + 1) % 
+                                 vg_list_size(vg_console.history );
+      vg_console.history_count = 
+         VG_MIN( vg_list_size( vg_console.history ), 
+               vg_console.history_count + 1 );
+      strcpy( vg_console.history[ vg_console.history_last ], 
+              vg_console.input );
+   }
+
+   vg_console.history_pos = -1;
+   execute_console_input( vg_console.input );
+   console_move_cursor( &vg_console.cursor_user, 
+                        &vg_console.cursor_pos, -10000, 1 );
+   vg_console.input[0] = '\0';
+}
+
 static void console_proc_key( GLFWwindow* ptrW, int key, int scancode, 
-      int action, int mods )
+                              int action, int mods )
 {
-       if( action )
-       {
-               int cursor_diff = vg_console.cursor_pos - vg_console.cursor_user? 0: 1;
+       if( !action )
+      return;
                
-               if( key == GLFW_KEY_GRAVE_ACCENT )
-               {
-                       vg_console.enabled = !vg_console.enabled;
-                       return;
-               }
-               
-               if( !vg_console.enabled ) 
-                       return;
-               
-               if( key == GLFW_KEY_LEFT )
-               {
-                       if( mods & GLFW_MOD_SHIFT ) /* Receed secondary cursor */
-                       { 
-                               console_move_cursor( &vg_console.cursor_user, NULL, -1, 0 );
-                       } 
-                       else /* Match and receed both cursors */
-                       {
-                               console_move_cursor( &vg_console.cursor_user, 
-                  &vg_console.cursor_pos, -cursor_diff, 1 );
-                       }
-               }
-               else if( key == GLFW_KEY_RIGHT ) /* Advance secondary cursor */
-               {
-                       if( mods & GLFW_MOD_SHIFT )
-                       {
-                               console_move_cursor( &vg_console.cursor_user, NULL, 1, 0 );
-                       } 
-                       else /* Match and advance both cursors */
-                       {
-                               console_move_cursor( &vg_console.cursor_user, 
-                  &vg_console.cursor_pos, +cursor_diff, 1 );
-                       }
-               } 
-               else if( key == GLFW_KEY_DOWN )
-               {
-                       if( mods & GLFW_MOD_SHIFT ){} 
-                       else 
-                       {
-                               vg_console.history_pos = VG_MAX( 0, vg_console.history_pos-1 );
-                               console_history_get( vg_console.input, vg_console.history_pos );
-                               console_move_cursor( &vg_console.cursor_user, 
-                  &vg_console.cursor_pos, vg_list_size( vg_console.input ), 1 );
-                       }
-               } 
-               else if( key == GLFW_KEY_UP )
-               {
-                       if( mods & GLFW_MOD_SHIFT ){} 
-                       else 
-                       {
-                               vg_console.history_pos = VG_MAX
-                               ( 
-                                       0, 
-                                       VG_MIN
-                                       (
-                                               vg_console.history_pos+1, 
-                                               VG_MIN
-                                               ( 
-                                                       vg_list_size( vg_console.history ), 
-                                                       vg_console.history_count - 1 
-                                               )
-                                       )
-                               );
-                               
-                               console_history_get( vg_console.input, vg_console.history_pos );
-                               console_move_cursor( &vg_console.cursor_user, 
-                                 &vg_console.cursor_pos, 
-                                 vg_list_size( vg_console.input ), 1);
-                       }
-               } 
-               else if( key == GLFW_KEY_BACKSPACE ) /* Lookback delete */
-               {
-                       vg_console.cursor_user = console_delete_char( -1 );
-                       vg_console.cursor_pos = vg_console.cursor_user;
-               } 
-               else if( key == GLFW_KEY_DELETE ) /* Lookforward delete */
-               {
-                       vg_console.cursor_user = console_delete_char( 1 );
-                       vg_console.cursor_pos = vg_console.cursor_user;
-               } 
-               else if( key == GLFW_KEY_HOME ) /* Home key */
-               {
-                       if( mods & GLFW_MOD_SHIFT ) 
-                               console_move_cursor( &vg_console.cursor_user, NULL, -10000, 0 );
-                       else 
-                               console_move_cursor( &vg_console.cursor_user, 
-                                 &vg_console.cursor_pos, -10000, 1 );
-               } 
-               else if( key == GLFW_KEY_END ) /* End key */
-               {
-                       if( mods & GLFW_MOD_SHIFT ) 
-                               console_move_cursor( &vg_console.cursor_user, NULL, 10000, 0 );
-                       else 
-                               console_move_cursor( &vg_console.cursor_user, 
-                                 &vg_console.cursor_pos, 
-                                 vg_list_size( vg_console.input ), 1 );
-               }
-               else if( key == GLFW_KEY_A )
-               {
-                       if( mods & GLFW_MOD_CONTROL ) /* Select all */
-                       {
-                               console_move_cursor( &vg_console.cursor_user, NULL, 10000, 0);
-                               console_move_cursor( &vg_console.cursor_pos, NULL, -10000, 0);
-                       }
-               } 
-               else if( key == GLFW_KEY_C ) /* Copy */
-               {
-                       if( mods & GLFW_MOD_CONTROL )
-                       {
-                               console_to_clipboard();
-                       }
-               } 
-               else if( key == GLFW_KEY_X ) /* Cut */
-               {
-                       if( mods & GLFW_MOD_CONTROL )
-                       {
-                               console_to_clipboard();
-                               vg_console.cursor_user = console_delete_char(0);
-                               vg_console.cursor_pos = vg_console.cursor_user;
-                       }
-               } 
-               else if( key == GLFW_KEY_V ) /* Paste */
-               {
-                       if( mods & GLFW_MOD_CONTROL )
-                       {
-                               console_clipboard_paste();
-                       }
-               } 
-               else if( key == GLFW_KEY_ENTER )
-               {
-                       if( !strlen( vg_console.input ) ) 
-                               return;
-                       
-                       vg_info( "%s\n", vg_console.input );
-                       
-                       if( strcmp( vg_console.input, 
-                  vg_console.history[ vg_console.history_last ]) )
-                       {
-                               vg_console.history_last = ( vg_console.history_last + 1) % 
-                                       vg_list_size(vg_console.history );
-                               vg_console.history_count = 
-               VG_MIN( vg_list_size( vg_console.history ), 
-                     vg_console.history_count + 1 );
-                               strcpy( vg_console.history[ vg_console.history_last ], 
-                    vg_console.input );
-                       }
-                       
-                       vg_console.history_pos = -1;
-                       execute_console_input( vg_console.input );
-                       console_move_cursor( &vg_console.cursor_user, 
-                              &vg_console.cursor_pos, -10000, 1 );
-                       vg_console.input[0] = '\0';
-               }
-       }
+   /* Open / close console */
+   if( key == GLFW_KEY_GRAVE_ACCENT )
+      vg_console.enabled = !vg_console.enabled;
+   
+   if( !vg_console.enabled ) return;
+   
+   struct console_mapping
+   {
+      u32 mod, key;
+      void (*handler)(void);
+   }
+   mapping[] =
+   {
+      { 0,                 GLFW_KEY_LEFT,       _console_left              },
+      { GLFW_MOD_SHIFT,    GLFW_KEY_LEFT,       _console_left_select       },
+      { 0,                 GLFW_KEY_RIGHT,      _console_right             },
+      { GLFW_MOD_SHIFT,    GLFW_KEY_RIGHT,      _console_right_select      },
+      { 0,                 GLFW_KEY_DOWN,       _console_down              },
+      { 0,                 GLFW_KEY_UP,         _console_up                },
+      { 0,                 GLFW_KEY_BACKSPACE,  _console_backspace         },
+      { 0,                 GLFW_KEY_DELETE,     _console_delete            },
+      { 0,                 GLFW_KEY_HOME,       _console_home              },
+      { GLFW_MOD_SHIFT,    GLFW_KEY_HOME,       _console_home_select       },
+      { 0,                 GLFW_KEY_END,        _console_end               },
+      { GLFW_MOD_SHIFT,    GLFW_KEY_END,        _console_end_select        },
+      { GLFW_MOD_CONTROL,  GLFW_KEY_A,          _console_select_all        },
+      { GLFW_MOD_CONTROL,  GLFW_KEY_C,          console_to_clipboard       },
+      { GLFW_MOD_CONTROL,  GLFW_KEY_X,          _console_cut               },
+      { GLFW_MOD_CONTROL,  GLFW_KEY_V,          console_clipboard_paste    },
+      { 0,                 GLFW_KEY_ENTER,      _console_enter             }
+   };
+
+   for( int i=0; i<vg_list_size( mapping ); i++ )
+   {
+      struct console_mapping *mk = &mapping[i];
+
+      if( mk->key == key )
+      {
+         if( mk->mod == 0 )
+         {
+            if( mods == 0 )
+            {
+               mk->handler();
+               return;
+            }
+         }
+         else if( (mods & mk->mod) == mk->mod )
+         {
+            mk->handler();
+            return;
+         }
+      }
+   }
 }
 
 /* Handle an OS based input of UTF32 character from the keyboard or such */