Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
976709a
wip
NiZe42 Aug 28, 2025
962a012
fix hashed_string, move notes.cpp to outside of the project
GlynLeine Aug 28, 2025
649c171
update rsl to get argh
GlynLeine Aug 28, 2025
ce30cac
Update rsl
NiZe42 Aug 28, 2025
d85b8d5
Merge remote-tracking branch 'origin/main'
NiZe42 Aug 28, 2025
c6661fa
update rsl
GlynLeine Aug 28, 2025
703a691
Merge branch 'main' of https://github.com/Rythe-Interactive/reflectio…
GlynLeine Aug 28, 2025
ad2f7c0
added working AST
NiZe42 Sep 4, 2025
a703465
added parameters
NiZe42 Sep 5, 2025
5d4713e
rsl::cli_parser alias
GlynLeine Sep 8, 2025
0011ea3
broken codegen
NiZe42 Sep 9, 2025
2d88278
Merge branch 'main' of https://github.com/Rythe-Interactive/reflectio…
NiZe42 Sep 9, 2025
dada67b
wip
NiZe42 Sep 12, 2025
1211ae8
update rsl
GlynLeine Sep 15, 2025
fbe1f85
wip
NiZe42 Sep 15, 2025
a989037
update rsl again
GlynLeine Sep 15, 2025
291ea76
wip broken print
NiZe42 Sep 15, 2025
f0e3701
update rsl, rbs, and set debug args in project
GlynLeine Sep 15, 2025
e890759
update rsl
GlynLeine Sep 15, 2025
ba17054
small suggestion
GlynLeine Sep 16, 2025
e236e0b
works for hashed string too
GlynLeine Sep 16, 2025
561eb14
WIP
NiZe42 Sep 22, 2025
0323990
started adding compile reflection
NiZe42 Sep 22, 2025
0b064a1
not compiling variable container
NiZe42 Sep 23, 2025
da5308d
Started reworking parser yet again.
NiZe42 Sep 24, 2025
f3a2294
changed some more code style, continued with restructure
NiZe42 Sep 25, 2025
1269573
some minor review notes
GlynLeine Sep 25, 2025
9e913f5
almost done ast_parser
NiZe42 Sep 25, 2025
617706a
Merge branch 'main' of https://github.com/Rythe-Interactive/reflectio…
NiZe42 Sep 25, 2025
88878ba
added comments back in, fixed a little error
NiZe42 Sep 25, 2025
fb29c5c
Implemented templates for containers
NiZe42 Oct 1, 2025
10f00e9
wip printing, added base element class
NiZe42 Oct 1, 2025
097dd6d
working parser with printing
NiZe42 Oct 2, 2025
22a031a
little print improvement
NiZe42 Oct 3, 2025
005669b
started code_gen
NiZe42 Oct 9, 2025
f3cc14a
added hashing
NiZe42 Oct 10, 2025
0023950
WIP not working code gen
NiZe42 Oct 14, 2025
3746067
implemented reviews
NiZe42 Oct 16, 2025
fc81672
WIP hashing system
NiZe42 Oct 17, 2025
7aa6a4c
WIP still broken hashing
NiZe42 Oct 20, 2025
5485e1d
finished hashing
NiZe42 Oct 21, 2025
ade8f67
added const to constructors
NiZe42 Oct 21, 2025
31f27f3
fixed hashing bugs
NiZe42 Oct 24, 2025
dc954b3
WIP
NiZe42 Oct 27, 2025
35ca05d
continued codegen
NiZe42 Oct 29, 2025
733a099
fix bug
NiZe42 Oct 29, 2025
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
14 changes: 14 additions & 0 deletions StructurePlan.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ Have a cash system which will partially generate things

Having as multiple .cpp and .hpp files does feel significantly better performance wise as it would allow to not recompile everything when something is changed and make it modular. In addition we would be able to remove need for registry if generated.hpp file would hold a reference to metadata. The downside is having a lot of files. BUT THREAAADING CAN BE IMPLEMENTED TO MAKE IT PARALLEL.

Add supported list of attributes to our precompiler step, which will give warning based on if it is in there already or not.

LLVM + clang; consider parsing AST myself vs let clang parse it;


2 During compilation populate unordered map with type - members

Different types and info we need to keep track of:
Expand All @@ -16,6 +21,7 @@ Different types and info we need to keep track of:
4 Functions: -//-, const, static, virtual and co, pointer to function,
5 Template instances: our concept thing, member functions and variables, allignment, size, name with parameters,
6 Enums: underlying type, scoped?, values
7 unions?


If we implement inheritance reflected_member - we will incur 8*virtual_func_num hidden bytes
Expand All @@ -25,3 +31,11 @@ Need to figure out which modifiers exactly can be used in the future.
Need to add a way to manually add reflections.

buffer_string,dynamic string

Need to include namespace into strings

For choices: Hash function, hash structure, compile vs runtime containers

For choices, where to store runtime reflection data - BSS vs Heap vs Stack

Names are made from recursive parents. No runtime reflected namespaces objects.
3 changes: 2 additions & 1 deletion VisualStudio22-All.bat
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
rythe-build-system\premake5 --file=rythe-build-system/premake5.lua vs2022 --workspace-name=reflection-experiments
rythe-build-system\premake5 --file=rythe-build-system/premake5.lua vs2022 --workspace-name=reflection-experiments
pause
9 changes: 4 additions & 5 deletions applications/reflection-experiments/.rythe_project
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ local fs = dofile("filesystem.lua")

local project = {
additional_types = { "test" },
dependencies = { "public rythe/rythe-standard-library", "private third_party/clang-c:header-only" },
dependencies = { "public rythe/rythe-standard-library", "private third_party/clang-c:header-only",
"private third_party/xxhash"},
additional_link_targets = { "libclang" },
}

function project.init(proj, context)
local targetDir = fs.sanitize(fs.parentPath(_MAIN_SCRIPT_DIR) .. "/build/" .. _ACTION) .. fs.getPathSeperator()
local srcDir = fs.sanitize(fs.parentPath(_MAIN_SCRIPT_DIR) .. "/" .. proj.location .. "/src/test.hpp")
proj.post_build = { "xcopy \"" .. srcDir .. "\" \"" .. targetDir .. "\" /i /r /y /s /c" }

local srcDir = fs.sanitize(context.getProjectDir() .. "/src/target/")
proj.debug_args = { "--fpath=\"" .. srcDir .. "\"" }
return proj
end

Expand Down
57 changes: 57 additions & 0 deletions applications/reflection-experiments/src/code_gen/example.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once
#include "../runtime_reflection_containers/runtime_reflected_class.h"
#include "../runtime_reflection_containers/runtime_reflected_variable.h"
#include "../runtime_reflection_containers/runtime_reflected_function.h"

/* This is example of generated from this file:
namespace examle_namespace
{
class target_class
{
public:
int int_variable;

void void_function(int int_parameter);

class nested_class
{
public:
nested_class() : value(0) {}

void set_value(int v)
{
value = v;
}

int get_value() const
{
return value;
}

private:
int value;
};
private:
char char_variable;
};
}
*/

class example_file_generated
{
public:
void add_reflected_file()
{
// All defined types in this file should go in here.
static const runtime_reflected_class classes[2] = {
runtime_reflected_class(
rsl::dynamic_string::from_buffer("example_namespace::target_class"),
reflection_id(12875366372301390368, 31932944099034707, 15853025086180115556)),
runtime_reflected_class(
rsl::dynamic_string::from_buffer("example_namespace::target_class::nested_class"),
reflection_id(8627741348740311923, 10691473971882747459, 3168970719907517523))
};

for(auto reflected_class : classes) { context.add_type(&reflected_class); }
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
#include "reflection_code_generator.h"
#include "D:/MyProjects/reflection-experiments/applications/reflection-experiments/src/target/test.hpp"
#include <fstream>
#include <iostream>
#include <stdio.h>

#include "../runtime_reflection_containers/runtime_reflected_variable.h"

const rsl::dynamic_string reflection_code_generator::generate_variable(
[[maybe_unused]] runtime_reflected_variable parsed_variable)
{
/*
std::string pad = " ";
std::ostringstream out;

out << "rythe::reflection_containers::runtime_reflected_variable(\n";

const char* name = parsed_variable.get_name().data();
out << pad << "\"" << name << "\"\n";

const char* name_space = parsed_variable.get_namespace().data();
out << pad << "\"" << name_space << "\"\n";

switch(parsed_variable.get_access_modifier())
{
case reflection_properties::access_modifier::public_access:
out << pad << "reflection_properties::acess_modifier::public_access,\n";
break;
case reflection_properties::access_modifier::protected_access:
out << pad << "reflection_properties::acess_modifier::protected_access,\n";
break;
case reflection_properties::access_modifier::private_access:
out << pad << "reflection_properties::acess_modifier::private_access,\n";
break;
default:
out << pad << "reflection_properties::acess_modifier::public_access,\n";
break;
}

out << pad << (parsed_variable.get_is_static() ? "true" : "false") << ",\n";
out << pad << (parsed_variable.get_is_const() ? "true" : "false") << ",\n";
out << pad << (parsed_variable.get_is_array() ? "true" : "false") << ",\n";
out << pad << parsed_variable.get_array_size() << ",\n";

out << pad << parsed_variable.get_offset() << ",\n";
out << pad << parsed_variable.get_size() << ",\n";
out << pad << parsed_variable.get_alignment() << ",\n";

//const char* type_str = parsed_variable.get_type_id().get_type().data();
//out << pad << "reflection_id(rsl::dynamic_string::from_string_length(" << type_str << ")),\n";

const auto& attributes = parsed_variable.get_attributes();
out << pad << "rsl::dynamic_array<rsl::dynamic_string>{";
if(!attributes.empty()) { out << "\n"; }
for (int i = 0; i < attributes.size(); ++i) {
const char* attribute = attributes[i].data();
out << pad << " rsl::dynamic_string::from_buffer("
<< attribute << ", " << (attribute ? attributes.size() : 0) << ")";
if (i + 1 < attributes) out << ",";
out << "\n";
}

if(!attributes.empty()) { out << pad; }
out << "}\n";

out << " )";

std::string string = out.str();
return rsl::dynamic_string::from_buffer(string.c_str(), string.size());
*/
return {};
}

reflection_code_generator::reflection_code_generator() {}

reflection_code_generator::~reflection_code_generator() {}

void reflection_code_generator::generate_reflected_file(const compile_reflected_file& compile_file)
{
const rsl::string_view source_location = compile_file.get_source_location();
std::ofstream file(get_gen_source_file(source_location).data());
if(!file.is_open()) { std::cout << "Could not open file " << source_location.data() << " for writing.\n"; }

file << "#include \"runtime_reflected_variable.hpp\"\n";
file << "using namespace rythe::reflection_containers;\n\n";
file << "void generate_variable(rythe::reflection_containers::runtime_reflected_variable parsed_variable) {\n";
//file << " auto var = " << generate_variable(parsed_variable).data() << ";\n";
file << "}\n";
}

rsl::dynamic_string reflection_code_generator::get_gen_source_file(rsl::string_view source_location)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this function is only used in the reflection_code_generator and static, it might be better to leave this as an implementation detail function, so a global function in an anonymous namespace, or marked static so it gets internal linkage

{
if(source_location.size() >= 256)
{
std::cout << "source_path is too long\n";
return {};
}

char buffer[256];
std::memcpy(buffer, source_location.data(), source_location.size());
buffer[source_location.size()] = '\0';

char* lastSlash = std::strrchr(buffer, '/');
if(lastSlash != nullptr) { *lastSlash = '\0'; }

strcat_s(buffer, sizeof(buffer), "/generated");

return rsl::dynamic_string::from_buffer(buffer, std::strlen(buffer));
}


/*
rsl::dynamic_string reflection_code_generator::generate_variable(rythe::reflection_containers::runtime_reflected_variable parsed_variable) {

std::string pad = " ";
std::ostringstream out;

out << "rythe::reflection_containers::runtime_reflected_variable(\n";

const char* name = parsed_variable.get_source_location().data();
out << pad << "\"" << name << "\"\n";

const char* name_space = parsed_variable.get_namespace().data();
out << pad << "\"" << name_space << "\"\n";

switch (parsed_variable.get_access_modifier()) {
case reflection_properties::acess_modifier::public_access:
out << pad << "reflection_properties::acess_modifier::public_access,\n"; break;
case reflection_properties::acess_modifier::protected_access:
out << pad << "reflection_properties::acess_modifier::protected_access,\n"; break;
case reflection_properties::acess_modifier::private_access:
out << pad << "reflection_properties::acess_modifier::private_access,\n"; break;
default:
out << pad << "reflection_properties::acess_modifier::public_access,\n"; break;
}

out << pad << (parsed_variable.get_is_static() ? "true" : "false") << ",\n";
out << pad << (parsed_variable.get_is_const() ? "true" : "false") << ",\n";
out << pad << (parsed_variable.get_is_array() ? "true" : "false") << ",\n";
out << pad << parsed_variable.get_array_size() << ",\n";

out << pad << parsed_variable.get_offset() << ",\n";
out << pad << parsed_variable.get_size() << ",\n";
out << pad << parsed_variable.get_alignment() << ",\n";

const char* type_str = parsed_variable.get_type_id().get_type().data();
out << pad << "reflection_id(rsl::dynamic_string::from_buffer("
<< type_str << ", " << (type_str ? std::strlen(type_str) : 0) << ")),\n";

const auto& attributes = parsed_variable.get_attributes();
out << pad << "rsl::dynamic_array<rsl::dynamic_string>{";
if (!attributes.empty()) out << "\n";
for (int i = 0; i < attributes.size(); ++i) {
const char* attribute = attributes[i].data();
out << pad << " rsl::dynamic_string::from_buffer("
<< attribute << ", " << (attribute ? attributes.size() : 0) << ")";
if (i + 1 < attributes) out << ",";
out << "\n";
}
if (!attributes.empty()) out << pad;
out << "}\n";

out << " )";

std::string string = out.str();
return rsl::dynamic_string::from_buffer(string.c_str(), string.size());
}
*/

void reflection_code_generator::generate_reflected_variable_file(
const runtime_reflected_variable& parsed_variable,
const std::string& outFile)
{
std::cout << "reflection_code_generator::generate_reflected_variable_file\n";
std::ofstream file(outFile);
if(!file.is_open()) { std::cout << "Could not open file " << outFile << " for writing.\n"; }

file << "#include \"runtime_reflected_variable.hpp\"\n";
file << "using namespace rythe::reflection_containers;\n\n";
file << "void generate_variable(rythe::reflection_containers::runtime_reflected_variable parsed_variable) {\n";
file << " auto var = " << generate_variable(parsed_variable).data() << ";\n";
file << "}\n";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once
#include "../runtime_reflection_containers/runtime_reflected_variable.h"
#include <sstream>
#include <rsl/containers>
#include "../compiletime_reflection_containers/compile_reflected_file.h"

class reflection_code_generator
{
public:
const rsl::dynamic_string generate_variable(runtime_reflected_variable parsed_variable);

reflection_code_generator();
~reflection_code_generator();

void generate_reflected_variable_file(
const runtime_reflected_variable& parsed_variable,
const std::string& outFile);

void generate_reflected_file(const compile_reflected_file& file);
static rsl::dynamic_string get_gen_source_file(rsl::string_view source_location);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragme once

#include "compiletime_reflection_containers/compile_reflected_class.h"
#include "compiletime_reflection_containers/compile_reflected_file.h"
#include "reflection_id/reflection_id.h"
Loading