work on auto-adding console commands

This commit is contained in:
Tuomas Katajisto 2025-07-26 21:47:04 +03:00
parent 977bb107dc
commit 7344c44576
10 changed files with 137 additions and 9 deletions

View File

@ -77,6 +77,7 @@ Iprof :: #import "Iprof"(IMPORT_MODE = .METAPROGRAM);
while true { while true {
message := compiler_wait_for_message(); message := compiler_wait_for_message();
custom_message_handler(message, *w);
if message.kind == { if message.kind == {
case .TYPECHECKED; case .TYPECHECKED;
typechecked := cast(*Message_Typechecked) message; typechecked := cast(*Message_Typechecked) message;
@ -146,15 +147,14 @@ Iprof :: #import "Iprof"(IMPORT_MODE = .METAPROGRAM);
} else { } else {
add_build_string("HAS_TACOMA :: false;", w); add_build_string("HAS_TACOMA :: false;", w);
} }
add_build_string("HAS_IPROF :: true;", w);
iprof_plugin.add_source(iprof_plugin); iprof_plugin.add_source(iprof_plugin);
add_build_file("src/platform_specific/main_native.jai", w); add_build_file("src/platform_specific/main_native.jai", w);
lint_ok := true;
while true { while true {
message := compiler_wait_for_message(); message := compiler_wait_for_message();
iprof_plugin.message(iprof_plugin, message); iprof_plugin.message(iprof_plugin, message);
if !lint_checks(message) then lint_ok = false; custom_message_handler(message, *w);
if message.kind == .COMPLETE then break; if message.kind == .COMPLETE then break;
} }
compiler_end_intercept(w); compiler_end_intercept(w);

View File

@ -1,3 +1,5 @@
#scope_file
Console_State :: enum { Console_State :: enum {
CLOSED; CLOSED;
OPEN_HALF; OPEN_HALF;
@ -23,6 +25,38 @@ get_console_h_target_from_state :: (state: Console_State) -> float {
return 0; return 0;
} }
console_input_start : string = "";
parse_argument_float :: (s: string) -> bool {
return false;
}
command_add :: (a: int, b: int) -> int {
return a + b;
}
command_add_front :: (args: []string) {
if verify_argument_count(2,2,args.count) {
array_add(*console_report, sprint("Argument count error: count = % not in range %..%.", args.count, 2, 2));
return;
}
}
#scope_export
console_command_procs : [..]([]string) -> string;
console_command_names : [..]string;
init_console :: () {
register_commands();
}
verify_argument_count :: (range_start: s64, range_end: s64, count: s64) -> bool {
return count >= range_start && count <= range_end;
}
tick_console :: () { tick_console :: () {
if input_button_states[Key_Code.F1] & .START { if input_button_states[Key_Code.F1] & .START {
if console_state != .CLOSED { if console_state != .CLOSED {
@ -69,7 +103,6 @@ tick_console :: () {
} }
} }
console_input_start : string = "";
draw_console :: (theme: *GR.Overall_Theme) { draw_console :: (theme: *GR.Overall_Theme) {
if console_h < 1 then return; if console_h < 1 then return;
@ -84,7 +117,15 @@ draw_console :: (theme: *GR.Overall_Theme) {
if a & .ENTERED { if a & .ENTERED {
array_add(*console_report, copy_string(tprint("> %", new))); array_add(*console_report, copy_string(tprint("> %", new)));
state.text = console_input_start; state.text = console_input_start;
array_add(*console_report, "Unknown command."); found := false;
for it, idx : console_command_names {
print("%\n", it);
if it == new {
array_add(*console_report, console_command_procs[idx](.[]));
found = true;
}
}
if !found then array_add(*console_report, "Unknown command.");
} }
for < console_report { for < console_report {

View File

@ -21,6 +21,7 @@ current_editor_view : Editor_View = .Trile_Editor;
init_editor :: () { init_editor :: () {
init_profiler(); init_profiler();
init_console();
} }
// Used when the console is open, so typing doesn't cause all sorts of stuff. // Used when the console is open, so typing doesn't cause all sorts of stuff.

View File

@ -1,5 +1,15 @@
#scope_file #if HAS_IPROF == false {
init_profiler :: () {}
draw_profiler :: () {}
profiler_update :: () {}
tick_profiler :: () {}
} else {
#scope_file
iprof_conf : __Iprof.Config; iprof_conf : __Iprof.Config;
iprof_font : Ui_Font; iprof_font : Ui_Font;
@ -119,3 +129,4 @@ tick_profiler :: () {
__Iprof.set_cursor_screen_coordinates(xx input_mouse_x, xx input_mouse_y); __Iprof.set_cursor_screen_coordinates(xx input_mouse_x, xx input_mouse_y);
} }
}

View File

@ -1,5 +1,5 @@
#run { #run {
#load "../../meta/ascii.jai"; #load "../meta/ascii.jai";
print("%\n", ascii_tacoma); print("%\n", ascii_tacoma);
} }

View File

@ -108,6 +108,10 @@ handle_tool_click :: () {
current_color : Vector3 = .{1.0, 0.0, 0.0}; current_color : Vector3 = .{1.0, 0.0, 0.0};
reset_trile :: () {
print("Reset called!\n");
} @Command
tick_trile_editor :: () { tick_trile_editor :: () {
if console_open_ignore_input then return; if console_open_ignore_input then return;

View File

@ -0,0 +1,64 @@
console_commands_to_register : [..]string;
add_console_registration_code :: (w: *Workspace) {
builder : String_Builder;
print_to_builder(*builder, "register_commands :: () {\n");
for console_commands_to_register {
print_to_builder(*builder, "array_add(*console_command_procs, %__command_front);\n", it);
print_to_builder(*builder, "array_add(*console_command_names, \"%\");\n", it);
}
print_to_builder(*builder, "}\n");
add_build_string(builder_to_string(*builder), w.*);
}
add_console_commands :: (message: *Message, w: *Workspace) {
if message.kind == .PHASE {
phase_message := cast(*Message_Phase) message;
if phase_message.phase == .TYPECHECKED_ALL_WE_CAN {
if console_commands_to_register.count > 0 {
add_console_registration_code(w);
array_reset(*console_commands_to_register);
}
}
}
if message.kind != .TYPECHECKED then return;
code := cast(*Message_Typechecked) message;
all_commands_builder : String_Builder;
for code.declarations {
import := it.expression.enclosing_load.enclosing_import;
expression := it.expression;
if expression.expression && expression.expression.kind == .PROCEDURE_HEADER {
header := cast(*Code_Procedure_Header) expression.expression;
is_command := false;
for expression.notes {
if it.text == "Command" {
is_command = true;
}
}
if !is_command then continue;
print("Found console command called: %\n", expression.name);
if expression.flags & .SCOPE_FILE {
compiler_report(sprint("Command % is file scoped, that is not okay. Commands must be exported.", expression.name), make_location(cast(*Code_Node)expression), .ERROR);
}
// @ToDo: Count argument range properly.
arg_count := header.arguments.count;
builder : String_Builder;
print_to_builder(*builder, "%__command_front :: (args: []string) -> string {\n", expression.name);
print_to_builder(*builder, "if !verify_argument_count(%, %, args.count) return sprint(\"Wrong number of arguments! Expected \%, got \%.\", %, args.count);\n", arg_count, arg_count, arg_count);
print_to_builder(*builder, "return sprint(\"\%\", %());\n", expression.name);
print_to_builder(*builder, "}\n");
str := builder_to_string(*builder);
print("%\n", str);
array_add(*console_commands_to_register, sprint("%", expression.name));
add_build_string(str, w.*);
free(str);
}
}
return;
}

View File

@ -1,2 +1,8 @@
#load "ascii.jai"; #load "ascii.jai";
#load "lint.jai"; #load "lint.jai";
#load "console_commands.jai";
custom_message_handler :: (message: *Message, w: *Workspace) {
lint_checks(message);
add_console_commands(message, w);
}

View File

@ -5,6 +5,7 @@
trile_gfx_table : Table(string, Trile_GFX); trile_gfx_table : Table(string, Trile_GFX);
trile_table : Table(string, Trile); trile_table : Table(string, Trile);
#scope_export #scope_export
Trile_GFX :: struct { Trile_GFX :: struct {
@ -21,7 +22,7 @@ Trile_GFX :: struct {
// once it's more clear how this whole trile storage thing // once it's more clear how this whole trile storage thing
// will pan out. -ktjst // will pan out. -ktjst
get_trile_gfx :: (name: string) -> (Trile_GFX, success: bool) { get_trile_gfx :: (name: string) -> (Trile_GFX, success: bool) {
value, success := table_find(*trile_gfx_table, name); success, value := table_find_new(*trile_gfx_table, name);
if !success { if !success {
// Check if such a trile exists. // Check if such a trile exists.
trile, success_with_trile := get_trile(name); trile, success_with_trile := get_trile(name);

View File

@ -28,7 +28,7 @@ world_config_to_shader_type :: (wc: *World_Config, data: *$T) {
} }
return builder_to_string(*builder); return builder_to_string(*builder);
} }
#insert #run generate_copy_code(); #insert #run,stallable generate_copy_code();
} }
IVector3 :: struct { IVector3 :: struct {