From 9e63219bf9b4c100cb2d7dfce43c2023b6df66c8 Mon Sep 17 00:00:00 2001 From: Folling Date: Tue, 21 Nov 2023 15:10:43 +0100 Subject: [PATCH] split property & values into separate classes and files Signed-off-by: Folling --- implementation_details | 12 -- include/ikarus/objects/blueprint.h | 5 +- include/ikarus/objects/entity.h | 39 +++--- include/ikarus/objects/object.h | 12 ++ include/ikarus/objects/object_type.h | 3 - .../objects/properties/number_property.h | 25 ++++ .../objects/{ => properties}/property.h | 81 ++++++----- .../{ => properties}/property_source.h | 16 ++- .../objects/{ => properties}/property_type.h | 2 - .../settings/number_property_settings.h | 31 ++++ .../properties/settings/property_settings.h | 92 ++++++++++++ .../settings/text_property_settings.h | 31 ++++ .../settings/toggle_property_settings.h | 31 ++++ .../ikarus/objects/properties/text_property.h | 25 ++++ .../objects/properties/toggle_property.h | 25 ++++ include/ikarus/objects/property_type_info.h | 79 ----------- include/ikarus/values/number_value.h | 44 ++++++ include/ikarus/values/text_value.h | 44 ++++++ include/ikarus/values/toggle_value.h | 44 ++++++ include/ikarus/values/value.h | 132 ++++-------------- src/objects/blueprint.cpp | 3 - src/objects/property.cpp | 87 ++++++++++++ src/objects/property_info.hpp | 74 ++++++++++ src/objects/property_source.hpp | 10 ++ src/persistence/project.hpp | 3 +- src/values/number_value.hpp | 5 + src/values/text_value.hpp | 8 ++ src/values/toggle_value.hpp | 6 + 28 files changed, 700 insertions(+), 269 deletions(-) delete mode 100644 implementation_details create mode 100644 include/ikarus/objects/properties/number_property.h rename include/ikarus/objects/{ => properties}/property.h (62%) rename include/ikarus/objects/{ => properties}/property_source.h (69%) rename include/ikarus/objects/{ => properties}/property_type.h (96%) create mode 100644 include/ikarus/objects/properties/settings/number_property_settings.h create mode 100644 include/ikarus/objects/properties/settings/property_settings.h create mode 100644 include/ikarus/objects/properties/settings/text_property_settings.h create mode 100644 include/ikarus/objects/properties/settings/toggle_property_settings.h create mode 100644 include/ikarus/objects/properties/text_property.h create mode 100644 include/ikarus/objects/properties/toggle_property.h delete mode 100644 include/ikarus/objects/property_type_info.h create mode 100644 include/ikarus/values/number_value.h create mode 100644 include/ikarus/values/text_value.h create mode 100644 include/ikarus/values/toggle_value.h create mode 100644 src/objects/property.cpp create mode 100644 src/objects/property_info.hpp create mode 100644 src/objects/property_source.hpp create mode 100644 src/values/number_value.hpp create mode 100644 src/values/text_value.hpp create mode 100644 src/values/toggle_value.hpp diff --git a/implementation_details b/implementation_details deleted file mode 100644 index 42b38fc..0000000 --- a/implementation_details +++ /dev/null @@ -1,12 +0,0 @@ -This list is intended to help keep the documentation up to date. -If you make changes to, for example, templates, always check the documentation for templates. -But sometimes information is shared. and referenced in multiple places. This helps keep track of that. - -Usage: Search for these keys prefixed with IMPLEMENTATION_DETAIL_* to change documentation in relevant places. - -DATABASE: References to the usage of a database -TREE_LAYOUT: References to our usage of a tree layout -OBJECT_TYPES: References to the types of objects -OBJECT_SCOPES: References to the usage of object scopes -PROPERTY_TYPES: The property types that currently exist -LAZY_VALUE_CREATION: The fact that values are created lazily \ No newline at end of file diff --git a/include/ikarus/objects/blueprint.h b/include/ikarus/objects/blueprint.h index 85f40eb..57d1a7c 100644 --- a/include/ikarus/objects/blueprint.h +++ b/include/ikarus/objects/blueprint.h @@ -77,7 +77,10 @@ IKA_API void ikarus_blueprint_get_linked_entities( /// \pre \li Must exist. /// \return The blueprint represented as an object or null if an error occurs. /// \remark This operation is guaranteed to be very fast and is intended to be used frequently. -IKA_API struct IkarusObject * ikarus_blueprint_to_object(IkarusBlueprint const * blueprint); +IKA_API struct IkarusObject * ikarus_blueprint_to_object(IkarusBlueprint * blueprint); + +/// \see ikarus_blueprint_to_object +IKA_API struct IkarusObject const * ikarus_blueprint_to_object_const(IkarusBlueprint const * blueprint); IKARUS_END_HEADER diff --git a/include/ikarus/objects/entity.h b/include/ikarus/objects/entity.h index 813adea..2ac9087 100644 --- a/include/ikarus/objects/entity.h +++ b/include/ikarus/objects/entity.h @@ -50,12 +50,7 @@ struct IkarusEntity; /// \return The created entity or null if an error occurs. /// \remark Must be freed using #ikarus_free. IKA_API IkarusEntity * ikarus_entity_create( - struct IkarusProject * project, - struct IkarusEntityFolder * parent, - size_t position, - char const * name, - struct IkarusBlueprint ** blueprints, - size_t blueprints_count + struct IkarusProject * project, char const * name, struct IkarusBlueprint ** blueprints, size_t blueprints_count ); /// \brief Deletes an entity. @@ -67,16 +62,6 @@ IKA_API void ikarus_entity_delete(IkarusEntity * entity); IKA_API bool ikarus_entity_is_linked_to_blueprint(IkarusEntity const * entity, struct IkarusBlueprint const * blueprint); -/// \brief Checks if an entity has a specific property. -/// \param entity The entity to check. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param property The property to check. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \return True if the entity has the property, false otherwise. -IKA_API bool ikarus_entity_has_property(IkarusEntity const * entity, struct IkarusProperty const * property); - /// \brief Links an entity to a blueprint. /// \param entity The entity to link. /// \pre \li Must not be null. @@ -98,6 +83,16 @@ IKA_API void ikarus_entity_link_to_blueprint(IkarusEntity * entity, struct Ikaru /// \remark No-op if the entity is not linked to the blueprint. IKA_API void ikarus_entity_unlink_from_blueprint(IkarusEntity * entity, struct IkarusBlueprint * blueprint); +/// \brief Checks if an entity has a specific property. +/// \param entity The entity to check. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param property The property to check. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \return True if the entity has the property, false otherwise. +IKA_API bool ikarus_entity_has_property(IkarusEntity const * entity, struct IkarusProperty const * property); + /// \brief Gets the number of properties of an entity. /// \param entity The entity to get the number of properties of. /// \pre \li Must not be null. @@ -126,7 +121,7 @@ IKA_API void ikarus_entity_get_properties( /// \pre \li Must exist. /// \return The value of the property or null if the entity does not have the property or an error occurs. /// \remark Must be freed using #ikarus_free. -IKA_API struct IkarusEntityValue * get_value(IkarusEntity const * entity, struct IkarusProperty const * property); +IKA_API struct IkarusEntityValue * ikarus_entity_get_value(IkarusEntity const * entity, struct IkarusProperty const * property); /// \brief Sets the value of a property of an entity. /// \param entity The entity to set the value of. @@ -138,11 +133,10 @@ IKA_API struct IkarusEntityValue * get_value(IkarusEntity const * entity, struct /// \param value The new value of the property. /// \pre \li Must not be null. /// \pre \li Must be of the same type as the property. -/// \param validate_settings If set, this function fails not only if the type of the value is invalid, but also if it's not -/// valid under the properties settings. \see property.h +/// \pre \li Must be valid for the property's settings. /// \remark If the entity does not have the property, this function fails. IKA_API void ikarus_entity_set_value( - IkarusEntity * entity, struct IkarusProperty const * property, struct IkarusValue * value, bool validate_settings + IkarusEntity * entity, struct IkarusProperty const * property, struct IkarusValue const * value ); /// \brief Casts an entity to an object. @@ -151,7 +145,10 @@ IKA_API void ikarus_entity_set_value( /// \pre \li Must exist. /// \return The entity represented as an object or null if an error occurs. /// \remark This operation is guaranteed to be very fast and is intended to be used frequently. -IKA_API struct IkarusObject * ikarus_entity_to_object(IkarusEntity const * entity); +IKA_API struct IkarusObject * ikarus_entity_to_object(IkarusEntity * entity); + +/// \see ikarus_entity_to_object +IKA_API struct IkarusObject const * ikarus_entity_to_object_const(IkarusEntity const * entity); IKARUS_END_HEADER diff --git a/include/ikarus/objects/object.h b/include/ikarus/objects/object.h index 256e8a0..a2cce6a 100644 --- a/include/ikarus/objects/object.h +++ b/include/ikarus/objects/object.h @@ -41,6 +41,18 @@ IKA_API void ikarus_object_visit( void * data ); +/// \see ikarus_object_visit +IKA_API void ikarus_object_visit_const( + IkarusObject const * object, + void (*blueprint_visitor)(struct IkarusBlueprint const *, void *), + void (*property_visitor)(struct IkarusProperty const *, void *), + void (*entity_visitor)(struct IkarusEntity const *, void *), + void (*blueprint_folder_visitor)(struct IkarusBlueprintFolder const *, void *), + void (*property_folder_visitor)(struct IkarusPropertyFolder const *, void *), + void (*entity_folder_visitor)(struct IkarusEntityFolder const *, void *), + void * data +); + IKARUS_END_HEADER // @} diff --git a/include/ikarus/objects/object_type.h b/include/ikarus/objects/object_type.h index 73f724b..2539e2d 100644 --- a/include/ikarus/objects/object_type.h +++ b/include/ikarus/objects/object_type.h @@ -10,10 +10,7 @@ IKARUS_BEGIN_HEADER -// IMPLEMENTATION_DETAIL_OBJECT_TYPES - /// \brief The type of an object. -/// \remark The folder types are identical to their counterparts in #IkarusFolderType. enum IkarusObjectType { /// \brief Not an object or no object. IkarusObjectType_None = 0, diff --git a/include/ikarus/objects/properties/number_property.h b/include/ikarus/objects/properties/number_property.h new file mode 100644 index 0000000..9045140 --- /dev/null +++ b/include/ikarus/objects/properties/number_property.h @@ -0,0 +1,25 @@ +#pragma once + +/// \file number_property.h +/// \author Folling + +#include + +/// \addtogroup properties Properties +/// \brief Number properties store a numeric value. (e.g. "Weight" or "Age") +/// @{ + +IKARUS_BEGIN_HEADER + +struct IkarusNumberProperty; + +IKA_API IkarusNumberProperty * ikarus_number_property_create( + struct IkarusProject * project, + char const * name, + struct IkarusPropertySource * property_source, + struct IkarusNumberSettings * settings +); + +IKARUS_END_HEADER + +/// @} diff --git a/include/ikarus/objects/property.h b/include/ikarus/objects/properties/property.h similarity index 62% rename from include/ikarus/objects/property.h rename to include/ikarus/objects/properties/property.h index a62a821..f1ebf49 100644 --- a/include/ikarus/objects/property.h +++ b/include/ikarus/objects/properties/property.h @@ -1,12 +1,10 @@ #pragma once -// IMPLEMENTATION_DETAIL_LAZY_VALUE_CREATION - /// \file property.h /// \author Folling #include -#include +#include #include /// \defgroup properties Properties @@ -52,33 +50,12 @@ IKARUS_BEGIN_HEADER /// \remark Properties' tree structures are scoped to the entity or blueprint they are associated with. struct IkarusProperty; -/// \brief Creates a property -/// \param project The project the property is part of. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param property_source The property source the property is part of. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param name The name of the property. -/// \pre \li Must not be null. -/// \pre \li Must not be empty. -/// \param property_info The info of the property. -/// \pre \li Must not be null. -/// \return The created property or null if an error occurs. -/// \remark Must be freed using #ikarus_free. -IKA_API struct IkarusProperty * ikarus_property_create( - struct IkarusProject * project, - struct IkarusPropertySource * property_source, - char const * name, - struct IkarusPropertyTypeInfo * property_info -); - /// \brief Deletes a property. /// \param property The property to delete. /// \pre \li Must not be null. /// \pre \li Must exist. /// \remark The property must not be accessed after deletion. -IKA_API void ikarus_property_delete(struct IkarusProperty * property); +IKA_API void ikarus_property_delete(IkarusProperty * property); /// \brief Gets the type info of a property. /// \param property The property to get the type info of. @@ -86,7 +63,18 @@ IKA_API void ikarus_property_delete(struct IkarusProperty * property); /// \pre \li Must exist. /// \return The type info of the property or null if an error occurs. /// \remark Must be freed using #ikarus_free. -IKA_API struct IkarusPropertyTypeInfo * ikarus_property_get_type_info(IkarusProperty const * property); +IKA_API IkarusPropertyType ikarus_property_get_type(IkarusProperty const * property); + +/// \brief Gets the settings of a property. +/// \param property The property to get the settings of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \return The settings of the property or null if an error occurs. +/// \remark Must be freed using #ikarus_free. +IKA_API struct IkarusPropertySettings * ikarus_property_get_settings(IkarusProperty * property); + +/// \see ikarus_property_get_settings +IKA_API struct IkarusPropertySettings const * ikarus_property_get_settings_const(IkarusProperty const * property); /// \brief Gets the source of a property. /// \param property The property to get the source of. @@ -94,25 +82,31 @@ IKA_API struct IkarusPropertyTypeInfo * ikarus_property_get_type_info(IkarusProp /// \pre \li Must exist. /// \return The source of the property or null if an error occurs. /// \remark Must be freed using #ikarus_free. -IKA_API struct IkarusPropertySource * ikarus_property_get_source(IkarusProperty const * property); +IKA_API struct IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * property); -/// \brief Gets the default value of a property. -/// \param property The property to get the default value of. +/// \brief Visits a property. Calling the appropriate function for the property's type. +/// \param property The property to visit. /// \pre \li Must not be null. /// \pre \li Must exist. -/// \return The default value of the property or null if an error occurs. -/// \remark Must be freed using #ikarus_free. -IKA_API struct IkarusValue * ikarus_property_get_default_value(IkarusProperty const * property); +/// \param toggle_property The function to call if the property is a toggle property. Skipped if null. +/// \param number_property The function to call if the property is a number property. Skipped if null. +/// \param text_property The function to call if the property is a text property. Skipped if null. +/// \param data The data to pass to the functions. +IKA_API void ikarus_property_visit( + IkarusProperty * property, + void (*toggle_property)(struct IkarusToggleProperty *, void *), + void (*number_property)(struct IkarusNumberProperty *, void *), + void (*text_property)(struct IkarusTextProperty *, void *), + void * data +); -/// \brief Sets the type info of a property and resets all values to the new default value. -/// \param property The property to set the type info of. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param new_type The new type info of the property. -/// \param attempt_conversion Whether to attempt to convert the property's values to the new type info. Conversion rules are -/// unspecified for now, but follow common sense. -IKA_API void ikarus_property_set_type_info( - IkarusProperty * property, struct IkarusPropertyTypeInfo new_type_info, bool attempt_conversion +/// \see ikarus_property_visit +IKA_API void ikarus_property_visit_const( + IkarusProperty const * property, + void (*toggle_property)(struct IkarusToggleProperty const *, void *), + void (*number_property)(struct IkarusNumberProperty const *, void *), + void (*text_property)(struct IkarusTextProperty const *, void *), + void * data ); /// \brief Casts a property to an object. @@ -121,7 +115,10 @@ IKA_API void ikarus_property_set_type_info( /// \pre \li Must exist. /// \return The property represented as an object or null if an error occurs. /// \remark This operation is guaranteed to be very fast and is intended to be used frequently. -IKA_API struct IkarusObject * ikarus_property_to_object(IkarusProperty const * property); +IKA_API struct IkarusObject * ikarus_property_to_object(IkarusProperty * property); + +/// \see ikarus_property_to_object +IKA_API struct IkarusObject const * ikarus_property_to_object_const(IkarusProperty const * property); IKARUS_END_HEADER diff --git a/include/ikarus/objects/property_source.h b/include/ikarus/objects/properties/property_source.h similarity index 69% rename from include/ikarus/objects/property_source.h rename to include/ikarus/objects/properties/property_source.h index 4dbcd47..275baa4 100644 --- a/include/ikarus/objects/property_source.h +++ b/include/ikarus/objects/properties/property_source.h @@ -10,7 +10,7 @@ IKARUS_BEGIN_HEADER -struct PropertySource; +struct IkarusPropertySource; /// \brief Creates an blueprint property source. /// \param blueprint The blueprint to create the property source for. @@ -18,7 +18,7 @@ struct PropertySource; /// \pre \li Must exist. /// \return The created property source or null if an error occurs. /// \remark Must be freed using #ikarus_free. -IKA_API struct PropertySource * ikarus_property_source_create_blueprint(struct IkarusBlueprint * blueprint); +IKA_API struct IkarusPropertySource * ikarus_property_source_create_blueprint(struct IkarusBlueprint * blueprint); /// \brief Creates an entity property source. /// \param entity The entity to create the property source for. @@ -26,7 +26,7 @@ IKA_API struct PropertySource * ikarus_property_source_create_blueprint(struct I /// \pre \li Must exist. /// \return The created property source or null if an error occurs. /// \remark Must be freed using #ikarus_free. -IKA_API struct PropertySource * ikarus_property_source_create_entity(struct IkarusEntity * entity); +IKA_API struct IkarusPropertySource * ikarus_property_source_create_entity(struct IkarusEntity * entity); /// \brief Visits a property source, calling the appropriate callback. /// \param property_source The property source to visit. @@ -36,12 +36,20 @@ IKA_API struct PropertySource * ikarus_property_source_create_entity(struct Ikar /// \param entity_visitor The callback to call if the source is an entity, skipped if null. /// \param user_data User data to pass to the callbacks. IKA_API void ikarus_property_source_visit( - struct PropertySource * property_source, + struct IkarusPropertySource * property_source, void (*blueprint_visitor)(struct IkarusBlueprint *, void *), void (*entity_visitor)(struct IkarusEntity *, void *), void * user_data ); +/// \see ikarus_property_source_visit +IKA_API void ikarus_property_source_visit_const( + struct IkarusPropertySource const * property_source, + void (*blueprint_visitor)(struct IkarusBlueprint const *, void *), + void (*entity_visitor)(struct IkarusEntity const *, void *), + void * user_data +); + IKARUS_END_HEADER /// @} diff --git a/include/ikarus/objects/property_type.h b/include/ikarus/objects/properties/property_type.h similarity index 96% rename from include/ikarus/objects/property_type.h rename to include/ikarus/objects/properties/property_type.h index e26b1f0..89e5fa1 100644 --- a/include/ikarus/objects/property_type.h +++ b/include/ikarus/objects/properties/property_type.h @@ -1,7 +1,5 @@ #pragma once -// IMPLEMENTATION_DETAIL_PROPERTY_TYPES - /// \file property_type.h /// \author Folling diff --git a/include/ikarus/objects/properties/settings/number_property_settings.h b/include/ikarus/objects/properties/settings/number_property_settings.h new file mode 100644 index 0000000..fcdaee8 --- /dev/null +++ b/include/ikarus/objects/properties/settings/number_property_settings.h @@ -0,0 +1,31 @@ +#pragma once + +/// \file number_property_settings.h +/// \author Folling + +#include + +/// \addtogroup property_settings PropertySettings +/// \brief Number property settings add additional constraints to number properties. +/// \details The following settings are available: +/// +/// @{ + +IKARUS_BEGIN_HEADER + +struct IkarusNumberPropertySettings; + +/// \brief Sets the default value for a number property. +/// \param settings The number property settings. +/// \pre \li Must not be null. +/// \param default_value The default value. +/// \pre \li Must not be null. +/// \pre \li Must be a valid value for the property. +/// \remark The settings take ownership of the value, the caller must not free it. +IKA_API void ikarus_number_property_settings_set_default_value( + struct IkarusNumberPropertySettings * settings, struct IkarusNumberValue * default_value +); + +IKARUS_END_HEADER + +/// @} diff --git a/include/ikarus/objects/properties/settings/property_settings.h b/include/ikarus/objects/properties/settings/property_settings.h new file mode 100644 index 0000000..359097c --- /dev/null +++ b/include/ikarus/objects/properties/settings/property_settings.h @@ -0,0 +1,92 @@ +#pragma once + +/// \file property_settings.h +/// \author Folling + +#include + +/// \defgroup property_settings PropertySettings +/// \brief Property settings add additional constraints to properties. +/// \details Each property has a certain set of settings. The options available depend on the type of the property. +/// Settings can be changed after the property has been created. Examples of settings are: +/// Note that the default value must be set using the concrete subtypes to ascertain type correctness. +/// - Minimum: The minimum value for a number property. +/// - Matches: A regular expression that the value of a text property must match. +/// There are also some common settings, shared among all properties: +/// - Default Value (default: PropertyType's default default (sic) value): The value that is returned if no value is specified +/// for some entity. +/// - List (default: false): If set to true, the property becomes a list. Instead of one number, you could then specify a series +/// of numbers. Note that each element in the list is subject to changes in values. E.g. when we say that all values are changed +/// in some way (e.g. reset to the default value), this applies to all elements in the list. +/// - Allow undefined (default: false): If set to true, you can specify an "unknown" value for a property. +/// It might not be known if a character is dead or not for example. +/// @{ + +IKARUS_BEGIN_HEADER + +struct IkarusPropertySettings; + +/// \brief Gets the default value of a property. +/// \param settings The settings to get the default value of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \return The default value of the property or null if an error occurs. +/// \remark Must be freed using #ikarus_free. +IKA_API struct IkarusValue const * ikarus_property_settings_get_default_value(IkarusPropertySettings const * settings); + +/// \brief Fetches whether a property is a list. +/// \param settings The property settings. +/// \pre \li Must not be null. +/// \return True if the property is a list, false otherwise. +IKA_API bool ikarus_property_settings_is_list(IkarusPropertySettings const * settings); + +/// \brief Sets whether a property is a list. +/// \details Noop if unchanged. A change from list -> single truncates to just the first element. A change from single -> list +/// sets the first element to the current value. +/// \param settings The property settings. +/// \pre \li Must not be null. +/// \param list Whether the property should be +/// a list. +IKA_API void ikarus_property_settings_set_is_list(IkarusPropertySettings * settings, bool list); + +/// \brief Fetches whether a property may be undefined. +/// \param settings The property settings. +/// \pre \li Must not be null. +/// \return True if the property may be undefined, false otherwise. +IKA_API bool ikarus_property_settings_may_be_undefined(IkarusPropertySettings const * settings); + +/// \brief Sets whether a property may be undefined. +/// \details Noop if unchanged. If the transition is from undefined -> defined, all undefined values will be reset to the +/// default value. +/// \param settings The property settings. +/// \pre \li Must not be null. +/// \param allow_undefined Whether the property should be allowed to be undefined. +/// \param allow_undefined Whether the property should be allowed to be undefined. +IKA_API void ikarus_property_settings_set_may_be_undefined(IkarusPropertySettings * settings, bool allow_undefined); + +/// \brief Visits a property settings. Calling the appropriate function for the property's type. +/// \param settings The property settings. +/// \pre \li Must not be null. +/// \param toggle_property_visitor The function to call if the property is a toggle property. Skipped if null. +/// \param number_property_visitor The function to call if the property is a number property. Skipped if null. +/// \param text_property_visitor The function to call if the property is a text property. Skipped if null. +/// \param data Data passed to the visitors. +IKA_API void ikarus_property_settings_visit( + struct IkarusPropertySettings * settings, + void (*toggle_property_visitor)(struct IkarusTogglePropertySettings * settings, void * data), + void (*number_property_visitor)(struct IkarusNumberPropertySettings * settings, void * data), + void (*text_property_visitor)(struct IkarusTextPropertySettings * settings, void * data), + void * data +); + +IKA_API void ikarus_property_settings_visit_const( + struct IkarusPropertySettings const * settings, + void (*toggle_property_visitor)(struct IkarusTogglePropertySettings const * settings, void * data), + void (*number_property_visitor)(struct IkarusNumberPropertySettings const * settings, void * data), + void (*text_property_visitor)(struct IkarusTextPropertySettings const * settings, void * data), + void * data +); + +IKARUS_END_HEADER + +/// @} diff --git a/include/ikarus/objects/properties/settings/text_property_settings.h b/include/ikarus/objects/properties/settings/text_property_settings.h new file mode 100644 index 0000000..926058d --- /dev/null +++ b/include/ikarus/objects/properties/settings/text_property_settings.h @@ -0,0 +1,31 @@ +#pragma once + +/// \file text_property_settings.h +/// \author Folling + +#include + +/// \addtogroup property_settings PropertySettings +/// \brief Text property settings add additional constraints to text properties. +/// \details The following settings are available: +/// +/// @{ + +IKARUS_BEGIN_HEADER + +struct IkarusTextPropertySettings; + +/// \brief Sets the default value for a text property. +/// \param settings The text property settings. +/// \pre \li Must not be null. +/// \param default_value The default value. +/// \pre \li Must not be null. +/// \pre \li Must be a valid value for the property. +/// \remark The settings take ownership of the value, the caller must not free it. +IKA_API void ikarus_text_property_settings_set_default_value( + struct IkarusTextPropertySettings * settings, struct IkarusTextValue * default_value +); + +IKARUS_END_HEADER + +/// @} diff --git a/include/ikarus/objects/properties/settings/toggle_property_settings.h b/include/ikarus/objects/properties/settings/toggle_property_settings.h new file mode 100644 index 0000000..d372929 --- /dev/null +++ b/include/ikarus/objects/properties/settings/toggle_property_settings.h @@ -0,0 +1,31 @@ +#pragma once + +/// \file toggle_property_settings.h +/// \author Folling + +#include + +/// \addtogroup property_settings PropertySettings +/// \brief Toggle property settings add additional constraints to toggle properties. +/// \details The following settings are available: +/// +/// @{ + +IKARUS_BEGIN_HEADER + +struct IkarusTogglePropertySettings; + +/// \brief Sets the default value for a toggle property. +/// \param settings The toggle property settings. +/// \pre \li Must not be null. +/// \param default_value The default value. +/// \pre \li Must not be null. +/// \pre \li Must be a valid value for the property. +/// \remark The settings take ownership of the value, the caller must not free it. +IKA_API void ikarus_toggle_property_settings_set_default_value( + struct IkarusTogglePropertySettings * settings, struct IkarusToggleValue * default_value +); + +IKARUS_END_HEADER + +/// @} diff --git a/include/ikarus/objects/properties/text_property.h b/include/ikarus/objects/properties/text_property.h new file mode 100644 index 0000000..f7975b3 --- /dev/null +++ b/include/ikarus/objects/properties/text_property.h @@ -0,0 +1,25 @@ +#pragma once + +/// \file text_property.h +/// \author Folling + +#include + +/// \addtogroup properties Properties +/// \brief Text properties store an arbitrary piece of text. (e.g. "Firstname" or "Description") +/// @{ + +IKARUS_BEGIN_HEADER + +struct IkarusTextProperty; + +IKA_API IkarusTextProperty * ikarus_text_property_create( + struct IkarusProject * project, + char const * name, + struct IkarusPropertySource * property_source, + struct IkarusTextSettings * settings +); + +IKARUS_END_HEADER + +/// @} diff --git a/include/ikarus/objects/properties/toggle_property.h b/include/ikarus/objects/properties/toggle_property.h new file mode 100644 index 0000000..baa0801 --- /dev/null +++ b/include/ikarus/objects/properties/toggle_property.h @@ -0,0 +1,25 @@ +#pragma once + +/// \file toggle_property.h +/// \author Folling + +#include + +/// \addtogroup properties Properties +/// \brief Toggle properties store a value that can be either true or false. (e.g. "Is the character dead?") +/// @{ + +IKARUS_BEGIN_HEADER + +struct IkarusToggleProperty; + +IKA_API IkarusToggleProperty * ikarus_toggle_property_create( + struct IkarusProject * project, + char const * name, + struct IkarusPropertySource * property_source, + struct IkarusToggleSettings * settings +); + +IKARUS_END_HEADER + +/// @} diff --git a/include/ikarus/objects/property_type_info.h b/include/ikarus/objects/property_type_info.h deleted file mode 100644 index cd7b6b9..0000000 --- a/include/ikarus/objects/property_type_info.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once - -/// \file property_info.h -/// \author Folling - -#include - -/// \addtogroup properties Properties -/// @{ - -IKARUS_BEGIN_HEADER - -/// \brief Information about a property. -/// \details Property information includes their type and settings consolidated to ascertain type safety. -struct IkarusPropertyTypeInfo; - -/// \brief Information about a toggle property. -struct IkarusTogglePropertyInfo; - -/// \brief Information about a number property. -struct IkarusNumberPropertyInfo; - -/// \brief Information about a text property. -struct IkarusTextPropertyInfo; - -/// \brief Creates a new toggle property info. -/// \return The created toggle property info. -/// \remark Must be freed with #ikarus_free. -IKA_API IkarusTogglePropertyInfo * ikarus_toggle_property_info_create(); -/// \brief Sets the default value of a toggle property info. -/// \param toggle_property_info The toggle property info to set the default value of. -/// \pre \li Must not be null. -/// \param default_value The default value to set. -/// \pre \li Must not be null. -IKA_API void ikarus_toggle_property_info_set_default_value( - IkarusTogglePropertyInfo * toggle_property_info, struct IkarusToggleValue * default_value -); -/// \brief Converts a toggle property info to a generic property info. -/// \param toggle_property_info The toggle property info to convert. -/// \return The converted property info. -IKA_API IkarusPropertyTypeInfo * ikarus_toggle_property_info_to_property_info(IkarusTogglePropertyInfo * toggle_property_info); - -/// \brief Creates a new number property info. -/// \return The created number property info. -/// \remark Must be freed with #ikarus_free. -IKA_API IkarusNumberPropertyInfo * ikarus_number_property_info_create(); -/// \brief Sets the default value of a number property info. -/// \param number_property_info The number property info to set the default value of. -/// \pre \li Must not be null. -/// \param default_value The default value to set. -/// \pre \li Must not be null. -IKA_API void ikarus_number_property_info_set_default_value( - IkarusNumberPropertyInfo * number_property_info, struct IkarusNumberValue * default_value -); -/// \brief Converts a number property info to a generic property info. -/// \param number_property_info The number property info to convert. -/// \return The converted property info. -IKA_API IkarusPropertyTypeInfo * ikarus_number_property_info_to_property_info(IkarusNumberPropertyInfo * number_property_info); - -/// \brief Creates a new text property info. -/// \return The created text property info. -/// \remark Must be freed with #ikarus_free. -IKA_API IkarusTextPropertyInfo * ikarus_text_property_info_create(); -/// \brief Sets the default value of a text property info. -/// \param text_property_info The text property info to set the default value of. -/// \pre \li Must not be null. -/// \param default_value The default value to set. -/// \pre \li Must not be null. -IKA_API void ikarus_text_property_info_set_default_value( - IkarusTextPropertyInfo * text_property_info, struct IkarusTextValue * default_value -); -/// \brief Converts a text property info to a generic property info. -/// \param text_property_info The text property info to convert. -/// \return The converted property info. -IKA_API IkarusPropertyTypeInfo * ikarus_text_property_info_to_property_info(IkarusTextPropertyInfo * text_property_info); - -IKARUS_END_HEADER - -/// @} diff --git a/include/ikarus/values/number_value.h b/include/ikarus/values/number_value.h new file mode 100644 index 0000000..2c054f8 --- /dev/null +++ b/include/ikarus/values/number_value.h @@ -0,0 +1,44 @@ +#pragma once + +/// \file number_value.h +/// \author Folling + +#include + +/// \addtogroup entity_value Entity Values +/// @{ + +IKARUS_BEGIN_HEADER + +/// \brief A true/false boolean-like value. For example "IsDead". +struct IkarusNumberValue; + +/// \brief Creates a number value from a long double. +/// \param value The numeric value. +/// \return The entity value. +/// \remark Must be freed with #ikarus_free. +IKA_API IkarusNumberValue * ikarus_number_value_create(long double value); + +/// \brief Creates an indeterminate number value. +/// \return The entity value. +/// \remark Must be freed with #ikarus_free. +IKA_API IkarusNumberValue * ikarus_number_value_create_indeterminate(); + +/// \brief Sets the value of a number value. +/// \param value The number value. +/// \pre \li Must not be null. +/// \param new_value The new value. +IKA_API void ikarus_number_value_set(IkarusNumberValue * value, bool new_value); + +/// \brief Fetches the underlying value of a number value. +/// \param value The number value. +/// \return The underlying value. +/// \warning If the value is indeterminate, false is returned. +IKA_API long double ikarus_number_value_get_underlying(IkarusNumberValue const * value); + +/// \brief Converts a number value to an entity value. +/// \param number_value The number value to convert. +/// \return The converted entity value. +IKA_API struct IkarusEntityValue * ikarus_number_value_to_entity_value(IkarusNumberValue * number_value); + +IKARUS_END_HEADER diff --git a/include/ikarus/values/text_value.h b/include/ikarus/values/text_value.h new file mode 100644 index 0000000..867a638 --- /dev/null +++ b/include/ikarus/values/text_value.h @@ -0,0 +1,44 @@ +#pragma once + +/// \file text_value.h +/// \author Folling + +#include + +/// \addtogroup entity_value Entity Values +/// @{ + +IKARUS_BEGIN_HEADER + +/// \brief A true/false boolean-like value. For example "IsDead". +struct IkarusTextValue; + +/// \brief Creates a text value from a boolean. +/// \param value The text value. +/// \return The entity value. +/// \remark Must be freed with #ikarus_free. +IKA_API IkarusTextValue * ikarus_text_value_create(char const * value); + +/// \brief Creates an indeterminate text value. +/// \return The entity value. +/// \remark Must be freed with #ikarus_free. +IKA_API IkarusTextValue * ikarus_text_value_create_indeterminate(); + +/// \brief Sets the value of a text value. +/// \param value The text value. +/// \pre \li Must not be null. +/// \param new_value The new value. +IKA_API void ikarus_text_value_set(IkarusTextValue * value, bool new_value); + +/// \brief Fetches the underlying value of a text value. +/// \param value The text value. +/// \return The underlying value. +/// \warning If the value is indeterminate, false is returned. +IKA_API char const * ikarus_text_value_get_underlying(IkarusTextValue const * value); + +/// \brief Converts a text value to an entity value. +/// \param text_value The text value to convert. +/// \return The converted entity value. +IKA_API struct IkarusEntityValue * ikarus_text_value_to_entity_value(IkarusTextValue * text_value); + +IKARUS_END_HEADER diff --git a/include/ikarus/values/toggle_value.h b/include/ikarus/values/toggle_value.h new file mode 100644 index 0000000..7c77870 --- /dev/null +++ b/include/ikarus/values/toggle_value.h @@ -0,0 +1,44 @@ +#pragma once + +/// \file toggle_value.h +/// \author Folling + +#include + +/// \addtogroup entity_value Entity Values +/// @{ + +IKARUS_BEGIN_HEADER + +/// \brief A true/false boolean-like value. For example "IsDead". +struct IkarusToggleValue; + +/// \brief Creates a toggle value from a boolean. +/// \param value The toggle value. +/// \return The entity value. +/// \remark Must be freed with #ikarus_free. +IKA_API IkarusToggleValue * ikarus_toggle_value_create(bool value); + +/// \brief Creates an indeterminate toggle value. +/// \return The entity value. +/// \remark Must be freed with #ikarus_free. +IKA_API IkarusToggleValue * ikarus_toggle_value_create_indeterminate(); + +/// \brief Sets the value of a toggle value. +/// \param value The toggle value. +/// \pre \li Must not be null. +/// \param new_value The new value. +IKA_API void ikarus_toggle_value_set(IkarusToggleValue * value, bool new_value); + +/// \brief Fetches the underlying value of a toggle value. +/// \param value The toggle value. +/// \return The underlying value. +/// \warning If the value is indeterminate, false is returned. +IKA_API bool ikarus_toggle_value_get_underlying(IkarusToggleValue const * value); + +/// \brief Converts a toggle value to an entity value. +/// \param toggle_value The toggle value to convert. +/// \return The converted entity value. +IKA_API struct IkarusEntityValue * ikarus_toggle_value_to_entity_value(IkarusToggleValue * toggle_value); + +IKARUS_END_HEADER diff --git a/include/ikarus/values/value.h b/include/ikarus/values/value.h index a30cf2d..fd17f5b 100644 --- a/include/ikarus/values/value.h +++ b/include/ikarus/values/value.h @@ -1,16 +1,11 @@ #pragma once -// IMPLEMENTATION_DETAIL_PROPERTY_TYPES - /// \file value.h /// \author Folling #include -#include #include -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. @@ -19,112 +14,47 @@ IKARUS_BEGIN_HEADER /// \see PropertyType PropertySettings /// @{ -/// \brief A true/false boolean-like value. For example "IsDead". -struct IkarusToggleValue; +IKARUS_BEGIN_HEADER -/// \brief An arbitrary numeric value. For example "Age". -struct IkarusNumberValue; +/// \brief The common type for all values. +struct IkarusValue; -/// \brief An arbitrary textual value. For example "First Name". -struct IkarusTextValue; - -/// \brief The value of an entity associated with a property. -struct IkarusEntityValue; - -/// \brief Creates a toggle value from a boolean. -/// \param value The toggle value. -/// \return The entity value. -/// \remark Must be freed with #ikarus_free. -IKA_API IkarusToggleValue * ikarus_toggle_value_create(bool value); -/// \brief Creates an indeterminate toggle value. -/// \return The entity value. -/// \remark Must be freed with #ikarus_free. -IKA_API IkarusToggleValue * ikarus_toggle_value_create_indeterminate(); -/// \brief Sets the value of a toggle value. -/// \param value The toggle value. -/// \pre Must not be null. -/// \param new_value The new value. -IKA_API void ikarus_toggle_value_set(IkarusToggleValue * value, bool new_value); - -/// \brief Creates a number value from a number. -/// \param value The number value. -/// \pre Must be finite & not NaN. -/// \return The entity value. -/// \remark Must be freed with #ikarus_free. -IKA_API IkarusNumberValue * ikarus_number_value_create(long double value); -/// \brief Creates an indeterminate number value. -/// \return The entity value. -/// \remark Must be freed with #ikarus_free. -IKA_API IkarusNumberValue * ikarus_number_value_create_indeterminate(); -/// \brief Sets the value of a number value. -/// \param value The number value. -/// \pre Must not be null. -/// \param new_value The new value. -IKA_API void ikarus_number_value_set(IkarusNumberValue * value, bool new_value); - -/// \brief Creates a text value from string. -/// \param value The text value. -/// \pre Must not be null. -/// \return The entity value. -/// \remark Must be freed with #ikarus_free. -IKA_API IkarusTextValue * ikarus_text_value_create(char const * value); -/// \brief Creates an indeterminate text value. -/// \return The entity value. -/// \remark Must be freed with #ikarus_free. -IKA_API IkarusTextValue * ikarus_text_value_create_indeterminate(); -/// \brief Sets the value of a text value. -/// \param value The text value. -/// \pre Must not be null. -/// \param new_value The new value. -IKA_API void ikarus_text_value_set(IkarusTextValue * value, bool new_value); - -/// \brief Checks if a toggle value is indeterminate. -/// \param value The toggle value. -/// \pre Must not be null. +/// \brief Checks if a value is indeterminate. +/// \param value The value. +/// \pre \li Must not be null. /// \return True if the value is indeterminate, false otherwise. -IKA_API bool ikarus_toggle_value_is_indeterminate(IkarusToggleValue const * value); -/// \brief Checks if a number value is indeterminate. -/// \param value The number value. -/// \pre Must not be null. -/// \return True if the value is indeterminate, false otherwise. -IKA_API bool ikarus_number_value_is_indeterminate(IkarusNumberValue const * value); -/// \brief Checks if a text value is indeterminate. -/// \param value The text value. -/// \pre Must not be null. -/// \return True if the value is indeterminate, false otherwise. -IKA_API bool ikarus_text_value_is_indeterminate(IkarusTextValue const * value); +IKA_API bool ikarus_value_is_indeterminate(IkarusValue const * value); -/// \brief Fetches the underlying value of a toggle value. -/// \param value The toggle value. -/// \return The underlying value. -/// \warning If the value is indeterminate, false is returned. -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. -/// \warning If the value is indeterminate, 0.0 is returned. -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 A copy of the underlying value. -/// \remark The returned value is a copy and owned by the caller. -/// \warning If the value is indeterminate, an empty string is returned. -IKA_API char const * ikarus_text_value_get_underlying(IkarusTextValue const * value); +// \brief Converts an entity value to a string. +// \pre \li Must not be null. +// \param value The entity value. +// \return A string representation of the value or null if an error occurred. +// \remark The returned value is a copy and owned by the caller. +IKA_API char const * ikarus_value_to_string(IkarusValue 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. Skipped if null. -/// \param number The function to call if the value is a number value. Skipped if null. -/// \param text 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. 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 data The data passed to the visitor functions. IKA_API void ikarus_value_visit( - IkarusEntityValue * value, - void (*toggle)(IkarusToggleValue *, void *), - void (*number)(IkarusNumberValue *, void *), - void (*text)(IkarusTextValue *, void *), + IkarusValue * value, + void (*toggle_visitor)(struct IkarusToggleValue *, void *), + void (*number_visitor)(struct IkarusNumberValue *, void *), + void (*text_visitor)(struct IkarusTextValue *, void *), + void * data +); + +/// \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 ); IKARUS_END_HEADER + +/// @} diff --git a/src/objects/blueprint.cpp b/src/objects/blueprint.cpp index 63ce726..df059ac 100644 --- a/src/objects/blueprint.cpp +++ b/src/objects/blueprint.cpp @@ -5,10 +5,7 @@ #include #include -#include -#include -#include #include #include #include diff --git a/src/objects/property.cpp b/src/objects/property.cpp new file mode 100644 index 0000000..ba11491 --- /dev/null +++ b/src/objects/property.cpp @@ -0,0 +1,87 @@ +#include "property.hpp" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +IkarusProperty * ikarus_property_create( + struct IkarusProject * project, + char const * name, + struct IkarusPropertySource * property_source, + struct IkarusPropertyInfo * property_info +) { + LOG_INFO("creating new property"); + + if (project == nullptr) { + LOG_ERROR("project is nullptr"); + return nullptr; + } + + auto ctx = project->function_context(); + + if (property_source == nullptr) { + ctx->set_error("property_source is nullptr", true, IkarusErrorInfo_Source_Client, IkarusErrorInfo_Type_Client_Input); + return nullptr; + } + + if (name == nullptr) { + ctx->set_error("name is nullptr", true, IkarusErrorInfo_Source_Client, IkarusErrorInfo_Type_Client_Input); + return nullptr; + } + + if (cppbase::is_empty_or_blank(name)) { + ctx->set_error("name is empty or blank", true, IkarusErrorInfo_Source_Client, IkarusErrorInfo_Type_Client_Input); + return nullptr; + } + + if (property_info == nullptr) { + ctx->set_error("property_info is nullptr", true, IkarusErrorInfo_Source_Client, IkarusErrorInfo_Type_Client_Input); + return nullptr; + } + + LOG_VERBOSE( + "project={}; name={}; property_source={}; property_info={}", + project->path().c_str(), + name, + std::visit( + cppbase::overload{ + [](IkarusBlueprint * blueprint) { return fmt::format("Blueprint({})", blueprint->id); }, + [](IkarusEntity * entity) { return fmt::format("Entity({})", entity->id); }}, + property_source->data + ), + std::visit( + cppbase::overload{ + [](IkarusTogglePropertyInfo * info) { + return fmt::format( + "Toggle(default_value={})", + cppbase::OwningString{ikarus_value_to_string(ikarus_toggle_value_to_entity_value(info->default_value))} + .data + ); + }, + [](IkarusNumberPropertyInfo * info) { + return fmt::format( + "Number(default_value={})", + cppbase::OwningString{ikarus_value_to_string(ikarus_number_value_to_entity_value(info->default_value))} + .data + ); + }, + [](IkarusTextPropertyInfo * info) { + return fmt::format( + "Text(default_value={})", + cppbase::OwningString{ikarus_value_to_string(ikarus_text_value_to_entity_value(info->default_value))} + .data + ); + }}, + property_info->data + ) + ); +} diff --git a/src/objects/property_info.hpp b/src/objects/property_info.hpp new file mode 100644 index 0000000..8c131f7 --- /dev/null +++ b/src/objects/property_info.hpp @@ -0,0 +1,74 @@ +#pragma once + +#include + +#include + +#include +#include +#include + +// this looks a bit cursed, but there's reason to my madness: +// Let's go over the facts: +// 1. The client uses the concrete types (e.g. Ikarus"Toggle"PropertyInfo) +// 2. The API needs to accept a common type (i.e. IkarusPropertyInfo) +// 3. Casting between a concrete subtype and a common type is only defined behaviour if we use inheritance, otherwise an +// allocation is unavoidable +// 4. On the implementation side, we need to be able to distinguish between the concrete types +// +// There's a few ways to model this (using dynamic_casts, using an enum, a union, the visitor pattern, ...) but std::variant +// gives us the most type safety without any performance overhead + +/// \private +struct IkarusPropertyInfo { +public: + using IkarusPropertyInfoData = + std::variant; + +public: + inline explicit IkarusPropertyInfo( + std::variant data + ): + data{data} {} + +public: + [[nodiscard]] inline IkarusPropertyInfoData const& get_data() const { + return data; + } + +private: + IkarusPropertyInfoData data; +}; + +/// \private +struct IkarusTogglePropertyInfo : public IkarusPropertyInfo { +public: + inline IkarusTogglePropertyInfo(): + IkarusPropertyInfo{this} {} + +public: + [[nodiscard]] IkarusToggleValue * get_default_value() const {} + +private: + IkarusToggleValue * default_value{nullptr}; +}; + +/// \private +struct IkarusNumberPropertyInfo : public IkarusPropertyInfo { +public: + inline IkarusNumberPropertyInfo(): + IkarusPropertyInfo{this} {} + +private: + IkarusNumberValue * default_value{nullptr}; +}; + +/// \private +struct IkarusTextPropertyInfo : public IkarusPropertyInfo { +public: + inline IkarusTextPropertyInfo(): + IkarusPropertyInfo{this} {} + +private: + IkarusTextValue * default_value{nullptr}; +}; diff --git a/src/objects/property_source.hpp b/src/objects/property_source.hpp new file mode 100644 index 0000000..16fab4f --- /dev/null +++ b/src/objects/property_source.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +#include + +/// \private +struct IkarusPropertySource { + std::variant data; +}; diff --git a/src/persistence/project.hpp b/src/persistence/project.hpp index 5cbea00..fbb84f2 100644 --- a/src/persistence/project.hpp +++ b/src/persistence/project.hpp @@ -13,6 +13,7 @@ constexpr inline size_t MAXIMUM_ERROR_INFOS = 8; constexpr inline size_t MAXIMUM_ERROR_MESSAGE_LENGTH = 256; +/// \private class FunctionContext { public: explicit FunctionContext(struct IkarusProject * project); @@ -128,7 +129,7 @@ FunctionContext::~FunctionContext() { template requires(std::is_same_v && ...) && (sizeof...(Infos) <= MAXIMUM_ERROR_INFOS) -auto FunctionContext::set_error(std::string_view error_message, bool log_error, Infos... infos) { +auto FunctionContext::set_error(std::string_view error_message, bool log_error, Infos... infos) -> void { if (error_message.size() > _project->error_message_buffer.size()) { _project->error_message_buffer.resize(error_message.size() + 1); } diff --git a/src/values/number_value.hpp b/src/values/number_value.hpp new file mode 100644 index 0000000..51020fc --- /dev/null +++ b/src/values/number_value.hpp @@ -0,0 +1,5 @@ +#pragma once + +struct IkarusNumberValue { + long double value; +}; diff --git a/src/values/text_value.hpp b/src/values/text_value.hpp new file mode 100644 index 0000000..20880c4 --- /dev/null +++ b/src/values/text_value.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include + +/// \private +struct IkarusTextValue { + std::string value; +}; diff --git a/src/values/toggle_value.hpp b/src/values/toggle_value.hpp new file mode 100644 index 0000000..a2f2d70 --- /dev/null +++ b/src/values/toggle_value.hpp @@ -0,0 +1,6 @@ +#pragma once + +/// \private +struct IkarusToggleValue { + bool value; +};