change error system & function signatures
Signed-off-by: Folling <mail@folling.io>
This commit is contained in:
parent
1367373819
commit
e1bf97704a
28 changed files with 633 additions and 651 deletions
|
|
@ -67,7 +67,7 @@ BreakInheritanceList: AfterColon
|
||||||
BreakStringLiterals: false
|
BreakStringLiterals: false
|
||||||
|
|
||||||
ColumnLimit: 140
|
ColumnLimit: 140
|
||||||
|
CommentPragmas: '^\\.+'
|
||||||
CompactNamespaces: false
|
CompactNamespaces: false
|
||||||
ConstructorInitializerIndentWidth: 4
|
ConstructorInitializerIndentWidth: 4
|
||||||
ContinuationIndentWidth: 4
|
ContinuationIndentWidth: 4
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
Checks: >-
|
Checks: >-
|
||||||
-*,
|
-*,
|
||||||
bugprone-*, -bugprone-lambda-function-name,
|
bugprone-*, -bugprone-lambda-function-name,
|
||||||
cppcoreguidelines-*, -cppcoreguidelines-owning-memory,
|
cppcoreguidelines-*, -cppcoreguidelines-owning-memory, -cppcoreguidelines-non-private-member-variables-in-classes,
|
||||||
clang-analyzer-*,
|
clang-analyzer-*,
|
||||||
google-*, -google-readability-todo,
|
google-*, -google-readability-todo,
|
||||||
modernize-*, -modernize-use-trailing-return-type,
|
modernize-*, -modernize-use-trailing-return-type,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ A snapshot if you will.
|
||||||
One must not rely on it representing the actual state of the project at any given time. The data is simply copied
|
One must not rely on it representing the actual state of the project at any given time. The data is simply copied
|
||||||
from the underlying data sources and returned to the caller.
|
from the underlying data sources and returned to the caller.
|
||||||
|
|
||||||
No mechanisms are provided to avoid race conditions. LibIkarus itself should only be used in a single-threaded context.
|
No mechanisms are provided to avoid race conditions. libikarus itself should only be used in a single-threaded context.
|
||||||
However, nothing breaks if you do use it in a multithreaded context, that is, libikarus is threadsafe.
|
However, nothing breaks if you do use it in a multithreaded context, that is, libikarus is threadsafe.
|
||||||
You just cannot rely on the data being consistent.
|
You just cannot rely on the data being consistent.
|
||||||
This goes especially for inter-process access to the same project.
|
This goes especially for inter-process access to the same project.
|
||||||
|
|
@ -7,57 +7,111 @@
|
||||||
|
|
||||||
/// \addtogroup errors Errors
|
/// \addtogroup errors Errors
|
||||||
/// \brief Error handling within libikarus
|
/// \brief Error handling within libikarus
|
||||||
/// \details Errors are stored for each project, akin to the errno handling in C.
|
/// \details Functions in Ikarus may fail, in which case they have an out parameter for the error.
|
||||||
/// We store multiple pieces of information about the error occurring. For more information see
|
/// Upon erring the function will store relevant information about the error in the out parameter.
|
||||||
/// #ikarus_project_get_error_message.
|
/// If the out parameter is null nothing will be stored. This is not recommended as it essentially ignores errors.
|
||||||
|
/// For the sake of simplicity we have avoided mechanisms that "force" clients to handle errors.
|
||||||
|
/// Note that Ikarus does not check for null pointers. Passing null pointers to functions that do not explicitly state that they accept null
|
||||||
|
/// pointers is undefined behaviour. This decision is done for the sake of brevity and readability. `project_get_name(project)` is also
|
||||||
|
/// synonymous to `project->get_name()` in OOP languages, which shares the same semantics.
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
IKARUS_BEGIN_HEADER
|
IKARUS_BEGIN_HEADER
|
||||||
|
|
||||||
/// \brief Delineates what caused an error.
|
/// \brief Delineates what caused an error.
|
||||||
/// \details First 2 bytes delineate the major type, next 2 bytes delineate the minor type, next 4 bytes delineate the
|
|
||||||
/// detail type.
|
|
||||||
/// \remark Note that this doesn't show responsibility. An error with source "SubSystem" could still be the
|
/// \remark Note that this doesn't show responsibility. An error with source "SubSystem" could still be the
|
||||||
/// fault of libikarus.
|
/// fault of libikarus, it just indicates where the error occurred.
|
||||||
enum IkarusErrorInfo {
|
enum IkarusErrorInfo {
|
||||||
/// \brief No error occurred.
|
/// \brief No error occurred.
|
||||||
IkarusErrorInfo_Source_None = 0x0001000000000000,
|
IkarusErrorInfo_None = 0x0,
|
||||||
/// \brief The error was caused by the client.
|
/// \brief The error was caused by the client.
|
||||||
IkarusErrorInfo_Source_Client = 0x0001000000000001,
|
IkarusErrorInfo_Client = 0x10100000,
|
||||||
/// \brief The error was caused by a sub-system of libikarus.
|
/// \brief The error was caused by a dependency (e.g. boost) of libikarus.
|
||||||
IkarusErrorInfo_Source_SubSystem = 0x0001000000000002,
|
IkarusErrorInfo_Dependency = 0x10200000,
|
||||||
|
/// \brief The error was caused by the filesystem.
|
||||||
|
IkarusErrorInfo_Filesystem = 0x10300000,
|
||||||
|
/// \brief The error was caused by the database.
|
||||||
|
IkarusErrorInfo_Database = 0x10400000,
|
||||||
|
/// \brief The error was caused by the underlying OS.
|
||||||
|
IkarusErrorInfo_OS = 0x10500000,
|
||||||
/// \brief The error was caused by libikarus itself.
|
/// \brief The error was caused by libikarus itself.
|
||||||
IkarusErrorInfo_Source_LibIkarus = 0x0001000000000003,
|
IkarusErrorInfo_LibIkarus = 0x10600000,
|
||||||
/// \brief The error was caused by an unknown source.
|
|
||||||
IkarusErrorInfo_Source_Unknown = 0x00010000FFFFFFFF,
|
/// \brief The client misused the API.
|
||||||
/// \brief No error occurred.
|
|
||||||
IkarusErrorInfo_Type_None = 0x0002000000000000,
|
|
||||||
/// \brief The user misused the API.
|
|
||||||
/// Example: Accessing a resource that does not exist.
|
/// Example: Accessing a resource that does not exist.
|
||||||
IkarusErrorInfo_Type_Client_Misuse = 0x0002000100000001,
|
IkarusErrorInfo_Client_Misuse = 0x10100001,
|
||||||
/// \brief The user provided invalid input.
|
/// \brief The client provided a null value for a parameter that must not be null.
|
||||||
/// Example: Passing null for a pointer that must not be null.
|
/// Example: Passing null for `ikarus_project_get_name`
|
||||||
IkarusErrorInfo_Type_Client_Input = 0x0002000100000002,
|
IkarusErrorInfo_Client_InvalidNull = 0x10100002,
|
||||||
/// \brief An error occurred while interacting with a dependency from ikarus.
|
/// \brief The client provided an index that was out of bounds for some array.
|
||||||
/// Example: An error occurred in the underlying OS library.
|
/// Example: Passing the index 3 for an `IkarusToggleValue` with size 3.
|
||||||
IkarusErrorInfo_Type_SubSystem_Dependency = 0x0002000200000001,
|
IkarusErrorInfo_Client_IndexOutOfBounds = 0x10100003,
|
||||||
/// \brief An error occurred while interacting with the database.
|
/// \brief The client provided a numeric value that was out of bounds
|
||||||
/// Example: An error occurred while executing a query.
|
/// Example: Passing the value 2^32 to an i32 (might be passed as a string).
|
||||||
IkarusErrorInfo_Type_SubSystem_Database = 0x0002000200000002,
|
IkarusErrorInfo_Client_ValueOutOfBounds = 0x10100004,
|
||||||
/// \brief An error occurred while interacting with the filesystem.
|
/// \brief The client provided invalid input that doesn't fit in any of the other categories.
|
||||||
/// Example: An error occurred while reading a file.
|
/// Example: Passing an empty/blank string for a string that must be non-empty/-blank.
|
||||||
IkarusErrorInfo_Type_SubSystem_Filesystem = 0x0002000200000003,
|
IkarusErrorInfo_Client_InvalidInput = 0x10100005,
|
||||||
|
/// \brief The client provided valid data in an invalid format.
|
||||||
|
/// Example: Passing a malformed JSON string.
|
||||||
|
IkarusErrorInfo_Client_InvalidFormat = 0x10100006,
|
||||||
|
/// \brief The client violated a constraint.
|
||||||
|
/// \details This error is most likely caused by endusers.
|
||||||
|
/// Example: A user tries to set the age of a character to an value outside of their specified range.
|
||||||
|
IkarusErrorInfo_Client_ConstraintViolated = 0x10100007,
|
||||||
|
|
||||||
|
/// \brief A file was not found.
|
||||||
|
IkarusErrorInfo_Filesystem_NotFound = 0x10300001,
|
||||||
|
/// \brief A file or directory already exists.
|
||||||
|
IkarusErrorInfo_Filesystem_AlreadyExists = 0x10300002,
|
||||||
|
/// \brief Missing permissions to access a file or directory.
|
||||||
|
IkarusErrorInfo_Filesystem_MissingPermissions = 0x10300003,
|
||||||
|
/// \brief Insufficient space to perform an operation.
|
||||||
|
IkarusErrorInfo_Filesystem_InsufficientSpace = 0x10300004,
|
||||||
|
/// \brief A path is invalid.
|
||||||
|
IkarusErrorInfo_Filesystem_InvalidPath = 0x10300005,
|
||||||
|
|
||||||
|
/// \brief A database connection failed.
|
||||||
|
IkarusErrorInfo_Database_ConnectionFailed = 0x10400001,
|
||||||
|
/// \brief A database query failed.
|
||||||
|
IkarusErrorInfo_Database_QueryFailed = 0x10400002,
|
||||||
|
/// \brief A database migration failed.
|
||||||
|
IkarusErrorInfo_Database_MigrationFailed = 0x10400003,
|
||||||
|
/// \brief A database is in an invalid state. This indicates a corrupt project.
|
||||||
|
/// Example: An entity is linked to a non-existant blueprint.
|
||||||
|
IkarusErrorInfo_Database_InvalidState = 0x10400004,
|
||||||
|
|
||||||
|
/// \brief A system call failed.
|
||||||
|
IkarusErrorInfo_OS_SystemCallFailed = 0x10500001,
|
||||||
|
/// \brief A system call returned an invalid value.
|
||||||
|
IkarusErrorInfo_OS_InvalidReturnValue = 0x10500002,
|
||||||
|
/// \brief An OOM error occurred.
|
||||||
|
IkarusErrorInfo_OS_InsufficientMemory = 0x10500003,
|
||||||
|
|
||||||
/// \brief A datapoint within ikarus is invalid for the current state of the system.
|
/// \brief A datapoint within ikarus is invalid for the current state of the system.
|
||||||
/// Example: The name of an object is found to be invalid UTF8.
|
/// Example: The name of an object is found to be invalid UTF8.
|
||||||
IkarusErrorInfo_Type_LibIkarus_InvalidState = 0x0002000300000001,
|
IkarusErrorInfo_LibIkarus_InvalidState = 0x20030001,
|
||||||
/// \brief LibIkarus is unable to perform a certain operation that should succeed.
|
/// \brief libikarus is unable to perform a certain operation within a given timeframe.
|
||||||
/// Example: Migrating a project fails
|
|
||||||
IkarusErrorInfo_Type_LibIkarus_CannotPerformOperation = 0x0002000300000002,
|
|
||||||
/// \brief LibIkarus is unable to perform a certain operation within a given timeframe.
|
|
||||||
/// Example: A query takes longer than the timeout.
|
/// Example: A query takes longer than the timeout.
|
||||||
IkarusErrorInfo_Type_LibIkarus_Timeout = 0x0002000300000003,
|
IkarusErrorInfo_LibIkarus_Timeout = 0x20030003,
|
||||||
/// \brief The type of error is unknown.
|
};
|
||||||
IkarusErrorInfo_Type_Unknown = 0xFFFFFFFFFFFFFFFF,
|
|
||||||
|
/// \brief The data limits for an error.
|
||||||
|
enum IkarusErrorDataLimit {
|
||||||
|
/// \brief The maximum number of error infos that can be stored in an error.
|
||||||
|
IkarusErrorDataLimit_MaxErrorInfos = 8,
|
||||||
|
/// \brief The maximum length of an error message.
|
||||||
|
IkarusErrorDataLimit_MaxMessageLength = 128,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief The data stored for an error
|
||||||
|
struct IkarusErrorData {
|
||||||
|
/// \brief The scope of the error.
|
||||||
|
/// \details This array may at most hold #IkarusErrorDataLimit_MaxErrorInfos elements.
|
||||||
|
/// The first occurrence of #IkarusErrorInfo_None signifies the end of the array. If this happens at idx x== 0, no error occurred.
|
||||||
|
IkarusErrorInfo infos[IkarusErrorDataLimit_MaxErrorInfos];
|
||||||
|
|
||||||
|
char message[IkarusErrorDataLimit_MaxMessageLength];
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Gets the name of an error info.
|
/// \brief Gets the name of an error info.
|
||||||
|
|
@ -66,6 +120,20 @@ enum IkarusErrorInfo {
|
||||||
/// \remark The returned pointer is valid for the lifetime of the program and must not be freed.
|
/// \remark The returned pointer is valid for the lifetime of the program and must not be freed.
|
||||||
IKA_API char const * get_error_info_name(IkarusErrorInfo info);
|
IKA_API char const * get_error_info_name(IkarusErrorInfo info);
|
||||||
|
|
||||||
|
/// \brief Checks if an error data is a success.
|
||||||
|
/// \param data The error data to check.
|
||||||
|
/// \return True if the error data is a success, false otherwise.
|
||||||
|
IKA_API bool ikarus_error_data_is_success(IkarusErrorData const * data);
|
||||||
|
/// \brief Checks if an error data is an error.
|
||||||
|
/// \param data The error data to check.
|
||||||
|
/// \return True if the error data is an error, false otherwise.
|
||||||
|
IKA_API bool ikarus_error_data_is_error(IkarusErrorData const * data);
|
||||||
|
/// \brief Formats the error data in a reasonable but unspecified way.
|
||||||
|
/// \param data The error data to format.
|
||||||
|
/// \return The formatted error data.
|
||||||
|
/// \remark Ownership of the returned pointer is passed to the user and must be freed at their leisure using ikarus_free.
|
||||||
|
IKA_API char const * ikarus_error_data_pretty_format(IkarusErrorData const * data);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,12 @@ IKARUS_BEGIN_HEADER
|
||||||
/// To avoid ordering fiascos and potential index performance degradation we just skip the first bit.
|
/// To avoid ordering fiascos and potential index performance degradation we just skip the first bit.
|
||||||
/// - next 7 bits: #IkarusObjectType
|
/// - next 7 bits: #IkarusObjectType
|
||||||
/// - last 56 bits: incremented counter generated by the database
|
/// - last 56 bits: incremented counter generated by the database
|
||||||
using IkarusId = int64_t;
|
typedef int64_t IkarusId;
|
||||||
|
|
||||||
|
/// \brief Creates an id from the given data and type.
|
||||||
|
/// \param data The data to use for the id.
|
||||||
|
/// \param type The type to use for the id.
|
||||||
|
/// \return The created id.
|
||||||
IKA_API IkarusId ikarus_id_from_data_and_type(int64_t data, IkarusObjectType type);
|
IKA_API IkarusId ikarus_id_from_data_and_type(int64_t data, IkarusObjectType type);
|
||||||
|
|
||||||
/// \brief Fetches the object type of the given id.
|
/// \brief Fetches the object type of the given id.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
/// \file blueprint.h
|
/// \file blueprint.h
|
||||||
/// \author Folling <folling@ikarus.world>
|
/// \author Folling <folling@ikarus.world>
|
||||||
|
|
||||||
|
#include <ikarus/errors.h>
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
#include <ikarus/stdtypes.h>
|
#include <ikarus/stdtypes.h>
|
||||||
|
|
||||||
|
|
@ -24,16 +25,18 @@ struct IkarusBlueprint;
|
||||||
/// \param name The name of the blueprint.
|
/// \param name The name of the blueprint.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must not be empty.
|
/// \pre \li Must not be empty.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The created blueprint or null if an error occurs.
|
/// \return The created blueprint or null if an error occurs.
|
||||||
/// \remark Must be freed using #ikarus_free.
|
/// \remark Must be freed using #ikarus_free.
|
||||||
IKA_API IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project, char const * name);
|
IKA_API IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project, char const * name, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Deletes & frees a blueprint.
|
/// \brief Deletes & frees a blueprint.
|
||||||
/// \param blueprint The blueprint to delete.
|
/// \param blueprint The blueprint to delete.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark The blueprint must not be accessed after deletion.
|
/// \remark The blueprint must not be accessed after deletion.
|
||||||
IKA_API void ikarus_blueprint_delete(IkarusBlueprint * blueprint);
|
IKA_API void ikarus_blueprint_delete(IkarusBlueprint * blueprint, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Gets the properties of a blueprint.
|
/// \brief Gets the properties of a blueprint.
|
||||||
/// \param blueprint The blueprint to get the properties of.
|
/// \param blueprint The blueprint to get the properties of.
|
||||||
|
|
@ -42,16 +45,22 @@ IKA_API void ikarus_blueprint_delete(IkarusBlueprint * blueprint);
|
||||||
/// \param properties_out The buffer to write the properties to.
|
/// \param properties_out The buffer to write the properties to.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param properties_out_size The size of the buffer.
|
/// \param properties_out_size The size of the buffer.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \see ikarus_blueprint_get_property_count
|
/// \see ikarus_blueprint_get_property_count
|
||||||
IKA_API void
|
IKA_API void ikarus_blueprint_get_properties(
|
||||||
ikarus_blueprint_get_properties(IkarusBlueprint const * blueprint, struct IkarusProperty ** properties_out, size_t properties_out_size);
|
IkarusBlueprint const * blueprint,
|
||||||
|
struct IkarusProperty ** properties_out,
|
||||||
|
size_t properties_out_size,
|
||||||
|
IkarusErrorData * error_out
|
||||||
|
);
|
||||||
|
|
||||||
/// \brief Gets the number of properties of a blueprint.
|
/// \brief Gets the number of properties of a blueprint.
|
||||||
/// \param blueprint The blueprint to get the number of properties of.
|
/// \param blueprint The blueprint to get the number of properties of.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The number of properties or undefined if an error occurs.
|
/// \return The number of properties or undefined if an error occurs.
|
||||||
IKA_API size_t ikarus_blueprint_get_property_count(IkarusBlueprint const * blueprint);
|
IKA_API size_t ikarus_blueprint_get_property_count(IkarusBlueprint const * blueprint, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Gets the entities linked to a blueprint.
|
/// \brief Gets the entities linked to a blueprint.
|
||||||
/// \param blueprint The blueprint to get the linked entities of.
|
/// \param blueprint The blueprint to get the linked entities of.
|
||||||
|
|
@ -60,27 +69,34 @@ IKA_API size_t ikarus_blueprint_get_property_count(IkarusBlueprint const * bluep
|
||||||
/// \param entities_out The buffer to write the entities to.
|
/// \param entities_out The buffer to write the entities to.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param entities_out_size The size of the buffer.
|
/// \param entities_out_size The size of the buffer.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \see ikarus_blueprint_get_linked_entity_count
|
/// \see ikarus_blueprint_get_linked_entity_count
|
||||||
IKA_API void
|
IKA_API void ikarus_blueprint_get_linked_entities(
|
||||||
ikarus_blueprint_get_linked_entities(IkarusBlueprint const * blueprint, struct IkarusEntity ** entities_out, size_t entities_out_size);
|
IkarusBlueprint const * blueprint,
|
||||||
|
struct IkarusEntity ** entities_out,
|
||||||
|
size_t entities_out_size,
|
||||||
|
IkarusErrorData * error_out
|
||||||
|
);
|
||||||
|
|
||||||
/// \brief Gets the number of entities linked to a blueprint.
|
/// \brief Gets the number of entities linked to a blueprint.
|
||||||
/// \param blueprint The blueprint to get the number of linked entities of.
|
/// \param blueprint The blueprint to get the number of linked entities of.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The number of linked entities or undefined if an error occurs.
|
/// \return The number of linked entities or undefined if an error occurs.
|
||||||
IKA_API size_t ikarus_blueprint_get_linked_entity_count(IkarusBlueprint const * blueprint);
|
IKA_API size_t ikarus_blueprint_get_linked_entity_count(IkarusBlueprint const * blueprint, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Casts a blueprint to an object.
|
/// \brief Casts a blueprint to an object.
|
||||||
/// \param blueprint The blueprint to cast.
|
/// \param blueprint The blueprint to cast.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The blueprint represented as an object or null if an error occurs.
|
/// \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.
|
/// \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 * blueprint);
|
IKA_API struct IkarusObject * ikarus_blueprint_to_object(IkarusBlueprint * blueprint, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \see ikarus_blueprint_to_object
|
/// \see ikarus_blueprint_to_object
|
||||||
IKA_API struct IkarusObject const * ikarus_blueprint_to_object_const(IkarusBlueprint const * blueprint);
|
IKA_API struct IkarusObject const * ikarus_blueprint_to_object_const(IkarusBlueprint const * blueprint, IkarusErrorData * error_out);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <ikarus/errors.h>
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
#include <ikarus/stdtypes.h>
|
#include <ikarus/stdtypes.h>
|
||||||
|
|
||||||
|
|
@ -37,24 +38,21 @@ struct IkarusEntity;
|
||||||
/// \param project The project the entity is part of.
|
/// \param project The project the entity is part of.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
/// \param parent The parent folder of the entity.
|
|
||||||
/// \pre \li Must not be null.
|
|
||||||
/// \pre \li Must exist.
|
|
||||||
/// \param position The position of the entity in the parent folder. \see #FolderPosition
|
|
||||||
/// \pre \li Must be within bounds for the parent folder.
|
|
||||||
/// \param name The name of the entity.
|
/// \param name The name of the entity.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must not be empty.
|
/// \pre \li Must not be empty.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The created entity or null if an error occurs.
|
/// \return The created entity or null if an error occurs.
|
||||||
/// \remark Must be freed using #ikarus_free.
|
/// \remark Must be freed using #ikarus_free.
|
||||||
IKA_API IkarusEntity * ikarus_entity_create(struct IkarusProject * project, char const * name);
|
IKA_API IkarusEntity * ikarus_entity_create(struct IkarusProject * project, char const * name, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Deletes an entity.
|
/// \brief Deletes an entity.
|
||||||
/// \param entity The entity to delete.
|
/// \param entity The entity to delete.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark The entity must not be accessed after deletion.
|
/// \remark The entity must not be accessed after deletion.
|
||||||
IKA_API void ikarus_entity_delete(IkarusEntity * entity);
|
IKA_API void ikarus_entity_delete(IkarusEntity * entity, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Checks if an entity is linked to a blueprint.
|
/// \brief Checks if an entity is linked to a blueprint.
|
||||||
/// \param entity The entity to check.
|
/// \param entity The entity to check.
|
||||||
|
|
@ -63,8 +61,10 @@ IKA_API void ikarus_entity_delete(IkarusEntity * entity);
|
||||||
/// \param blueprint The blueprint to check.
|
/// \param blueprint The blueprint to check.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return True if the entity is linked to the blueprint, false otherwise.
|
/// \return True if the entity is linked to the blueprint, false otherwise.
|
||||||
IKA_API bool ikarus_entity_is_linked_to_blueprint(IkarusEntity const * entity, struct IkarusBlueprint const * blueprint);
|
IKA_API bool
|
||||||
|
ikarus_entity_is_linked_to_blueprint(IkarusEntity const * entity, struct IkarusBlueprint const * blueprint, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Links an entity to a blueprint.
|
/// \brief Links an entity to a blueprint.
|
||||||
/// \param entity The entity to link.
|
/// \param entity The entity to link.
|
||||||
|
|
@ -73,8 +73,9 @@ IKA_API bool ikarus_entity_is_linked_to_blueprint(IkarusEntity const * entity, s
|
||||||
/// \param blueprint The blueprint to link the entity to.
|
/// \param blueprint The blueprint to link the entity to.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark No-op if the entity is already linked to the blueprint.
|
/// \remark No-op if the entity is already linked to the blueprint.
|
||||||
IKA_API void ikarus_entity_link_to_blueprint(IkarusEntity * entity, struct IkarusBlueprint * blueprint);
|
IKA_API void ikarus_entity_link_to_blueprint(IkarusEntity * entity, struct IkarusBlueprint * blueprint, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Unlinks an entity from a blueprint. All values of the properties of the blueprint the entity is linked with
|
/// \brief Unlinks an entity from a blueprint. All values of the properties of the blueprint the entity is linked with
|
||||||
/// will be deleted.
|
/// will be deleted.
|
||||||
|
|
@ -84,8 +85,9 @@ IKA_API void ikarus_entity_link_to_blueprint(IkarusEntity * entity, struct Ikaru
|
||||||
/// \param blueprint The blueprint to unlink the entity from.
|
/// \param blueprint The blueprint to unlink the entity from.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark No-op if the entity is not linked to the blueprint.
|
/// \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);
|
IKA_API void ikarus_entity_unlink_from_blueprint(IkarusEntity * entity, struct IkarusBlueprint * blueprint, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Checks if an entity has a specific property.
|
/// \brief Checks if an entity has a specific property.
|
||||||
/// \param entity The entity to check.
|
/// \param entity The entity to check.
|
||||||
|
|
@ -94,15 +96,17 @@ IKA_API void ikarus_entity_unlink_from_blueprint(IkarusEntity * entity, struct I
|
||||||
/// \param property The property to check.
|
/// \param property The property to check.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return True if the entity has the property, false otherwise.
|
/// \return True if the entity has the property, false otherwise.
|
||||||
IKA_API bool ikarus_entity_has_property(IkarusEntity const * entity, struct IkarusProperty const * property);
|
IKA_API bool ikarus_entity_has_property(IkarusEntity const * entity, struct IkarusProperty const * property, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Gets the number of properties of an entity.
|
/// \brief Gets the number of properties of an entity.
|
||||||
/// \param entity The entity to get the number of properties of.
|
/// \param entity The entity to get the number of properties of.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The number of properties or undefined if an error occurs.
|
/// \return The number of properties or undefined if an error occurs.
|
||||||
IKA_API size_t ikarus_entity_get_property_count(IkarusEntity const * entity);
|
IKA_API size_t ikarus_entity_get_property_count(IkarusEntity const * entity, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Gets the properties of an entity.
|
/// \brief Gets the properties of an entity.
|
||||||
/// \param entity The entity to get the properties of.
|
/// \param entity The entity to get the properties of.
|
||||||
|
|
@ -110,8 +114,14 @@ IKA_API size_t ikarus_entity_get_property_count(IkarusEntity const * entity);
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
/// \param properties_out The buffer to write the properties to.
|
/// \param properties_out The buffer to write the properties to.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \param properties_out_size The size of the buffer.
|
/// \param properties_out_size The size of the buffer.
|
||||||
IKA_API void ikarus_entity_get_properties(IkarusEntity const * entity, struct IkarusProperty ** properties_out, size_t properties_out_size);
|
IKA_API void ikarus_entity_get_properties(
|
||||||
|
IkarusEntity const * entity,
|
||||||
|
struct IkarusProperty ** properties_out,
|
||||||
|
size_t properties_out_size,
|
||||||
|
IkarusErrorData * error_out
|
||||||
|
);
|
||||||
|
|
||||||
/// \brief Gets the value of a property of an entity.
|
/// \brief Gets the value of a property of an entity.
|
||||||
/// \details If the entity has never set the value of the property, the default value is returned (which may be
|
/// \details If the entity has never set the value of the property, the default value is returned (which may be
|
||||||
|
|
@ -122,10 +132,12 @@ IKA_API void ikarus_entity_get_properties(IkarusEntity const * entity, struct Ik
|
||||||
/// \param property The property to get the value of.
|
/// \param property The property to get the value of.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The value of the property or null if the entity does not have the property or an error occurs.
|
/// \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
|
/// \remark Must be freed using
|
||||||
/// #ikarus_free.
|
/// #ikarus_free.
|
||||||
IKA_API struct IkarusEntityValue * ikarus_entity_get_value(IkarusEntity const * entity, struct IkarusProperty const * property);
|
IKA_API struct IkarusEntityValue *
|
||||||
|
ikarus_entity_get_value(IkarusEntity const * entity, struct IkarusProperty const * property, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Sets the value of a property of an entity.
|
/// \brief Sets the value of a property of an entity.
|
||||||
/// \param entity The entity to set the value of.
|
/// \param entity The entity to set the value of.
|
||||||
|
|
@ -138,19 +150,26 @@ IKA_API struct IkarusEntityValue * ikarus_entity_get_value(IkarusEntity const *
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must be of the same type as the property.
|
/// \pre \li Must be of the same type as the property.
|
||||||
/// \pre \li Must be valid for the property's settings.
|
/// \pre \li Must be valid for the property's settings.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark If the entity does not have the property, this function fails.
|
/// \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 const * value);
|
IKA_API void ikarus_entity_set_value(
|
||||||
|
IkarusEntity * entity,
|
||||||
|
struct IkarusProperty const * property,
|
||||||
|
struct IkarusValue const * value,
|
||||||
|
IkarusErrorData * error_out
|
||||||
|
);
|
||||||
|
|
||||||
/// \brief Casts an entity to an object.
|
/// \brief Casts an entity to an object.
|
||||||
/// \param entity The entity to cast.
|
/// \param entity The entity to cast.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The entity represented as an object or null if an error occurs.
|
/// \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.
|
/// \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 * entity);
|
IKA_API struct IkarusObject * ikarus_entity_to_object(IkarusEntity * entity, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \see ikarus_entity_to_object
|
/// \see ikarus_entity_to_object
|
||||||
IKA_API struct IkarusObject const * ikarus_entity_to_object_const(IkarusEntity const * entity);
|
IKA_API struct IkarusObject const * ikarus_entity_to_object_const(IkarusEntity const * entity, IkarusErrorData * error_out);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
/// \file object.h
|
/// \file object.h
|
||||||
/// \author Folling <folling@ikarus.world>
|
/// \author Folling <folling@ikarus.world>
|
||||||
|
|
||||||
|
#include <ikarus/errors.h>
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
|
|
||||||
/// \defgroup object Objects
|
/// \defgroup object Objects
|
||||||
|
|
@ -20,10 +21,14 @@ struct IkarusObject;
|
||||||
|
|
||||||
/// \brief Compares two objects for equality.
|
/// \brief Compares two objects for equality.
|
||||||
/// \details This neither compares the pointers nor does a deep copy. Instead it figures out if the objects _are_ the
|
/// \details This neither compares the pointers nor does a deep copy. Instead it figures out if the objects _are_ the
|
||||||
/// same object. \param lhs The left hand side object. \pre \li Must not be null. \param rhs The right hand side object.
|
/// same object.
|
||||||
|
/// \param lhs The left hand side object.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param rhs The right hand side object.
|
||||||
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return True if the objects are equal, false otherwise.
|
/// \return True if the objects are equal, false otherwise.
|
||||||
IKA_API bool ikarus_object_is_equal(IkarusObject const * lhs, IkarusObject const * rhs);
|
IKA_API bool ikarus_object_is_equal(IkarusObject const * lhs, IkarusObject const * rhs, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Visits an object. Calling the appropriate function for the object's type.
|
/// \brief Visits an object. Calling the appropriate function for the object's type.
|
||||||
/// \param object The object to visit.
|
/// \param object The object to visit.
|
||||||
|
|
@ -34,6 +39,7 @@ IKA_API bool ikarus_object_is_equal(IkarusObject const * lhs, IkarusObject const
|
||||||
/// \param property_folder_visitor The function to call if the object is a property folder. Skipped if null.
|
/// \param property_folder_visitor The function to call if the object is a property folder. Skipped if null.
|
||||||
/// \param entity_folder_visitor The function to call if the object is an entity folder. Skipped if null.
|
/// \param entity_folder_visitor The function to call if the object is an entity folder. Skipped if null.
|
||||||
/// \param data The data passed to the visitor functions.
|
/// \param data The data passed to the visitor functions.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
IKA_API void ikarus_object_visit(
|
IKA_API void ikarus_object_visit(
|
||||||
IkarusObject * object,
|
IkarusObject * object,
|
||||||
void (*blueprint_visitor)(struct IkarusBlueprint *, void *),
|
void (*blueprint_visitor)(struct IkarusBlueprint *, void *),
|
||||||
|
|
@ -42,7 +48,8 @@ IKA_API void ikarus_object_visit(
|
||||||
void (*blueprint_folder_visitor)(struct IkarusBlueprintFolder *, void *),
|
void (*blueprint_folder_visitor)(struct IkarusBlueprintFolder *, void *),
|
||||||
void (*property_folder_visitor)(struct IkarusPropertyFolder *, void *),
|
void (*property_folder_visitor)(struct IkarusPropertyFolder *, void *),
|
||||||
void (*entity_folder_visitor)(struct IkarusEntityFolder *, void *),
|
void (*entity_folder_visitor)(struct IkarusEntityFolder *, void *),
|
||||||
void * data
|
void * data,
|
||||||
|
IkarusErrorData * error_out
|
||||||
);
|
);
|
||||||
|
|
||||||
/// \see ikarus_object_visit
|
/// \see ikarus_object_visit
|
||||||
|
|
@ -54,7 +61,8 @@ IKA_API void ikarus_object_visit_const(
|
||||||
void (*blueprint_folder_visitor)(struct IkarusBlueprintFolder const *, void *),
|
void (*blueprint_folder_visitor)(struct IkarusBlueprintFolder const *, void *),
|
||||||
void (*property_folder_visitor)(struct IkarusPropertyFolder const *, void *),
|
void (*property_folder_visitor)(struct IkarusPropertyFolder const *, void *),
|
||||||
void (*entity_folder_visitor)(struct IkarusEntityFolder const *, void *),
|
void (*entity_folder_visitor)(struct IkarusEntityFolder const *, void *),
|
||||||
void * data
|
void * data,
|
||||||
|
IkarusErrorData * error_out
|
||||||
);
|
);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
/// \file object_type.h
|
/// \file object_type.h
|
||||||
/// \author Folling <folling@ikarus.world>
|
/// \author Folling <folling@ikarus.world>
|
||||||
|
|
||||||
|
#include <ikarus/errors.h>
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
|
|
||||||
/// \addtogroup objects Objects
|
/// \addtogroup objects Objects
|
||||||
|
|
@ -24,9 +25,10 @@ enum IkarusObjectType {
|
||||||
|
|
||||||
/// \brief Converts an IkarusObjectType to a string.
|
/// \brief Converts an IkarusObjectType to a string.
|
||||||
/// \param type The type to convert.
|
/// \param type The type to convert.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The string representation of the type.
|
/// \return The string representation of the type.
|
||||||
/// \remark The returned string must not be freed.
|
/// \remark The returned string must not be freed.
|
||||||
char const * ikarus_object_type_to_string(IkarusObjectType type);
|
char const * ikarus_object_type_to_string(IkarusObjectType type, IkarusErrorData * error_out);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,24 +3,44 @@
|
||||||
/// \file number_property.h
|
/// \file number_property.h
|
||||||
/// \author Folling <folling@ikarus.world>
|
/// \author Folling <folling@ikarus.world>
|
||||||
|
|
||||||
|
#include <ikarus/errors.h>
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
|
|
||||||
/// \addtogroup properties Properties
|
/// \addtogroup properties Properties
|
||||||
/// \brief Number properties store a numeric value. (e.g. "Weight" or "Age")
|
/// \brief Number properties store a value that can be either true or false. (e.g. "Is the character dead?")
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
IKARUS_BEGIN_HEADER
|
IKARUS_BEGIN_HEADER
|
||||||
|
|
||||||
struct IkarusNumberProperty;
|
struct IkarusNumberProperty;
|
||||||
|
|
||||||
IKA_API IkarusNumberProperty *
|
/// \brief Creates a number property.
|
||||||
ikarus_number_property_create(struct IkarusProject * project, char const * name, struct IkarusPropertySource * property_source);
|
/// \param project The project to create the property in.
|
||||||
|
/// \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_source The property source to create the property for.
|
||||||
|
/// \pre \li Must not be null.
|
||||||
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
|
/// \return The created property or null if an error occurs.
|
||||||
|
IKA_API IkarusNumberProperty * ikarus_number_property_create(
|
||||||
|
struct IkarusProject * project,
|
||||||
|
char const * name,
|
||||||
|
struct IkarusPropertySource * property_source,
|
||||||
|
IkarusErrorData * error_out
|
||||||
|
);
|
||||||
|
|
||||||
/// \brief Sets the default value for a number property.
|
/// \brief Sets the default value for a number property.
|
||||||
/// \param property The number property.
|
/// \param property The number property.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
IKA_API struct IkarusNumberValue * ikarus_number_property_get_default_value(struct IkarusNumberProperty * property);
|
/// \param error_out \see errors.h
|
||||||
|
/// \return The default value or null if an error occurs.
|
||||||
|
IKA_API struct IkarusNumberValue *
|
||||||
|
ikarus_number_property_get_default_value(struct IkarusNumberProperty * property, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Sets the default value for a number property.
|
/// \brief Sets the default value for a number property.
|
||||||
/// \param property The number property.
|
/// \param property The number property.
|
||||||
|
|
@ -29,9 +49,14 @@ IKA_API struct IkarusNumberValue * ikarus_number_property_get_default_value(stru
|
||||||
/// \param default_value The default value.
|
/// \param default_value The default value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must be a valid value for the property.
|
/// \pre \li Must be a valid value for the property.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark Please see \ref property.h "the property documentation" for more information on the interplay between
|
/// \remark Please see \ref property.h "the property documentation" for more information on the interplay between
|
||||||
/// default values and other settings.
|
/// default values and other settings.
|
||||||
IKA_API void ikarus_number_property_set_default_value(struct IkarusNumberProperty * property, struct IkarusNumberValue * default_value);
|
IKA_API void ikarus_number_property_set_default_value(
|
||||||
|
struct IkarusNumberProperty * property,
|
||||||
|
struct IkarusNumberValue * default_value,
|
||||||
|
IkarusErrorData * error_out
|
||||||
|
);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
/// \file property.h
|
/// \file property.h
|
||||||
/// \author Folling <folling@ikarus.world>
|
/// \author Folling <folling@ikarus.world>
|
||||||
|
|
||||||
|
#include <ikarus/errors.h>
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
#include <ikarus/objects/properties/property_type.h>
|
#include <ikarus/objects/properties/property_type.h>
|
||||||
#include <ikarus/stdtypes.h>
|
#include <ikarus/stdtypes.h>
|
||||||
|
|
@ -59,32 +60,36 @@ struct IkarusProperty;
|
||||||
/// \param property The property to delete.
|
/// \param property The property to delete.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark The property must not be accessed after deletion.
|
/// \remark The property must not be accessed after deletion.
|
||||||
IKA_API void ikarus_property_delete(IkarusProperty * property);
|
IKA_API void ikarus_property_delete(IkarusProperty * property, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Gets the type info of a property.
|
/// \brief Gets the type info of a property.
|
||||||
/// \param property The property to get the type info of.
|
/// \param property The property to get the type info of.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The type info of the property or null if an error occurs.
|
/// \return The type info of the property or null if an error occurs.
|
||||||
/// \remark Must be freed using #ikarus_free.
|
/// \remark Must be freed using #ikarus_free.
|
||||||
IKA_API IkarusPropertyType ikarus_property_get_type(IkarusProperty const * property);
|
IKA_API IkarusPropertyType ikarus_property_get_type(IkarusProperty const * property, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Gets the source of a property.
|
/// \brief Gets the source of a property.
|
||||||
/// \param property The property to get the source of.
|
/// \param property The property to get the source of.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The source of the property or null if an error occurs.
|
/// \return The source of the property or null if an error occurs.
|
||||||
/// \remark Must be freed using #ikarus_free.
|
/// \remark Must be freed using #ikarus_free.
|
||||||
IKA_API struct IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * property);
|
IKA_API struct IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * property, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Gets the default value of a property.
|
/// \brief Gets the default value of a property.
|
||||||
/// \param property The property to get the type info of.
|
/// \param property The property to get the type info of.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The default value of the property or null if an error occurs.
|
/// \return The default value of the property or null if an error occurs.
|
||||||
/// \remark Must be freed using #ikarus_free.
|
/// \remark Must be freed using #ikarus_free.
|
||||||
IKA_API struct IkarusValue const * ikarus_property_get_default_value(IkarusProperty const * property);
|
IKA_API struct IkarusValue const * ikarus_property_get_default_value(IkarusProperty const * property, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Visits a property. Calling the appropriate function for the property's type.
|
/// \brief Visits a property. Calling the appropriate function for the property's type.
|
||||||
/// \param property The property to visit.
|
/// \param property The property to visit.
|
||||||
|
|
@ -94,12 +99,14 @@ IKA_API struct IkarusValue const * ikarus_property_get_default_value(IkarusPrope
|
||||||
/// \param number_property_visitor The function to call if the property is a number 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 text_property_visitor The function to call if the property is a text property. Skipped if null.
|
||||||
/// \param data The data to pass to the functions.
|
/// \param data The data to pass to the functions.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
IKA_API void ikarus_property_visit(
|
IKA_API void ikarus_property_visit(
|
||||||
IkarusProperty * property,
|
IkarusProperty * property,
|
||||||
void (*toggle_property_visitor)(struct IkarusToggleProperty *, void *),
|
void (*toggle_property_visitor)(struct IkarusToggleProperty *, void *),
|
||||||
void (*number_property_visitor)(struct IkarusNumberProperty *, void *),
|
void (*number_property_visitor)(struct IkarusNumberProperty *, void *),
|
||||||
void (*text_property_visitor)(struct IkarusTextProperty *, void *),
|
void (*text_property_visitor)(struct IkarusTextProperty *, void *),
|
||||||
void * data
|
void * data,
|
||||||
|
IkarusErrorData * error_out
|
||||||
);
|
);
|
||||||
|
|
||||||
/// \see ikarus_property_visit
|
/// \see ikarus_property_visit
|
||||||
|
|
@ -108,19 +115,21 @@ IKA_API void ikarus_property_visit_const(
|
||||||
void (*toggle_property_visitor)(struct IkarusToggleProperty const *, void *),
|
void (*toggle_property_visitor)(struct IkarusToggleProperty const *, void *),
|
||||||
void (*number_property_visitor)(struct IkarusNumberProperty const *, void *),
|
void (*number_property_visitor)(struct IkarusNumberProperty const *, void *),
|
||||||
void (*text_property_visitor)(struct IkarusTextProperty const *, void *),
|
void (*text_property_visitor)(struct IkarusTextProperty const *, void *),
|
||||||
void * data
|
void * data,
|
||||||
|
IkarusErrorData * error_out
|
||||||
);
|
);
|
||||||
|
|
||||||
/// \brief Casts a property to an object.
|
/// \brief Casts a property to an object.
|
||||||
/// \param property The property to cast.
|
/// \param property The property to cast.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The property represented as an object or null if an error occurs.
|
/// \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.
|
/// \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 * property);
|
IKA_API struct IkarusObject * ikarus_property_to_object(IkarusProperty * property, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \see ikarus_property_to_object
|
/// \see ikarus_property_to_object
|
||||||
IKA_API struct IkarusObject const * ikarus_property_to_object_const(IkarusProperty const * property);
|
IKA_API struct IkarusObject const * ikarus_property_to_object_const(IkarusProperty const * property, IkarusErrorData * error_out);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
/// \file property_source.h
|
/// \file property_source.h
|
||||||
/// \author Folling <folling@ikarus.world>
|
/// \author Folling <folling@ikarus.world>
|
||||||
|
|
||||||
|
#include <ikarus/errors.h>
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
|
|
||||||
/// \addtogroup properties Properties
|
/// \addtogroup properties Properties
|
||||||
|
|
@ -16,17 +17,20 @@ struct IkarusPropertySource;
|
||||||
/// \param blueprint The blueprint to create the property source for.
|
/// \param blueprint The blueprint to create the property source for.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The created property source or null if an error occurs.
|
/// \return The created property source or null if an error occurs.
|
||||||
/// \remark Must be freed using #ikarus_free.
|
/// \remark Must be freed using #ikarus_free.
|
||||||
IKA_API struct IkarusPropertySource * ikarus_property_source_create_blueprint(struct IkarusBlueprint * blueprint);
|
IKA_API struct IkarusPropertySource *
|
||||||
|
ikarus_property_source_create_blueprint(struct IkarusBlueprint * blueprint, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Creates an entity property source.
|
/// \brief Creates an entity property source.
|
||||||
/// \param entity The entity to create the property source for.
|
/// \param entity The entity to create the property source for.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The created property source or null if an error occurs.
|
/// \return The created property source or null if an error occurs.
|
||||||
/// \remark Must be freed using #ikarus_free.
|
/// \remark Must be freed using #ikarus_free.
|
||||||
IKA_API struct IkarusPropertySource * ikarus_property_source_create_entity(struct IkarusEntity * entity);
|
IKA_API struct IkarusPropertySource * ikarus_property_source_create_entity(struct IkarusEntity * entity, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Visits a property source, calling the appropriate callback.
|
/// \brief Visits a property source, calling the appropriate callback.
|
||||||
/// \param property_source The property source to visit.
|
/// \param property_source The property source to visit.
|
||||||
|
|
@ -35,11 +39,13 @@ IKA_API struct IkarusPropertySource * ikarus_property_source_create_entity(struc
|
||||||
/// \param blueprint_visitor The callback to call if the source is a blueprint, skipped if null.
|
/// \param blueprint_visitor The callback to call if the source is a blueprint, skipped if null.
|
||||||
/// \param entity_visitor The callback to call if the source is an entity, skipped if null.
|
/// \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.
|
/// \param user_data User data to pass to the callbacks.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
IKA_API void ikarus_property_source_visit(
|
IKA_API void ikarus_property_source_visit(
|
||||||
struct IkarusPropertySource * property_source,
|
struct IkarusPropertySource * property_source,
|
||||||
void (*blueprint_visitor)(struct IkarusBlueprint *, void *),
|
void (*blueprint_visitor)(struct IkarusBlueprint *, void *),
|
||||||
void (*entity_visitor)(struct IkarusEntity *, void *),
|
void (*entity_visitor)(struct IkarusEntity *, void *),
|
||||||
void * user_data
|
void * user_data,
|
||||||
|
IkarusErrorData * error_out
|
||||||
);
|
);
|
||||||
|
|
||||||
/// \see ikarus_property_source_visit
|
/// \see ikarus_property_source_visit
|
||||||
|
|
@ -47,7 +53,8 @@ IKA_API void ikarus_property_source_visit_const(
|
||||||
struct IkarusPropertySource const * property_source,
|
struct IkarusPropertySource const * property_source,
|
||||||
void (*blueprint_visitor)(struct IkarusBlueprint const *, void *),
|
void (*blueprint_visitor)(struct IkarusBlueprint const *, void *),
|
||||||
void (*entity_visitor)(struct IkarusEntity const *, void *),
|
void (*entity_visitor)(struct IkarusEntity const *, void *),
|
||||||
void * user_data
|
void * user_data,
|
||||||
|
IkarusErrorData * error_out
|
||||||
);
|
);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
|
||||||
|
|
@ -3,24 +3,43 @@
|
||||||
/// \file text_property.h
|
/// \file text_property.h
|
||||||
/// \author Folling <folling@ikarus.world>
|
/// \author Folling <folling@ikarus.world>
|
||||||
|
|
||||||
|
#include <ikarus/errors.h>
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
|
|
||||||
/// \addtogroup properties Properties
|
/// \addtogroup properties Properties
|
||||||
/// \brief Text properties store an arbitrary piece of text. (e.g. "Firstname" or "Description")
|
/// \brief Text properties store a value that can be either true or false. (e.g. "Is the character dead?")
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
IKARUS_BEGIN_HEADER
|
IKARUS_BEGIN_HEADER
|
||||||
|
|
||||||
struct IkarusTextProperty;
|
struct IkarusTextProperty;
|
||||||
|
|
||||||
IKA_API IkarusTextProperty *
|
/// \brief Creates a text property.
|
||||||
ikarus_text_property_create(struct IkarusProject * project, char const * name, struct IkarusPropertySource * property_source);
|
/// \param project The project to create the property in.
|
||||||
|
/// \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_source The property source to create the property for.
|
||||||
|
/// \pre \li Must not be null.
|
||||||
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
|
/// \return The created property or null if an error occurs.
|
||||||
|
IKA_API IkarusTextProperty * ikarus_text_property_create(
|
||||||
|
struct IkarusProject * project,
|
||||||
|
char const * name,
|
||||||
|
struct IkarusPropertySource * property_source,
|
||||||
|
IkarusErrorData * error_out
|
||||||
|
);
|
||||||
|
|
||||||
/// \brief Sets the default value for a text property.
|
/// \brief Sets the default value for a text property.
|
||||||
/// \param property The text property.
|
/// \param property The text property.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
IKA_API struct IkarusTextValue * ikarus_text_property_get_default_value(struct IkarusTextProperty * property);
|
/// \param error_out \see errors.h
|
||||||
|
/// \return The default value or null if an error occurs.
|
||||||
|
IKA_API struct IkarusTextValue * ikarus_text_property_get_default_value(struct IkarusTextProperty * property, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Sets the default value for a text property.
|
/// \brief Sets the default value for a text property.
|
||||||
/// \param property The text property.
|
/// \param property The text property.
|
||||||
|
|
@ -29,9 +48,14 @@ IKA_API struct IkarusTextValue * ikarus_text_property_get_default_value(struct I
|
||||||
/// \param default_value The default value.
|
/// \param default_value The default value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must be a valid value for the property.
|
/// \pre \li Must be a valid value for the property.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark Please see \ref property.h "the property documentation" for more information on the interplay between
|
/// \remark Please see \ref property.h "the property documentation" for more information on the interplay between
|
||||||
/// default values and other settings.
|
/// default values and other settings.
|
||||||
IKA_API void ikarus_text_property_set_default_value(struct IkarusTextProperty * property, struct IkarusTextValue * default_value);
|
IKA_API void ikarus_text_property_set_default_value(
|
||||||
|
struct IkarusTextProperty * property,
|
||||||
|
struct IkarusTextValue * default_value,
|
||||||
|
IkarusErrorData * error_out
|
||||||
|
);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
/// \file toggle_property.h
|
/// \file toggle_property.h
|
||||||
/// \author Folling <folling@ikarus.world>
|
/// \author Folling <folling@ikarus.world>
|
||||||
|
|
||||||
|
#include <ikarus/errors.h>
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
|
|
||||||
/// \addtogroup properties Properties
|
/// \addtogroup properties Properties
|
||||||
|
|
@ -13,14 +14,33 @@ IKARUS_BEGIN_HEADER
|
||||||
|
|
||||||
struct IkarusToggleProperty;
|
struct IkarusToggleProperty;
|
||||||
|
|
||||||
IKA_API IkarusToggleProperty *
|
/// \brief Creates a toggle property.
|
||||||
ikarus_toggle_property_create(struct IkarusProject * project, char const * name, struct IkarusPropertySource * property_source);
|
/// \param project The project to create the property in.
|
||||||
|
/// \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_source The property source to create the property for.
|
||||||
|
/// \pre \li Must not be null.
|
||||||
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
|
/// \return The created property or null if an error occurs.
|
||||||
|
IKA_API IkarusToggleProperty * ikarus_toggle_property_create(
|
||||||
|
struct IkarusProject * project,
|
||||||
|
char const * name,
|
||||||
|
struct IkarusPropertySource * property_source,
|
||||||
|
IkarusErrorData * error_out
|
||||||
|
);
|
||||||
|
|
||||||
/// \brief Sets the default value for a toggle property.
|
/// \brief Sets the default value for a toggle property.
|
||||||
/// \param property The toggle property.
|
/// \param property The toggle property.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
IKA_API struct IkarusToggleValue * ikarus_toggle_property_get_default_value(struct IkarusToggleProperty * property);
|
/// \param error_out \see errors.h
|
||||||
|
/// \return The default value or null if an error occurs.
|
||||||
|
IKA_API struct IkarusToggleValue *
|
||||||
|
ikarus_toggle_property_get_default_value(struct IkarusToggleProperty * property, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Sets the default value for a toggle property.
|
/// \brief Sets the default value for a toggle property.
|
||||||
/// \param property The toggle property.
|
/// \param property The toggle property.
|
||||||
|
|
@ -29,9 +49,14 @@ IKA_API struct IkarusToggleValue * ikarus_toggle_property_get_default_value(stru
|
||||||
/// \param default_value The default value.
|
/// \param default_value The default value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must be a valid value for the property.
|
/// \pre \li Must be a valid value for the property.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark Please see \ref property.h "the property documentation" for more information on the interplay between
|
/// \remark Please see \ref property.h "the property documentation" for more information on the interplay between
|
||||||
/// default values and other settings.
|
/// default values and other settings.
|
||||||
IKA_API void ikarus_toggle_property_set_default_value(struct IkarusToggleProperty * property, struct IkarusToggleValue * default_value);
|
IKA_API void ikarus_toggle_property_set_default_value(
|
||||||
|
struct IkarusToggleProperty * property,
|
||||||
|
struct IkarusToggleValue * default_value,
|
||||||
|
IkarusErrorData * error_out
|
||||||
|
);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,28 +25,31 @@ struct IkarusProject;
|
||||||
/// \param name The name of the project. Must neither be null nor empty.
|
/// \param name The name of the project. Must neither be null nor empty.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must not be empty.
|
/// \pre \li Must not be empty.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The created project or null if an error occurs.
|
/// \return The created project or null if an error occurs.
|
||||||
/// \remark Must be freed using #ikarus_free. Freeing does not delete the project from the filesystem. For that, use
|
/// \remark Must be freed using #ikarus_free. Freeing does not delete the project from the filesystem. For that, use
|
||||||
/// ikarus_project_delete
|
/// ikarus_project_delete
|
||||||
IKA_API IkarusProject * ikarus_project_create(char const * path, char const * name);
|
IKA_API IkarusProject * ikarus_project_create(char const * path, char const * name, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Creates a project in memory.
|
/// \brief Creates a project in memory.
|
||||||
/// \param name The name of the project. Must neither be null nor empty.
|
/// \param name The name of the project. Must neither be null nor empty.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must not be empty.
|
/// \pre \li Must not be empty.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The created project or null if an error occurs.
|
/// \return The created project or null if an error occurs.
|
||||||
/// \remark Must be freed using #ikarus_free. Freeing does not delete the project from the filesystem. For that, use
|
/// \remark Must be freed using #ikarus_free. Freeing does not delete the project from the filesystem. For that, use
|
||||||
/// ikarus_project_delete
|
/// ikarus_project_delete
|
||||||
IKA_API IkarusProject * ikarus_project_create_in_memory(char const * name);
|
IKA_API IkarusProject * ikarus_project_create_in_memory(char const * name, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Opens an existing project.
|
/// \brief Opens an existing project.
|
||||||
/// \param path The path to the project.
|
/// \param path The path to the project.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must point to an existing project on the system.
|
/// \pre \li Must point to an existing project on the system.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The opened project or null if an error occurs.
|
/// \return The opened project or null if an error occurs.
|
||||||
/// \remark Must be freed using ikarus_free. Freeing does not delete the project from the filesystem. For that, use
|
/// \remark Must be freed using ikarus_free. Freeing does not delete the project from the filesystem. For that, use
|
||||||
/// ikarus_project_delete
|
/// ikarus_project_delete
|
||||||
IKA_API IkarusProject * ikarus_project_open(char const * path);
|
IKA_API IkarusProject * ikarus_project_open(char const * path, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Copies a project to a new location.
|
/// \brief Copies a project to a new location.
|
||||||
/// \details The new project is not opened.
|
/// \details The new project is not opened.
|
||||||
|
|
@ -59,25 +62,29 @@ IKA_API IkarusProject * ikarus_project_open(char const * path);
|
||||||
/// \param target_name The name of the new project.
|
/// \param target_name The name of the new project.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must not be empty.
|
/// \pre \li Must not be empty.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark If successful the project connection remains intact. The previous location will still exist.
|
/// \remark If successful the project connection remains intact. The previous location will still exist.
|
||||||
IKA_API void ikarus_project_copy(IkarusProject const * project, char const * target_path, char const * target_name);
|
IKA_API void
|
||||||
|
ikarus_project_copy(IkarusProject const * project, char const * target_path, char const * target_name, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Deletes a project and all its associated data from the filesystem.
|
/// \brief Deletes a project and all its associated data from the filesystem.
|
||||||
/// \param project The project to delete.
|
/// \param project The project to delete.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark also frees the project.
|
/// \remark also frees the project.
|
||||||
/// \remark In-Memory projects will just be freed.
|
/// \remark In-Memory projects will just be freed.
|
||||||
/// \remark If deletion fails, the project pointer remains intact.
|
/// \remark If deletion fails, the project pointer remains intact.
|
||||||
IKA_API void ikarus_project_delete(IkarusProject * project);
|
IKA_API void ikarus_project_delete(IkarusProject * project, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Gets the name of a project.
|
/// \brief Gets the name of a project.
|
||||||
/// \param project The project to get the name of.
|
/// \param project The project to get the name of.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The name of the project.
|
/// \return The name of the project.
|
||||||
/// \remark Must be freed using #ikarus_free.
|
/// \remark Must be freed using #ikarus_free.
|
||||||
IKA_API char const * ikarus_project_get_name(IkarusProject const * project);
|
IKA_API char const * ikarus_project_get_name(IkarusProject const * project, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Sets the name of a project.
|
/// \brief Sets the name of a project.
|
||||||
/// \param project The project to set the name of.
|
/// \param project The project to set the name of.
|
||||||
|
|
@ -86,15 +93,17 @@ IKA_API char const * ikarus_project_get_name(IkarusProject const * project);
|
||||||
/// \param new_name The new name of the project.
|
/// \param new_name The new name of the project.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must not be empty.
|
/// \pre \li Must not be empty.
|
||||||
IKA_API void ikarus_project_set_name(IkarusProject * project, char const * new_name);
|
/// \param error_out \see errors.h
|
||||||
|
IKA_API void ikarus_project_set_name(IkarusProject * project, char const * new_name, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Gets the path of a project.
|
/// \brief Gets the path of a project.
|
||||||
/// \param project The project to get the path of.
|
/// \param project The project to get the path of.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The path of the project.
|
/// \return The path of the project.
|
||||||
/// \remark Must be freed using #ikarus_free.
|
/// \remark Must be freed using #ikarus_free.
|
||||||
IKA_API char const * ikarus_project_get_path(IkarusProject const * project);
|
IKA_API char const * ikarus_project_get_path(IkarusProject const * project, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Moves a project to a new location.
|
/// \brief Moves a project to a new location.
|
||||||
/// \param project The project to move.
|
/// \param project The project to move.
|
||||||
|
|
@ -103,39 +112,19 @@ IKA_API char const * ikarus_project_get_path(IkarusProject const * project);
|
||||||
/// \param target_path The new location of the project.
|
/// \param target_path The new location of the project.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must point to a valid unused path on the system.
|
/// \pre \li Must point to a valid unused path on the system.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark If successful the project connection remains intact. The previous location will not exist anymore.
|
/// \remark If successful the project connection remains intact. The previous location will not exist anymore.
|
||||||
/// \remark Due to the nature of filesystems this function may not be atomic.
|
/// \remark Due to the nature of filesystems this function may not be atomic.
|
||||||
IKA_API void ikarus_project_move(IkarusProject * project, char const * target_path);
|
IKA_API void ikarus_project_move(IkarusProject * project, char const * target_path, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Gets the error code of a project.
|
|
||||||
/// \param project The project to get the error code of.
|
|
||||||
/// \pre \li Must not be null.
|
|
||||||
/// \pre \li Must exist.
|
|
||||||
/// \return The error code of the project.
|
|
||||||
IKA_API int ikarus_project_get_error_code(IkarusProject const * project);
|
|
||||||
/// \brief Gets the error message of a project.
|
|
||||||
/// \param project The project to get the error message of.
|
|
||||||
/// \pre \li Must not be null.
|
|
||||||
/// \pre \li Must exist.
|
|
||||||
/// \return The error message of the project.
|
|
||||||
/// \remark The returned pointer is valid until the project is freed but may be altered by other operations.
|
|
||||||
/// \warning Must not be freed.
|
|
||||||
IKA_API char const * ikarus_project_get_error_message(IkarusProject const * project);
|
|
||||||
|
|
||||||
/// \brief Gets the blueprint root folder of a project.
|
/// \brief Gets the blueprint root folder of a project.
|
||||||
/// \param project The project to get the blueprint root folder of.
|
/// \param project The project to get the blueprint root folder of.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The blueprint root folder of the project or null if an error occurs.
|
/// \return The blueprint root folder of the project or null if an error occurs.
|
||||||
/// \remark Must be freed using #ikarus_free.
|
/// \remark Must be freed using #ikarus_free.
|
||||||
IKA_API struct IkarusBlueprintFolder * ikarus_project_get_blueprint_root_folder(IkarusProject const * project);
|
IKA_API struct IkarusBlueprintFolder * ikarus_project_get_blueprint_root_folder(IkarusProject const * project, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Gets the number of blueprints of a project.
|
|
||||||
/// \param project The project to get the number of blueprints of.
|
|
||||||
/// \pre \li Must not be null.
|
|
||||||
/// \pre \li Must exist.
|
|
||||||
/// \return The number of blueprints or undefined if an error occurs.
|
|
||||||
IKA_API size_t ikarus_project_get_blueprint_count(IkarusProject const * project);
|
|
||||||
|
|
||||||
/// \brief Gets the blueprints of a project.
|
/// \brief Gets the blueprints of a project.
|
||||||
/// \param project The project to get the blueprints of.
|
/// \param project The project to get the blueprints of.
|
||||||
|
|
@ -144,23 +133,30 @@ IKA_API size_t ikarus_project_get_blueprint_count(IkarusProject const * project)
|
||||||
/// \param blueprints_out The buffer to write the blueprints to.
|
/// \param blueprints_out The buffer to write the blueprints to.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param blueprints_out_size The size of the buffer.
|
/// \param blueprints_out_size The size of the buffer.
|
||||||
IKA_API void
|
/// \param error_out \see errors.h
|
||||||
ikarus_project_get_blueprints(IkarusProject const * project, struct IkarusBlueprint ** blueprints_out, size_t blueprints_out_size);
|
IKA_API void ikarus_project_get_blueprints(
|
||||||
|
IkarusProject const * project,
|
||||||
|
struct IkarusBlueprint ** blueprints_out,
|
||||||
|
size_t blueprints_out_size,
|
||||||
|
IkarusErrorData * error_out
|
||||||
|
);
|
||||||
|
|
||||||
|
/// \brief Gets the number of blueprints of a project.
|
||||||
|
/// \param project The project to get the number of blueprints of.
|
||||||
|
/// \pre \li Must not be null.
|
||||||
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
|
/// \return The number of blueprints or undefined if an error occurs.
|
||||||
|
IKA_API size_t ikarus_project_get_blueprint_count(IkarusProject const * project, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Gets the entity root folder of a project.
|
/// \brief Gets the entity root folder of a project.
|
||||||
/// \param project The project to get the entity root folder of.
|
/// \param project The project to get the entity root folder of.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \pre \li Must exist.
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The entity root folder of the project or null if an error occurs.
|
/// \return The entity root folder of the project or null if an error occurs.
|
||||||
/// \remark Must be freed using #ikarus_free.
|
/// \remark Must be freed using #ikarus_free.
|
||||||
IKA_API struct IkarusEntityFolder * ikarus_project_get_entity_root_folder(IkarusProject const * project);
|
IKA_API struct IkarusEntityFolder * ikarus_project_get_entity_root_folder(IkarusProject const * project, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Gets the number of entities of a project.
|
|
||||||
/// \param project The project to get the number of entities of.
|
|
||||||
/// \pre \li Must not be null.
|
|
||||||
/// \pre \li Must exist.
|
|
||||||
/// \return The number of entities or undefined if an error occurs.
|
|
||||||
IKA_API size_t ikarus_project_get_entity_count(IkarusProject const * project);
|
|
||||||
|
|
||||||
/// \brief Gets the entities of a project.
|
/// \brief Gets the entities of a project.
|
||||||
/// \param project The project to get the entities of.
|
/// \param project The project to get the entities of.
|
||||||
|
|
@ -169,7 +165,21 @@ IKA_API size_t ikarus_project_get_entity_count(IkarusProject const * project);
|
||||||
/// \param entities_out The buffer to write the entities to.
|
/// \param entities_out The buffer to write the entities to.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param entities_out_size The size of the buffer.
|
/// \param entities_out_size The size of the buffer.
|
||||||
IKA_API void ikarus_project_get_entities(IkarusProject const * project, struct IkarusEntity ** entities_out, size_t entities_out_size);
|
/// \param error_out \see errors.h
|
||||||
|
IKA_API void ikarus_project_get_entities(
|
||||||
|
IkarusProject const * project,
|
||||||
|
struct IkarusEntity ** entities_out,
|
||||||
|
size_t entities_out_size,
|
||||||
|
IkarusErrorData * error_out
|
||||||
|
);
|
||||||
|
|
||||||
|
/// \brief Gets the number of entities of a project.
|
||||||
|
/// \param project The project to get the number of entities of.
|
||||||
|
/// \pre \li Must not be null.
|
||||||
|
/// \pre \li Must exist.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
|
/// \return The number of entities or undefined if an error occurs.
|
||||||
|
IKA_API size_t ikarus_project_get_entity_count(IkarusProject const * project, IkarusErrorData * error_out);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
/// \file number_value.h
|
/// \file number_value.h
|
||||||
/// \author Folling <folling@ikarus.world>
|
/// \author Folling <folling@ikarus.world>
|
||||||
|
|
||||||
|
#include <ikarus/errors.h>
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
#include <ikarus/stdtypes.h>
|
|
||||||
|
|
||||||
/// \addtogroup values Values
|
/// \addtogroup values Values
|
||||||
/// @{
|
/// @{
|
||||||
|
|
@ -14,24 +14,27 @@ IKARUS_BEGIN_HEADER
|
||||||
/// \brief A numeric value. For example "Age" or "Height".
|
/// \brief A numeric value. For example "Age" or "Height".
|
||||||
struct IkarusNumberValue;
|
struct IkarusNumberValue;
|
||||||
|
|
||||||
/// \brief Creates a number value.
|
/// \brief Creates an empty number value.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The value or null if an error occurs.
|
/// \return The value or null if an error occurs.
|
||||||
/// \remark Must be freed with #ikarus_free.
|
/// \remark Must be freed with #ikarus_free.
|
||||||
IKA_API IkarusNumberValue * ikarus_number_value_create();
|
IKA_API IkarusNumberValue * ikarus_number_value_create(IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Fetches the underlying data of a number value at a specific index.
|
/// \brief Fetches the underlying data of a number value at a specific index.
|
||||||
/// \param value The number value.
|
/// \param value The number value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param idx The index of the data to fetch.
|
/// \param idx The index of the data to fetch.
|
||||||
/// \pre \li Must be less than the size of the value.
|
/// \pre \li Must be less than the size of the value.
|
||||||
/// \return The underlying data or null if an error occurs or the value is undefined.
|
/// \param error_out \see errors.h
|
||||||
IKA_API double const * ikarus_number_value_get(IkarusNumberValue * value, size_t idx);
|
/// \return The underlying data or NaN if an error occurs or the value is undefined.
|
||||||
|
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.
|
/// \brief Fetches the size of the underlying data of a number value.
|
||||||
/// \param value The number value.
|
/// \param value The number value.
|
||||||
/// \pre \li Must not be null.
|
/// \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 or the value is undefined.
|
||||||
IKA_API size_t ikarus_number_value_get_size(IkarusNumberValue const * value);
|
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.
|
/// \brief Sets the data of a number value at a specific index.
|
||||||
/// \param value The number value.
|
/// \param value The number value.
|
||||||
|
|
@ -39,14 +42,16 @@ IKA_API size_t ikarus_number_value_get_size(IkarusNumberValue const * value);
|
||||||
/// \param idx The index of the data to set.
|
/// \param idx The index of the data to set.
|
||||||
/// \pre \li Must be less than the size of the value.
|
/// \pre \li Must be less than the size of the value.
|
||||||
/// \param new_data The new data.
|
/// \param new_data The new data.
|
||||||
IKA_API void ikarus_number_value_set(IkarusNumberValue * value, size_t idx, double const * new_data);
|
/// \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.
|
/// \brief Removes a data from a number value.
|
||||||
/// \param value The number value.
|
/// \param value The number value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param idx The index of the data to remove.
|
/// \param idx The index of the data to remove.
|
||||||
/// \pre \li Must be less than the size of the value.
|
/// \pre \li Must be less than the size of the value.
|
||||||
IKA_API void ikarus_number_value_remove(IkarusNumberValue * value, size_t idx);
|
/// \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.
|
/// \brief Inserts a data into a number value.
|
||||||
/// \param value The number value.
|
/// \param value The number value.
|
||||||
|
|
@ -54,60 +59,68 @@ IKA_API void ikarus_number_value_remove(IkarusNumberValue * value, size_t idx);
|
||||||
/// \param idx The index of the data to insert.
|
/// \param idx The index of the data to insert.
|
||||||
/// \pre \li Must be less than or equal to the size of the value.
|
/// \pre \li Must be less than or equal to the size of the value.
|
||||||
/// \param new_data The new data.
|
/// \param new_data The new data.
|
||||||
IKA_API void ikarus_number_value_insert(IkarusNumberValue * value, size_t idx, double const * 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 Clears a number value.
|
/// \brief Clears a number value.
|
||||||
/// \param value The number value.
|
/// \param value The number value.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark Noop if the value is undefined.
|
/// \remark Noop if the value is undefined.
|
||||||
IKA_API void ikarus_number_value_clear(IkarusNumberValue * value);
|
IKA_API void ikarus_number_value_clear(IkarusNumberValue * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Checks if a number value is undefined.
|
/// \brief Checks if a number value is undefined.
|
||||||
/// \param value The number value.
|
/// \param value The number value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return True if the value is undefined, false otherwise.
|
/// \return True if the value is undefined, false otherwise.
|
||||||
IKA_API bool ikarus_number_value_is_undefined(IkarusNumberValue const * value);
|
IKA_API bool ikarus_number_value_is_undefined(IkarusNumberValue const * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Changes a number value's undefined state.
|
/// \brief Changes a number value's undefined state.
|
||||||
/// \param value The number value.
|
/// \param value The number value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param undefined The new undefined state.
|
/// \param undefined The new undefined state.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark Noop if the value is already undefined.
|
/// \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 undefined, all data will be cleared.
|
||||||
/// \remark If the value is set to not undefined, the value is as if newly created.
|
/// \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);
|
IKA_API void ikarus_number_value_set_undefined(IkarusNumberValue * value, bool undefined, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Converts a number value to a string.
|
/// \brief Converts a number value to a string.
|
||||||
/// \param value The number value to convert.
|
/// \param value The number value to convert.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The converted string.
|
/// \return The converted string.
|
||||||
/// \remark Must be freed with #ikarus_free.
|
/// \remark Must be freed with #ikarus_free.
|
||||||
/// \remark Undefined if the value is undefined.
|
/// \remark Undefined if the value is undefined.
|
||||||
IKA_API char const * ikarus_number_value_to_string(IkarusNumberValue const * value);
|
IKA_API char const * ikarus_number_value_to_string(IkarusNumberValue const * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Checks if two values are equal.
|
/// \brief Checks if two values are equal.
|
||||||
/// \param lhs The left hand side value.
|
/// \param lhs The left hand side value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param rhs The right hand side value.
|
/// \param rhs The right hand side value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return True if the values' data are equal, false otherwise.
|
/// \return True if the values' data are equal, false otherwise.
|
||||||
IKA_API bool ikarus_number_value_is_equal(IkarusNumberValue const * lhs, IkarusNumberValue const * rhs);
|
IKA_API bool ikarus_number_value_is_equal(IkarusNumberValue const * lhs, IkarusNumberValue const * rhs, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Creates a copy of a number value.
|
/// \brief Creates a copy of a number value.
|
||||||
/// \param value The value to copy.
|
/// \param value The value to copy.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The copied value.
|
/// \return The copied value.
|
||||||
/// \remark Must be freed with #ikarus_free.
|
/// \remark Must be freed with #ikarus_free.
|
||||||
IKA_API IkarusNumberValue * ikarus_number_value_copy(IkarusNumberValue const * value);
|
IKA_API IkarusNumberValue * ikarus_number_value_copy(IkarusNumberValue const * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Converts a number value to an entity value.
|
/// \brief Converts a number value to an entity value.
|
||||||
/// \param value The number value to convert.
|
/// \param value The number value to convert.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The converted entity value.
|
/// \return The converted entity value.
|
||||||
/// \remark This is the same pointer, so freeing it implies freeing the original 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);
|
IKA_API struct IkarusValue * ikarus_number_value_to_value(IkarusNumberValue * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \see ikarus_toggle_value_to_value
|
/// \see ikarus_toggle_value_to_value
|
||||||
IKA_API struct IkarusValue const * ikarus_number_value_to_value_const(IkarusNumberValue const * value);
|
IKA_API struct IkarusValue const * ikarus_number_value_to_value_const(IkarusNumberValue const * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
/// \file text_value.h
|
/// \file text_value.h
|
||||||
/// \author Folling <folling@ikarus.world>
|
/// \author Folling <folling@ikarus.world>
|
||||||
|
|
||||||
|
#include <ikarus/errors.h>
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
#include <ikarus/stdtypes.h>
|
#include <ikarus/stdtypes.h>
|
||||||
|
|
||||||
|
|
@ -14,101 +15,115 @@ IKARUS_BEGIN_HEADER
|
||||||
/// \brief A textual value. For example "Surname" or "Description"
|
/// \brief A textual value. For example "Surname" or "Description"
|
||||||
struct IkarusTextValue;
|
struct IkarusTextValue;
|
||||||
|
|
||||||
/// \brief Creates a text value.
|
/// \brief Creates an empty text value.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The value or null if an error occurs.
|
/// \return The value or null if an error occurs.
|
||||||
/// \remark Must be freed with #ikarus_free.
|
/// \remark Must be freed with #ikarus_free.
|
||||||
IKA_API IkarusTextValue * ikarus_text_value_create();
|
IKA_API IkarusTextValue * ikarus_text_value_create(IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Fetches the underlying data of a number value at a specific index.
|
/// \brief Fetches the underlying data of a number value at a specific index.
|
||||||
/// \param value The number value.
|
/// \param value The number value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param idx The index of the data to fetch.
|
/// \param idx The index of the data to fetch.
|
||||||
/// \pre \li Must be less than the size of the value.
|
/// \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.
|
/// \return The underlying data or null if an error occurs or the value is undefined.
|
||||||
/// \remark This value is owned by LibIkarus and must not be freed.
|
IKA_API char const * const * ikarus_text_value_get(IkarusTextValue const * value, size_t idx, IkarusErrorData * error_out);
|
||||||
IKA_API char const * ikarus_text_value_get(IkarusTextValue * value, size_t idx);
|
|
||||||
|
|
||||||
/// \brief Fetches the size of the underlying data of a text value.
|
/// \brief Fetches the size of the underlying data of a text value.
|
||||||
/// \param value The text value.
|
/// \param value The text value.
|
||||||
/// \pre \li Must not be null.
|
/// \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 or the value is undefined.
|
||||||
IKA_API size_t ikarus_text_value_get_size(IkarusTextValue const * value);
|
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.
|
/// \brief Sets the data of a text value at a specific index.
|
||||||
/// \param value The text value.
|
/// \param value The text value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param idx The index of the data to set.
|
/// \param idx The index of the data to set.
|
||||||
/// \pre \li Must be less than the size of the value.
|
/// \pre \li Must be less than the size of the value.
|
||||||
/// \param new_data The new data. LibIkarus assumes ownership of this pointer.
|
/// \param new_data The new data. Ownership remains with the caller.
|
||||||
IKA_API void ikarus_text_value_set(IkarusTextValue * value, size_t idx, char const * new_data);
|
/// \pre \li Must not be null.
|
||||||
|
/// \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 Removes a data from a text value.
|
/// \brief Removes a data from a text value.
|
||||||
/// \param value The text value.
|
/// \param value The text value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param idx The index of the data to remove.
|
/// \param idx The index of the data to remove.
|
||||||
/// \pre \li Must be less than the size of the value.
|
/// \pre \li Must be less than the size of the value.
|
||||||
IKA_API void ikarus_text_value_remove(IkarusTextValue * value, size_t idx);
|
/// \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.
|
/// \brief Inserts a data into a text value.
|
||||||
/// \param value The text value.
|
/// \param value The text value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param idx The index of the data to insert.
|
/// \param idx The index of the data to insert.
|
||||||
/// \pre \li Must be less than or equal to the size of the value.
|
/// \pre \li Must be less than or equal to the size of the value.
|
||||||
/// \param new_data The new data.
|
/// \param new_data The new data. Ownership remains with the caller.
|
||||||
IKA_API void ikarus_text_value_insert(IkarusTextValue * value, size_t idx, char const * new_data);
|
/// \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.
|
/// \brief Clears a text value.
|
||||||
/// \param value The text value.
|
/// \param value The text value.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark Noop if the value is undefined.
|
/// \remark Noop if the value is undefined.
|
||||||
IKA_API void ikarus_text_value_clear(IkarusTextValue * value);
|
IKA_API void ikarus_text_value_clear(IkarusTextValue * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Checks if a text value is undefined.
|
/// \brief Checks if a text value is undefined.
|
||||||
/// \param value The text value.
|
/// \param value The text value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return True if the value is undefined, false otherwise.
|
/// \return True if the value is undefined, false otherwise.
|
||||||
IKA_API bool ikarus_text_value_is_undefined(IkarusTextValue const * value);
|
IKA_API bool ikarus_text_value_is_undefined(IkarusTextValue const * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Changes a text value's undefined state.
|
/// \brief Changes a text value's undefined state.
|
||||||
/// \param value The text value.
|
/// \param value The text value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param undefined The new undefined state.
|
/// \param undefined The new undefined state.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark Noop if the value is already undefined.
|
/// \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 undefined, all data will be cleared.
|
||||||
/// \remark If the value is set to not undefined, the value is as if newly created.
|
/// \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);
|
IKA_API void ikarus_text_value_set_undefined(IkarusTextValue * value, bool undefined, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Converts a text value to a string.
|
/// \brief Converts a text value to a string.
|
||||||
/// \param value The text value to convert.
|
/// \param value The text value to convert.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The converted string.
|
/// \return The converted string.
|
||||||
/// \remark Must be freed with #ikarus_free.
|
/// \remark Must be freed with #ikarus_free.
|
||||||
/// \remark Undefined if the value is undefined.
|
/// \remark Undefined if the value is undefined.
|
||||||
IKA_API char const * ikarus_text_value_to_string(IkarusTextValue const * value);
|
IKA_API char const * ikarus_text_value_to_string(IkarusTextValue const * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Checks if two values are equal.
|
/// \brief Checks if two values are equal.
|
||||||
/// \param lhs The left hand side value.
|
/// \param lhs The left hand side value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param rhs The right hand side value.
|
/// \param rhs The right hand side value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return True if the values' data are equal, false otherwise.
|
/// \return True if the values' data are equal, false otherwise.
|
||||||
IKA_API bool ikarus_text_value_is_equal(IkarusTextValue const * lhs, IkarusTextValue const * rhs);
|
IKA_API bool ikarus_text_value_is_equal(IkarusTextValue const * lhs, IkarusTextValue const * rhs, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Creates a copy of a text value.
|
/// \brief Creates a copy of a text value.
|
||||||
/// \param value The value to copy.
|
/// \param value The value to copy.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The copied value.
|
/// \return The copied value.
|
||||||
/// \remark Must be freed with #ikarus_free.
|
/// \remark Must be freed with #ikarus_free.
|
||||||
IKA_API IkarusTextValue * ikarus_text_value_copy(IkarusTextValue const * value);
|
IKA_API IkarusTextValue * ikarus_text_value_copy(IkarusTextValue const * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Converts a text value to an entity value.
|
/// \brief Converts a text value to an entity value.
|
||||||
/// \param value The text value to convert.
|
/// \param value The text value to convert.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The converted entity value.
|
/// \return The converted entity value.
|
||||||
/// \remark This is the same pointer, so freeing it implies freeing the original 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);
|
IKA_API struct IkarusValue * ikarus_text_value_to_value(IkarusTextValue * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \see ikarus_toggle_value_to_value
|
/// \see ikarus_text_value_to_value
|
||||||
IKA_API struct IkarusValue const * ikarus_text_value_to_value_const(IkarusTextValue const * value);
|
IKA_API struct IkarusValue const * ikarus_text_value_to_value_const(IkarusTextValue const * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
/// \file toggle_value.h
|
/// \file toggle_value.h
|
||||||
/// \author Folling <folling@ikarus.world>
|
/// \author Folling <folling@ikarus.world>
|
||||||
|
|
||||||
|
#include <ikarus/errors.h>
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
#include <ikarus/stdtypes.h>
|
#include <ikarus/stdtypes.h>
|
||||||
|
|
||||||
|
|
@ -14,24 +15,27 @@ IKARUS_BEGIN_HEADER
|
||||||
/// \brief A true/false boolean-esque value. For example "Is Dead".
|
/// \brief A true/false boolean-esque value. For example "Is Dead".
|
||||||
struct IkarusToggleValue;
|
struct IkarusToggleValue;
|
||||||
|
|
||||||
/// \brief Creates a toggle.
|
/// \brief Creates an empty toggle value.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The value or null if an error occurs.
|
/// \return The value or null if an error occurs.
|
||||||
/// \remark Must be freed with #ikarus_free.
|
/// \remark Must be freed with #ikarus_free.
|
||||||
IKA_API IkarusToggleValue * ikarus_toggle_value_create();
|
IKA_API IkarusToggleValue * ikarus_toggle_value_create(IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Fetches the underlying data of a number value at a specific index.
|
/// \brief Fetches the underlying data of a number value at a specific index.
|
||||||
/// \param value The number value.
|
/// \param value The number value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param idx The index of the data to fetch.
|
/// \param idx The index of the data to fetch.
|
||||||
/// \pre \li Must be less than the size of the value.
|
/// \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.
|
/// \return The underlying data or null if an error occurs or the value is undefined.
|
||||||
IKA_API bool const * ikarus_toggle_value_get(IkarusToggleValue * value, size_t idx);
|
IKA_API bool const * 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.
|
/// \brief Fetches the size of the underlying data of a toggle value.
|
||||||
/// \param value The toggle value.
|
/// \param value The toggle value.
|
||||||
/// \pre \li Must not be null.
|
/// \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 or the value is undefined.
|
||||||
IKA_API size_t ikarus_toggle_value_get_size(IkarusToggleValue const * value);
|
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.
|
/// \brief Sets the data of a toggle value at a specific index.
|
||||||
/// \param value The toggle value.
|
/// \param value The toggle value.
|
||||||
|
|
@ -39,14 +43,16 @@ IKA_API size_t ikarus_toggle_value_get_size(IkarusToggleValue const * value);
|
||||||
/// \param idx The index of the data to set.
|
/// \param idx The index of the data to set.
|
||||||
/// \pre \li Must be less than the size of the value.
|
/// \pre \li Must be less than the size of the value.
|
||||||
/// \param new_data The new data.
|
/// \param new_data The new data.
|
||||||
IKA_API void ikarus_toggle_value_set(IkarusToggleValue * value, size_t idx, bool new_data);
|
/// \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.
|
/// \brief Removes a data from a toggle value.
|
||||||
/// \param value The toggle value.
|
/// \param value The toggle value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param idx The index of the data to remove.
|
/// \param idx The index of the data to remove.
|
||||||
/// \pre \li Must be less than the size of the value.
|
/// \pre \li Must be less than the size of the value.
|
||||||
IKA_API void ikarus_toggle_value_remove(IkarusToggleValue * value, size_t idx);
|
/// \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.
|
/// \brief Inserts a data into a toggle value.
|
||||||
/// \param value The toggle value.
|
/// \param value The toggle value.
|
||||||
|
|
@ -54,60 +60,68 @@ IKA_API void ikarus_toggle_value_remove(IkarusToggleValue * value, size_t idx);
|
||||||
/// \param idx The index of the data to insert.
|
/// \param idx The index of the data to insert.
|
||||||
/// \pre \li Must be less than or equal to the size of the value.
|
/// \pre \li Must be less than or equal to the size of the value.
|
||||||
/// \param new_data The new data.
|
/// \param new_data The new data.
|
||||||
IKA_API void ikarus_toggle_value_insert(IkarusToggleValue * value, size_t idx, bool 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 Clears a toggle value.
|
/// \brief Clears a toggle value.
|
||||||
/// \param value The toggle value.
|
/// \param value The toggle value.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark Noop if the value is undefined.
|
/// \remark Noop if the value is undefined.
|
||||||
IKA_API void ikarus_toggle_value_clear(IkarusToggleValue * value);
|
IKA_API void ikarus_toggle_value_clear(IkarusToggleValue * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Checks if a toggle value is undefined.
|
/// \brief Checks if a toggle value is undefined.
|
||||||
/// \param value The toggle value.
|
/// \param value The toggle value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return True if the value is undefined, false otherwise.
|
/// \return True if the value is undefined, false otherwise.
|
||||||
IKA_API bool ikarus_toggle_value_is_undefined(IkarusToggleValue const * value);
|
IKA_API bool ikarus_toggle_value_is_undefined(IkarusToggleValue const * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Changes a toggle value's undefined state.
|
/// \brief Changes a toggle value's undefined state.
|
||||||
/// \param value The toggle value.
|
/// \param value The toggle value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param undefined The new undefined state.
|
/// \param undefined The new undefined state.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \remark Noop if the value is already undefined.
|
/// \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 undefined, all data will be cleared.
|
||||||
/// \remark If the value is set to not undefined, the value is as if newly created.
|
/// \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);
|
IKA_API void ikarus_toggle_value_set_undefined(IkarusToggleValue * value, bool undefined, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Converts a toggle value to a string.
|
/// \brief Converts a toggle value to a string.
|
||||||
/// \param value The toggle value to convert.
|
/// \param value The toggle value to convert.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The converted string.
|
/// \return The converted string.
|
||||||
/// \remark Must be freed with #ikarus_free.
|
/// \remark Must be freed with #ikarus_free.
|
||||||
/// \remark Undefined if the value is undefined.
|
/// \remark Undefined if the value is undefined.
|
||||||
IKA_API char const * ikarus_toggle_value_to_string(IkarusToggleValue const * value);
|
IKA_API char const * ikarus_toggle_value_to_string(IkarusToggleValue const * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Checks if two values are equal.
|
/// \brief Checks if two values are equal.
|
||||||
/// \param lhs The left hand side value.
|
/// \param lhs The left hand side value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
/// \param rhs The right hand side value.
|
/// \param rhs The right hand side value.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return True if the values' data are equal, false otherwise.
|
/// \return True if the values' data are equal, false otherwise.
|
||||||
IKA_API bool ikarus_toggle_value_is_equal(IkarusToggleValue const * lhs, IkarusToggleValue const * rhs);
|
IKA_API bool ikarus_toggle_value_is_equal(IkarusToggleValue const * lhs, IkarusToggleValue const * rhs, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Creates a copy of a toggle value.
|
/// \brief Creates a copy of a toggle value.
|
||||||
/// \param value The value to copy.
|
/// \param value The value to copy.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The copied value.
|
/// \return The copied value.
|
||||||
/// \remark Must be freed with #ikarus_free.
|
/// \remark Must be freed with #ikarus_free.
|
||||||
IKA_API IkarusToggleValue * ikarus_toggle_value_copy(IkarusToggleValue const * value);
|
IKA_API IkarusToggleValue * ikarus_toggle_value_copy(IkarusToggleValue const * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \brief Converts a toggle value to an entity value.
|
/// \brief Converts a toggle value to an entity value.
|
||||||
/// \param value The toggle value to convert.
|
/// \param value The toggle value to convert.
|
||||||
/// \pre \li Must not be null.
|
/// \pre \li Must not be null.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
/// \return The converted entity value.
|
/// \return The converted entity value.
|
||||||
/// \remark This is the same pointer, so freeing it implies freeing the original 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);
|
IKA_API struct IkarusValue * ikarus_toggle_value_to_value(IkarusToggleValue * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
/// \see ikarus_toggle_value_to_value
|
/// \see ikarus_toggle_value_to_value
|
||||||
IKA_API struct IkarusValue const * ikarus_toggle_value_to_value_const(IkarusToggleValue const * value);
|
IKA_API struct IkarusValue const * ikarus_toggle_value_to_value_const(IkarusToggleValue const * value, IkarusErrorData * error_out);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
/// \file value.h
|
/// \file value.h
|
||||||
/// \author Folling <folling@ikarus.world>
|
/// \author Folling <folling@ikarus.world>
|
||||||
|
|
||||||
|
#include <ikarus/errors.h>
|
||||||
#include <ikarus/macros.h>
|
#include <ikarus/macros.h>
|
||||||
|
|
||||||
/// \defgroup values Values
|
/// \defgroup values Values
|
||||||
|
|
@ -11,7 +12,7 @@
|
||||||
/// These value classes represent plain objects. They are not associated with any entity.
|
/// These value classes represent plain objects. They are not associated with any entity.
|
||||||
/// Each value may be undefined. \see IkarusProperty
|
/// 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 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.
|
/// 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
|
/// 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
|
/// property's settings. \see PropertyType
|
||||||
/// @{
|
/// @{
|
||||||
|
|
@ -28,12 +29,14 @@ struct IkarusValue;
|
||||||
/// \param number_visitor The function to call if the value is a number 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 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.
|
/// \param data The data passed to the visitor functions.
|
||||||
|
/// \param error_out \see errors.h
|
||||||
IKA_API void ikarus_value_visit(
|
IKA_API void ikarus_value_visit(
|
||||||
IkarusValue * value,
|
IkarusValue * value,
|
||||||
void (*toggle_visitor)(struct IkarusToggleValue *, void *),
|
void (*toggle_visitor)(struct IkarusToggleValue *, void *),
|
||||||
void (*number_visitor)(struct IkarusNumberValue *, void *),
|
void (*number_visitor)(struct IkarusNumberValue *, void *),
|
||||||
void (*text_visitor)(struct IkarusTextValue *, void *),
|
void (*text_visitor)(struct IkarusTextValue *, void *),
|
||||||
void * data
|
void * data,
|
||||||
|
IkarusErrorData * error_out
|
||||||
);
|
);
|
||||||
|
|
||||||
/// \see ikarus_value_visit
|
/// \see ikarus_value_visit
|
||||||
|
|
@ -42,7 +45,8 @@ IKA_API void ikarus_value_visit_const(
|
||||||
void (*toggle_visitor)(struct IkarusToggleValue const *, void *),
|
void (*toggle_visitor)(struct IkarusToggleValue const *, void *),
|
||||||
void (*number_visitor)(struct IkarusNumberValue const *, void *),
|
void (*number_visitor)(struct IkarusNumberValue const *, void *),
|
||||||
void (*text_visitor)(struct IkarusTextValue const *, void *),
|
void (*text_visitor)(struct IkarusTextValue const *, void *),
|
||||||
void * data
|
void * data,
|
||||||
|
IkarusErrorData * error_out
|
||||||
);
|
);
|
||||||
|
|
||||||
IKARUS_END_HEADER
|
IKARUS_END_HEADER
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,71 @@
|
||||||
#include "ikarus/errors.h"
|
#include "ikarus/errors.h"
|
||||||
|
|
||||||
|
#include "cppbase/functional.hpp"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
char const * get_error_info_name(IkarusErrorInfo info) {
|
char const * get_error_info_name(IkarusErrorInfo info) {
|
||||||
switch (info) {
|
switch (info) {
|
||||||
case IkarusErrorInfo_Source_None: return "IkarusErrorInfo_Source_None";
|
case IkarusErrorInfo_None: return "None";
|
||||||
case IkarusErrorInfo_Source_Client: return "IkarusErrorInfo_Source_Client";
|
case IkarusErrorInfo_Client: return "Client";
|
||||||
case IkarusErrorInfo_Source_SubSystem: return "IkarusErrorInfo_Source_SubSystem";
|
case IkarusErrorInfo_Dependency: return "Dependency";
|
||||||
case IkarusErrorInfo_Source_LibIkarus: return "IkarusErrorInfo_Source_LibIkarus";
|
case IkarusErrorInfo_Filesystem: return "Filesystem";
|
||||||
case IkarusErrorInfo_Source_Unknown: return "IkarusErrorInfo_Source_Unknown";
|
case IkarusErrorInfo_Database: return "Database";
|
||||||
case IkarusErrorInfo_Type_None: return "IkarusErrorInfo_Type_None";
|
case IkarusErrorInfo_OS: return "OS";
|
||||||
case IkarusErrorInfo_Type_Client_Misuse: return "IkarusErrorInfo_Type_Client_Misuse";
|
case IkarusErrorInfo_LibIkarus: return "libikarus";
|
||||||
case IkarusErrorInfo_Type_Client_Input: return "IkarusErrorInfo_Type_Client_Input";
|
|
||||||
case IkarusErrorInfo_Type_SubSystem_Dependency: return "IkarusErrorInfo_Type_SubSystem_Dependency";
|
case IkarusErrorInfo_Client_Misuse: return "Misuse";
|
||||||
case IkarusErrorInfo_Type_SubSystem_Database: return "IkarusErrorInfo_Type_SubSystem_Database";
|
case IkarusErrorInfo_Client_InvalidInput: return "InvalidInput";
|
||||||
case IkarusErrorInfo_Type_SubSystem_Filesystem: return "IkarusErrorInfo_Type_SubSystem_Filesystem";
|
case IkarusErrorInfo_Client_InvalidFormat: return "InvalidFormat";
|
||||||
case IkarusErrorInfo_Type_LibIkarus_InvalidState: return "IkarusErrorInfo_Type_LibIkarus_InvalidState";
|
case IkarusErrorInfo_Client_ConstraintViolated: return "ConstraintViolated";
|
||||||
case IkarusErrorInfo_Type_LibIkarus_CannotPerformOperation: return "IkarusErrorInfo_Type_LibIkarus_CannotPerformOperation";
|
|
||||||
case IkarusErrorInfo_Type_LibIkarus_Timeout: return "IkarusErrorInfo_Type_LibIkarus_Timeout";
|
case IkarusErrorInfo_Filesystem_NotFound: return "NotFound";
|
||||||
case IkarusErrorInfo_Type_Unknown: return "IkarusErrorInfo_Type_Unknown";
|
case IkarusErrorInfo_Filesystem_AlreadyExists: return "AlreadyExists";
|
||||||
default: return "Unknown";
|
case IkarusErrorInfo_Filesystem_MissingPermissions: return "MissingPermissions";
|
||||||
|
case IkarusErrorInfo_Filesystem_InsufficientSpace: return "InsufficientSpace";
|
||||||
|
case IkarusErrorInfo_Filesystem_InvalidPath: return "InvalidPath";
|
||||||
|
|
||||||
|
case IkarusErrorInfo_Database_ConnectionFailed: return "ConnectionFailed";
|
||||||
|
case IkarusErrorInfo_Database_QueryFailed: return "QueryFailed";
|
||||||
|
case IkarusErrorInfo_Database_MigrationFailed: return "MigrationFailed";
|
||||||
|
case IkarusErrorInfo_Database_InvalidState: return "InvalidState";
|
||||||
|
|
||||||
|
case IkarusErrorInfo_OS_SystemCallFailed: return "SystemCallFailed";
|
||||||
|
case IkarusErrorInfo_OS_InvalidReturnValue: return "InvalidReturnValue";
|
||||||
|
case IkarusErrorInfo_OS_InsufficientMemory: return "InsufficientMemory";
|
||||||
|
|
||||||
|
case IkarusErrorInfo_LibIkarus_InvalidState: return "InvalidState";
|
||||||
|
case IkarusErrorInfo_LibIkarus_Timeout: return "Timeout";
|
||||||
|
|
||||||
|
default: return "Invalid";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ikarus_error_data_is_success(IkarusErrorData const * data) {
|
||||||
|
return data->infos[0] == IkarusErrorInfo_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ikarus_error_data_is_error(IkarusErrorData const * data) {
|
||||||
|
return data->infos[0] != IkarusErrorInfo_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
char const * ikarus_error_data_pretty_format(IkarusErrorData const * data) {
|
||||||
|
if (ikarus_error_data_is_success(data)) {
|
||||||
|
return "Success";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const formatted = fmt::format(
|
||||||
|
"{} - {}",
|
||||||
|
fmt::join(
|
||||||
|
data->infos | std::views::take_while(cppbase::pred_ne(IkarusErrorInfo_None)) | std::views::transform(get_error_info_name),
|
||||||
|
"->"
|
||||||
|
),
|
||||||
|
data->message
|
||||||
|
);
|
||||||
|
|
||||||
|
return strndup(formatted.data(), formatted.size());
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
#include "ikarus/objects/blueprint.h"
|
#include "ikarus/objects/blueprint.h"
|
||||||
|
|
||||||
#include "objects/blueprint.hpp"
|
#include "objects/blueprint.hpp"
|
||||||
#include "util.hpp"
|
|
||||||
|
|
||||||
#include <cppbase/logger.hpp>
|
#include <cppbase/logger.hpp>
|
||||||
#include <cppbase/result.hpp>
|
#include <cppbase/result.hpp>
|
||||||
|
|
@ -9,25 +8,44 @@
|
||||||
|
|
||||||
#include <objects/entity.hpp>
|
#include <objects/entity.hpp>
|
||||||
#include <objects/properties/property.hpp>
|
#include <objects/properties/property.hpp>
|
||||||
#include <objects/util.hpp>
|
|
||||||
#include <persistence/function_context.hpp>
|
|
||||||
#include <persistence/project.hpp>
|
#include <persistence/project.hpp>
|
||||||
|
|
||||||
IkarusBlueprint::IkarusBlueprint(IkarusProject * project, IkarusId id):
|
IkarusBlueprint::IkarusBlueprint(IkarusProject * project, IkarusId id):
|
||||||
IkarusObject{project, id} {}
|
IkarusObject{project, id} {}
|
||||||
|
|
||||||
IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project, char const * name) {
|
IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project, char const * name) {
|
||||||
return ikarus::util::insert_object(
|
if (cppbase::is_empty_or_blank(name)) {
|
||||||
project,
|
project->set_error("blueprint name must not be empty", true, IkarusErrorInfo_Source_Client, IkarusErrorInfo_Type_Client_Input);
|
||||||
IkarusObjectType_Blueprint,
|
|
||||||
name,
|
return nullptr;
|
||||||
[](auto * db, IkarusId id) { return db->execute("INSERT INTO `blueprints`(`id`) VALUES(?)", id); },
|
}
|
||||||
[project](IkarusId id) { return project->get_blueprint(id); }
|
|
||||||
).unwrap_value_or(nullptr);
|
project->db
|
||||||
|
->transact([name](auto * db) {
|
||||||
|
TRY(db->execute("INSERT INTO `objects`(`type`, `name`) VALUES(?, ?, ?)", IkarusObjectType_Blueprint, name));
|
||||||
|
auto id = ikarus_id_from_data_and_type(db->last_insert_rowid(), IkarusObjectType_Blueprint);
|
||||||
|
TRY(db->execute("INSERT INTO `blueprints`(`id`) VALUES(?)", id));
|
||||||
|
return cppbase::ok();
|
||||||
|
})
|
||||||
|
.on_error([project](auto const & err) {
|
||||||
|
project->set_error(
|
||||||
|
fmt::format("failed to create blueprint: {}", err),
|
||||||
|
true,
|
||||||
|
IkarusErrorInfo_Source_SubSystem,
|
||||||
|
IkarusErrorInfo_Type_SubSystem_Database
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ikarus_blueprint_delete(IkarusBlueprint * blueprint) {
|
void ikarus_blueprint_delete(IkarusBlueprint * blueprint) {
|
||||||
ikarus::util::delete_object(blueprint);
|
blueprint->project->db->execute("DELETE FROM `objects` WHERE `id` = ?", blueprint->id).on_error([blueprint](auto const & err) {
|
||||||
|
blueprint->project->set_error(
|
||||||
|
fmt::format("failed to delete blueprint from objects table: {}", err),
|
||||||
|
true,
|
||||||
|
IkarusErrorInfo_Source_SubSystem,
|
||||||
|
IkarusErrorInfo_Type_SubSystem_Database
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ikarus_blueprint_get_properties(
|
void ikarus_blueprint_get_properties(
|
||||||
|
|
@ -35,41 +53,34 @@ void ikarus_blueprint_get_properties(
|
||||||
struct IkarusProperty ** properties_out,
|
struct IkarusProperty ** properties_out,
|
||||||
size_t properties_out_size
|
size_t properties_out_size
|
||||||
) {
|
) {
|
||||||
ikarus::util::fetch_multiple_buffered<IkarusId>(
|
IkarusId ids[properties_out_size];
|
||||||
blueprint,
|
|
||||||
ikarus::util::MultipleBufferQueryData{
|
TRYRV(
|
||||||
.table_name = "properties",
|
,
|
||||||
.select_field_name = "id",
|
blueprint->project->db
|
||||||
.where_field_name = "blueprint",
|
->query_many_buffered<IkarusId>("SELECT `id` FROM `properties` WHERE `source` = ?", ids, properties_out_size, blueprint->id)
|
||||||
.relation_desc = "properties"
|
.on_error([&](auto const & err) {
|
||||||
},
|
blueprint->project->set_error(
|
||||||
properties_out,
|
fmt::format("failed to fetch blueprint properties from database: {}", err),
|
||||||
properties_out_size,
|
|
||||||
[&](IkarusProject * project, IkarusFunctionContext * ctx, IkarusId id) -> cppbase::Result<IkarusProperty *, sqlitecpp::QueryError> {
|
|
||||||
VTRY(auto const type, IkarusProperty::get_property_type(blueprint->project, id).on_error([ctx, id](auto const & err) {
|
|
||||||
ctx->set_error(
|
|
||||||
fmt::format("failed to fetch property {}'s type: {}", id, err),
|
|
||||||
true,
|
true,
|
||||||
IkarusErrorInfo_Source_SubSystem,
|
IkarusErrorInfo_Source_SubSystem,
|
||||||
IkarusErrorInfo_Type_SubSystem_Database
|
IkarusErrorInfo_Type_SubSystem_Database
|
||||||
);
|
);
|
||||||
}));
|
})
|
||||||
|
|
||||||
return cppbase::ok(project->get_property(id, type));
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// not atomic, could be switched to two loops if necessary
|
||||||
|
for (size_t i = 0; i < properties_out_size; ++i) {
|
||||||
|
IkarusId id = ids[i];
|
||||||
|
|
||||||
|
VTRYRV(auto const type, , IkarusProperty::get_property_type(blueprint->project, id));
|
||||||
|
|
||||||
|
properties_out[i] = blueprint->project->get_property(id, type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ikarus_blueprint_get_property_count(IkarusBlueprint const * blueprint) {
|
size_t ikarus_blueprint_get_property_count(IkarusBlueprint const * blueprint) {
|
||||||
return ikarus::util::fetch_count(
|
return blueprint->project->db->query_one<int64_t>("SELECT COUNT(*) FROM `properties` WHERE `source` = ?", blueprint->id)
|
||||||
blueprint,
|
|
||||||
ikarus::util::CountQueryData{
|
|
||||||
.table_name = "blueprint_properties",
|
|
||||||
.select_field_name = "property",
|
|
||||||
.where_field_name = "blueprint",
|
|
||||||
.relation_desc = "properties"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.unwrap_value_or(0);
|
.unwrap_value_or(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,31 +89,34 @@ void ikarus_blueprint_get_linked_entities(
|
||||||
struct IkarusEntity ** entities_out,
|
struct IkarusEntity ** entities_out,
|
||||||
size_t entities_out_size
|
size_t entities_out_size
|
||||||
) {
|
) {
|
||||||
ikarus::util::fetch_multiple_buffered<IkarusId>(
|
IkarusId ids[entities_out_size];
|
||||||
blueprint,
|
|
||||||
ikarus::util::MultipleBufferQueryData{
|
TRYRV(
|
||||||
.table_name = "entity_blueprint_links",
|
,
|
||||||
.select_field_name = "entity",
|
blueprint->project->db
|
||||||
.where_field_name = "blueprint",
|
->query_many_buffered<IkarusId>(
|
||||||
.relation_desc = "linked entities"
|
"SELECT `entity` FROM `entity_blueprint_links` WHERE `blueprint` = ?",
|
||||||
},
|
ids,
|
||||||
entities_out,
|
entities_out_size,
|
||||||
entities_out_size,
|
blueprint->id
|
||||||
[&](IkarusProject * project, [[maybe_unused]] IkarusFunctionContext * ctx, IkarusId id
|
)
|
||||||
) -> cppbase::Result<IkarusEntity *, sqlitecpp::QueryError> { return cppbase::ok(project->get_entity(id)); }
|
.on_error([&](auto const & err) {
|
||||||
|
blueprint->project->set_error(
|
||||||
|
fmt::format("failed to fetch linked entities from database: {}", err),
|
||||||
|
true,
|
||||||
|
IkarusErrorInfo_Source_SubSystem,
|
||||||
|
IkarusErrorInfo_Type_SubSystem_Database
|
||||||
|
);
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < entities_out_size; ++i) {
|
||||||
|
entities_out[i] = blueprint->project->get_entity(ids[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ikarus_blueprint_get_linked_entity_count(IkarusBlueprint const * blueprint) {
|
size_t ikarus_blueprint_get_linked_entity_count(IkarusBlueprint const * blueprint) {
|
||||||
return ikarus::util::fetch_count(
|
return blueprint->project->db->query_one<int64_t>("SELECT COUNT(*) FROM `entity_blueprint_links` WHERE `blueprint` = ?", blueprint->id)
|
||||||
blueprint,
|
|
||||||
ikarus::util::CountQueryData{
|
|
||||||
.table_name = "entity_blueprint_links",
|
|
||||||
.select_field_name = "entity",
|
|
||||||
.where_field_name = "blueprint",
|
|
||||||
.relation_desc = "linked entities"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.unwrap_value_or(0);
|
.unwrap_value_or(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include <objects/blueprint.hpp>
|
#include <objects/blueprint.hpp>
|
||||||
#include <objects/util.hpp>
|
#include <objects/util.hpp>
|
||||||
#include <persistence/function_context.hpp>
|
|
||||||
#include <persistence/project.hpp>
|
#include <persistence/project.hpp>
|
||||||
|
|
||||||
IkarusEntity * ikarus_entity_create(struct IkarusProject * project, char const * name) {
|
IkarusEntity * ikarus_entity_create(struct IkarusProject * project, char const * name) {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
#include <ikarus/objects/properties/property_type.h>
|
#include <ikarus/objects/properties/property_type.h>
|
||||||
|
|
||||||
#include <objects/properties/property_source.hpp>
|
#include <objects/properties/property_source.hpp>
|
||||||
#include <persistence/function_context.hpp>
|
|
||||||
#include <persistence/project.hpp>
|
#include <persistence/project.hpp>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <values/value.hpp>
|
#include <values/value.hpp>
|
||||||
|
|
@ -23,12 +22,10 @@ IkarusProperty::Data const & IkarusProperty::get_data() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
cppbase::Result<IkarusPropertyType, sqlitecpp::SingleQueryError> IkarusProperty::get_property_type(IkarusProject * project, IkarusId id) {
|
cppbase::Result<IkarusPropertyType, sqlitecpp::SingleQueryError> IkarusProperty::get_property_type(IkarusProject * project, IkarusId id) {
|
||||||
auto * ctx = project->get_function_context();
|
|
||||||
|
|
||||||
VTRY(
|
VTRY(
|
||||||
auto const type,
|
auto const type,
|
||||||
project->get_db()->query_one<int>("SELECT `type` FROM `properties` WHERE `id` = ?", id).on_error([ctx](auto const & err) {
|
project->db->query_one<int>("SELECT `type` FROM `properties` WHERE `id` = ?", id).on_error([project](auto const & err) {
|
||||||
ctx->set_error(
|
project->set_error(
|
||||||
fmt::format("failed to fetch unboxed property type: {}", err),
|
fmt::format("failed to fetch unboxed property type: {}", err),
|
||||||
true,
|
true,
|
||||||
IkarusErrorInfo_Source_SubSystem,
|
IkarusErrorInfo_Source_SubSystem,
|
||||||
|
|
@ -41,16 +38,17 @@ cppbase::Result<IkarusPropertyType, sqlitecpp::SingleQueryError> IkarusProperty:
|
||||||
}
|
}
|
||||||
|
|
||||||
IKA_API void ikarus_property_delete(IkarusProperty * property) {
|
IKA_API void ikarus_property_delete(IkarusProperty * property) {
|
||||||
auto * ctx = property->project->get_function_context();
|
TRYRV(
|
||||||
|
,
|
||||||
TRYRV(, property->project->get_db()->execute("DELETE FROM `objects` WHERE `id` = ?", property->id).on_error([ctx](auto const & err) {
|
property->project->db->execute("DELETE FROM `objects` WHERE `id` = ?", property->id).on_error([property](auto const & err) {
|
||||||
ctx->set_error(
|
property->project->set_error(
|
||||||
fmt::format("failed to delete property from objects table: {}", err),
|
fmt::format("failed to delete property from objects table: {}", err),
|
||||||
true,
|
true,
|
||||||
IkarusErrorInfo_Source_SubSystem,
|
IkarusErrorInfo_Source_SubSystem,
|
||||||
IkarusErrorInfo_Type_SubSystem_Database
|
IkarusErrorInfo_Type_SubSystem_Database
|
||||||
);
|
);
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
property->project->uncache(property);
|
property->project->uncache(property);
|
||||||
}
|
}
|
||||||
|
|
@ -60,15 +58,13 @@ IkarusPropertyType ikarus_property_get_type(IkarusProperty const * property) {
|
||||||
}
|
}
|
||||||
|
|
||||||
IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * property) {
|
IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * property) {
|
||||||
auto * ctx = property->project->get_function_context();
|
|
||||||
|
|
||||||
VTRYRV(
|
VTRYRV(
|
||||||
auto const source,
|
auto const source,
|
||||||
nullptr,
|
nullptr,
|
||||||
property->project->get_db()
|
property->project->db
|
||||||
->query_one<int>("SELECT `source` FROM `properties` WHERE `id` = ?", property->id)
|
->query_one<int>("SELECT `source` FROM `properties` WHERE `id` = ?", property->id)
|
||||||
.on_error([ctx](auto const & err) {
|
.on_error([property](auto const & err) {
|
||||||
ctx->set_error(
|
property->project->set_error(
|
||||||
fmt::format("failed to fetch property's source: {}", err),
|
fmt::format("failed to fetch property's source: {}", err),
|
||||||
true,
|
true,
|
||||||
IkarusErrorInfo_Source_SubSystem,
|
IkarusErrorInfo_Source_SubSystem,
|
||||||
|
|
@ -81,7 +77,7 @@ IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * p
|
||||||
case IkarusObjectType_Blueprint: return new IkarusPropertySource{property->project->get_blueprint(source)};
|
case IkarusObjectType_Blueprint: return new IkarusPropertySource{property->project->get_blueprint(source)};
|
||||||
case IkarusObjectType_Entity: return new IkarusPropertySource{property->project->get_entity(source)};
|
case IkarusObjectType_Entity: return new IkarusPropertySource{property->project->get_entity(source)};
|
||||||
default: {
|
default: {
|
||||||
ctx->set_error(
|
property->project->set_error(
|
||||||
fmt::format("PropertySource is neither blueprint nor entity"),
|
fmt::format("PropertySource is neither blueprint nor entity"),
|
||||||
true,
|
true,
|
||||||
IkarusErrorInfo_Source_LibIkarus,
|
IkarusErrorInfo_Source_LibIkarus,
|
||||||
|
|
@ -94,15 +90,13 @@ IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * p
|
||||||
}
|
}
|
||||||
|
|
||||||
IkarusValue * ikarus_property_get_default_value(IkarusProperty const * property) {
|
IkarusValue * ikarus_property_get_default_value(IkarusProperty const * property) {
|
||||||
auto * ctx = property->project->get_function_context();
|
|
||||||
|
|
||||||
VTRYRV(
|
VTRYRV(
|
||||||
auto const value,
|
auto const value,
|
||||||
nullptr,
|
nullptr,
|
||||||
property->project->get_db()
|
property->project->db
|
||||||
->query_one<int>("SELECT `default_value` FROM `properties` WHERE `id` = ?", property->id)
|
->query_one<int>("SELECT `default_value` FROM `properties` WHERE `id` = ?", property->id)
|
||||||
.on_error([ctx](auto const & err) {
|
.on_error([property](auto const & err) {
|
||||||
ctx->set_error(
|
property->project->set_error(
|
||||||
fmt::format("failed to fetch property's default value: {}", err),
|
fmt::format("failed to fetch property's default value: {}", err),
|
||||||
true,
|
true,
|
||||||
IkarusErrorInfo_Source_SubSystem,
|
IkarusErrorInfo_Source_SubSystem,
|
||||||
|
|
|
||||||
|
|
@ -1,241 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "util.hpp"
|
|
||||||
|
|
||||||
#include <concepts>
|
|
||||||
|
|
||||||
#include <cppbase/result.hpp>
|
|
||||||
#include <cppbase/strings.hpp>
|
|
||||||
|
|
||||||
#include <ikarus/id.h>
|
|
||||||
#include <ikarus/objects/object_type.h>
|
|
||||||
|
|
||||||
#include <persistence/function_context.hpp>
|
|
||||||
|
|
||||||
namespace ikarus::util {
|
|
||||||
|
|
||||||
struct EmptyNameError {};
|
|
||||||
|
|
||||||
COMPOUND_ERROR(InsertObjectError, EmptyNameError, sqlitecpp::TransactionError);
|
|
||||||
|
|
||||||
template<typename InsertFunction, typename ObjectFactory>
|
|
||||||
[[nodiscard]] cppbase::Result<std::invoke_result_t<ObjectFactory, IkarusId>, InsertObjectError> insert_object(
|
|
||||||
IkarusProject * project,
|
|
||||||
IkarusObjectType type,
|
|
||||||
std::string_view name,
|
|
||||||
InsertFunction insert_function,
|
|
||||||
ObjectFactory object_factory
|
|
||||||
) {
|
|
||||||
auto const * object_type_str = ikarus_object_type_to_string(type);
|
|
||||||
|
|
||||||
auto * ctx = project->get_function_context();
|
|
||||||
|
|
||||||
if (cppbase::is_empty_or_blank(name)) {
|
|
||||||
ctx->set_error("name is empty or blank", true, IkarusErrorInfo_Source_Client, IkarusErrorInfo_Type_Client_Input);
|
|
||||||
return cppbase::err(EmptyNameError{});
|
|
||||||
}
|
|
||||||
|
|
||||||
VTRY(
|
|
||||||
auto const id,
|
|
||||||
project->get_db()
|
|
||||||
->transact([&](auto * db) -> cppbase::Result<IkarusId, sqlitecpp::TransactionError> {
|
|
||||||
TRY(db->execute("INSERT INTO `objects` (`object_type`, `name`) VALUES(?, ?);", static_cast<int>(type), name));
|
|
||||||
|
|
||||||
auto id = ikarus_id_from_data_and_type(db->last_insert_rowid(), IkarusObjectType_Blueprint);
|
|
||||||
|
|
||||||
TRY(insert_function(db, id));
|
|
||||||
|
|
||||||
return cppbase::ok(id);
|
|
||||||
})
|
|
||||||
.on_error([&](auto const & err) {
|
|
||||||
ctx->set_error(
|
|
||||||
fmt::format("unable to insert {} into database: {}", object_type_str, err),
|
|
||||||
true,
|
|
||||||
IkarusErrorInfo_Source_SubSystem,
|
|
||||||
IkarusErrorInfo_Type_SubSystem_Database
|
|
||||||
);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return cppbase::ok(object_factory(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Object>
|
|
||||||
requires std::derived_from<Object, IkarusObject>
|
|
||||||
void delete_object(Object * object) {
|
|
||||||
auto object_type_str = ikarus_object_type_to_string(ikarus_id_get_object_type(object->id));
|
|
||||||
|
|
||||||
auto * ctx = object->project->get_function_context();
|
|
||||||
|
|
||||||
TRYRV(, object->project->get_db()->execute("DELETE FROM `objects` WHERE `id` = ?", object->id).on_error([&](auto const & err) {
|
|
||||||
ctx->set_error(
|
|
||||||
fmt::format("failed to delete {} from objects table: {}", object_type_str, err),
|
|
||||||
true,
|
|
||||||
IkarusErrorInfo_Source_SubSystem,
|
|
||||||
IkarusErrorInfo_Type_SubSystem_Database
|
|
||||||
);
|
|
||||||
}));
|
|
||||||
|
|
||||||
object->project->uncache(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SingleQueryData {
|
|
||||||
std::string_view table_name;
|
|
||||||
std::string_view select_field_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename Object>
|
|
||||||
requires std::derived_from<Object, IkarusObject>
|
|
||||||
cppbase::Result<T, sqlitecpp::SingleQueryError> fetch_single_field(Object const * object, SingleQueryData const & query_data) {
|
|
||||||
auto object_type_str = ikarus_object_type_to_string(ikarus_id_get_object_type(object->id));
|
|
||||||
|
|
||||||
auto * ctx = object->project->get_function_context();
|
|
||||||
|
|
||||||
VTRY(
|
|
||||||
T value,
|
|
||||||
object->project->get_db()
|
|
||||||
->template query_one<T>(
|
|
||||||
fmt::format("SELECT `{}` FROM `{}` WHERE `id` = ?", query_data.select_field_name, query_data.table_name),
|
|
||||||
object->id
|
|
||||||
)
|
|
||||||
.on_error([&](auto const & err) {
|
|
||||||
ctx->set_error(
|
|
||||||
fmt::format("failed to fetch {} {} from database: {}", object_type_str, query_data.select_field_name, err),
|
|
||||||
true,
|
|
||||||
IkarusErrorInfo_Source_SubSystem,
|
|
||||||
IkarusErrorInfo_Type_SubSystem_Database
|
|
||||||
);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MultipleBufferQueryData {
|
|
||||||
std::string_view table_name;
|
|
||||||
std::string_view select_field_name;
|
|
||||||
std::string_view where_field_name;
|
|
||||||
std::string_view relation_desc;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Selected, typename Mapped, typename Object, typename F>
|
|
||||||
requires std::derived_from<Object, IkarusObject>
|
|
||||||
void fetch_multiple_buffered(
|
|
||||||
Object const * object,
|
|
||||||
MultipleBufferQueryData const & query_data,
|
|
||||||
Mapped * mapped_buffer,
|
|
||||||
size_t buffer_size,
|
|
||||||
F transformer
|
|
||||||
)
|
|
||||||
requires cppbase::is_result_with_value_type_v<Mapped, std::invoke_result_t<F, IkarusProject *, IkarusFunctionContext *, Selected>>
|
|
||||||
{
|
|
||||||
auto * ctx = object->project->get_function_context();
|
|
||||||
|
|
||||||
auto object_type_str = ikarus_object_type_to_string(ikarus_id_get_object_type(object->id));
|
|
||||||
|
|
||||||
Selected select_buffer[buffer_size];
|
|
||||||
|
|
||||||
TRYRV(
|
|
||||||
,
|
|
||||||
object->project->get_db()
|
|
||||||
->template query_many_buffered<Selected>(
|
|
||||||
fmt::format(
|
|
||||||
"SELECT `{}` FROM `{}` WHERE `{}` = ?",
|
|
||||||
query_data.select_field_name,
|
|
||||||
query_data.table_name,
|
|
||||||
query_data.where_field_name
|
|
||||||
),
|
|
||||||
select_buffer,
|
|
||||||
buffer_size,
|
|
||||||
object->id
|
|
||||||
)
|
|
||||||
.on_error([&](auto const & err) {
|
|
||||||
ctx->set_error(
|
|
||||||
fmt::format("failed to fetch {} {} from database: {}", object_type_str, query_data.relation_desc, err),
|
|
||||||
true,
|
|
||||||
IkarusErrorInfo_Source_SubSystem,
|
|
||||||
IkarusErrorInfo_Type_SubSystem_Database
|
|
||||||
);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < buffer_size; ++i) {
|
|
||||||
VTRYRV(mapped_buffer[i], , transformer(object->project, ctx, select_buffer[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CountQueryData {
|
|
||||||
std::string_view table_name;
|
|
||||||
std::string_view select_field_name;
|
|
||||||
std::string_view where_field_name;
|
|
||||||
std::string_view relation_desc;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Object>
|
|
||||||
requires std::derived_from<Object, IkarusObject>
|
|
||||||
cppbase::Result<cppbase::usize, sqlitecpp::QueryError> fetch_count(Object const * object, CountQueryData const & query_data) {
|
|
||||||
auto * object_type_str = ikarus_object_type_to_string(ikarus_id_get_object_type(object->id));
|
|
||||||
|
|
||||||
auto * ctx = object->project->get_function_context();
|
|
||||||
|
|
||||||
VTRY(
|
|
||||||
auto count,
|
|
||||||
object->project->get_db()
|
|
||||||
->template query_one<int>(
|
|
||||||
fmt::format(
|
|
||||||
"SELECT COUNT(`{}`) FROM `{}` WHERE `{}` = ?;",
|
|
||||||
query_data.select_field_name,
|
|
||||||
query_data.table_name,
|
|
||||||
query_data.where_field_name
|
|
||||||
),
|
|
||||||
object->id
|
|
||||||
)
|
|
||||||
.on_error([&](auto const & err) {
|
|
||||||
ctx->set_error(
|
|
||||||
fmt::format("failed to fetch {} {} count: {}", object_type_str, query_data.relation_desc, err),
|
|
||||||
true,
|
|
||||||
IkarusErrorInfo_Source_SubSystem,
|
|
||||||
IkarusErrorInfo_Type_SubSystem_Database
|
|
||||||
);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return cppbase::ok(static_cast<size_t>(count));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct ExistsQueryData {
|
|
||||||
std::string_view table_name;
|
|
||||||
std::string_view where_field_name;
|
|
||||||
T where_field_value;
|
|
||||||
std::string_view relation_desc;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Object, typename T>
|
|
||||||
requires std::derived_from<Object, IkarusObject>
|
|
||||||
cppbase::Result<bool, sqlitecpp::QueryError> check_exists(Object const * object, ExistsQueryData<T> const & query_data) {
|
|
||||||
auto * object_type_str = ikarus_object_type_to_string(ikarus_id_get_object_type(object->id));
|
|
||||||
|
|
||||||
auto * ctx = object->project->get_function_context();
|
|
||||||
|
|
||||||
VTRY(
|
|
||||||
auto exists,
|
|
||||||
object->project->get_db()
|
|
||||||
->template query_one<int>(
|
|
||||||
fmt::format("SELECT EXISTS(SELECT 1 FROM `{}` WHERE `{}` = ?);", query_data.table_name, query_data.where_field_name),
|
|
||||||
query_data.where_field_value
|
|
||||||
)
|
|
||||||
.on_error([&](auto const & err) {
|
|
||||||
ctx->set_error(
|
|
||||||
fmt::format("failed to check whether {} {} exists: {}", object_type_str, query_data.relation_desc, err),
|
|
||||||
true,
|
|
||||||
IkarusErrorInfo_Source_SubSystem,
|
|
||||||
IkarusErrorInfo_Type_SubSystem_Database
|
|
||||||
);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return cppbase::ok(static_cast<bool>(exists));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ikarus::util
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
#include "function_context.hpp"
|
|
||||||
|
|
||||||
IkarusFunctionContext::IkarusFunctionContext(IkarusProject * project):
|
|
||||||
_project{project} {}
|
|
||||||
|
|
||||||
IkarusFunctionContext::~IkarusFunctionContext() {
|
|
||||||
if (_project->_function_contexts.size() == 1) {
|
|
||||||
if (_project->error_message_buffer.empty()) {
|
|
||||||
_project->error_message_buffer.push_back('\0');
|
|
||||||
} else {
|
|
||||||
_project->error_message_buffer[0] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
_project->error_infos = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
_project->_function_contexts.pop_back();
|
|
||||||
}
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ranges>
|
|
||||||
#include <string_view>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include <fmt/format.h>
|
|
||||||
|
|
||||||
#include <cppbase/logger.hpp>
|
|
||||||
|
|
||||||
#include <ikarus/errors.h>
|
|
||||||
|
|
||||||
#include <persistence/project.hpp>
|
|
||||||
|
|
||||||
struct IkarusFunctionContext {
|
|
||||||
public:
|
|
||||||
explicit IkarusFunctionContext(struct IkarusProject * project);
|
|
||||||
|
|
||||||
IkarusFunctionContext(IkarusFunctionContext const &) noexcept = default;
|
|
||||||
IkarusFunctionContext(IkarusFunctionContext &&) noexcept = default;
|
|
||||||
|
|
||||||
auto operator=(IkarusFunctionContext const &) noexcept -> IkarusFunctionContext & = default;
|
|
||||||
auto operator=(IkarusFunctionContext &&) noexcept -> IkarusFunctionContext & = default;
|
|
||||||
|
|
||||||
~IkarusFunctionContext();
|
|
||||||
|
|
||||||
public:
|
|
||||||
template<typename... Infos>
|
|
||||||
requires(std::is_same_v<IkarusErrorInfo, Infos> && ...) && (sizeof...(Infos) <= MAXIMUM_ERROR_INFOS)
|
|
||||||
auto 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < error_message.size(); ++i) {
|
|
||||||
_project->error_message_buffer[i] = error_message[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
_project->error_message_buffer[error_message.size()] = '\0';
|
|
||||||
_project->error_infos = {infos...};
|
|
||||||
|
|
||||||
if (log_error) {
|
|
||||||
LOG_ERROR("Error({}): {}", fmt::join(_project->error_infos | std::views::transform(get_error_info_name), ", "), error_message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct IkarusProject * _project;
|
|
||||||
};
|
|
||||||
|
|
@ -8,27 +8,14 @@
|
||||||
#include <objects/properties/property.hpp>
|
#include <objects/properties/property.hpp>
|
||||||
#include <objects/properties/text_property.hpp>
|
#include <objects/properties/text_property.hpp>
|
||||||
#include <objects/properties/toggle_property.hpp>
|
#include <objects/properties/toggle_property.hpp>
|
||||||
#include <persistence/function_context.hpp>
|
|
||||||
|
|
||||||
auto IkarusProject::get_name() const -> std::string_view {
|
IkarusProject::IkarusProject(std::string_view name, std::filesystem::path path):
|
||||||
return _name;
|
name{name},
|
||||||
}
|
path{path},
|
||||||
|
db{nullptr},
|
||||||
auto IkarusProject::get_path() const -> std::filesystem::path const & {
|
_blueprints{},
|
||||||
return _path;
|
_properties{},
|
||||||
}
|
_entities{} {}
|
||||||
|
|
||||||
auto IkarusProject::get_db() -> sqlitecpp::Connection * {
|
|
||||||
return _db.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto IkarusProject::get_db() const -> sqlitecpp::Connection const * {
|
|
||||||
return _db.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto IkarusProject::get_function_context() -> IkarusFunctionContext * {
|
|
||||||
return &_function_contexts.emplace_back(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
IkarusBlueprint * IkarusProject::get_blueprint(IkarusId id) {
|
IkarusBlueprint * IkarusProject::get_blueprint(IkarusId id) {
|
||||||
return get_cached_object<IkarusBlueprint>(id, this->_blueprints);
|
return get_cached_object<IkarusBlueprint>(id, this->_blueprints);
|
||||||
|
|
|
||||||
|
|
@ -11,20 +11,10 @@
|
||||||
#include <ikarus/id.h>
|
#include <ikarus/id.h>
|
||||||
#include <ikarus/objects/properties/property_type.h>
|
#include <ikarus/objects/properties/property_type.h>
|
||||||
|
|
||||||
constexpr inline auto MAXIMUM_ERROR_INFOS = 8;
|
|
||||||
|
|
||||||
/// \private
|
/// \private
|
||||||
struct IkarusProject {
|
struct IkarusProject {
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] auto get_name() const -> std::string_view;
|
IkarusProject(std::string_view name, std::filesystem::path path);
|
||||||
|
|
||||||
[[nodiscard]] auto get_path() const -> std::filesystem::path const &;
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_db() -> sqlitecpp::Connection *;
|
|
||||||
[[nodiscard]] auto get_db() const -> sqlitecpp::Connection const *;
|
|
||||||
|
|
||||||
public:
|
|
||||||
[[nodiscard]] auto get_function_context() -> struct IkarusFunctionContext *;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] auto get_blueprint(IkarusId id) -> struct IkarusBlueprint *;
|
[[nodiscard]] auto get_blueprint(IkarusId id) -> struct IkarusBlueprint *;
|
||||||
|
|
@ -53,19 +43,13 @@ private:
|
||||||
cache.erase(object->id);
|
cache.erase(object->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string name;
|
||||||
|
std::filesystem::path path;
|
||||||
|
std::unique_ptr<sqlitecpp::Connection> db;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend struct IkarusFunctionContext;
|
std::unordered_map<IkarusId, std::unique_ptr<struct IkarusBlueprint>> _blueprints;
|
||||||
|
std::unordered_map<IkarusId, std::unique_ptr<struct IkarusProperty>> _properties;
|
||||||
std::string _name;
|
std::unordered_map<IkarusId, std::unique_ptr<struct IkarusEntity>> _entities;
|
||||||
std::filesystem::path _path;
|
|
||||||
std::unique_ptr<sqlitecpp::Connection> _db;
|
|
||||||
|
|
||||||
std::array<IkarusErrorInfo, MAXIMUM_ERROR_INFOS> error_infos;
|
|
||||||
std::string error_message_buffer;
|
|
||||||
|
|
||||||
std::unordered_map<IkarusId, std::unique_ptr<IkarusBlueprint>> _blueprints;
|
|
||||||
std::unordered_map<IkarusId, std::unique_ptr<IkarusProperty>> _properties;
|
|
||||||
std::unordered_map<IkarusId, std::unique_ptr<IkarusEntity>> _entities;
|
|
||||||
|
|
||||||
std::vector<IkarusFunctionContext> _function_contexts;
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue