Skip to content

Commit

Permalink
docs(reflection): add nullable trait sample
Browse files Browse the repository at this point in the history
  • Loading branch information
roby2014 committed Nov 18, 2023
1 parent 206eb01 commit 1739a02
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
1 change: 1 addition & 0 deletions core/samples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
66 changes: 66 additions & 0 deletions core/samples/reflection/traits/nullable/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <cubos/core/log.hpp>

/// [MyEntity declaration]
#include <cubos/core/reflection/reflect.hpp>

struct MyEntity
{
CUBOS_REFLECT;
uint32_t idx;
uint32_t generation;
};
/// [MyEntity declaration]

/// [Reflection definition]
#include <cubos/core/reflection/traits/nullable.hpp>
#include <cubos/core/reflection/type.hpp>

// Since we're exposing fields of primitive types (uint32_t), its important to
// include the header which defines their reflection.
#include <cubos/core/reflection/external/primitives.hpp>

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<const MyEntity*>(instance);
return ent->idx == UINT32_MAX && ent->generation == UINT32_MAX;
},
[](void* instance) {
auto* ent = static_cast<MyEntity*>(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<MyEntity>();

// Check if MyEntity has the NullableTrait
CUBOS_ASSERT(entityType.has<NullableTrait>());

// Retrieve the NullableTrait for MyEntity
const auto& nullableTrait = entityType.get<NullableTrait>();

// 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]
19 changes: 19 additions & 0 deletions core/samples/reflection/traits/nullable/page.md
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 1739a02

Please sign in to comment.