From 5dce2ced9464fe82f7e07239ad4e93019b987b9e Mon Sep 17 00:00:00 2001 From: Folling Date: Tue, 30 Jan 2024 09:31:08 +0100 Subject: [PATCH] add src/ikarus subdir and make names unique for objects per scope Signed-off-by: Folling --- .clang-tidy | 26 ++- clang-format.txt | 192 ------------------ include/ikarus/errors.h | 3 +- include/ikarus/id.h | 8 +- include/ikarus/objects/blueprint.h | 41 ++-- include/ikarus/objects/entity.h | 41 ++-- include/ikarus/objects/object.h | 68 +------ include/ikarus/objects/properties/property.h | 3 +- .../{property_source.h => property_scope.h} | 10 +- include/ikarus/persistence/project.h | 88 +++++--- src/{ => ikarus}/errors.cpp | 4 +- src/{ => ikarus}/errors.hpp | 0 src/{ => ikarus}/global.cpp | 0 src/{ => ikarus}/id.cpp | 2 +- src/{ => ikarus}/objects/blueprint.cpp | 43 ++-- src/{ => ikarus}/objects/blueprint.hpp | 8 +- src/{ => ikarus}/objects/entity.cpp | 47 ++--- src/{ => ikarus}/objects/entity.hpp | 8 +- src/ikarus/objects/object.cpp | 93 +++++++++ src/{ => ikarus}/objects/object.hpp | 5 + src/{ => ikarus}/objects/object_type.cpp | 0 .../objects/properties/number_property.cpp | 15 +- .../objects/properties/number_property.hpp | 5 +- .../objects/properties/property.cpp | 29 ++- .../objects/properties/property.hpp | 7 +- .../objects/properties/property_scope.cpp} | 39 ++-- .../objects/properties/property_scope.hpp | 39 ++++ .../objects/properties/text_property.cpp | 12 +- .../objects/properties/text_property.hpp | 5 +- .../objects/properties/toggle_property.cpp | 12 +- .../objects/properties/toggle_property.hpp | 5 +- src/{ => ikarus}/objects/properties/util.hpp | 34 ++-- src/ikarus/objects/util.hpp | 125 ++++++++++++ src/{ => ikarus}/persistence/migrations.hpp | 2 +- .../migrations/m0_initial_layout.sql | 54 +---- src/{ => ikarus}/persistence/project.cpp | 16 +- src/{ => ikarus}/persistence/project.hpp | 0 .../values/entity_property_value.cpp | 4 +- .../values/entity_property_value.hpp | 0 src/{ => ikarus}/values/number_value.cpp | 4 +- src/{ => ikarus}/values/number_value.hpp | 2 +- src/{ => ikarus}/values/text_value.cpp | 4 +- src/{ => ikarus}/values/text_value.hpp | 2 +- src/{ => ikarus}/values/toggle_value.cpp | 4 +- src/{ => ikarus}/values/toggle_value.hpp | 2 +- src/{ => ikarus}/values/value.cpp | 9 +- src/{ => ikarus}/values/value.hpp | 6 +- src/{ => ikarus}/values/value_base.hpp | 0 src/objects/object.cpp | 170 ---------------- src/objects/properties/property_source.hpp | 27 --- vendor/sqlitecpp | 2 +- 51 files changed, 590 insertions(+), 735 deletions(-) delete mode 100644 clang-format.txt rename include/ikarus/objects/properties/{property_source.h => property_scope.h} (86%) rename src/{ => ikarus}/errors.cpp (98%) rename src/{ => ikarus}/errors.hpp (100%) rename src/{ => ikarus}/global.cpp (100%) rename src/{ => ikarus}/id.cpp (93%) rename src/{ => ikarus}/objects/blueprint.cpp (83%) rename src/{ => ikarus}/objects/blueprint.hpp (71%) rename src/{ => ikarus}/objects/entity.cpp (88%) rename src/{ => ikarus}/objects/entity.hpp (72%) create mode 100644 src/ikarus/objects/object.cpp rename src/{ => ikarus}/objects/object.hpp (82%) rename src/{ => ikarus}/objects/object_type.cpp (100%) rename src/{ => ikarus}/objects/properties/number_property.cpp (70%) rename src/{ => ikarus}/objects/properties/number_property.hpp (77%) rename src/{ => ikarus}/objects/properties/property.cpp (81%) rename src/{ => ikarus}/objects/properties/property.hpp (79%) rename src/{objects/properties/property_source.cpp => ikarus/objects/properties/property_scope.cpp} (58%) create mode 100644 src/ikarus/objects/properties/property_scope.hpp rename src/{ => ikarus}/objects/properties/text_property.cpp (77%) rename src/{ => ikarus}/objects/properties/text_property.hpp (77%) rename src/{ => ikarus}/objects/properties/toggle_property.cpp (77%) rename src/{ => ikarus}/objects/properties/toggle_property.hpp (77%) rename src/{ => ikarus}/objects/properties/util.hpp (73%) create mode 100644 src/ikarus/objects/util.hpp rename src/{ => ikarus}/persistence/migrations.hpp (90%) rename src/{ => ikarus}/persistence/migrations/m0_initial_layout.sql (61%) rename src/{ => ikarus}/persistence/project.cpp (95%) rename src/{ => ikarus}/persistence/project.hpp (100%) rename src/{ => ikarus}/values/entity_property_value.cpp (90%) rename src/{ => ikarus}/values/entity_property_value.hpp (100%) rename src/{ => ikarus}/values/number_value.cpp (96%) rename src/{ => ikarus}/values/number_value.hpp (94%) rename src/{ => ikarus}/values/text_value.cpp (96%) rename src/{ => ikarus}/values/text_value.hpp (94%) rename src/{ => ikarus}/values/toggle_value.cpp (96%) rename src/{ => ikarus}/values/toggle_value.hpp (94%) rename src/{ => ikarus}/values/value.cpp (96%) rename src/{ => ikarus}/values/value.hpp (91%) rename src/{ => ikarus}/values/value_base.hpp (100%) delete mode 100644 src/objects/object.cpp delete mode 100644 src/objects/properties/property_source.hpp diff --git a/.clang-tidy b/.clang-tidy index 63731e9..49b97c2 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,26 +1,24 @@ Checks: >- -*, - bugprone-*, -bugprone-lambda-function-name, - cppcoreguidelines-*, -cppcoreguidelines-macro-usage, -cppcoreguidelines-owning-memory, -cppcoreguidelines-non-private-member-variables-in-classes, - clang-analyzer-*, - google-*, -google-readability-todo, - modernize-*, -modernize-use-trailing-return-type, - performance-*, -performance-enum-size, - portability-*, - readability-*, -readability-redundant-access-specifiers +# bugprone-*, -bugprone-lambda-function-name, +# cppcoreguidelines-*, -cppcoreguidelines-macro-usage, -cppcoreguidelines-owning-memory, -cppcoreguidelines-non-private-member-variables-in-classes, +# clang-analyzer-*, +# google-*, -google-readability-todo, +# modernize-*, -modernize-use-trailing-return-type, +# performance-*, -performance-enum-size, +# portability-*, +# readability-*, -readability-redundant-access-specifiers CheckOptions: readability-identifier-length.IgnoredParameterNames: '^(db|rc|id|ec)$' readability-identifier-length.IgnoredLoopCounterNames: '^[ij]$' readability-identifier-length.IgnoredVariableNames: '^(db|rc|id|ec)$' cppcoreguidelines-avoid-do-while.IgnoreMacros: Yes HeaderFileExtensions: - - h - - hpp - - tpp - - ipp +# - hpp +# - tpp +# - ipp ImplementationFileExtensions: - - c - - cpp +# - cpp FormatStyle: file InheritParentConfig: false WarningsAsErrors: '*' diff --git a/clang-format.txt b/clang-format.txt deleted file mode 100644 index a600edb..0000000 --- a/clang-format.txt +++ /dev/null @@ -1,192 +0,0 @@ -BasedOnStyle: Google - -AccessModifierOffset: -4 - -AlignAfterOpenBracket: BlockIndent -AlignArrayOfStructures: Right -AlignConsecutiveAssignments: - Enabled: false -AlignConsecutiveBitFields: - Enabled: false -AlignConsecutiveDeclarations: - Enabled: false -AlignConsecutiveMacros: AcrossEmptyLines -AlignEscapedNewlines: Left -AlignOperands: Align -AlignTrailingComments: true - -AllowAllArgumentsOnNextLine: false -AllowAllParametersOfDeclarationOnNextLine: false -AllowShortBlocksOnASingleLine: Empty -AllowShortCaseLabelsOnASingleLine: true -AllowShortEnumsOnASingleLine: true -AllowShortFunctionsOnASingleLine: Empty -AllowShortIfStatementsOnASingleLine: WithoutElse -AllowShortLambdasOnASingleLine: All -AllowShortLoopsOnASingleLine: true - -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: true -AlwaysBreakTemplateDeclarations: Yes - -BinPackArguments: false -BinPackParameters: false - -BitFieldColonSpacing: Both - -BraceWrapping: - AfterCaseLabel: false - AfterClass: false - AfterControlStatement: Never - AfterEnum: false - AfterFunction: false - AfterNamespace: false - AfterStruct: false - AfterUnion: false - AfterExternBlock: false - BeforeCatch: false - BeforeElse: false - BeforeLambdaBody: false - BeforeWhile: false - IndentBraces: false - SplitEmptyFunction: false - SplitEmptyNamespace: false - SplitEmptyRecord: false - -BracedInitializerIndentWidth: 4 - -# BreakAdjacentStringLiterals: true -BreakAfterAttributes: Never -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Custom -BreakBeforeConceptDeclarations: Always -BreakBeforeInlineASMColon: OnlyMultiline -BreakBeforeTernaryOperators: false -BreakConstructorInitializers: AfterColon -BreakInheritanceList: AfterColon -BreakStringLiterals: false - -ColumnLimit: 140 - -CompactNamespaces: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 - -Cpp11BracedListStyle: true - -DerivePointerAlignment: false - -EmptyLineAfterAccessModifier: Never -EmptyLineBeforeAccessModifier: Always - -ExperimentalAutoDetectBinPacking: true - -FixNamespaceComments: true - -IncludeBlocks: Regroup -IncludeCategories: - - Regex: '^".+\.(h|hpp)"$' - Priority: 1 - - Regex: '^<[a-z0-9_]+\.h>$' - Priority: 2 - - Regex: '^<[a-z0-9_]+>$' - Priority: 3 - - Regex: '^$' - Priority: 4 - - Regex: '^$' - Priority: 5 - - Regex: '^$' - Priority: 6 - - Regex: '^$' - Priority: 7 - - Regex: '^$' - Priority: 8 - - Regex: '^$' - Priority: 9 - - Regex: '^$' - Priority: 10 - - Regex: '^$' - Priority: 11 - - Regex: '^$' - Priority: 12 - - Regex: '^$' - Priority: 13 - -IndentAccessModifiers: false -IndentCaseBlocks: false -IndentCaseLabels: false -IndentExternBlock: NoIndent -IndentGotoLabels: false -IndentPPDirectives: None -IndentRequiresClause: true -IndentWidth: 4 -IndentWrappedFunctionNames: false -InsertBraces: true -InsertNewlineAtEOF: true -InsertTrailingCommas: Wrapped - -IntegerLiteralSeparator: - Binary: -1 - Decimal: 3 - Hex: -1 - -KeepEmptyLinesAtEOF: false -KeepEmptyLinesAtTheStartOfBlocks: false - -LambdaBodyIndentation: Signature -Language: Cpp - -LineEnding: LF - -MaxEmptyLinesToKeep: 1 - -NamespaceIndentation: None - -PPIndentWidth: -1 -PackConstructorInitializers: Never - -PointerAlignment: Middle -QualifierAlignment: Right -# QualifierOrder: [ 'friend', 'constexpr', 'inline', 'static', 'type', 'const', 'volatile' ] -ReferenceAlignment: Middle - -ReflowComments: true -RemoveBracesLLVM: false -RemoveParentheses: MultipleParentheses -RemoveSemicolon: true - -RequiresClausePosition: OwnLine -RequiresExpressionIndentation: OuterScope - -SeparateDefinitionBlocks: Always - -SortIncludes: CaseInsensitive -SortUsingDeclarations: LexicographicNumeric - -SpaceAfterCStyleCast: false -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: false -SpaceAroundPointerQualifiers: Both -SpaceBeforeAssignmentOperators: true -SpaceBeforeCaseColon: false -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: false -SpaceBeforeInheritanceColon: true -SpaceBeforeParens: ControlStatements -SpaceBeforeRangeBasedForLoopColon: true -SpaceBeforeSquareBrackets: false -SpaceInEmptyBlock: false -SpaceInEmptyParentheses: false -SpacesInAngles: false -SpacesInCStyleCastParentheses: false -SpacesInConditionalStatement: false -SpacesInContainerLiterals: false -SpacesInLineCommentPrefix: - Minimum: 1 - Maximum: 1 -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: c++20 - -TabWidth: 4 -UseTab: Never diff --git a/include/ikarus/errors.h b/include/ikarus/errors.h index a4887a3..ce11788 100644 --- a/include/ikarus/errors.h +++ b/include/ikarus/errors.h @@ -1,6 +1,6 @@ #pragma once -/// \file global.h +/// \file errors.h /// \author Folling #include @@ -92,6 +92,7 @@ enum IkarusErrorInfo { IkarusErrorInfo_LibIkarus_Timeout = 0x06000003, }; +/// \brief The maximum length of an error message. size_t const IKARUS_ERROR_DATA_MAX_MESSAGE_LIMIT = 128; /// \brief The data stored for an error diff --git a/include/ikarus/id.h b/include/ikarus/id.h index ae545a9..c76e341 100644 --- a/include/ikarus/id.h +++ b/include/ikarus/id.h @@ -11,8 +11,6 @@ #include #include -IKARUS_BEGIN_HEADER - /// \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: @@ -22,6 +20,8 @@ IKARUS_BEGIN_HEADER /// - last 56 bits: incremented counter generated by the database /// @{ +IKARUS_BEGIN_HEADER + /// \brief A wrapper around a 64 bit integer that represents the id of an object. /// \details They are stored as 64 bit integers with the following layout: /// - first bit: ignored, technically we could use it, but SQLite doesn't support u64 integers. @@ -41,6 +41,6 @@ IKA_API IkarusId ikarus_id_from_data_and_type(int64_t data, IkarusObjectType typ /// \return The object type of the given id. IKA_API IkarusObjectType ikarus_id_get_object_type(IkarusId id); -/// @} - IKARUS_END_HEADER + +/// @} diff --git a/include/ikarus/objects/blueprint.h b/include/ikarus/objects/blueprint.h index 3ce07ce..adfacd4 100644 --- a/include/ikarus/objects/blueprint.h +++ b/include/ikarus/objects/blueprint.h @@ -25,9 +25,9 @@ struct IkarusBlueprint; /// \param name The name of the blueprint. /// \pre \li Must not be null. /// \pre \li Must not be empty. +/// \pre \li Must be unique among all blueprints in the project. /// \param error_out \see errors.h /// \return The created blueprint or null if an error occurs. -/// \remark Must be freed using #ikarus_free. IKA_API IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project, char const * name, IkarusErrorData * error_out); /// \brief Deletes & frees a blueprint. @@ -38,6 +38,33 @@ IKA_API IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project /// \remark The blueprint must not be accessed after deletion. IKA_API void ikarus_blueprint_delete(IkarusBlueprint * blueprint, IkarusErrorData * error_out); +/// \brief Gets the project a blueprint is part of. +/// \param blueprint The blueprint to get the project of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param error_out \see errors.h +/// \return The project the blueprint is part of or null if an error occurs. +IKA_API IkarusProject * ikarus_blueprint_get_project(IkarusBlueprint const * blueprint, IkarusErrorData * error_out); + +/// \brief Gets the name of a blueprint. +/// \param blueprint The blueprint to get the name of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param error_out \see errors.h +/// \return The name of the blueprint or null if an error occurs. +IKA_API char const * ikarus_blueprint_get_name(IkarusBlueprint const * blueprint, IkarusErrorData * error_out); + +/// \brief Sets the name of a blueprint. +/// \param blueprint The blueprint to set the name of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param name The new name of the blueprint. +/// \pre \li Must not be null. +/// \pre \li Must not be empty. +/// \pre \li Must be unique among all blueprints in the project. +/// \param error_out \see errors.h +IKA_API void ikarus_blueprint_set_name(IkarusBlueprint * blueprint, char const * name, IkarusErrorData * error_out); + /// \brief Gets the properties of a blueprint. /// \param blueprint The blueprint to get the properties of. /// \pre \li Must not be null. @@ -86,18 +113,6 @@ IKA_API void ikarus_blueprint_get_linked_entities( /// \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, IkarusErrorData * error_out); -/// \brief Casts a blueprint to an object. -/// \param blueprint The blueprint to cast. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param error_out \see errors.h -/// \return The blueprint represented as an object or null if an error occurs. -/// \remark This operation is guaranteed to be very fast and is intended to be used frequently. -IKA_API struct IkarusObject * ikarus_blueprint_to_object(IkarusBlueprint * blueprint, IkarusErrorData * error_out); - -/// \see ikarus_blueprint_to_object -IKA_API struct IkarusObject const * ikarus_blueprint_to_object_const(IkarusBlueprint const * blueprint, IkarusErrorData * error_out); - IKARUS_END_HEADER // @} diff --git a/include/ikarus/objects/entity.h b/include/ikarus/objects/entity.h index 9610230..53abc70 100644 --- a/include/ikarus/objects/entity.h +++ b/include/ikarus/objects/entity.h @@ -41,9 +41,9 @@ struct IkarusEntity; /// \param name The name of the entity. /// \pre \li Must not be null. /// \pre \li Must not be empty. +/// \pre \li Must be unique among all entities in the project. /// \param error_out \see errors.h /// \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, char const * name, IkarusErrorData * error_out); /// \brief Deletes an entity. @@ -54,6 +54,33 @@ IKA_API IkarusEntity * ikarus_entity_create(struct IkarusProject * project, char /// \remark The entity must not be accessed after deletion. IKA_API void ikarus_entity_delete(IkarusEntity * entity, IkarusErrorData * error_out); +/// \brief Gets the project an entity is part of. +/// \param entity The entity to get the project of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param error_out \see errors.h +/// \return The project the entity is part of or null if an error occurs. +IKA_API IkarusProject * ikarus_entity_get_project(IkarusEntity const * entity, IkarusErrorData * error_out); + +/// \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. +/// \param error_out \see errors.h +/// \return The name of the entity or null if an error occurs. +IKA_API char const * ikarus_entity_get_name(IkarusEntity const * entity, IkarusErrorData * error_out); + +/// \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 name The new name of the entity. +/// \pre \li Must not be null. +/// \pre \li Must not be empty. +/// \pre \li Must be unique among all entities in the project. +/// \param error_out \see errors.h +IKA_API void ikarus_entity_set_name(IkarusEntity * entity, char const * name, IkarusErrorData * error_out); + /// \brief Checks if an entity is linked to a blueprint. /// \param entity The entity to check. /// \pre \li Must not be null. @@ -182,18 +209,6 @@ IKA_API void ikarus_entity_set_value( IkarusErrorData * error_out ); -/// \brief Casts an entity to an object. -/// \param entity The entity to cast. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param error_out \see errors.h -/// \return The entity represented as an object or null if an error occurs. -/// \remark This operation is guaranteed to be very fast and is intended to be used frequently. -IKA_API struct IkarusObject * ikarus_entity_to_object(IkarusEntity * entity, IkarusErrorData * error_out); - -/// \see ikarus_entity_to_object -IKA_API struct IkarusObject const * ikarus_entity_to_object_const(IkarusEntity const * entity, IkarusErrorData * error_out); - IKARUS_END_HEADER // @} diff --git a/include/ikarus/objects/object.h b/include/ikarus/objects/object.h index 7dcc97f..6a46e17 100644 --- a/include/ikarus/objects/object.h +++ b/include/ikarus/objects/object.h @@ -19,62 +19,6 @@ IKARUS_BEGIN_HEADER /// \brief A generic object. Wraps all types of objects, including folders. struct IkarusObject; -/// \brief Fetches the project of an object. -/// \param object The object to fetch the project from. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param error_out \see errors.h -/// \return The project of the object or null if an error occurs. -IKA_API struct IkarusProject * ikarus_object_get_project(IkarusObject const * object, IkarusErrorData * error_out); - -/// \brief Fetches the name of an object. -/// \param object The object to fetch the name from. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param error_out \see errors.h -/// \return The name of the object or null if an error occurs. -IKA_API char const * ikarus_object_get_name(IkarusObject const * object, IkarusErrorData * error_out); - -/// \brief Sets the name of an object. -/// \param object The object to set the name of. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param new_name The new name of the object. -/// \pre \li Must not be null. -/// \pre \li Must not be empty. -/// \param error_out \see errors.h -IKA_API void ikarus_object_set_name(IkarusObject const * object, char const * new_name, IkarusErrorData * error_out); - -/// \brief Fetches the information of an object. -/// \param object The object to fetch the information from. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param error_out \see errors.h -/// \return The information of the object or null if an error occurs. -IKA_API char const * ikarus_object_get_info(IkarusObject const * object, IkarusErrorData * error_out); - -/// \brief Sets the information of an object. -/// \param object The object to set the information of. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param new_info The new information of the object. -/// \pre \li Must not be null. -/// \param error_out \see errors.h -IKA_API void ikarus_object_set_info(IkarusObject const * object, char const * new_info, IkarusErrorData * error_out); - -/// \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 -/// same object. -/// \param lhs The left hand side object. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param rhs The right hand side object. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param error_out \see errors.h -/// \return True if the objects are equal, false otherwise. -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. /// \param object The object to visit. /// \param blueprint_visitor The function to call if the object is a blueprint. Skipped if null. @@ -84,9 +28,9 @@ IKA_API bool ikarus_object_is_equal(IkarusObject const * lhs, IkarusObject const /// \param error_out \see errors.h IKA_API void ikarus_object_visit( IkarusObject * object, - void (*blueprint_visitor)(struct IkarusBlueprint *, void *), - void (*property_visitor)(struct IkarusProperty *, void *), - void (*entity_visitor)(struct IkarusEntity *, void *), + void (*blueprint_visitor)(struct IkarusBlueprint *, IkarusErrorData * error_out, void *), + void (*property_visitor)(struct IkarusProperty *, IkarusErrorData * error_out, void *), + void (*entity_visitor)(struct IkarusEntity *, IkarusErrorData * error_out, void *), void * data, IkarusErrorData * error_out ); @@ -94,9 +38,9 @@ IKA_API void ikarus_object_visit( /// \see ikarus_object_visit IKA_API void ikarus_object_visit_const( IkarusObject const * object, - void (*blueprint_visitor)(struct IkarusBlueprint const *, void *), - void (*property_visitor)(struct IkarusProperty const *, void *), - void (*entity_visitor)(struct IkarusEntity const *, void *), + void (*blueprint_visitor)(struct IkarusBlueprint const *, IkarusErrorData * error_out, void *), + void (*property_visitor)(struct IkarusProperty const *, IkarusErrorData * error_out, void *), + void (*entity_visitor)(struct IkarusEntity const *, IkarusErrorData * error_out, void *), void * data, IkarusErrorData * error_out ); diff --git a/include/ikarus/objects/properties/property.h b/include/ikarus/objects/properties/property.h index 7a94079..589854f 100644 --- a/include/ikarus/objects/properties/property.h +++ b/include/ikarus/objects/properties/property.h @@ -70,7 +70,6 @@ IKA_API void ikarus_property_delete(IkarusProperty * property, IkarusErrorData * /// \pre \li Must exist. /// \param error_out \see errors.h /// \return The type info of the property or null if an error occurs. -/// \remark Must be freed using #ikarus_free. IKA_API IkarusPropertyType ikarus_property_get_type(IkarusProperty const * property, IkarusErrorData * error_out); /// \brief Gets the source of a property. @@ -80,7 +79,7 @@ IKA_API IkarusPropertyType ikarus_property_get_type(IkarusProperty const * prope /// \param error_out \see errors.h /// \return The source of the property or null if an error occurs. /// \remark Must be freed using #ikarus_free. -IKA_API struct IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * property, IkarusErrorData * error_out); +IKA_API struct IkarusPropertyScope const * ikarus_property_get_scope(IkarusProperty const * property, IkarusErrorData * error_out); /// \brief Gets the default value of a property. /// \param property The property to get the type info of. diff --git a/include/ikarus/objects/properties/property_source.h b/include/ikarus/objects/properties/property_scope.h similarity index 86% rename from include/ikarus/objects/properties/property_source.h rename to include/ikarus/objects/properties/property_scope.h index f1da29d..a211e67 100644 --- a/include/ikarus/objects/properties/property_source.h +++ b/include/ikarus/objects/properties/property_scope.h @@ -11,7 +11,7 @@ IKARUS_BEGIN_HEADER -struct IkarusPropertySource; +struct IkarusPropertyScope; /// \brief Creates an blueprint property source. /// \param blueprint The blueprint to create the property source for. @@ -20,7 +20,7 @@ struct IkarusPropertySource; /// \param error_out \see errors.h /// \return The created property source or null if an error occurs. /// \remark Must be freed using #ikarus_free. -IKA_API struct IkarusPropertySource * +IKA_API struct IkarusPropertyScope * ikarus_property_source_create_blueprint(struct IkarusBlueprint * blueprint, IkarusErrorData * error_out); /// \brief Creates an entity property source. @@ -30,7 +30,7 @@ ikarus_property_source_create_blueprint(struct IkarusBlueprint * blueprint, Ikar /// \param error_out \see errors.h /// \return The created property source or null if an error occurs. /// \remark Must be freed using #ikarus_free. -IKA_API struct IkarusPropertySource * ikarus_property_source_create_entity(struct IkarusEntity * entity, IkarusErrorData * error_out); +IKA_API struct IkarusPropertyScope * ikarus_property_source_create_entity(struct IkarusEntity * entity, IkarusErrorData * error_out); /// \brief Visits a property source, calling the appropriate callback. /// \param property_source The property source to visit. @@ -41,7 +41,7 @@ IKA_API struct IkarusPropertySource * ikarus_property_source_create_entity(struc /// \param user_data User data to pass to the callbacks. /// \param error_out \see errors.h IKA_API void ikarus_property_source_visit( - struct IkarusPropertySource * property_source, + struct IkarusPropertyScope * property_source, void (*blueprint_visitor)(struct IkarusBlueprint *, void *), void (*entity_visitor)(struct IkarusEntity *, void *), void * user_data, @@ -50,7 +50,7 @@ IKA_API void ikarus_property_source_visit( /// \see ikarus_property_source_visit IKA_API void ikarus_property_source_visit_const( - struct IkarusPropertySource const * property_source, + struct IkarusPropertyScope const * property_source, void (*blueprint_visitor)(struct IkarusBlueprint const *, void *), void (*entity_visitor)(struct IkarusEntity const *, void *), void * user_data, diff --git a/include/ikarus/persistence/project.h b/include/ikarus/persistence/project.h index 117909e..f1f083a 100644 --- a/include/ikarus/persistence/project.h +++ b/include/ikarus/persistence/project.h @@ -80,29 +80,6 @@ IKA_API void ikarus_project_set_name(IkarusProject * project, char const * new_n /// \remark Ownership remains with libikarus, must not be freed. IKA_API char const * ikarus_project_get_path(IkarusProject const * project, IkarusErrorData * error_out); -/// \brief Gets the blueprints of a project. -/// \param project The project to get the blueprints of. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param blueprints_out The buffer to write the blueprints to. -/// \pre \li Must not be null. -/// \param blueprints_out_size The size of the buffer. -/// \param error_out \see errors.h -IKA_API void ikarus_project_get_blueprints( - IkarusProject * 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 entities of a project. /// \param project The project to get the entities of. /// \pre \li Must not be null. @@ -126,6 +103,71 @@ IKA_API void ikarus_project_get_entities( /// \return The number of entities or undefined if an error occurs. IKA_API size_t ikarus_project_get_entity_count(IkarusProject * project, IkarusErrorData * error_out); +/// \brief Gets the blueprints of a project. +/// \param project The project to get the blueprints of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param blueprints_out The buffer to write the blueprints to. +/// \pre \li Must not be null. +/// \param blueprints_out_size The size of the buffer. +/// \param error_out \see errors.h +IKA_API void ikarus_project_get_blueprints( + IkarusProject * 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 Finds an entity by a given name. +/// \param project The project to search. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param name The name to search for. +/// \pre \li Must not be null. +/// \pre \li Must not be empty. +/// \param error_out \see errors.h +/// \return The entity with the given name or null if none was found. +IKA_API struct IkarusEntity* get_entity_by_name( + IkarusProject const * project, + char const * name, + IkarusErrorData * error_out +); + +/// \brief Finds a property by a given name. +/// \param project The project to search. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param scope The scope of the property. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \remark Property names are unique only within their scope. +/// \param name The name to search for. +/// \pre \li Must not be null. +/// \pre \li Must not be empty. +/// \param error_out \see errors.h +/// \return The property with the given name or null if none was found. +IKA_API struct IkarusProperty * +get_property_by_name(IkarusProject const * project, struct IkarusPropertyScope * scope, char const * name, IkarusErrorData * error_out); + +/// \brief Finds a blueprint by a given name. +/// \param project The project to search. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param name The name to search for. +/// \pre \li Must not be null. +/// \pre \li Must not be empty. +/// \param error_out \see errors.h +/// \return The blueprint with the given name or null if none was found. +IKA_API struct IkarusBlueprint * get_blueprints_by_name(IkarusProject const * project, char const * name, IkarusErrorData * error_out); + IKARUS_END_HEADER /// @} diff --git a/src/errors.cpp b/src/ikarus/errors.cpp similarity index 98% rename from src/errors.cpp rename to src/ikarus/errors.cpp index 4441fe9..d98b28c 100644 --- a/src/errors.cpp +++ b/src/ikarus/errors.cpp @@ -1,13 +1,13 @@ #include "ikarus/errors.h" -#include "cppbase/functional.hpp" - #include #include #include +#include + char const * get_error_info_name(IkarusErrorInfo info) { switch (info) { case IkarusErrorInfo_None: return "None"; diff --git a/src/errors.hpp b/src/ikarus/errors.hpp similarity index 100% rename from src/errors.hpp rename to src/ikarus/errors.hpp diff --git a/src/global.cpp b/src/ikarus/global.cpp similarity index 100% rename from src/global.cpp rename to src/ikarus/global.cpp diff --git a/src/id.cpp b/src/ikarus/id.cpp similarity index 93% rename from src/id.cpp rename to src/ikarus/id.cpp index 4269215..031c490 100644 --- a/src/id.cpp +++ b/src/ikarus/id.cpp @@ -3,7 +3,7 @@ #include constexpr uint64_t IKARUS_ID_OBJECT_TYPE_BITS = 8; -constexpr uint64_t IKARUS_ID_OBJECT_RANDOM_BITS = sizeof(IkarusId) * 8 - IKARUS_ID_OBJECT_TYPE_BITS; +constexpr uint64_t IKARUS_ID_OBJECT_RANDOM_BITS = sizeof(IkarusId) - IKARUS_ID_OBJECT_TYPE_BITS; auto ikarus_id_from_data_and_type(int64_t data, IkarusObjectType type) -> IkarusId { return data | (static_cast(type) << IKARUS_ID_OBJECT_RANDOM_BITS); diff --git a/src/objects/blueprint.cpp b/src/ikarus/objects/blueprint.cpp similarity index 83% rename from src/objects/blueprint.cpp rename to src/ikarus/objects/blueprint.cpp index e5f3f0c..326129d 100644 --- a/src/objects/blueprint.cpp +++ b/src/ikarus/objects/blueprint.cpp @@ -1,24 +1,23 @@ #include "ikarus/objects/blueprint.h" -#include "ikarus/objects/properties/property.h" -#include "objects/blueprint.hpp" - #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include IkarusBlueprint::IkarusBlueprint(IkarusProject * project, IkarusId id): IkarusObject{project, id} {} IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project, char const * name, IkarusErrorData * error_out) { IKARUS_FAIL_IF_NULL(project, nullptr); - IKARUS_FAIL_IF_NULL(name, nullptr); - IKARUS_FAIL_IF(cppbase::is_empty_or_blank(name), nullptr, "name must not be empty", IkarusErrorInfo_Client_InvalidInput); + IKARUS_FAIL_IF_NAME_INVALID(name, project, nullptr, nullptr); IKARUS_VTRYRV_OR_FAIL( IkarusId const id, @@ -50,6 +49,18 @@ void ikarus_blueprint_delete(IkarusBlueprint * blueprint, IkarusErrorData * erro blueprint->project->uncache(blueprint); } +IkarusProject * ikarus_blueprint_get_project(IkarusBlueprint const * blueprint, IkarusErrorData * error_out) { + return ikarus::util::object_get_project(blueprint, error_out); +} + +char const * ikarus_blueprint_get_name(IkarusBlueprint const * blueprint, IkarusErrorData * error_out) { + return ikarus::util::object_get_name(blueprint, error_out); +} + +void ikarus_blueprint_set_name(IkarusBlueprint * blueprint, char const * name, IkarusErrorData * error_out) { + ikarus::util::object_set_name(blueprint, name, error_out); +} + void ikarus_blueprint_get_properties( IkarusBlueprint const * blueprint, struct IkarusProperty ** properties_out, @@ -147,17 +158,3 @@ size_t ikarus_blueprint_get_linked_entity_count(IkarusBlueprint const * blueprin return ret; } - -// No existence checks here for performance reasons. All methods on IkarusObject perform this check anyway. - -IkarusObject * ikarus_blueprint_to_object(IkarusBlueprint * blueprint, IkarusErrorData * error_out) { - IKARUS_FAIL_IF_NULL(blueprint, nullptr); - - return static_cast(blueprint); -} - -IkarusObject const * ikarus_blueprint_to_object_const(IkarusBlueprint const * blueprint, IkarusErrorData * error_out) { - IKARUS_FAIL_IF_NULL(blueprint, nullptr); - - return static_cast(blueprint); -} diff --git a/src/objects/blueprint.hpp b/src/ikarus/objects/blueprint.hpp similarity index 71% rename from src/objects/blueprint.hpp rename to src/ikarus/objects/blueprint.hpp index 61aca64..30c57b0 100644 --- a/src/objects/blueprint.hpp +++ b/src/ikarus/objects/blueprint.hpp @@ -1,8 +1,9 @@ #pragma once -#include +#include struct IkarusBlueprint : IkarusObject { +public: IkarusBlueprint(struct IkarusProject * project, IkarusId id); IkarusBlueprint(IkarusBlueprint const &) = default; @@ -12,4 +13,9 @@ struct IkarusBlueprint : IkarusObject { IkarusBlueprint & operator=(IkarusBlueprint &&) = default; ~IkarusBlueprint() override = default; + +public: + inline std::string_view get_table_name() const noexcept override { + return "blueprints"; + } }; diff --git a/src/objects/entity.cpp b/src/ikarus/objects/entity.cpp similarity index 88% rename from src/objects/entity.cpp rename to src/ikarus/objects/entity.cpp index 6c1839a..94e8b75 100644 --- a/src/objects/entity.cpp +++ b/src/ikarus/objects/entity.cpp @@ -1,19 +1,18 @@ #include "entity.hpp" -#include "values/value.hpp" - #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include IkarusEntity * ikarus_entity_create(struct IkarusProject * project, char const * name, IkarusErrorData * error_out) { IKARUS_FAIL_IF_NULL(project, nullptr); - IKARUS_FAIL_IF_NULL(name, nullptr); - IKARUS_FAIL_IF(cppbase::is_empty_or_blank(name), nullptr, "name must not be empty", IkarusErrorInfo_Client_InvalidInput); + IKARUS_FAIL_IF_NAME_INVALID(name, project, nullptr, nullptr); IKARUS_VTRYRV_OR_FAIL( IkarusId const id, @@ -21,9 +20,9 @@ IkarusEntity * ikarus_entity_create(struct IkarusProject * project, char const * "failed to create entity: {}", IkarusErrorInfo_Database_QueryFailed, project->db->transact([name](auto * db) -> cppbase::Result { - TRY(db->execute("INSERT INTO `objects`(`type`, `name`, `information`) VALUES(?, ?, ?)", IkarusObjectType_Entity, name, "")); + TRY(db->execute("INSERT INTO `objects`(`type`) VALUES(?, ?, ?)", IkarusObjectType_Entity)); auto id = ikarus_id_from_data_and_type(db->last_insert_rowid(), IkarusObjectType_Entity); - TRY(db->execute("INSERT INTO `entities`(`id`) VALUES(?)", id)); + TRY(db->execute("INSERT INTO `entities`(`id`, `name`) VALUES(?)", id, name)); return cppbase::ok(id); }) ); @@ -45,6 +44,18 @@ void ikarus_entity_delete(IkarusEntity * entity, IkarusErrorData * error_out) { entity->project->uncache(entity); } +IkarusProject * ikarus_entity_get_project(IkarusEntity const * entity, IkarusErrorData * error_out) { + return ikarus::util::object_get_project(entity, error_out); +} + +char const * ikarus_entity_get_name(IkarusEntity const * entity, IkarusErrorData * error_out) { + return ikarus::util::object_get_name(entity, error_out); +} + +void ikarus_entity_set_name(IkarusEntity * entity, char const * name, IkarusErrorData * error_out) { + ikarus::util::object_set_name(entity, name, error_out); +} + bool ikarus_entity_is_linked_to_blueprint( IkarusEntity const * entity, struct IkarusBlueprint const * blueprint, @@ -273,17 +284,3 @@ void ikarus_entity_set_value( ) ); } - -// No existence checks here for performance reasons. All methods on IkarusObject perform this check anyway. - -struct IkarusObject * ikarus_entity_to_object(IkarusEntity * entity, IkarusErrorData * error_out) { - IKARUS_FAIL_IF_NULL(entity, nullptr); - - return static_cast(entity); -} - -struct IkarusObject const * ikarus_entity_to_object_const(IkarusEntity const * entity, IkarusErrorData * error_out) { - IKARUS_FAIL_IF_NULL(entity, nullptr); - - return static_cast(entity); -} diff --git a/src/objects/entity.hpp b/src/ikarus/objects/entity.hpp similarity index 72% rename from src/objects/entity.hpp rename to src/ikarus/objects/entity.hpp index 92cf4c6..586c88f 100644 --- a/src/objects/entity.hpp +++ b/src/ikarus/objects/entity.hpp @@ -1,8 +1,9 @@ #pragma once -#include +#include struct IkarusEntity : IkarusObject { +public: inline IkarusEntity(struct IkarusProject * project, IkarusId id): IkarusObject{project, id} {} @@ -13,4 +14,9 @@ struct IkarusEntity : IkarusObject { IkarusEntity & operator=(IkarusEntity &&) = default; ~IkarusEntity() override = default; + +public: + inline std::string_view get_table_name() const noexcept override { + return "entities"; + } }; diff --git a/src/ikarus/objects/object.cpp b/src/ikarus/objects/object.cpp new file mode 100644 index 0000000..d233783 --- /dev/null +++ b/src/ikarus/objects/object.cpp @@ -0,0 +1,93 @@ +#include "object.hpp" + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +IkarusObject::IkarusObject(IkarusProject * project, IkarusId id): + project{project}, + id{id} {} + +void ikarus_object_visit( + IkarusObject * object, + void (*blueprint_visitor)(struct IkarusBlueprint *, IkarusErrorData * error_out, void *), + void (*property_visitor)(struct IkarusProperty *, IkarusErrorData * error_out, void *), + void (*entity_visitor)(struct IkarusEntity *, IkarusErrorData * error_out, void *), + void * data, + IkarusErrorData * error_out +) { + struct Data { + void (*blueprint_visitor)(struct IkarusBlueprint *, IkarusErrorData * error_out, void *); + void (*property_visitor)(struct IkarusProperty *, IkarusErrorData * error_out, void *); + void (*entity_visitor)(struct IkarusEntity *, IkarusErrorData * error_out, void *); + void * data; + }; + + Data passthru_data{blueprint_visitor, property_visitor, entity_visitor, data}; + + ikarus_object_visit_const( + object, + [](IkarusBlueprint const * blueprint, IkarusErrorData * error_out, void * data) { + auto const * passthru_data = static_cast(data); + passthru_data->blueprint_visitor(const_cast(blueprint), error_out, passthru_data->data); + }, + [](IkarusProperty const * property, IkarusErrorData * error_out, void * data) { + auto const * passthru_data = static_cast(data); + passthru_data->property_visitor(const_cast(property), error_out, passthru_data->data); + }, + [](IkarusEntity const * entity, IkarusErrorData * error_out, void * data) { + auto const * passthru_data = static_cast(data); + passthru_data->entity_visitor(const_cast(entity), error_out, passthru_data->data); + }, + &passthru_data, + error_out + ); +} + +void ikarus_object_visit_const( + IkarusObject const * object, + void (*blueprint_visitor)(struct IkarusBlueprint const *, IkarusErrorData * error_out, void *), + void (*property_visitor)(struct IkarusProperty const *, IkarusErrorData * error_out, void *), + void (*entity_visitor)(struct IkarusEntity const *, IkarusErrorData * error_out, void *), + void * data, + IkarusErrorData * error_out +) { + IKARUS_FAIL_IF_NULL(object, ); + IKARUS_FAIL_IF_OBJECT_MISSING(object, ); + + switch (ikarus_id_get_object_type(object->id)) { + case IkarusObjectType_Entity: { + auto const * entity = dynamic_cast(object); + IKARUS_FAIL_IF(entity == nullptr, , "object with entity id wasn't a entity", IkarusErrorInfo_LibIkarus_InvalidState); + entity_visitor(entity, error_out, data); + } + case IkarusObjectType_Blueprint: { + auto const * blueprint = dynamic_cast(object); + IKARUS_FAIL_IF(blueprint == nullptr, , "object with blueprint id wasn't a blueprint", IkarusErrorInfo_LibIkarus_InvalidState); + blueprint_visitor(blueprint, error_out, data); + } + case IkarusObjectType_Property: { + auto const * property = dynamic_cast(object); + IKARUS_FAIL_IF(property == nullptr, , "object with property id wasn't a property", IkarusErrorInfo_LibIkarus_InvalidState); + property_visitor(property, error_out, data); + } + default: { + IKARUS_FAIL( + , + fmt::format("unknown object type: {}", ikarus_object_type_to_string(ikarus_id_get_object_type(object->id))), + IkarusErrorInfo_LibIkarus_InvalidState + ); + } + } + + // not needed, but a good delineation of our intention if this function gets extended + IKARUS_FAIL_IF_ERROR() +} diff --git a/src/objects/object.hpp b/src/ikarus/objects/object.hpp similarity index 82% rename from src/objects/object.hpp rename to src/ikarus/objects/object.hpp index 56e141b..20eed59 100644 --- a/src/objects/object.hpp +++ b/src/ikarus/objects/object.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include struct IkarusObject { @@ -14,6 +16,9 @@ public: virtual ~IkarusObject() = default; +public: + virtual std::string_view get_table_name() const noexcept = 0; + public: struct IkarusProject * project; IkarusId id; diff --git a/src/objects/object_type.cpp b/src/ikarus/objects/object_type.cpp similarity index 100% rename from src/objects/object_type.cpp rename to src/ikarus/objects/object_type.cpp diff --git a/src/objects/properties/number_property.cpp b/src/ikarus/objects/properties/number_property.cpp similarity index 70% rename from src/objects/properties/number_property.cpp rename to src/ikarus/objects/properties/number_property.cpp index b94429d..43a966c 100644 --- a/src/objects/properties/number_property.cpp +++ b/src/ikarus/objects/properties/number_property.cpp @@ -1,13 +1,11 @@ -#include "ikarus/objects/properties/number_property.h" +#include "number_property.hpp" #include #include - -#include -#include -#include -#include +#include +#include +#include IkarusNumberProperty::IkarusNumberProperty(IkarusProject * project, IkarusId id): IkarusProperty{project, id, this} {} @@ -15,11 +13,10 @@ IkarusNumberProperty::IkarusNumberProperty(IkarusProject * project, IkarusId id) IkarusNumberProperty * ikarus_number_property_create( struct IkarusProject * project, char const * name, - struct IkarusPropertySource * property_source, - struct IkarusNumberValue * default_value, + struct IkarusPropertyScope * property_source, IkarusErrorData * error_out ) { - return ikarus::util::create_property(project, name, property_source, default_value, error_out); + return ikarus::util::create_property(project, name, property_source, error_out); } IkarusNumberValue * ikarus_number_property_get_default_value(IkarusNumberProperty * property, IkarusErrorData * error_out) { diff --git a/src/objects/properties/number_property.hpp b/src/ikarus/objects/properties/number_property.hpp similarity index 77% rename from src/objects/properties/number_property.hpp rename to src/ikarus/objects/properties/number_property.hpp index 22ca3d3..eddb189 100644 --- a/src/objects/properties/number_property.hpp +++ b/src/ikarus/objects/properties/number_property.hpp @@ -1,9 +1,8 @@ #pragma once +#include #include - -#include -#include +#include struct IkarusNumberProperty : IkarusProperty { public: diff --git a/src/objects/properties/property.cpp b/src/ikarus/objects/properties/property.cpp similarity index 81% rename from src/objects/properties/property.cpp rename to src/ikarus/objects/properties/property.cpp index d3c27be..f45adbb 100644 --- a/src/objects/properties/property.cpp +++ b/src/ikarus/objects/properties/property.cpp @@ -2,14 +2,13 @@ #include +#include #include +#include #include - -#include -#include -#include -#include -#include +#include +#include +#include IkarusProperty::IkarusProperty(IkarusProject * project, IkarusId id, Data data): IkarusObject{project, id}, @@ -29,6 +28,18 @@ IKA_API void ikarus_property_delete(IkarusProperty * property, IkarusErrorData * property->project->uncache(property); } +IkarusProject * ikarus_property_get_project(IkarusProperty const * property, IkarusErrorData * error_out) { + return ikarus::util::object_get_project(property, error_out); +} + +char const * ikarus_property_get_name(IkarusProperty const * property, IkarusErrorData * error_out) { + return ikarus::util::object_get_name(property, error_out); +} + +void ikarus_property_set_name(IkarusProperty * property, char const * name, IkarusErrorData * error_out) { + ikarus::util::object_set_name(property, name, error_out); +} + IkarusPropertyType ikarus_property_get_type(IkarusProperty const * property, IkarusErrorData * error_out) { IKARUS_FAIL_IF_NULL(property, IkarusPropertyType_Toggle); IKARUS_FAIL_IF_OBJECT_MISSING(property, IkarusPropertyType_Toggle); @@ -44,7 +55,7 @@ IkarusPropertyType ikarus_property_get_type(IkarusProperty const * property, Ika return static_cast(ret); } -IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * property, IkarusErrorData * error_out) { +IkarusPropertyScope const * ikarus_property_get_scope(IkarusProperty const * property, IkarusErrorData * error_out) { IKARUS_FAIL_IF_NULL(property, nullptr); IKARUS_FAIL_IF_OBJECT_MISSING(property, nullptr); @@ -57,8 +68,8 @@ IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * p ); switch (ikarus_id_get_object_type(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_Blueprint: return new IkarusPropertyScope{property->project->get_blueprint(source)}; + case IkarusObjectType_Entity: return new IkarusPropertyScope{property->project->get_entity(source)}; default: IKARUS_FAIL( nullptr, diff --git a/src/objects/properties/property.hpp b/src/ikarus/objects/properties/property.hpp similarity index 79% rename from src/objects/properties/property.hpp rename to src/ikarus/objects/properties/property.hpp index 3a95d6b..5c37d7c 100644 --- a/src/objects/properties/property.hpp +++ b/src/ikarus/objects/properties/property.hpp @@ -2,7 +2,7 @@ #include -#include +#include struct IkarusProperty : IkarusObject { public: @@ -19,6 +19,11 @@ public: ~IkarusProperty() override = default; +public: + inline std::string_view get_table_name() const noexcept override { + return "properties"; + } + public: Data data; }; diff --git a/src/objects/properties/property_source.cpp b/src/ikarus/objects/properties/property_scope.cpp similarity index 58% rename from src/objects/properties/property_source.cpp rename to src/ikarus/objects/properties/property_scope.cpp index 3e31bb3..a0b9ade 100644 --- a/src/objects/properties/property_source.cpp +++ b/src/ikarus/objects/properties/property_scope.cpp @@ -1,17 +1,16 @@ -#include "property_source.hpp" +#include "property_scope.hpp" -#include - -#include -#include #include -IkarusPropertySource::IkarusPropertySource(Data data): +#include +#include + +IkarusPropertyScope::IkarusPropertyScope(Data data): data{data} {} -IkarusId IkarusPropertySource::get_id() const { - return boost::variant2::visit( - cppbase::overloaded { +IkarusId IkarusPropertyScope::get_id() const { + return std::visit( + cppbase::overloaded{ [](IkarusBlueprint const * blueprint) { return blueprint->id; }, [](IkarusEntity const * entity) { return entity->id; } }, @@ -19,37 +18,37 @@ IkarusId IkarusPropertySource::get_id() const { ); } -IkarusPropertySource * ikarus_property_source_create_blueprint(IkarusBlueprint * blueprint) { - return new IkarusPropertySource{blueprint}; +IkarusPropertyScope * ikarus_property_source_create_blueprint(IkarusBlueprint * blueprint) { + return new IkarusPropertyScope{blueprint}; } -IkarusPropertySource * ikarus_property_source_create_entity(IkarusEntity * entity) { - return new IkarusPropertySource{entity}; +IkarusPropertyScope * ikarus_property_source_create_entity(IkarusEntity * entity) { + return new IkarusPropertyScope{entity}; } void ikarus_property_source_visit( - struct IkarusPropertySource * property_source, + struct IkarusPropertyScope * property_source, void (*blueprint_visitor)(struct IkarusBlueprint *, void *), void (*entity_visitor)(struct IkarusEntity *, void *), void * user_data ) { - boost::variant2::visit( - boost::make_overloaded_function( + std::visit( + cppbase::overloaded{ [blueprint_visitor, user_data](IkarusBlueprint * blueprint) { blueprint_visitor(blueprint, user_data); }, [entity_visitor, user_data](IkarusEntity * entity) { entity_visitor(entity, user_data); } - ), + }, property_source->data ); } void ikarus_property_source_visit_const( - struct IkarusPropertySource const * property_source, + struct IkarusPropertyScope const * property_source, void (*blueprint_visitor)(struct IkarusBlueprint const *, void *), void (*entity_visitor)(struct IkarusEntity const *, void *), void * user_data ) { - boost::variant2::visit( - boost::make_overloaded_function( + std::visit( + cppbase::overloaded( [blueprint_visitor, user_data](IkarusBlueprint const * blueprint) { blueprint_visitor(blueprint, user_data); }, [entity_visitor, user_data](IkarusEntity const * entity) { entity_visitor(entity, user_data); } ), diff --git a/src/ikarus/objects/properties/property_scope.hpp b/src/ikarus/objects/properties/property_scope.hpp new file mode 100644 index 0000000..ab8832a --- /dev/null +++ b/src/ikarus/objects/properties/property_scope.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include + +#include +#include + +#define IKARUS_FAIL_IF_PROPERTY_SCOPE_INVALID(scope, ret) \ + std::visit( \ + cppbase::overloaded{[error_out](auto const * object) { \ + IKARUS_FAIL_IF_NULL(object, ); \ + IKARUS_FAIL_IF_OBJECT_MISSING(object, ); \ + }}, \ + scope->data \ + ); \ + \ + IKARUS_FAIL_IF_ERROR(nullptr); + +struct IkarusPropertyScope { +public: + using Data = std::variant; + +public: + explicit IkarusPropertyScope(Data data); + + IkarusPropertyScope(IkarusPropertyScope const &) = default; + IkarusPropertyScope(IkarusPropertyScope &&) = default; + + IkarusPropertyScope & operator=(IkarusPropertyScope const &) = default; + IkarusPropertyScope & operator=(IkarusPropertyScope &&) = default; + + virtual ~IkarusPropertyScope() = default; + +public: + [[nodiscard]] IkarusId get_id() const; + +public: + Data data; +}; diff --git a/src/objects/properties/text_property.cpp b/src/ikarus/objects/properties/text_property.cpp similarity index 77% rename from src/objects/properties/text_property.cpp rename to src/ikarus/objects/properties/text_property.cpp index c7541ff..6aaf483 100644 --- a/src/objects/properties/text_property.cpp +++ b/src/ikarus/objects/properties/text_property.cpp @@ -3,10 +3,9 @@ #include #include - -#include -#include -#include +#include +#include +#include IkarusTextProperty::IkarusTextProperty(IkarusProject * project, IkarusId id): IkarusProperty{project, id, this} {} @@ -14,11 +13,10 @@ IkarusTextProperty::IkarusTextProperty(IkarusProject * project, IkarusId id): IkarusTextProperty * ikarus_text_property_create( struct IkarusProject * project, char const * name, - struct IkarusPropertySource * property_source, - struct IkarusTextValue * default_value, + struct IkarusPropertyScope * property_source, IkarusErrorData * error_out ) { - return ikarus::util::create_property(project, name, property_source, default_value, error_out); + return ikarus::util::create_property(project, name, property_source, error_out); } IkarusTextValue * ikarus_text_property_get_default_value(IkarusTextProperty * property, IkarusErrorData * error_out) { diff --git a/src/objects/properties/text_property.hpp b/src/ikarus/objects/properties/text_property.hpp similarity index 77% rename from src/objects/properties/text_property.hpp rename to src/ikarus/objects/properties/text_property.hpp index a3b7e97..aca2cfa 100644 --- a/src/objects/properties/text_property.hpp +++ b/src/ikarus/objects/properties/text_property.hpp @@ -1,9 +1,8 @@ #pragma once +#include #include - -#include -#include +#include struct IkarusTextProperty : IkarusProperty { public: diff --git a/src/objects/properties/toggle_property.cpp b/src/ikarus/objects/properties/toggle_property.cpp similarity index 77% rename from src/objects/properties/toggle_property.cpp rename to src/ikarus/objects/properties/toggle_property.cpp index 2cde654..2449b39 100644 --- a/src/objects/properties/toggle_property.cpp +++ b/src/ikarus/objects/properties/toggle_property.cpp @@ -3,10 +3,9 @@ #include #include - -#include -#include -#include +#include +#include +#include IkarusToggleProperty::IkarusToggleProperty(IkarusProject * project, IkarusId id): IkarusProperty{project, id, this} {} @@ -14,11 +13,10 @@ IkarusToggleProperty::IkarusToggleProperty(IkarusProject * project, IkarusId id) IkarusToggleProperty * ikarus_toggle_property_create( struct IkarusProject * project, char const * name, - struct IkarusPropertySource * property_source, - struct IkarusToggleValue * default_value, + struct IkarusPropertyScope * property_source, IkarusErrorData * error_out ) { - return ikarus::util::create_property(project, name, property_source, default_value, error_out); + return ikarus::util::create_property(project, name, property_source, error_out); } IkarusToggleValue * ikarus_toggle_property_get_default_value(struct IkarusToggleProperty * property, IkarusErrorData * error_out) { diff --git a/src/objects/properties/toggle_property.hpp b/src/ikarus/objects/properties/toggle_property.hpp similarity index 77% rename from src/objects/properties/toggle_property.hpp rename to src/ikarus/objects/properties/toggle_property.hpp index 247cbcb..bf53c19 100644 --- a/src/objects/properties/toggle_property.hpp +++ b/src/ikarus/objects/properties/toggle_property.hpp @@ -1,9 +1,8 @@ #pragma once +#include #include - -#include -#include +#include struct IkarusToggleProperty : IkarusProperty { public: diff --git a/src/objects/properties/util.hpp b/src/ikarus/objects/properties/util.hpp similarity index 73% rename from src/objects/properties/util.hpp rename to src/ikarus/objects/properties/util.hpp index d9321c7..092296e 100644 --- a/src/objects/properties/util.hpp +++ b/src/ikarus/objects/properties/util.hpp @@ -4,48 +4,40 @@ #include +#include #include - -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include namespace ikarus::util { template T * create_property( struct IkarusProject * project, char const * name, - struct IkarusPropertySource * property_source, - typename T::value_type * default_value, + struct IkarusPropertyScope * property_scope, IkarusErrorData * error_out ) { IKARUS_FAIL_IF_NULL(project, nullptr); - IKARUS_FAIL_IF_NULL(name, nullptr); - IKARUS_FAIL_IF_NULL(property_source, nullptr); - IKARUS_FAIL_IF( - cppbase::is_empty_or_blank(name), - nullptr, - fmt::format("{} name cannot be empty or blank", boost::typeindex::type_id().pretty_name()), - IkarusErrorInfo_Client_InvalidInput - ) - IKARUS_FAIL_IF_NULL(default_value, nullptr); + IKARUS_FAIL_IF_NULL(property_scope, nullptr); + IKARUS_FAIL_IF_PROPERTY_SCOPE_INVALID(property_scope, nullptr); + IKARUS_FAIL_IF_NAME_INVALID(name, project, property_scope, nullptr); IKARUS_VTRYRV_OR_FAIL( IkarusId const id, nullptr, "failed to create property: {}", IkarusErrorInfo_Database_QueryFailed, - project->db->transact([name, property_source, default_value](auto * db) -> cppbase::Result { + project->db->transact([name, property_scope](auto * db) -> cppbase::Result { TRY(db->execute("INSERT INTO `objects`(`type`, `name`, `information`) VALUES(?, ?, ?)", IkarusObjectType_Property, name, "")); auto id = ikarus_id_from_data_and_type(db->last_insert_rowid(), IkarusObjectType_Property); TRY(db->execute( - "INSERT INTO `properties`(`id`, `type`, `source`, `default_value`) VALUES(?, ?, ?, ?)", + "INSERT INTO `properties`(`id`, `type`, `source`) VALUES(?, ?, ?)", id, T::PropertyType, - property_source->get_id(), - boost::json::serialize(default_value->to_json()) + property_scope->get_id() )); return cppbase::ok(id); }) diff --git a/src/ikarus/objects/util.hpp b/src/ikarus/objects/util.hpp new file mode 100644 index 0000000..29857cf --- /dev/null +++ b/src/ikarus/objects/util.hpp @@ -0,0 +1,125 @@ +#pragma once + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ikarus::util { + +template +[[nodiscard]] IkarusProject * object_get_project(O const * object, IkarusErrorData * error_out) { + IKARUS_FAIL_IF_NULL(object, nullptr); + IKARUS_FAIL_IF_OBJECT_MISSING(object, nullptr); + + return object->project; +} + +template +[[nodiscard]] char const * object_get_name(O const * object, IkarusErrorData * error_out) { + IKARUS_FAIL_IF_NULL(object, nullptr); + IKARUS_FAIL_IF_OBJECT_MISSING(object, nullptr); + + IKARUS_VTRYRV_OR_FAIL( + auto const ret, + nullptr, + fmt::runtime(fmt::format("unable to fetch {} name: {{}}", ikarus_object_type_to_string(ikarus_id_get_object_type(object->id)))), + IkarusErrorInfo_Database_QueryFailed, + object->project->db + ->template query_one(fmt::format("SELECT `name` FROM `{}` WHERE `id` = ?", object->get_table_name()), object->id) + ); + + return strdup(ret.data()); +} + +[[nodiscard]] inline bool name_is_unique( + IkarusProject const * project, + std::string_view name, + [[maybe_unused]] IkarusBlueprint const * blueprint, + IkarusErrorData * error_out +) { + IKARUS_VTRYRV_OR_FAIL( + bool const exists, + false, + "unable to check if blueprint name is unique", + IkarusErrorInfo_Database_QueryFailed, + project->db->query_one("SELECT EXISTS(SELECT 1 FROM `blueprints` WHERE `name` = ?)", name) + ); + + return exists; +} + +[[nodiscard]] inline bool name_is_unique( + IkarusProject const * project, + std::string_view name, + [[maybe_unused]] IkarusEntity const * entity, + IkarusErrorData * error_out +) { + IKARUS_VTRYRV_OR_FAIL( + bool const exists, + false, + "unable to check if entity name is unique", + IkarusErrorInfo_Database_QueryFailed, + project->db->query_one("SELECT EXISTS(SELECT 1 FROM `entities` WHERE `name` = ?)", name) + ); + + return exists; +} + +[[nodiscard]] inline bool +name_is_unique(IkarusProject const * project, std::string_view name, IkarusPropertyScope const * scope, IkarusErrorData * error_out) { + IKARUS_VTRYRV_OR_FAIL( + bool const exists, + false, + "unable to check if property name is unique", + IkarusErrorInfo_Database_QueryFailed, + project->db->query_one("SELECT EXISTS(SELECT 1 FROM `properties` WHERE `name` = ? AND `scope` = ?)", name, scope->get_id()) + ); + + return exists; +} + +[[nodiscard]] inline bool +name_is_unique(IkarusProject * project, std::string_view name, IkarusProperty const * property, IkarusErrorData * error_out) { + std::unique_ptr scope{ikarus_property_get_scope(property, error_out)}; + IKARUS_FAIL_IF_ERROR(false); + + return name_is_unique(project, name, scope.get(), error_out); +} + +#define IKARUS_FAIL_IF_NAME_INVALID(name, project, object, ret, ...) \ + IKARUS_FAIL_IF_NULL(name, ret); \ + IKARUS_FAIL_IF(cppbase::is_empty_or_blank(name), ret, "name must not be empty", IkarusErrorInfo_Client_InvalidInput); \ + IKARUS_FAIL_IF( \ + !ikarus::util::name_is_unique(project, name, object, error_out), \ + ret, \ + "name must be unique", \ + IkarusErrorInfo_Client_InvalidInput \ + ); \ + IKARUS_FAIL_IF_ERROR(ret); + +template +void object_set_name(O * object, char const * name, IkarusErrorData * error_out) { + IKARUS_FAIL_IF_NULL(object, ); + IKARUS_FAIL_IF_OBJECT_MISSING(object, ); + IKARUS_FAIL_IF_NULL(name, ); + IKARUS_FAIL_IF_NAME_INVALID(name, object->project, object, ); + + IKARUS_TRYRV_OR_FAIL( + , + fmt::runtime(fmt::format("unable to set {} name: {{}}", ikarus_object_type_to_string(ikarus_id_get_object_type(object->id)))), + IkarusErrorInfo_Database_QueryFailed, + object->project->db->execute(fmt::format("UPDATE `{}` SET `name` = ? WHERE `id` = ?", object->get_table_name()), name, object->id) + ); +} + +} // namespace ikarus::util diff --git a/src/persistence/migrations.hpp b/src/ikarus/persistence/migrations.hpp similarity index 90% rename from src/persistence/migrations.hpp rename to src/ikarus/persistence/migrations.hpp index c777e84..a46d1ee 100644 --- a/src/persistence/migrations.hpp +++ b/src/ikarus/persistence/migrations.hpp @@ -8,7 +8,7 @@ #include namespace ikarus { -CPPBASE_ASSET(m0_initial_layout, "persistence/migrations/m0_initial_layout.sql"); +CPPBASE_ASSET(m0_initial_layout, "ikarus/persistence/migrations/m0_initial_layout.sql"); class Migration : public sqlitecpp::Migration { public: diff --git a/src/persistence/migrations/m0_initial_layout.sql b/src/ikarus/persistence/migrations/m0_initial_layout.sql similarity index 61% rename from src/persistence/migrations/m0_initial_layout.sql rename to src/ikarus/persistence/migrations/m0_initial_layout.sql index 99ba61b..0031cee 100644 --- a/src/persistence/migrations/m0_initial_layout.sql +++ b/src/ikarus/persistence/migrations/m0_initial_layout.sql @@ -2,36 +2,29 @@ CREATE TABLE `objects` ( `do_not_access_rowid_alias` INTEGER PRIMARY KEY, `type` INT NOT NULL, - `id` INT GENERATED ALWAYS AS (`do_not_access_rowid_alias` | (`type` << 56)) VIRTUAL, - `name` TEXT NOT NULL, - `information` TEXT NOT NULL + `id` INT GENERATED ALWAYS AS (`do_not_access_rowid_alias` | (`type` << 56)) VIRTUAL UNIQUE ) STRICT; CREATE UNIQUE INDEX `object_id` ON `objects` (`id`); CREATE INDEX `object_type` ON `objects` (`type`); -CREATE VIRTUAL TABLE `objects_fts` USING fts5 -( - `name`, - `information`, - content='objects', - content_rowid='id', - tokenize="unicode61 remove_diacritics 2 tokenchars '-_'" -); - CREATE TABLE `entities` ( - `id` INT, + `id` INT, + `name` TEXT NOT NULL, PRIMARY KEY (`id`), + UNIQUE (`name`), FOREIGN KEY (`id`) REFERENCES `objects` (`id`) ON DELETE CASCADE ) WITHOUT ROWID, STRICT; CREATE TABLE `blueprints` ( - `id` INT, + `id` INT, + `name` TEXT NOT NULL, PRIMARY KEY (`id`), + UNIQUE (`name`), FOREIGN KEY (`id`) REFERENCES `objects` (`id`) ON DELETE CASCADE ) WITHOUT ROWID, STRICT; @@ -40,23 +33,22 @@ CREATE TABLE `entity_blueprint_links` `entity` INT NOT NULL, `blueprint` INT NOT NULL, - PRIMARY KEY (`entity`), - UNIQUE (`entity`, `blueprint`), + PRIMARY KEY (`entity`, `blueprint`), FOREIGN KEY (`entity`) REFERENCES `entities` (`id`) ON DELETE CASCADE, FOREIGN KEY (`blueprint`) REFERENCES `blueprints` (`id`) ON DELETE CASCADE ) WITHOUT ROWID, STRICT; -CREATE INDEX `entity_blueprints_blueprint` ON `entity_blueprint_links` (`blueprint`); - CREATE TABLE `properties` ( `id` INT, + `name` TEXT NOT NULL, `type` INT NOT NULL, `default_value` TEXT NOT NULL, `settings` TEXT NOT NULL, `source` INT NOT NULL, PRIMARY KEY (`id`), + UNIQUE(`source`, `name`), FOREIGN KEY (`id`) REFERENCES `objects` (`id`) ON DELETE CASCADE, FOREIGN KEY (`source`) REFERENCES `objects` (`id`) ON DELETE CASCADE ) WITHOUT ROWID, STRICT; @@ -64,24 +56,6 @@ CREATE TABLE `properties` CREATE INDEX `properties_type` ON `properties` (`type`); CREATE INDEX `properties_source` ON `properties` (`source`); -CREATE -VIRTUAL TABLE `property_default_value_fts` USING fts5 -( - `default_value`, - content='properties', - content_rowid='object_id', - tokenize="unicode61 remove_diacritics 2 tokenchars '-_'" -); - -CREATE -VIRTUAL TABLE `property_settings_fts` USING fts5 -( - `settings`, - content='properties', - content_rowid='object_id', - tokenize="unicode61 remove_diacritics 2 tokenchars '-_'" -); - CREATE TABLE `values` ( `entity` INT NOT NULL, @@ -92,11 +66,3 @@ CREATE TABLE `values` FOREIGN KEY (`entity`) REFERENCES `entities` (`id`) ON DELETE CASCADE, FOREIGN KEY (`property`) REFERENCES `properties` (`id`) ON DELETE CASCADE ) WITHOUT ROWID, STRICT; - -CREATE -VIRTUAL TABLE `values_fts` USING fts5 -( - `value`, - content='values', - tokenize="unicode61 remove_diacritics 2 tokenchars '-_'" -); diff --git a/src/persistence/project.cpp b/src/ikarus/persistence/project.cpp similarity index 95% rename from src/persistence/project.cpp rename to src/ikarus/persistence/project.cpp index 41ddbf7..6c460f7 100644 --- a/src/persistence/project.cpp +++ b/src/ikarus/persistence/project.cpp @@ -4,14 +4,14 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include IkarusProject::IkarusProject(std::string_view name, std::string_view path, std::unique_ptr && db): name{name}, diff --git a/src/persistence/project.hpp b/src/ikarus/persistence/project.hpp similarity index 100% rename from src/persistence/project.hpp rename to src/ikarus/persistence/project.hpp diff --git a/src/values/entity_property_value.cpp b/src/ikarus/values/entity_property_value.cpp similarity index 90% rename from src/values/entity_property_value.cpp rename to src/ikarus/values/entity_property_value.cpp index d1580ea..165383d 100644 --- a/src/values/entity_property_value.cpp +++ b/src/ikarus/values/entity_property_value.cpp @@ -1,6 +1,6 @@ -#include "values/entity_property_value.hpp" +#include "entity_property_value.hpp" -#include +#include IkarusEntity const * ikarus_entity_property_value_get_entity(IkarusEntityPropertyValue const * value, IkarusErrorData * error_out) { IKARUS_FAIL_IF_NULL(value, nullptr); diff --git a/src/values/entity_property_value.hpp b/src/ikarus/values/entity_property_value.hpp similarity index 100% rename from src/values/entity_property_value.hpp rename to src/ikarus/values/entity_property_value.hpp diff --git a/src/values/number_value.cpp b/src/ikarus/values/number_value.cpp similarity index 96% rename from src/values/number_value.cpp rename to src/ikarus/values/number_value.cpp index c339149..37eab49 100644 --- a/src/values/number_value.cpp +++ b/src/ikarus/values/number_value.cpp @@ -2,8 +2,8 @@ #include -#include -#include +#include +#include IkarusNumberValue::IkarusNumberValue(): IkarusValue{this} {} diff --git a/src/values/number_value.hpp b/src/ikarus/values/number_value.hpp similarity index 94% rename from src/values/number_value.hpp rename to src/ikarus/values/number_value.hpp index 8644d3e..6c6cb70 100644 --- a/src/values/number_value.hpp +++ b/src/ikarus/values/number_value.hpp @@ -3,7 +3,7 @@ #include #include -#include +#include struct IkarusNumberValue : IkarusValue { public: diff --git a/src/values/text_value.cpp b/src/ikarus/values/text_value.cpp similarity index 96% rename from src/values/text_value.cpp rename to src/ikarus/values/text_value.cpp index 64006ac..8235c6d 100644 --- a/src/values/text_value.cpp +++ b/src/ikarus/values/text_value.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include IkarusTextValue::IkarusTextValue(): IkarusValue{this} {} diff --git a/src/values/text_value.hpp b/src/ikarus/values/text_value.hpp similarity index 94% rename from src/values/text_value.hpp rename to src/ikarus/values/text_value.hpp index 40d3945..512bb8d 100644 --- a/src/values/text_value.hpp +++ b/src/ikarus/values/text_value.hpp @@ -2,7 +2,7 @@ #include -#include +#include struct IkarusTextValue : IkarusValue { public: diff --git a/src/values/toggle_value.cpp b/src/ikarus/values/toggle_value.cpp similarity index 96% rename from src/values/toggle_value.cpp rename to src/ikarus/values/toggle_value.cpp index dabbe00..7bec1f2 100644 --- a/src/values/toggle_value.cpp +++ b/src/ikarus/values/toggle_value.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include IkarusToggleValue::IkarusToggleValue(): IkarusValue{this} {} diff --git a/src/values/toggle_value.hpp b/src/ikarus/values/toggle_value.hpp similarity index 94% rename from src/values/toggle_value.hpp rename to src/ikarus/values/toggle_value.hpp index 20a5dd6..6882ecc 100644 --- a/src/values/toggle_value.hpp +++ b/src/ikarus/values/toggle_value.hpp @@ -2,7 +2,7 @@ #include -#include +#include struct IkarusToggleValue : IkarusValue { public: diff --git a/src/values/value.cpp b/src/ikarus/values/value.cpp similarity index 96% rename from src/values/value.cpp rename to src/ikarus/values/value.cpp index 812b2c8..bbea7f3 100644 --- a/src/values/value.cpp +++ b/src/ikarus/values/value.cpp @@ -10,11 +10,10 @@ #include #include - -#include -#include -#include -#include +#include +#include +#include +#include IkarusValue::IkarusValue(Data data): data(data) {} diff --git a/src/values/value.hpp b/src/ikarus/values/value.hpp similarity index 91% rename from src/values/value.hpp rename to src/ikarus/values/value.hpp index 94b423d..1e5791b 100644 --- a/src/values/value.hpp +++ b/src/ikarus/values/value.hpp @@ -5,8 +5,8 @@ #include -#include -#include +#include +#include struct IkarusValue { public: @@ -41,7 +41,7 @@ struct fmt::formatter { return ctx.end(); } - constexpr static auto format([[maybe_unused]]IkarusValue::FromJsonError const & error, fmt::format_context & ctx) { + constexpr static auto format([[maybe_unused]] IkarusValue::FromJsonError const & error, fmt::format_context & ctx) { return fmt::format_to(ctx.out(), "unable to parse ikarus value JSON"); } }; diff --git a/src/values/value_base.hpp b/src/ikarus/values/value_base.hpp similarity index 100% rename from src/values/value_base.hpp rename to src/ikarus/values/value_base.hpp diff --git a/src/objects/object.cpp b/src/objects/object.cpp deleted file mode 100644 index e8a3353..0000000 --- a/src/objects/object.cpp +++ /dev/null @@ -1,170 +0,0 @@ -#include "object.hpp" - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include - -IkarusObject::IkarusObject(IkarusProject * project, IkarusId id): - project{project}, - id{id} {} - -IkarusProject * ikarus_object_get_project(IkarusObject const * object, IkarusErrorData * error_out) { - IKARUS_FAIL_IF_NULL(object, nullptr); - IKARUS_FAIL_IF_OBJECT_MISSING(object, nullptr); - - return object->project; -} - -char const * ikarus_object_get_name(IkarusObject const * object, IkarusErrorData * error_out) { - IKARUS_FAIL_IF_NULL(object, nullptr); - IKARUS_FAIL_IF_OBJECT_MISSING(object, nullptr); - - IKARUS_VTRYRV_OR_FAIL( - std::string ret, - nullptr, - "unable to get object name: {}", - IkarusErrorInfo_Database_QueryFailed, - object->project->db->template query_one("SELECT `name` FROM `objects` WHERE `id` = ?", object->id) - ); - - return strdup(ret.data()); -} - -void ikarus_object_set_name(IkarusObject * object, char const * name, IkarusErrorData * error_out) { - IKARUS_FAIL_IF_NULL(object, ); - IKARUS_FAIL_IF_OBJECT_MISSING(object, ); - IKARUS_FAIL_IF_NULL(name, ); - IKARUS_FAIL_IF(cppbase::is_empty_or_blank(name), , "name must not be empty", IkarusErrorInfo_Client_InvalidInput); - - IKARUS_TRYRV_OR_FAIL( - , - "unable to set object name: {}", - IkarusErrorInfo_Database_QueryFailed, - object->project->db->template execute("UPDATE `objects` SET `name` = ? WHERE `id` = ?", name, object->id) - ); -} - -char const * ikarus_object_get_information(IkarusObject const * object, IkarusErrorData * error_out) { - IKARUS_FAIL_IF_NULL(object, nullptr); - IKARUS_FAIL_IF_OBJECT_MISSING(object, nullptr); - - IKARUS_VTRYRV_OR_FAIL( - std::string ret, - nullptr, - "unable to get object information: {}", - IkarusErrorInfo_Database_QueryFailed, - object->project->db->template query_one("SELECT `information` FROM `objects` WHERE `id` = ?", object->id) - ); - - return strdup(ret.data()); -} - -void ikarus_object_set_information(IkarusObject * object, char const * information, IkarusErrorData * error_out) { - IKARUS_FAIL_IF_NULL(object, ); - IKARUS_FAIL_IF_OBJECT_MISSING(object, ); - IKARUS_FAIL_IF_NULL(information, ); - IKARUS_FAIL_IF(cppbase::is_empty_or_blank(information), , "information must not be empty", IkarusErrorInfo_Client_InvalidInput); - - IKARUS_TRYRV_OR_FAIL( - , - "unable to set object information: {}", - IkarusErrorInfo_Database_QueryFailed, - object->project->db->template execute("UPDATE `objects` SET `information` = ? WHERE `id` = ?", information, object->id) - ); -} - -bool ikarus_object_is_equal(IkarusObject const * lhs, IkarusObject const * rhs, IkarusErrorData * error_out) { - IKARUS_FAIL_IF_NULL(lhs, false); - IKARUS_FAIL_IF_OBJECT_MISSING(lhs, false); - IKARUS_FAIL_IF_NULL(rhs, false); - IKARUS_FAIL_IF_OBJECT_MISSING(rhs, false); - - return lhs->id == rhs->id; -} - -void ikarus_object_visit( - IkarusObject * object, - void (*blueprint_visitor)(struct IkarusBlueprint *, void *), - void (*property_visitor)(struct IkarusProperty *, void *), - void (*entity_visitor)(struct IkarusEntity *, void *), - void * data, - IkarusErrorData * error_out -) { - struct Data { - void (*blueprint_visitor)(struct IkarusBlueprint *, void *); - void (*property_visitor)(struct IkarusProperty *, void *); - void (*entity_visitor)(struct IkarusEntity *, void *); - void * data; - }; - - Data passthru_data{ - blueprint_visitor, - property_visitor, - entity_visitor, - data, - }; - - ikarus_object_visit_const( - object, - [](IkarusBlueprint const * blueprint, void * data) { - auto const * passthru_data = static_cast(data); - passthru_data->blueprint_visitor(const_cast(blueprint), passthru_data->data); - }, - [](IkarusProperty const * property, void * data) { - auto const * passthru_data = static_cast(data); - passthru_data->property_visitor(const_cast(property), passthru_data->data); - }, - [](IkarusEntity const * entity, void * data) { - auto const * passthru_data = static_cast(data); - passthru_data->entity_visitor(const_cast(entity), passthru_data->data); - }, - &passthru_data, - error_out - ); -} - -void ikarus_object_visit_const( - IkarusObject const * object, - void (*blueprint_visitor)(struct IkarusBlueprint const *, void *), - void (*property_visitor)(struct IkarusProperty const *, void *), - void (*entity_visitor)(struct IkarusEntity const *, void *), - void * data, - IkarusErrorData * error_out -) { - IKARUS_FAIL_IF_NULL(object, ); - IKARUS_FAIL_IF_OBJECT_MISSING(object, ); - - switch (ikarus_id_get_object_type(object->id)) { - case IkarusObjectType_Entity: { - auto const * entity = dynamic_cast(object); - IKARUS_FAIL_IF(entity == nullptr, , "object with entity id wasn't a entity", IkarusErrorInfo_LibIkarus_InvalidState); - entity_visitor(entity, data); - } - case IkarusObjectType_Blueprint: { - auto const * blueprint = dynamic_cast(object); - IKARUS_FAIL_IF(blueprint == nullptr, , "object with blueprint id wasn't a blueprint", IkarusErrorInfo_LibIkarus_InvalidState); - blueprint_visitor(blueprint, data); - } - case IkarusObjectType_Property: { - auto const * property = dynamic_cast(object); - IKARUS_FAIL_IF(property == nullptr, , "object with property id wasn't a property", IkarusErrorInfo_LibIkarus_InvalidState); - property_visitor(property, data); - } - default: { - IKARUS_FAIL( - , - fmt::format("unknown object type: {}", ikarus_object_type_to_string(ikarus_id_get_object_type(object->id))), - IkarusErrorInfo_LibIkarus_InvalidState - ); - } - } -} diff --git a/src/objects/properties/property_source.hpp b/src/objects/properties/property_source.hpp deleted file mode 100644 index 672021d..0000000 --- a/src/objects/properties/property_source.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include -#include -#include - -struct IkarusPropertySource { -public: - using Data = boost::variant2::variant; - -public: - explicit IkarusPropertySource(Data data); - - IkarusPropertySource(IkarusPropertySource const &) = default; - IkarusPropertySource(IkarusPropertySource &&) = default; - - IkarusPropertySource & operator=(IkarusPropertySource const &) = default; - IkarusPropertySource & operator=(IkarusPropertySource &&) = default; - - virtual ~IkarusPropertySource() = default; - -public: - [[nodiscard]] IkarusId get_id() const; - -public: - Data data; -}; diff --git a/vendor/sqlitecpp b/vendor/sqlitecpp index 77e7260..eadf323 160000 --- a/vendor/sqlitecpp +++ b/vendor/sqlitecpp @@ -1 +1 @@ -Subproject commit 77e726036b52fff6f82ff2d44081f05aee7408a8 +Subproject commit eadf3237bfa853763b332777e9dc0f16df8cca71