From 7b1e8a237acc3121c86fab9b5946da6a8d3bf6c4 Mon Sep 17 00:00:00 2001 From: hgn Date: Thu, 8 Jun 2023 16:39:05 +0100 Subject: [PATCH] enable workshop world submissions --- addon.c | 33 +++++ addon.h | 4 +- ent_skateshop.c | 110 +++++++--------- maps_src/template/addon.inf | Bin 0 -> 81 bytes maps_src/template/preview.jpg | Bin 0 -> 44020 bytes skaterift.c | 5 +- skaterift.h | 3 +- workshop.c | 228 ++++++++++++++++++---------------- world_load.c | 42 ++++--- world_load.h | 8 +- world_routes.c | 45 ++++--- 11 files changed, 270 insertions(+), 208 deletions(-) create mode 100644 maps_src/template/addon.inf create mode 100644 maps_src/template/preview.jpg diff --git a/addon.c b/addon.c index 29b24a0..504904f 100644 --- a/addon.c +++ b/addon.c @@ -4,6 +4,8 @@ #include "addon.h" #include "vg/vg_msg.h" #include "steam.h" +#include "workshop_types.h" +#include "workshop.h" static u32 addon_count( enum workshop_file_type type ){ return addon_system.registry_type_counts[ type ]; @@ -347,4 +349,35 @@ VG_STATIC void addon_mount_content_folder( enum workshop_file_type type, vg_dir_close(&dir); } +static int addon_get_content_folder( addon_reg *reg, vg_str *folder ){ + if( reg->workshop_id ){ + vg_async_item *call = + vg_async_alloc( sizeof(struct async_workshop_filepath_info) ); + struct async_workshop_filepath_info *info = call->payload; + info->buf = folder->buffer; + info->id = reg->workshop_id; + info->len = folder->len; + vg_async_dispatch( call, async_workshop_get_filepath ); + vg_async_stall(); /* too bad! */ + if( info->buf[0] == '\0' ){ + vg_error( "Failed SteamAPI_GetItemInstallInfo(" PRINTF_U64 ")\n", + reg->workshop_id ); + return 0; + } + folder->i = strlen( folder->buffer ); + return 1; + } + else{ + folder->i = 0; + if( reg->type == k_workshop_file_type_board ) + vg_strcat( folder, "boards/" ); + else if( reg->type == k_workshop_file_type_world ) + vg_strcat( folder, "maps/" ); + else return 0; + + vg_strcat( folder, reg->foldername ); + return 1; + } +} + #endif /* ADDON_C */ diff --git a/addon.h b/addon.h index 65e88e1..f1d466e 100644 --- a/addon.h +++ b/addon.h @@ -1,7 +1,8 @@ #ifndef ADDON_H #define ADDON_H -#include "workshop.h" +#include "common.h" +#include "vg/vg_steam_ugc.h" #include "workshop_types.h" #define ADDON_MOUNTED_MAX 128 #define ADDON_FOLDERNAME_MAX 64 @@ -38,6 +39,7 @@ static void addon_system_init( void ); static u32 addon_count( enum workshop_file_type type ); static addon_reg *get_addon_from_index(enum workshop_file_type type, u32 index); static u32 get_index_from_addon( enum workshop_file_type type, addon_reg *a ); +static int addon_get_content_folder( addon_reg *reg, vg_str *folder ); /* scanning routines */ VG_STATIC void addon_mount_content_folder( enum workshop_file_type type, diff --git a/ent_skateshop.c b/ent_skateshop.c index 08d32e8..7898f58 100644 --- a/ent_skateshop.c +++ b/ent_skateshop.c @@ -130,7 +130,6 @@ VG_STATIC void workshop_visibile_load_loop(void) { vg_info( "Running load loop\n" ); char path_buf[4096]; - vg_str folder; for( u32 i=0; ireg_ptr = get_addon_from_index( k_workshop_file_type_board, cache_ptr->reg_index ); - if( cache_ptr->reg_ptr->workshop_id ){ - vg_async_item *call = - vg_async_alloc( sizeof(struct async_workshop_filepath_info) ); - - struct async_workshop_filepath_info *info = call->payload; - info->buf = path_buf; - info->id = cache_ptr->reg_ptr->workshop_id; - info->len = vg_list_size(path_buf); - vg_async_dispatch( call, async_workshop_get_filepath ); - vg_async_stall(); /* too bad! */ - - if( path_buf[0] == '\0' ){ - vg_error( "Failed SteamAPI_GetItemInstallInfo(" PRINTF_U64 ")\n", - cache_ptr->reg_ptr->workshop_id ); - goto file_is_broken; - } + vg_str folder; + vg_strnull( &folder, path_buf, 4096 ); + if( !addon_get_content_folder( cache_ptr->reg_ptr, &folder ) ) + goto file_is_broken; - folder.buffer = path_buf; - folder.i = strlen(path_buf); - folder.len = 4096; - } - else{ - vg_strnull( &folder, path_buf, 4096 ); - vg_strcat( &folder, "boards/" ); - vg_strcat( &folder, cache_ptr->reg_ptr->foldername ); - } /* load content files * --------------------------------- */ @@ -336,45 +313,38 @@ VG_STATIC void pointcloud_clear_async(void *_, u32 __) VG_STATIC void skateshop_preview_loader_thread( void *_data ) { addon_reg *reg = _data; + + char path_buf[4096]; + vg_str path; + vg_strnull( &path, path_buf, 4096 ); + addon_get_content_folder( reg, &path ); + vg_strcat( &path, "/preview.bin" ); + + vg_linear_clear(vg_mem.scratch); + u32 size; - if( reg->workshop_id ){ - vg_error( "Workshop files unsupported\n" ); - vg_async_call( pointcloud_clear_async, NULL, 0 ); - } - else{ - char path_buf[4096]; - vg_str path; - vg_strnull( &path, path_buf, 4096 ); - vg_strcat( &path, "maps/" ); - vg_strcat( &path, reg->foldername ); - vg_strcat( &path, "/preview.bin" ); - - vg_linear_clear(vg_mem.scratch); - u32 size; - - void *data = vg_file_read( vg_mem.scratch, path_buf, &size ); - if( data ){ - if( size < sizeof(pointcloud_buffer) ){ - vg_async_call( pointcloud_clear_async, NULL, 0 ); - return; - } - - vg_async_item *call = vg_async_alloc(size); - pointcloud_buffer *pcbuf = call->payload; - memcpy( pcbuf, data, size ); - - u32 point_count = (size-sizeof(pointcloud_buffer)) / - sizeof(struct pointcloud_vert); - pcbuf->max = point_count; - pcbuf->count = point_count; - pcbuf->op = k_pointcloud_op_clear; - - vg_async_dispatch( call, async_pointcloud_sub ); - vg_async_call( pointcloud_async_end, NULL, 0 ); - } - else{ + void *data = vg_file_read( vg_mem.scratch, path_buf, &size ); + if( data ){ + if( size < sizeof(pointcloud_buffer) ){ vg_async_call( pointcloud_clear_async, NULL, 0 ); + return; } + + vg_async_item *call = vg_async_alloc(size); + pointcloud_buffer *pcbuf = call->payload; + memcpy( pcbuf, data, size ); + + u32 point_count = (size-sizeof(pointcloud_buffer)) / + sizeof(struct pointcloud_vert); + pcbuf->max = point_count; + pcbuf->count = point_count; + pcbuf->op = k_pointcloud_op_clear; + + vg_async_dispatch( call, async_pointcloud_sub ); + vg_async_call( pointcloud_async_end, NULL, 0 ); + } + else{ + vg_async_call( pointcloud_clear_async, NULL, 0 ); } } @@ -564,7 +534,9 @@ VG_STATIC void global_skateshop_preupdate(void) if( loadable && button_down( k_srbind_maccept ) ){ vg_info( "Select rift (%u)\n", global_skateshop.selected_world_id ); - skaterift_change_world( reg->foldername ); + world_loader.reg = reg; + world_loader.override_name[0] = '\0'; + skaterift_change_world_start(); return; } else{ @@ -711,6 +683,8 @@ fade_out:; } if( global_skateshop.render.reg_id != global_skateshop.selected_board_id ){ + global_skateshop.render.item_title = ""; + global_skateshop.render.item_desc = ""; addon_reg *reg = cache_ptr->reg_ptr; vg_msg root; vg_msg_init( &root, reg->metadata, reg->metadata_len ); @@ -771,6 +745,8 @@ VG_STATIC void skateshop_render_worldshop(void) mdl_entity_id_id(shop->boards.id_info)); if( global_skateshop.render.world_reg != global_skateshop.selected_world_id){ + global_skateshop.render.world_title = ""; + addon_reg *reg = get_addon_from_index( k_workshop_file_type_world, global_skateshop.selected_world_id ); vg_msg root; @@ -808,6 +784,12 @@ VG_STATIC void skateshop_render_worldshop(void) vg_strcat( &subtext, "Loading..." ); } else{ + addon_reg *reg = get_addon_from_index( k_workshop_file_type_world, + global_skateshop.selected_world_id ); + + if( reg->workshop_id ) + vg_strcat( &subtext, "(Workshop) " ); + vg_strcat( &subtext, global_skateshop.render.world_loc ); } } diff --git a/maps_src/template/addon.inf b/maps_src/template/addon.inf new file mode 100644 index 0000000000000000000000000000000000000000..b71b46640132ee4121b7d28c783a9a9a153431af GIT binary patch literal 81 zcmXZS!3}^Q5Cp)LFHKN^Rak-z5IH09;4ZLJuh=aR;pl^=9(#~Wlxkz bYL?5D)8=PPAP6+KS=>L(Li~ literal 0 HcmV?d00001 diff --git a/maps_src/template/preview.jpg b/maps_src/template/preview.jpg new file mode 100644 index 0000000000000000000000000000000000000000..63b72e48a1228fcf2fa5036d4d18c7f568ba689d GIT binary patch literal 44020 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

2xSO6M8 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 ) ){ + workshop_form.ptr_ent = + mdl_arritm( &workshop_form.view_world->ent_swspreview, 0 ); + } + else{ + vg_error( "There is no ent_swspreview in the level. " + "Cannot publish here\n" ); return; } @@ -683,7 +695,7 @@ VG_STATIC void workshop_op_download_and_view_submission( int result_index ) vg_msg root; vg_msg_init( &root, metadata_buf, len/2 ); - vg_msg workshop; + vg_msg workshop = root; if( vg_msg_seekframe( &workshop, "workshop", k_vg_msg_first )){ vg_msg_cmd kv_type = vg_msg_seekkv( &workshop, "type", k_vg_msg_first ); @@ -900,26 +912,24 @@ VG_STATIC void workshop_init(void) vg_console_reg_cmd( "workshop_submit", workshop_submit_command, NULL ); } -VG_STATIC void workshop_find_preview_entity(void) -{ - workshop_form.view_world = world_current_instance(); +VG_STATIC void workshop_render_world_preview(void){ + render_fb_bind( gpipeline.fb_workshop_preview, 0 ); - if( mdl_arrcount( &workshop_form.view_world->ent_swspreview ) ){ - workshop_form.ptr_ent = - mdl_arritm( &workshop_form.view_world->ent_swspreview, 0 ); - workshop_form.page = k_workshop_form_edit; - } - else{ - vg_error( "There is no ent_swspreview in the level. " - "Cannot publish here\n" ); - } + glClearColor( 0.0f, 0.0f, 0.3f, 1.0f ); + glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); + glEnable( GL_DEPTH_TEST ); + glDisable( GL_BLEND ); + + render_world( localplayer.viewable_world, &main_camera, 1 ); + + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); + glViewport( 0,0, vg.window_x, vg.window_y ); } /* * Redraw the model file into the workshop framebuffer */ -VG_STATIC void workshop_render_preview(void) -{ +VG_STATIC void workshop_render_board_preview(void){ if( !workshop_form.ptr_ent ){ return; } @@ -1024,88 +1034,65 @@ VG_STATIC void workshop_changed_description( char *buf, u32 len ){ workshop_form.submission.submit_description = 1; } -VG_STATIC void workshop_form_gui_edit_page( ui_rect content ) -{ - if( workshop_form.submission.type == k_workshop_file_type_none ){ - ui_rect box; - rect_copy( content, box ); - box[3] = 128; - box[2] = (box[2]*2)/3; - ui_rect_center( content, box ); - - ui_rect row; - ui_split( box, k_ui_axis_h, 28, 0, row, box ); - ui_text( row, "Select the type of item\n", 1, k_ui_align_middle_center,0); - ui_split( box, k_ui_axis_h, 28, 0, row, box ); - ui_enum( row, "Type:", workshop_form_type_opts, - 3, &workshop_form.submission.submission_type_selection ); - ui_split( box, k_ui_axis_h, 8, 0, row, box ); - ui_split( box, k_ui_axis_h, 28, 0, row, box ); - - ui_rect button_l, button_r; - rect_copy( row, button_l ); - button_l[2] = 128*2; - ui_rect_center( row, button_l ); - ui_split_ratio( button_l, k_ui_axis_v, 0.5f, 2, button_l, button_r ); - - if( workshop_form.submission.submission_type_selection.value != - k_workshop_file_type_none ){ - if( ui_button_text( button_l, "OK", 1 ) ){ - workshop_form.submission.type = +VG_STATIC void workshop_form_gui_page_undecided( ui_rect content ){ + ui_rect box; + rect_copy( content, box ); + box[3] = 128; + box[2] = (box[2]*2)/3; + ui_rect_center( content, box ); + + ui_rect row; + ui_split( box, k_ui_axis_h, 28, 0, row, box ); + ui_text( row, "Select the type of item\n", 1, k_ui_align_middle_center,0); + ui_split( box, k_ui_axis_h, 28, 0, row, box ); + ui_enum( row, "Type:", workshop_form_type_opts, + 3, &workshop_form.submission.submission_type_selection ); + ui_split( box, k_ui_axis_h, 8, 0, row, box ); + ui_split( box, k_ui_axis_h, 28, 0, row, box ); + + ui_rect button_l, button_r; + rect_copy( row, button_l ); + button_l[2] = 128*2; + ui_rect_center( row, button_l ); + ui_split_ratio( button_l, k_ui_axis_v, 0.5f, 2, button_l, button_r ); + + if( workshop_form.submission.submission_type_selection.value != + k_workshop_file_type_none ){ + if( ui_button_text( button_l, "OK", 1 ) ){ + enum workshop_file_type type = workshop_form.submission.submission_type_selection.value; + workshop_form.submission.type = type; + + if( type == k_workshop_file_type_world ){ + workshop_form.view_changed = 1; + workshop_form.file_intent = k_workshop_form_file_intent_new; } } - else{ - ui_fill( button_l, ui_colour(k_ui_bg) ); - ui_text( button_l, "OK", 1, k_ui_align_middle_center, - ui_colour(k_ui_bg+4) ); - } - - if( ui_button_text( button_r, "Cancel", 1 ) ){ - workshop_form.page = k_workshop_form_open; - workshop_form.file_intent = k_workshop_form_file_intent_none; - } - return; } - - if( workshop_form.submission.type == k_workshop_file_type_world ){ - ui_rect box; - rect_copy( content, box ); - box[3] = 128; - box[2] = (box[2]*2)/3; - ui_rect_center( content, box ); - - ui_rect row; - ui_split( box, k_ui_axis_h, 28, 0, row, box ); - ui_text( row, "World submissions are currently not ready, sorry.", - 1, k_ui_align_middle_center,0); - ui_split( box, k_ui_axis_h, 8, 0, row, box ); - ui_split( box, k_ui_axis_h, 28, 0, row, box ); - - ui_rect button; - rect_copy( row, button ); - button[2] = 128; - ui_rect_center( row, button ); - if( ui_button_text( button, "OK", 1 ) ){ - workshop_form.page = k_workshop_form_open; - workshop_form.file_intent = k_workshop_form_file_intent_none; - } - - return; + else{ + ui_fill( button_l, ui_colour(k_ui_bg) ); + ui_text( button_l, "OK", 1, k_ui_align_middle_center, + ui_colour(k_ui_bg+4) ); } + + if( ui_button_text( button_r, "Cancel", 1 ) ){ + workshop_form.page = k_workshop_form_open; + workshop_form.file_intent = k_workshop_form_file_intent_none; + } +} - ui_rect image_plane; - ui_split( content, k_ui_axis_h, 300, 0, image_plane, content ); - ui_fill( image_plane, ui_colour( k_ui_bg+0 ) ); - - ui_rect img_box; - ui_fit_item( image_plane, (ui_px[2]){ 3, 2 }, img_box ); - +VG_STATIC void workshop_form_gui_draw_preview( ui_rect img_box ){ + enum workshop_file_type type = workshop_form.submission.type; if( workshop_form.file_intent == k_workshop_form_file_intent_keep_old ){ ui_image( img_box, gpipeline.fb_workshop_preview->attachments[0].id ); } else if( workshop_form.file_intent == k_workshop_form_file_intent_new ){ ui_image( img_box, gpipeline.fb_workshop_preview->attachments[0].id ); + + if( type == k_workshop_file_type_world ){ + return; + } + int hover = ui_inside_rect( img_box, vg_ui.mouse ), target = ui_inside_rect( img_box, vg_ui.mouse_click ); @@ -1159,12 +1146,28 @@ VG_STATIC void workshop_form_gui_edit_page( ui_rect content ) ui_text( img_box, "No image", 1, k_ui_align_middle_center, ui_colour( k_ui_orange ) ); } +} + +VG_STATIC void workshop_form_gui_edit_page( ui_rect content ){ + enum workshop_file_type type = workshop_form.submission.type; + + if( type == k_workshop_file_type_none ){ + workshop_form_gui_page_undecided( content ); + return; + } + + ui_rect image_plane; + ui_split( content, k_ui_axis_h, 300, 0, image_plane, content ); + ui_fill( image_plane, ui_colour( k_ui_bg+0 ) ); + + ui_rect img_box; + ui_fit_item( image_plane, (ui_px[2]){ 3, 2 }, img_box ); + workshop_form_gui_draw_preview( img_box ); /* file path */ ui_rect null, file_entry, file_button, file_label; ui_split( content, k_ui_axis_h, 8, 0, null, content ); ui_split( content, k_ui_axis_h, 28, 0, file_entry, content ); - ui_split( file_entry, k_ui_axis_v, -128, 0, file_entry, file_button ); if( workshop_form.submission.type == k_workshop_file_type_board ){ ui_label( file_entry, "Addon folder: skaterift/boards/", @@ -1175,27 +1178,36 @@ VG_STATIC void workshop_form_gui_edit_page( ui_rect content ) 1, 8, file_entry ); } - if( workshop_form.file_intent != k_workshop_form_file_intent_none ){ - ui_text( file_entry, workshop_form.addon_folder, 1, - k_ui_align_middle_left, ui_colour( k_ui_fg+4 ) ); - - if( ui_button_text( file_button, "Remove", 1 ) ){ - player_board_unload( &workshop_form.board_model ); - workshop_form.file_intent = k_workshop_form_file_intent_none; - workshop_form.addon_folder[0] = '\0'; - } - } - else{ + if( type == k_workshop_file_type_world ){ struct ui_textbox_callbacks callbacks = { .change = workshop_changed_model_path }; - ui_textbox( file_entry, workshop_form.addon_folder, vg_list_size(workshop_form.addon_folder), 0, &callbacks ); + } + else{ + ui_split( file_entry, k_ui_axis_v, -128, 0, file_entry, file_button ); + if( workshop_form.file_intent != k_workshop_form_file_intent_none ){ + ui_text( file_entry, workshop_form.addon_folder, 1, + k_ui_align_middle_left, ui_colour( k_ui_fg+4 ) ); + + if( ui_button_text( file_button, "Remove", 1 ) ){ + player_board_unload( &workshop_form.board_model ); + workshop_form.file_intent = k_workshop_form_file_intent_none; + workshop_form.addon_folder[0] = '\0'; + } + } + else{ + struct ui_textbox_callbacks callbacks = { + .change = workshop_changed_model_path + }; + + ui_textbox( file_entry, workshop_form.addon_folder, + vg_list_size(workshop_form.addon_folder), 0, &callbacks ); - if( ui_button_text( file_button, "Load", 1 ) ){ - workshop_find_preview_entity(); - workshop_op_load_model(); + if( ui_button_text( file_button, "Load", 1 ) ){ + workshop_op_load_model(); + } } } @@ -1369,7 +1381,6 @@ VG_STATIC void workshop_form_gui_sidebar( ui_rect sidebar ) workshop_form.submission.submit_description = 1; workshop_form.submission.submit_file_and_image = 1; workshop_form.page = k_workshop_form_edit; - workshop_find_preview_entity(); } for( int i=0; ifoldername, world_loader.reg->workshop_id ); + } + else{ + vg_info( "switching to %s(local)\n", world_loader.override_name ); + } if( world_static.active_world != 0 ){ vg_error( "Cannot change worlds while in non-root world\n" ); @@ -228,10 +234,7 @@ static void skaterift_change_world( const char *world_name ) else{ skaterift_begin_op( k_async_op_world_preloading ); - vg_linear_clear( vg_mem.scratch ); - vg_strncpy( world_name, world_loader.name, - vg_list_size(world_loader.name), k_strncpy_overflow_fatal ); - + vg_linear_clear( vg_mem.scratch ); /* ?? */ vg_info( "unloading old worlds\n" ); world_unlink_nonlocal( &world_static.worlds[0] ); @@ -249,8 +252,13 @@ static void skaterift_change_world( const char *world_name ) /* console command for the above function */ static int skaterift_change_world_command( int argc, const char *argv[] ) { - if( argc == 1 ) - skaterift_change_world( argv[0] ); + if( argc == 1 ){ + world_loader.reg = NULL; + vg_strncpy( argv[0], world_loader.override_name, + vg_list_size( world_loader.override_name ), + k_strncpy_always_add_null ); + skaterift_change_world_start(); + } return 0; } diff --git a/world_load.h b/world_load.h index 0b8a912..b37bae3 100644 --- a/world_load.h +++ b/world_load.h @@ -8,15 +8,21 @@ #include "world_routes.h" #include "world_entity.h" #include "world_volumes.h" +#include "addon.h" struct{ - char name[64]; + addon_reg *reg; +#if 0 enum world_load_type{ + k_world_load_type_none, k_world_load_type_local, k_world_load_type_workshop /* unimplemented */ } location; +#endif + + char override_name[64]; int generate_point_cloud; u32 world_index; } diff --git a/world_routes.c b/world_routes.c index 1ff33fe..56e6e4b 100644 --- a/world_routes.c +++ b/world_routes.c @@ -767,6 +767,33 @@ VG_STATIC void world_routes_surface_grid( world_instance *world, } } +VG_STATIC void world_write_preview( pointcloud_buffer *pcbuf ){ + char path_buf[4096]; + vg_str path; + vg_strnull( &path, path_buf, 4096 ); + + if( world_loader.reg ){ + /* Don't want to override the one we get from the workshop */ + if( world_loader.reg->workshop_id ) return; + + addon_get_content_folder( world_loader.reg, &path ); + } + else{ + vg_strcat( &path, "maps/" ); + vg_strcat( &path, world_loader.override_name ); + } + + vg_strcat( &path, "/preview.bin" ); + + if( !vg_strgood( &path ) ) vg_fatal_error( "Path too long\n" ); + FILE *fp = fopen( path_buf, "wb" ); + if( !fp ) vg_fatal_error( "Cannot open '%s' for writing\n", path_buf ); + + fwrite( pcbuf, sizeof(struct pointcloud_buffer) + + sizeof(struct pointcloud_vert)*pcbuf->count, 1, fp ); + fclose( fp ); +} + /* * Create the strips of colour that run through the world along course paths */ @@ -861,23 +888,7 @@ VG_STATIC void world_gen_routes_generate(void) vg_info( "Distrubuted %u points over %fkm^2!\n", pcbuf->count, area/1e6f ); - if( world_loader.location == k_world_load_type_local ){ - char path_buf[4096]; - vg_str path; - vg_strnull( &path, path_buf, 4096 ); - vg_strcat( &path, "maps/" ); - vg_strcat( &path, world_loader.name ); - vg_strcat( &path, "/preview.bin" ); - - if( !vg_strgood( &path ) ) vg_fatal_error( "Path too long\n" ); - FILE *fp = fopen( path_buf, "wb" ); - if( !fp ) vg_fatal_error( "Cannot open '%s' for writing\n", path_buf ); - - fwrite( pcbuf, sizeof(pcbuf) + - sizeof(struct pointcloud_vert)*pcbuf->count, 1, fp ); - fclose( fp ); - } - + world_write_preview( pcbuf ); vg_async_dispatch( call_pointcloud, async_pointcloud_sub ); } -- 2.25.1