#pragma once #include #include /// \file entity.h /// \author Folling /// \defgroup entities Entities /// \brief Entities are the core building blocks of Ikarus. IKARUS_BEGIN_HEADER /// \brief Entities are the core building blocks of Ikarus. /// \detials Blueprints and Properties define the structure of the data. /// Entities define the data itself. /// /// Properties can be associated with Entities in two ways: /// - Directly: The property is linked to the entity. /// - Indirectly: The property is linked to a blueprint the entity is linked to. /// /// For each property an entity is linked to, it has a value. These values depend on the property's type. /// For more information on the types see the property documentation. /// /// Values are the core type of data within Ikarus. /// Each value is associated with one page and one property. /// /// \remark Values are typed, the type of a value is specified by its associated property. /// For more information on the types see the property documentation. /// /// \remark Values are guaranteed to be in valid format for a given type /// but not guaranteed to be valid under the settings of the property. /// This is because changing the settings can invalidate existing values without resetting them. struct IkarusEntity; /// \brief Creates an entity. /// \param project The project the entity is part of. /// \pre \li Must not be null. /// \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. /// \pre \li Must not be null. /// \pre \li Must not be empty. /// \param blueprints Blueprints to link the entity to (0..n). Null is treated as an empty array. /// \param blueprints_count The number of blueprints. /// \return The created entity or null if an error occurs. /// \remark Must be freed using #ikarus_free. IKA_API IkarusEntity * ikarus_entity_create( struct IkarusProject * project, struct IkarusEntityFolder * parent, size_t position, char const * name, struct IkarusBlueprint ** blueprints, size_t blueprints_count ); /// \brief Copies an entity. /// \details Creates a deep copy of the entity including all of its properties & associated values. /// \param entity The entity to copy. /// \pre \li Must not be null. /// \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. /// \pre \li Must not be null. /// \pre \li Must not be empty. /// \return The created entity or null if an error occurs. /// \remark Must be freed using #ikarus_free. IKA_API IkarusEntity * ikarus_entity_copy( struct IkarusEntity * entity, struct IkarusEntityFolder * parent, size_t position, char const * name ); /// \brief Deletes an entity. /// \param entity The entity to delete. /// \pre \li Must not be null. /// \pre \li Must exist. /// \remark The entity must not be accessed after deletion. IKA_API void ikarus_entity_delete(IkarusEntity * entity); IKA_API bool ikarus_entity_is_linked_to_blueprint(IkarusEntity const * entity, struct IkarusBlueprint const * blueprint); /// \brief Checks if an entity has a specific property. /// \param entity The entity to check. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param property The property to check. /// \pre \li Must not be null. /// \pre \li Must exist. /// \return True if the entity has the property, false otherwise. IKA_API bool ikarus_entity_has_property(IkarusEntity const * entity, struct IkarusProperty const * property); /// \brief Links an entity to a blueprint. /// \param entity The entity to link. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param blueprint The blueprint to link the entity to. /// \pre \li Must not be null. /// \pre \li Must exist. /// \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); /// \brief Unlinks an entity from a blueprint. All values of the properties of the blueprint the entity is linked with will be /// deleted. /// \param entity The entity to unlink. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param blueprint The blueprint to unlink the entity from. /// \pre \li Must not be null. /// \pre \li Must exist. /// \remark No-op if the entity is not linked to the blueprint. IKA_API void ikarus_entity_unlink_from_blueprint(IkarusEntity * entity, struct IkarusBlueprint * blueprint); /// \brief Gets the project of an entity. /// \param entity The entity to get the project of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \return The project of the entity or null if an error occurs. IKA_API struct IkarusProject * ikarus_entity_get_project(IkarusEntity const * entity); /// \brief Gets the parent folder of an entity. /// \param entity The entity to get the parent folder of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \return The parent folder of the entity or null if an error occurs. IKA_API struct IkarusEntityFolder * ikarus_entity_get_parent(IkarusEntity const * entity); /// \brief Gets the position of an entity within its parent folder. /// \param entity The entity to get the position of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \return The position of the entity or undefined if an error occurs. IKA_API size_t ikarus_entity_get_position(IkarusEntity const * entity); /// \brief Gets the name of an entity. /// \param entity The entity to get the name of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \return The name of the entity or null if an error occurs. /// \remark The returned pointer is valid until the entity is freed but may be invalidated by other operations. IKA_API char const * ikarus_entity_get_name(IkarusEntity const * entity); /// \brief Gets the property root folder of an entity. /// \param entity The entity to get the root folder of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \return The root folder of all properties of the entity or null if an error occurs. /// \remark Must be freed using #ikarus_free. IKA_API struct IkarusPropertyFolder * ikarus_entity_get_property_root_folder(IkarusEntity const * entity); /// \brief Gets the number of properties of an entity. /// \param entity The entity to get the number of properties of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \return The number of properties or undefined if an error occurs. IKA_API size_t ikarus_entity_get_property_count(IkarusEntity const * entity); /// \brief Gets the properties of an entity. /// \param entity The entity to get the properties of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param properties_out The buffer to write the properties to. /// \pre \li Must not be null. /// \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 ); /// \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 indeterminate). /// \param entity The entity to get the value of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param property The property to get the value of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \return The value of the property or null if the entity does not have the property or an error occurs. /// \remark Must be freed using #ikarus_free. IKA_API struct IkarusEntityValue * get_value(IkarusEntity const * entity, struct IkarusProperty const * property); /// \brief Sets the parent folder of an entity. /// \param entity The entity to set the parent folder of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param new_parent The new parent folder of the entity. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param new_position The new position of the entity in the parent folder. \see #FolderPosition /// \pre \li Must be within bounds for the parent folder. /// \remark This adjusts the positions of old and new siblings. IKA_API void ikarus_entity_set_parent(IkarusEntity * entity, struct IkarusEntityFolder * new_parent, size_t new_position); /// \brief Sets the position of an entity within its parent folder. /// \param entity The entity to set the position of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param new_position The new position of the entity. \see #FolderPosition /// \pre \li Must be within bounds for the parent folder. /// \remark This adjusts the positions of siblings. IKA_API void ikarus_entity_set_position(IkarusEntity * entity, size_t new_position); /// \brief Sets the name of an entity. /// \param entity The entity to set the name of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param new_name The new name of the entity. /// \pre \li Must not be null. /// \pre \li Must not be empty. IKA_API void ikarus_entity_set_name(IkarusEntity * entity, char const * new_name); /// \brief Sets the value of a property of an entity. /// \param entity The entity to set the value of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param property The property to set the value of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param value The new value of the property. /// \pre \li Must not be null. /// \pre \li Must be of the same type as the property. /// \param validate_settings If set, this function fails not only if the type of the value is invalid, but also if it's not /// valid under the properties settings. \see property.h /// \remark If the entity does not have the property, this function fails. IKA_API void ikarus_entity_set_value( IkarusEntity * entity, struct IkarusProperty const * property, struct IkarusValue * value, bool validate_settings ); /// \brief Compares two entities. /// \param left The left entity to compare. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param right The right entity to compare. /// \pre \li Must not be null. /// \pre \li Must exist. /// \return True if the two entities are equal, false otherwise. /// \remark This neither performs a pointer comparison nor a deep comparison. When we say "equal" we mean that the two /// entities reference the same entity in the same project. IKA_API bool ikarus_entity_is_equal(IkarusEntity const * left, IkarusEntity const * right); IKARUS_END_HEADER // @}