From b5e3812014fe13c8f63cb1ff499f1c2463d3343a Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 10 Nov 2019 14:56:03 -0800 Subject: [PATCH] HMS demo mostly ready --- custom/4coder_base_commands.cpp | 10 +- custom/4coder_default_hooks.cpp | 6 +- custom/4coder_draw.cpp | 5 +- custom/4coder_lister_base.cpp | 3 +- custom/4coder_lists.cpp | 4 +- custom/4coder_search.cpp | 5 +- custom/4coder_tutorial.cpp | 198 +++++++++++++++++++++++++++- custom/generated/command_metadata.h | 8 +- 8 files changed, 213 insertions(+), 26 deletions(-) diff --git a/custom/4coder_base_commands.cpp b/custom/4coder_base_commands.cpp index 17b3dc89..d2f0f5b4 100644 --- a/custom/4coder_base_commands.cpp +++ b/custom/4coder_base_commands.cpp @@ -6,7 +6,7 @@ moving the cursor, which work even without the default 4coder framework. // TOP function void -write_character_parameter(Application_Links *app, String_Const_u8 insert){ +write_text(Application_Links *app, String_Const_u8 insert){ ProfileScope(app, "write character"); if (insert.str != 0 && insert.size > 0){ View_ID view = get_active_view(app, Access_ReadWriteVisible); @@ -57,23 +57,23 @@ write_character_parameter(Application_Links *app, String_Const_u8 insert){ } CUSTOM_COMMAND_SIG(write_text_input) -CUSTOM_DOC("Inserts whatever character was used to trigger this command.") +CUSTOM_DOC("Inserts whatever text was used to trigger this command.") { User_Input in = get_current_input(app); String_Const_u8 insert = to_writable(&in); - write_character_parameter(app, insert); + write_text(app, insert); } CUSTOM_COMMAND_SIG(write_space) CUSTOM_DOC("Inserts an underscore.") { - write_character_parameter(app, string_u8_litexpr(" ")); + write_text(app, string_u8_litexpr(" ")); } CUSTOM_COMMAND_SIG(write_underscore) CUSTOM_DOC("Inserts an underscore.") { - write_character_parameter(app, string_u8_litexpr("_")); + write_text(app, string_u8_litexpr("_")); } CUSTOM_COMMAND_SIG(delete_char) diff --git a/custom/4coder_default_hooks.cpp b/custom/4coder_default_hooks.cpp index 51475a6d..c6587eb3 100644 --- a/custom/4coder_default_hooks.cpp +++ b/custom/4coder_default_hooks.cpp @@ -357,7 +357,7 @@ default_render_buffer(Application_Links *app, View_ID view_id, Face_ID face_id, // NOTE(allen): Token colorizing Token_Array token_array = get_token_array_from_buffer(app, buffer); if (token_array.tokens != 0){ - draw_buffer_add_cpp_token_colors(app, text_layout_id, &token_array); + draw_cpp_token_colors(app, text_layout_id, &token_array); // NOTE(allen): Scan for TODOs and NOTEs if (global_config.use_comment_keyword){ @@ -518,9 +518,7 @@ default_render_caller(Application_Links *app, Frame_Info frame_info, View_ID vie } // NOTE(allen): draw the buffer - default_render_buffer(app, view_id, face_id, - buffer, text_layout_id, - region); + default_render_buffer(app, view_id, face_id, buffer, text_layout_id, region); text_layout_free(app, text_layout_id); draw_set_clip(app, prev_clip); diff --git a/custom/4coder_draw.cpp b/custom/4coder_draw.cpp index f37de6a5..ed0348ab 100644 --- a/custom/4coder_draw.cpp +++ b/custom/4coder_draw.cpp @@ -261,8 +261,7 @@ draw_query_bar(Application_Links *app, Query_Bar *query_bar, Face_ID face_id, Re } function void -draw_line_number_margin(Application_Links *app, View_ID view_id, Buffer_ID buffer, Face_ID face_id, - Text_Layout_ID text_layout_id, Rect_f32 margin){ +draw_line_number_margin(Application_Links *app, View_ID view_id, Buffer_ID buffer, Face_ID face_id, Text_Layout_ID text_layout_id, Rect_f32 margin){ Rect_f32 prev_clip = draw_set_clip(app, margin); draw_rectangle(app, margin, 0.f, fcolor_id(Stag_Line_Numbers_Back)); @@ -407,7 +406,7 @@ get_token_color_cpp(Token token){ } function void -draw_buffer_add_cpp_token_colors(Application_Links *app, Text_Layout_ID text_layout_id, Token_Array *array){ +draw_cpp_token_colors(Application_Links *app, Text_Layout_ID text_layout_id, Token_Array *array){ Interval_i64 visible_range = text_layout_get_visible_range(app, text_layout_id); i64 first_index = token_index_from_pos(array, visible_range.first); Token_Iterator_Array it = token_iterator_index(0, array, first_index); diff --git a/custom/4coder_lister_base.cpp b/custom/4coder_lister_base.cpp index 2faebeff..4b492c10 100644 --- a/custom/4coder_lister_base.cpp +++ b/custom/4coder_lister_base.cpp @@ -459,8 +459,7 @@ run_lister(Application_Links *app, Lister *lister){ View_Context_Block ctx_block(app, view, &ctx); for (;;){ - User_Input in = get_next_input(app, EventPropertyGroup_Any, - EventProperty_Escape); + User_Input in = get_next_input(app, EventPropertyGroup_Any, EventProperty_Escape); if (in.abort){ block_zero_struct(&lister->out); lister->out.canceled = true; diff --git a/custom/4coder_lists.cpp b/custom/4coder_lists.cpp index db0199a3..105fe397 100644 --- a/custom/4coder_lists.cpp +++ b/custom/4coder_lists.cpp @@ -416,9 +416,9 @@ do_4coder_close_user_check(Application_Links *app, View_ID view){ CUSTOM_UI_COMMAND_SIG(interactive_switch_buffer) CUSTOM_DOC("Interactively switch to an open buffer.") { - View_ID view = get_active_view(app, Access_Always); Buffer_ID buffer = get_buffer_from_user(app, "Switch:"); if (buffer != 0){ + View_ID view = get_this_ctx_view(app, Access_Always); view_set_buffer(app, view, buffer, 0); } } @@ -426,9 +426,9 @@ CUSTOM_DOC("Interactively switch to an open buffer.") CUSTOM_UI_COMMAND_SIG(interactive_kill_buffer) CUSTOM_DOC("Interactively kill an open buffer.") { - View_ID view = get_active_view(app, Access_Always); Buffer_ID buffer = get_buffer_from_user(app, "Kill:"); if (buffer != 0){ + View_ID view = get_this_ctx_view(app, Access_Always); try_buffer_kill(app, buffer, view, 0); } } diff --git a/custom/4coder_search.cpp b/custom/4coder_search.cpp index 179a3571..56b313a5 100644 --- a/custom/4coder_search.cpp +++ b/custom/4coder_search.cpp @@ -281,10 +281,7 @@ get_complete_list_raw(Application_Links *app, Arena *arena, Buffer_ID buffer, } function void -word_complete_list_extend_from_raw(Application_Links *app, Arena *arena, - String_Match_List *matches, - List_String_Const_u8 *list, - Table_Data_u64 *used_table){ +word_complete_list_extend_from_raw(Application_Links *app, Arena *arena, String_Match_List *matches, List_String_Const_u8 *list, Table_Data_u64 *used_table){ ProfileScope(app, "word complete list extend from raw"); Scratch_Block scratch(app); for (String_Match *node = matches->first; diff --git a/custom/4coder_tutorial.cpp b/custom/4coder_tutorial.cpp index 192f9d92..fdfde628 100644 --- a/custom/4coder_tutorial.cpp +++ b/custom/4coder_tutorial.cpp @@ -315,7 +315,7 @@ hms_demo_tutorial_long_start(Application_Links *app, Arena *arena, Fancy_Block * Face_ID face = get_face_id(app, 0); // line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default)); -#define M "If there are any features you'd like to know about or try out, " +#define M "If you want more information than what you can find here, please " push_fancy_string(arena, line, string_u8_litexpr(M)); #undef M push_fancy_string(arena, line, fcolor_id(Stag_Pop2), string_u8_litexpr("ask!")); @@ -628,7 +628,193 @@ hms_demo_tutorial_slide_6(Application_Links *app, Arena *arena){ push_fancy_line(arena, long_details, face, fcolor_id(Stag_Pop1), string_u8_litexpr("Auto Indentation:")); hms_demo_tutorial_binding_line(app, arena, long_details, face, - "Control", "Tab", "auto indent the lines marked by the cursor-mark range; this command only observable when virtual whitespace is off."); + "Control", "Tab", "auto indent the lines marked by the range; the effect is only visible with virtual whitespace off."); + + return(result); +} + +function Tutorial_Slide +hms_demo_tutorial_slide_7(Application_Links *app, Arena *arena){ + Tutorial_Slide result = {}; + + Face_ID face = get_face_id(app, 0); + tutorial_init_title_face(app); + + hms_demo_tutorial_short_details(app, arena, &result.short_details); + + Fancy_Block *long_details = &result.long_details; + hms_demo_tutorial_long_start(app, arena, long_details); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Pop1), string_u8_litexpr("Builds, scripts, and projects:")); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "Alt", "M", "searches for and runs a build script (windows -> 'build.bat'; unix -> 'build.sh')"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "execute_any_cli", "queries the user for a buffer name and a system command then runs the command and pipes output to the buffer"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "execute_previous_cli", "repeats an execute_any_cli command with the same command and ouptut buffer"); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Pop1), string_u8_litexpr("If a script/command generates output that can be parsed as jumps (e.g. compilation errors) then it becomes the active jump buffer:")); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "Alt", "N", "jump to the next jump location"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "Alt Shift", "N", "jump to the previous jump location"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "Alt Shift", "M", "jump to the first jump"); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Pop1), string_u8_litexpr("The project system enables rich bindings of arbitrary system scripts (when a project is loaded):")); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "F#", "run a script bound to the corresponding index in the loaded project"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "project_command_lister", "use a lister to examine all system commands encoded in the loaded project"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "load_project", "searches for and loads a 'project.4coder' file"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "setup_new_project", "command to generate a new 'project.4coder' file and build scripts"); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default), + string_u8_litexpr("\tCheckout 'project.4coder' to see more about what is in a project.")); + + return(result); +} + +function Tutorial_Slide +hms_demo_tutorial_slide_8(Application_Links *app, Arena *arena){ + Tutorial_Slide result = {}; + + Face_ID face = get_face_id(app, 0); + tutorial_init_title_face(app); + + hms_demo_tutorial_short_details(app, arena, &result.short_details); + + Fancy_Block *long_details = &result.long_details; + hms_demo_tutorial_long_start(app, arena, long_details); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default), + string_u8_litexpr("Probably the biggest feature in 4coder is that so many things about it can be customized.")); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default), + string_u8_litexpr("The code project loaded for this demo is the 'default custom layer' everything here can be done differently as you see fit.")); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Pop1), + string_u8_litexpr("Search for these commands to see some of the features available to customization:")); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "Alt", "F", "(hint!) this is the default binding for search, use it to find these functions"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "write_text_input", "the default implementation for text insertion"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "copy", "the default implementation copying to clipboard"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "goto_line", "jump to a line specified by the user (which you should try by the way!)"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "interactive_switch_buffer", "see how this command encodes it's use of a lister with the call 'get_buffer_from_user'"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "project_command_lister", "again see how this command encodes a lister with a call, this time 'get_project_command_from_user'"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "setup_default_mapping", "defines the mapping of commands to bindings"); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default), string_u8_litexpr("")); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default), string_u8_litexpr("\tThe macros CUSTOM_COMMAND_SIG and CUSTOM_DOC markup the commands to create the list of all available commands.")); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default), string_u8_litexpr("\tThis means that user written commands that use the same markup automatically appear in the command_lister along side built in commands!")); + + return(result); +} + +function Tutorial_Slide +hms_demo_tutorial_slide_9(Application_Links *app, Arena *arena){ + Tutorial_Slide result = {}; + + Face_ID face = get_face_id(app, 0); + tutorial_init_title_face(app); + + hms_demo_tutorial_short_details(app, arena, &result.short_details); + + Fancy_Block *long_details = &result.long_details; + hms_demo_tutorial_long_start(app, arena, long_details); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default), + string_u8_litexpr("The customization system exposes much more than just commands to be customized...")); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "Alt", "F", "(hint!) this is the default binding for search, use it to find these functions"); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Pop1), + string_u8_litexpr("Write completely custom GUIs:")); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "run_lister/lister_render", "the input handling loop for listers; and the render handler for listers"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "tutorial_run_loop/tutorial_render", "underlying implementation for the tutorial system powering this demo!"); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Pop1), + string_u8_litexpr("Write custom text coloring and highlighting in buffers:")); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "draw_cpp_token_colors", "syntax highlighting for C++ tokens."); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "draw_line_number_margin", "draws a line number margin"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "default_render_buffer", "puts together all the default markup in buffer rendering"); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Pop1), + string_u8_litexpr("Write custom line layout rules:")); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "layout_unwrapped_small_blank_lines", "a funky layout that makes blank lines half height"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "layout_index_unwrapped__inner", "the unwrapped version of the virtual whitespace layout logic"); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Pop1), + string_u8_litexpr("Write custom smoothing rules that interact with buffer and UI scrolling:")); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "snap_delta", "a delta rule that snaps to the destination point instantly"); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "fixed_time_cubic_delta", "the smooth scrolling enabled in this build"); + + return(result); +} + +function Tutorial_Slide +hms_demo_tutorial_slide_10(Application_Links *app, Arena *arena){ + Tutorial_Slide result = {}; + + Face_ID face = get_face_id(app, 0); + tutorial_init_title_face(app); + + hms_demo_tutorial_short_details(app, arena, &result.short_details); + + Fancy_Block *long_details = &result.long_details; + hms_demo_tutorial_long_start(app, arena, long_details); + + push_fancy_line(arena, long_details, face, fcolor_id(Stag_Pop1), + string_u8_litexpr("Some miscellaneous things to try:")); + + hms_demo_tutorial_binding_line(app, arena, long_details, face, + "", "Tab", "in a code file this triggers the cyclic word complete, often a handy command"); return(result); } @@ -649,6 +835,14 @@ CUSTOM_DOC("Tutorial for built in 4coder bindings and features.") hms_demo_tutorial_slide_5, // virtual whitespace hms_demo_tutorial_slide_6, + // system commands + hms_demo_tutorial_slide_7, + // customizable commands + hms_demo_tutorial_slide_8, + // customizable ui + hms_demo_tutorial_slide_9, + // miscellanea + hms_demo_tutorial_slide_10, }; run_tutorial(app, slides, ArrayCount(slides)); } diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index e1c9f676..4544f6c5 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -262,7 +262,7 @@ static Command_Metadata fcoder_metacmd_table[216] = { { PROC_LINKS(toggle_highlight_enclosing_scopes, 0), false, "toggle_highlight_enclosing_scopes", 33, "In code files scopes surrounding the cursor are highlighted with distinguishing colors.", 87, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 411 }, { PROC_LINKS(toggle_paren_matching_helper, 0), false, "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 417 }, { PROC_LINKS(toggle_fullscreen, 0), false, "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 423 }, -{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever character was used to trigger this command.", 60, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 59 }, +{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 59 }, { PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts an underscore.", 22, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 67 }, { PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 73 }, { PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 79 }, @@ -381,8 +381,8 @@ static Command_Metadata fcoder_metacmd_table[216] = { { PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), false, "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 204 }, { PROC_LINKS(list_all_locations_of_type_definition, 0), false, "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 210 }, { PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), false, "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 218 }, -{ PROC_LINKS(word_complete, 0), false, "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 395 }, -{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 644 }, +{ PROC_LINKS(word_complete, 0), false, "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 392 }, +{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 641 }, { PROC_LINKS(goto_jump_at_cursor, 0), false, "goto_jump_at_cursor", 19, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 346 }, { PROC_LINKS(goto_jump_at_cursor_same_panel, 0), false, "goto_jump_at_cursor_same_panel", 30, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 373 }, { PROC_LINKS(goto_next_jump, 0), false, "goto_next_jump", 14, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 462 }, @@ -451,7 +451,7 @@ static Command_Metadata fcoder_metacmd_table[216] = { { PROC_LINKS(miblo_decrement_time_stamp_minute, 0), false, "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 249 }, { PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "w:\\4ed\\code\\custom\\4coder_profile_inspect.cpp", 45, 779 }, { PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 9 }, -{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 636 }, +{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 801 }, { PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 7 }, { PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 22 }, };