Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
7507648
add window api
YasInvolved Jun 1, 2026
92466b5
make hInstance and startupInfo global
YasInvolved Jun 1, 2026
a5e71e5
window lifetime functions
YasInvolved Jun 1, 2026
ed56396
platform header mess fix
YasInvolved Jun 2, 2026
f410d7e
expose Window_SetTitle function
YasInvolved Jun 2, 2026
7cd511e
expand the win32 api a little with new window functions
YasInvolved Jun 2, 2026
a60948d
update the branch
YasInvolved Jun 23, 2026
eb93662
fix namespace inconsistency (cosmetics, but I needed to do it)
YasInvolved Jul 9, 2026
395577c
CTMath header
YasInvolved Jul 10, 2026
35ea839
introduce aos_helper header
YasInvolved Jul 10, 2026
5b7f1d7
start reworking ThreadContext to use AoS layout (will be used later i…
YasInvolved Jul 10, 2026
8f41ec7
change naming convention a bit
YasInvolved Jul 10, 2026
c29d318
initialize new structures
YasInvolved Jul 10, 2026
630662e
update memory map
YasInvolved Jul 10, 2026
eb51703
simple codegen utility
YasInvolved Jul 11, 2026
e4cf8f7
ignore pycache
YasInvolved Jul 11, 2026
0a0c388
accept external schemas only
YasInvolved Jul 11, 2026
4a03ff8
fix bugs
YasInvolved Jul 11, 2026
1779d08
Merge pull request #8 from YasInvolved/codegen
YasInvolved Jul 11, 2026
26aec4b
add cmake codegen targets
YasInvolved Jul 11, 2026
e21b8ec
add codegen to main cmake file
YasInvolved Jul 11, 2026
95a79af
add generated types to the engine
YasInvolved Jul 11, 2026
8419240
add more types and change the target name
YasInvolved Jul 11, 2026
4cdb81c
added namespace support in codegen
YasInvolved Jul 11, 2026
14d949b
remove aos_helper header
YasInvolved Jul 11, 2026
d495039
organize generated headers better and delete old aos_helper remains
YasInvolved Jul 11, 2026
8822a65
fix type name assignment in emitter
YasInvolved Jul 11, 2026
2a8935b
update thread contexts with threadid fields and add FromSoA factory f…
YasInvolved Jul 11, 2026
10dc6e0
codegen structure alignment setting
YasInvolved Jul 11, 2026
bb61dd0
use view for clean initialization of worker context
YasInvolved Jul 11, 2026
e55101d
finish initialization
YasInvolved Jul 11, 2026
71124e7
CTMath header optimization
YasInvolved Jul 12, 2026
3163878
string util header
YasInvolved Jul 12, 2026
b24c582
fix variable naming in MemoryConfig
YasInvolved Jul 12, 2026
3b1e66c
Thread Context Array index and allocator functions for the master thread
YasInvolved Jul 12, 2026
9c38531
type update
YasInvolved Jul 12, 2026
013c10e
bring back the engine to the compilable state
YasInvolved Jul 12, 2026
c17d3c9
fix logic bug
YasInvolved Jul 12, 2026
6fdf9d9
fix variable naming
YasInvolved Jul 12, 2026
7f2e0ca
bring back missing worker allocation functions
YasInvolved Jul 12, 2026
5cb6e13
improve predictiveness and added small assertion
YasInvolved Jul 12, 2026
1791081
expose compiler header
YasInvolved Jul 12, 2026
421a704
better assertion counterpart and cosmetical changes to memory map
YasInvolved Jul 12, 2026
c9d292d
utils pch
YasInvolved Jul 12, 2026
51783f7
tidy up cmake stuff and pch
YasInvolved Jul 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ indent_size = 4
cpp_indent_access_specifiers = false
end_of_line = lf

[*.py]
charset = utf-8
indent_style = tab
indent_size = 4
end_of_line = lf

[*.json]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf

[*.yaml]
charset = utf-8
indent_style = space
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.vs
build
out
__pycache__
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ project(ProjectDelta LANGUAGES CXX)
get_filename_component(DLT_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)
get_filename_component(DLT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" ABSOLUTE)

include(cmake/DeltaCodegen.cmake)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS False)
Expand Down
30 changes: 30 additions & 0 deletions CodeGen/emitters/buffer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class CodeBuffer:
def __init__(self, indent_string=" "):
self.lines = []
self._indent_string = indent_string
self._current_indent = 0

def indent(self):
self._current_indent += 1

def dedent(self):
self._current_indent = max(0, self._current_indent - 1)

def write_line(self, text=""):
if (text.strip() == ""):
self.lines.append("")
else:
spacing = self._indent_string * self._current_indent
self.lines.append(f"{spacing}{text}")

def open_block(self, prefix_text=""):
if prefix_text:
self.write_line(prefix_text)
self.indent()

def close_block(self, suffix_text="};"):
self.dedent()
self.write_line(suffix_text)

def render(self) -> str:
return "\n".join(self.lines)
124 changes: 124 additions & 0 deletions CodeGen/emitters/engine_emitters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
from .buffer import CodeBuffer

class EngineEmitter:
def __init__(self, structures, primitives_registry, namespace=None):
self.structures = structures
self.primitives = primitives_registry
self.namespace = namespace
self.buf = CodeBuffer()

def emit_all(self, output_filepath):
self.buf.write_line("// AUTOMATICALLY GENERATED FILE - DO NOT MODIFY")
self.buf.write_line("#pragma once")
self.buf.write_line("#include <cstdint>")
self.buf.write_line()

if self.namespace:
self.buf.open_block(f"namespace {self.namespace} {{")
self.buf.write_line()

for struct in self.structures:
self._emit_aos(struct)
self.buf.write_line()

for struct in self.structures:
self._emit_soa(struct)
self.buf.write_line()

for struct in self.structures:
self._emit_view(struct)
self.buf.write_line()

if self.namespace:
self.buf.close_block(f"}}; // namespace {self.namespace}")

new_content = self.buf.render()
self._write_if_changed(output_filepath, new_content)

def _get_type_name(self, field, target_track):
if target_track == "aos":
suffix = "AoS"
elif target_track == "soa":
suffix = "SoA"
else:
suffix = "View"

return f"{field.type_name}{suffix}"

def _get_field_type(self, field, target_track):
if field.is_primitive:
return self.primitives[field.type_name][target_track]
else:
if target_track == "aos":
suffix = "AoS"
elif target_track == "soa":
suffix = "SoA"
else:
suffix = "View"

return f"{field.type_name}{suffix}"

def _emit_aos(self, struct):
align_prefix = f"alignas({struct.alignment}) " if struct.alignment else ""

self.buf.open_block(f"struct {align_prefix}{struct.name}AoS {{")
for field in struct.fields:
ftype = self._get_field_type(field, "aos")
self.buf.write_line(f"{ftype} {field.name};")
self.buf.close_block()

def _emit_soa(self, struct):
align_prefix = f"alignas({struct.alignment}) " if struct.alignment else ""

self.buf.open_block(f"struct {align_prefix}{struct.name}SoA {{")
for field in struct.fields:
ftype = self._get_field_type(field, "soa")
self.buf.write_line(f"{ftype} {field.name};")
self.buf.close_block()

def _emit_view(self, struct):
self.buf.open_block(f"struct {struct.name}View {{")

# Write references
for field in struct.fields:
ftype = self._get_field_type(field, "view")
self.buf.write_line(f"{ftype} {field.name};")
self.buf.write_line()

# FromAoS factory initialization
self.buf.open_block(f"[[nodiscard]] static inline {struct.name}View FromAoS({struct.name}AoS& instance) noexcept {{")
self.buf.open_block(f"return {struct.name}View {{")

for field in struct.fields:
if field.is_primitive:
self.buf.write_line(f".{field.name} = instance.{field.name},")
else:
self.buf.write_line(f".{field.name} = {field.type_name}View::FromAoS(instance.{field.name}),")

self.buf.close_block("};")
self.buf.close_block("}")

# FromSoA factory initialization
self.buf.open_block(f"[[nodiscard]] static inline {struct.name}View FromSoA({struct.name}SoA& instance, uint32_t ix) noexcept {{")
self.buf.open_block(f"return {struct.name}View {{")

for field in struct.fields:
if field.is_primitive:
self.buf.write_line(f".{field.name} = instance.{field.name}[ix],")
else:
self.buf.write_line(f".{field.name} = {field.type_name}View::FromSoA(instance.{field.name}, ix),")

self.buf.close_block("};")
self.buf.close_block("}")

# end structure
self.buf.close_block()

def _write_if_changed(self, filepath, content):
import os
if os.path.exists(filepath):
with open(filepath, "r") as f:
if f.read() == content:
return
with open(filepath, "w") as f:
f.write(content)
43 changes: 43 additions & 0 deletions CodeGen/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import os
import sys
import json
from model import load_schemas_tree
from emitters.engine_emitters import EngineEmitter

def main():
if len(sys.argv) < 3:
print("Error: Missing output file path argument from CMake.", file=sys.stderr)
sys.exit(1)

input_schema_path = sys.argv[1]
output_filepath = sys.argv[2]

script_dir = os.path.dirname(os.path.abspath(__file__))
core_types_path = os.path.join(script_dir, "schemas", "core_types.json")
output_directory, _ = os.path.split(output_filepath)

print(output_directory)
os.makedirs(output_directory, exist_ok=True)

if not os.path.exists(core_types_path):
print(f"Error: Missing core types registry at {core_types_path}", file=sys.stderr)
sys.exit(1)

with open(core_types_path, "r") as f:
core_data = json.load(f)

primitives_map = {}
for p in core_data.get("primitives", []) + core_data.get("opaque_engine_types", []):
primitives_map[p["name"]] = p

if not os.path.exists(input_schema_path):
print(f"Error: Structural schema missing at {input_schema_path}", file=sys.stderr)
sys.exit(1)

parsed_structures, target_namespace = load_schemas_tree([input_schema_path], primitives_map)

emitter = EngineEmitter(parsed_structures, primitives_map, target_namespace)
emitter.emit_all(output_filepath)

if __name__ == "__main__":
main()
40 changes: 40 additions & 0 deletions CodeGen/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import json

class Field:
def __init__(self, type_name, name, is_primitive):
self.type_name = type_name
self.name = name
self.is_primitive = is_primitive

class Structure:
def __init__(self, name, raw_fields, primitives_registry, custom_types, alignment = None):
self.name = name
self.fields = []
self.alignment = int(alignment) if alignment is not None else None

for f in raw_fields:
is_prim = f["type"] in primitives_registry
self.fields.append(Field(f["type"], f["name"], is_prim))

def load_schemas_tree(schema_files, primitives_registry):
custom_types = set()
raw_structs = []
target_namespace = None

for file_path in schema_files:
with open(file_path, "r") as f:
data = json.load(f)

if "namespace" in data:
target_namespace = data["namespace"]

for s in data["structures"]:
custom_types.add(s["name"])
raw_structs.append(s)

parsed_structures = [
Structure(s["name"], s["fields"], primitives_registry, custom_types, s.get("alignment"))
for s in raw_structs
]

return parsed_structures, target_namespace
46 changes: 46 additions & 0 deletions CodeGen/schemas/core_types.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"primitives": [
{
"name": "uint8_t",
"alignment": 1,
"aos": "uint8_t",
"soa": "uint8_t*",
"view": "uint8_t&"
},
{
"name": "uint16_t",
"alignment": 2,
"aos": "uint16_t",
"soa": "uint16_t*",
"view": "uint16_t&"
},
{
"name": "uint32_t",
"alignment": 4,
"aos": "uint32_t",
"soa": "uint32_t*",
"view": "uint32_t&"
},
{
"name": "uint64_t",
"alignment": 8,
"aos": "uint64_t",
"soa": "uint64_t*",
"view": "uint64_t&"
},
{
"name": "size_t",
"alignment": 8,
"aos": "size_t",
"soa": "size_t*",
"view": "size_t&"
},
{
"name": "uintptr_t",
"alignment": 8,
"aos": "uintptr_t",
"soa": "uintptr_t*",
"view": "uintptr_t&"
}
]
}
Loading