Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split quadrados-gen from quadrados #583

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions cmake/QuadradosGenerate.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ function(quadrados_generate target source_dir)

add_custom_command(
OUTPUT ${binary_dir}/${target}-components.cpp
COMMAND $<TARGET_FILE:quadrados> generate ${source_dir} ${binary_dir}/${target}-components.cpp
DEPENDS $<TARGET_FILE:quadrados> ${source_dir}
COMMAND $<TARGET_FILE:quadrados-gen> ${source_dir} ${binary_dir}/${target}-components.cpp
DEPENDS $<TARGET_FILE:quadrados-gen> ${source_dir}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)

Expand Down
104 changes: 0 additions & 104 deletions docs/pages/2_features/quadrados.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ contains the following commands:
used by CUBOS., `.grd` and `.pal`.
- `quadrados embed` - utility used to embed files directly into an executable
for use with the `EmbeddedArchive`.
- `quadrados generate` - generates component definition boilerplate code.

## Convert

Expand Down Expand Up @@ -165,106 +164,3 @@ It's also possible to embed a whole directory, in which case you will need to
use the `-r` flag. This will recursively embed all files in the directory.

Checkout the `embedded_archive` sample for a complete example.

## Generate

For a type to be usable as a component, it must satisfy the following
requirements:
- it must be (de)serializable, taking optionally some context necessary (such
as the mapping between `Entity`s and their IDs, or a function to read or
write handles).
- it must define a storage type, which will then be used to store the
component's data in the `World`.
- it must call the `CUBOS_REGISTER_COMPONENT` macro, passing the ID of the
component type, which associates the type with a unique ID.

This means that, before `quadrados generate`, component definitions looked like:

```cpp
struct MyComponent
{
int x;
float y;
std::string z;
};

// The serialization functions must be defined in this namespace.
namespace cubos::core::data
{
inline static void serialize(Serializer& s, const MyComponent& c, const char* name)
{
s.beginObject(name);
s.write(c.x);
s.write(c.y);
s.write(c.z);
s.endObject();
}

inline static void deserialize(Deserializer& d, MyComponent& c)
{
d.beginObject();
d.read(c.x);
d.read(c.y);
d.read(c.z);
d.endObject();
}
}

// The storage type must be defined in this namespace.
namespace cubos::core::ecs
{
template <>
struct ComponentStorage<MyComponent>
{
using Type = VecStorage<MyComponent>;
};
}

CUBOS_REGISTER_COMPONENT(MyComponent, "my_component");
```

This amount of boilerplate is not acceptable, specially for user-facing code.
The `quadrados generate` command makes use of a recent C++ feature called
[attributes](https://en.cppreference.com/w/cpp/language/attributes). Attributes
are usually used to provide hints to the compiler. However, on our case, we're
using them to mark types as components.

With `quadrados generate`, the same component definition can be written as:

```cpp
// Must be included in the file where the component is defined.
#include <components/base.hpp>

struct [[cubos::component("my_component", VecStorage)]] MyComponent
{
int x;
float y;
std::string z;
};
```

This tool then searches for all types marked with the `cubos::component` and
generates a header file for each one. In this case, a header file would be
generated which could be included with `#include <components/my_component.hpp>`.

When using the component, the user must include the generated header file, and
not the original one. Otherwise, the compiler won't see the generated code.

If the component is identified with a slash, as, for example,
`game/my_component`, the generated header file will be placed in the
`components/game` directory. This is useful for organizing components into
different modules. For example, `cubos-engine` names all its components with the
`cubos/` directory.

### CMake

This tool can be configured to run automatically when building the project. To
do this, you can include the `QuadradosGenerate` module in your `CMakeLists.txt`
and call the `quadrados_generate` function with your target and the directory
where the base component headers are located.

```cmake
include(QuadradosGenerate)

quadrados_generate(my_target ${CMAKE_CURRENT_SOURCE_DIR}/components)
```
3 changes: 2 additions & 1 deletion tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
# Cubos tools build configuration

add_subdirectory(quadrados)
add_subdirectory(tesseratos)
add_subdirectory(quadrados-gen)
add_subdirectory(tesseratos)
6 changes: 6 additions & 0 deletions tools/quadrados-gen/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# tools/quadrados-gen/CMakeLists.txt
# Quadrados generate build configuration

add_executable(quadrados-gen "src/main.cpp")
target_link_libraries(quadrados-gen PUBLIC cubos-core)
cubos_common_target_options(quadrados-gen)
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
#include <utility>
#include <vector>

#include "tools.hpp"

namespace fs = std::filesystem;

/// The input options of the program.
Expand All @@ -31,7 +29,7 @@
/// Prints the help message of the program.
static void printHelp()
{
std::cerr << "Usage: quadrados generate <INPUT> <OUTPUT>" << std::endl;
std::cerr << "Usage: quadrados-gen <INPUT> <OUTPUT>" << std::endl;

Check warning on line 32 in tools/quadrados-gen/src/main.cpp

View check run for this annotation

Codecov / codecov/patch

tools/quadrados-gen/src/main.cpp#L32

Added line #L32 was not covered by tests
std::cerr << "Options:" << std::endl;
std::cerr << " -h Prints this help message." << std::endl;
}
Expand Down Expand Up @@ -790,7 +788,7 @@
return false;
}

file << "/// This file was generated by quadrados generate." << std::endl;
file << "/// This file was generated by quadrados-gen." << std::endl;

Check warning on line 791 in tools/quadrados-gen/src/main.cpp

View check run for this annotation

Codecov / codecov/patch

tools/quadrados-gen/src/main.cpp#L791

Added line #L791 was not covered by tests
file << "/// Do not edit this file." << std::endl;
file << std::endl;
file << "#include <cubos/core/ecs/registry.hpp>" << std::endl;
Expand Down Expand Up @@ -892,11 +890,11 @@
return true;
}

int runGenerate(int argc, char** argv)
int main(int argc, char** argv)

Check warning on line 893 in tools/quadrados-gen/src/main.cpp

View check run for this annotation

Codecov / codecov/patch

tools/quadrados-gen/src/main.cpp#L893

Added line #L893 was not covered by tests
{
// Parse command line arguments.
GenerateOptions options = {};
if (!parseArguments(argc, argv, options))
if (!parseArguments(argc - 1, argv + 1, options))

Check warning on line 897 in tools/quadrados-gen/src/main.cpp

View check run for this annotation

Codecov / codecov/patch

tools/quadrados-gen/src/main.cpp#L897

Added line #L897 was not covered by tests
{
printHelp();
return 1;
Expand Down
5 changes: 1 addition & 4 deletions tools/quadrados/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ set(QUADRADOS_SOURCE
"src/entry.cpp"
"src/embed.cpp"
"src/convert.cpp"
"src/generate.cpp"
)

add_executable(quadrados ${QUADRADOS_SOURCE})
set_property(TARGET quadrados PROPERTY CXX_STANDARD 20)
target_compile_features(quadrados PUBLIC cxx_std_20)
target_link_libraries(quadrados PUBLIC cubos-core)
target_link_libraries(quadrados PUBLIC cubos-engine)
cubos_common_target_options(quadrados)
2 changes: 0 additions & 2 deletions tools/quadrados/src/tools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ struct Tool
int runHelp(int argc, char** argv);
int runEmbed(int argc, char** argv);
int runConvert(int argc, char** argv);
int runGenerate(int argc, char** argv);

static const Tool Tools[] = {
{"help", runHelp},
{"embed", runEmbed},
{"convert", runConvert},
{"generate", runGenerate},
};
Loading