add flatbuffers support and initial rewrite

Signed-off-by: Folling <mail@folling.io>
This commit is contained in:
Folling 2024-05-12 14:15:42 +02:00 committed by Folling
parent b5852698e3
commit 70820129ae
Signed by: folling
SSH key fingerprint: SHA256:S9qEx5WCFFLK49tE/LKnKuJYM5sw+++Dn6qJbbyxnCY
72 changed files with 3929 additions and 1403 deletions

View file

@ -1,46 +0,0 @@
#pragma once
/// \file entity_property_value.h
/// \author Folling <folling@ikarus.world>
/// \defgroup entity_property_values EntityPropertyValue
/// \brief Values in relation to an entity and one of its properties.
/// @{
#include <ikarus/errors.h>
#include <ikarus/macros.h>
#include <ikarus/values/entity_property_value.h>
IKARUS_BEGIN_HEADER
/// \brief Like an \ref value.h "IkarusValue", but in relation to an entity and one of its properties
struct IkarusEntityPropertyValue;
/// \brief Fetches the entity of an entity property value.
/// \param value The entity property value.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The entity of the entity property value.
/// \remark This value is owned by the entity property value and must not be freed directly.
struct IkarusEntity const * ikarus_entity_property_value_get_entity(IkarusEntityPropertyValue const * value, IkarusErrorData * error_out);
/// \brief Fetches the property of an entity property value.
/// \param value The entity property value.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The property of the entity property value.
/// \remark This value is owned by the entity property value and must not be freed directly.
struct IkarusProperty const *
ikarus_entity_property_value_get_property(IkarusEntityPropertyValue const * value, IkarusErrorData * error_out);
/// \brief Fetches the value of an entity property value.
/// \param value The entity property value.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The value of the entity property value.
/// \remark This value is owned by the entity property value and must not be freed directly.
struct IkarusValue const * ikarus_entity_property_value_get_value(IkarusEntityPropertyValue const * value, IkarusErrorData * error_out);
IKARUS_END_HEADER
/// @}

View file

@ -5,6 +5,7 @@
#include <ikarus/errors.h>
#include <ikarus/macros.h>
#include <ikarus/values/value_cardinality.h>
/// \addtogroup values Values
/// @{
@ -15,10 +16,11 @@ IKARUS_BEGIN_HEADER
struct IkarusNumberValue;
/// \brief Creates an empty number value.
/// \details If the cardinality is "Single", the value will be initialized with 0.0.
/// \param cardinality The cardinality of the value.
/// \param error_out \see errors.h
/// \return The value or null if an error occurs.
/// \remark Must be freed with #ikarus_free.
IKA_API IkarusNumberValue * ikarus_number_value_create(IkarusErrorData * error_out);
IKA_API IkarusNumberValue * ikarus_number_value_create(IkarusValueCardinality cardinality, IkarusErrorData * error_out);
/// \brief Fetches the underlying data of a number value at a specific index.
/// \param value The number value.
@ -26,14 +28,14 @@ IKA_API IkarusNumberValue * ikarus_number_value_create(IkarusErrorData * error_o
/// \param idx The index of the data to fetch.
/// \pre \li Must be less than the size of the value.
/// \param error_out \see errors.h
/// \return The underlying data or NaN if an error occurs or the value is undefined.
/// \return The underlying data or NaN if an error occurs.
IKA_API double ikarus_number_value_get(IkarusNumberValue const * value, size_t idx, IkarusErrorData * error_out);
/// \brief Fetches the size of the underlying data of a number value.
/// \param value The number value.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The size of the underlying data or 0 if an error occurs or the value is undefined.
/// \return The size of the underlying data or 0 if an error occurs.
IKA_API size_t ikarus_number_value_get_size(IkarusNumberValue const * value, IkarusErrorData * error_out);
/// \brief Sets the data of a number value at a specific index.
@ -45,53 +47,37 @@ IKA_API size_t ikarus_number_value_get_size(IkarusNumberValue const * value, Ika
/// \param error_out \see errors.h
IKA_API void ikarus_number_value_set(IkarusNumberValue * value, size_t idx, double new_data, IkarusErrorData * error_out);
/// \brief Removes a data from a number value.
/// \param value The number value.
/// \pre \li Must not be null.
/// \param idx The index of the data to remove.
/// \pre \li Must be less than the size of the value.
/// \param error_out \see errors.h
IKA_API void ikarus_number_value_remove(IkarusNumberValue * value, size_t idx, IkarusErrorData * error_out);
/// \brief Inserts a data into a number value.
/// \param value The number value.
/// \pre \li Must not be null.
/// \pre \li Cardinality must be "Multiple".
/// \param idx The index of the data to insert.
/// \pre \li Must be less than or equal to the size of the value.
/// \param new_data The new data.
/// \param error_out \see errors.h
IKA_API void ikarus_number_value_insert(IkarusNumberValue * value, size_t idx, double new_data, IkarusErrorData * error_out);
/// \brief Removes a data from a number value.
/// \param value The number value.
/// \pre \li Must not be null.
/// \pre \li Cardinality must be "Multiple".
/// \param idx The index of the data to remove.
/// \pre \li Must be less than the size of the value.
/// \param error_out \see errors.h
IKA_API void ikarus_number_value_remove(IkarusNumberValue * value, size_t idx, IkarusErrorData * error_out);
/// \brief Clears a number value.
/// \param value The number value.
/// \pre \li Cardinality must be "Multiple".
/// \param error_out \see errors.h
/// \remark Noop if the value is undefined.
IKA_API void ikarus_number_value_clear(IkarusNumberValue * value, IkarusErrorData * error_out);
/// \brief Checks if a number value is undefined.
/// \param value The number value.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return True if the value is undefined, false otherwise.
IKA_API bool ikarus_number_value_is_undefined(IkarusNumberValue const * value, IkarusErrorData * error_out);
/// \brief Changes a number value's undefined state.
/// \param value The number value.
/// \pre \li Must not be null.
/// \param undefined The new undefined state.
/// \param error_out \see errors.h
/// \remark Noop if the value is already undefined.
/// \remark If the value is set to undefined, all data will be cleared.
/// \remark If the value is set to not undefined, the value is as if newly created.
IKA_API void ikarus_number_value_set_undefined(IkarusNumberValue * value, bool undefined, IkarusErrorData * error_out);
/// \brief Converts a number value to a string.
/// \param value The number value to convert.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The converted string.
/// \remark Must be freed with #ikarus_free.
/// \remark Undefined if the value is undefined.
IKA_API char const * ikarus_number_value_to_string(IkarusNumberValue const * value, IkarusErrorData * error_out);
/// \brief Checks if two values are equal.
@ -108,7 +94,6 @@ IKA_API bool ikarus_number_value_is_equal(IkarusNumberValue const * lhs, IkarusN
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The copied value.
/// \remark Must be freed with #ikarus_free.
IKA_API IkarusNumberValue * ikarus_number_value_copy(IkarusNumberValue const * value, IkarusErrorData * error_out);
/// \brief Converts a number value to an entity value.
@ -117,10 +102,7 @@ IKA_API IkarusNumberValue * ikarus_number_value_copy(IkarusNumberValue const * v
/// \param error_out \see errors.h
/// \return The converted entity value.
/// \remark This is the same pointer, so freeing it implies freeing the original value.
IKA_API struct IkarusValue * ikarus_number_value_to_value(IkarusNumberValue * value, IkarusErrorData * error_out);
/// \see ikarus_toggle_value_to_value
IKA_API struct IkarusValue const * ikarus_number_value_to_value_const(IkarusNumberValue const * value, IkarusErrorData * error_out);
IKA_API struct IkarusValueData * ikarus_number_value_to_value(IkarusNumberValue * value, IkarusErrorData * error_out);
IKARUS_END_HEADER

View file

@ -5,36 +5,37 @@
#include <ikarus/errors.h>
#include <ikarus/macros.h>
#include <ikarus/stdtypes.h>
#include <ikarus/values/value_cardinality.h>
/// \addtogroup values Values
/// @{
IKARUS_BEGIN_HEADER
/// \brief A textual value. For example "Surname" or "Description"
/// \brief A numeric value. For example "Age" or "Height".
struct IkarusTextValue;
/// \brief Creates an empty text value.
/// \details If the cardinality is "Single", the value will be initialized with 0.0.
/// \param cardinality The cardinality of the value.
/// \param error_out \see errors.h
/// \return The value or null if an error occurs.
/// \remark Must be freed with #ikarus_free.
IKA_API IkarusTextValue * ikarus_text_value_create(IkarusErrorData * error_out);
IKA_API IkarusTextValue * ikarus_text_value_create(IkarusValueCardinality cardinality, IkarusErrorData * error_out);
/// \brief Fetches the underlying data of a number value at a specific index.
/// \param value The number value.
/// \brief Fetches the underlying data of a text value at a specific index.
/// \param value The text value.
/// \pre \li Must not be null.
/// \param idx The index of the data to fetch.
/// \pre \li Must be less than the size of the value.
/// \param error_out \see errors.h
/// \return The underlying data or null if an error occurs or the value is undefined.
IKA_API char const * const * ikarus_text_value_get(IkarusTextValue const * value, size_t idx, IkarusErrorData * error_out);
/// \return The underlying data or NaN if an error occurs.
IKA_API char const * ikarus_text_value_get(IkarusTextValue const * value, size_t idx, IkarusErrorData * error_out);
/// \brief Fetches the size of the underlying data of a text value.
/// \param value The text value.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The size of the underlying data or 0 if an error occurs or the value is undefined.
/// \return The size of the underlying data or 0 if an error occurs.
IKA_API size_t ikarus_text_value_get_size(IkarusTextValue const * value, IkarusErrorData * error_out);
/// \brief Sets the data of a text value at a specific index.
@ -42,59 +43,41 @@ IKA_API size_t ikarus_text_value_get_size(IkarusTextValue const * value, IkarusE
/// \pre \li Must not be null.
/// \param idx The index of the data to set.
/// \pre \li Must be less than the size of the value.
/// \param new_data The new data. Ownership remains with the caller.
/// \pre \li Must not be null.
/// \param new_data The new data.
/// \param error_out \see errors.h
IKA_API void ikarus_text_value_set(IkarusTextValue * value, size_t idx, char const * new_data, IkarusErrorData * error_out);
/// \brief Inserts a data into a text value.
/// \param value The text value.
/// \pre \li Must not be null.
/// \pre \li Cardinality must be "Multiple".
/// \param idx The index of the data to insert.
/// \pre \li Must be less than or equal to the size of the value.
/// \param new_data The new data.
/// \param error_out \see errors.h
IKA_API void ikarus_text_value_insert(IkarusTextValue * value, size_t idx, char const * new_data, IkarusErrorData * error_out);
/// \brief Removes a data from a text value.
/// \param value The text value.
/// \pre \li Must not be null.
/// \pre \li Cardinality must be "Multiple".
/// \param idx The index of the data to remove.
/// \pre \li Must be less than the size of the value.
/// \param error_out \see errors.h
IKA_API void ikarus_text_value_remove(IkarusTextValue * value, size_t idx, IkarusErrorData * error_out);
/// \brief Inserts a data into a text value.
/// \param value The text value.
/// \pre \li Must not be null.
/// \param idx The index of the data to insert.
/// \pre \li Must be less than or equal to the size of the value.
/// \param new_data The new data. Ownership remains with the caller.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
IKA_API void ikarus_text_value_insert(IkarusTextValue * value, size_t idx, char const * new_data, IkarusErrorData * error_out);
/// \brief Clears a text value.
/// \param value The text value.
/// \pre \li Cardinality must be "Multiple".
/// \param error_out \see errors.h
/// \remark Noop if the value is undefined.
IKA_API void ikarus_text_value_clear(IkarusTextValue * value, IkarusErrorData * error_out);
/// \brief Checks if a text value is undefined.
/// \param value The text value.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return True if the value is undefined, false otherwise.
IKA_API bool ikarus_text_value_is_undefined(IkarusTextValue const * value, IkarusErrorData * error_out);
/// \brief Changes a text value's undefined state.
/// \param value The text value.
/// \pre \li Must not be null.
/// \param undefined The new undefined state.
/// \param error_out \see errors.h
/// \remark Noop if the value is already undefined.
/// \remark If the value is set to undefined, all data will be cleared.
/// \remark If the value is set to not undefined, the value is as if newly created.
IKA_API void ikarus_text_value_set_undefined(IkarusTextValue * value, bool undefined, IkarusErrorData * error_out);
/// \brief Converts a text value to a string.
/// \param value The text value to convert.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The converted string.
/// \remark Must be freed with #ikarus_free.
/// \remark Undefined if the value is undefined.
IKA_API char const * ikarus_text_value_to_string(IkarusTextValue const * value, IkarusErrorData * error_out);
/// \brief Checks if two values are equal.
@ -111,7 +94,6 @@ IKA_API bool ikarus_text_value_is_equal(IkarusTextValue const * lhs, IkarusTextV
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The copied value.
/// \remark Must be freed with #ikarus_free.
IKA_API IkarusTextValue * ikarus_text_value_copy(IkarusTextValue const * value, IkarusErrorData * error_out);
/// \brief Converts a text value to an entity value.
@ -120,10 +102,7 @@ IKA_API IkarusTextValue * ikarus_text_value_copy(IkarusTextValue const * value,
/// \param error_out \see errors.h
/// \return The converted entity value.
/// \remark This is the same pointer, so freeing it implies freeing the original value.
IKA_API struct IkarusValue * ikarus_text_value_to_value(IkarusTextValue * value, IkarusErrorData * error_out);
/// \see ikarus_text_value_to_value
IKA_API struct IkarusValue const * ikarus_text_value_to_value_const(IkarusTextValue const * value, IkarusErrorData * error_out);
IKA_API struct IkarusValueData * ikarus_text_value_to_value(IkarusTextValue * value, IkarusErrorData * error_out);
IKARUS_END_HEADER

View file

@ -5,36 +5,37 @@
#include <ikarus/errors.h>
#include <ikarus/macros.h>
#include <ikarus/stdtypes.h>
#include <ikarus/values/value_cardinality.h>
/// \addtogroup values Values
/// @{
IKARUS_BEGIN_HEADER
/// \brief A true/false boolean-esque value. For example "Is Dead".
/// \brief A numeric value. For example "Age" or "Height".
struct IkarusToggleValue;
/// \brief Creates an empty toggle value.
/// \details If the cardinality is "Single", the value will be initialized with 0.0.
/// \param cardinality The cardinality of the value.
/// \param error_out \see errors.h
/// \return The value or null if an error occurs.
/// \remark Must be freed with #ikarus_free.
IKA_API IkarusToggleValue * ikarus_toggle_value_create(IkarusErrorData * error_out);
IKA_API IkarusToggleValue * ikarus_toggle_value_create(IkarusValueCardinality cardinality, IkarusErrorData * error_out);
/// \brief Fetches the underlying data of a number value at a specific index.
/// \param value The number value.
/// \brief Fetches the underlying data of a toggle value at a specific index.
/// \param value The toggle value.
/// \pre \li Must not be null.
/// \param idx The index of the data to fetch.
/// \pre \li Must be less than the size of the value.
/// \param error_out \see errors.h
/// \return The underlying data or null if an error occurs or the value is undefined.
IKA_API bool const * ikarus_toggle_value_get(IkarusToggleValue const * value, size_t idx, IkarusErrorData * error_out);
/// \return The underlying data or NaN if an error occurs.
IKA_API bool ikarus_toggle_value_get(IkarusToggleValue const * value, size_t idx, IkarusErrorData * error_out);
/// \brief Fetches the size of the underlying data of a toggle value.
/// \param value The toggle value.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The size of the underlying data or 0 if an error occurs or the value is undefined.
/// \return The size of the underlying data or 0 if an error occurs.
IKA_API size_t ikarus_toggle_value_get_size(IkarusToggleValue const * value, IkarusErrorData * error_out);
/// \brief Sets the data of a toggle value at a specific index.
@ -46,53 +47,37 @@ IKA_API size_t ikarus_toggle_value_get_size(IkarusToggleValue const * value, Ika
/// \param error_out \see errors.h
IKA_API void ikarus_toggle_value_set(IkarusToggleValue * value, size_t idx, bool new_data, IkarusErrorData * error_out);
/// \brief Removes a data from a toggle value.
/// \param value The toggle value.
/// \pre \li Must not be null.
/// \param idx The index of the data to remove.
/// \pre \li Must be less than the size of the value.
/// \param error_out \see errors.h
IKA_API void ikarus_toggle_value_remove(IkarusToggleValue * value, size_t idx, IkarusErrorData * error_out);
/// \brief Inserts a data into a toggle value.
/// \param value The toggle value.
/// \pre \li Must not be null.
/// \pre \li Cardinality must be "Multiple".
/// \param idx The index of the data to insert.
/// \pre \li Must be less than or equal to the size of the value.
/// \param new_data The new data.
/// \param error_out \see errors.h
IKA_API void ikarus_toggle_value_insert(IkarusToggleValue * value, size_t idx, bool new_data, IkarusErrorData * error_out);
/// \brief Removes a data from a toggle value.
/// \param value The toggle value.
/// \pre \li Must not be null.
/// \pre \li Cardinality must be "Multiple".
/// \param idx The index of the data to remove.
/// \pre \li Must be less than the size of the value.
/// \param error_out \see errors.h
IKA_API void ikarus_toggle_value_remove(IkarusToggleValue * value, size_t idx, IkarusErrorData * error_out);
/// \brief Clears a toggle value.
/// \param value The toggle value.
/// \pre \li Cardinality must be "Multiple".
/// \param error_out \see errors.h
/// \remark Noop if the value is undefined.
IKA_API void ikarus_toggle_value_clear(IkarusToggleValue * value, IkarusErrorData * error_out);
/// \brief Checks if a toggle value is undefined.
/// \param value The toggle value.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return True if the value is undefined, false otherwise.
IKA_API bool ikarus_toggle_value_is_undefined(IkarusToggleValue const * value, IkarusErrorData * error_out);
/// \brief Changes a toggle value's undefined state.
/// \param value The toggle value.
/// \pre \li Must not be null.
/// \param undefined The new undefined state.
/// \param error_out \see errors.h
/// \remark Noop if the value is already undefined.
/// \remark If the value is set to undefined, all data will be cleared.
/// \remark If the value is set to not undefined, the value is as if newly created.
IKA_API void ikarus_toggle_value_set_undefined(IkarusToggleValue * value, bool undefined, IkarusErrorData * error_out);
/// \brief Converts a toggle value to a string.
/// \param value The toggle value to convert.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The converted string.
/// \remark Must be freed with #ikarus_free.
/// \remark Undefined if the value is undefined.
IKA_API char const * ikarus_toggle_value_to_string(IkarusToggleValue const * value, IkarusErrorData * error_out);
/// \brief Checks if two values are equal.
@ -109,7 +94,6 @@ IKA_API bool ikarus_toggle_value_is_equal(IkarusToggleValue const * lhs, IkarusT
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The copied value.
/// \remark Must be freed with #ikarus_free.
IKA_API IkarusToggleValue * ikarus_toggle_value_copy(IkarusToggleValue const * value, IkarusErrorData * error_out);
/// \brief Converts a toggle value to an entity value.
@ -118,10 +102,7 @@ IKA_API IkarusToggleValue * ikarus_toggle_value_copy(IkarusToggleValue const * v
/// \param error_out \see errors.h
/// \return The converted entity value.
/// \remark This is the same pointer, so freeing it implies freeing the original value.
IKA_API struct IkarusValue * ikarus_toggle_value_to_value(IkarusToggleValue * value, IkarusErrorData * error_out);
/// \see ikarus_toggle_value_to_value
IKA_API struct IkarusValue const * ikarus_toggle_value_to_value_const(IkarusToggleValue const * value, IkarusErrorData * error_out);
IKA_API struct IkarusValueData * ikarus_toggle_value_to_value(IkarusToggleValue * value, IkarusErrorData * error_out);
IKARUS_END_HEADER

View file

@ -4,14 +4,27 @@
/// \author Folling <folling@ikarus.world>
/// \defgroup values Values
/// \brief The values of properties.
/// \details Each entity has a value for each property it is associated with.
/// These value classes represent plain objects. They are not associated with any entity.
/// Each value may be undefined. \see IkarusProperty
/// Values are stored as lists. If a property is "singular" then its value is a list of size 1.
/// Values are typed, with types existing for each of the corresponding property types. The data of values starts with the index 0.
/// When setting values for a property the type must match the property type and the value must be valid under the
/// property's settings. \see PropertyType
/// \brief Values are data in entities.
/// \details An entity is made up of any number of values.
/// Each value defines a certain aspect of an entity.
/// Values have a name, a type, and some data.
/// Examples of values would be:
/// - Is Dead (Toggle)
/// - Age (Number)
/// - ISBN (Text)
///
/// Values are either single or multiple.
/// We call this property "Cardinality" (\see IkarusValueCardinality)
/// because it's really hard to find a simpler name.
/// Each piece of data within a value is called a "datapoint".
/// Single values have exactly one datapoint, multiple values have any number of
/// datapoints. For example "Age" would be singular, while "Nicknames" would be
/// multiple. The type is unaffected by this. A pendant in programming languages
/// would be a List<T>. Note that all values are stored as a list of items,
/// even if the value is singular. Single values effectively act as a list with
/// one element. This is enforced by the API at runtime.
///
/// For a comprehensive list of value types, see \ref IkarusValueType.
/// @{
#include <ikarus/errors.h>
@ -19,15 +32,19 @@
IKARUS_BEGIN_HEADER
/// \brief The common type for all values.
/// \brief The common type for all value data.
struct IkarusValue;
/// \brief Visits an entity value, calling the appropriate function for the value's type.
/// \brief Visits an entity value,
/// calling the appropriate function for the value's type.
/// \param value The entity value to visit.
/// \pre \li Must not be null.
/// \param toggle_visitor The function to call if the value is a toggle value. Skipped if null.
/// \param number_visitor The function to call if the value is a number value. Skipped if null.
/// \param text_visitor The function to call if the value is a text value. Skipped if null.
/// \param toggle_visitor The function to call if the value is a toggle value.
/// \remark Skipped if null.
/// \param number_visitor The function to call if the value is a number value.
/// \remark Skipped if null.
/// \param text_visitor The function to call if the value is a text value.
/// \remark Skipped if null.
/// \param data The data passed to the visitor functions.
/// \param error_out \see errors.h
IKA_API void ikarus_value_visit(
@ -39,16 +56,6 @@ IKA_API void ikarus_value_visit(
IkarusErrorData * error_out
);
/// \see ikarus_value_visit
IKA_API void ikarus_value_visit_const(
IkarusValue const * value,
void (*toggle_visitor)(struct IkarusToggleValue const *, void *),
void (*number_visitor)(struct IkarusNumberValue const *, void *),
void (*text_visitor)(struct IkarusTextValue const *, void *),
void * data,
IkarusErrorData * error_out
);
IKARUS_END_HEADER
/// @}

View file

@ -0,0 +1,23 @@
#pragma once
/// \file value_cardinality.h
/// \author Folling <folling@ikarus.world>
/// \addtogroup values Values
/// @{
#include <ikarus/macros.h>
IKARUS_BEGIN_HEADER
/// \brief The cardinality of a value.
enum IkarusValueCardinality {
/// \brief Only contains one datapoint
IkarusValueCardinality_Single,
/// \brief Contains any number of datapoints
IkarusValueCardinality_List
};
IKARUS_END_HEADER
/// @}

View file

@ -0,0 +1,198 @@
#pragma once
/// \file value_schema.h
/// \author Folling <folling@ikarus.world>
/// \addtogroup values Values
/// @{
#include <ikarus/errors.h>
#include <ikarus/macros.h>
#include <ikarus/stdtypes.h>
IKARUS_BEGIN_HEADER
/// \brief Layouts define the structure and constraints of values.
/// \details Ikarus lets you define any schema for values and add constraints to them.
/// These schemas are assembled hierarchical and are akin to JSON schemas.
/// Layouts may be arbitrarily nested and combined e.g.:
/// Combination<List<Text>, Number, Complex<"Foo":Toggle,"Bar":Text>
struct IkarusValueLayout;
/// \brief A fixed datapoint with a fixed layout.
/// Example: Age: Union<Number, Constant<Text, "Dead">>
struct IkarusValueLayoutConstant;
/// \brief A singular datapoint with one of a list of layouts.
/// Example: ChestReward: Combination<Item, Gold, Mimic>
struct IkarusValueLayoutCombination;
/// \brief A collection of datapoints with a homogenous layout.
/// Example: Friends: List<Character>
struct IkarusValueLayoutList;
/// \brief A collection of nameable datapoints with heterogeneous layouts.
/// Example: GeoLocation: Complex<"Latitude":Number, "Longitude":Number>
struct IkarusValueLayoutComplex;
/// \brief Defines the type of datapoints.
enum IkarusValueDataType {
/// \brief Boolean datapoints
/// Example: Is the character alive? Yes
Toggle,
/// \brief Numeric datapoints
/// Example: How much does the character weigh? 57kg
Number,
/// \brief Textual datapoints
/// Example: What is the character's maiden name? Sandra
Text,
/// \brief A colour datapoint
/// Example: What colours make up the nation's flag? White/Pink/Blue.
/// \remark Not yet implemented
Colour,
/// \brief A date/time datapoint, interfacing with the calendar and timeline feature.
/// Example: When was the city founded? 12th of January 233 at 2:11
/// \remark Not yet implemented
Time,
/// \brief A location datapoint, interfacing with the map feature.
/// Example: Where is the city situated? 12.345, 67.890
/// \remark Not yet implemented
Location,
/// \brief An enum-esque datapoint
/// Example: Of which rarity is the weapon? Normal/Rare/Legendary
/// \remark Not yet implemented
Choice,
/// \brief A datapoint linking to some other object in Ikarus
/// Example: Who wrote this hymn? Peter Parker
/// \remark Not yet implemented
Reference
};
/// \brief Stores either a schema or a datatype
struct IkarusValueSchema;
/// \see ikarus_value_schema_from_layout_const
IkarusValueSchema * ikarus_value_schema_from_layout(
IkarusValueLayout * layout,
IkarusErrorData * error_out
);
/// \brief Creates a value schema from a layout.
/// \param layout The layout to create the schema from.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The created schema or null if an error occurs.
IkarusValueSchema const * ikarus_value_schema_from_layout_const(
IkarusValueLayout const * layout,
IkarusErrorData * error_out
);
/// \brief Creates a value schema from a datatype.
/// \param type The datatype to create the schema from.
/// \param error_out \see errors.h
/// \return The created schema or null if an error occurs.
IkarusValueSchema * ikarus_value_schema_from_data_type(
IkarusValueDataType type,
IkarusErrorData * error_out
);
/// \brief Frees a value schema.
/// \param schema The schema to free.
/// \pre \li Must not be null.
/// \remark Must not be accessed after freeing.
void ikarus_value_schema_free(IkarusValueSchema * schema);
/// \see ikarus_value_schema_visit_const
void ikarus_value_schema_visit(
IkarusValueSchema * schema,
void (*layout_visitor)(IkarusValueLayout * layout),
void (*data_type_visitor)(IkarusValueDataType type),
IkarusErrorData * error_out
);
/// \brief Visits a value schema.
/// \param schema The schema to visit.
/// \pre \li Must not be null.
/// \param layout_visitor The function to call if the schema is a layout. Skipped if null.
/// \param data_type_visitor The function to call if the schema is a datatype. Skipped if null.
void ikarus_value_schema_visit_const(
IkarusValueSchema const * schema,
void (*layout_visitor)(IkarusValueLayout const * layout),
void (*data_type_visitor)(IkarusValueDataType type),
IkarusErrorData * error_out
);
/// \brief Creates a constant layout.
/// \param schema The schema of the value.
/// \pre \li Must not be null.
/// \param value The value of the constant.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
IkarusValueLayoutConstant * ikarus_value_layout_constant_create(
IkarusValueSchema * schema,
struct IkarusValue * value,
IkarusErrorData * error_out
);
/// \brief Gets the underyling schema of a constant layout.
/// \param layout The layout to get the underyling schema of.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The underlying schema of the layout or null if an error occurs.
IkarusValueSchema const * ikarus_value_layout_constant_get_underyling_schema(
IkarusValueLayoutConstant const * layout,
IkarusErrorData * error_out
);
/// \brief Gets the underyling value of a constant layout.
/// \param layout The layout to get the underyling value of.
/// \pre \li Must not be null.
/// \param error_out \see errors.h
/// \return The underlying value of the layout or null if an error occurs.
struct IkarusValue const * ikarus_value_layout_constant_get_underlying_value(
IkarusValueLayoutConstant const * layout,
IkarusErrorData * error_out
);
/// \brief Creates a combination layout.
/// \param schemas The schemas of the values.
/// \pre \li Must not be null.
/// \param schemas_size The number of schemas.
/// \param error_out \see errors.h
/// \return The created layout or null if an error occurs.
/// \remark The schemas are copied.
IkarusValueLayoutCombination * ikarus_value_layout_combination_create(
IkarusValueSchema * schemas,
size_t schemas_size,
IkarusErrorData * error_out
);
void ikarus_value_layout_combination_get_schemas(
IkarusValueLayoutCombination const * layout,
IkarusValueSchema ** schemas_out,
size_t * schemas_size_out,
IkarusErrorData * error_out
);
size_t ikarus_value_layout_combination_get_schemas_count(
IkarusValueLayoutCombination const * layout,
IkarusErrorData * error_out
);
IkarusValueLayoutList * ikarus_value_layout_list_create(
IkarusValueSchema * schema,
IkarusErrorData * error_out
);
IkarusValueLayoutComplex * ikarus_value_layout_complex_create(
IkarusValueSchema * schemas,
size_t schemas_size,
IkarusErrorData * error_out
);
IkarusValueLayoutComplex * ikarus_value_layout_complex_create_named(
IkarusValueSchema * schemas,
char const ** names,
size_t schemas_size,
IkarusErrorData * error_out
);
IKARUS_END_HEADER
/// @}