id interface
Signed-off-by: Folling <mail@folling.io>
This commit is contained in:
parent
b0a31a2140
commit
d43fe3e0b4
4 changed files with 85 additions and 19 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
using std::size_t;
|
using std::size_t;
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
|
#include <ikarus/stdtypes.h>
|
||||||
|
|
||||||
IKARUS_BEGIN_HEADER
|
IKARUS_BEGIN_HEADER
|
||||||
|
|
||||||
#include <ikarus/stdtypes.h>
|
|
||||||
#include <ikarus/types/object_type.h>
|
#include <ikarus/types/object_type.h>
|
||||||
|
|
||||||
/// \defgroup id Ids
|
/// \defgroup id Ids
|
||||||
|
|
@ -21,11 +21,13 @@ IKARUS_BEGIN_HEADER
|
||||||
|
|
||||||
/// \brief A wrapper around a 64 bit integer that represents the id of an object.
|
/// \brief A wrapper around a 64 bit integer that represents the id of an object.
|
||||||
/// \details They are stored as 64 bit integers with the following layout:
|
/// \details They are stored as 64 bit integers with the following layout:
|
||||||
/// - first 8 bits: #IkarusObjectType - 255 possible values, 0 for special values
|
/// - first bit: ignored, technically we could use it, but SQLite doesn't support u64 integers.
|
||||||
|
/// To avoid ordering fiascos and potential index performance degradation we just skip the first bit.
|
||||||
|
/// - next 7 bits: #IkarusObjectType - 127 possible values, 0 for special values
|
||||||
/// - last 56 bits: incremented counter generated by the database
|
/// - last 56 bits: incremented counter generated by the database
|
||||||
struct IkarusId {
|
struct IkarusId {
|
||||||
/// \private \brief The value of the id.
|
/// \private \brief The value of the id.
|
||||||
uint64_t value;
|
int64_t data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief A special id returned by failed functions.
|
/// \brief A special id returned by failed functions.
|
||||||
|
|
@ -34,9 +36,16 @@ IkarusId const IKARUS_ID_NONE{0};
|
||||||
IkarusId const IKARUS_ID_UNSPECIFIED{1};
|
IkarusId const IKARUS_ID_UNSPECIFIED{1};
|
||||||
|
|
||||||
/// \private \brief Generates a new id for the given object type.
|
/// \private \brief Generates a new id for the given object type.
|
||||||
/// \param object_type The type of the object to generate an id for.
|
/// \param data The data from which the id will be constructed.
|
||||||
/// \return The generated id.
|
/// \return The generated id.
|
||||||
IkarusId ikarus_id_from_integer(IkarusObjectType object_type);
|
/// \pre data must be valid under the format described in Id. It should also point to an object in the database.
|
||||||
|
IkarusId ikarus_id_from_data(int64_t data);
|
||||||
|
|
||||||
|
/// \brief Checkes whether two ids are equal
|
||||||
|
/// \param left the left side of the comparison
|
||||||
|
/// \param right the right side of the comparison
|
||||||
|
/// \return True if the bits from the left id are equal to the bits of the right id
|
||||||
|
bool ikarus_id_is_equal(IkarusId left, IkarusId right);
|
||||||
|
|
||||||
/// \brief Fetches the object type of the given id.
|
/// \brief Fetches the object type of the given id.
|
||||||
/// \param id The id to fetch the object type for.
|
/// \param id The id to fetch the object type for.
|
||||||
|
|
|
||||||
|
|
@ -25,37 +25,37 @@ enum IkarusFolderType {
|
||||||
/// \remark folders have the first bit set and then mirror the object type of the underlying object
|
/// \remark folders have the first bit set and then mirror the object type of the underlying object
|
||||||
enum IkarusObjectType {
|
enum IkarusObjectType {
|
||||||
/// \brief Not an object or no object.
|
/// \brief Not an object or no object.
|
||||||
ObjectType_None = 0,
|
IkarusObjectType_None = 0,
|
||||||
/// \brief An IkarusBlueprint.
|
/// \brief An IkarusBlueprint.
|
||||||
ObjectType_Blueprint = 0b0000'0001,
|
IkarusObjectType_Blueprint = 0b0000'0001,
|
||||||
/// \brief An IkarusProperty.
|
/// \brief An IkarusProperty.
|
||||||
ObjectType_Property = 0b0000'0010,
|
IkarusObjectType_Property = 0b0000'0010,
|
||||||
/// \brief An IkarusEntity.
|
/// \brief An IkarusEntity.
|
||||||
ObjectType_Entity = 0b0000'0011,
|
IkarusObjectType_Entity = 0b0000'0011,
|
||||||
/// \brief An IkarusBlueprintFolder
|
/// \brief An IkarusBlueprintFolder
|
||||||
ObjectType_BlueprintFolder = 0b1000'0001,
|
IkarusObjectType_BlueprintFolder = 0b1000'0001,
|
||||||
/// \brief An IkarusPropertyFolder
|
/// \brief An IkarusPropertyFolder
|
||||||
ObjectType_PropertyFolder = 0b1000'0010,
|
IkarusObjectType_PropertyFolder = 0b1000'0010,
|
||||||
/// \brief An IkarusEntityFolder
|
/// \brief An IkarusEntityFolder
|
||||||
ObjectType_EntityFolder = 0b1000'0011,
|
IkarusObjectType_EntityFolder = 0b1000'0011,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief A bitset of IkarusObjectType%s.
|
/// \brief A bitset of IkarusObjectType%s.
|
||||||
enum ObjectTypes {
|
enum ObjectTypes {
|
||||||
/// \brief No object type.
|
/// \brief No object type.
|
||||||
ObjectTypes_None = 0,
|
IkarusObjectTypes_None = 0,
|
||||||
/// \brief An IkarusBlueprint.
|
/// \brief An IkarusBlueprint.
|
||||||
ObjectTypes_Blueprint = 1 << ObjectType_Blueprint,
|
IkarusObjectTypes_Blueprint = 1 << IkarusObjectType_Blueprint,
|
||||||
/// \brief An IkarusProperty.
|
/// \brief An IkarusProperty.
|
||||||
ObjectTypes_Property = 1 << ObjectType_Property,
|
IkarusObjectTypes_Property = 1 << IkarusObjectType_Property,
|
||||||
/// \brief An IkarusEntity.
|
/// \brief An IkarusEntity.
|
||||||
ObjectTypes_Entity = 1 << ObjectType_Entity,
|
IkarusObjectTypes_Entity = 1 << IkarusObjectType_Entity,
|
||||||
/// \brief An IkarusBlueprintFolder
|
/// \brief An IkarusBlueprintFolder
|
||||||
ObjectTypes_BlueprintFolder = 1 << ObjectType_BlueprintFolder,
|
IkarusObjectTypes_BlueprintFolder = 1 << IkarusObjectType_BlueprintFolder,
|
||||||
/// \brief An IkarusPropertyFolder
|
/// \brief An IkarusPropertyFolder
|
||||||
ObjectTypes_PropertyFolder = 1 << ObjectType_PropertyFolder,
|
IkarusObjectTypes_PropertyFolder = 1 << IkarusObjectType_PropertyFolder,
|
||||||
/// \brief An IkarusEntityFolder
|
/// \brief An IkarusEntityFolder
|
||||||
ObjectTypes_EntityFolder = 1 << ObjectType_EntityFolder,
|
IkarusObjectTypes_EntityFolder = 1 << IkarusObjectType_EntityFolder,
|
||||||
};
|
};
|
||||||
|
|
||||||
// @}
|
// @}
|
||||||
|
|
|
||||||
56
src/types/id.cpp
Normal file
56
src/types/id.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include "ikarus/types/id.h"
|
||||||
|
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
IkarusId ikarus_id_from_data(int64_t data) {
|
||||||
|
return IkarusId {
|
||||||
|
.data = data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
IkarusObjectType ikarus_id_get_object_type(IkarusId id) {
|
||||||
|
return static_cast<IkarusObjectType>(id.data >> 56);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ikarus_id_is_equal(IkarusId left, IkarusId right) {
|
||||||
|
return left.data == right.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ikarus_id_is_none(IkarusId id) {
|
||||||
|
return ikarus_id_is_equal(id, IKARUS_ID_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ikarus_id_is_unspecified(IkarusId id) {
|
||||||
|
return ikarus_id_is_equal(id, IKARUS_ID_UNSPECIFIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("id_object_type", "[id]") {
|
||||||
|
auto id = ikarus_id_from_data(static_cast<uint64_t>(IkarusObjectType_Blueprint) << 56);
|
||||||
|
|
||||||
|
REQUIRE(ikarus_id_get_object_type(id) == IkarusObjectType_Blueprint);
|
||||||
|
REQUIRE(!ikarus_id_is_none(id) == IkarusObjectType_Blueprint);
|
||||||
|
REQUIRE(!ikarus_id_is_unspecified(id) == IkarusObjectType_Blueprint);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("id_equal", "[id]") {
|
||||||
|
auto id = ikarus_id_from_data(static_cast<uint64_t>(IkarusObjectType_Blueprint) << 56);
|
||||||
|
auto copy = id;
|
||||||
|
auto third = ikarus_id_from_data(static_cast<uint64_t>(IkarusObjectType_Property) << 56);
|
||||||
|
|
||||||
|
REQUIRE(ikarus_id_is_equal(id, copy));
|
||||||
|
REQUIRE(!ikarus_id_is_equal(id, third));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("id_none", "[id]") {
|
||||||
|
auto id = IKARUS_ID_NONE;
|
||||||
|
|
||||||
|
REQUIRE(ikarus_id_is_none(id));
|
||||||
|
REQUIRE(!ikarus_id_is_unspecified(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("id_unspecified", "[id]") {
|
||||||
|
auto id = IKARUS_ID_UNSPECIFIED;
|
||||||
|
|
||||||
|
REQUIRE(!ikarus_id_is_none(id));
|
||||||
|
REQUIRE(ikarus_id_is_unspecified(id));
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue