From bd0220bf8c44fc5d368e6edf4d0769bbcd5eba5d Mon Sep 17 00:00:00 2001 From: hgn Date: Wed, 24 May 2023 16:54:49 +0100 Subject: [PATCH] binary message system --- vg_imgui.h | 21 ++--- vg_msg.h | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++ vg_platform.h | 13 ++++ 3 files changed, 231 insertions(+), 9 deletions(-) create mode 100644 vg_msg.h diff --git a/vg_imgui.h b/vg_imgui.h index 58a2fd4..7de96f1 100644 --- a/vg_imgui.h +++ b/vg_imgui.h @@ -599,12 +599,6 @@ static void ui_split( ui_rect rect, } static ui_px ui_text_line_width( const char *str ); -static void ui_split_label( ui_rect rect, const char *text, ui_px size, - ui_px gap, ui_rect l, ui_rect r ) -{ - ui_px width = ui_text_line_width( text ) * size; - ui_split( rect, k_ui_axis_v, width, gap, l, r ); -} static void ui_rect_center( ui_rect parent, ui_rect rect ) { @@ -721,8 +715,8 @@ static int ui_inside_rect( ui_rect rect, ui_px co[2] ) { if( co[0] >= rect[0] && co[1] >= rect[1] && - co[0] <= rect[0]+rect[2] && - co[1] <= rect[1]+rect[3] ) + co[0] < rect[0]+rect[2] && + co[1] < rect[1]+rect[3] ) { return 1; } @@ -1199,7 +1193,7 @@ static void ui_enum_post(void) for( u32 i=0; iindex ) colour = k_ui_orange; @@ -1898,4 +1892,13 @@ VG_STATIC void ui_proc_utf8( const char *text ) } } +static void ui_label( ui_rect rect, const char *text, ui_px size, + ui_px gap, ui_rect r ) +{ + ui_rect l; + ui_px width = (ui_text_line_width( text )+1) * size; + ui_split( rect, k_ui_axis_v, width, gap, l, r ); + ui_text( l, text, 1, k_ui_align_middle_left, 0 ); +} + #endif /* VG_IMGUI_H */ diff --git a/vg_msg.h b/vg_msg.h new file mode 100644 index 0000000..cc38e85 --- /dev/null +++ b/vg_msg.h @@ -0,0 +1,206 @@ +#ifndef VG_MSG_H +#define VG_MSG_H +#include "vg_stdint.h" + +enum vg_msg_code{ + k_vg_msg_code_end = 0, + k_vg_msg_code_frame = 1, + k_vg_msg_code_endframe = 2, + k_vg_msg_code_kv = 10, + k_vg_msg_code_kvstring = 11, + k_vg_msg_code_kvbin = 12, + k_vg_msg_code_signed = 0x80, /* byte sizes stored in lower 4 bits */ + k_vg_msg_code_unsigned = 0x40, + k_vg_msg_code_float = 0x20 +}; + +typedef struct vg_msg vg_msg; +typedef struct vg_msg_cmd vg_msg_cmd; +struct vg_msg{ + u32 cur,max; + u8 *buf; + u32 depth; + + enum vg_msg_error{ + k_vg_msg_error_OK, + k_vg_msg_error_unbalanced, + k_vg_msg_error_overflow, + k_vg_msg_error_unhandled_cmd + } + error; +}; + +struct vg_msg_cmd{ + u8 code; + + const char *key; + u32 key_djb2; + + union{ const void *_buf; + u8 _u8; i8 _i8; + u16 _u16; i16 _i16; + u32 _u32; i32 _i32; f32 _f32; + u64 _u64; i64 _i64; f64 _f64; + } value; + u32 value_djb2; +}; + +static void vg_msg_init( vg_msg *msg, u8 *buf, u32 max ){ + msg->cur = 0; + msg->max = max; + msg->buf = buf; + msg->depth = 0; + msg->error = k_vg_msg_error_OK; +} + +static void vg_msg_exchbuf( vg_msg *msg, int write, u8 *buf, u32 len ){ + if( msg->error != k_vg_msg_error_OK ) return; + if( msg->cur+len > msg->max ){ + msg->error = k_vg_msg_error_overflow; + return; + } + for( u32 i=0; ibuf[ msg->cur ++ ] = buf[i]; + else buf[i] = msg->buf[ msg->cur ++ ]; + } +} + +static void vg_msg_wstr( vg_msg *msg, const char *str ){ + if( msg->error != k_vg_msg_error_OK ) return; + for( u32 i=0;; i++ ){ + vg_msg_exchbuf( msg, 1, (u8[]){ str[i] }, 1 ); + if( !str[i] ) break; + } +} + +static const char *vg_msg_rstr( vg_msg *msg, u32 *djb2 ){ + if( msg->error != k_vg_msg_error_OK ) return 0; + + u32 hash = 5381, c; + const char *str = (void *)(&msg->buf[ msg->cur ]); + + while( (c = msg->buf[ msg->cur ++ ]) ){ + if( msg->cur >= msg->max ){ + msg->error = k_vg_msg_error_overflow; + return 0; + } + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + } + + *djb2 = hash; + return str; +} + +static void vg_msg_frame( vg_msg *msg, const char *name ){ + if( msg->error != k_vg_msg_error_OK ) return; + + msg->depth ++; + vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_frame }, 1 ); + vg_msg_wstr( msg, name ); +} + +static void vg_msg_end_frame( vg_msg *msg ){ + if( msg->error != k_vg_msg_error_OK ) return; + if( !msg->depth ){ + msg->error = k_vg_msg_error_unbalanced; + return; + } + msg->depth --; + vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_endframe }, 1 ); +} + +static void vg_msg_wkvstr( vg_msg *msg, const char *key, const char *value ){ + vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_kvstring }, 1 ); + vg_msg_wstr( msg, key ); + vg_msg_wstr( msg, value ); +} + +static void vg_msg_wkvbin( vg_msg *msg, const char *key, u8 *bin, u32 len ){ + vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_kvbin }, 1 ); + vg_msg_wstr( msg, key ); + vg_msg_exchbuf( msg, 1, (u8 *)(&len), 4 ); + vg_msg_exchbuf( msg, 1, bin, len ); +} + +static void vg__msg_wkvgen( vg_msg *msg, const char *key, + u8 basecode, void *value, u32 size ){ + u8 code = basecode | size; + vg_msg_exchbuf( msg, 1, &code, 1 ); + vg_msg_wstr( msg, key ); + vg_msg_exchbuf( msg, 1, value, size ); +} + +#define vg_msg_wkvint( MSGPTR, KEY, DECL ){ \ + DECL; \ + vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_signed, &value, sizeof(value));\ + } +#define vg_msg_wkvuint( MSGPTR, KEY, DECL ){ \ + DECL; \ + vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_unsigned, &value, sizeof(value));\ + } +#define vg_msg_wkvfloat( MSGPTR, KEY, DECL ){ \ + DECL; \ + vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_float, &value, sizeof(value));\ + } + +static int vg_msg_next( vg_msg *msg, vg_msg_cmd *cmd ){ + vg_msg_exchbuf( msg, 0, &cmd->code, 1 ); + if( msg->error != k_vg_msg_error_OK ) return 0; + + if( cmd->code == k_vg_msg_code_frame ){ + cmd->key = vg_msg_rstr( msg, &cmd->key_djb2 ); + msg->depth ++; + } + else if( cmd->code == k_vg_msg_code_endframe ){ + if( !msg->depth ){ + msg->error = k_vg_msg_error_unbalanced; + return 0; + } + msg->depth --; + } + else if( cmd->code >= k_vg_msg_code_kv ){ + cmd->key = vg_msg_rstr( msg, &cmd->key_djb2 ); + cmd->value_djb2 = 0; + cmd->value._u64 = 0; + + if( cmd->code & (k_vg_msg_code_float|k_vg_msg_code_unsigned| + k_vg_msg_code_signed )){ + u8 len = cmd->code & 0xf; + vg_msg_exchbuf( msg, 0, (u8 *)(&cmd->value._u64), len ); + } + else if( cmd->code == k_vg_msg_code_kvstring ){ + cmd->value._buf = vg_msg_rstr( msg, &cmd->value_djb2 ); + } + else if( cmd->code == k_vg_msg_code_kvbin ){ + u32 len; + vg_msg_exchbuf( msg, 0, (u8 *)(&len), 4 ); + if( msg->error != k_vg_msg_error_OK ) return 0; + cmd->value._buf = &msg->buf[ msg->cur ]; + msg->cur += len; + if( msg->cur > msg->max ){ + msg->error = k_vg_msg_error_overflow; + } + } + else{ + msg->error = k_vg_msg_error_unhandled_cmd; + } + } + else{ + msg->error = k_vg_msg_error_unhandled_cmd; + } + + if( msg->error != k_vg_msg_error_OK ) return 0; + else return 1; +} + +static int vg_msg_skip_frame( vg_msg *msg ){ + vg_msg_cmd cmd; + + u32 depth = msg->depth-1; + while( vg_msg_next( msg, &cmd ) ){ + if( msg->depth == depth ) return 1; + } + return 0; +} + +#endif /* VG_MSG_H */ diff --git a/vg_platform.h b/vg_platform.h index b04ce67..1f38898 100644 --- a/vg_platform.h +++ b/vg_platform.h @@ -129,6 +129,19 @@ VG_STATIC u32 vg_strdjb2( const char *str ) return hash; } +VG_STATIC int vg_strdjb2_eq( const char *s1, u32 h1, + const char *s2, u32 h2 ) +{ + if( h1 == h2 ){ + if(!strcmp(s1, s2)) return 1; + else return 0; + } else return 0; +} + +#define VG_STRDJB2_EQ( CS1, S2, H2 ) \ + vg_strdjb2_eq( CS1, vg_strdjb2(CS1), S2, H2 ) + + #define VG_MIN( A, B ) ((A)<(B)?(A):(B)) #define VG_MAX( A, B ) ((A)>(B)?(A):(B)) #endif -- 2.25.1