diff --git a/.clang-format b/.clang-format index 0372fa7..513423e 100644 --- a/.clang-format +++ b/.clang-format @@ -81,72 +81,31 @@ FixNamespaceComments: false IncludeBlocks: Regroup IncludeCategories: - # Relative Includes - # "blubb.h" / "blubb/blubber.h" - Regex: '^".+\.(h|hpp)"$' Priority: 1 - - # C Includes - # - Regex: '^<[a-z0-9_]+\.h>$' Priority: 2 - - # C++ Includes - # - Regex: '^<[a-z0-9_]+>$' Priority: 3 - - # expected - # - Regex: '^$' Priority: 4 - - # libfmt - # - Regex: '^$' Priority: 5 - - # nlohmann::json - # - Regex: '^$' Priority: 6 - - # ranges - # - Regex: '^$' Priority: 7 - - # ICU - # - - Regex: '^$' + - Regex: '^$' Priority: 8 - - # ranges - # - - Regex: '^$' + - Regex: '^$' Priority: 9 - - # ranges - # - - Regex: '^$' + - Regex: '^$' Priority: 10 - - # ranges - # - - Regex: '^$' + - Regex: '^$' Priority: 11 - - # ranges - # - - Regex: '^$' + - Regex: '^$' Priority: 12 - # ranges - # ranges - # - - Regex: '^$' - Priority: 13 - IndentAccessModifiers: false IndentCaseBlocks: false IndentCaseLabels: false diff --git a/CMakeLists.txt b/CMakeLists.txt index a7faf39..5edd8b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required(VERSION 3.18) project(ikarus) +option(LIBIKARUS_ENABLE_TESTS "Enable tests" OFF) +option(LIBIKARUS_ENABLE_LINTS "Enable linting" OFF) + set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 20) @@ -11,7 +14,7 @@ add_subdirectory(include) add_subdirectory(src) add_library( - libikarus OBJECT + libikarus SHARED ${INCLUDE_FILES} ${SOURCE_FILES} ) @@ -27,7 +30,7 @@ target_include_directories( ) target_link_libraries( - libikarus PUBLIC + libikarus PRIVATE Catch2::Catch2WithMain ) @@ -37,19 +40,40 @@ target_link_libraries( sqlitecpp ) -set_target_properties( - libikarus PROPERTIES - LINKER_LANGUAGE CXX -) +if (LIBIKARUS_ENABLE_LINTS) + find_program(IWYU_PATH NAMES include-what-you-use iwyu REQUIRED) + find_program(CLANG_TIDY_PATH NAMES clang-tidy REQUIRED) -add_executable(ikarus_tests ${SOURCE_FILES}) -target_link_libraries(ikarus_tests PRIVATE Catch2::Catch2WithMain) + set_property(TARGET libikarus PROPERTY CXX_INCLUDE_WHAT_YOU_USE ${IWYU_PATH}) + string( + CONCAT CLANG_TIDY_OPTIONS + "-checks=-*," + "bugprone-*," + "concurrency-*," + "cppcoreguidelines-*,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-union-access," + "misc-*," + "modernize-*,-modernize-use-trailing-return-type," + "performance-*," + "portability-*," + "readability-*,-readability-identifier-length,-readability-magic-numbers,-readability-function-cognitive-complexity" + ) -target_include_directories( - ikarus_tests PUBLIC - ${CMAKE_CURRENT_LIST_DIR}/include -) + set_property( + TARGET libikarus + PROPERTY CXX_CLANG_TIDY ${CLANG_TIDY_PATH};${CLANG_TIDY_OPTIONS} + ) +endif () -include(CTest) -include(vendor/catch2/extras/Catch.cmake) -catch_discover_tests(ikarus_tests) +if (LIBIKARUS_ENABLE_TESTS) + add_executable(libikarus_tests ${SOURCE_FILES}) + target_link_libraries(libikarus_tests PRIVATE Catch2::Catch2WithMain) + + target_include_directories( + libikarus_tests PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/include + ) + + include(CTest) + include(vendor/catch2/extras/Catch.cmake) + catch_discover_tests(libikarus_tests) +endif () \ No newline at end of file diff --git a/include/ikarus/folders/blueprint_folder.h b/include/ikarus/folders/blueprint_folder.h new file mode 100644 index 0000000..8ab973e --- /dev/null +++ b/include/ikarus/folders/blueprint_folder.h @@ -0,0 +1,22 @@ +#pragma once + +/// \file blueprint_folder.h +/// \author Folling + +#include +#include + +/// \addtogroup folder Folders +/// @{ + +IKARUS_BEGIN_HEADER + +/// \brief A blueprint folder, storing blueprints and other blueprint folders. +struct IkarusBlueprintFolder { + /// \private \brief The id of the blueprint folder. + IkarusId id; +}; + +IKARUS_END_HEADER + +// @} diff --git a/include/ikarus/folders/entity_folder.h b/include/ikarus/folders/entity_folder.h new file mode 100644 index 0000000..2bffa3f --- /dev/null +++ b/include/ikarus/folders/entity_folder.h @@ -0,0 +1,22 @@ +#pragma once + +/// \file entity_folder.h +/// \author Folling + +#include +#include + +/// \addtogroup folder Folders +/// @{ + +IKARUS_BEGIN_HEADER + +/// \brief A entity folder, storing entities and other entity folders. +struct IkarusEntityFolder { + /// \private \brief The id of the entity folder. + IkarusId id; +}; + +IKARUS_END_HEADER + +// @} diff --git a/include/ikarus/folders/folder.h b/include/ikarus/folders/folder.h new file mode 100644 index 0000000..0cdf946 --- /dev/null +++ b/include/ikarus/folders/folder.h @@ -0,0 +1,76 @@ +#pragma once + +/// \file folder.h +/// \author Folling + +#include +#include +#include +#include +#include + +IKARUS_BEGIN_HEADER + +/// \defgroup folder Folders +/// \brief Folders are used to group objects together. +/// @{ + +/// \private \brief The data of a folder. +union IkarusFolderData { + /// \private \brief The blueprint folder data of the folder. + IkarusBlueprintFolder blueprint_folder; + /// \private \brief The property folder data of the folder. + IkarusPropertyFolder property_folder; + /// \private \brief The entity folder data of the folder. + IkarusEntityFolder entity_folder; +}; + +/// \brief A generic folder. Similar to how Objects wrap all types of objects, Folders wrap all types of folders. +struct IkarusFolder { + /// \private \brief The data of the folder. + IkarusFolderData data; + + /// \private \brief The type of the folder. + IkarusFolderType type; +}; + +/// \brief Constructs a folder from a blueprint folder. +/// \param blueprint_folder The blueprint folder to construct the folder from. +/// \return The constructed folder. +IKA_API IkarusFolder ikarus_folder_from_blueprint_folder(IkarusBlueprintFolder blueprint_folder); +/// \brief Constructs a folder from a property folder. +/// \param property_folder The property folder to construct the folder from. +/// \return The constructed folder. +IKA_API IkarusFolder ikarus_folder_from_property_folder(IkarusPropertyFolder property_folder); +/// \brief Constructs a folder from an entity folder. +/// \param entity_folder The entity folder to construct the folder from. +/// \return The constructed folder. +IKA_API IkarusFolder ikarus_folder_from_entity_folder(IkarusEntityFolder entity_folder); + +/// \brief Fetches the folder type of a folder. +/// \param folder The folder to fetch the type of. +/// \return The type of the folder. +IKA_API IkarusFolderType ikarus_folder_get_type(IkarusFolder folder); + +/// \brief Checks if two folders are equal. +/// \details Since ids store the type of the object, this boils down to a simple comparison of the ids. +/// \param left The left side of the comparison. +/// \param right The right side of the comparison. +/// \return True if the folders are equal, false otherwise +IKA_API bool ikarus_folder_is_equal(IkarusFolder left, IkarusFolder right); + +/// \brief Visits a folder. Calling the appropriate function for the folder's type. +/// \param folder The folder to visit. +/// \param blueprint The function to call if the folder is a blueprint folder. +/// \param property The function to call if the folder is a property folder. +/// \param entity The function to call if the folder is an entity folder. +/// \param data The data to pass to the functions. +IKA_API void ikarus_folder_visit( + IkarusFolder folder, + void (*blueprint)(IkarusBlueprintFolder, void *), + void (*property)(IkarusPropertyFolder, void *), + void (*entity)(IkarusEntityFolder, void *), + void * data +); + +IKARUS_END_HEADER diff --git a/include/ikarus/folders/folder_type.h b/include/ikarus/folders/folder_type.h new file mode 100644 index 0000000..2a63e46 --- /dev/null +++ b/include/ikarus/folders/folder_type.h @@ -0,0 +1,26 @@ +#pragma once + +// IMPLEMENTATION_DETAIL_FOLDER_TYPES + +/// \file folder_type.h +/// \author Folling + +#include + +/// \addtogroup folder folders +/// @{ + +/// \brief The type of an folder. +/// \remark Folders have the 8th bit set. +enum IkarusFolderType { + /// \brief Not a folder or no folder. + IkarusFolderType_None = 0, + /// \brief An IkarusBlueprintFolder + IkarusFolderType_BlueprintFolder = 0b1000'0001, + /// \brief An IkarusPropertyFolder + IkarusFolderType_PropertyFolder = 0b1000'0010, + /// \brief An IkarusEntityFolder + IkarusFolderType_EntityFolder = 0b1000'0011, +}; + +/// @} diff --git a/include/ikarus/folders/property_folder.h b/include/ikarus/folders/property_folder.h new file mode 100644 index 0000000..8e6709f --- /dev/null +++ b/include/ikarus/folders/property_folder.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +/// \file property_folder.h +/// \author Folling + +/// \addtogroup folder Folders +/// @{ + +IKARUS_BEGIN_HEADER + +/// \brief A property folder, storing properties and other property folders. +/// \remark Property folders are scoped to the blueprint or entity they are associated with. +struct IkarusPropertyFolder { + /// \private \brief The id of the property folder. + IkarusId id; +}; + +IKARUS_END_HEADER + +// @} diff --git a/include/ikarus/types/id.h b/include/ikarus/id.h similarity index 97% rename from include/ikarus/types/id.h rename to include/ikarus/id.h index e2ca0b5..d184e63 100644 --- a/include/ikarus/types/id.h +++ b/include/ikarus/id.h @@ -6,12 +6,11 @@ #pragma once #include +#include #include IKARUS_BEGIN_HEADER -#include - /// \defgroup id Ids /// \brief Ids are used to identify objects in the database. /// \details They are stored as 64 bit integers with the following layout: @@ -64,4 +63,4 @@ IKA_API bool ikarus_id_is_unspecified(IkarusId id); /// @} -IKARUS_END_HEADER \ No newline at end of file +IKARUS_END_HEADER diff --git a/include/ikarus/objects/blueprint.h b/include/ikarus/objects/blueprint.h new file mode 100644 index 0000000..bd0abd3 --- /dev/null +++ b/include/ikarus/objects/blueprint.h @@ -0,0 +1,24 @@ +#pragma once + +/// \file blueprint.h +/// \author Folling + +#include +#include + +/// \defgroup blueprints Blueprints +/// \brief Blueprints are templates for entities. + +IKARUS_BEGIN_HEADER + +/// \brief A blueprint object. +/// \details A blueprint is a collection of properties which can be linked to entities. +/// Each entity the blueprint is linked to will have values for the blueprints properties. +struct IkarusBlueprint { + /// \private \brief The id of the blueprint. + IkarusId id; +}; + +IKARUS_END_HEADER + +// @} diff --git a/include/ikarus/objects/entity.h b/include/ikarus/objects/entity.h new file mode 100644 index 0000000..980c03e --- /dev/null +++ b/include/ikarus/objects/entity.h @@ -0,0 +1,41 @@ +#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 of the entity. +/// +/// For each property an entity is linked to, it has a value. These values depend on the property's type. +/// For more information on the types see the property documentation. +/// +/// Values are the core type of data within Ikarus. +/// Each value is associated with one page and one property. +/// +/// \remark Values are typed, the type of a value is specified by its associated property. +/// For more information on the types see the property documentation. +/// +/// \remark Values are guaranteed to be in valid format for a given type +/// but not guaranteed to be valid under the settings of the property. +/// This is because changing the settings can invalidate existing values without resetting them. +struct IkarusEntity { + /// \private \brief The ID of the entity. + IkarusId id; +}; + +IKARUS_END_HEADER + +// @} diff --git a/include/ikarus/objects/object.h b/include/ikarus/objects/object.h new file mode 100644 index 0000000..ef8c592 --- /dev/null +++ b/include/ikarus/objects/object.h @@ -0,0 +1,123 @@ +#pragma once + +/// \file object.h +/// \author Folling + +#include +#include +#include +#include +#include +#include +#include +#include + +/// \defgroup object Objects +/// \brief Objects are a compound type of all types of objects in the database. +/// \details The following objects currently exist: +/// - blueprints +/// - properties +/// - entities +/// - blueprint folders +/// - property folders +/// - entity folders +/// @{ + +IKARUS_BEGIN_HEADER + +struct IkarusFolder; + +/// \private \brief The data of an object. +union IkarusObjectData { + /// \private \brief The blueprint data of the object. + IkarusBlueprint blueprint; + /// \private \brief The property data of the object. + IkarusProperty property; + /// \private \brief The entity data of the object. + IkarusEntity entity; + /// \private \brief The blueprint folder data of the object. + IkarusBlueprintFolder blueprint_folder; + /// \private \brief The property folder data of the object. + IkarusPropertyFolder property_folder; + /// \private \brief The entity folder data of the object. + IkarusEntityFolder entity_folder; +}; + +/// \brief A generic object. Wraps all types of objects, including folders. +struct IkarusObject { + /// \private \brief The type of the object. + IkarusObjectType type; + /// \private \brief The data of the object. + IkarusObjectData data; +}; + +/// \brief Constructs an object from a blueprint. +/// \param blueprint The blueprint to construct the object from. +/// \return The constructed object, representing the blueprint. +IKA_API IkarusObject ikarus_object_from_blueprint(IkarusBlueprint blueprint); + +/// \brief Constructs an object from a property. +/// \param property The property to construct the object from. +/// \return The constructed object, representing the property. +IKA_API IkarusObject ikarus_object_from_property(IkarusProperty property); + +/// \brief Constructs an object from an entity. +/// \param entity The entity to construct the object from. +/// \return The constructed object, representing the entity. +IKA_API IkarusObject ikarus_object_from_entity(IkarusEntity entity); + +/// \brief Constructs an object from a blueprint folder. +/// \param blueprint The folder to construct the object from. +/// \return The constructed object, representing the folder. +IKA_API IkarusObject ikarus_object_from_blueprint_folder(IkarusBlueprintFolder folder); + +/// \brief Constructs an object from a property folder. +/// \param property The folder to construct the object from. +/// \return The constructed object, representing the folder. +IKA_API IkarusObject ikarus_object_from_property_folder(IkarusPropertyFolder folder); + +/// \brief Constructs an object from a entity folder. +/// \param entity The folder to construct the object from. +/// \return The constructed object, representing the folder. +IKA_API IkarusObject ikarus_object_from_entity_folder(IkarusEntityFolder folder); + +/// \brief Constructs an object from a folder. +/// \param folder The folder to construct the object from. +/// \return The constructed object, representing the folder. +IKA_API IkarusObject ikarus_object_from_folder(IkarusFolder folder); + +/// \brief Compares two objects for equality. +/// \details Since ids store the type of the object, this boils down to a simple comparison of the ids. +/// \param left The left side of the comparison. +/// \param right The right side of the comparison. +/// \return Whether the objects are equal. +IKA_API bool ikarus_object_is_equal(IkarusObject left, IkarusObject right); + +/// \brief Fetches the type of an object. +/// \param object The object to fetch the type of. +/// \return The type of the object. +IKA_API IkarusObjectType ikarus_object_get_type(IkarusObject object); + +/// \brief Visits an object. Calling the appropriate function for the object's type. +/// \param object The object to visit. +/// \param blueprint The function to call if the object is a blueprint. +/// \param property The function to call if the object is a property. +/// \param entity The function to call if the object is an entity. +/// \param blueprint_folder The function to call if the object is a blueprint folder. +/// \param property_folder The function to call if the object is a property folder. +/// \param entity_folder The function to call if the object is an entity folder. +/// \param data The data to pass to the functions. +IKA_API void ikarus_object_visit( + IkarusObject object, + void (*visit_blueprint)(IkarusBlueprint, void *), + void (*visit_property)(IkarusProperty, void *), + void (*visit_entity)(IkarusEntity, void *), + void (*visit_blueprint_folder)(IkarusBlueprintFolder, void *), + void (*visit_property_folder)(IkarusPropertyFolder, void *), + void (*visit_entity_folder)(IkarusEntityFolder, void *), + void * data +); + +IKARUS_END_HEADER + +// @} diff --git a/include/ikarus/objects/object_type.h b/include/ikarus/objects/object_type.h new file mode 100644 index 0000000..0fafc68 --- /dev/null +++ b/include/ikarus/objects/object_type.h @@ -0,0 +1,38 @@ +#pragma once + +// IMPLEMENTATION_DETAIL_OBJECT_TYPES + +/// \file object.h +/// \author Folling + +#include +#include + +/// \addtogroup object Objects +/// @{ + +/// \brief The type of an object. +/// \remark Folders have the 4th bit set. +enum IkarusObjectType { + /// \brief Not an object or no object. + IkarusObjectType_None = 0, + /// \brief An IkarusBlueprint. + IkarusObjectType_Blueprint = 1, + /// \brief An IkarusProperty. + IkarusObjectType_Property = 2, + /// \brief An IkarusEntity. + IkarusObjectType_Entity = 3, + /// \brief An IkarusBlueprintFolder + IkarusObjectType_BlueprintFolder = IkarusFolderType_BlueprintFolder, + /// \brief An IkarusPropertyFolder + IkarusObjectType_PropertyFolder = IkarusFolderType_PropertyFolder, + /// \brief An IkarusEntityFolder + IkarusObjectType_EntityFolder = IkarusFolderType_EntityFolder, +}; + +/// \brief Constructs an IkarusObjectType from an IkarusFolderType. +/// \param type The IkarusFolderType of which to construct the IkarusObjectType from. +/// \return The constructed IkarusObjectType, representing the folder type. +IKA_API IkarusObjectType ikarus_object_type_from_folder_type(IkarusFolderType type); + +/// @} diff --git a/include/ikarus/objects/property.h b/include/ikarus/objects/property.h new file mode 100644 index 0000000..d104ac3 --- /dev/null +++ b/include/ikarus/objects/property.h @@ -0,0 +1,73 @@ +#pragma once + +// IMPLEMENTATION_DETAIL_LAZY_VALUE_CREATION, IMPLEMENTATION_DETAIL_PROPERTY_TYPES + +/// \file property.h +/// \author Folling + +#include +#include +#include +#include + +/// \defgroup properties Properties +/// \brief Properties define the structure and types of data. + +IKARUS_BEGIN_HEADER + +/// \brief Properties are the placeholders of values for entities. +/// \details Each entity can have any number of properties. +/// Every property has a type that identifies the kind of data that can be put in. +/// +/// The following types currently exist: +/// - Toggle: A true/false boolean-like value +/// - Number: An arbitrary numeric value +/// - Text: An arbitrary textual value +/// +/// Property Examples: +/// - Is Dead (Toggle) +/// - Age (Number) +/// - ISBN (Text) +/// +/// Every property has settings which can be used to customise the property further. +/// Two settings that are shared among all properties are the following: +/// - Multiple +/// - Allow undefined +/// +/// The former transforms a property into a list. Instead of one number, you could then specify a series of numbers. +/// The latter allows you to specify an "unknown" value for a property. +/// It might not be known if a character is dead or not for example. +/// +/// Each entity associated with the property has a value for it. +/// +/// Properties can also be added to blueprints in which case they are available for all entities associated with the +/// blueprint. +/// +/// We call properties within entities "Entity Properties" and properties within blueprints "Blueprint Properties". +/// +/// \remark Properties are scoped to the blueprint or entity they are associated with. +/// \remark Values for properties are lazily created as space saving measure. +/// Fetching the value for some property of some entity will return the property's default value if none is specified. +/// This default value is specified when the property is created and can be updated later. +/// \remark Properties' tree structures are scoped to the entity or blueprint they are associated with. +struct IkarusProperty { + /// \private \brief The id of the property. + IkarusId id; +}; + +/// \brief The type of a property. +/// \details Designates the type of data stored by the property as well as which settings are +/// available. +/// \see IkarusPropertySettings +enum IkarusPropertyType { + /// \brief A true/false boolean-like value. + IkarusPropertyType_Toggle, + /// \brief An arbitrary numeric value. + IkarusPropertyType_Number, + /// \brief An arbitrary textual value. + IkarusPropertyType_Text, +}; + +IKARUS_END_HEADER + +// @} diff --git a/include/ikarus/types/property_type.h b/include/ikarus/objects/property_type.h similarity index 96% rename from include/ikarus/types/property_type.h rename to include/ikarus/objects/property_type.h index d22e1a6..3709a37 100644 --- a/include/ikarus/types/property_type.h +++ b/include/ikarus/objects/property_type.h @@ -2,7 +2,7 @@ // IMPLEMENTATION_DETAIL_PROPERTY_TYPES -/// \file id.h +/// \file property_type.h /// \author Folling #include diff --git a/include/ikarus/scopes/blueprint_scope.h b/include/ikarus/scopes/blueprint_scope.h new file mode 100644 index 0000000..eac5eac --- /dev/null +++ b/include/ikarus/scopes/blueprint_scope.h @@ -0,0 +1,26 @@ +#pragma once + +/// \file blueprint_scope.h +/// \author Folling + +#include +#include + +/// \addtogroup object_scopes ObjectScopes +/// @{ + +IKARUS_BEGIN_HEADER + +/// \brief The global scope of all blueprints. +struct IkarusBlueprintScope { + /// \private \brief Empty structs aren't allowed in C, so we need a dummy field. + short _dummy; +}; + +/// \brief Creates a blueprint scope. +/// \return The created blueprint scope. +IKA_API IkarusBlueprintScope ikarus_blueprint_scope_create(); + +IKARUS_END_HEADER + +// @} diff --git a/include/ikarus/scopes/entity_scope.h b/include/ikarus/scopes/entity_scope.h new file mode 100644 index 0000000..e29d725 --- /dev/null +++ b/include/ikarus/scopes/entity_scope.h @@ -0,0 +1,26 @@ +#pragma once + +/// \file entity_scope.h +/// \author Folling + +#include +#include + +/// \addtogroup object_scopes ObjectScopes +/// @{ + +IKARUS_BEGIN_HEADER + +/// \brief The global scope of all entities. +struct IkarusEntityScope { + /// \private \brief Empty structs aren't allowed in C, so we need a dummy field. + short _dummy; +}; + +/// \brief Creates a entity scope. +/// \return The created entity scope. +IKA_API IkarusEntityScope ikarus_entity_scope_create(); + +IKARUS_END_HEADER + +// @} diff --git a/include/ikarus/scopes/object_scope.h b/include/ikarus/scopes/object_scope.h new file mode 100644 index 0000000..1c16d9f --- /dev/null +++ b/include/ikarus/scopes/object_scope.h @@ -0,0 +1,84 @@ +#pragma once + +// IMPLEMENTATION_DETAIL_OBJECT_SCOPES + +/// \file object_scope.h +/// \author Folling + +#include +#include +#include +#include + +/// \defgroup object_scopes Object Scopes +/// \brief Scopes define where objects belong to. +/// \details They are required to differentiate between different types of objects with NULL as their parent. +/// @{ + +IKARUS_BEGIN_HEADER + +/// \private \brief The data for an object scope. +union IkarusObjectScopeData { + /// \private \brief The blueprint data of the scope. + IkarusBlueprintScope _blueprint; + /// \private \brief The property data of the scope. + IkarusPropertyScope _property; + /// \private \brief The entity data of the scope. + IkarusEntityScope _entity; +}; + +/// The type of an object scope. +enum IkarusObjectScopeType { + /// \brief The scope is a blueprint scope. + IkarusObjectScopeType_Blueprint, + /// \brief The scope is a property scope. + IkarusObjectScopeType_Property, + /// \brief The scope is an entity scope. + IkarusObjectScopeType_Entity +}; + +/// \brief The scope of an object. +struct IkarusObjectScope { + /// \private \brief Represents the type of the scope. + IkarusObjectScopeType _type; + /// \private \brief Represents the data of the scope. + IkarusObjectScopeData _data; +}; + +/// \brief Converts a blueprint scope to an object scope. +/// \param scope The scope to convert. +/// \return The converted scope. +IKA_API IkarusObjectScope ikarus_blueprint_scope_to_object_scope(IkarusBlueprintScope scope); + +/// \brief Converts a property scope to an object scope. +/// \param scope The scope to convert. +/// \return The converted scope. +IKA_API IkarusObjectScope ikarus_property_scope_to_object_scope(IkarusPropertyScope scope); + +/// Converts an entity scope to an object scope. +/// \param scope The scope to convert. +/// \return The converted scope. +IKA_API IkarusObjectScope ikarus_entity_scope_to_object_scope(IkarusEntityScope scope); + +/// \brief Fetches the type of an object scope. +/// \param scope The scope to fetch the type of. +/// \return The type of the scope. +IKA_API IkarusObjectScopeType ikarus_object_scope_get_type(IkarusObjectScope scope); + +/// \brief Visits an object scope, calling the appropriate function. +/// \param scope The scope to visit. +/// \param blueprint The function to call if the scope is an #IkarusBlueprintScope. +/// \param property The function to call if the scope is an #IkarusPropertyScope. +/// \param entity The function to call if the scope is an #IkarusEntityScope. +/// \remark function pointers may be null in which case they are not called. +IKA_API void ikarus_object_scope_visit( + IkarusObjectScope scope, + void (*blueprint)(IkarusBlueprintScope, void *), + void (*property)(IkarusPropertyScope, void *), + void (*entity)(IkarusEntityScope, void *), + void * data +); + +/// @} + +IKARUS_END_HEADER diff --git a/include/ikarus/scopes/property_scope.h b/include/ikarus/scopes/property_scope.h new file mode 100644 index 0000000..6de365c --- /dev/null +++ b/include/ikarus/scopes/property_scope.h @@ -0,0 +1,65 @@ +#pragma once + +/// \file property_scope.h +/// \author Folling + +#include +#include +#include +#include + +/// \addtogroup object_scopes ObjectScopes +/// @{ + +IKARUS_BEGIN_HEADER + +/// \brief Data for a property scope. This can either be a blueprint or an entity. +union IkarusPropertyScopeData { + /// \private \brief The blueprint the property is scoped to. + IkarusBlueprint _blueprint; + /// \private \brief The entity the property is scoped to. + IkarusEntity _entity; +}; + +/// \brief The type of a property scope. This can either be a blueprint or an entity. +enum IkarusPropertyScopeType { + /// \brief The property is scoped to a blueprint. + IkarusPropertyScopeType_Blueprint, + /// \brief The property is scoped to an entity. + IkarusPropertyScopeType_Entity +}; + +/// \brief The scope of a property +struct IkarusPropertyScope { + /// \private \brief Represents the type of the scope. + IkarusPropertyScopeType _type; + /// \private \brief Represents the data of the scope. + IkarusPropertyScopeData _data; +}; + +/// \brief Creates a property scope from a blueprint. +/// \param blueprint The blueprint the property is scoped to. +/// \return The created property scope. +IKA_API IkarusPropertyScope ikarus_property_scope_create_blueprint(IkarusBlueprint blueprint); +/// \brief Creates a property scope from a entity. +/// \param entity The entity the property is scoped to. +/// \return The created property scope. +IKA_API IkarusPropertyScope ikarus_property_scope_create_entity(IkarusEntity entity); + +/// \brief Fetches the type of an property scope. +/// \param scope The scope to fetch the type of. +/// \return The type of the scope. +IKA_API IkarusPropertyScopeType ikarus_property_scope_get_type(IkarusPropertyScope scope); + +/// \brief Visits a property scope, calling the appropriate function. +/// \param scope The scope to to visit +/// \param blueprint The function to call if the property is scoped to a blueprint. +/// \param entity The function to call if the property is scoped to an entity. +/// \param data Optional data to pass to the functions. +void ikarus_property_scope_visit( + IkarusPropertyScope scope, void (*blueprint)(IkarusBlueprint, void *), void (*entity)(IkarusEntity, void *), void * data +); + +IKARUS_END_HEADER + +// @} diff --git a/include/ikarus/types/object.h b/include/ikarus/types/object.h deleted file mode 100644 index 9d8b9bd..0000000 --- a/include/ikarus/types/object.h +++ /dev/null @@ -1,164 +0,0 @@ -#pragma once - -// IMPLEMENTATION_DETAIL_OBJECT_TYPES -// IMPLEMENTATION_DETAIL_LAZY_VALUE_CREATION -// IMPLEMENTATION_DETAIL_PROPERTY_TYPES - -/// \file id.h -/// \author Folling - -/// \defgroup object Objects -/// \brief Objects are a compound type of all types of objects in the database. -/// \details The following objects currently exist: -/// - blueprints -/// - properties -/// - entities -/// - blueprint folders -/// - property folders -/// - entity folders -/// @{ - -#include - -IKARUS_BEGIN_HEADER - -/// \brief A blueprint object. -/// \details A blueprint is a collection of properties which can be linked to entities. -/// Each entity the blueprint is linked to will have values for the blueprints properties. -struct IkarusBlueprint { - IkarusId id; -}; - -/// \brief Properties are the placeholders of values for entities. -/// \details Each entity can have any number of properties. -/// Every property has a type that identifies the kind of data that can be put in. -/// -/// The following types currently exist: -/// - Toggle: A true/false boolean-like value -/// - Number: An arbitrary numeric value -/// - Text: An arbitrary textual value -/// -/// Property Examples: -/// - Is Dead (Toggle) -/// - Age (Number) -/// - ISBN (Text) -/// -/// Every property has settings which can be used to customise the property further. -/// Two settings that are shared among all properties are the following: -/// - Multiple -/// - Allow undefined -/// -/// The former transforms a property into a list. Instead of one number, you could then specify a series of numbers. -/// The latter allows you to specify an "unknown" value for a property. -/// It might not be known if a character is dead or not for example. -/// -/// Each entity associated with the property has a value for it. -/// -/// Properties can also be added to blueprints in which case they are available for all entities associated with the -/// blueprint. -/// -/// We call properties within entities "Entity Properties" and properties within blueprints "Blueprint Properties". -/// -/// \remark Values for properties are lazily created as space saving measure. -/// Fetching the value for some property of some entity will return the property's default value if none is specified. -/// This default value is specified when the property is created and can be updated later. -/// -/// \remark Properties' tree structures are scoped to the entity or blueprint they are associated with. -struct IkarusProperty { - /// \private \brief The ID of the property. - IkarusId id; -}; - -/// \brief Entities are the core building blocks of Ikarus. -/// \detials Blueprints and Properties define the structure of the data. -/// Entities define the data itself. -/// -/// Properties can be associated with Entities in two ways: -/// - Directly: The property is linked to the entity. -/// - Indirectly: The property is linked to a blueprint of the entity. -/// -/// For each property an entity is linked to, it has a value. These values depend on the property's type. -/// For more information on the types see the property documentation. -/// -/// Values are the core type of data within Ikarus. -/// Each value is associated with one page and one property. -/// -/// \remark Values are typed, the type of a value is specified by its associated property. -/// For more information on the types see the property documentation. -/// -/// \remark Values are guaranteed to be in valid format for a given type -/// but not guaranteed to be valid under the settings of the property. -/// This is because changing the settings can invalidate existing values without resetting them. -struct IkarusEntity { - /// \private \brief The ID of the entity. - IkarusId id; -}; - -/// \brief A blueprint folder. -/// \see Folder -struct IkarusBlueprintFolder { - /// \private \brief The ID of the folder. - IkarusId id; -}; - -/// \brief A property folder. -/// \remark Property folders are scoped to the blueprint or entity they are associated with. -/// \see Folder -struct IkarusPropertyFolder { - /// \private \brief The ID of the folder. - IkarusId id; -}; - -/// \brief An entity folder. -/// \see Folder -struct IkarusEntityFolder { - /// \private \brief The ID of the folder. - IkarusId id; -}; - -/// \private \brief The data of a folder. -union IkarusFolderData { - /// \private \brief The blueprint folder data of the folder. - IkarusBlueprintFolder blueprint_folder; - /// \private \brief The property folder data of the folder. - IkarusPropertyFolder property_folder; - /// \private \brief The entity folder data of the folder. - IkarusEntityFolder entity_folder; -}; - -/// \brief A generic folder. Similar to how Objects wrap all types of objects, Folders wrap all types of folders. -struct IkarusFolder { - /// \private \brief The data of the folder. - IkarusFolderData data; - - /// \private \brief The type of the folder. - IkarusFolderType type; -}; - -/// \private \brief The data of an object. -union IkarusObjectData { - /// \private \brief The blueprint data of the object. - IkarusBlueprint blueprint; - /// \private \brief The property data of the object. - IkarusProperty property; - /// \private \brief The entity data of the object. - IkarusEntity entity; - /// \private \brief The blueprint folder data of the object. - IkarusBlueprintFolder blueprint_folder; - /// \private \brief The property folder data of the object. - IkarusPropertyFolder property_folder; - /// \private \brief The entity folder data of the object. - IkarusEntityFolder entity_folder; -}; - -/// \brief A generic object. Wraps all types of objects, including folders. -struct IkarusObject { - /// \private \brief The data of the object. - IkarusObjectData data; - /// \private \brief The type of the object. - IkarusObjectType type; -}; - -// @} - -IKARUS_END_HEADER diff --git a/include/ikarus/types/object_scope.h b/include/ikarus/types/object_scope.h deleted file mode 100644 index 1fe51e1..0000000 --- a/include/ikarus/types/object_scope.h +++ /dev/null @@ -1,149 +0,0 @@ -// IMPLEMENTATION_DETAIL_OBJECT_SCOPES, IMPLEMENTATION_DETAIL_TREE_LAYOUT - -/// \file object_scope.h -/// \author Folling - -/// \defgroup object_scopes Object Scopes -/// \brief Scopes define where objects belong to. -/// \details They are required to differentiate between different types of objects with NULL as their parent. -/// @{ - -#pragma once - -#include -#include - -IKARUS_BEGIN_HEADER - -/// \brief The global scope of all blueprints. -struct IkarusBlueprintScope { - /// \private \brief Empty structs aren't allowed in C, so we need a dummy field. - short _dummy; -}; - -/// \brief Data for a property scope. This can either be a blueprint or an entity. -union IkarusPropertyScopeData { - /// \private \brief The blueprint the property is scoped to. - IkarusBlueprint _blueprint; - /// \private \brief The entity the property is scoped to. - IkarusEntity _entity; -}; - -/// \brief The type of a property scope. This can either be a blueprint or an entity. -enum IkarusPropertyScopeType { - /// \brief The property is scoped to a blueprint. - IkarusPropertyScopeType_Blueprint, - /// \brief The property is scoped to an entity. - IkarusPropertyScopeType_Entity -}; - -/// \brief The scope of a property -struct IkarusPropertyScope { - /// \private \brief Represents the type of the scope. - IkarusPropertyScopeType _type; - /// \private \brief Represents the data of the scope. - IkarusPropertyScopeData _data; -}; - -/// The global scope of all entities. -struct IkarusEntityScope { - /// \private \brief Empty structs aren't allowed in C, so we need a dummy field. - short _dummy; -}; - -/// \private \brief The data for an object scope. -union IkarusObjectScopeData { - /// \private \brief The blueprint data of the scope. - IkarusBlueprintScope _blueprint; - /// \private \brief The property data of the scope. - IkarusPropertyScope _property; - /// \private \brief The entity data of the scope. - IkarusEntityScope _entity; -}; - -/// The type of an object scope. -enum IkarusObjectScopeType { - /// \brief The scope is a blueprint scope. - IkarusObjectScopeType_Blueprint, - /// \brief The scope is a property scope. - IkarusObjectScopeType_Property, - /// \brief The scope is an entity scope. - IkarusObjectScopeType_Entity -}; - -/// \brief The scope of an object. -struct IkarusObjectScope { - /// \private \brief Represents the type of the scope. - IkarusObjectScopeType _type; - /// \private \brief Represents the data of the scope. - IkarusObjectScopeData _data; -}; - -/// \brief Creates a blueprint scope. -/// \return The created blueprint scope. -IKA_API IkarusBlueprintScope ikarus_blueprint_scope_create(); -/// \brief Converts a blueprint scope to an object scope. -/// \param scope The scope to convert. -/// \return The converted scope. -IKA_API IkarusObjectScope ikarus_blueprint_scope_to_object_scope(IkarusBlueprintScope const * scope); - -/// \brief Creates a property scope from a blueprint. -/// \param blueprint The blueprint the property is scoped to. -/// \return The created property scope. -IKA_API IkarusPropertyScope ikarus_property_scope_create_blueprint(IkarusBlueprint const * blueprint); -/// \brief Creates a property scope from a entity. -/// \param entity The entity the property is scoped to. -/// \return The created property scope. -IKA_API IkarusPropertyScope ikarus_property_scope_create_entity(IkarusEntity const * entity); -/// \brief Converts a property scope to an object scope. -/// \param scope The scope to convert. -/// \return The converted scope. -IKA_API IkarusObjectScope ikarus_property_scope_to_object_scope(IkarusPropertyScope const * scope); - -/// \brief Fetches the type of an property scope. -/// \param scope The scope to fetch the type of. -/// \return The type of the scope. -IKA_API IkarusPropertyScopeType ikarus_property_scope_get_type(IkarusPropertyScope const * scope); - -/// \brief Visits a property scope, calling the appropriate function. -/// \param scope The scope to to visit -/// \param blueprint The function to call if the property is scoped to a blueprint. -/// \param entity The function to call if the property is scoped to an entity. -/// \param data Optional data to pass to the functions. -void ikarus_property_scope_visit( - IkarusPropertyScope const * scope, - void (*blueprint)(IkarusBlueprint const *, void *), - void (*entity)(IkarusEntity const *, void *), - void * data -); - -/// \brief Creates an entity scope. -/// \return The created entity scope. -IKA_API IkarusEntityScope ikarus_entity_scope_create(); -/// Converts an entity scope to an object scope. -/// \param scope The scope to convert. -/// \return The converted scope. -IKA_API IkarusObjectScope ikarus_entity_scope_to_object_scope(IkarusEntityScope const * scope); - -/// \brief Fetches the type of an object scope. -/// \param scope The scope to fetch the type of. -/// \return The type of the scope. -IKA_API IkarusObjectScopeType ikarus_object_scope_get_type(IkarusObjectScope const * scope); - -/// \brief Visits an object scope, calling the appropriate function. -/// \param scope The scope to visit. -/// \param blueprint The function to call if the scope is an #IkarusBlueprintScope. -/// \param property The function to call if the scope is an #IkarusPropertyScope. -/// \param entity The function to call if the scope is an #IkarusEntityScope. -/// \remark function pointers may be null in which case they are not called. -IKA_API void ikarus_object_scope_visit( - IkarusObjectScope const * scope, - void (*blueprint)(IkarusBlueprintScope const *, void *), - void (*property)(IkarusPropertyScope const *, void *), - void (*entity)(IkarusEntityScope const *, void *), - void * data -); - -/// @} - -IKARUS_END_HEADER diff --git a/include/ikarus/types/object_type.h b/include/ikarus/types/object_type.h deleted file mode 100644 index fd8685a..0000000 --- a/include/ikarus/types/object_type.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include - -IKARUS_BEGIN_HEADER - -/// \defgroup object_types ObjectTypes -/// \brief ObjectTypes are used to identify the type of objects. -/// @{ - -/// \brief The type of a folder. -/// \remark These values are identical to the associated values of IkarusObjectType. -enum IkarusFolderType { - /// \brief Not a folder or no folder. - IkarusFolderType_None = 0, - /// \brief An IkarusBlueprintFolder - IkarusFolderType_BlueprintFolder = 17, - /// \brief An IkarusPropertyFolder - IkarusFolderType_PropertyFolder = 18, - /// \brief An IkarusEntityFolder - IkarusFolderType_EntityFolder = 19, -}; - -/// \brief The type of an object. -/// \remark Folders have the 4th bit set. -enum IkarusObjectType { - /// \brief Not an object or no object. - IkarusObjectType_None = 0, - /// \brief An IkarusBlueprint. - IkarusObjectType_Blueprint = 1, - /// \brief An IkarusProperty. - IkarusObjectType_Property = 2, - /// \brief An IkarusEntity. - IkarusObjectType_Entity = 3, - /// \brief An IkarusBlueprintFolder - IkarusObjectType_BlueprintFolder = IkarusFolderType_BlueprintFolder, - /// \brief An IkarusPropertyFolder - IkarusObjectType_PropertyFolder = IkarusFolderType_PropertyFolder, - /// \brief An IkarusEntityFolder - IkarusObjectType_EntityFolder = IkarusFolderType_EntityFolder, -}; - -// because of the nature of bitsets, the largest possible object-type is 31 -/// \brief A bitset of IkarusObjectType%s. -enum IkarusObjectTypes { - /// \brief No object type. - IkarusObjectTypes_None = 0, - /// \brief An IkarusBlueprint. - IkarusObjectTypes_Blueprint = 1 << IkarusObjectType_Blueprint, - /// \brief An IkarusProperty. - IkarusObjectTypes_Property = 1 << IkarusObjectType_Property, - /// \brief An IkarusEntity. - IkarusObjectTypes_Entity = 1 << IkarusObjectType_Entity, - /// \brief An IkarusBlueprintFolder - IkarusObjectTypes_BlueprintFolder = 1 << IkarusObjectType_BlueprintFolder, - /// \brief An IkarusPropertyFolder - IkarusObjectTypes_PropertyFolder = 1 << IkarusObjectType_PropertyFolder, - /// \brief An IkarusEntityFolder - IkarusObjectTypes_EntityFolder = 1 << IkarusObjectType_EntityFolder, -}; - -/// \brief Converts an IkarusFolderType to an IkarusObjectType. -/// \param type The IkarusFolderType to convert. -/// \return The converted IkarusObjectType, representing the folder type. -IKA_API IkarusObjectType ikarus_folder_type_to_object_type(IkarusFolderType type); -/// \brief Converts an IkarusObjectType to a bitset of IkarusObjectTypes. -/// \param type The IkarusObjectType to convert. -/// \return The converted IkarusObjectTypes, representing the object type. -IKA_API IkarusObjectTypes ikarus_object_type_to_bitset(IkarusObjectType type); - -// @} - -IKARUS_END_HEADER diff --git a/include/ikarus/types/value.h b/include/ikarus/values/value.h similarity index 98% rename from include/ikarus/types/value.h rename to include/ikarus/values/value.h index d636d27..e1457af 100644 --- a/include/ikarus/types/value.h +++ b/include/ikarus/values/value.h @@ -2,9 +2,12 @@ // IMPLEMENTATION_DETAIL_PROPERTY_TYPES +/// \file value.h +/// \author Folling + #include +#include #include -#include IKARUS_BEGIN_HEADER diff --git a/src/types/id.cpp b/src/id.cpp similarity index 93% rename from src/types/id.cpp rename to src/id.cpp index 53f2689..caa08be 100644 --- a/src/types/id.cpp +++ b/src/id.cpp @@ -1,11 +1,11 @@ -#include "ikarus/types/id.h" +#include "ikarus/id.h" #include +#include + IkarusId ikarus_id_from_data(int64_t data) { - return IkarusId { - .data = data - }; + return IkarusId{.data = data}; } IkarusObjectType ikarus_id_get_object_type(IkarusId id) { diff --git a/src/objects/object.cpp b/src/objects/object.cpp new file mode 100644 index 0000000..7378c39 --- /dev/null +++ b/src/objects/object.cpp @@ -0,0 +1,27 @@ +#include "ikarus/objects/object.h" + +#include + +#include + +#include + +IkarusObjectType ikarus_object_get_type(IkarusObject object) { + return object.type; +} + +TEST_CASE("object_type", "[object]") { + auto types = { + IkarusObjectType_Blueprint, + IkarusObjectType_Property, + IkarusObjectType_Entity, + IkarusObjectType_BlueprintFolder, + IkarusObjectType_PropertyFolder, + IkarusObjectType_EntityFolder, + }; + + for (auto type : types) { + auto object = IkarusObject{.type = type}; + REQUIRE(ikarus_object_get_type(object) == type); + } +} diff --git a/src/objects/object_type.cpp b/src/objects/object_type.cpp new file mode 100644 index 0000000..a9a3e32 --- /dev/null +++ b/src/objects/object_type.cpp @@ -0,0 +1,16 @@ +#include "ikarus/objects/object_type.h" + +#include + +#include + +IkarusObjectType ikarus_folder_type_to_object_type(IkarusFolderType type) { + return static_cast(type); +} + +TEST_CASE("folder_to_object_type_conversion", "[object_type]") { + REQUIRE(ikarus_folder_type_to_object_type(IkarusFolderType_None) == IkarusObjectType_None); + REQUIRE(ikarus_folder_type_to_object_type(IkarusFolderType_BlueprintFolder) == IkarusObjectType_BlueprintFolder); + REQUIRE(ikarus_folder_type_to_object_type(IkarusFolderType_PropertyFolder) == IkarusObjectType_PropertyFolder); + REQUIRE(ikarus_folder_type_to_object_type(IkarusFolderType_EntityFolder) == IkarusObjectType_EntityFolder); +} diff --git a/src/types/object_scope.cpp b/src/scopes/object_scope.cpp similarity index 62% rename from src/types/object_scope.cpp rename to src/scopes/object_scope.cpp index a4f2b49..348b007 100644 --- a/src/types/object_scope.cpp +++ b/src/scopes/object_scope.cpp @@ -1,52 +1,56 @@ -#include "ikarus/types/object_scope.h" +#include "ikarus/scopes/object_scope.h" +#include #include #include +#include +#include +#include +#include +#include + IkarusBlueprintScope ikarus_blueprint_scope_create() { return IkarusBlueprintScope{._dummy = 0}; } -IkarusObjectScope ikarus_blueprint_scope_to_object_scope(IkarusBlueprintScope const * scope) { +IkarusObjectScope ikarus_blueprint_scope_to_object_scope(IkarusBlueprintScope scope) { IkarusObjectScopeData data{}; - data._blueprint = *scope; + data._blueprint = scope; return IkarusObjectScope{._type = IkarusObjectScopeType_Blueprint, ._data = data}; } -IkarusPropertyScope ikarus_property_scope_create_blueprint(IkarusBlueprint const * blueprint) { +IkarusPropertyScope ikarus_property_scope_create_blueprint(IkarusBlueprint blueprint) { IkarusPropertyScopeData data{}; - data._blueprint = *blueprint; + data._blueprint = blueprint; return IkarusPropertyScope{._type = IkarusPropertyScopeType_Blueprint, ._data = data}; } -IkarusPropertyScope ikarus_property_scope_create_entity(IkarusEntity const * entity) { +IkarusPropertyScope ikarus_property_scope_create_entity(IkarusEntity entity) { IkarusPropertyScopeData data{}; - data._entity = *entity; + data._entity = entity; return IkarusPropertyScope{._type = IkarusPropertyScopeType_Entity, ._data = data}; } -IkarusObjectScope ikarus_property_scope_to_object_scope(IkarusPropertyScope const * scope) { +IkarusObjectScope ikarus_property_scope_to_object_scope(IkarusPropertyScope scope) { IkarusObjectScopeData data{}; - data._property = *scope; + data._property = scope; return IkarusObjectScope{._type = IkarusObjectScopeType_Property, ._data = data}; } -IkarusPropertyScopeType ikarus_property_scope_get_type(IkarusPropertyScope const * scope) { - return scope->_type; +IkarusPropertyScopeType ikarus_property_scope_get_type(IkarusPropertyScope scope) { + return scope._type; } void ikarus_property_scope_visit( - IkarusPropertyScope const * scope, - void (*blueprint)(IkarusBlueprint const *, void *), - void (*entity)(IkarusEntity const *, void *), - void * data + IkarusPropertyScope scope, void(blueprint)(IkarusBlueprint, void *), void(entity)(IkarusEntity, void *), void * data ) { - switch (scope->_type) { - case IkarusPropertyScopeType_Blueprint: blueprint(&scope->_data._blueprint, data); break; - case IkarusPropertyScopeType_Entity: entity(&scope->_data._entity, data); break; + switch (scope._type) { + case IkarusPropertyScopeType_Blueprint: blueprint(scope._data._blueprint, data); break; + case IkarusPropertyScopeType_Entity: entity(scope._data._entity, data); break; } } @@ -54,40 +58,40 @@ IkarusEntityScope ikarus_entity_scope_create() { return IkarusEntityScope{._dummy = 0}; } -IkarusObjectScope ikarus_entity_scope_to_object_scope(IkarusEntityScope const * scope) { +IkarusObjectScope ikarus_entity_scope_to_object_scope(IkarusEntityScope scope) { IkarusObjectScopeData data{}; - data._entity = *scope; + data._entity = scope; return IkarusObjectScope{._type = IkarusObjectScopeType_Entity, ._data = data}; } -IkarusObjectScopeType ikarus_object_scope_get_type(IkarusObjectScope const * scope) { - return scope->_type; +IkarusObjectScopeType ikarus_object_scope_get_type(IkarusObjectScope scope) { + return scope._type; } void ikarus_object_scope_visit( - IkarusObjectScope const * scope, - void (*blueprint)(IkarusBlueprintScope const *, void *), - void (*property)(IkarusPropertyScope const *, void *), - void (*entity)(IkarusEntityScope const *, void *), + IkarusObjectScope scope, + void(blueprint)(IkarusBlueprintScope, void *), + void(property)(IkarusPropertyScope, void *), + void(entity)(IkarusEntityScope, void *), void * data ) { - switch (scope->_type) { + switch (scope._type) { case IkarusObjectScopeType_Blueprint: { if (blueprint != nullptr) { - blueprint(&scope->_data._blueprint, data); + blueprint(scope._data._blueprint, data); } break; } case IkarusObjectScopeType_Property: { if (property != nullptr) { - property(&scope->_data._property, data); + property(scope._data._property, data); } break; } case IkarusObjectScopeType_Entity: { if (entity != nullptr) { - entity(&scope->_data._entity, data); + entity(scope._data._entity, data); } break; } @@ -96,7 +100,7 @@ void ikarus_object_scope_visit( TEST_CASE("blueprint_object_scope_conversion", "[object_scope]") { auto blueprint_scope = ikarus_blueprint_scope_create(); - auto blueprint_object_scope = ikarus_blueprint_scope_to_object_scope(&blueprint_scope); + auto blueprint_object_scope = ikarus_blueprint_scope_to_object_scope(blueprint_scope); REQUIRE(blueprint_object_scope._type == IkarusObjectScopeType_Blueprint); } @@ -104,24 +108,24 @@ TEST_CASE("property_scope_type", "[object_scope]") { auto blueprint = IkarusBlueprint{}; auto entity = IkarusEntity{}; - auto property_blueprint_scope = ikarus_property_scope_create_blueprint(&blueprint); - auto property_entity_scope = ikarus_property_scope_create_entity(&entity); + auto property_blueprint_scope = ikarus_property_scope_create_blueprint(blueprint); + auto property_entity_scope = ikarus_property_scope_create_entity(entity); - REQUIRE(ikarus_property_scope_get_type(&property_blueprint_scope) == IkarusPropertyScopeType_Blueprint); - REQUIRE(ikarus_property_scope_get_type(&property_entity_scope) == IkarusPropertyScopeType_Entity); + REQUIRE(ikarus_property_scope_get_type(property_blueprint_scope) == IkarusPropertyScopeType_Blueprint); + REQUIRE(ikarus_property_scope_get_type(property_entity_scope) == IkarusPropertyScopeType_Entity); } TEST_CASE("property_object_scope_conversion", "[object_scope]") { auto blueprint = IkarusBlueprint{}; auto entity = IkarusEntity{}; - auto property_blueprint_scope = ikarus_property_scope_create_blueprint(&blueprint); - auto property_blueprint_object_scope = ikarus_property_scope_to_object_scope(&property_blueprint_scope); + auto property_blueprint_scope = ikarus_property_scope_create_blueprint(blueprint); + auto property_blueprint_object_scope = ikarus_property_scope_to_object_scope(property_blueprint_scope); REQUIRE(property_blueprint_object_scope._type == IkarusObjectScopeType_Property); - auto property_entity_scope = ikarus_property_scope_create_entity(&entity); - auto property_entity_object_scope = ikarus_property_scope_to_object_scope(&property_entity_scope); + auto property_entity_scope = ikarus_property_scope_create_entity(entity); + auto property_entity_object_scope = ikarus_property_scope_to_object_scope(property_entity_scope); REQUIRE(property_entity_object_scope._type == IkarusObjectScopeType_Property); } @@ -130,24 +134,24 @@ TEST_CASE("property_scope_visiting", "[object_scope]") { auto blueprint = IkarusBlueprint{}; auto entity = IkarusEntity{}; - auto property_blueprint_scope = ikarus_property_scope_create_blueprint(&blueprint); - auto property_entity_scope = ikarus_property_scope_create_entity(&entity); + auto property_blueprint_scope = ikarus_property_scope_create_blueprint(blueprint); + auto property_entity_scope = ikarus_property_scope_create_entity(entity); int test = 0; ikarus_property_scope_visit( - &property_blueprint_scope, - [](IkarusBlueprint const * _, void * data) { *reinterpret_cast(data) = 1; }, - [](IkarusEntity const * _, void * data) { *reinterpret_cast(data) = 2; }, + property_blueprint_scope, + [](IkarusBlueprint, void * data) { *reinterpret_cast(data) = 1; }, + [](IkarusEntity, void * data) { *reinterpret_cast(data) = 2; }, &test ); REQUIRE(test == 1); ikarus_property_scope_visit( - &property_entity_scope, - [](IkarusBlueprint const * _, void * data) { *reinterpret_cast(data) = 1; }, - [](IkarusEntity const * _, void * data) { *reinterpret_cast(data) = 2; }, + property_entity_scope, + [](IkarusBlueprint, void * data) { *reinterpret_cast(data) = 1; }, + [](IkarusEntity, void * data) { *reinterpret_cast(data) = 2; }, &test ); @@ -156,7 +160,7 @@ TEST_CASE("property_scope_visiting", "[object_scope]") { TEST_CASE("entity_object_scope_conversion", "[object_scope]") { auto entity_scope = ikarus_entity_scope_create(); - auto entity_object_scope = ikarus_entity_scope_to_object_scope(&entity_scope); + auto entity_object_scope = ikarus_entity_scope_to_object_scope(entity_scope); REQUIRE(entity_object_scope._type == IkarusObjectScopeType_Entity); } @@ -164,28 +168,28 @@ TEST_CASE("object_scope_type_fetching", "[object_scope]") { auto blueprint = IkarusBlueprint{}; auto blueprint_scope = ikarus_blueprint_scope_create(); - auto property_scope = ikarus_property_scope_create_blueprint(&blueprint); + auto property_scope = ikarus_property_scope_create_blueprint(blueprint); auto entity_scope = ikarus_entity_scope_create(); - auto blueprint_object_scope = ikarus_blueprint_scope_to_object_scope(&blueprint_scope); - auto property_object_scope = ikarus_property_scope_to_object_scope(&property_scope); - auto entity_object_scope = ikarus_entity_scope_to_object_scope(&entity_scope); + auto blueprint_object_scope = ikarus_blueprint_scope_to_object_scope(blueprint_scope); + auto property_object_scope = ikarus_property_scope_to_object_scope(property_scope); + auto entity_object_scope = ikarus_entity_scope_to_object_scope(entity_scope); - REQUIRE(ikarus_object_scope_get_type(&blueprint_object_scope) == IkarusObjectScopeType_Blueprint); - REQUIRE(ikarus_object_scope_get_type(&property_object_scope) == IkarusObjectScopeType_Property); - REQUIRE(ikarus_object_scope_get_type(&entity_object_scope) == IkarusObjectScopeType_Entity); + REQUIRE(ikarus_object_scope_get_type(blueprint_object_scope) == IkarusObjectScopeType_Blueprint); + REQUIRE(ikarus_object_scope_get_type(property_object_scope) == IkarusObjectScopeType_Property); + REQUIRE(ikarus_object_scope_get_type(entity_object_scope) == IkarusObjectScopeType_Entity); } TEST_CASE("object_scope_visiting", "[object_scope]") { auto blueprint = IkarusBlueprint{}; auto blueprint_scope = ikarus_blueprint_scope_create(); - auto property_scope = ikarus_property_scope_create_blueprint(&blueprint); + auto property_scope = ikarus_property_scope_create_blueprint(blueprint); auto entity_scope = ikarus_entity_scope_create(); - auto blueprint_object_scope = ikarus_blueprint_scope_to_object_scope(&blueprint_scope); - auto property_object_scope = ikarus_property_scope_to_object_scope(&property_scope); - auto entity_object_scope = ikarus_entity_scope_to_object_scope(&entity_scope); + auto blueprint_object_scope = ikarus_blueprint_scope_to_object_scope(blueprint_scope); + auto property_object_scope = ikarus_property_scope_to_object_scope(property_scope); + auto entity_object_scope = ikarus_entity_scope_to_object_scope(entity_scope); auto scopes = { std::make_pair(blueprint_object_scope, 1), @@ -197,10 +201,10 @@ TEST_CASE("object_scope_visiting", "[object_scope]") { int test = 0; ikarus_object_scope_visit( - &scope, - [](IkarusBlueprintScope const * _, void * data) { *reinterpret_cast(data) = 1; }, - [](IkarusPropertyScope const * _, void * data) { *reinterpret_cast(data) = 2; }, - [](IkarusEntityScope const * _, void * data) { *reinterpret_cast(data) = 3; }, + scope, + [](IkarusBlueprintScope, void * data) { *reinterpret_cast(data) = 1; }, + [](IkarusPropertyScope, void * data) { *reinterpret_cast(data) = 2; }, + [](IkarusEntityScope, void * data) { *reinterpret_cast(data) = 3; }, &test ); diff --git a/src/types/object_type.cpp b/src/types/object_type.cpp deleted file mode 100644 index 7f5e377..0000000 --- a/src/types/object_type.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include - -#include - -IkarusObjectType ikarus_folder_type_to_object_type(IkarusFolderType type) { - return static_cast(type); -} - -IkarusObjectTypes ikarus_object_type_to_bitset(IkarusObjectType type) { - if (type == 0) { - return static_cast(0); - } - - return static_cast(1 << type); -} - -TEST_CASE("folder_to_object_type_conversion", "[object_type]") { - REQUIRE(ikarus_folder_type_to_object_type(IkarusFolderType_None) == IkarusObjectType_None); - REQUIRE(ikarus_folder_type_to_object_type(IkarusFolderType_BlueprintFolder) == IkarusObjectType_BlueprintFolder); - REQUIRE(ikarus_folder_type_to_object_type(IkarusFolderType_PropertyFolder) == IkarusObjectType_PropertyFolder); - REQUIRE(ikarus_folder_type_to_object_type(IkarusFolderType_EntityFolder) == IkarusObjectType_EntityFolder); -} - -TEST_CASE("object_type_to_bitset_conversion", "[object_type]") { - REQUIRE(ikarus_object_type_to_bitset(IkarusObjectType_None) == IkarusObjectTypes_None); - REQUIRE(ikarus_object_type_to_bitset(IkarusObjectType_Blueprint) == IkarusObjectTypes_Blueprint); - REQUIRE(ikarus_object_type_to_bitset(IkarusObjectType_Property) == IkarusObjectTypes_Property); - REQUIRE(ikarus_object_type_to_bitset(IkarusObjectType_Entity) == IkarusObjectTypes_Entity); - REQUIRE(ikarus_object_type_to_bitset(IkarusObjectType_BlueprintFolder) == IkarusObjectTypes_BlueprintFolder); - REQUIRE(ikarus_object_type_to_bitset(IkarusObjectType_PropertyFolder) == IkarusObjectTypes_PropertyFolder); - REQUIRE(ikarus_object_type_to_bitset(IkarusObjectType_EntityFolder) == IkarusObjectTypes_EntityFolder); -} diff --git a/src/types/value.cpp b/src/values/value.cpp similarity index 96% rename from src/types/value.cpp rename to src/values/value.cpp index 251db2c..56fa9c5 100644 --- a/src/types/value.cpp +++ b/src/values/value.cpp @@ -1,10 +1,16 @@ -#include "ikarus/types/value.h" +#include "ikarus/values/value.h" #include +#include +#include #include +#include #include +#include +#include + /// \brief Creates an indeterminate entity value of a given type. /// \param type The type of the value. /// \return The entity value. @@ -39,7 +45,7 @@ IkarusEntityValue ikarus_value_create_number(long double value) { IkarusEntityValue ikarus_value_create_text(char const * value) { if (value == nullptr) { return value_create_invalid(IkarusPropertyType_Text); - }; + } return IkarusEntityValue{ ._type = IkarusPropertyType_Text, @@ -326,9 +332,9 @@ TEST_CASE("visit_value", "[value]") { ikarus_value_visit( &value, - [](IkarusToggleValue const * _, void * data) { *reinterpret_cast(data) = 1; }, - [](IkarusNumberValue const * _, void * data) { *reinterpret_cast(data) = 2; }, - [](IkarusTextValue const * _, void * data) { *reinterpret_cast(data) = 3; }, + [](IkarusToggleValue const *, void * data) { *reinterpret_cast(data) = 1; }, + [](IkarusNumberValue const *, void * data) { *reinterpret_cast(data) = 2; }, + [](IkarusTextValue const *, void * data) { *reinterpret_cast(data) = 3; }, &test );