restructure into smaller files & add IWYU/clang-tidy

Signed-off-by: Folling <mail@folling.io>
This commit is contained in:
folling 2023-08-29 14:12:08 +02:00 committed by Folling
parent 660736133a
commit 13eee8b168
Signed by: folling
SSH key fingerprint: SHA256:S9qEx5WCFFLK49tE/LKnKuJYM5sw+++Dn6qJbbyxnCY
28 changed files with 845 additions and 556 deletions

View file

@ -0,0 +1,22 @@
#pragma once
/// \file blueprint_folder.h
/// \author Folling <mail@folling.io>
#include <ikarus/id.h>
#include <ikarus/macros.h>
/// \addtogroup folder Folders
/// @{
IKARUS_BEGIN_HEADER
/// \brief A blueprint folder, storing blueprints and other blueprint folders.
struct IkarusBlueprintFolder {
/// \private \brief The id of the blueprint folder.
IkarusId id;
};
IKARUS_END_HEADER
// @}

View file

@ -0,0 +1,22 @@
#pragma once
/// \file entity_folder.h
/// \author Folling <mail@folling.io>
#include <ikarus/id.h>
#include <ikarus/macros.h>
/// \addtogroup folder Folders
/// @{
IKARUS_BEGIN_HEADER
/// \brief A entity folder, storing entities and other entity folders.
struct IkarusEntityFolder {
/// \private \brief The id of the entity folder.
IkarusId id;
};
IKARUS_END_HEADER
// @}

View file

@ -0,0 +1,76 @@
#pragma once
/// \file folder.h
/// \author Folling <mail@folling.io>
#include <ikarus/folders/blueprint_folder.h>
#include <ikarus/folders/entity_folder.h>
#include <ikarus/folders/folder_type.h>
#include <ikarus/folders/property_folder.h>
#include <ikarus/macros.h>
IKARUS_BEGIN_HEADER
/// \defgroup folder Folders
/// \brief Folders are used to group objects together.
/// @{
/// \private \brief The data of a folder.
union IkarusFolderData {
/// \private \brief The blueprint folder data of the folder.
IkarusBlueprintFolder blueprint_folder;
/// \private \brief The property folder data of the folder.
IkarusPropertyFolder property_folder;
/// \private \brief The entity folder data of the folder.
IkarusEntityFolder entity_folder;
};
/// \brief A generic folder. Similar to how Objects wrap all types of objects, Folders wrap all types of folders.
struct IkarusFolder {
/// \private \brief The data of the folder.
IkarusFolderData data;
/// \private \brief The type of the folder.
IkarusFolderType type;
};
/// \brief Constructs a folder from a blueprint folder.
/// \param blueprint_folder The blueprint folder to construct the folder from.
/// \return The constructed folder.
IKA_API IkarusFolder ikarus_folder_from_blueprint_folder(IkarusBlueprintFolder blueprint_folder);
/// \brief Constructs a folder from a property folder.
/// \param property_folder The property folder to construct the folder from.
/// \return The constructed folder.
IKA_API IkarusFolder ikarus_folder_from_property_folder(IkarusPropertyFolder property_folder);
/// \brief Constructs a folder from an entity folder.
/// \param entity_folder The entity folder to construct the folder from.
/// \return The constructed folder.
IKA_API IkarusFolder ikarus_folder_from_entity_folder(IkarusEntityFolder entity_folder);
/// \brief Fetches the folder type of a folder.
/// \param folder The folder to fetch the type of.
/// \return The type of the folder.
IKA_API IkarusFolderType ikarus_folder_get_type(IkarusFolder folder);
/// \brief Checks if two folders are equal.
/// \details Since ids store the type of the object, this boils down to a simple comparison of the ids.
/// \param left The left side of the comparison.
/// \param right The right side of the comparison.
/// \return True if the folders are equal, false otherwise
IKA_API bool ikarus_folder_is_equal(IkarusFolder left, IkarusFolder right);
/// \brief Visits a folder. Calling the appropriate function for the folder's type.
/// \param folder The folder to visit.
/// \param blueprint The function to call if the folder is a blueprint folder.
/// \param property The function to call if the folder is a property folder.
/// \param entity The function to call if the folder is an entity folder.
/// \param data The data to pass to the functions.
IKA_API void ikarus_folder_visit(
IkarusFolder folder,
void (*blueprint)(IkarusBlueprintFolder, void *),
void (*property)(IkarusPropertyFolder, void *),
void (*entity)(IkarusEntityFolder, void *),
void * data
);
IKARUS_END_HEADER

View file

@ -0,0 +1,26 @@
#pragma once
// IMPLEMENTATION_DETAIL_FOLDER_TYPES
/// \file folder_type.h
/// \author Folling <mail@folling.io>
#include <ikarus/macros.h>
/// \addtogroup folder folders
/// @{
/// \brief The type of an folder.
/// \remark Folders have the 8th bit set.
enum IkarusFolderType {
/// \brief Not a folder or no folder.
IkarusFolderType_None = 0,
/// \brief An IkarusBlueprintFolder
IkarusFolderType_BlueprintFolder = 0b1000'0001,
/// \brief An IkarusPropertyFolder
IkarusFolderType_PropertyFolder = 0b1000'0010,
/// \brief An IkarusEntityFolder
IkarusFolderType_EntityFolder = 0b1000'0011,
};
/// @}

View file

@ -0,0 +1,23 @@
#pragma once
#include <ikarus/id.h>
#include <ikarus/macros.h>
/// \file property_folder.h
/// \author Folling <mail@folling.io>
/// \addtogroup folder Folders
/// @{
IKARUS_BEGIN_HEADER
/// \brief A property folder, storing properties and other property folders.
/// \remark Property folders are scoped to the blueprint or entity they are associated with.
struct IkarusPropertyFolder {
/// \private \brief The id of the property folder.
IkarusId id;
};
IKARUS_END_HEADER
// @}

View file

@ -6,12 +6,11 @@
#pragma once
#include <ikarus/macros.h>
#include <ikarus/objects/object_type.h>
#include <ikarus/stdtypes.h>
IKARUS_BEGIN_HEADER
#include <ikarus/types/object_type.h>
/// \defgroup id Ids
/// \brief Ids are used to identify objects in the database.
/// \details They are stored as 64 bit integers with the following layout:
@ -64,4 +63,4 @@ IKA_API bool ikarus_id_is_unspecified(IkarusId id);
/// @}
IKARUS_END_HEADER
IKARUS_END_HEADER

View file

@ -0,0 +1,24 @@
#pragma once
/// \file blueprint.h
/// \author Folling <mail@folling.io>
#include <ikarus/id.h>
#include <ikarus/macros.h>
/// \defgroup blueprints Blueprints
/// \brief Blueprints are templates for entities.
IKARUS_BEGIN_HEADER
/// \brief A blueprint object.
/// \details A blueprint is a collection of properties which can be linked to entities.
/// Each entity the blueprint is linked to will have values for the blueprints properties.
struct IkarusBlueprint {
/// \private \brief The id of the blueprint.
IkarusId id;
};
IKARUS_END_HEADER
// @}

View file

@ -0,0 +1,41 @@
#pragma once
#include <ikarus/id.h>
#include <ikarus/macros.h>
/// \file entity.h
/// \author Folling <mail@folling.io>
/// \defgroup entities Entities
/// \brief Entities are the core building blocks of Ikarus.
IKARUS_BEGIN_HEADER
/// \brief Entities are the core building blocks of Ikarus.
/// \detials Blueprints and Properties define the structure of the data.
/// Entities define the data itself.
///
/// Properties can be associated with Entities in two ways:
/// - Directly: The property is linked to the entity.
/// - Indirectly: The property is linked to a blueprint of the entity.
///
/// For each property an entity is linked to, it has a value. These values depend on the property's type.
/// For more information on the types see the property documentation.
///
/// Values are the core type of data within Ikarus.
/// Each value is associated with one page and one property.
///
/// \remark Values are typed, the type of a value is specified by its associated property.
/// For more information on the types see the property documentation.
///
/// \remark Values are guaranteed to be in valid format for a given type
/// but not guaranteed to be valid under the settings of the property.
/// This is because changing the settings can invalidate existing values without resetting them.
struct IkarusEntity {
/// \private \brief The ID of the entity.
IkarusId id;
};
IKARUS_END_HEADER
// @}

View file

@ -0,0 +1,123 @@
#pragma once
/// \file object.h
/// \author Folling <mail@folling.io>
#include <ikarus/folders/blueprint_folder.h>
#include <ikarus/folders/entity_folder.h>
#include <ikarus/folders/property_folder.h>
#include <ikarus/macros.h>
#include <ikarus/objects/blueprint.h>
#include <ikarus/objects/entity.h>
#include <ikarus/objects/object_type.h>
#include <ikarus/objects/property.h>
/// \defgroup object Objects
/// \brief Objects are a compound type of all types of objects in the database.
/// \details The following objects currently exist:
/// - blueprints
/// - properties
/// - entities
/// - blueprint folders
/// - property folders
/// - entity folders
/// @{
IKARUS_BEGIN_HEADER
struct IkarusFolder;
/// \private \brief The data of an object.
union IkarusObjectData {
/// \private \brief The blueprint data of the object.
IkarusBlueprint blueprint;
/// \private \brief The property data of the object.
IkarusProperty property;
/// \private \brief The entity data of the object.
IkarusEntity entity;
/// \private \brief The blueprint folder data of the object.
IkarusBlueprintFolder blueprint_folder;
/// \private \brief The property folder data of the object.
IkarusPropertyFolder property_folder;
/// \private \brief The entity folder data of the object.
IkarusEntityFolder entity_folder;
};
/// \brief A generic object. Wraps all types of objects, including folders.
struct IkarusObject {
/// \private \brief The type of the object.
IkarusObjectType type;
/// \private \brief The data of the object.
IkarusObjectData data;
};
/// \brief Constructs an object from a blueprint.
/// \param blueprint The blueprint to construct the object from.
/// \return The constructed object, representing the blueprint.
IKA_API IkarusObject ikarus_object_from_blueprint(IkarusBlueprint blueprint);
/// \brief Constructs an object from a property.
/// \param property The property to construct the object from.
/// \return The constructed object, representing the property.
IKA_API IkarusObject ikarus_object_from_property(IkarusProperty property);
/// \brief Constructs an object from an entity.
/// \param entity The entity to construct the object from.
/// \return The constructed object, representing the entity.
IKA_API IkarusObject ikarus_object_from_entity(IkarusEntity entity);
/// \brief Constructs an object from a blueprint folder.
/// \param blueprint The folder to construct the object from.
/// \return The constructed object, representing the folder.
IKA_API IkarusObject ikarus_object_from_blueprint_folder(IkarusBlueprintFolder folder);
/// \brief Constructs an object from a property folder.
/// \param property The folder to construct the object from.
/// \return The constructed object, representing the folder.
IKA_API IkarusObject ikarus_object_from_property_folder(IkarusPropertyFolder folder);
/// \brief Constructs an object from a entity folder.
/// \param entity The folder to construct the object from.
/// \return The constructed object, representing the folder.
IKA_API IkarusObject ikarus_object_from_entity_folder(IkarusEntityFolder folder);
/// \brief Constructs an object from a folder.
/// \param folder The folder to construct the object from.
/// \return The constructed object, representing the folder.
IKA_API IkarusObject ikarus_object_from_folder(IkarusFolder folder);
/// \brief Compares two objects for equality.
/// \details Since ids store the type of the object, this boils down to a simple comparison of the ids.
/// \param left The left side of the comparison.
/// \param right The right side of the comparison.
/// \return Whether the objects are equal.
IKA_API bool ikarus_object_is_equal(IkarusObject left, IkarusObject right);
/// \brief Fetches the type of an object.
/// \param object The object to fetch the type of.
/// \return The type of the object.
IKA_API IkarusObjectType ikarus_object_get_type(IkarusObject object);
/// \brief Visits an object. Calling the appropriate function for the object's type.
/// \param object The object to visit.
/// \param blueprint The function to call if the object is a blueprint.
/// \param property The function to call if the object is a property.
/// \param entity The function to call if the object is an entity.
/// \param blueprint_folder The function to call if the object is a blueprint folder.
/// \param property_folder The function to call if the object is a property folder.
/// \param entity_folder The function to call if the object is an entity folder.
/// \param data The data to pass to the functions.
IKA_API void ikarus_object_visit(
IkarusObject object,
void (*visit_blueprint)(IkarusBlueprint, void *),
void (*visit_property)(IkarusProperty, void *),
void (*visit_entity)(IkarusEntity, void *),
void (*visit_blueprint_folder)(IkarusBlueprintFolder, void *),
void (*visit_property_folder)(IkarusPropertyFolder, void *),
void (*visit_entity_folder)(IkarusEntityFolder, void *),
void * data
);
IKARUS_END_HEADER
// @}

View file

@ -0,0 +1,38 @@
#pragma once
// IMPLEMENTATION_DETAIL_OBJECT_TYPES
/// \file object.h
/// \author Folling <mail@folling.io>
#include <ikarus/folders/folder_type.h>
#include <ikarus/macros.h>
/// \addtogroup object Objects
/// @{
/// \brief The type of an object.
/// \remark Folders have the 4th bit set.
enum IkarusObjectType {
/// \brief Not an object or no object.
IkarusObjectType_None = 0,
/// \brief An IkarusBlueprint.
IkarusObjectType_Blueprint = 1,
/// \brief An IkarusProperty.
IkarusObjectType_Property = 2,
/// \brief An IkarusEntity.
IkarusObjectType_Entity = 3,
/// \brief An IkarusBlueprintFolder
IkarusObjectType_BlueprintFolder = IkarusFolderType_BlueprintFolder,
/// \brief An IkarusPropertyFolder
IkarusObjectType_PropertyFolder = IkarusFolderType_PropertyFolder,
/// \brief An IkarusEntityFolder
IkarusObjectType_EntityFolder = IkarusFolderType_EntityFolder,
};
/// \brief Constructs an IkarusObjectType from an IkarusFolderType.
/// \param type The IkarusFolderType of which to construct the IkarusObjectType from.
/// \return The constructed IkarusObjectType, representing the folder type.
IKA_API IkarusObjectType ikarus_object_type_from_folder_type(IkarusFolderType type);
/// @}

View file

@ -0,0 +1,73 @@
#pragma once
// IMPLEMENTATION_DETAIL_LAZY_VALUE_CREATION, IMPLEMENTATION_DETAIL_PROPERTY_TYPES
/// \file property.h
/// \author Folling <mail@folling.io>
#include <ikarus/id.h>
#include <ikarus/macros.h>
#include <ikarus/objects/blueprint.h>
#include <ikarus/objects/entity.h>
/// \defgroup properties Properties
/// \brief Properties define the structure and types of data.
IKARUS_BEGIN_HEADER
/// \brief Properties are the placeholders of values for entities.
/// \details Each entity can have any number of properties.
/// Every property has a type that identifies the kind of data that can be put in.
///
/// The following types currently exist:
/// - Toggle: A true/false boolean-like value
/// - Number: An arbitrary numeric value
/// - Text: An arbitrary textual value
///
/// Property Examples:
/// - Is Dead (Toggle)
/// - Age (Number)
/// - ISBN (Text)
///
/// Every property has settings which can be used to customise the property further.
/// Two settings that are shared among all properties are the following:
/// - Multiple
/// - Allow undefined
///
/// The former transforms a property into a list. Instead of one number, you could then specify a series of numbers.
/// The latter allows you to specify an "unknown" value for a property.
/// It might not be known if a character is dead or not for example.
///
/// Each entity associated with the property has a value for it.
///
/// Properties can also be added to blueprints in which case they are available for all entities associated with the
/// blueprint.
///
/// We call properties within entities "Entity Properties" and properties within blueprints "Blueprint Properties".
///
/// \remark Properties are scoped to the blueprint or entity they are associated with.
/// \remark Values for properties are lazily created as space saving measure.
/// Fetching the value for some property of some entity will return the property's default value if none is specified.
/// This default value is specified when the property is created and can be updated later.
/// \remark Properties' tree structures are scoped to the entity or blueprint they are associated with.
struct IkarusProperty {
/// \private \brief The id of the property.
IkarusId id;
};
/// \brief The type of a property.
/// \details Designates the type of data stored by the property as well as which settings are
/// available.
/// \see IkarusPropertySettings
enum IkarusPropertyType {
/// \brief A true/false boolean-like value.
IkarusPropertyType_Toggle,
/// \brief An arbitrary numeric value.
IkarusPropertyType_Number,
/// \brief An arbitrary textual value.
IkarusPropertyType_Text,
};
IKARUS_END_HEADER
// @}

View file

@ -2,7 +2,7 @@
// IMPLEMENTATION_DETAIL_PROPERTY_TYPES
/// \file id.h
/// \file property_type.h
/// \author Folling <mail@folling.io>
#include <ikarus/macros.h>

View file

@ -0,0 +1,26 @@
#pragma once
/// \file blueprint_scope.h
/// \author Folling <mail@folling.io>
#include <ikarus/id.h>
#include <ikarus/macros.h>
/// \addtogroup object_scopes ObjectScopes
/// @{
IKARUS_BEGIN_HEADER
/// \brief The global scope of all blueprints.
struct IkarusBlueprintScope {
/// \private \brief Empty structs aren't allowed in C, so we need a dummy field.
short _dummy;
};
/// \brief Creates a blueprint scope.
/// \return The created blueprint scope.
IKA_API IkarusBlueprintScope ikarus_blueprint_scope_create();
IKARUS_END_HEADER
// @}

View file

@ -0,0 +1,26 @@
#pragma once
/// \file entity_scope.h
/// \author Folling <mail@folling.io>
#include <ikarus/id.h>
#include <ikarus/macros.h>
/// \addtogroup object_scopes ObjectScopes
/// @{
IKARUS_BEGIN_HEADER
/// \brief The global scope of all entities.
struct IkarusEntityScope {
/// \private \brief Empty structs aren't allowed in C, so we need a dummy field.
short _dummy;
};
/// \brief Creates a entity scope.
/// \return The created entity scope.
IKA_API IkarusEntityScope ikarus_entity_scope_create();
IKARUS_END_HEADER
// @}

View file

@ -0,0 +1,84 @@
#pragma once
// IMPLEMENTATION_DETAIL_OBJECT_SCOPES
/// \file object_scope.h
/// \author Folling <mail@folling.io>
#include <ikarus/macros.h>
#include <ikarus/scopes/blueprint_scope.h>
#include <ikarus/scopes/entity_scope.h>
#include <ikarus/scopes/property_scope.h>
/// \defgroup object_scopes Object Scopes
/// \brief Scopes define where objects belong to.
/// \details They are required to differentiate between different types of objects with NULL as their parent.
/// @{
IKARUS_BEGIN_HEADER
/// \private \brief The data for an object scope.
union IkarusObjectScopeData {
/// \private \brief The blueprint data of the scope.
IkarusBlueprintScope _blueprint;
/// \private \brief The property data of the scope.
IkarusPropertyScope _property;
/// \private \brief The entity data of the scope.
IkarusEntityScope _entity;
};
/// The type of an object scope.
enum IkarusObjectScopeType {
/// \brief The scope is a blueprint scope.
IkarusObjectScopeType_Blueprint,
/// \brief The scope is a property scope.
IkarusObjectScopeType_Property,
/// \brief The scope is an entity scope.
IkarusObjectScopeType_Entity
};
/// \brief The scope of an object.
struct IkarusObjectScope {
/// \private \brief Represents the type of the scope.
IkarusObjectScopeType _type;
/// \private \brief Represents the data of the scope.
IkarusObjectScopeData _data;
};
/// \brief Converts a blueprint scope to an object scope.
/// \param scope The scope to convert.
/// \return The converted scope.
IKA_API IkarusObjectScope ikarus_blueprint_scope_to_object_scope(IkarusBlueprintScope scope);
/// \brief Converts a property scope to an object scope.
/// \param scope The scope to convert.
/// \return The converted scope.
IKA_API IkarusObjectScope ikarus_property_scope_to_object_scope(IkarusPropertyScope scope);
/// Converts an entity scope to an object scope.
/// \param scope The scope to convert.
/// \return The converted scope.
IKA_API IkarusObjectScope ikarus_entity_scope_to_object_scope(IkarusEntityScope scope);
/// \brief Fetches the type of an object scope.
/// \param scope The scope to fetch the type of.
/// \return The type of the scope.
IKA_API IkarusObjectScopeType ikarus_object_scope_get_type(IkarusObjectScope scope);
/// \brief Visits an object scope, calling the appropriate function.
/// \param scope The scope to visit.
/// \param blueprint The function to call if the scope is an #IkarusBlueprintScope.
/// \param property The function to call if the scope is an #IkarusPropertyScope.
/// \param entity The function to call if the scope is an #IkarusEntityScope.
/// \remark function pointers may be null in which case they are not called.
IKA_API void ikarus_object_scope_visit(
IkarusObjectScope scope,
void (*blueprint)(IkarusBlueprintScope, void *),
void (*property)(IkarusPropertyScope, void *),
void (*entity)(IkarusEntityScope, void *),
void * data
);
/// @}
IKARUS_END_HEADER

View file

@ -0,0 +1,65 @@
#pragma once
/// \file property_scope.h
/// \author Folling <mail@folling.io>
#include <ikarus/id.h>
#include <ikarus/macros.h>
#include <ikarus/objects/blueprint.h>
#include <ikarus/objects/entity.h>
/// \addtogroup object_scopes ObjectScopes
/// @{
IKARUS_BEGIN_HEADER
/// \brief Data for a property scope. This can either be a blueprint or an entity.
union IkarusPropertyScopeData {
/// \private \brief The blueprint the property is scoped to.
IkarusBlueprint _blueprint;
/// \private \brief The entity the property is scoped to.
IkarusEntity _entity;
};
/// \brief The type of a property scope. This can either be a blueprint or an entity.
enum IkarusPropertyScopeType {
/// \brief The property is scoped to a blueprint.
IkarusPropertyScopeType_Blueprint,
/// \brief The property is scoped to an entity.
IkarusPropertyScopeType_Entity
};
/// \brief The scope of a property
struct IkarusPropertyScope {
/// \private \brief Represents the type of the scope.
IkarusPropertyScopeType _type;
/// \private \brief Represents the data of the scope.
IkarusPropertyScopeData _data;
};
/// \brief Creates a property scope from a blueprint.
/// \param blueprint The blueprint the property is scoped to.
/// \return The created property scope.
IKA_API IkarusPropertyScope ikarus_property_scope_create_blueprint(IkarusBlueprint blueprint);
/// \brief Creates a property scope from a entity.
/// \param entity The entity the property is scoped to.
/// \return The created property scope.
IKA_API IkarusPropertyScope ikarus_property_scope_create_entity(IkarusEntity entity);
/// \brief Fetches the type of an property scope.
/// \param scope The scope to fetch the type of.
/// \return The type of the scope.
IKA_API IkarusPropertyScopeType ikarus_property_scope_get_type(IkarusPropertyScope scope);
/// \brief Visits a property scope, calling the appropriate function.
/// \param scope The scope to to visit
/// \param blueprint The function to call if the property is scoped to a blueprint.
/// \param entity The function to call if the property is scoped to an entity.
/// \param data Optional data to pass to the functions.
void ikarus_property_scope_visit(
IkarusPropertyScope scope, void (*blueprint)(IkarusBlueprint, void *), void (*entity)(IkarusEntity, void *), void * data
);
IKARUS_END_HEADER
// @}

View file

@ -1,164 +0,0 @@
#pragma once
// IMPLEMENTATION_DETAIL_OBJECT_TYPES
// IMPLEMENTATION_DETAIL_LAZY_VALUE_CREATION
// IMPLEMENTATION_DETAIL_PROPERTY_TYPES
/// \file id.h
/// \author Folling <mail@folling.io>
/// \defgroup object Objects
/// \brief Objects are a compound type of all types of objects in the database.
/// \details The following objects currently exist:
/// - blueprints
/// - properties
/// - entities
/// - blueprint folders
/// - property folders
/// - entity folders
/// @{
#include <ikarus/types/id.h>
IKARUS_BEGIN_HEADER
/// \brief A blueprint object.
/// \details A blueprint is a collection of properties which can be linked to entities.
/// Each entity the blueprint is linked to will have values for the blueprints properties.
struct IkarusBlueprint {
IkarusId id;
};
/// \brief Properties are the placeholders of values for entities.
/// \details Each entity can have any number of properties.
/// Every property has a type that identifies the kind of data that can be put in.
///
/// The following types currently exist:
/// - Toggle: A true/false boolean-like value
/// - Number: An arbitrary numeric value
/// - Text: An arbitrary textual value
///
/// Property Examples:
/// - Is Dead (Toggle)
/// - Age (Number)
/// - ISBN (Text)
///
/// Every property has settings which can be used to customise the property further.
/// Two settings that are shared among all properties are the following:
/// - Multiple
/// - Allow undefined
///
/// The former transforms a property into a list. Instead of one number, you could then specify a series of numbers.
/// The latter allows you to specify an "unknown" value for a property.
/// It might not be known if a character is dead or not for example.
///
/// Each entity associated with the property has a value for it.
///
/// Properties can also be added to blueprints in which case they are available for all entities associated with the
/// blueprint.
///
/// We call properties within entities "Entity Properties" and properties within blueprints "Blueprint Properties".
///
/// \remark Values for properties are lazily created as space saving measure.
/// Fetching the value for some property of some entity will return the property's default value if none is specified.
/// This default value is specified when the property is created and can be updated later.
///
/// \remark Properties' tree structures are scoped to the entity or blueprint they are associated with.
struct IkarusProperty {
/// \private \brief The ID of the property.
IkarusId id;
};
/// \brief Entities are the core building blocks of Ikarus.
/// \detials Blueprints and Properties define the structure of the data.
/// Entities define the data itself.
///
/// Properties can be associated with Entities in two ways:
/// - Directly: The property is linked to the entity.
/// - Indirectly: The property is linked to a blueprint of the entity.
///
/// For each property an entity is linked to, it has a value. These values depend on the property's type.
/// For more information on the types see the property documentation.
///
/// Values are the core type of data within Ikarus.
/// Each value is associated with one page and one property.
///
/// \remark Values are typed, the type of a value is specified by its associated property.
/// For more information on the types see the property documentation.
///
/// \remark Values are guaranteed to be in valid format for a given type
/// but not guaranteed to be valid under the settings of the property.
/// This is because changing the settings can invalidate existing values without resetting them.
struct IkarusEntity {
/// \private \brief The ID of the entity.
IkarusId id;
};
/// \brief A blueprint folder.
/// \see Folder
struct IkarusBlueprintFolder {
/// \private \brief The ID of the folder.
IkarusId id;
};
/// \brief A property folder.
/// \remark Property folders are scoped to the blueprint or entity they are associated with.
/// \see Folder
struct IkarusPropertyFolder {
/// \private \brief The ID of the folder.
IkarusId id;
};
/// \brief An entity folder.
/// \see Folder
struct IkarusEntityFolder {
/// \private \brief The ID of the folder.
IkarusId id;
};
/// \private \brief The data of a folder.
union IkarusFolderData {
/// \private \brief The blueprint folder data of the folder.
IkarusBlueprintFolder blueprint_folder;
/// \private \brief The property folder data of the folder.
IkarusPropertyFolder property_folder;
/// \private \brief The entity folder data of the folder.
IkarusEntityFolder entity_folder;
};
/// \brief A generic folder. Similar to how Objects wrap all types of objects, Folders wrap all types of folders.
struct IkarusFolder {
/// \private \brief The data of the folder.
IkarusFolderData data;
/// \private \brief The type of the folder.
IkarusFolderType type;
};
/// \private \brief The data of an object.
union IkarusObjectData {
/// \private \brief The blueprint data of the object.
IkarusBlueprint blueprint;
/// \private \brief The property data of the object.
IkarusProperty property;
/// \private \brief The entity data of the object.
IkarusEntity entity;
/// \private \brief The blueprint folder data of the object.
IkarusBlueprintFolder blueprint_folder;
/// \private \brief The property folder data of the object.
IkarusPropertyFolder property_folder;
/// \private \brief The entity folder data of the object.
IkarusEntityFolder entity_folder;
};
/// \brief A generic object. Wraps all types of objects, including folders.
struct IkarusObject {
/// \private \brief The data of the object.
IkarusObjectData data;
/// \private \brief The type of the object.
IkarusObjectType type;
};
// @}
IKARUS_END_HEADER

View file

@ -1,149 +0,0 @@
// IMPLEMENTATION_DETAIL_OBJECT_SCOPES, IMPLEMENTATION_DETAIL_TREE_LAYOUT
/// \file object_scope.h
/// \author Folling <mail@folling.io>
/// \defgroup object_scopes Object Scopes
/// \brief Scopes define where objects belong to.
/// \details They are required to differentiate between different types of objects with NULL as their parent.
/// @{
#pragma once
#include <ikarus/macros.h>
#include <ikarus/types/object.h>
IKARUS_BEGIN_HEADER
/// \brief The global scope of all blueprints.
struct IkarusBlueprintScope {
/// \private \brief Empty structs aren't allowed in C, so we need a dummy field.
short _dummy;
};
/// \brief Data for a property scope. This can either be a blueprint or an entity.
union IkarusPropertyScopeData {
/// \private \brief The blueprint the property is scoped to.
IkarusBlueprint _blueprint;
/// \private \brief The entity the property is scoped to.
IkarusEntity _entity;
};
/// \brief The type of a property scope. This can either be a blueprint or an entity.
enum IkarusPropertyScopeType {
/// \brief The property is scoped to a blueprint.
IkarusPropertyScopeType_Blueprint,
/// \brief The property is scoped to an entity.
IkarusPropertyScopeType_Entity
};
/// \brief The scope of a property
struct IkarusPropertyScope {
/// \private \brief Represents the type of the scope.
IkarusPropertyScopeType _type;
/// \private \brief Represents the data of the scope.
IkarusPropertyScopeData _data;
};
/// The global scope of all entities.
struct IkarusEntityScope {
/// \private \brief Empty structs aren't allowed in C, so we need a dummy field.
short _dummy;
};
/// \private \brief The data for an object scope.
union IkarusObjectScopeData {
/// \private \brief The blueprint data of the scope.
IkarusBlueprintScope _blueprint;
/// \private \brief The property data of the scope.
IkarusPropertyScope _property;
/// \private \brief The entity data of the scope.
IkarusEntityScope _entity;
};
/// The type of an object scope.
enum IkarusObjectScopeType {
/// \brief The scope is a blueprint scope.
IkarusObjectScopeType_Blueprint,
/// \brief The scope is a property scope.
IkarusObjectScopeType_Property,
/// \brief The scope is an entity scope.
IkarusObjectScopeType_Entity
};
/// \brief The scope of an object.
struct IkarusObjectScope {
/// \private \brief Represents the type of the scope.
IkarusObjectScopeType _type;
/// \private \brief Represents the data of the scope.
IkarusObjectScopeData _data;
};
/// \brief Creates a blueprint scope.
/// \return The created blueprint scope.
IKA_API IkarusBlueprintScope ikarus_blueprint_scope_create();
/// \brief Converts a blueprint scope to an object scope.
/// \param scope The scope to convert.
/// \return The converted scope.
IKA_API IkarusObjectScope ikarus_blueprint_scope_to_object_scope(IkarusBlueprintScope const * scope);
/// \brief Creates a property scope from a blueprint.
/// \param blueprint The blueprint the property is scoped to.
/// \return The created property scope.
IKA_API IkarusPropertyScope ikarus_property_scope_create_blueprint(IkarusBlueprint const * blueprint);
/// \brief Creates a property scope from a entity.
/// \param entity The entity the property is scoped to.
/// \return The created property scope.
IKA_API IkarusPropertyScope ikarus_property_scope_create_entity(IkarusEntity const * entity);
/// \brief Converts a property scope to an object scope.
/// \param scope The scope to convert.
/// \return The converted scope.
IKA_API IkarusObjectScope ikarus_property_scope_to_object_scope(IkarusPropertyScope const * scope);
/// \brief Fetches the type of an property scope.
/// \param scope The scope to fetch the type of.
/// \return The type of the scope.
IKA_API IkarusPropertyScopeType ikarus_property_scope_get_type(IkarusPropertyScope const * scope);
/// \brief Visits a property scope, calling the appropriate function.
/// \param scope The scope to to visit
/// \param blueprint The function to call if the property is scoped to a blueprint.
/// \param entity The function to call if the property is scoped to an entity.
/// \param data Optional data to pass to the functions.
void ikarus_property_scope_visit(
IkarusPropertyScope const * scope,
void (*blueprint)(IkarusBlueprint const *, void *),
void (*entity)(IkarusEntity const *, void *),
void * data
);
/// \brief Creates an entity scope.
/// \return The created entity scope.
IKA_API IkarusEntityScope ikarus_entity_scope_create();
/// Converts an entity scope to an object scope.
/// \param scope The scope to convert.
/// \return The converted scope.
IKA_API IkarusObjectScope ikarus_entity_scope_to_object_scope(IkarusEntityScope const * scope);
/// \brief Fetches the type of an object scope.
/// \param scope The scope to fetch the type of.
/// \return The type of the scope.
IKA_API IkarusObjectScopeType ikarus_object_scope_get_type(IkarusObjectScope const * scope);
/// \brief Visits an object scope, calling the appropriate function.
/// \param scope The scope to visit.
/// \param blueprint The function to call if the scope is an #IkarusBlueprintScope.
/// \param property The function to call if the scope is an #IkarusPropertyScope.
/// \param entity The function to call if the scope is an #IkarusEntityScope.
/// \remark function pointers may be null in which case they are not called.
IKA_API void ikarus_object_scope_visit(
IkarusObjectScope const * scope,
void (*blueprint)(IkarusBlueprintScope const *, void *),
void (*property)(IkarusPropertyScope const *, void *),
void (*entity)(IkarusEntityScope const *, void *),
void * data
);
/// @}
IKARUS_END_HEADER

View file

@ -1,73 +0,0 @@
#pragma once
#include <ikarus/macros.h>
IKARUS_BEGIN_HEADER
/// \defgroup object_types ObjectTypes
/// \brief ObjectTypes are used to identify the type of objects.
/// @{
/// \brief The type of a folder.
/// \remark These values are identical to the associated values of IkarusObjectType.
enum IkarusFolderType {
/// \brief Not a folder or no folder.
IkarusFolderType_None = 0,
/// \brief An IkarusBlueprintFolder
IkarusFolderType_BlueprintFolder = 17,
/// \brief An IkarusPropertyFolder
IkarusFolderType_PropertyFolder = 18,
/// \brief An IkarusEntityFolder
IkarusFolderType_EntityFolder = 19,
};
/// \brief The type of an object.
/// \remark Folders have the 4th bit set.
enum IkarusObjectType {
/// \brief Not an object or no object.
IkarusObjectType_None = 0,
/// \brief An IkarusBlueprint.
IkarusObjectType_Blueprint = 1,
/// \brief An IkarusProperty.
IkarusObjectType_Property = 2,
/// \brief An IkarusEntity.
IkarusObjectType_Entity = 3,
/// \brief An IkarusBlueprintFolder
IkarusObjectType_BlueprintFolder = IkarusFolderType_BlueprintFolder,
/// \brief An IkarusPropertyFolder
IkarusObjectType_PropertyFolder = IkarusFolderType_PropertyFolder,
/// \brief An IkarusEntityFolder
IkarusObjectType_EntityFolder = IkarusFolderType_EntityFolder,
};
// because of the nature of bitsets, the largest possible object-type is 31
/// \brief A bitset of IkarusObjectType%s.
enum IkarusObjectTypes {
/// \brief No object type.
IkarusObjectTypes_None = 0,
/// \brief An IkarusBlueprint.
IkarusObjectTypes_Blueprint = 1 << IkarusObjectType_Blueprint,
/// \brief An IkarusProperty.
IkarusObjectTypes_Property = 1 << IkarusObjectType_Property,
/// \brief An IkarusEntity.
IkarusObjectTypes_Entity = 1 << IkarusObjectType_Entity,
/// \brief An IkarusBlueprintFolder
IkarusObjectTypes_BlueprintFolder = 1 << IkarusObjectType_BlueprintFolder,
/// \brief An IkarusPropertyFolder
IkarusObjectTypes_PropertyFolder = 1 << IkarusObjectType_PropertyFolder,
/// \brief An IkarusEntityFolder
IkarusObjectTypes_EntityFolder = 1 << IkarusObjectType_EntityFolder,
};
/// \brief Converts an IkarusFolderType to an IkarusObjectType.
/// \param type The IkarusFolderType to convert.
/// \return The converted IkarusObjectType, representing the folder type.
IKA_API IkarusObjectType ikarus_folder_type_to_object_type(IkarusFolderType type);
/// \brief Converts an IkarusObjectType to a bitset of IkarusObjectTypes.
/// \param type The IkarusObjectType to convert.
/// \return The converted IkarusObjectTypes, representing the object type.
IKA_API IkarusObjectTypes ikarus_object_type_to_bitset(IkarusObjectType type);
// @}
IKARUS_END_HEADER

View file

@ -2,9 +2,12 @@
// IMPLEMENTATION_DETAIL_PROPERTY_TYPES
/// \file value.h
/// \author Folling <mail@folling.io>
#include <ikarus/macros.h>
#include <ikarus/objects/property.h>
#include <ikarus/stdtypes.h>
#include <ikarus/types/property_type.h>
IKARUS_BEGIN_HEADER