diff --git a/.vscode/bookmarks.json b/.vscode/bookmarks.json index 4d87d72..cdebe3b 100644 --- a/.vscode/bookmarks.json +++ b/.vscode/bookmarks.json @@ -4,32 +4,32 @@ "path": "project/platform/win32_platform.cpp", "bookmarks": [ { - "line": 57, + "line": 59, "column": 0, "label": "Struct Defs" }, { - "line": 96, + "line": 98, "column": 0, "label": "Static Data" }, { - "line": 629, + "line": 631, "column": 0, "label": "Timing" }, { - "line": 1478, + "line": 1453, "column": 4, "label": "Main Loop : Audio Processing" }, { - "line": 1597, + "line": 1572, "column": 2, "label": "Main Loop : Timing Update" }, { - "line": 1681, + "line": 1656, "column": 0, "label": "Main Loop : End" } diff --git a/.vscode/launch.json b/.vscode/launch.json index 88c6c82..9e24c5c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,6 +12,15 @@ "args": [], "cwd": "${workspaceFolder}/data/binaries/", "visualizerFile": "${workspaceFolder}/scripts/handmade.natvis" + }, + { + "type":"cppvsdbg", + "request": "launch", + "name" : "Debug handmade platform gen msvc", + "program": "${workspaceFolder}/build/handmade_platform_gen.exe", + "args": [], + "cwd": "${workspaceFolder}/build", + "visualizerFile": "${workspaceFolder}/scripts/handmade.natvis" } ] } diff --git a/data/binaries/handmade_engine.symbols b/data/binaries/handmade_engine.symbols deleted file mode 100644 index fb9320c..0000000 --- a/data/binaries/handmade_engine.symbols +++ /dev/null @@ -1,5 +0,0 @@ -?on_module_reload@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z -?startup@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z -?shutdown@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z -?update_and_render@engine@@YAXPEAUInputState@1@PEAUOffscreenBuffer@1@PEAUMemory@1@PEAUModuleAPI@platform@@@Z -?update_audio@engine@@YAXPEAUAudioBuffer@1@PEAUMemory@1@PEAUModuleAPI@platform@@@Z diff --git a/data/test_input.hmi b/data/test_input.hmi deleted file mode 100644 index 7759f02..0000000 Binary files a/data/test_input.hmi and /dev/null differ diff --git a/engine_symbol_table.hpp b/engine_symbol_table.hpp new file mode 100644 index 0000000..e69de29 diff --git a/project/codegen/Readme.md b/project/codegen/Readme.md new file mode 100644 index 0000000..1f8413e --- /dev/null +++ b/project/codegen/Readme.md @@ -0,0 +1,4 @@ +# Project Code Generation + +This directory contains metaprograms that generate code for the project. +Any code generated will be put into `*.gen.cpp` files within a gen folder for the respective module the metaprogram is generating for. diff --git a/project/gen/handmade_gen.cpp b/project/codegen/handmade_engine_gen.cpp similarity index 65% rename from project/gen/handmade_gen.cpp rename to project/codegen/handmade_engine_gen.cpp index 9087866..e7db5df 100644 --- a/project/gen/handmade_gen.cpp +++ b/project/codegen/handmade_engine_gen.cpp @@ -9,9 +9,11 @@ using namespace gen; int gen_main() { gen::init(); - log_fmt("Generating code for Handmade Hero\n"); + log_fmt("Generating code for Handmade Hero: Engine Module\n"); - log_fmt("Generaton finished for Handmade Hero\n"); + + + log_fmt("Generaton finished for Handmade Hero: Engine Module\n"); // gen::deinit(); return 0; } diff --git a/project/codegen/handmade_platform_gen.cpp b/project/codegen/handmade_platform_gen.cpp new file mode 100644 index 0000000..d14d659 --- /dev/null +++ b/project/codegen/handmade_platform_gen.cpp @@ -0,0 +1,101 @@ +#if GEN_TIME +#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS +#define GEN_IMPLEMENTATION +#define GEN_BENCHMARK +#define GEN_ENFORCE_STRONG_CODE_TYPES +#include "dependencies/gen.hpp" +using namespace gen; + +#include "platform/platform_engine_api.hpp" +constexpr StrC fname_handmade_engine_symbols = txt("handmade_engine.symbols"); + +String get_symbol_from_module_table( FileContents symbol_table, u32 symbol_ID ) +{ + struct Token + { + char const* Ptr; + u32 Len; + }; + + Token tokens[256] = {}; + + char const* scanner = rcast( char const*, symbol_table.data ); + u32 left = symbol_table.size; + u32 line = 0; + while ( left ) + { + if ( *scanner == '\n' || *scanner == '\r' ) + { + ++ scanner; + -- left; + } + else + { + tokens[line].Ptr = scanner; + while ( left && *scanner != '\r' && *scanner != '\n' ) + { + -- left; + ++ scanner; + ++ tokens[line].Len; + } + + if ( line == symbol_ID ) + { + String result = String::make_length( GlobalAllocator, tokens[line].Ptr, tokens[line].Len ); + return result; + } + ++ line; + } + } + return {}; +} + +int gen_main() +{ + gen::init(); + log_fmt("Generating code for Handmade Hero: Platfom Module\n"); + + FileContents symbol_table = file_read_contents( GlobalAllocator, true, fname_handmade_engine_symbols ); + +#pragma push_macro("str_ascii") +#undef str_ascii + Builder builder = Builder::open( "engine_symbol_table.hpp" ); + builder.print( pragma_once ); + builder.print( def_include( txt("platform/platform.hpp") ) ); + builder.print( fmt_newline ); + builder.print_fmt( "NS_ENGINE_BEGIN\n\n" ); + + StrC symbol_on_module_load = get_symbol_from_module_table( symbol_table, engine::ModuleAPI::Sym_OnModuleReload ); + StrC symbol_startup = get_symbol_from_module_table( symbol_table, engine::ModuleAPI::Sym_Startup ); + StrC symbol_shutdown = get_symbol_from_module_table( symbol_table, engine::ModuleAPI::Sym_Shutdown ); + StrC symbol_update_and_render = get_symbol_from_module_table( symbol_table, engine::ModuleAPI::Sym_UpdateAndRender ); + StrC symbol_update_audio = get_symbol_from_module_table( symbol_table, engine::ModuleAPI::Sym_UpdateAudio ); + + + builder.print( parse_variable( token_fmt( "symbol", symbol_on_module_load, stringize( + constexpr const Str symbol_on_module_load = str_ascii(""); + )))); + builder.print( parse_variable( token_fmt( "symbol", symbol_startup, stringize( + constexpr const Str symbol_startup = str_ascii(""); + )))); + builder.print( parse_variable( token_fmt( "symbol", symbol_shutdown, stringize( + constexpr const Str symbol_shutdown = str_ascii(""); + )))); + builder.print( parse_variable( token_fmt( "symbol", symbol_update_and_render, stringize( + constexpr const Str symbol_update_and_render = str_ascii(""); + )))); + builder.print( parse_variable( token_fmt( "symbol", symbol_update_audio, stringize( + constexpr const Str symbol_update_audio = str_ascii(""); + )))); + + builder.print_fmt( "\nNS_ENGINE_END" ); + builder.print( fmt_newline ); + builder.write(); +#pragma pop_macro("str_ascii") + + log_fmt("Generaton finished for Handmade Hero: Platform Module\n"); + // gen::deinit(); + return 0; +} +#endif + diff --git a/project/dependencies/gen.hpp b/project/dependencies/gen.hpp index dddc1dd..b31cb04 100644 --- a/project/dependencies/gen.hpp +++ b/project/dependencies/gen.hpp @@ -23056,7 +23056,7 @@ internal CodeVar parse_variable() // Ignore const specifiers, they're handled by the type if ( spec == ESpecifier::Const ) - continue; + break; specs_found[ NumSpecifiers ] = spec; NumSpecifiers++; diff --git a/project/gen/Readme.md b/project/gen/Readme.md new file mode 100644 index 0000000..549dde9 --- /dev/null +++ b/project/gen/Readme.md @@ -0,0 +1,3 @@ +# Universal Generated Code + +This is for generated code used for multiple modules. diff --git a/project/gen/engine_symbol_table.hpp b/project/gen/engine_symbol_table.hpp new file mode 100644 index 0000000..d4605d7 --- /dev/null +++ b/project/gen/engine_symbol_table.hpp @@ -0,0 +1,17 @@ +#pragma once +#include "platform/platform.hpp" + +NS_ENGINE_BEGIN + +constexpr +Str const symbol_on_module_load = str_ascii("?on_module_reload@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z"); +constexpr +Str const symbol_startup = str_ascii("?startup@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z"); +constexpr +Str const symbol_shutdown = str_ascii("?shutdown@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z"); +constexpr +Str const symbol_update_and_render = str_ascii("?update_and_render@engine@@YAXPEAUInputState@1@PEAUOffscreenBuffer@1@PEAUMemory@1@PEAUModuleAPI@platform@@@Z"); +constexpr +Str const symbol_update_audio = str_ascii("?update_audio@engine@@YAXPEAUAudioBuffer@1@PEAUMemory@1@PEAUModuleAPI@platform@@@Z"); + +NS_ENGINE_END diff --git a/project/platform/platform.hpp b/project/platform/platform.hpp index 46190ea..ee00551 100644 --- a/project/platform/platform.hpp +++ b/project/platform/platform.hpp @@ -53,51 +53,6 @@ struct File u32 Size; }; -// TODO(Ed): This also assumes the symbol name is always within size of the provided buffer, needs to fail if not. -// Note: This is a temporary solution until there is more infrastructure for the engine to use. -void get_symbol_from_module_table( File symbol_table, u32 symbol_ID, char* symbol_name ) -{ - struct Token - { - char const* Ptr; - u32 Len; - }; - - Token tokens[256] = {}; - s32 idx = 0; - - char const* scanner = rcast( char const*, symbol_table.Data ); - u32 left = symbol_table.Size; - while ( left ) - { - if ( *scanner == '\n' || *scanner == '\r' ) - { - ++ scanner; - -- left; - } - else - { - tokens[idx].Ptr = scanner; - while ( left && *scanner != '\r' && *scanner != '\n' ) - { - -- left; - ++ scanner; - ++ tokens[idx].Len; - } - ++ idx; - } - } - - Token& token = tokens[symbol_ID]; - while ( token.Len -- ) - { - *symbol_name = *token.Ptr; - ++ symbol_name; - ++ token.Ptr; - } - *symbol_name = '\0'; -} - #pragma region Settings Exposure // Exposing specific properties for user configuration in settings diff --git a/project/platform/win32_platform.cpp b/project/platform/win32_platform.cpp index d799345..7246fe2 100644 --- a/project/platform/win32_platform.cpp +++ b/project/platform/win32_platform.cpp @@ -26,6 +26,8 @@ #include "engine/engine.hpp" #include "platform_engine_api.hpp" +#include "gen/engine_symbol_table.hpp" + #if 1 // TODO(Ed): Redo these macros properly later. @@ -1086,39 +1088,12 @@ engine::ModuleAPI load_engine_module_api() return {}; } - constexpr Str fname_handmade_engine_symbols = str_ascii("handmade_engine.symbols"); - - StrFixed< S16_MAX > path_handmade_engine_symbols { 0, {} }; - path_handmade_engine_symbols.concat( Path_Binaries, fname_handmade_engine_symbols ); - - File symbol_table {}; - symbol_table.Path = path_handmade_engine_symbols; - if ( file_read_content( & symbol_table ), symbol_table.Size == 0 ) - { - fatal( "Failed to load symbol table for handmade engine module!" ); - return {}; - } - - // TODO(Ed) : Clean this up later when Casey makes strings. (If he doesn't we'll do it) - char symbol_on_module_reload[256]; - char symboL_startup[256]; - char symboL_shutdown[256]; - char symboL_update_and_render[256]; - char symbol_update_audio[256]; - get_symbol_from_module_table( symbol_table, ModuleAPI::Sym_OnModuleReload, symbol_on_module_reload ); - get_symbol_from_module_table( symbol_table, ModuleAPI::Sym_Startup, symboL_startup ); - get_symbol_from_module_table( symbol_table, ModuleAPI::Sym_Shutdown, symboL_shutdown ); - get_symbol_from_module_table( symbol_table, ModuleAPI::Sym_UpdateAndRender, symboL_update_and_render ); - get_symbol_from_module_table( symbol_table, ModuleAPI::Sym_UpdateAudio, symbol_update_audio ); - - file_close( & symbol_table ); - engine::ModuleAPI engine_api {}; - engine_api.on_module_reload = get_procedure_from_library< engine::OnModuleRelaodFn > ( Lib_Handmade_Engine, symbol_on_module_reload ); - engine_api.startup = get_procedure_from_library< engine::StartupFn > ( Lib_Handmade_Engine, symboL_startup ); - engine_api.shutdown = get_procedure_from_library< engine::ShutdownFn > ( Lib_Handmade_Engine, symboL_shutdown ); - engine_api.update_and_render = get_procedure_from_library< engine::UpdateAndRenderFn >( Lib_Handmade_Engine, symboL_update_and_render ); - engine_api.update_audio = get_procedure_from_library< engine::UpdateAudioFn > ( Lib_Handmade_Engine, symbol_update_audio ); + engine_api.on_module_reload = get_procedure_from_library< engine::OnModuleRelaodFn > ( Lib_Handmade_Engine, engine::symbol_on_module_load ); + engine_api.startup = get_procedure_from_library< engine::StartupFn > ( Lib_Handmade_Engine, engine::symbol_startup ); + engine_api.shutdown = get_procedure_from_library< engine::ShutdownFn > ( Lib_Handmade_Engine, engine::symbol_shutdown ); + engine_api.update_and_render = get_procedure_from_library< engine::UpdateAndRenderFn >( Lib_Handmade_Engine, engine::symbol_update_and_render ); + engine_api.update_audio = get_procedure_from_library< engine::UpdateAudioFn > ( Lib_Handmade_Engine, engine::symbol_update_audio ); engine_api.IsValid = engine_api.on_module_reload diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 5e8f62f..03c65d7 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -3,6 +3,7 @@ Clear-Host $target_arch = Join-Path $PSScriptRoot 'helpers/target_arch.psm1' $devshell = Join-Path $PSScriptRoot 'helpers/devshell.ps1' $path_root = git rev-parse --show-toplevel +$path_build = Join-Path $path_root 'build' Import-Module $target_arch @@ -196,6 +197,8 @@ if ( $vendor -match "clang" ) $object = $unit -replace '\.cpp', '.obj' $map = $unit -replace '\.cpp', '.map' + $object = join-path $path_build (split-path $object -Leaf) + $map = join-path $path_build (split-path $map -Leaf) # The PDB file has to also be time-stamped so that we can reload the DLL at runtime $timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss" @@ -315,8 +318,8 @@ if ( $vendor -match "msvc" ) $object = $unit -replace '\.(cpp)$', '.obj' $map = $unit -replace '\.(cpp)$', '.map' - $object = $object -replace '\bproject\b', 'build' - $map = $map -replace '\bproject\b', 'build' + $object = join-path $path_build (split-path $object -Leaf) + $map = join-path $path_build (split-path $map -Leaf) # The PDB file has to also be time-stamped so that we can reload the DLL at runtime $timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss" @@ -391,10 +394,10 @@ if ( $vendor -match "msvc" ) #region Building $path_project = Join-Path $path_root 'project' -$path_build = Join-Path $path_root 'build' $path_data = Join-Path $path_root 'data' $path_binaries = Join-Path $path_data 'binaries' $path_deps = Join-Path $path_project 'dependencies' +$path_codegen = Join-Path $path_project 'codegen' $path_gen = Join-Path $path_project 'gen' $path_platform = Join-Path $path_project 'platform' $path_engine = Join-Path $path_project 'engine' @@ -413,36 +416,6 @@ if ( (Test-Path $path_binaries) -eq $false ) { New-Item $path_binaries -ItemType Directory } -#region Handmade Generate -if ( $false ) { - $includes = @( - $path_project, - $path_gen, - # $path_deps, - $path_platform - ) - $compiler_args = @() - $compiler_args += ( $flag_define + 'GEN_TIME' ) - - $linker_args = @( - $flag_link_win_subsystem_console - ) - - $unit = Join-Path $path_gen 'handmade_gen.cpp' - $executable = Join-Path $path_build 'handmade_gen.exe' - - build-simple $includes $compiler_args $linker_args $unit $executable - write-host - - & $executable - write-host - - if ( $false ) { - Remove-Item (Get-ChildItem -Path $path_build -Recurse -Force) - } -} -#endregion Handmade Generate - #region Handmade Runtime $includes = @( $path_project @@ -576,7 +549,7 @@ if ( $engine ) } # Write the symbol table to a file - $path_engine_symbols = Join-Path $path_binaries 'handmade_engine.symbols' + $path_engine_symbols = Join-Path $path_build 'handmade_engine.symbols' $engine_symbols.Values | Out-File -Path $path_engine_symbols } @@ -585,6 +558,32 @@ if ( $engine ) if ( $platform ) { + + #region CodeGen + if ( $true ) { + $engine_codegen_compiler_args = @() + $engine_codegen_compiler_args += ( $flag_define + 'GEN_TIME' ) + + $engine_codegen_linker_args = @( + $flag_link_win_subsystem_console + ) + + $unit = Join-Path $path_codegen 'handmade_platform_gen.cpp' + $executable = Join-Path $path_build 'handmade_platform_gen.exe' + + build-simple $includes $engine_codegen_compiler_args $engine_codegen_linker_args $unit $executable + write-host + + Push-Location $path_build + & $executable + Pop-Location + write-host + + $path_generated_file = Join-Path $path_build 'engine_symbol_table.hpp' + move-item $path_generated_file (join-path $path_gen (split-path $path_generated_file -leaf)) -Force + } + #endregion CodeGen + # Delete old PDBs $pdb_files = Get-ChildItem -Path $path_binaries -Filter "handmade_win32_*.pdb" foreach ($file in $pdb_files) { @@ -604,7 +603,7 @@ if ( $platform ) $lib_jsl, $flag_link_win_subsystem_windows - # $flag_link_optimize_references + $flag_link_optimize_references ) $unit = Join-Path $path_project 'handmade_win32.cpp' diff --git a/scripts/clean.ps1 b/scripts/clean.ps1 index f41ace3..cd65823 100644 --- a/scripts/clean.ps1 +++ b/scripts/clean.ps1 @@ -13,3 +13,4 @@ if ( Test-Path $path_build ) { if ( Test-Path $path_binaries ) { Remove-Item -verbose $path_binaries -Recurse } +