From 1739a02c12ecfdbd59d34d749db7e42e58e94b22 Mon Sep 17 00:00:00 2001 From: roby2014 Date: Fri, 17 Nov 2023 11:09:02 +0000 Subject: [PATCH] docs(reflection): add nullable trait sample --- core/samples/CMakeLists.txt | 1 + .../reflection/traits/nullable/main.cpp | 66 +++++++++++++++++++ .../reflection/traits/nullable/page.md | 19 ++++++ 3 files changed, 86 insertions(+) create mode 100644 core/samples/reflection/traits/nullable/main.cpp create mode 100644 core/samples/reflection/traits/nullable/page.md diff --git a/core/samples/CMakeLists.txt b/core/samples/CMakeLists.txt index 843680df3..9c15d6153 100644 --- a/core/samples/CMakeLists.txt +++ b/core/samples/CMakeLists.txt @@ -33,6 +33,7 @@ make_sample(DIR "reflection/traits/fields") make_sample(DIR "reflection/traits/array") make_sample(DIR "reflection/traits/dictionary") make_sample(DIR "reflection/traits/string_conversion") +make_sample(DIR "reflection/traits/nullable") make_sample(DIR "data/fs/embedded_archive" SOURCES "embed.cpp") make_sample(DIR "data/fs/standard_archive") make_sample(DIR "data/ser/custom") diff --git a/core/samples/reflection/traits/nullable/main.cpp b/core/samples/reflection/traits/nullable/main.cpp new file mode 100644 index 000000000..cdb5c7250 --- /dev/null +++ b/core/samples/reflection/traits/nullable/main.cpp @@ -0,0 +1,66 @@ +#include + +/// [MyEntity declaration] +#include + +struct MyEntity +{ + CUBOS_REFLECT; + uint32_t idx; + uint32_t generation; +}; +/// [MyEntity declaration] + +/// [Reflection definition] +#include +#include + +// Since we're exposing fields of primitive types (uint32_t), its important to +// include the header which defines their reflection. +#include + +using cubos::core::reflection::NullableTrait; +using cubos::core::reflection::Type; + +CUBOS_REFLECT_IMPL(MyEntity) +{ + return Type::create("MyEntity") + .with(NullableTrait{[](const void* instance) { + const auto* ent = static_cast(instance); + return ent->idx == UINT32_MAX && ent->generation == UINT32_MAX; + }, + [](void* instance) { + auto* ent = static_cast(instance); + ent->idx = UINT32_MAX; + ent->generation = UINT32_MAX; + }}); +} +/// [Reflection definition] + +/// [Example usage] +int main() +{ + using cubos::core::reflection::reflect; + + // Retrieve the reflection information for MyEntity + const auto& entityType = reflect(); + + // Check if MyEntity has the NullableTrait + CUBOS_ASSERT(entityType.has()); + + // Retrieve the NullableTrait for MyEntity + const auto& nullableTrait = entityType.get(); + + // Create an instance of MyEntity + MyEntity ent{1, 1}; + + // Check if the instance is not null + CUBOS_ASSERT(!nullableTrait.isNull(&ent)); + + // Set the instance to the null state + nullableTrait.setToNull(&ent); + + // Check if the instance is now null + CUBOS_ASSERT(nullableTrait.isNull(&ent)); +} +/// [Example usage] diff --git a/core/samples/reflection/traits/nullable/page.md b/core/samples/reflection/traits/nullable/page.md new file mode 100644 index 000000000..a23e89b60 --- /dev/null +++ b/core/samples/reflection/traits/nullable/page.md @@ -0,0 +1,19 @@ +# Nullable Trait {#examples-core-reflection-traits-nullable} + +@brief Handling null type representation. + +The `NullableTrait` is a reflection trait designed to provide a mechanism for representing a null state for a specific type. This is particularly useful when working with types that are not literally null but can be conceptually treated as null in certain scenarios. + +Consider a scenario where you have a data structure, such as the `Entity` struct, which represents an entity with an `index` and a `generation`. In some cases, you may want to define a special state that indicates the absence of a valid entity instead of checking if both fields are `UINT32_MAX`. So, instead of using a separate boolean flag to represent this state, the `NullableTrait` allows you to define a custom condition for considering an instance of the type as "null". + +So, let's see how we can use this. First, we create a reflectable structure: + +@snippet reflection/traits/nullable/main.cpp MyEntity declaration + +In the reflection definition, we use the `NullableTrait` to define the conditions under which an instance of `MyEntity` is considered null, and also another to set it to null. + +@snippet reflection/traits/nullable/main.cpp Reflection definition + +Now, we can simply use it: + +@snippet reflection/traits/nullable/main.cpp Example usage