a new beginning
Signed-off-by: Folling <mail@folling.io>
This commit is contained in:
commit
8eb2067318
25 changed files with 1718 additions and 0 deletions
8
include/CMakeLists.txt
Normal file
8
include/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
file(
|
||||
GLOB_RECURSE
|
||||
FILES
|
||||
"*.h"
|
||||
)
|
||||
|
||||
set(INCLUDE_FILES ${FILES} PARENT_SCOPE)
|
||||
|
||||
27
include/ikarus/macros.h
Normal file
27
include/ikarus/macros.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#if defined(__unix__)
|
||||
|
||||
#define IKA_OS_FAMILY_UNIX
|
||||
#define IKA_API __attribute__((visibility("default")))
|
||||
|
||||
#if defined(linux)
|
||||
#define IKA_OS_LINUX
|
||||
#endif
|
||||
|
||||
#elif defined(_WIN32) || defined(WIN32)
|
||||
#define IKA_OS_WIN
|
||||
#define IKA_API __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#ifndef IKA_API
|
||||
#define IKA_API
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define IKARUS_BEGIN_HEADER extern "C" {
|
||||
#define IKARUS_END_HEADER }
|
||||
#else
|
||||
#define IKARUS_BEGIN_HEADER
|
||||
#define IKARUS_END_HEADER
|
||||
#endif
|
||||
8
include/ikarus/stdtypes.h
Normal file
8
include/ikarus/stdtypes.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdint>
|
||||
using std::size_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
58
include/ikarus/types/id.h
Normal file
58
include/ikarus/types/id.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
// IMPLEMENTATION_DETAIL_DATABASE
|
||||
|
||||
/// \file id.h
|
||||
/// \author Folling <mail@folling.io>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ikarus/macros.h>
|
||||
|
||||
IKARUS_BEGIN_HEADER
|
||||
|
||||
#include <ikarus/stdtypes.h>
|
||||
#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:
|
||||
/// - first 8 bits: #IkarusObjectType - 255 possible values, 0 for special values
|
||||
/// - last 56 bits: incremented counter generated by the database
|
||||
/// @{
|
||||
|
||||
/// \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:
|
||||
/// - first 8 bits: #IkarusObjectType - 255 possible values, 0 for special values
|
||||
/// - last 56 bits: incremented counter generated by the database
|
||||
struct IkarusId {
|
||||
/// \private \brief The value of the id.
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
/// \brief A special id returned by failed functions.
|
||||
IkarusId const IKARUS_ID_NONE{0};
|
||||
/// \brief A special id used to indicate an optional id not being specified.
|
||||
IkarusId const IKARUS_ID_UNSPECIFIED{1};
|
||||
|
||||
/// \private \brief Generates a new id for the given object type.
|
||||
/// \param object_type The type of the object to generate an id for.
|
||||
/// \return The generated id.
|
||||
IkarusId ikarus_id_from_integer(IkarusObjectType object_type);
|
||||
|
||||
/// \brief Fetches the object type of the given id.
|
||||
/// \param id The id to fetch the object type for.
|
||||
/// \return The object type of the given id.
|
||||
IKA_API IkarusObjectType ikarus_id_get_object_type(IkarusId id);
|
||||
|
||||
/// \brief Checks if the given id is IKARUS_ID_NONE.
|
||||
/// \param id The id to check.
|
||||
/// \return True if the id is IKARUS_ID_NONE, false otherwise.
|
||||
IKA_API bool ikarus_id_is_none(IkarusId id);
|
||||
|
||||
/// \brief Checks if the given id is IKARUS_ID_UNSPECIFIED.
|
||||
/// \param id The id to check.
|
||||
/// \return True if the id is IKARUS_ID_UNSPECIFIED, false otherwise.
|
||||
IKA_API bool ikarus_id_is_unspecified(IkarusId id);
|
||||
|
||||
/// @}
|
||||
|
||||
IKARUS_END_HEADER
|
||||
164
include/ikarus/types/object.h
Normal file
164
include/ikarus/types/object.h
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
#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
|
||||
149
include/ikarus/types/object_scope.h
Normal file
149
include/ikarus/types/object_scope.h
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
// 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
|
||||
63
include/ikarus/types/object_type.h
Normal file
63
include/ikarus/types/object_type.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#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 folders have the first bit set and then mirror the object type of the underlying object
|
||||
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,
|
||||
};
|
||||
|
||||
/// \brief The type of an object.
|
||||
/// \remark folders have the first bit set and then mirror the object type of the underlying object
|
||||
enum IkarusObjectType {
|
||||
/// \brief Not an object or no object.
|
||||
ObjectType_None = 0,
|
||||
/// \brief An IkarusBlueprint.
|
||||
ObjectType_Blueprint = 0b0000'0001,
|
||||
/// \brief An IkarusProperty.
|
||||
ObjectType_Property = 0b0000'0010,
|
||||
/// \brief An IkarusEntity.
|
||||
ObjectType_Entity = 0b0000'0011,
|
||||
/// \brief An IkarusBlueprintFolder
|
||||
ObjectType_BlueprintFolder = 0b1000'0001,
|
||||
/// \brief An IkarusPropertyFolder
|
||||
ObjectType_PropertyFolder = 0b1000'0010,
|
||||
/// \brief An IkarusEntityFolder
|
||||
ObjectType_EntityFolder = 0b1000'0011,
|
||||
};
|
||||
|
||||
/// \brief A bitset of IkarusObjectType%s.
|
||||
enum ObjectTypes {
|
||||
/// \brief No object type.
|
||||
ObjectTypes_None = 0,
|
||||
/// \brief An IkarusBlueprint.
|
||||
ObjectTypes_Blueprint = 1 << ObjectType_Blueprint,
|
||||
/// \brief An IkarusProperty.
|
||||
ObjectTypes_Property = 1 << ObjectType_Property,
|
||||
/// \brief An IkarusEntity.
|
||||
ObjectTypes_Entity = 1 << ObjectType_Entity,
|
||||
/// \brief An IkarusBlueprintFolder
|
||||
ObjectTypes_BlueprintFolder = 1 << ObjectType_BlueprintFolder,
|
||||
/// \brief An IkarusPropertyFolder
|
||||
ObjectTypes_PropertyFolder = 1 << ObjectType_PropertyFolder,
|
||||
/// \brief An IkarusEntityFolder
|
||||
ObjectTypes_EntityFolder = 1 << ObjectType_EntityFolder,
|
||||
};
|
||||
|
||||
// @}
|
||||
|
||||
IKARUS_END_HEADER
|
||||
31
include/ikarus/types/property_type.h
Normal file
31
include/ikarus/types/property_type.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
// IMPLEMENTATION_DETAIL_PROPERTY_TYPES
|
||||
|
||||
/// \file id.h
|
||||
/// \author Folling <mail@folling.io>
|
||||
|
||||
#include <ikarus/macros.h>
|
||||
|
||||
IKARUS_BEGIN_HEADER
|
||||
|
||||
/// \defgroup property_types Property Types
|
||||
/// \brief Property Types delineate the type of data stored by a property.
|
||||
/// @{
|
||||
|
||||
/// \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
|
||||
161
include/ikarus/types/value.h
Normal file
161
include/ikarus/types/value.h
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
#pragma once
|
||||
|
||||
// IMPLEMENTATION_DETAIL_PROPERTY_TYPES
|
||||
|
||||
#include <ikarus/macros.h>
|
||||
#include <ikarus/stdtypes.h>
|
||||
#include <ikarus/types/property_type.h>
|
||||
|
||||
IKARUS_BEGIN_HEADER
|
||||
|
||||
/// \defgroup entity_value Entity Values
|
||||
/// \brief The values stored in entities.
|
||||
/// \details Each entity has a value for each property it is associated with.
|
||||
/// The value is of the type specified by the property and constrained by the property's settings.
|
||||
/// \see PropertyType PropertySettings
|
||||
/// @{
|
||||
|
||||
/// \brief A true/false boolean-like value. For example "IsDead".
|
||||
struct IkarusToggleValue {
|
||||
/// \private \brief The value of the property.
|
||||
bool _value;
|
||||
};
|
||||
|
||||
/// \brief An arbitrary numeric value. For example "Age".
|
||||
struct IkarusNumberValue {
|
||||
/// \private \brief The value of the property.
|
||||
long double _value;
|
||||
};
|
||||
|
||||
/// \brief An arbitrary textual value. For example "First Name".
|
||||
struct IkarusTextValue {
|
||||
/// \private \brief The value of the property.
|
||||
char const * _value;
|
||||
};
|
||||
|
||||
/// \private \brief The data for a value.
|
||||
union IkarusEntityValueData {
|
||||
/// \private \brief The value as a toggle.
|
||||
IkarusToggleValue toggle;
|
||||
/// \private \brief The value as a number.
|
||||
IkarusNumberValue number;
|
||||
/// \private \brief The value as text.
|
||||
IkarusTextValue text;
|
||||
};
|
||||
|
||||
/// \brief The state of an entity value.
|
||||
/// \details States provide insight into the nature of a value.
|
||||
enum IkarusEntityValueState {
|
||||
/// \brief The value is invalid.
|
||||
IkarusEntityValueState_Invalid,
|
||||
/// \brief The value is normal and can be used as-is.
|
||||
IkarusEntityValueState_Normal,
|
||||
/// \brief The value is unknown.
|
||||
IkarusEntityValueState_Indeterminate,
|
||||
};
|
||||
|
||||
/// \brief The value of an entity associated with a property.
|
||||
struct IkarusEntityValue {
|
||||
/// \private \brief The type of the value.
|
||||
IkarusPropertyType _type;
|
||||
/// \private \brief The data for the value.p
|
||||
IkarusEntityValueData _data;
|
||||
/// \private \brief The state of the value.
|
||||
IkarusEntityValueState _state;
|
||||
};
|
||||
|
||||
/// \brief Creates an entity value from a toggle value.
|
||||
/// \param value The toggle value.
|
||||
/// \return The entity value.
|
||||
IKA_API IkarusEntityValue ikarus_value_create_toggle(bool value);
|
||||
/// \brief Creates an entity value from a number value.
|
||||
/// \param value The number value.
|
||||
/// \return The entity value.
|
||||
/// \remark If the value is NaN or infinity an InvalidEntityValue is returned.
|
||||
IKA_API IkarusEntityValue ikarus_value_create_number(long double value);
|
||||
/// \brief Creates an entity value from a text value.
|
||||
/// \param value The text value.
|
||||
/// \return The entity value.
|
||||
/// \remark If the value is null an InvalidEntityValue is returned.
|
||||
IKA_API IkarusEntityValue ikarus_value_create_text(char const * value);
|
||||
|
||||
/// \brief Creates an indeterminate entity value of a given type.
|
||||
/// \param type The type of the value.
|
||||
/// \return The entity value.
|
||||
IKA_API IkarusEntityValue ikarus_value_create_indeterminate(IkarusPropertyType type);
|
||||
|
||||
/// \brief Fetches the default value for a property type.
|
||||
/// \remark Not to be confused with the default value of a property. See ikarus_property_get_default_value
|
||||
/// \param type The property type.
|
||||
/// \return The default value for the property type.
|
||||
IKA_API IkarusEntityValue ikarus_value_get_default(IkarusPropertyType type);
|
||||
|
||||
/// \brief Fetches the underlying value of a toggle value.
|
||||
/// \param value The toggle value.
|
||||
/// \return The underlying value.
|
||||
IKA_API bool ikarus_toggle_value_get_underlying(IkarusToggleValue const * value);
|
||||
|
||||
/// \brief Fetches the underlying value of a number value.
|
||||
/// \param value The number value.
|
||||
/// \return The underlying value.
|
||||
IKA_API long double ikarus_number_value_get_underlying(IkarusNumberValue const * value);
|
||||
|
||||
/// \brief Fetches the underlying value of a text value.
|
||||
/// \param value The text value.
|
||||
/// \return The underlying value.
|
||||
IKA_API char const * ikarus_text_value_get_underlying(IkarusTextValue const * value);
|
||||
|
||||
/// \brief Checks if a toggle value is equal to a boolean.
|
||||
/// \param value The toggle value.
|
||||
/// \param check The boolean value.
|
||||
/// \return False if value is null. True if it is equal to check, false otherwise.
|
||||
IKA_API bool ikarus_toggle_value_is_equal(IkarusToggleValue const * value, bool check);
|
||||
|
||||
/// \brief Checks if a number value is equal to a number.
|
||||
/// \param value The number value.
|
||||
/// \param check The number value.
|
||||
/// \return False if value is null. True if it is equal to check, false otherwise.
|
||||
IKA_API bool ikarus_number_value_is_equal(IkarusNumberValue const * value, long double check);
|
||||
|
||||
/// \brief Checks if a text value is equal to a string.
|
||||
/// \param value The text value.
|
||||
/// \param check The string value.
|
||||
/// \return False if value or check are null. True if it is equal to check, false otherwise.
|
||||
IKA_API bool ikarus_text_value_is_equal(IkarusTextValue const * value, char const * check);
|
||||
|
||||
/// \brief Checks if two entity values are equal.
|
||||
/// \details Two entity values are equal if they are of the same type and their value is considered equal.
|
||||
/// Note that floating point values can only be checked for approximate equality.
|
||||
/// \param left The left-hand entity value.
|
||||
/// \param right The right-hand entity value.
|
||||
/// \return True if the values are considered equal, false otherwise.
|
||||
/// \remark Null values compare false to all other values. As do invalid values. Indeterminate values however, compare true to
|
||||
/// other indeterminate values of the same type.
|
||||
IKA_API bool ikarus_value_is_equal(IkarusEntityValue const * left, IkarusEntityValue const * right);
|
||||
|
||||
/// \brief Checks if an entity value is invalid.
|
||||
/// \param value The entity value.
|
||||
/// \return True if the value is invalid or null, false otherwise.
|
||||
IKA_API bool ikarus_value_is_invalid(IkarusEntityValue const * value);
|
||||
|
||||
/// \brief Fetches the type of an entity value.
|
||||
/// \param value The entity value.
|
||||
/// \return The type of the entity value.
|
||||
IKA_API IkarusPropertyType ikarus_value_get_type(IkarusEntityValue const * value);
|
||||
|
||||
/// \brief Visits an entity value, calling the appropriate function for the value's type.
|
||||
/// \param value The entity value to visit.
|
||||
/// \param toggle The function to call if the value is a toggle value.
|
||||
/// \param number The function to call if the value is a number value.
|
||||
/// \param text The function to call if the value is a text value.
|
||||
/// \param data The data to pass to the functions.
|
||||
/// \remark function pointers may be null in which case they are not called.
|
||||
IKA_API void ikarus_value_visit(
|
||||
IkarusEntityValue const * value,
|
||||
void (*toggle)(IkarusToggleValue const *, void *),
|
||||
void (*number)(IkarusNumberValue const *, void *),
|
||||
void (*text)(IkarusTextValue const *, void *),
|
||||
void * data
|
||||
);
|
||||
|
||||
IKARUS_END_HEADER
|
||||
Loading…
Add table
Add a link
Reference in a new issue