diff --git a/.clang-format b/.clang-format index 7d8a46d..85337cc 100644 --- a/.clang-format +++ b/.clang-format @@ -64,9 +64,9 @@ BreakBeforeInlineASMColon: OnlyMultiline BreakBeforeTernaryOperators: false BreakConstructorInitializers: AfterColon BreakInheritanceList: AfterColon -BreakStringLiterals: false +BreakStringLiterals: true -ColumnLimit: 140 +ColumnLimit: 80 CommentPragmas: '^\\.+' CompactNamespaces: false ConstructorInitializerIndentWidth: 4 @@ -117,7 +117,7 @@ IndentCaseBlocks: false IndentCaseLabels: false IndentExternBlock: NoIndent IndentGotoLabels: false -IndentPPDirectives: None +IndentPPDirectives: BeforeHash IndentRequiresClause: true IndentWidth: 4 IndentWrappedFunctionNames: false diff --git a/CMakeLists.txt b/CMakeLists.txt index 92e04cc..8a16b08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,11 @@ add_library( ${SOURCE_FILES} ) +add_dependencies( + ikarus + flatbuffer_headers +) + set_target_properties( ikarus PROPERTIES CXX_STANDARD 23 @@ -71,9 +76,4 @@ if (LIBIKARUS_BUILD_DOCS) ikarus libikarus_docs ) - - add_dependencies( - libikarus_tests - libikarus_docs - ) endif () diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 2e91ee9..e3043c7 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -6,3 +6,4 @@ file( set(INCLUDE_FILES ${FILES} PARENT_SCOPE) +add_subdirectory(ikarus) \ No newline at end of file diff --git a/include/ikarus/CMakeLists.txt b/include/ikarus/CMakeLists.txt new file mode 100644 index 0000000..cd981b8 --- /dev/null +++ b/include/ikarus/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(models) \ No newline at end of file diff --git a/include/ikarus/errors.h b/include/ikarus/errors.h index a7a4fb4..926f07d 100644 --- a/include/ikarus/errors.h +++ b/include/ikarus/errors.h @@ -4,11 +4,10 @@ /// \author Folling #include -#include /// \addtogroup errors Errors /// \brief Error handling within libikarus -/// \details Functions in Ikarus may fail, in which case they have an out parameter for the error. +/// \details Functions in Ikarus may fail. To report the type of failure all functions have an out parameter for the error. /// Upon erring the function will store relevant information about the error in the out parameter. /// If the out parameter is null nothing will be stored. This is not recommended as it essentially ignores errors. /// For the sake of simplicity we have avoided mechanisms that "force" clients to handle errors. @@ -93,7 +92,7 @@ enum IkarusErrorInfo { }; /// \brief The maximum length of an error message. -size_t const IKARUS_ERROR_DATA_MAX_MESSAGE_LIMIT = 128; +#define IKARUS_ERROR_DATA_MAX_MESSAGE_LIMIT 128 /// \brief The data stored for an error struct IkarusErrorData { diff --git a/include/ikarus/global.h b/include/ikarus/global.h deleted file mode 100644 index 4665863..0000000 --- a/include/ikarus/global.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -/// \file global.h -/// \author Folling - -#include - -/// \defgroup global Global -/// \brief Information relevant to the entire library. -/// @{ - -IKARUS_BEGIN_HEADER - -/// \brief Frees a pointer allocated by ikarus. Every pointer returned by a function must be freed using this function -/// unless explicitly stated otherwise. -IKA_API void ikarus_free(void * ptr); - -IKARUS_END_HEADER - -/// @} diff --git a/include/ikarus/id.h b/include/ikarus/id.h deleted file mode 100644 index c76e341..0000000 --- a/include/ikarus/id.h +++ /dev/null @@ -1,46 +0,0 @@ -// IMPLEMENTATION_DETAIL_DATABASE - -/// \file id.h -/// \author Folling - -/// \privatesection - -#pragma once - -#include -#include -#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: -/// - first bit: ignored, technically we could use it, but SQLite doesn't support u64 integers. -/// To avoid ordering fiascos and potential index performance degradation we just skip the first bit. -/// - next 7 bits: #IkarusObjectType -/// - 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. -/// To avoid ordering fiascos and potential index performance degradation we just skip the first bit. -/// - next 7 bits: #IkarusObjectType -/// - last 56 bits: incremented counter generated by the database -typedef int64_t IkarusId; - -/// \brief Creates an id from the given data and type. -/// \param data The data to use for the id. -/// \param type The type to use for the id. -/// \return The created id. -IKA_API IkarusId ikarus_id_from_data_and_type(int64_t data, IkarusObjectType type); - -/// \brief Fetches the object type of the given id. -/// \param id The id to fetch the object type for. -/// \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/macros.h b/include/ikarus/macros.h index fdc6510..e7714dc 100644 --- a/include/ikarus/macros.h +++ b/include/ikarus/macros.h @@ -1,27 +1,23 @@ #pragma once -#if defined(__unix__) - -#define IKA_OS_FAMILY_UNIX -#define IKA_API __attribute__((visibility("default"))) - -#if defined(linux) -#define IKA_OS_LINUX -#endif - -#elif defined(_WIN32) || defined(WIN32) -#define IKA_OS_WIN -#define IKA_API __declspec(dllexport) -#endif - -#ifndef IKA_API #define IKA_API + +#if defined(__unix__) + #define IKA_OS_FAMILY_UNIX + #define IKA_API __attribute__((visibility("default"))) + + #if defined(linux) + #define IKA_OS_LINUX + #endif +#elif defined(_WIN32) + #define IKA_OS_WIN + #define IKA_API __declspec(dllexport) #endif #ifdef __cplusplus -#define IKARUS_BEGIN_HEADER extern "C" { -#define IKARUS_END_HEADER } + #define IKARUS_BEGIN_HEADER extern "C" { + #define IKARUS_END_HEADER } #else -#define IKARUS_BEGIN_HEADER -#define IKARUS_END_HEADER + #define IKARUS_BEGIN_HEADER + #define IKARUS_END_HEADER #endif diff --git a/include/ikarus/models/CMakeLists.txt b/include/ikarus/models/CMakeLists.txt new file mode 100644 index 0000000..e3d8758 --- /dev/null +++ b/include/ikarus/models/CMakeLists.txt @@ -0,0 +1,41 @@ +file( + GLOB_RECURSE + FLATBUFFER_SOURCES + "*.fbs" +) + +foreach (FLATBUFFER_SOURCE IN LISTS ${FLATBUFFER_SOURCES}) + cmake_path( + GET + ${FLATBUFFER_SOURCE} + FILENAME + FLATBUFFER_SOURCE_NAME + ) + + string( + CONCAT + FLATBUFFER_GENERATED_SOURCE_NAME + ${FLATBUFFER_SOURCE_NAME} + "_generated" + ) + + cmake_path( + REPLACE_EXTENSION + ${FLATBUFFER_GENERATED_SOURCE_NAME} + ".h" + OUTPUT_VARIABLE + FLATBUFFER_GENERATED_HEADER + ) + + list(APPEND FLATBUFFER_GENERATED_HEADERS ${FLATBUFFER_GENERATED_HEADER}) +endforeach () + +add_custom_target( + flatbuffer_headers + COMMENT "Generating flatbuffer headers" + DEPENDS ${FLATBUFFER_SOURCES} + BYPRODUCTS ${FLATBUFFER_GENERATED_HEADERS} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND flatc --cpp --cpp-std "c++17" ${FLATBUFFER_SOURCES} + VERBATIM +) diff --git a/include/ikarus/models/blueprint.fbs b/include/ikarus/models/blueprint.fbs new file mode 100644 index 0000000..fb782d8 --- /dev/null +++ b/include/ikarus/models/blueprint.fbs @@ -0,0 +1,12 @@ +include "property.fbs"; + +namespace Ikarus; + +table Blueprint { + id: int64; + name: string; + description: string; + tags: [string]; +} + +root_type Blueprint; diff --git a/include/ikarus/models/blueprint_generated.h b/include/ikarus/models/blueprint_generated.h new file mode 100644 index 0000000..b70924b --- /dev/null +++ b/include/ikarus/models/blueprint_generated.h @@ -0,0 +1,153 @@ +// automatically generated by the FlatBuffers compiler, do not modify + + +#ifndef FLATBUFFERS_GENERATED_BLUEPRINT_IKARUS_H_ +#define FLATBUFFERS_GENERATED_BLUEPRINT_IKARUS_H_ + +#include "flatbuffers/flatbuffers.h" + +// Ensure the included flatbuffers.h is the same version as when this file was +// generated, otherwise it may not be compatible. +static_assert(FLATBUFFERS_VERSION_MAJOR == 24 && + FLATBUFFERS_VERSION_MINOR == 3 && + FLATBUFFERS_VERSION_REVISION == 25, + "Non-compatible flatbuffers version included"); + +#include "property_generated.h" + +namespace Ikarus { + +struct Blueprint; +struct BlueprintBuilder; + +struct Blueprint FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef BlueprintBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4, + VT_NAME = 6, + VT_DESCRIPTION = 8, + VT_TAGS = 10 + }; + int64_t id() const { + return GetField(VT_ID, 0); + } + const ::flatbuffers::String *name() const { + return GetPointer(VT_NAME); + } + const ::flatbuffers::String *description() const { + return GetPointer(VT_DESCRIPTION); + } + const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *tags() const { + return GetPointer> *>(VT_TAGS); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_ID, 8) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyOffset(verifier, VT_DESCRIPTION) && + verifier.VerifyString(description()) && + VerifyOffset(verifier, VT_TAGS) && + verifier.VerifyVector(tags()) && + verifier.VerifyVectorOfStrings(tags()) && + verifier.EndTable(); + } +}; + +struct BlueprintBuilder { + typedef Blueprint Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_id(int64_t id) { + fbb_.AddElement(Blueprint::VT_ID, id, 0); + } + void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { + fbb_.AddOffset(Blueprint::VT_NAME, name); + } + void add_description(::flatbuffers::Offset<::flatbuffers::String> description) { + fbb_.AddOffset(Blueprint::VT_DESCRIPTION, description); + } + void add_tags(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> tags) { + fbb_.AddOffset(Blueprint::VT_TAGS, tags); + } + explicit BlueprintBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateBlueprint( + ::flatbuffers::FlatBufferBuilder &_fbb, + int64_t id = 0, + ::flatbuffers::Offset<::flatbuffers::String> name = 0, + ::flatbuffers::Offset<::flatbuffers::String> description = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> tags = 0) { + BlueprintBuilder builder_(_fbb); + builder_.add_id(id); + builder_.add_tags(tags); + builder_.add_description(description); + builder_.add_name(name); + return builder_.Finish(); +} + +struct Blueprint::Traits { + using type = Blueprint; + static auto constexpr Create = CreateBlueprint; +}; + +inline ::flatbuffers::Offset CreateBlueprintDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + int64_t id = 0, + const char *name = nullptr, + const char *description = nullptr, + const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *tags = nullptr) { + auto name__ = name ? _fbb.CreateString(name) : 0; + auto description__ = description ? _fbb.CreateString(description) : 0; + auto tags__ = tags ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*tags) : 0; + return Ikarus::CreateBlueprint( + _fbb, + id, + name__, + description__, + tags__); +} + +inline const Ikarus::Blueprint *GetBlueprint(const void *buf) { + return ::flatbuffers::GetRoot(buf); +} + +inline const Ikarus::Blueprint *GetSizePrefixedBlueprint(const void *buf) { + return ::flatbuffers::GetSizePrefixedRoot(buf); +} + +inline bool VerifyBlueprintBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifyBuffer(nullptr); +} + +inline bool VerifySizePrefixedBlueprintBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifySizePrefixedBuffer(nullptr); +} + +inline void FinishBlueprintBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.Finish(root); +} + +inline void FinishSizePrefixedBlueprintBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.FinishSizePrefixed(root); +} + +} // namespace Ikarus + +#endif // FLATBUFFERS_GENERATED_BLUEPRINT_IKARUS_H_ diff --git a/include/ikarus/models/entity.fbs b/include/ikarus/models/entity.fbs new file mode 100644 index 0000000..bce2ff5 --- /dev/null +++ b/include/ikarus/models/entity.fbs @@ -0,0 +1,26 @@ +include "value.fbs"; +include "property.fbs"; +include "blueprint.fbs"; + +namespace Ikarus; + +table NamedValue { + name: string (key); + value: Ikarus.Value.Value; +} + +table PropertyValue { + property_id: int64 (key); + data: Ikarus.Value.Data; +} + +table Entity { + id: int64; + name: string; + description: string; + tags: [string]; + values: [NamedValue]; + property_values: [PropertyValue]; +} + +root_type Entity; diff --git a/include/ikarus/models/entity_generated.h b/include/ikarus/models/entity_generated.h new file mode 100644 index 0000000..e253038 --- /dev/null +++ b/include/ikarus/models/entity_generated.h @@ -0,0 +1,398 @@ +// automatically generated by the FlatBuffers compiler, do not modify + + +#ifndef FLATBUFFERS_GENERATED_ENTITY_IKARUS_H_ +#define FLATBUFFERS_GENERATED_ENTITY_IKARUS_H_ + +#include "flatbuffers/flatbuffers.h" + +// Ensure the included flatbuffers.h is the same version as when this file was +// generated, otherwise it may not be compatible. +static_assert(FLATBUFFERS_VERSION_MAJOR == 24 && + FLATBUFFERS_VERSION_MINOR == 3 && + FLATBUFFERS_VERSION_REVISION == 25, + "Non-compatible flatbuffers version included"); + +#include "blueprint_generated.h" +#include "property_generated.h" +#include "value_generated.h" + +namespace Ikarus { + +struct NamedValue; +struct NamedValueBuilder; + +struct PropertyValue; +struct PropertyValueBuilder; + +struct Entity; +struct EntityBuilder; + +struct NamedValue FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef NamedValueBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NAME = 4, + VT_VALUE = 6 + }; + const ::flatbuffers::String *name() const { + return GetPointer(VT_NAME); + } + bool KeyCompareLessThan(const NamedValue * const o) const { + return *name() < *o->name(); + } + int KeyCompareWithValue(const char *_name) const { + return strcmp(name()->c_str(), _name); + } + template + int KeyCompareWithValue(const StringType& _name) const { + if (name()->c_str() < _name) return -1; + if (_name < name()->c_str()) return 1; + return 0; + } + const Ikarus::Value::Value *value() const { + return GetPointer(VT_VALUE); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffsetRequired(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyOffset(verifier, VT_VALUE) && + verifier.VerifyTable(value()) && + verifier.EndTable(); + } +}; + +struct NamedValueBuilder { + typedef NamedValue Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { + fbb_.AddOffset(NamedValue::VT_NAME, name); + } + void add_value(::flatbuffers::Offset value) { + fbb_.AddOffset(NamedValue::VT_VALUE, value); + } + explicit NamedValueBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, NamedValue::VT_NAME); + return o; + } +}; + +inline ::flatbuffers::Offset CreateNamedValue( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::String> name = 0, + ::flatbuffers::Offset value = 0) { + NamedValueBuilder builder_(_fbb); + builder_.add_value(value); + builder_.add_name(name); + return builder_.Finish(); +} + +struct NamedValue::Traits { + using type = NamedValue; + static auto constexpr Create = CreateNamedValue; +}; + +inline ::flatbuffers::Offset CreateNamedValueDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, + ::flatbuffers::Offset value = 0) { + auto name__ = name ? _fbb.CreateString(name) : 0; + return Ikarus::CreateNamedValue( + _fbb, + name__, + value); +} + +struct PropertyValue FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef PropertyValueBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_PROPERTY_ID = 4, + VT_DATA_TYPE = 6, + VT_DATA = 8 + }; + int64_t property_id() const { + return GetField(VT_PROPERTY_ID, 0); + } + bool KeyCompareLessThan(const PropertyValue * const o) const { + return property_id() < o->property_id(); + } + int KeyCompareWithValue(int64_t _property_id) const { + return static_cast(property_id() > _property_id) - static_cast(property_id() < _property_id); + } + Ikarus::Value::Data data_type() const { + return static_cast(GetField(VT_DATA_TYPE, 0)); + } + const void *data() const { + return GetPointer(VT_DATA); + } + template const T *data_as() const; + const Ikarus::Value::ToggleDataPoint *data_as_ToggleDataPoint() const { + return data_type() == Ikarus::Value::Data::ToggleDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::NumberDataPoint *data_as_NumberDataPoint() const { + return data_type() == Ikarus::Value::Data::NumberDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::TextDataPoint *data_as_TextDataPoint() const { + return data_type() == Ikarus::Value::Data::TextDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::SimpleData *data_as_SimpleData() const { + return data_type() == Ikarus::Value::Data::SimpleData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::CombinedData *data_as_CombinedData() const { + return data_type() == Ikarus::Value::Data::CombinedData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::ListData *data_as_ListData() const { + return data_type() == Ikarus::Value::Data::ListData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::ComplexData *data_as_ComplexData() const { + return data_type() == Ikarus::Value::Data::ComplexData ? static_cast(data()) : nullptr; + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_PROPERTY_ID, 8) && + VerifyField(verifier, VT_DATA_TYPE, 1) && + VerifyOffset(verifier, VT_DATA) && + VerifyData(verifier, data(), data_type()) && + verifier.EndTable(); + } +}; + +template<> inline const Ikarus::Value::ToggleDataPoint *PropertyValue::data_as() const { + return data_as_ToggleDataPoint(); +} + +template<> inline const Ikarus::Value::NumberDataPoint *PropertyValue::data_as() const { + return data_as_NumberDataPoint(); +} + +template<> inline const Ikarus::Value::TextDataPoint *PropertyValue::data_as() const { + return data_as_TextDataPoint(); +} + +template<> inline const Ikarus::Value::SimpleData *PropertyValue::data_as() const { + return data_as_SimpleData(); +} + +template<> inline const Ikarus::Value::CombinedData *PropertyValue::data_as() const { + return data_as_CombinedData(); +} + +template<> inline const Ikarus::Value::ListData *PropertyValue::data_as() const { + return data_as_ListData(); +} + +template<> inline const Ikarus::Value::ComplexData *PropertyValue::data_as() const { + return data_as_ComplexData(); +} + +struct PropertyValueBuilder { + typedef PropertyValue Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_property_id(int64_t property_id) { + fbb_.AddElement(PropertyValue::VT_PROPERTY_ID, property_id, 0); + } + void add_data_type(Ikarus::Value::Data data_type) { + fbb_.AddElement(PropertyValue::VT_DATA_TYPE, static_cast(data_type), 0); + } + void add_data(::flatbuffers::Offset data) { + fbb_.AddOffset(PropertyValue::VT_DATA, data); + } + explicit PropertyValueBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreatePropertyValue( + ::flatbuffers::FlatBufferBuilder &_fbb, + int64_t property_id = 0, + Ikarus::Value::Data data_type = Ikarus::Value::Data::NONE, + ::flatbuffers::Offset data = 0) { + PropertyValueBuilder builder_(_fbb); + builder_.add_property_id(property_id); + builder_.add_data(data); + builder_.add_data_type(data_type); + return builder_.Finish(); +} + +struct PropertyValue::Traits { + using type = PropertyValue; + static auto constexpr Create = CreatePropertyValue; +}; + +struct Entity FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef EntityBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4, + VT_NAME = 6, + VT_DESCRIPTION = 8, + VT_TAGS = 10, + VT_VALUES = 12, + VT_PROPERTY_VALUES = 14 + }; + int64_t id() const { + return GetField(VT_ID, 0); + } + const ::flatbuffers::String *name() const { + return GetPointer(VT_NAME); + } + const ::flatbuffers::String *description() const { + return GetPointer(VT_DESCRIPTION); + } + const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *tags() const { + return GetPointer> *>(VT_TAGS); + } + const ::flatbuffers::Vector<::flatbuffers::Offset> *values() const { + return GetPointer> *>(VT_VALUES); + } + const ::flatbuffers::Vector<::flatbuffers::Offset> *property_values() const { + return GetPointer> *>(VT_PROPERTY_VALUES); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_ID, 8) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyOffset(verifier, VT_DESCRIPTION) && + verifier.VerifyString(description()) && + VerifyOffset(verifier, VT_TAGS) && + verifier.VerifyVector(tags()) && + verifier.VerifyVectorOfStrings(tags()) && + VerifyOffset(verifier, VT_VALUES) && + verifier.VerifyVector(values()) && + verifier.VerifyVectorOfTables(values()) && + VerifyOffset(verifier, VT_PROPERTY_VALUES) && + verifier.VerifyVector(property_values()) && + verifier.VerifyVectorOfTables(property_values()) && + verifier.EndTable(); + } +}; + +struct EntityBuilder { + typedef Entity Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_id(int64_t id) { + fbb_.AddElement(Entity::VT_ID, id, 0); + } + void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { + fbb_.AddOffset(Entity::VT_NAME, name); + } + void add_description(::flatbuffers::Offset<::flatbuffers::String> description) { + fbb_.AddOffset(Entity::VT_DESCRIPTION, description); + } + void add_tags(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> tags) { + fbb_.AddOffset(Entity::VT_TAGS, tags); + } + void add_values(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> values) { + fbb_.AddOffset(Entity::VT_VALUES, values); + } + void add_property_values(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> property_values) { + fbb_.AddOffset(Entity::VT_PROPERTY_VALUES, property_values); + } + explicit EntityBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateEntity( + ::flatbuffers::FlatBufferBuilder &_fbb, + int64_t id = 0, + ::flatbuffers::Offset<::flatbuffers::String> name = 0, + ::flatbuffers::Offset<::flatbuffers::String> description = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> tags = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> values = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> property_values = 0) { + EntityBuilder builder_(_fbb); + builder_.add_id(id); + builder_.add_property_values(property_values); + builder_.add_values(values); + builder_.add_tags(tags); + builder_.add_description(description); + builder_.add_name(name); + return builder_.Finish(); +} + +struct Entity::Traits { + using type = Entity; + static auto constexpr Create = CreateEntity; +}; + +inline ::flatbuffers::Offset CreateEntityDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + int64_t id = 0, + const char *name = nullptr, + const char *description = nullptr, + const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *tags = nullptr, + std::vector<::flatbuffers::Offset> *values = nullptr, + std::vector<::flatbuffers::Offset> *property_values = nullptr) { + auto name__ = name ? _fbb.CreateString(name) : 0; + auto description__ = description ? _fbb.CreateString(description) : 0; + auto tags__ = tags ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*tags) : 0; + auto values__ = values ? _fbb.CreateVectorOfSortedTables(values) : 0; + auto property_values__ = property_values ? _fbb.CreateVectorOfSortedTables(property_values) : 0; + return Ikarus::CreateEntity( + _fbb, + id, + name__, + description__, + tags__, + values__, + property_values__); +} + +inline const Ikarus::Entity *GetEntity(const void *buf) { + return ::flatbuffers::GetRoot(buf); +} + +inline const Ikarus::Entity *GetSizePrefixedEntity(const void *buf) { + return ::flatbuffers::GetSizePrefixedRoot(buf); +} + +inline bool VerifyEntityBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifyBuffer(nullptr); +} + +inline bool VerifySizePrefixedEntityBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifySizePrefixedBuffer(nullptr); +} + +inline void FinishEntityBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.Finish(root); +} + +inline void FinishSizePrefixedEntityBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.FinishSizePrefixed(root); +} + +} // namespace Ikarus + +#endif // FLATBUFFERS_GENERATED_ENTITY_IKARUS_H_ diff --git a/include/ikarus/models/property.fbs b/include/ikarus/models/property.fbs new file mode 100644 index 0000000..8a96bb2 --- /dev/null +++ b/include/ikarus/models/property.fbs @@ -0,0 +1,14 @@ +include "value.fbs"; + +namespace Ikarus; + +table Property { + id: int64; + name: string; + description: string; + tags: [string]; + value_schema: Ikarus.Value.Schema; + default_value: Ikarus.Value.Data; +} + +root_type Property; diff --git a/include/ikarus/models/property_generated.h b/include/ikarus/models/property_generated.h new file mode 100644 index 0000000..1111bee --- /dev/null +++ b/include/ikarus/models/property_generated.h @@ -0,0 +1,289 @@ +// automatically generated by the FlatBuffers compiler, do not modify + + +#ifndef FLATBUFFERS_GENERATED_PROPERTY_IKARUS_H_ +#define FLATBUFFERS_GENERATED_PROPERTY_IKARUS_H_ + +#include "flatbuffers/flatbuffers.h" + +// Ensure the included flatbuffers.h is the same version as when this file was +// generated, otherwise it may not be compatible. +static_assert(FLATBUFFERS_VERSION_MAJOR == 24 && + FLATBUFFERS_VERSION_MINOR == 3 && + FLATBUFFERS_VERSION_REVISION == 25, + "Non-compatible flatbuffers version included"); + +#include "value_generated.h" + +namespace Ikarus { + +struct Property; +struct PropertyBuilder; + +struct Property FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef PropertyBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4, + VT_NAME = 6, + VT_DESCRIPTION = 8, + VT_TAGS = 10, + VT_VALUE_SCHEMA_TYPE = 12, + VT_VALUE_SCHEMA = 14, + VT_DEFAULT_VALUE_TYPE = 16, + VT_DEFAULT_VALUE = 18 + }; + int64_t id() const { + return GetField(VT_ID, 0); + } + const ::flatbuffers::String *name() const { + return GetPointer(VT_NAME); + } + const ::flatbuffers::String *description() const { + return GetPointer(VT_DESCRIPTION); + } + const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *tags() const { + return GetPointer> *>(VT_TAGS); + } + Ikarus::Value::Schema value_schema_type() const { + return static_cast(GetField(VT_VALUE_SCHEMA_TYPE, 0)); + } + const void *value_schema() const { + return GetPointer(VT_VALUE_SCHEMA); + } + template const T *value_schema_as() const; + const Ikarus::Value::ConstantSchema *value_schema_as_ConstantSchema() const { + return value_schema_type() == Ikarus::Value::Schema::ConstantSchema ? static_cast(value_schema()) : nullptr; + } + const Ikarus::Value::SimpleSchema *value_schema_as_SimpleSchema() const { + return value_schema_type() == Ikarus::Value::Schema::SimpleSchema ? static_cast(value_schema()) : nullptr; + } + const Ikarus::Value::CombinedSchema *value_schema_as_CombinedSchema() const { + return value_schema_type() == Ikarus::Value::Schema::CombinedSchema ? static_cast(value_schema()) : nullptr; + } + const Ikarus::Value::ListSchema *value_schema_as_ListSchema() const { + return value_schema_type() == Ikarus::Value::Schema::ListSchema ? static_cast(value_schema()) : nullptr; + } + const Ikarus::Value::ComplexSchema *value_schema_as_ComplexSchema() const { + return value_schema_type() == Ikarus::Value::Schema::ComplexSchema ? static_cast(value_schema()) : nullptr; + } + Ikarus::Value::Data default_value_type() const { + return static_cast(GetField(VT_DEFAULT_VALUE_TYPE, 0)); + } + const void *default_value() const { + return GetPointer(VT_DEFAULT_VALUE); + } + template const T *default_value_as() const; + const Ikarus::Value::ToggleDataPoint *default_value_as_ToggleDataPoint() const { + return default_value_type() == Ikarus::Value::Data::ToggleDataPoint ? static_cast(default_value()) : nullptr; + } + const Ikarus::Value::NumberDataPoint *default_value_as_NumberDataPoint() const { + return default_value_type() == Ikarus::Value::Data::NumberDataPoint ? static_cast(default_value()) : nullptr; + } + const Ikarus::Value::TextDataPoint *default_value_as_TextDataPoint() const { + return default_value_type() == Ikarus::Value::Data::TextDataPoint ? static_cast(default_value()) : nullptr; + } + const Ikarus::Value::SimpleData *default_value_as_SimpleData() const { + return default_value_type() == Ikarus::Value::Data::SimpleData ? static_cast(default_value()) : nullptr; + } + const Ikarus::Value::CombinedData *default_value_as_CombinedData() const { + return default_value_type() == Ikarus::Value::Data::CombinedData ? static_cast(default_value()) : nullptr; + } + const Ikarus::Value::ListData *default_value_as_ListData() const { + return default_value_type() == Ikarus::Value::Data::ListData ? static_cast(default_value()) : nullptr; + } + const Ikarus::Value::ComplexData *default_value_as_ComplexData() const { + return default_value_type() == Ikarus::Value::Data::ComplexData ? static_cast(default_value()) : nullptr; + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_ID, 8) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyOffset(verifier, VT_DESCRIPTION) && + verifier.VerifyString(description()) && + VerifyOffset(verifier, VT_TAGS) && + verifier.VerifyVector(tags()) && + verifier.VerifyVectorOfStrings(tags()) && + VerifyField(verifier, VT_VALUE_SCHEMA_TYPE, 1) && + VerifyOffset(verifier, VT_VALUE_SCHEMA) && + VerifySchema(verifier, value_schema(), value_schema_type()) && + VerifyField(verifier, VT_DEFAULT_VALUE_TYPE, 1) && + VerifyOffset(verifier, VT_DEFAULT_VALUE) && + VerifyData(verifier, default_value(), default_value_type()) && + verifier.EndTable(); + } +}; + +template<> inline const Ikarus::Value::ConstantSchema *Property::value_schema_as() const { + return value_schema_as_ConstantSchema(); +} + +template<> inline const Ikarus::Value::SimpleSchema *Property::value_schema_as() const { + return value_schema_as_SimpleSchema(); +} + +template<> inline const Ikarus::Value::CombinedSchema *Property::value_schema_as() const { + return value_schema_as_CombinedSchema(); +} + +template<> inline const Ikarus::Value::ListSchema *Property::value_schema_as() const { + return value_schema_as_ListSchema(); +} + +template<> inline const Ikarus::Value::ComplexSchema *Property::value_schema_as() const { + return value_schema_as_ComplexSchema(); +} + +template<> inline const Ikarus::Value::ToggleDataPoint *Property::default_value_as() const { + return default_value_as_ToggleDataPoint(); +} + +template<> inline const Ikarus::Value::NumberDataPoint *Property::default_value_as() const { + return default_value_as_NumberDataPoint(); +} + +template<> inline const Ikarus::Value::TextDataPoint *Property::default_value_as() const { + return default_value_as_TextDataPoint(); +} + +template<> inline const Ikarus::Value::SimpleData *Property::default_value_as() const { + return default_value_as_SimpleData(); +} + +template<> inline const Ikarus::Value::CombinedData *Property::default_value_as() const { + return default_value_as_CombinedData(); +} + +template<> inline const Ikarus::Value::ListData *Property::default_value_as() const { + return default_value_as_ListData(); +} + +template<> inline const Ikarus::Value::ComplexData *Property::default_value_as() const { + return default_value_as_ComplexData(); +} + +struct PropertyBuilder { + typedef Property Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_id(int64_t id) { + fbb_.AddElement(Property::VT_ID, id, 0); + } + void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { + fbb_.AddOffset(Property::VT_NAME, name); + } + void add_description(::flatbuffers::Offset<::flatbuffers::String> description) { + fbb_.AddOffset(Property::VT_DESCRIPTION, description); + } + void add_tags(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> tags) { + fbb_.AddOffset(Property::VT_TAGS, tags); + } + void add_value_schema_type(Ikarus::Value::Schema value_schema_type) { + fbb_.AddElement(Property::VT_VALUE_SCHEMA_TYPE, static_cast(value_schema_type), 0); + } + void add_value_schema(::flatbuffers::Offset value_schema) { + fbb_.AddOffset(Property::VT_VALUE_SCHEMA, value_schema); + } + void add_default_value_type(Ikarus::Value::Data default_value_type) { + fbb_.AddElement(Property::VT_DEFAULT_VALUE_TYPE, static_cast(default_value_type), 0); + } + void add_default_value(::flatbuffers::Offset default_value) { + fbb_.AddOffset(Property::VT_DEFAULT_VALUE, default_value); + } + explicit PropertyBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateProperty( + ::flatbuffers::FlatBufferBuilder &_fbb, + int64_t id = 0, + ::flatbuffers::Offset<::flatbuffers::String> name = 0, + ::flatbuffers::Offset<::flatbuffers::String> description = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> tags = 0, + Ikarus::Value::Schema value_schema_type = Ikarus::Value::Schema::NONE, + ::flatbuffers::Offset value_schema = 0, + Ikarus::Value::Data default_value_type = Ikarus::Value::Data::NONE, + ::flatbuffers::Offset default_value = 0) { + PropertyBuilder builder_(_fbb); + builder_.add_id(id); + builder_.add_default_value(default_value); + builder_.add_value_schema(value_schema); + builder_.add_tags(tags); + builder_.add_description(description); + builder_.add_name(name); + builder_.add_default_value_type(default_value_type); + builder_.add_value_schema_type(value_schema_type); + return builder_.Finish(); +} + +struct Property::Traits { + using type = Property; + static auto constexpr Create = CreateProperty; +}; + +inline ::flatbuffers::Offset CreatePropertyDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + int64_t id = 0, + const char *name = nullptr, + const char *description = nullptr, + const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *tags = nullptr, + Ikarus::Value::Schema value_schema_type = Ikarus::Value::Schema::NONE, + ::flatbuffers::Offset value_schema = 0, + Ikarus::Value::Data default_value_type = Ikarus::Value::Data::NONE, + ::flatbuffers::Offset default_value = 0) { + auto name__ = name ? _fbb.CreateString(name) : 0; + auto description__ = description ? _fbb.CreateString(description) : 0; + auto tags__ = tags ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*tags) : 0; + return Ikarus::CreateProperty( + _fbb, + id, + name__, + description__, + tags__, + value_schema_type, + value_schema, + default_value_type, + default_value); +} + +inline const Ikarus::Property *GetProperty(const void *buf) { + return ::flatbuffers::GetRoot(buf); +} + +inline const Ikarus::Property *GetSizePrefixedProperty(const void *buf) { + return ::flatbuffers::GetSizePrefixedRoot(buf); +} + +inline bool VerifyPropertyBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifyBuffer(nullptr); +} + +inline bool VerifySizePrefixedPropertyBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifySizePrefixedBuffer(nullptr); +} + +inline void FinishPropertyBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.Finish(root); +} + +inline void FinishSizePrefixedPropertyBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.FinishSizePrefixed(root); +} + +} // namespace Ikarus + +#endif // FLATBUFFERS_GENERATED_PROPERTY_IKARUS_H_ diff --git a/include/ikarus/models/value.fbs b/include/ikarus/models/value.fbs new file mode 100644 index 0000000..27a27e9 --- /dev/null +++ b/include/ikarus/models/value.fbs @@ -0,0 +1,85 @@ +namespace Ikarus.Value; + +table ToggleDataPoint { + data: [bool]; +} + +table NumberDataPoint { + data: [double]; +} + +table TextDataPoint { + data: [string]; +} + +union Data { + ToggleDataPoint, + NumberDataPoint, + TextDataPoint, + SimpleData, + CombinedData, + ListData, + ComplexData +} + +union Schema { + ConstantSchema, + SimpleSchema, + CombinedSchema, + ListSchema, + ComplexSchema +} + +table ConstantSchema { + sub_schema: Schema; + data: Data; +} + +table SimpleSchema { + sub_schema: Schema; +} + +table SimpleData { + data: Data; +} + +table CombinedSchema { + schemas: [Schema]; +} + +table CombinedData { + data: [Data]; +} + +table ListSchema { + schema: Schema; +} + +table ListData { + data: [Data]; +} + +table NamedSchema { + name: string; + schema: Schema; +} + +table ComplexSchema { + schemas: [NamedSchema]; +} + +table NamedData { + name: string; + data: Data; +} + +table ComplexData { + data: [NamedData]; +} + +table Value { + schema: Schema; + data: Data; +} + +root_type Value; diff --git a/include/ikarus/models/value_generated.h b/include/ikarus/models/value_generated.h new file mode 100644 index 0000000..c9da9e3 --- /dev/null +++ b/include/ikarus/models/value_generated.h @@ -0,0 +1,1719 @@ +// automatically generated by the FlatBuffers compiler, do not modify + + +#ifndef FLATBUFFERS_GENERATED_VALUE_IKARUS_VALUE_H_ +#define FLATBUFFERS_GENERATED_VALUE_IKARUS_VALUE_H_ + +#include "flatbuffers/flatbuffers.h" + +// Ensure the included flatbuffers.h is the same version as when this file was +// generated, otherwise it may not be compatible. +static_assert(FLATBUFFERS_VERSION_MAJOR == 24 && + FLATBUFFERS_VERSION_MINOR == 3 && + FLATBUFFERS_VERSION_REVISION == 25, + "Non-compatible flatbuffers version included"); + +namespace Ikarus { +namespace Value { + +struct ToggleDataPoint; +struct ToggleDataPointBuilder; + +struct NumberDataPoint; +struct NumberDataPointBuilder; + +struct TextDataPoint; +struct TextDataPointBuilder; + +struct ConstantSchema; +struct ConstantSchemaBuilder; + +struct SimpleSchema; +struct SimpleSchemaBuilder; + +struct SimpleData; +struct SimpleDataBuilder; + +struct CombinedSchema; +struct CombinedSchemaBuilder; + +struct CombinedData; +struct CombinedDataBuilder; + +struct ListSchema; +struct ListSchemaBuilder; + +struct ListData; +struct ListDataBuilder; + +struct NamedSchema; +struct NamedSchemaBuilder; + +struct ComplexSchema; +struct ComplexSchemaBuilder; + +struct NamedData; +struct NamedDataBuilder; + +struct ComplexData; +struct ComplexDataBuilder; + +struct Value; +struct ValueBuilder; + +enum class Data : uint8_t { + NONE = 0, + ToggleDataPoint = 1, + NumberDataPoint = 2, + TextDataPoint = 3, + SimpleData = 4, + CombinedData = 5, + ListData = 6, + ComplexData = 7, + MIN = NONE, + MAX = ComplexData +}; + +inline const Data (&EnumValuesData())[8] { + static const Data values[] = { + Data::NONE, + Data::ToggleDataPoint, + Data::NumberDataPoint, + Data::TextDataPoint, + Data::SimpleData, + Data::CombinedData, + Data::ListData, + Data::ComplexData + }; + return values; +} + +inline const char * const *EnumNamesData() { + static const char * const names[9] = { + "NONE", + "ToggleDataPoint", + "NumberDataPoint", + "TextDataPoint", + "SimpleData", + "CombinedData", + "ListData", + "ComplexData", + nullptr + }; + return names; +} + +inline const char *EnumNameData(Data e) { + if (::flatbuffers::IsOutRange(e, Data::NONE, Data::ComplexData)) return ""; + const size_t index = static_cast(e); + return EnumNamesData()[index]; +} + +template struct DataTraits { + static const Data enum_value = Data::NONE; +}; + +template<> struct DataTraits { + static const Data enum_value = Data::ToggleDataPoint; +}; + +template<> struct DataTraits { + static const Data enum_value = Data::NumberDataPoint; +}; + +template<> struct DataTraits { + static const Data enum_value = Data::TextDataPoint; +}; + +template<> struct DataTraits { + static const Data enum_value = Data::SimpleData; +}; + +template<> struct DataTraits { + static const Data enum_value = Data::CombinedData; +}; + +template<> struct DataTraits { + static const Data enum_value = Data::ListData; +}; + +template<> struct DataTraits { + static const Data enum_value = Data::ComplexData; +}; + +bool VerifyData(::flatbuffers::Verifier &verifier, const void *obj, Data type); +bool VerifyDataVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types); + +enum class Schema : uint8_t { + NONE = 0, + ConstantSchema = 1, + SimpleSchema = 2, + CombinedSchema = 3, + ListSchema = 4, + ComplexSchema = 5, + MIN = NONE, + MAX = ComplexSchema +}; + +inline const Schema (&EnumValuesSchema())[6] { + static const Schema values[] = { + Schema::NONE, + Schema::ConstantSchema, + Schema::SimpleSchema, + Schema::CombinedSchema, + Schema::ListSchema, + Schema::ComplexSchema + }; + return values; +} + +inline const char * const *EnumNamesSchema() { + static const char * const names[7] = { + "NONE", + "ConstantSchema", + "SimpleSchema", + "CombinedSchema", + "ListSchema", + "ComplexSchema", + nullptr + }; + return names; +} + +inline const char *EnumNameSchema(Schema e) { + if (::flatbuffers::IsOutRange(e, Schema::NONE, Schema::ComplexSchema)) return ""; + const size_t index = static_cast(e); + return EnumNamesSchema()[index]; +} + +template struct SchemaTraits { + static const Schema enum_value = Schema::NONE; +}; + +template<> struct SchemaTraits { + static const Schema enum_value = Schema::ConstantSchema; +}; + +template<> struct SchemaTraits { + static const Schema enum_value = Schema::SimpleSchema; +}; + +template<> struct SchemaTraits { + static const Schema enum_value = Schema::CombinedSchema; +}; + +template<> struct SchemaTraits { + static const Schema enum_value = Schema::ListSchema; +}; + +template<> struct SchemaTraits { + static const Schema enum_value = Schema::ComplexSchema; +}; + +bool VerifySchema(::flatbuffers::Verifier &verifier, const void *obj, Schema type); +bool VerifySchemaVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types); + +struct ToggleDataPoint FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ToggleDataPointBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_DATA = 4 + }; + const ::flatbuffers::Vector *data() const { + return GetPointer *>(VT_DATA); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_DATA) && + verifier.VerifyVector(data()) && + verifier.EndTable(); + } +}; + +struct ToggleDataPointBuilder { + typedef ToggleDataPoint Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_data(::flatbuffers::Offset<::flatbuffers::Vector> data) { + fbb_.AddOffset(ToggleDataPoint::VT_DATA, data); + } + explicit ToggleDataPointBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateToggleDataPoint( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::Vector> data = 0) { + ToggleDataPointBuilder builder_(_fbb); + builder_.add_data(data); + return builder_.Finish(); +} + +struct ToggleDataPoint::Traits { + using type = ToggleDataPoint; + static auto constexpr Create = CreateToggleDataPoint; +}; + +inline ::flatbuffers::Offset CreateToggleDataPointDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *data = nullptr) { + auto data__ = data ? _fbb.CreateVector(*data) : 0; + return Ikarus::Value::CreateToggleDataPoint( + _fbb, + data__); +} + +struct NumberDataPoint FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef NumberDataPointBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_DATA = 4 + }; + const ::flatbuffers::Vector *data() const { + return GetPointer *>(VT_DATA); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_DATA) && + verifier.VerifyVector(data()) && + verifier.EndTable(); + } +}; + +struct NumberDataPointBuilder { + typedef NumberDataPoint Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_data(::flatbuffers::Offset<::flatbuffers::Vector> data) { + fbb_.AddOffset(NumberDataPoint::VT_DATA, data); + } + explicit NumberDataPointBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateNumberDataPoint( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::Vector> data = 0) { + NumberDataPointBuilder builder_(_fbb); + builder_.add_data(data); + return builder_.Finish(); +} + +struct NumberDataPoint::Traits { + using type = NumberDataPoint; + static auto constexpr Create = CreateNumberDataPoint; +}; + +inline ::flatbuffers::Offset CreateNumberDataPointDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *data = nullptr) { + auto data__ = data ? _fbb.CreateVector(*data) : 0; + return Ikarus::Value::CreateNumberDataPoint( + _fbb, + data__); +} + +struct TextDataPoint FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef TextDataPointBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_DATA = 4 + }; + const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *data() const { + return GetPointer> *>(VT_DATA); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_DATA) && + verifier.VerifyVector(data()) && + verifier.VerifyVectorOfStrings(data()) && + verifier.EndTable(); + } +}; + +struct TextDataPointBuilder { + typedef TextDataPoint Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_data(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> data) { + fbb_.AddOffset(TextDataPoint::VT_DATA, data); + } + explicit TextDataPointBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateTextDataPoint( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> data = 0) { + TextDataPointBuilder builder_(_fbb); + builder_.add_data(data); + return builder_.Finish(); +} + +struct TextDataPoint::Traits { + using type = TextDataPoint; + static auto constexpr Create = CreateTextDataPoint; +}; + +inline ::flatbuffers::Offset CreateTextDataPointDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *data = nullptr) { + auto data__ = data ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*data) : 0; + return Ikarus::Value::CreateTextDataPoint( + _fbb, + data__); +} + +struct ConstantSchema FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ConstantSchemaBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SUB_SCHEMA_TYPE = 4, + VT_SUB_SCHEMA = 6, + VT_DATA_TYPE = 8, + VT_DATA = 10 + }; + Ikarus::Value::Schema sub_schema_type() const { + return static_cast(GetField(VT_SUB_SCHEMA_TYPE, 0)); + } + const void *sub_schema() const { + return GetPointer(VT_SUB_SCHEMA); + } + template const T *sub_schema_as() const; + const Ikarus::Value::ConstantSchema *sub_schema_as_ConstantSchema() const { + return sub_schema_type() == Ikarus::Value::Schema::ConstantSchema ? static_cast(sub_schema()) : nullptr; + } + const Ikarus::Value::SimpleSchema *sub_schema_as_SimpleSchema() const { + return sub_schema_type() == Ikarus::Value::Schema::SimpleSchema ? static_cast(sub_schema()) : nullptr; + } + const Ikarus::Value::CombinedSchema *sub_schema_as_CombinedSchema() const { + return sub_schema_type() == Ikarus::Value::Schema::CombinedSchema ? static_cast(sub_schema()) : nullptr; + } + const Ikarus::Value::ListSchema *sub_schema_as_ListSchema() const { + return sub_schema_type() == Ikarus::Value::Schema::ListSchema ? static_cast(sub_schema()) : nullptr; + } + const Ikarus::Value::ComplexSchema *sub_schema_as_ComplexSchema() const { + return sub_schema_type() == Ikarus::Value::Schema::ComplexSchema ? static_cast(sub_schema()) : nullptr; + } + Ikarus::Value::Data data_type() const { + return static_cast(GetField(VT_DATA_TYPE, 0)); + } + const void *data() const { + return GetPointer(VT_DATA); + } + template const T *data_as() const; + const Ikarus::Value::ToggleDataPoint *data_as_ToggleDataPoint() const { + return data_type() == Ikarus::Value::Data::ToggleDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::NumberDataPoint *data_as_NumberDataPoint() const { + return data_type() == Ikarus::Value::Data::NumberDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::TextDataPoint *data_as_TextDataPoint() const { + return data_type() == Ikarus::Value::Data::TextDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::SimpleData *data_as_SimpleData() const { + return data_type() == Ikarus::Value::Data::SimpleData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::CombinedData *data_as_CombinedData() const { + return data_type() == Ikarus::Value::Data::CombinedData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::ListData *data_as_ListData() const { + return data_type() == Ikarus::Value::Data::ListData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::ComplexData *data_as_ComplexData() const { + return data_type() == Ikarus::Value::Data::ComplexData ? static_cast(data()) : nullptr; + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_SUB_SCHEMA_TYPE, 1) && + VerifyOffset(verifier, VT_SUB_SCHEMA) && + VerifySchema(verifier, sub_schema(), sub_schema_type()) && + VerifyField(verifier, VT_DATA_TYPE, 1) && + VerifyOffset(verifier, VT_DATA) && + VerifyData(verifier, data(), data_type()) && + verifier.EndTable(); + } +}; + +template<> inline const Ikarus::Value::ConstantSchema *ConstantSchema::sub_schema_as() const { + return sub_schema_as_ConstantSchema(); +} + +template<> inline const Ikarus::Value::SimpleSchema *ConstantSchema::sub_schema_as() const { + return sub_schema_as_SimpleSchema(); +} + +template<> inline const Ikarus::Value::CombinedSchema *ConstantSchema::sub_schema_as() const { + return sub_schema_as_CombinedSchema(); +} + +template<> inline const Ikarus::Value::ListSchema *ConstantSchema::sub_schema_as() const { + return sub_schema_as_ListSchema(); +} + +template<> inline const Ikarus::Value::ComplexSchema *ConstantSchema::sub_schema_as() const { + return sub_schema_as_ComplexSchema(); +} + +template<> inline const Ikarus::Value::ToggleDataPoint *ConstantSchema::data_as() const { + return data_as_ToggleDataPoint(); +} + +template<> inline const Ikarus::Value::NumberDataPoint *ConstantSchema::data_as() const { + return data_as_NumberDataPoint(); +} + +template<> inline const Ikarus::Value::TextDataPoint *ConstantSchema::data_as() const { + return data_as_TextDataPoint(); +} + +template<> inline const Ikarus::Value::SimpleData *ConstantSchema::data_as() const { + return data_as_SimpleData(); +} + +template<> inline const Ikarus::Value::CombinedData *ConstantSchema::data_as() const { + return data_as_CombinedData(); +} + +template<> inline const Ikarus::Value::ListData *ConstantSchema::data_as() const { + return data_as_ListData(); +} + +template<> inline const Ikarus::Value::ComplexData *ConstantSchema::data_as() const { + return data_as_ComplexData(); +} + +struct ConstantSchemaBuilder { + typedef ConstantSchema Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_sub_schema_type(Ikarus::Value::Schema sub_schema_type) { + fbb_.AddElement(ConstantSchema::VT_SUB_SCHEMA_TYPE, static_cast(sub_schema_type), 0); + } + void add_sub_schema(::flatbuffers::Offset sub_schema) { + fbb_.AddOffset(ConstantSchema::VT_SUB_SCHEMA, sub_schema); + } + void add_data_type(Ikarus::Value::Data data_type) { + fbb_.AddElement(ConstantSchema::VT_DATA_TYPE, static_cast(data_type), 0); + } + void add_data(::flatbuffers::Offset data) { + fbb_.AddOffset(ConstantSchema::VT_DATA, data); + } + explicit ConstantSchemaBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateConstantSchema( + ::flatbuffers::FlatBufferBuilder &_fbb, + Ikarus::Value::Schema sub_schema_type = Ikarus::Value::Schema::NONE, + ::flatbuffers::Offset sub_schema = 0, + Ikarus::Value::Data data_type = Ikarus::Value::Data::NONE, + ::flatbuffers::Offset data = 0) { + ConstantSchemaBuilder builder_(_fbb); + builder_.add_data(data); + builder_.add_sub_schema(sub_schema); + builder_.add_data_type(data_type); + builder_.add_sub_schema_type(sub_schema_type); + return builder_.Finish(); +} + +struct ConstantSchema::Traits { + using type = ConstantSchema; + static auto constexpr Create = CreateConstantSchema; +}; + +struct SimpleSchema FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef SimpleSchemaBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SUB_SCHEMA_TYPE = 4, + VT_SUB_SCHEMA = 6 + }; + Ikarus::Value::Schema sub_schema_type() const { + return static_cast(GetField(VT_SUB_SCHEMA_TYPE, 0)); + } + const void *sub_schema() const { + return GetPointer(VT_SUB_SCHEMA); + } + template const T *sub_schema_as() const; + const Ikarus::Value::ConstantSchema *sub_schema_as_ConstantSchema() const { + return sub_schema_type() == Ikarus::Value::Schema::ConstantSchema ? static_cast(sub_schema()) : nullptr; + } + const Ikarus::Value::SimpleSchema *sub_schema_as_SimpleSchema() const { + return sub_schema_type() == Ikarus::Value::Schema::SimpleSchema ? static_cast(sub_schema()) : nullptr; + } + const Ikarus::Value::CombinedSchema *sub_schema_as_CombinedSchema() const { + return sub_schema_type() == Ikarus::Value::Schema::CombinedSchema ? static_cast(sub_schema()) : nullptr; + } + const Ikarus::Value::ListSchema *sub_schema_as_ListSchema() const { + return sub_schema_type() == Ikarus::Value::Schema::ListSchema ? static_cast(sub_schema()) : nullptr; + } + const Ikarus::Value::ComplexSchema *sub_schema_as_ComplexSchema() const { + return sub_schema_type() == Ikarus::Value::Schema::ComplexSchema ? static_cast(sub_schema()) : nullptr; + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_SUB_SCHEMA_TYPE, 1) && + VerifyOffset(verifier, VT_SUB_SCHEMA) && + VerifySchema(verifier, sub_schema(), sub_schema_type()) && + verifier.EndTable(); + } +}; + +template<> inline const Ikarus::Value::ConstantSchema *SimpleSchema::sub_schema_as() const { + return sub_schema_as_ConstantSchema(); +} + +template<> inline const Ikarus::Value::SimpleSchema *SimpleSchema::sub_schema_as() const { + return sub_schema_as_SimpleSchema(); +} + +template<> inline const Ikarus::Value::CombinedSchema *SimpleSchema::sub_schema_as() const { + return sub_schema_as_CombinedSchema(); +} + +template<> inline const Ikarus::Value::ListSchema *SimpleSchema::sub_schema_as() const { + return sub_schema_as_ListSchema(); +} + +template<> inline const Ikarus::Value::ComplexSchema *SimpleSchema::sub_schema_as() const { + return sub_schema_as_ComplexSchema(); +} + +struct SimpleSchemaBuilder { + typedef SimpleSchema Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_sub_schema_type(Ikarus::Value::Schema sub_schema_type) { + fbb_.AddElement(SimpleSchema::VT_SUB_SCHEMA_TYPE, static_cast(sub_schema_type), 0); + } + void add_sub_schema(::flatbuffers::Offset sub_schema) { + fbb_.AddOffset(SimpleSchema::VT_SUB_SCHEMA, sub_schema); + } + explicit SimpleSchemaBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateSimpleSchema( + ::flatbuffers::FlatBufferBuilder &_fbb, + Ikarus::Value::Schema sub_schema_type = Ikarus::Value::Schema::NONE, + ::flatbuffers::Offset sub_schema = 0) { + SimpleSchemaBuilder builder_(_fbb); + builder_.add_sub_schema(sub_schema); + builder_.add_sub_schema_type(sub_schema_type); + return builder_.Finish(); +} + +struct SimpleSchema::Traits { + using type = SimpleSchema; + static auto constexpr Create = CreateSimpleSchema; +}; + +struct SimpleData FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef SimpleDataBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_DATA_TYPE = 4, + VT_DATA = 6 + }; + Ikarus::Value::Data data_type() const { + return static_cast(GetField(VT_DATA_TYPE, 0)); + } + const void *data() const { + return GetPointer(VT_DATA); + } + template const T *data_as() const; + const Ikarus::Value::ToggleDataPoint *data_as_ToggleDataPoint() const { + return data_type() == Ikarus::Value::Data::ToggleDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::NumberDataPoint *data_as_NumberDataPoint() const { + return data_type() == Ikarus::Value::Data::NumberDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::TextDataPoint *data_as_TextDataPoint() const { + return data_type() == Ikarus::Value::Data::TextDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::SimpleData *data_as_SimpleData() const { + return data_type() == Ikarus::Value::Data::SimpleData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::CombinedData *data_as_CombinedData() const { + return data_type() == Ikarus::Value::Data::CombinedData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::ListData *data_as_ListData() const { + return data_type() == Ikarus::Value::Data::ListData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::ComplexData *data_as_ComplexData() const { + return data_type() == Ikarus::Value::Data::ComplexData ? static_cast(data()) : nullptr; + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_DATA_TYPE, 1) && + VerifyOffset(verifier, VT_DATA) && + VerifyData(verifier, data(), data_type()) && + verifier.EndTable(); + } +}; + +template<> inline const Ikarus::Value::ToggleDataPoint *SimpleData::data_as() const { + return data_as_ToggleDataPoint(); +} + +template<> inline const Ikarus::Value::NumberDataPoint *SimpleData::data_as() const { + return data_as_NumberDataPoint(); +} + +template<> inline const Ikarus::Value::TextDataPoint *SimpleData::data_as() const { + return data_as_TextDataPoint(); +} + +template<> inline const Ikarus::Value::SimpleData *SimpleData::data_as() const { + return data_as_SimpleData(); +} + +template<> inline const Ikarus::Value::CombinedData *SimpleData::data_as() const { + return data_as_CombinedData(); +} + +template<> inline const Ikarus::Value::ListData *SimpleData::data_as() const { + return data_as_ListData(); +} + +template<> inline const Ikarus::Value::ComplexData *SimpleData::data_as() const { + return data_as_ComplexData(); +} + +struct SimpleDataBuilder { + typedef SimpleData Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_data_type(Ikarus::Value::Data data_type) { + fbb_.AddElement(SimpleData::VT_DATA_TYPE, static_cast(data_type), 0); + } + void add_data(::flatbuffers::Offset data) { + fbb_.AddOffset(SimpleData::VT_DATA, data); + } + explicit SimpleDataBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateSimpleData( + ::flatbuffers::FlatBufferBuilder &_fbb, + Ikarus::Value::Data data_type = Ikarus::Value::Data::NONE, + ::flatbuffers::Offset data = 0) { + SimpleDataBuilder builder_(_fbb); + builder_.add_data(data); + builder_.add_data_type(data_type); + return builder_.Finish(); +} + +struct SimpleData::Traits { + using type = SimpleData; + static auto constexpr Create = CreateSimpleData; +}; + +struct CombinedSchema FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef CombinedSchemaBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SCHEMAS_TYPE = 4, + VT_SCHEMAS = 6 + }; + const ::flatbuffers::Vector *schemas_type() const { + return GetPointer *>(VT_SCHEMAS_TYPE); + } + const ::flatbuffers::Vector<::flatbuffers::Offset> *schemas() const { + return GetPointer> *>(VT_SCHEMAS); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_SCHEMAS_TYPE) && + verifier.VerifyVector(schemas_type()) && + VerifyOffset(verifier, VT_SCHEMAS) && + verifier.VerifyVector(schemas()) && + VerifySchemaVector(verifier, schemas(), schemas_type()) && + verifier.EndTable(); + } +}; + +struct CombinedSchemaBuilder { + typedef CombinedSchema Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_schemas_type(::flatbuffers::Offset<::flatbuffers::Vector> schemas_type) { + fbb_.AddOffset(CombinedSchema::VT_SCHEMAS_TYPE, schemas_type); + } + void add_schemas(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> schemas) { + fbb_.AddOffset(CombinedSchema::VT_SCHEMAS, schemas); + } + explicit CombinedSchemaBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateCombinedSchema( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::Vector> schemas_type = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> schemas = 0) { + CombinedSchemaBuilder builder_(_fbb); + builder_.add_schemas(schemas); + builder_.add_schemas_type(schemas_type); + return builder_.Finish(); +} + +struct CombinedSchema::Traits { + using type = CombinedSchema; + static auto constexpr Create = CreateCombinedSchema; +}; + +inline ::flatbuffers::Offset CreateCombinedSchemaDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *schemas_type = nullptr, + const std::vector<::flatbuffers::Offset> *schemas = nullptr) { + auto schemas_type__ = schemas_type ? _fbb.CreateVector(*schemas_type) : 0; + auto schemas__ = schemas ? _fbb.CreateVector<::flatbuffers::Offset>(*schemas) : 0; + return Ikarus::Value::CreateCombinedSchema( + _fbb, + schemas_type__, + schemas__); +} + +struct CombinedData FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef CombinedDataBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_DATA_TYPE = 4, + VT_DATA = 6 + }; + const ::flatbuffers::Vector *data_type() const { + return GetPointer *>(VT_DATA_TYPE); + } + const ::flatbuffers::Vector<::flatbuffers::Offset> *data() const { + return GetPointer> *>(VT_DATA); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_DATA_TYPE) && + verifier.VerifyVector(data_type()) && + VerifyOffset(verifier, VT_DATA) && + verifier.VerifyVector(data()) && + VerifyDataVector(verifier, data(), data_type()) && + verifier.EndTable(); + } +}; + +struct CombinedDataBuilder { + typedef CombinedData Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_data_type(::flatbuffers::Offset<::flatbuffers::Vector> data_type) { + fbb_.AddOffset(CombinedData::VT_DATA_TYPE, data_type); + } + void add_data(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> data) { + fbb_.AddOffset(CombinedData::VT_DATA, data); + } + explicit CombinedDataBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateCombinedData( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::Vector> data_type = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> data = 0) { + CombinedDataBuilder builder_(_fbb); + builder_.add_data(data); + builder_.add_data_type(data_type); + return builder_.Finish(); +} + +struct CombinedData::Traits { + using type = CombinedData; + static auto constexpr Create = CreateCombinedData; +}; + +inline ::flatbuffers::Offset CreateCombinedDataDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *data_type = nullptr, + const std::vector<::flatbuffers::Offset> *data = nullptr) { + auto data_type__ = data_type ? _fbb.CreateVector(*data_type) : 0; + auto data__ = data ? _fbb.CreateVector<::flatbuffers::Offset>(*data) : 0; + return Ikarus::Value::CreateCombinedData( + _fbb, + data_type__, + data__); +} + +struct ListSchema FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ListSchemaBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SCHEMA_TYPE = 4, + VT_SCHEMA = 6 + }; + Ikarus::Value::Schema schema_type() const { + return static_cast(GetField(VT_SCHEMA_TYPE, 0)); + } + const void *schema() const { + return GetPointer(VT_SCHEMA); + } + template const T *schema_as() const; + const Ikarus::Value::ConstantSchema *schema_as_ConstantSchema() const { + return schema_type() == Ikarus::Value::Schema::ConstantSchema ? static_cast(schema()) : nullptr; + } + const Ikarus::Value::SimpleSchema *schema_as_SimpleSchema() const { + return schema_type() == Ikarus::Value::Schema::SimpleSchema ? static_cast(schema()) : nullptr; + } + const Ikarus::Value::CombinedSchema *schema_as_CombinedSchema() const { + return schema_type() == Ikarus::Value::Schema::CombinedSchema ? static_cast(schema()) : nullptr; + } + const Ikarus::Value::ListSchema *schema_as_ListSchema() const { + return schema_type() == Ikarus::Value::Schema::ListSchema ? static_cast(schema()) : nullptr; + } + const Ikarus::Value::ComplexSchema *schema_as_ComplexSchema() const { + return schema_type() == Ikarus::Value::Schema::ComplexSchema ? static_cast(schema()) : nullptr; + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_SCHEMA_TYPE, 1) && + VerifyOffset(verifier, VT_SCHEMA) && + VerifySchema(verifier, schema(), schema_type()) && + verifier.EndTable(); + } +}; + +template<> inline const Ikarus::Value::ConstantSchema *ListSchema::schema_as() const { + return schema_as_ConstantSchema(); +} + +template<> inline const Ikarus::Value::SimpleSchema *ListSchema::schema_as() const { + return schema_as_SimpleSchema(); +} + +template<> inline const Ikarus::Value::CombinedSchema *ListSchema::schema_as() const { + return schema_as_CombinedSchema(); +} + +template<> inline const Ikarus::Value::ListSchema *ListSchema::schema_as() const { + return schema_as_ListSchema(); +} + +template<> inline const Ikarus::Value::ComplexSchema *ListSchema::schema_as() const { + return schema_as_ComplexSchema(); +} + +struct ListSchemaBuilder { + typedef ListSchema Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_schema_type(Ikarus::Value::Schema schema_type) { + fbb_.AddElement(ListSchema::VT_SCHEMA_TYPE, static_cast(schema_type), 0); + } + void add_schema(::flatbuffers::Offset schema) { + fbb_.AddOffset(ListSchema::VT_SCHEMA, schema); + } + explicit ListSchemaBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateListSchema( + ::flatbuffers::FlatBufferBuilder &_fbb, + Ikarus::Value::Schema schema_type = Ikarus::Value::Schema::NONE, + ::flatbuffers::Offset schema = 0) { + ListSchemaBuilder builder_(_fbb); + builder_.add_schema(schema); + builder_.add_schema_type(schema_type); + return builder_.Finish(); +} + +struct ListSchema::Traits { + using type = ListSchema; + static auto constexpr Create = CreateListSchema; +}; + +struct ListData FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ListDataBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_DATA_TYPE = 4, + VT_DATA = 6 + }; + const ::flatbuffers::Vector *data_type() const { + return GetPointer *>(VT_DATA_TYPE); + } + const ::flatbuffers::Vector<::flatbuffers::Offset> *data() const { + return GetPointer> *>(VT_DATA); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_DATA_TYPE) && + verifier.VerifyVector(data_type()) && + VerifyOffset(verifier, VT_DATA) && + verifier.VerifyVector(data()) && + VerifyDataVector(verifier, data(), data_type()) && + verifier.EndTable(); + } +}; + +struct ListDataBuilder { + typedef ListData Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_data_type(::flatbuffers::Offset<::flatbuffers::Vector> data_type) { + fbb_.AddOffset(ListData::VT_DATA_TYPE, data_type); + } + void add_data(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> data) { + fbb_.AddOffset(ListData::VT_DATA, data); + } + explicit ListDataBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateListData( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::Vector> data_type = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> data = 0) { + ListDataBuilder builder_(_fbb); + builder_.add_data(data); + builder_.add_data_type(data_type); + return builder_.Finish(); +} + +struct ListData::Traits { + using type = ListData; + static auto constexpr Create = CreateListData; +}; + +inline ::flatbuffers::Offset CreateListDataDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *data_type = nullptr, + const std::vector<::flatbuffers::Offset> *data = nullptr) { + auto data_type__ = data_type ? _fbb.CreateVector(*data_type) : 0; + auto data__ = data ? _fbb.CreateVector<::flatbuffers::Offset>(*data) : 0; + return Ikarus::Value::CreateListData( + _fbb, + data_type__, + data__); +} + +struct NamedSchema FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef NamedSchemaBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NAME = 4, + VT_SCHEMA_TYPE = 6, + VT_SCHEMA = 8 + }; + const ::flatbuffers::String *name() const { + return GetPointer(VT_NAME); + } + Ikarus::Value::Schema schema_type() const { + return static_cast(GetField(VT_SCHEMA_TYPE, 0)); + } + const void *schema() const { + return GetPointer(VT_SCHEMA); + } + template const T *schema_as() const; + const Ikarus::Value::ConstantSchema *schema_as_ConstantSchema() const { + return schema_type() == Ikarus::Value::Schema::ConstantSchema ? static_cast(schema()) : nullptr; + } + const Ikarus::Value::SimpleSchema *schema_as_SimpleSchema() const { + return schema_type() == Ikarus::Value::Schema::SimpleSchema ? static_cast(schema()) : nullptr; + } + const Ikarus::Value::CombinedSchema *schema_as_CombinedSchema() const { + return schema_type() == Ikarus::Value::Schema::CombinedSchema ? static_cast(schema()) : nullptr; + } + const Ikarus::Value::ListSchema *schema_as_ListSchema() const { + return schema_type() == Ikarus::Value::Schema::ListSchema ? static_cast(schema()) : nullptr; + } + const Ikarus::Value::ComplexSchema *schema_as_ComplexSchema() const { + return schema_type() == Ikarus::Value::Schema::ComplexSchema ? static_cast(schema()) : nullptr; + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyField(verifier, VT_SCHEMA_TYPE, 1) && + VerifyOffset(verifier, VT_SCHEMA) && + VerifySchema(verifier, schema(), schema_type()) && + verifier.EndTable(); + } +}; + +template<> inline const Ikarus::Value::ConstantSchema *NamedSchema::schema_as() const { + return schema_as_ConstantSchema(); +} + +template<> inline const Ikarus::Value::SimpleSchema *NamedSchema::schema_as() const { + return schema_as_SimpleSchema(); +} + +template<> inline const Ikarus::Value::CombinedSchema *NamedSchema::schema_as() const { + return schema_as_CombinedSchema(); +} + +template<> inline const Ikarus::Value::ListSchema *NamedSchema::schema_as() const { + return schema_as_ListSchema(); +} + +template<> inline const Ikarus::Value::ComplexSchema *NamedSchema::schema_as() const { + return schema_as_ComplexSchema(); +} + +struct NamedSchemaBuilder { + typedef NamedSchema Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { + fbb_.AddOffset(NamedSchema::VT_NAME, name); + } + void add_schema_type(Ikarus::Value::Schema schema_type) { + fbb_.AddElement(NamedSchema::VT_SCHEMA_TYPE, static_cast(schema_type), 0); + } + void add_schema(::flatbuffers::Offset schema) { + fbb_.AddOffset(NamedSchema::VT_SCHEMA, schema); + } + explicit NamedSchemaBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateNamedSchema( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::String> name = 0, + Ikarus::Value::Schema schema_type = Ikarus::Value::Schema::NONE, + ::flatbuffers::Offset schema = 0) { + NamedSchemaBuilder builder_(_fbb); + builder_.add_schema(schema); + builder_.add_name(name); + builder_.add_schema_type(schema_type); + return builder_.Finish(); +} + +struct NamedSchema::Traits { + using type = NamedSchema; + static auto constexpr Create = CreateNamedSchema; +}; + +inline ::flatbuffers::Offset CreateNamedSchemaDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, + Ikarus::Value::Schema schema_type = Ikarus::Value::Schema::NONE, + ::flatbuffers::Offset schema = 0) { + auto name__ = name ? _fbb.CreateString(name) : 0; + return Ikarus::Value::CreateNamedSchema( + _fbb, + name__, + schema_type, + schema); +} + +struct ComplexSchema FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ComplexSchemaBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SCHEMAS = 4 + }; + const ::flatbuffers::Vector<::flatbuffers::Offset> *schemas() const { + return GetPointer> *>(VT_SCHEMAS); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_SCHEMAS) && + verifier.VerifyVector(schemas()) && + verifier.VerifyVectorOfTables(schemas()) && + verifier.EndTable(); + } +}; + +struct ComplexSchemaBuilder { + typedef ComplexSchema Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_schemas(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> schemas) { + fbb_.AddOffset(ComplexSchema::VT_SCHEMAS, schemas); + } + explicit ComplexSchemaBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateComplexSchema( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> schemas = 0) { + ComplexSchemaBuilder builder_(_fbb); + builder_.add_schemas(schemas); + return builder_.Finish(); +} + +struct ComplexSchema::Traits { + using type = ComplexSchema; + static auto constexpr Create = CreateComplexSchema; +}; + +inline ::flatbuffers::Offset CreateComplexSchemaDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const std::vector<::flatbuffers::Offset> *schemas = nullptr) { + auto schemas__ = schemas ? _fbb.CreateVector<::flatbuffers::Offset>(*schemas) : 0; + return Ikarus::Value::CreateComplexSchema( + _fbb, + schemas__); +} + +struct NamedData FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef NamedDataBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NAME = 4, + VT_DATA_TYPE = 6, + VT_DATA = 8 + }; + const ::flatbuffers::String *name() const { + return GetPointer(VT_NAME); + } + Ikarus::Value::Data data_type() const { + return static_cast(GetField(VT_DATA_TYPE, 0)); + } + const void *data() const { + return GetPointer(VT_DATA); + } + template const T *data_as() const; + const Ikarus::Value::ToggleDataPoint *data_as_ToggleDataPoint() const { + return data_type() == Ikarus::Value::Data::ToggleDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::NumberDataPoint *data_as_NumberDataPoint() const { + return data_type() == Ikarus::Value::Data::NumberDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::TextDataPoint *data_as_TextDataPoint() const { + return data_type() == Ikarus::Value::Data::TextDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::SimpleData *data_as_SimpleData() const { + return data_type() == Ikarus::Value::Data::SimpleData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::CombinedData *data_as_CombinedData() const { + return data_type() == Ikarus::Value::Data::CombinedData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::ListData *data_as_ListData() const { + return data_type() == Ikarus::Value::Data::ListData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::ComplexData *data_as_ComplexData() const { + return data_type() == Ikarus::Value::Data::ComplexData ? static_cast(data()) : nullptr; + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyField(verifier, VT_DATA_TYPE, 1) && + VerifyOffset(verifier, VT_DATA) && + VerifyData(verifier, data(), data_type()) && + verifier.EndTable(); + } +}; + +template<> inline const Ikarus::Value::ToggleDataPoint *NamedData::data_as() const { + return data_as_ToggleDataPoint(); +} + +template<> inline const Ikarus::Value::NumberDataPoint *NamedData::data_as() const { + return data_as_NumberDataPoint(); +} + +template<> inline const Ikarus::Value::TextDataPoint *NamedData::data_as() const { + return data_as_TextDataPoint(); +} + +template<> inline const Ikarus::Value::SimpleData *NamedData::data_as() const { + return data_as_SimpleData(); +} + +template<> inline const Ikarus::Value::CombinedData *NamedData::data_as() const { + return data_as_CombinedData(); +} + +template<> inline const Ikarus::Value::ListData *NamedData::data_as() const { + return data_as_ListData(); +} + +template<> inline const Ikarus::Value::ComplexData *NamedData::data_as() const { + return data_as_ComplexData(); +} + +struct NamedDataBuilder { + typedef NamedData Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { + fbb_.AddOffset(NamedData::VT_NAME, name); + } + void add_data_type(Ikarus::Value::Data data_type) { + fbb_.AddElement(NamedData::VT_DATA_TYPE, static_cast(data_type), 0); + } + void add_data(::flatbuffers::Offset data) { + fbb_.AddOffset(NamedData::VT_DATA, data); + } + explicit NamedDataBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateNamedData( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::String> name = 0, + Ikarus::Value::Data data_type = Ikarus::Value::Data::NONE, + ::flatbuffers::Offset data = 0) { + NamedDataBuilder builder_(_fbb); + builder_.add_data(data); + builder_.add_name(name); + builder_.add_data_type(data_type); + return builder_.Finish(); +} + +struct NamedData::Traits { + using type = NamedData; + static auto constexpr Create = CreateNamedData; +}; + +inline ::flatbuffers::Offset CreateNamedDataDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, + Ikarus::Value::Data data_type = Ikarus::Value::Data::NONE, + ::flatbuffers::Offset data = 0) { + auto name__ = name ? _fbb.CreateString(name) : 0; + return Ikarus::Value::CreateNamedData( + _fbb, + name__, + data_type, + data); +} + +struct ComplexData FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ComplexDataBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_DATA = 4 + }; + const ::flatbuffers::Vector<::flatbuffers::Offset> *data() const { + return GetPointer> *>(VT_DATA); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_DATA) && + verifier.VerifyVector(data()) && + verifier.VerifyVectorOfTables(data()) && + verifier.EndTable(); + } +}; + +struct ComplexDataBuilder { + typedef ComplexData Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_data(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> data) { + fbb_.AddOffset(ComplexData::VT_DATA, data); + } + explicit ComplexDataBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateComplexData( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> data = 0) { + ComplexDataBuilder builder_(_fbb); + builder_.add_data(data); + return builder_.Finish(); +} + +struct ComplexData::Traits { + using type = ComplexData; + static auto constexpr Create = CreateComplexData; +}; + +inline ::flatbuffers::Offset CreateComplexDataDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const std::vector<::flatbuffers::Offset> *data = nullptr) { + auto data__ = data ? _fbb.CreateVector<::flatbuffers::Offset>(*data) : 0; + return Ikarus::Value::CreateComplexData( + _fbb, + data__); +} + +struct Value FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ValueBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SCHEMA_TYPE = 4, + VT_SCHEMA = 6, + VT_DATA_TYPE = 8, + VT_DATA = 10 + }; + Ikarus::Value::Schema schema_type() const { + return static_cast(GetField(VT_SCHEMA_TYPE, 0)); + } + const void *schema() const { + return GetPointer(VT_SCHEMA); + } + template const T *schema_as() const; + const Ikarus::Value::ConstantSchema *schema_as_ConstantSchema() const { + return schema_type() == Ikarus::Value::Schema::ConstantSchema ? static_cast(schema()) : nullptr; + } + const Ikarus::Value::SimpleSchema *schema_as_SimpleSchema() const { + return schema_type() == Ikarus::Value::Schema::SimpleSchema ? static_cast(schema()) : nullptr; + } + const Ikarus::Value::CombinedSchema *schema_as_CombinedSchema() const { + return schema_type() == Ikarus::Value::Schema::CombinedSchema ? static_cast(schema()) : nullptr; + } + const Ikarus::Value::ListSchema *schema_as_ListSchema() const { + return schema_type() == Ikarus::Value::Schema::ListSchema ? static_cast(schema()) : nullptr; + } + const Ikarus::Value::ComplexSchema *schema_as_ComplexSchema() const { + return schema_type() == Ikarus::Value::Schema::ComplexSchema ? static_cast(schema()) : nullptr; + } + Ikarus::Value::Data data_type() const { + return static_cast(GetField(VT_DATA_TYPE, 0)); + } + const void *data() const { + return GetPointer(VT_DATA); + } + template const T *data_as() const; + const Ikarus::Value::ToggleDataPoint *data_as_ToggleDataPoint() const { + return data_type() == Ikarus::Value::Data::ToggleDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::NumberDataPoint *data_as_NumberDataPoint() const { + return data_type() == Ikarus::Value::Data::NumberDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::TextDataPoint *data_as_TextDataPoint() const { + return data_type() == Ikarus::Value::Data::TextDataPoint ? static_cast(data()) : nullptr; + } + const Ikarus::Value::SimpleData *data_as_SimpleData() const { + return data_type() == Ikarus::Value::Data::SimpleData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::CombinedData *data_as_CombinedData() const { + return data_type() == Ikarus::Value::Data::CombinedData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::ListData *data_as_ListData() const { + return data_type() == Ikarus::Value::Data::ListData ? static_cast(data()) : nullptr; + } + const Ikarus::Value::ComplexData *data_as_ComplexData() const { + return data_type() == Ikarus::Value::Data::ComplexData ? static_cast(data()) : nullptr; + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_SCHEMA_TYPE, 1) && + VerifyOffset(verifier, VT_SCHEMA) && + VerifySchema(verifier, schema(), schema_type()) && + VerifyField(verifier, VT_DATA_TYPE, 1) && + VerifyOffset(verifier, VT_DATA) && + VerifyData(verifier, data(), data_type()) && + verifier.EndTable(); + } +}; + +template<> inline const Ikarus::Value::ConstantSchema *Value::schema_as() const { + return schema_as_ConstantSchema(); +} + +template<> inline const Ikarus::Value::SimpleSchema *Value::schema_as() const { + return schema_as_SimpleSchema(); +} + +template<> inline const Ikarus::Value::CombinedSchema *Value::schema_as() const { + return schema_as_CombinedSchema(); +} + +template<> inline const Ikarus::Value::ListSchema *Value::schema_as() const { + return schema_as_ListSchema(); +} + +template<> inline const Ikarus::Value::ComplexSchema *Value::schema_as() const { + return schema_as_ComplexSchema(); +} + +template<> inline const Ikarus::Value::ToggleDataPoint *Value::data_as() const { + return data_as_ToggleDataPoint(); +} + +template<> inline const Ikarus::Value::NumberDataPoint *Value::data_as() const { + return data_as_NumberDataPoint(); +} + +template<> inline const Ikarus::Value::TextDataPoint *Value::data_as() const { + return data_as_TextDataPoint(); +} + +template<> inline const Ikarus::Value::SimpleData *Value::data_as() const { + return data_as_SimpleData(); +} + +template<> inline const Ikarus::Value::CombinedData *Value::data_as() const { + return data_as_CombinedData(); +} + +template<> inline const Ikarus::Value::ListData *Value::data_as() const { + return data_as_ListData(); +} + +template<> inline const Ikarus::Value::ComplexData *Value::data_as() const { + return data_as_ComplexData(); +} + +struct ValueBuilder { + typedef Value Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_schema_type(Ikarus::Value::Schema schema_type) { + fbb_.AddElement(Value::VT_SCHEMA_TYPE, static_cast(schema_type), 0); + } + void add_schema(::flatbuffers::Offset schema) { + fbb_.AddOffset(Value::VT_SCHEMA, schema); + } + void add_data_type(Ikarus::Value::Data data_type) { + fbb_.AddElement(Value::VT_DATA_TYPE, static_cast(data_type), 0); + } + void add_data(::flatbuffers::Offset data) { + fbb_.AddOffset(Value::VT_DATA, data); + } + explicit ValueBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateValue( + ::flatbuffers::FlatBufferBuilder &_fbb, + Ikarus::Value::Schema schema_type = Ikarus::Value::Schema::NONE, + ::flatbuffers::Offset schema = 0, + Ikarus::Value::Data data_type = Ikarus::Value::Data::NONE, + ::flatbuffers::Offset data = 0) { + ValueBuilder builder_(_fbb); + builder_.add_data(data); + builder_.add_schema(schema); + builder_.add_data_type(data_type); + builder_.add_schema_type(schema_type); + return builder_.Finish(); +} + +struct Value::Traits { + using type = Value; + static auto constexpr Create = CreateValue; +}; + +inline bool VerifyData(::flatbuffers::Verifier &verifier, const void *obj, Data type) { + switch (type) { + case Data::NONE: { + return true; + } + case Data::ToggleDataPoint: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case Data::NumberDataPoint: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case Data::TextDataPoint: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case Data::SimpleData: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case Data::CombinedData: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case Data::ListData: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case Data::ComplexData: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + default: return true; + } +} + +inline bool VerifyDataVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types) { + if (!values || !types) return !values && !types; + if (values->size() != types->size()) return false; + for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { + if (!VerifyData( + verifier, values->Get(i), types->GetEnum(i))) { + return false; + } + } + return true; +} + +inline bool VerifySchema(::flatbuffers::Verifier &verifier, const void *obj, Schema type) { + switch (type) { + case Schema::NONE: { + return true; + } + case Schema::ConstantSchema: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case Schema::SimpleSchema: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case Schema::CombinedSchema: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case Schema::ListSchema: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case Schema::ComplexSchema: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + default: return true; + } +} + +inline bool VerifySchemaVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types) { + if (!values || !types) return !values && !types; + if (values->size() != types->size()) return false; + for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { + if (!VerifySchema( + verifier, values->Get(i), types->GetEnum(i))) { + return false; + } + } + return true; +} + +inline const Ikarus::Value::Value *GetValue(const void *buf) { + return ::flatbuffers::GetRoot(buf); +} + +inline const Ikarus::Value::Value *GetSizePrefixedValue(const void *buf) { + return ::flatbuffers::GetSizePrefixedRoot(buf); +} + +inline bool VerifyValueBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifyBuffer(nullptr); +} + +inline bool VerifySizePrefixedValueBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifySizePrefixedBuffer(nullptr); +} + +inline void FinishValueBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.Finish(root); +} + +inline void FinishSizePrefixedValueBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.FinishSizePrefixed(root); +} + +} // namespace Value +} // namespace Ikarus + +#endif // FLATBUFFERS_GENERATED_VALUE_IKARUS_VALUE_H_ diff --git a/include/ikarus/objects/blueprint.h b/include/ikarus/objects/blueprint.h index ec2087f..9ad444e 100644 --- a/include/ikarus/objects/blueprint.h +++ b/include/ikarus/objects/blueprint.h @@ -4,7 +4,6 @@ /// \author Folling #include -#include #include #include @@ -14,9 +13,10 @@ 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.q +/// \brief Blueprints are templates for managing common properties of entities. +/// \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. Changes in blueprints will be reflected in all linked entities. struct IkarusBlueprint; /// \brief Creates a blueprint. @@ -25,19 +25,24 @@ struct IkarusBlueprint; /// \pre \li Must exist. /// \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. -IKA_API IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project, char const * name, IkarusErrorData * error_out); +IKA_API IkarusBlueprint * ikarus_blueprint_create( + struct IkarusProject * project, + char const * name, + IkarusErrorData * error_out +); -/// \brief Deletes & frees a blueprint. +/// \brief Deletes a blueprint. /// \param blueprint The blueprint to delete. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param error_out \see errors.h /// \remark The blueprint must not be accessed after deletion. -IKA_API void ikarus_blueprint_delete(IkarusBlueprint * blueprint, IkarusErrorData * error_out); +IKA_API void ikarus_blueprint_delete( + IkarusBlueprint * blueprint, + IkarusErrorData * error_out +); /// \brief Gets the ID of a blueprint. /// \param blueprint The blueprint to get the ID of. @@ -45,23 +50,32 @@ IKA_API void ikarus_blueprint_delete(IkarusBlueprint * blueprint, IkarusErrorDat /// \pre \li Must exist. /// \param error_out \see errors.h /// \return The ID of the blueprint or 0 if an error occurs. -IKA_API IkarusId ikarus_blueprint_get_id(IkarusBlueprint const * blueprint, IkarusErrorData * error_out); +IKA_API int64_t ikarus_blueprint_get_id( + IkarusBlueprint const * 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); +/// \return The project 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); +/// \return The name 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. @@ -69,10 +83,12 @@ IKA_API char const * ikarus_blueprint_get_name(IkarusBlueprint const * blueprint /// \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); +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. @@ -96,7 +112,10 @@ IKA_API void ikarus_blueprint_get_properties( /// \pre \li Must exist. /// \param error_out \see errors.h /// \return The number of properties or undefined if an error occurs. -IKA_API size_t ikarus_blueprint_get_property_count(IkarusBlueprint const * blueprint, IkarusErrorData * error_out); +IKA_API size_t ikarus_blueprint_get_property_count( + IkarusBlueprint const * blueprint, + IkarusErrorData * error_out +); /// \brief Gets the entities linked to a blueprint. /// \param blueprint The blueprint to get the linked entities of. @@ -120,7 +139,10 @@ IKA_API void ikarus_blueprint_get_linked_entities( /// \pre \li Must exist. /// \param error_out \see errors.h /// \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); +IKA_API size_t ikarus_blueprint_get_linked_entity_count( + IkarusBlueprint const * blueprint, + IkarusErrorData * error_out +); IKARUS_END_HEADER diff --git a/include/ikarus/objects/entity.h b/include/ikarus/objects/entity.h index 04d59b0..28cebf8 100644 --- a/include/ikarus/objects/entity.h +++ b/include/ikarus/objects/entity.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include @@ -14,25 +13,20 @@ 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. +/// \details Entities store two data: A name and a set of values. +/// The name identifies the entity but does not have to be unique. The values +/// are the actual information of the entity. /// -/// Properties can be associated with Entities in two ways: -/// - Directly: The property is linked to the entity. -/// - Indirectly: The property is linked to a blueprint the entity is linked to. +/// For documentation on the types and layout of values \see Values.h. /// -/// 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. +/// Entities can be linked to blueprints. +/// The entity has a (possibly uninitialized) value for each property of all +/// blueprints it is linked to. \see Property.h \see Blueprint.h. /// -/// 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. +/// We distinguish between `EntityValues` and `EntityPropertyValues`. +/// `EntityValues` are a direct part of the entity. +/// `EntityPropertyValues` are an indirect part of the entity, linked to them +/// via a blueprint. struct IkarusEntity; /// \brief Creates an entity. @@ -41,11 +35,13 @@ struct IkarusEntity; /// \pre \li Must exist. /// \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. -IKA_API IkarusEntity * ikarus_entity_create(struct IkarusProject * project, char const * name, IkarusErrorData * error_out); +IKA_API IkarusEntity * ikarus_entity_create( + struct IkarusProject * project, + char const * name, + IkarusErrorData * error_out +); /// \brief Deletes an entity. /// \param entity The entity to delete. @@ -53,15 +49,17 @@ IKA_API IkarusEntity * ikarus_entity_create(struct IkarusProject * project, char /// \pre \li Must exist. /// \param error_out \see errors.h /// \remark The entity must not be accessed after deletion. -IKA_API void ikarus_entity_delete(IkarusEntity * entity, IkarusErrorData * error_out); +IKA_API void +ikarus_entity_delete(IkarusEntity * entity, IkarusErrorData * error_out); -/// \brief Gets the ID of an entity. -/// \param entity The entity to get the ID of. +/// \brief Gets the id of an entity. +/// \param entity The entity to get the id of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param error_out \see errors.h -/// \return The ID of the entity or 0 if an error occurs. -IKA_API IkarusId ikarus_entity_get_id(IkarusEntity const * entity, IkarusErrorData * error_out); +/// \return The id of the entity or 0 if an error occurs. +IKA_API int64_t +ikarus_entity_get_id(IkarusEntity const * entity, IkarusErrorData * error_out); /// \brief Gets the project an entity is part of. /// \param entity The entity to get the project of. @@ -69,7 +67,10 @@ IKA_API IkarusId ikarus_entity_get_id(IkarusEntity const * entity, IkarusErrorDa /// \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); +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. @@ -77,7 +78,10 @@ IKA_API IkarusProject * ikarus_entity_get_project(IkarusEntity const * entity, I /// \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); +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. @@ -85,10 +89,12 @@ IKA_API char const * ikarus_entity_get_name(IkarusEntity const * entity, IkarusE /// \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); +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. @@ -99,8 +105,11 @@ IKA_API void ikarus_entity_set_name(IkarusEntity * entity, char const * name, Ik /// \pre \li Must exist. /// \param error_out \see errors.h /// \return True if the entity is linked to the blueprint, false otherwise. -IKA_API bool -ikarus_entity_is_linked_to_blueprint(IkarusEntity const * entity, struct IkarusBlueprint const * blueprint, IkarusErrorData * error_out); +IKA_API bool ikarus_entity_is_linked_to_blueprint( + IkarusEntity const * entity, + struct IkarusBlueprint const * blueprint, + IkarusErrorData * error_out +); /// \brief Links an entity to a blueprint. /// \param entity The entity to link. @@ -111,10 +120,14 @@ ikarus_entity_is_linked_to_blueprint(IkarusEntity const * entity, struct IkarusB /// \pre \li Must exist. /// \param error_out \see errors.h /// \remark No-op if the entity is already linked to the blueprint. -IKA_API void ikarus_entity_link_to_blueprint(IkarusEntity * entity, struct IkarusBlueprint * blueprint, IkarusErrorData * error_out); +IKA_API void ikarus_entity_link_to_blueprint( + IkarusEntity * entity, + struct IkarusBlueprint * blueprint, + IkarusErrorData * error_out +); -/// \brief Unlinks an entity from a blueprint. All values of the properties of the blueprint the entity is linked with -/// will be deleted. +/// \brief Unlinks an entity from a blueprint. +/// All values of the blueprints' properties will be deleted. /// \param entity The entity to unlink. /// \pre \li Must not be null. /// \pre \li Must exist. @@ -123,9 +136,13 @@ IKA_API void ikarus_entity_link_to_blueprint(IkarusEntity * entity, struct Ikaru /// \pre \li Must exist. /// \param error_out \see errors.h /// \remark No-op if the entity is not linked to the blueprint. -IKA_API void ikarus_entity_unlink_from_blueprint(IkarusEntity * entity, struct IkarusBlueprint * blueprint, IkarusErrorData * error_out); +IKA_API void ikarus_entity_unlink_from_blueprint( + IkarusEntity * entity, + struct IkarusBlueprint * blueprint, + IkarusErrorData * error_out +); -/// \brief Gets the blueprints an entity is linked to. +/// \brief Gets all blueprints an entity is linked to. /// \param entity The entity to get the blueprints of. /// \pre \li Must not be null. /// \pre \li Must exist. @@ -142,14 +159,80 @@ IKA_API void ikarus_entity_get_linked_blueprints( ); /// \brief Gets the number of blueprints an entity is linked to. -/// \param entity The entity to get the number of blueprints of. +/// \param entity The entity to get the number of linked 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_entity_get_linked_blueprint_count(IkarusEntity const * entity, IkarusErrorData * error_out); +IKA_API size_t ikarus_entity_get_linked_blueprint_count( + IkarusEntity const * entity, + IkarusErrorData * error_out +); -/// \brief Checks if an entity has a specific property. +/// \brief Checks if an entity has a value with a given name. +/// \param entity The entity to check. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param name The name of the value to check. +/// \pre \li Must not be null. +/// \param error_out \see errors.h +/// \return False if the entity does not have a value associated with +/// the name or if an error occurs, true otherwise. +IKA_API bool ikarus_entity_has_value( + IkarusEntity const * entity, + char const * name, + IkarusErrorData * error_out +); + +/// \brief Gets the value of an entity. +/// \param entity The entity to get the value of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param name The name of the value to get. +/// \pre \li Must not be null. +/// \pre \li Must be an existing value of the entity. +/// \param error_out \see errors.h +/// \return The value of the entity or null if an error occurs. +IKA_API struct IkarusValue * ikarus_entity_get_value( + IkarusEntity const * entity, + char const * name, + IkarusErrorData * error_out +); + +/// \brief Sets the value of an entity. +/// If the entity does not have a value associated with the name, it is created. +/// \remark Types are overwritten if the value already exists. +/// \param entity The entity to set the value of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param name The name of the value to set. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param value The new value of the entity. +/// \pre \li Must not be null. +/// \param error_out \see errors.h +IKA_API void ikarus_entity_set_value( + IkarusEntity * entity, + char const * name, + struct IkarusValue const * value, + IkarusErrorData * error_out +); + +/// \brief Removes a value from an entity. +/// \pre \li The value must exist. +/// \param entity The entity to delete the value of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param name The name of the value to delete. +/// \pre \li Must not be null. +/// \param error_out \see errors.h +IKA_API void ikarus_entity_remove_value( + IkarusEntity * entity, + char const * name, + IkarusErrorData * error_out +); + +/// \brief Checks if a property is linked to an entity. /// \param entity The entity to check. /// \pre \li Must not be null. /// \pre \li Must exist. @@ -157,14 +240,19 @@ IKA_API size_t ikarus_entity_get_linked_blueprint_count(IkarusEntity const * ent /// \pre \li Must not be null. /// \pre \li Must exist. /// \param error_out \see errors.h -/// \return False if an error occurs or the entity does not have the property, true otherwise. -IKA_API bool ikarus_entity_has_property(IkarusEntity const * entity, struct IkarusProperty const * property, IkarusErrorData * error_out); +/// \return False if an error occurs or the entity does not have the property, +/// true otherwise. +IKA_API bool ikarus_entity_has_property( + IkarusEntity const * entity, + struct IkarusProperty const * property, + IkarusErrorData * error_out +); -/// \brief Gets the properties of an entity. -/// \param entity The entity to get the properties of. +/// \brief Gets the properties an entity is linked to. +/// \param entity The entity to get the linked properties of. /// \pre \li Must not be null. /// \pre \li Must exist. -/// \param properties_out The buffer to write the properties to. +/// \param properties_out The buffer to write the linked properties to. /// \pre \li Must not be null. /// \param error_out \see errors.h /// \param properties_out_size The size of the buffer. @@ -176,30 +264,37 @@ IKA_API void ikarus_entity_get_properties( IkarusErrorData * error_out ); -/// \brief Gets the number of properties of an entity. -/// \param entity The entity to get the number of properties of. +/// \brief Gets the number of properties an entity is linked to. +/// \param entity The entity to get the number of linked properties of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param error_out \see errors.h /// \return The number of properties or undefined if an error occurs. -IKA_API size_t ikarus_entity_get_property_count(IkarusEntity const * entity, IkarusErrorData * error_out); +IKA_API size_t ikarus_entity_get_property_count( + IkarusEntity const * entity, + IkarusErrorData * error_out +); /// \brief Gets the value of a property of an entity. -/// \details If the entity has never set the value of the property, the default value is returned (which may be undefined). +/// \details If the entity has never set the value of the property, +/// the property's default value is returned. /// \param entity The entity to get the value of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param property The property to get the value of. /// \pre \li Must not be null. /// \pre \li Must exist. +/// \pre \li Must be linked to the entity. /// \param error_out \see errors.h -/// \return The value of the property or null if the entity does not have the property or an error occurs. -/// \remark Must be freed using #ikarus_free. -IKA_API struct IkarusEntityPropertyValue * -ikarus_entity_get_value(IkarusEntity const * entity, struct IkarusProperty const * property, IkarusErrorData * error_out); +/// \return The value of the property or null if an error occurs. +IKA_API struct IkarusValue * ikarus_entity_get_property_value( + IkarusEntity const * entity, + struct IkarusProperty const * property, + IkarusErrorData * error_out +); /// \brief Sets the value of a property of an entity. -/// \param entity The entity to set the value of. +/// \param entity The entity to set the property value of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param property The property to set the value of. @@ -211,7 +306,7 @@ ikarus_entity_get_value(IkarusEntity const * entity, struct IkarusProperty const /// \pre \li Must be valid for the property's settings. /// \param error_out \see errors.h /// \remark If the entity does not have the property, this function fails. -IKA_API void ikarus_entity_set_value( +IKA_API void ikarus_entity_set_property_value( IkarusEntity * entity, struct IkarusProperty const * property, struct IkarusValue const * value, diff --git a/include/ikarus/objects/object.h b/include/ikarus/objects/object.h deleted file mode 100644 index 6a46e17..0000000 --- a/include/ikarus/objects/object.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -/// \file object.h -/// \author Folling - -#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: -/// - \ref blueprint.h "Blueprints" -/// - \ref property.h "Properties" -/// - \ref entity.h "Entities" -/// @{ - -IKARUS_BEGIN_HEADER - -/// \brief A generic object. Wraps all types of objects, including folders. -struct IkarusObject; - -/// \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. -/// \param property_visitor The function to call if the object is a property. Skipped if null. -/// \param entity_visitor The function to call if the object is an entity. Skipped if null. -/// \param data The data passed to the visitor functions. -/// \param error_out \see errors.h -IKA_API 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 -); - -/// \see ikarus_object_visit -IKA_API 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_END_HEADER - -/// @} diff --git a/include/ikarus/objects/object_type.h b/include/ikarus/objects/object_type.h deleted file mode 100644 index e30bb3c..0000000 --- a/include/ikarus/objects/object_type.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -/// \file object_type.h -/// \author Folling - -#include -#include - -/// \addtogroup objects Objects -/// @{ - -IKARUS_BEGIN_HEADER - -/// \brief The type of an object. -enum IkarusObjectType { - /// \brief Not an object or no object. - IkarusObjectType_None = 0, - /// \brief An IkarusEntity. - IkarusObjectType_Entity = 0b00000001, - /// \brief An IkarusBlueprint. - IkarusObjectType_Blueprint = 0b00000010, - /// \brief An IkarusProperty. - IkarusObjectType_Property = 0b00000011, -}; - -/// \brief Converts an IkarusObjectType to a string. -/// \param type The type to convert. -/// \return The string representation of the type. -/// \remark The returned string must not be freed. -char const * ikarus_object_type_to_string(IkarusObjectType type); - -IKARUS_END_HEADER - -/// @} diff --git a/include/ikarus/objects/properties/number_property.h b/include/ikarus/objects/properties/number_property.h index 2fcf63b..d989ec2 100644 --- a/include/ikarus/objects/properties/number_property.h +++ b/include/ikarus/objects/properties/number_property.h @@ -20,7 +20,6 @@ struct IkarusNumberProperty; /// \pre \li Must exist. /// \param name The name of the property. /// \pre \li Must not be null. -/// \pre \li Must not be empty. /// \param property_source The property source to create the property for. /// \pre \li Must not be null. /// \pre \li Must exist. @@ -36,31 +35,6 @@ IKA_API IkarusNumberProperty * ikarus_number_property_create( IkarusErrorData * error_out ); -/// \brief Sets the default value for a number property. -/// \param property The number property. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param error_out \see errors.h -/// \return The default value or null if an error occurs. -IKA_API struct IkarusNumberValue * -ikarus_number_property_get_default_value(struct IkarusNumberProperty * property, IkarusErrorData * error_out); - -/// \brief Sets the default value for a number property. -/// \param property The number property. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param new_default_value The default value. -/// \pre \li Must not be null. -/// \pre \li Must be a valid value for the property. -/// \param error_out \see errors.h -/// \remark Please see \ref property.h "the property documentation" for more information on the interplay between -/// default values and other settings. -IKA_API void ikarus_number_property_set_default_value( - struct IkarusNumberProperty * property, - struct IkarusNumberValue * new_default_value, - IkarusErrorData * error_out -); - IKARUS_END_HEADER /// @} diff --git a/include/ikarus/objects/properties/property.h b/include/ikarus/objects/properties/property.h index aa52b2c..c7ba19b 100644 --- a/include/ikarus/objects/properties/property.h +++ b/include/ikarus/objects/properties/property.h @@ -4,10 +4,10 @@ /// \author Folling #include -#include #include -#include #include +#include +#include /// \defgroup properties Properties /// \brief Properties define the structure and types of data. @@ -15,9 +15,10 @@ IKARUS_BEGIN_HEADER -/// \brief Properties are the placeholders of values for entities. -/// \details Each entity can have any number of properties. +/// \brief Properties define the structure of blueprints. +/// \details Each blueprint can have any number of properties. /// Every property has a type that identifies the kind of data that can be put in. +/// This is the "base class" of properties. See the derived types (e.g. IkarusToggleProperty) for more information. /// /// The following types currently exist: /// - Toggle: A true/false boolean-like value @@ -29,32 +30,10 @@ IKARUS_BEGIN_HEADER /// - 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: -/// - List -/// - May be undefined -/// -/// Additionally, each property has a default value. If no default value is provided, a sensible default is chosen. -/// Setting a default value that isn't valid for the property is an error. Changing settings so that the current default -/// value becomes invalid is valid but unsets the custom default value. -/// -/// 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. +/// \remark Values for properties are lazily created to save space. /// 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; /// \brief Deletes a property. @@ -71,7 +50,7 @@ IKA_API void ikarus_property_delete(IkarusProperty * property, IkarusErrorData * /// \pre \li Must exist. /// \param error_out \see errors.h /// \return The ID of the property or 0 if an error occurs. -IKA_API IkarusId ikarus_property_get_id(IkarusProperty const * property, IkarusErrorData * error_out); +IKA_API int64_t ikarus_property_get_id(IkarusProperty const * property, IkarusErrorData * error_out); /// \brief Gets the project of a property. /// \param property The property to get the project of. @@ -81,31 +60,66 @@ IKA_API IkarusId ikarus_property_get_id(IkarusProperty const * property, IkarusE /// \return The project of the property or null if an error occurs. IKA_API struct IkarusProject * ikarus_property_get_project(IkarusProperty const * property, IkarusErrorData * error_out); +/// \brief Gets the name of an property. +/// \param entity The property 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 property or null if an error occurs. +IKA_API char const * ikarus_property_get_name(IkarusProperty const * entity, IkarusErrorData * error_out); + +/// \brief Sets the name of an property. +/// \param entity The property to set the name of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param name The new name of the property. +/// \pre \li Must not be null. +/// \param error_out \see errors.h +IKA_API void ikarus_property_set_name(IkarusProperty * entity, char const * name, IkarusErrorData * error_out); + /// \brief Gets the type info of a property. /// \param property The property to get the type info of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \param error_out \see errors.h /// \return The type info of the property or null if an error occurs. -IKA_API IkarusPropertyType ikarus_property_get_type(IkarusProperty const * property, IkarusErrorData * error_out); +/// \remark Changing the type of a property is not supported. This is because the property would need to change +IKA_API IkarusValueType ikarus_property_get_type(IkarusProperty const * property, IkarusErrorData * error_out); -/// \brief Gets the source of a property. +// there is no `set_type` as we encode type information in the underlying datatype + +/// \briefs Gets a property's cardinality. +/// \param property The property to get the cardinality of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param error_out \see errors.h +/// \return The cardinality of the property or false if an error occurs. +IKA_API IkarusValueCardinality ikarus_property_get_cardinality(IkarusProperty const * property, IkarusErrorData * error_out); + +/// \briefs Sets a property's default value. +/// \param property The property to set the cardinality of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \\param cardinality The new cardinality of the property. +/// \param error_out \see errors.h +IKA_API void +ikarus_property_set_cardinality(IkarusProperty * property, IkarusValueCardinality cardinality, IkarusErrorData * error_out); + +/// \briefs Gets a property's default value. +/// \param property The property to get the default value of. +/// \pre \li Must not be null. +/// \pre \li Must exist. +/// \param error_out \see errors.h +/// \return The default value of the property or null if an error occurs. +IKA_API struct IkarusValue * ikarus_property_get_default_value(IkarusProperty const * property, IkarusErrorData * error_out); + +/// \brief Gets the source blueprint of a property. /// \param property The property to get the source of. /// \pre \li Must not be null. /// \pre \li Must exist. /// \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 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. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param error_out \see errors.h -/// \return The default value of the property or null if an error occurs. -/// \remark Must be freed using #ikarus_free. -IKA_API struct IkarusValue * ikarus_property_get_default_value(IkarusProperty const * property, IkarusErrorData * error_out); +IKA_API struct IkarusBlueprint * ikarus_property_get_blueprint(IkarusProperty const * property, IkarusErrorData * error_out); /// \brief Visits a property. Calling the appropriate function for the property's type. /// \param property The property to visit. @@ -125,28 +139,6 @@ IKA_API void ikarus_property_visit( IkarusErrorData * error_out ); -/// \see ikarus_property_visit -IKA_API void ikarus_property_visit_const( - IkarusProperty const * property, - void (*toggle_property_visitor)(struct IkarusToggleProperty const *, void *), - void (*number_property_visitor)(struct IkarusNumberProperty const *, void *), - void (*text_property_visitor)(struct IkarusTextProperty const *, void *), - void * data, - IkarusErrorData * error_out -); - -/// \brief Casts a property to an object. -/// \param property The property to cast. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param error_out \see errors.h -/// \return The property represented as an object or null if an error occurs. -/// \remark This operation is guaranteed to be very fast and is intended to be used frequently. -IKA_API struct IkarusObject * ikarus_property_to_object(IkarusProperty * property, IkarusErrorData * error_out); - -/// \see ikarus_property_to_object -IKA_API struct IkarusObject const * ikarus_property_to_object_const(IkarusProperty const * property, IkarusErrorData * error_out); - IKARUS_END_HEADER // @} diff --git a/include/ikarus/objects/properties/property_scope.h b/include/ikarus/objects/properties/property_scope.h deleted file mode 100644 index a211e67..0000000 --- a/include/ikarus/objects/properties/property_scope.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -/// \file property_source.h -/// \author Folling - -#include -#include - -/// \addtogroup properties Properties -/// @{ - -IKARUS_BEGIN_HEADER - -struct IkarusPropertyScope; - -/// \brief Creates an blueprint property source. -/// \param blueprint The blueprint to create the property source for. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \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 IkarusPropertyScope * -ikarus_property_source_create_blueprint(struct IkarusBlueprint * blueprint, IkarusErrorData * error_out); - -/// \brief Creates an entity property source. -/// \param entity The entity to create the property source for. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \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 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. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param blueprint_visitor The callback to call if the source is a blueprint, skipped if null. -/// \param entity_visitor The callback to call if the source is an entity, skipped if null. -/// \param user_data User data to pass to the callbacks. -/// \param error_out \see errors.h -IKA_API void ikarus_property_source_visit( - struct IkarusPropertyScope * property_source, - void (*blueprint_visitor)(struct IkarusBlueprint *, void *), - void (*entity_visitor)(struct IkarusEntity *, void *), - void * user_data, - IkarusErrorData * error_out -); - -/// \see ikarus_property_source_visit -IKA_API void ikarus_property_source_visit_const( - struct IkarusPropertyScope const * property_source, - void (*blueprint_visitor)(struct IkarusBlueprint const *, void *), - void (*entity_visitor)(struct IkarusEntity const *, void *), - void * user_data, - IkarusErrorData * error_out -); - -IKARUS_END_HEADER - -/// @} diff --git a/include/ikarus/objects/properties/property_type.h b/include/ikarus/objects/properties/property_type.h deleted file mode 100644 index 893cdca..0000000 --- a/include/ikarus/objects/properties/property_type.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -/// \file property_type.h -/// \author Folling - -#include - -/// \addtogroup properties Properties -/// @{ - -IKARUS_BEGIN_HEADER - -/// \brief The type of a property. -/// \details Designates the type of data stored by the property as well as which settings are -/// available. -enum IkarusPropertyType { - /// \brief A true/false boolean-esque value. - IkarusPropertyType_Toggle = 0x10000000, - /// \brief A numeric value, limited to IEEE 80 bit floating point numbers. - IkarusPropertyType_Number = 0x20000000, - /// \brief An arbitrary UTF-8 textual value. - IkarusPropertyType_Text = 0x30000000, -}; - -IKARUS_END_HEADER - -/// @} diff --git a/include/ikarus/objects/properties/text_property.h b/include/ikarus/objects/properties/text_property.h index 5e59d92..a0c0a9d 100644 --- a/include/ikarus/objects/properties/text_property.h +++ b/include/ikarus/objects/properties/text_property.h @@ -20,7 +20,6 @@ struct IkarusTextProperty; /// \pre \li Must exist. /// \param name The name of the property. /// \pre \li Must not be null. -/// \pre \li Must not be empty. /// \param property_source The property source to create the property for. /// \pre \li Must not be null. /// \pre \li Must exist. @@ -32,31 +31,7 @@ IKA_API IkarusTextProperty * ikarus_text_property_create( struct IkarusProject * project, char const * name, struct IkarusPropertySource * property_source, - struct IkarusTextValue* default_value, - IkarusErrorData * error_out -); - -/// \brief Sets the default value for a text property. -/// \param property The text property. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param error_out \see errors.h -/// \return The default value or null if an error occurs. -IKA_API struct IkarusTextValue * ikarus_text_property_get_default_value(struct IkarusTextProperty * property, IkarusErrorData * error_out); - -/// \brief Sets the default value for a text property. -/// \param property The text property. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param new_default_value The default value. -/// \pre \li Must not be null. -/// \pre \li Must be a valid value for the property. -/// \param error_out \see errors.h -/// \remark Please see \ref property.h "the property documentation" for more information on the interplay between -/// default values and other settings. -IKA_API void ikarus_text_property_set_default_value( - struct IkarusTextProperty * property, - struct IkarusTextValue * new_default_value, + struct IkarusTextValue * default_value, IkarusErrorData * error_out ); diff --git a/include/ikarus/objects/properties/toggle_property.h b/include/ikarus/objects/properties/toggle_property.h index 403f392..bfec311 100644 --- a/include/ikarus/objects/properties/toggle_property.h +++ b/include/ikarus/objects/properties/toggle_property.h @@ -7,11 +7,11 @@ #include /// \addtogroup properties Properties -/// \brief Toggle properties store a value that can be either true or false. (e.g. "Is the character dead?") /// @{ IKARUS_BEGIN_HEADER +/// \brief Toggle properties store a value that can be either true or false. (e.g. "Is the character dead?") struct IkarusToggleProperty; /// \brief Creates a toggle property. @@ -20,44 +20,15 @@ struct IkarusToggleProperty; /// \pre \li Must exist. /// \param name The name of the property. /// \pre \li Must not be null. -/// \pre \li Must not be empty. /// \param property_source The property source to create the property for. /// \pre \li Must not be null. /// \pre \li Must exist. -/// \param default_value The default value for the property. -/// \pre \li Must not be null. /// \param error_out \see errors.h /// \return The created property or null if an error occurs. IKA_API IkarusToggleProperty * ikarus_toggle_property_create( struct IkarusProject * project, char const * name, struct IkarusPropertySource * property_source, - struct IkarusToggleValue * default_value, - IkarusErrorData * error_out -); - -/// \brief Sets the default value for a toggle property. -/// \param property The toggle property. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param error_out \see errors.h -/// \return The default value or null if an error occurs. -IKA_API struct IkarusToggleValue * -ikarus_toggle_property_get_default_value(struct IkarusToggleProperty * property, IkarusErrorData * error_out); - -/// \brief Sets the default value for a toggle property. -/// \param property The toggle property. -/// \pre \li Must not be null. -/// \pre \li Must exist. -/// \param new_default_value The default value. -/// \pre \li Must not be null. -/// \pre \li Must be a valid value for the property. -/// \param error_out \see errors.h -/// \remark Please see \ref property.h "the property documentation" for more information on the interplay between -/// default values and other settings. -IKA_API void ikarus_toggle_property_set_default_value( - struct IkarusToggleProperty * property, - struct IkarusToggleValue * new_default_value, IkarusErrorData * error_out ); diff --git a/include/ikarus/persistence/project.h b/include/ikarus/persistence/project.h index 18a35f5..74258a9 100644 --- a/include/ikarus/persistence/project.h +++ b/include/ikarus/persistence/project.h @@ -30,7 +30,11 @@ struct IkarusProject; /// \return The created project or null if an error occurs. /// \remark Must be freed using #ikarus_free. Freeing does not delete the project from the filesystem. For that, use /// ikarus_project_delete -IKA_API IkarusProject * ikarus_project_create(char const * path, char const * name, IkarusErrorData * error_out); +IKA_API IkarusProject * ikarus_project_create( + char const * path, + char const * name, + IkarusErrorData * error_out +); /// \brief Creates a project in memory. /// \param name The name of the project. Must neither be null nor empty. @@ -40,7 +44,8 @@ IKA_API IkarusProject * ikarus_project_create(char const * path, char const * na /// \return The created project or null if an error occurs. /// \remark Must be freed using #ikarus_free. Freeing does not delete the project from the filesystem. For that, use /// ikarus_project_delete -IKA_API IkarusProject * ikarus_project_create_in_memory(char const * name, IkarusErrorData * error_out); +IKA_API IkarusProject * +ikarus_project_create_in_memory(char const * name, IkarusErrorData * error_out); /// \brief Opens an existing project. /// \param path The path to the project. @@ -50,7 +55,8 @@ IKA_API IkarusProject * ikarus_project_create_in_memory(char const * name, Ikaru /// \return The opened project or null if an error occurs. /// \remark Must be freed using ikarus_free. Freeing does not delete the project from the filesystem. For that, use /// ikarus_project_delete -IKA_API IkarusProject * ikarus_project_open(char const * path, IkarusErrorData * error_out); +IKA_API IkarusProject * +ikarus_project_open(char const * path, IkarusErrorData * error_out); /// \brief Gets the name of a project. /// \param project The project to get the name of. @@ -59,7 +65,10 @@ IKA_API IkarusProject * ikarus_project_open(char const * path, IkarusErrorData * /// \param error_out \see errors.h /// \return The name of the project. /// \remark Ownership remains with libikarus, must not be freed. -IKA_API char const * ikarus_project_get_name(IkarusProject const * project, IkarusErrorData * error_out); +IKA_API char const * ikarus_project_get_name( + IkarusProject const * project, + IkarusErrorData * error_out +); /// \brief Sets the name of a project. /// \param project The project to set the name of. @@ -69,7 +78,11 @@ IKA_API char const * ikarus_project_get_name(IkarusProject const * project, Ikar /// \pre \li Must not be null. /// \pre \li Must not be empty. /// \param error_out \see errors.h -IKA_API void ikarus_project_set_name(IkarusProject * project, char const * new_name, IkarusErrorData * error_out); +IKA_API void ikarus_project_set_name( + IkarusProject * project, + char const * new_name, + IkarusErrorData * error_out +); /// \brief Gets the path of a project. /// \param project The project to get the path of. @@ -78,7 +91,10 @@ IKA_API void ikarus_project_set_name(IkarusProject * project, char const * new_n /// \param error_out \see errors.h /// \return The path of the project. /// \remark Ownership remains with libikarus, must not be freed. -IKA_API char const * ikarus_project_get_path(IkarusProject const * project, IkarusErrorData * error_out); +IKA_API char const * ikarus_project_get_path( + IkarusProject const * project, + IkarusErrorData * error_out +); /// \brief Gets the entities of a project. /// \param project The project to get the entities of. @@ -101,7 +117,10 @@ IKA_API void ikarus_project_get_entities( /// \pre \li Must exist. /// \param error_out \see errors.h /// \return The number of entities or undefined if an error occurs. -IKA_API size_t ikarus_project_get_entity_count(IkarusProject const * project, IkarusErrorData * error_out); +IKA_API size_t ikarus_project_get_entity_count( + IkarusProject const * project, + IkarusErrorData * error_out +); /// \brief Gets the blueprints of a project. /// \param project The project to get the blueprints of. @@ -124,51 +143,11 @@ IKA_API void ikarus_project_get_blueprints( /// \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 * ikarus_project_get_entity_by_name(IkarusProject * 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 * ikarus_project_get_property_by_name_and_scope( - IkarusProject * project, - struct IkarusPropertyScope * scope, - char const * name, +IKA_API size_t ikarus_project_get_blueprint_count( + IkarusProject const * project, 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 * -ikarus_project_get_blueprint_by_name(IkarusProject * project, char const * name, IkarusErrorData * error_out); - IKARUS_END_HEADER /// @} diff --git a/include/ikarus/values/entity_property_value.h b/include/ikarus/values/entity_property_value.h deleted file mode 100644 index c408f00..0000000 --- a/include/ikarus/values/entity_property_value.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -/// \file entity_property_value.h -/// \author Folling - -/// \defgroup entity_property_values EntityPropertyValue -/// \brief Values in relation to an entity and one of its properties. -/// @{ - -#include -#include -#include - -IKARUS_BEGIN_HEADER - -/// \brief Like an \ref value.h "IkarusValue", but in relation to an entity and one of its properties -struct IkarusEntityPropertyValue; - -/// \brief Fetches the entity of an entity property value. -/// \param value The entity property value. -/// \pre \li Must not be null. -/// \param error_out \see errors.h -/// \return The entity of the entity property value. -/// \remark This value is owned by the entity property value and must not be freed directly. -struct IkarusEntity const * ikarus_entity_property_value_get_entity(IkarusEntityPropertyValue const * value, IkarusErrorData * error_out); - -/// \brief Fetches the property of an entity property value. -/// \param value The entity property value. -/// \pre \li Must not be null. -/// \param error_out \see errors.h -/// \return The property of the entity property value. -/// \remark This value is owned by the entity property value and must not be freed directly. -struct IkarusProperty const * -ikarus_entity_property_value_get_property(IkarusEntityPropertyValue const * value, IkarusErrorData * error_out); - -/// \brief Fetches the value of an entity property value. -/// \param value The entity property value. -/// \pre \li Must not be null. -/// \param error_out \see errors.h -/// \return The value of the entity property value. -/// \remark This value is owned by the entity property value and must not be freed directly. -struct IkarusValue const * ikarus_entity_property_value_get_value(IkarusEntityPropertyValue const * value, IkarusErrorData * error_out); - -IKARUS_END_HEADER - -/// @} diff --git a/include/ikarus/values/number_value.h b/include/ikarus/values/number_value.h index 1425fed..220a11c 100644 --- a/include/ikarus/values/number_value.h +++ b/include/ikarus/values/number_value.h @@ -5,6 +5,7 @@ #include #include +#include /// \addtogroup values Values /// @{ @@ -15,10 +16,11 @@ IKARUS_BEGIN_HEADER struct IkarusNumberValue; /// \brief Creates an empty number value. +/// \details If the cardinality is "Single", the value will be initialized with 0.0. +/// \param cardinality The cardinality of the value. /// \param error_out \see errors.h /// \return The value or null if an error occurs. -/// \remark Must be freed with #ikarus_free. -IKA_API IkarusNumberValue * ikarus_number_value_create(IkarusErrorData * error_out); +IKA_API IkarusNumberValue * ikarus_number_value_create(IkarusValueCardinality cardinality, IkarusErrorData * error_out); /// \brief Fetches the underlying data of a number value at a specific index. /// \param value The number value. @@ -26,14 +28,14 @@ IKA_API IkarusNumberValue * ikarus_number_value_create(IkarusErrorData * error_o /// \param idx The index of the data to fetch. /// \pre \li Must be less than the size of the value. /// \param error_out \see errors.h -/// \return The underlying data or NaN if an error occurs or the value is undefined. +/// \return The underlying data or NaN if an error occurs. IKA_API double ikarus_number_value_get(IkarusNumberValue const * value, size_t idx, IkarusErrorData * error_out); /// \brief Fetches the size of the underlying data of a number value. /// \param value The number value. /// \pre \li Must not be null. /// \param error_out \see errors.h -/// \return The size of the underlying data or 0 if an error occurs or the value is undefined. +/// \return The size of the underlying data or 0 if an error occurs. IKA_API size_t ikarus_number_value_get_size(IkarusNumberValue const * value, IkarusErrorData * error_out); /// \brief Sets the data of a number value at a specific index. @@ -45,53 +47,37 @@ IKA_API size_t ikarus_number_value_get_size(IkarusNumberValue const * value, Ika /// \param error_out \see errors.h IKA_API void ikarus_number_value_set(IkarusNumberValue * value, size_t idx, double new_data, IkarusErrorData * error_out); -/// \brief Removes a data from a number value. -/// \param value The number value. -/// \pre \li Must not be null. -/// \param idx The index of the data to remove. -/// \pre \li Must be less than the size of the value. -/// \param error_out \see errors.h -IKA_API void ikarus_number_value_remove(IkarusNumberValue * value, size_t idx, IkarusErrorData * error_out); - /// \brief Inserts a data into a number value. /// \param value The number value. /// \pre \li Must not be null. +/// \pre \li Cardinality must be "Multiple". /// \param idx The index of the data to insert. /// \pre \li Must be less than or equal to the size of the value. /// \param new_data The new data. /// \param error_out \see errors.h IKA_API void ikarus_number_value_insert(IkarusNumberValue * value, size_t idx, double new_data, IkarusErrorData * error_out); +/// \brief Removes a data from a number value. +/// \param value The number value. +/// \pre \li Must not be null. +/// \pre \li Cardinality must be "Multiple". +/// \param idx The index of the data to remove. +/// \pre \li Must be less than the size of the value. +/// \param error_out \see errors.h +IKA_API void ikarus_number_value_remove(IkarusNumberValue * value, size_t idx, IkarusErrorData * error_out); + /// \brief Clears a number value. /// \param value The number value. +/// \pre \li Cardinality must be "Multiple". /// \param error_out \see errors.h -/// \remark Noop if the value is undefined. IKA_API void ikarus_number_value_clear(IkarusNumberValue * value, IkarusErrorData * error_out); -/// \brief Checks if a number value is undefined. -/// \param value The number value. -/// \pre \li Must not be null. -/// \param error_out \see errors.h -/// \return True if the value is undefined, false otherwise. -IKA_API bool ikarus_number_value_is_undefined(IkarusNumberValue const * value, IkarusErrorData * error_out); - -/// \brief Changes a number value's undefined state. -/// \param value The number value. -/// \pre \li Must not be null. -/// \param undefined The new undefined state. -/// \param error_out \see errors.h -/// \remark Noop if the value is already undefined. -/// \remark If the value is set to undefined, all data will be cleared. -/// \remark If the value is set to not undefined, the value is as if newly created. -IKA_API void ikarus_number_value_set_undefined(IkarusNumberValue * value, bool undefined, IkarusErrorData * error_out); - /// \brief Converts a number value to a string. /// \param value The number value to convert. /// \pre \li Must not be null. /// \param error_out \see errors.h /// \return The converted string. /// \remark Must be freed with #ikarus_free. -/// \remark Undefined if the value is undefined. IKA_API char const * ikarus_number_value_to_string(IkarusNumberValue const * value, IkarusErrorData * error_out); /// \brief Checks if two values are equal. @@ -108,7 +94,6 @@ IKA_API bool ikarus_number_value_is_equal(IkarusNumberValue const * lhs, IkarusN /// \pre \li Must not be null. /// \param error_out \see errors.h /// \return The copied value. -/// \remark Must be freed with #ikarus_free. IKA_API IkarusNumberValue * ikarus_number_value_copy(IkarusNumberValue const * value, IkarusErrorData * error_out); /// \brief Converts a number value to an entity value. @@ -117,10 +102,7 @@ IKA_API IkarusNumberValue * ikarus_number_value_copy(IkarusNumberValue const * v /// \param error_out \see errors.h /// \return The converted entity value. /// \remark This is the same pointer, so freeing it implies freeing the original value. -IKA_API struct IkarusValue * ikarus_number_value_to_value(IkarusNumberValue * value, IkarusErrorData * error_out); - -/// \see ikarus_toggle_value_to_value -IKA_API struct IkarusValue const * ikarus_number_value_to_value_const(IkarusNumberValue const * value, IkarusErrorData * error_out); +IKA_API struct IkarusValueData * ikarus_number_value_to_value(IkarusNumberValue * value, IkarusErrorData * error_out); IKARUS_END_HEADER diff --git a/include/ikarus/values/text_value.h b/include/ikarus/values/text_value.h index 6511eb5..3b7d978 100644 --- a/include/ikarus/values/text_value.h +++ b/include/ikarus/values/text_value.h @@ -5,36 +5,37 @@ #include #include -#include +#include /// \addtogroup values Values /// @{ IKARUS_BEGIN_HEADER -/// \brief A textual value. For example "Surname" or "Description" +/// \brief A numeric value. For example "Age" or "Height". struct IkarusTextValue; /// \brief Creates an empty text value. +/// \details If the cardinality is "Single", the value will be initialized with 0.0. +/// \param cardinality The cardinality of the value. /// \param error_out \see errors.h /// \return The value or null if an error occurs. -/// \remark Must be freed with #ikarus_free. -IKA_API IkarusTextValue * ikarus_text_value_create(IkarusErrorData * error_out); +IKA_API IkarusTextValue * ikarus_text_value_create(IkarusValueCardinality cardinality, IkarusErrorData * error_out); -/// \brief Fetches the underlying data of a number value at a specific index. -/// \param value The number value. +/// \brief Fetches the underlying data of a text value at a specific index. +/// \param value The text value. /// \pre \li Must not be null. /// \param idx The index of the data to fetch. /// \pre \li Must be less than the size of the value. /// \param error_out \see errors.h -/// \return The underlying data or null if an error occurs or the value is undefined. -IKA_API char const * const * ikarus_text_value_get(IkarusTextValue const * value, size_t idx, IkarusErrorData * error_out); +/// \return The underlying data or NaN if an error occurs. +IKA_API char const * ikarus_text_value_get(IkarusTextValue const * value, size_t idx, IkarusErrorData * error_out); /// \brief Fetches the size of the underlying data of a text value. /// \param value The text value. /// \pre \li Must not be null. /// \param error_out \see errors.h -/// \return The size of the underlying data or 0 if an error occurs or the value is undefined. +/// \return The size of the underlying data or 0 if an error occurs. IKA_API size_t ikarus_text_value_get_size(IkarusTextValue const * value, IkarusErrorData * error_out); /// \brief Sets the data of a text value at a specific index. @@ -42,59 +43,41 @@ IKA_API size_t ikarus_text_value_get_size(IkarusTextValue const * value, IkarusE /// \pre \li Must not be null. /// \param idx The index of the data to set. /// \pre \li Must be less than the size of the value. -/// \param new_data The new data. Ownership remains with the caller. -/// \pre \li Must not be null. +/// \param new_data The new data. /// \param error_out \see errors.h IKA_API void ikarus_text_value_set(IkarusTextValue * value, size_t idx, char const * new_data, IkarusErrorData * error_out); +/// \brief Inserts a data into a text value. +/// \param value The text value. +/// \pre \li Must not be null. +/// \pre \li Cardinality must be "Multiple". +/// \param idx The index of the data to insert. +/// \pre \li Must be less than or equal to the size of the value. +/// \param new_data The new data. +/// \param error_out \see errors.h +IKA_API void ikarus_text_value_insert(IkarusTextValue * value, size_t idx, char const * new_data, IkarusErrorData * error_out); + /// \brief Removes a data from a text value. /// \param value The text value. /// \pre \li Must not be null. +/// \pre \li Cardinality must be "Multiple". /// \param idx The index of the data to remove. /// \pre \li Must be less than the size of the value. /// \param error_out \see errors.h IKA_API void ikarus_text_value_remove(IkarusTextValue * value, size_t idx, IkarusErrorData * error_out); -/// \brief Inserts a data into a text value. -/// \param value The text value. -/// \pre \li Must not be null. -/// \param idx The index of the data to insert. -/// \pre \li Must be less than or equal to the size of the value. -/// \param new_data The new data. Ownership remains with the caller. -/// \pre \li Must not be null. -/// \param error_out \see errors.h -IKA_API void ikarus_text_value_insert(IkarusTextValue * value, size_t idx, char const * new_data, IkarusErrorData * error_out); - /// \brief Clears a text value. /// \param value The text value. +/// \pre \li Cardinality must be "Multiple". /// \param error_out \see errors.h -/// \remark Noop if the value is undefined. IKA_API void ikarus_text_value_clear(IkarusTextValue * value, IkarusErrorData * error_out); -/// \brief Checks if a text value is undefined. -/// \param value The text value. -/// \pre \li Must not be null. -/// \param error_out \see errors.h -/// \return True if the value is undefined, false otherwise. -IKA_API bool ikarus_text_value_is_undefined(IkarusTextValue const * value, IkarusErrorData * error_out); - -/// \brief Changes a text value's undefined state. -/// \param value The text value. -/// \pre \li Must not be null. -/// \param undefined The new undefined state. -/// \param error_out \see errors.h -/// \remark Noop if the value is already undefined. -/// \remark If the value is set to undefined, all data will be cleared. -/// \remark If the value is set to not undefined, the value is as if newly created. -IKA_API void ikarus_text_value_set_undefined(IkarusTextValue * value, bool undefined, IkarusErrorData * error_out); - /// \brief Converts a text value to a string. /// \param value The text value to convert. /// \pre \li Must not be null. /// \param error_out \see errors.h /// \return The converted string. /// \remark Must be freed with #ikarus_free. -/// \remark Undefined if the value is undefined. IKA_API char const * ikarus_text_value_to_string(IkarusTextValue const * value, IkarusErrorData * error_out); /// \brief Checks if two values are equal. @@ -111,7 +94,6 @@ IKA_API bool ikarus_text_value_is_equal(IkarusTextValue const * lhs, IkarusTextV /// \pre \li Must not be null. /// \param error_out \see errors.h /// \return The copied value. -/// \remark Must be freed with #ikarus_free. IKA_API IkarusTextValue * ikarus_text_value_copy(IkarusTextValue const * value, IkarusErrorData * error_out); /// \brief Converts a text value to an entity value. @@ -120,10 +102,7 @@ IKA_API IkarusTextValue * ikarus_text_value_copy(IkarusTextValue const * value, /// \param error_out \see errors.h /// \return The converted entity value. /// \remark This is the same pointer, so freeing it implies freeing the original value. -IKA_API struct IkarusValue * ikarus_text_value_to_value(IkarusTextValue * value, IkarusErrorData * error_out); - -/// \see ikarus_text_value_to_value -IKA_API struct IkarusValue const * ikarus_text_value_to_value_const(IkarusTextValue const * value, IkarusErrorData * error_out); +IKA_API struct IkarusValueData * ikarus_text_value_to_value(IkarusTextValue * value, IkarusErrorData * error_out); IKARUS_END_HEADER diff --git a/include/ikarus/values/toggle_value.h b/include/ikarus/values/toggle_value.h index 9e1615b..05c5ddc 100644 --- a/include/ikarus/values/toggle_value.h +++ b/include/ikarus/values/toggle_value.h @@ -5,36 +5,37 @@ #include #include -#include +#include /// \addtogroup values Values /// @{ IKARUS_BEGIN_HEADER -/// \brief A true/false boolean-esque value. For example "Is Dead". +/// \brief A numeric value. For example "Age" or "Height". struct IkarusToggleValue; /// \brief Creates an empty toggle value. +/// \details If the cardinality is "Single", the value will be initialized with 0.0. +/// \param cardinality The cardinality of the value. /// \param error_out \see errors.h /// \return The value or null if an error occurs. -/// \remark Must be freed with #ikarus_free. -IKA_API IkarusToggleValue * ikarus_toggle_value_create(IkarusErrorData * error_out); +IKA_API IkarusToggleValue * ikarus_toggle_value_create(IkarusValueCardinality cardinality, IkarusErrorData * error_out); -/// \brief Fetches the underlying data of a number value at a specific index. -/// \param value The number value. +/// \brief Fetches the underlying data of a toggle value at a specific index. +/// \param value The toggle value. /// \pre \li Must not be null. /// \param idx The index of the data to fetch. /// \pre \li Must be less than the size of the value. /// \param error_out \see errors.h -/// \return The underlying data or null if an error occurs or the value is undefined. -IKA_API bool const * ikarus_toggle_value_get(IkarusToggleValue const * value, size_t idx, IkarusErrorData * error_out); +/// \return The underlying data or NaN if an error occurs. +IKA_API bool ikarus_toggle_value_get(IkarusToggleValue const * value, size_t idx, IkarusErrorData * error_out); /// \brief Fetches the size of the underlying data of a toggle value. /// \param value The toggle value. /// \pre \li Must not be null. /// \param error_out \see errors.h -/// \return The size of the underlying data or 0 if an error occurs or the value is undefined. +/// \return The size of the underlying data or 0 if an error occurs. IKA_API size_t ikarus_toggle_value_get_size(IkarusToggleValue const * value, IkarusErrorData * error_out); /// \brief Sets the data of a toggle value at a specific index. @@ -46,53 +47,37 @@ IKA_API size_t ikarus_toggle_value_get_size(IkarusToggleValue const * value, Ika /// \param error_out \see errors.h IKA_API void ikarus_toggle_value_set(IkarusToggleValue * value, size_t idx, bool new_data, IkarusErrorData * error_out); -/// \brief Removes a data from a toggle value. -/// \param value The toggle value. -/// \pre \li Must not be null. -/// \param idx The index of the data to remove. -/// \pre \li Must be less than the size of the value. -/// \param error_out \see errors.h -IKA_API void ikarus_toggle_value_remove(IkarusToggleValue * value, size_t idx, IkarusErrorData * error_out); - /// \brief Inserts a data into a toggle value. /// \param value The toggle value. /// \pre \li Must not be null. +/// \pre \li Cardinality must be "Multiple". /// \param idx The index of the data to insert. /// \pre \li Must be less than or equal to the size of the value. /// \param new_data The new data. /// \param error_out \see errors.h IKA_API void ikarus_toggle_value_insert(IkarusToggleValue * value, size_t idx, bool new_data, IkarusErrorData * error_out); +/// \brief Removes a data from a toggle value. +/// \param value The toggle value. +/// \pre \li Must not be null. +/// \pre \li Cardinality must be "Multiple". +/// \param idx The index of the data to remove. +/// \pre \li Must be less than the size of the value. +/// \param error_out \see errors.h +IKA_API void ikarus_toggle_value_remove(IkarusToggleValue * value, size_t idx, IkarusErrorData * error_out); + /// \brief Clears a toggle value. /// \param value The toggle value. +/// \pre \li Cardinality must be "Multiple". /// \param error_out \see errors.h -/// \remark Noop if the value is undefined. IKA_API void ikarus_toggle_value_clear(IkarusToggleValue * value, IkarusErrorData * error_out); -/// \brief Checks if a toggle value is undefined. -/// \param value The toggle value. -/// \pre \li Must not be null. -/// \param error_out \see errors.h -/// \return True if the value is undefined, false otherwise. -IKA_API bool ikarus_toggle_value_is_undefined(IkarusToggleValue const * value, IkarusErrorData * error_out); - -/// \brief Changes a toggle value's undefined state. -/// \param value The toggle value. -/// \pre \li Must not be null. -/// \param undefined The new undefined state. -/// \param error_out \see errors.h -/// \remark Noop if the value is already undefined. -/// \remark If the value is set to undefined, all data will be cleared. -/// \remark If the value is set to not undefined, the value is as if newly created. -IKA_API void ikarus_toggle_value_set_undefined(IkarusToggleValue * value, bool undefined, IkarusErrorData * error_out); - /// \brief Converts a toggle value to a string. /// \param value The toggle value to convert. /// \pre \li Must not be null. /// \param error_out \see errors.h /// \return The converted string. /// \remark Must be freed with #ikarus_free. -/// \remark Undefined if the value is undefined. IKA_API char const * ikarus_toggle_value_to_string(IkarusToggleValue const * value, IkarusErrorData * error_out); /// \brief Checks if two values are equal. @@ -109,7 +94,6 @@ IKA_API bool ikarus_toggle_value_is_equal(IkarusToggleValue const * lhs, IkarusT /// \pre \li Must not be null. /// \param error_out \see errors.h /// \return The copied value. -/// \remark Must be freed with #ikarus_free. IKA_API IkarusToggleValue * ikarus_toggle_value_copy(IkarusToggleValue const * value, IkarusErrorData * error_out); /// \brief Converts a toggle value to an entity value. @@ -118,10 +102,7 @@ IKA_API IkarusToggleValue * ikarus_toggle_value_copy(IkarusToggleValue const * v /// \param error_out \see errors.h /// \return The converted entity value. /// \remark This is the same pointer, so freeing it implies freeing the original value. -IKA_API struct IkarusValue * ikarus_toggle_value_to_value(IkarusToggleValue * value, IkarusErrorData * error_out); - -/// \see ikarus_toggle_value_to_value -IKA_API struct IkarusValue const * ikarus_toggle_value_to_value_const(IkarusToggleValue const * value, IkarusErrorData * error_out); +IKA_API struct IkarusValueData * ikarus_toggle_value_to_value(IkarusToggleValue * value, IkarusErrorData * error_out); IKARUS_END_HEADER diff --git a/include/ikarus/values/value.h b/include/ikarus/values/value.h index fbc50e1..aec86ac 100644 --- a/include/ikarus/values/value.h +++ b/include/ikarus/values/value.h @@ -4,14 +4,27 @@ /// \author Folling /// \defgroup values Values -/// \brief The values of properties. -/// \details Each entity has a value for each property it is associated with. -/// These value classes represent plain objects. They are not associated with any entity. -/// Each value may be undefined. \see IkarusProperty -/// Values are stored as lists. If a property is "singular" then its value is a list of size 1. -/// Values are typed, with types existing for each of the corresponding property types. The data of values starts with the index 0. -/// When setting values for a property the type must match the property type and the value must be valid under the -/// property's settings. \see PropertyType +/// \brief Values are data in entities. +/// \details An entity is made up of any number of values. +/// Each value defines a certain aspect of an entity. +/// Values have a name, a type, and some data. +/// Examples of values would be: +/// - Is Dead (Toggle) +/// - Age (Number) +/// - ISBN (Text) +/// +/// Values are either single or multiple. +/// We call this property "Cardinality" (\see IkarusValueCardinality) +/// because it's really hard to find a simpler name. +/// Each piece of data within a value is called a "datapoint". +/// Single values have exactly one datapoint, multiple values have any number of +/// datapoints. For example "Age" would be singular, while "Nicknames" would be +/// multiple. The type is unaffected by this. A pendant in programming languages +/// would be a List. Note that all values are stored as a list of items, +/// even if the value is singular. Single values effectively act as a list with +/// one element. This is enforced by the API at runtime. +/// +/// For a comprehensive list of value types, see \ref IkarusValueType. /// @{ #include @@ -19,15 +32,19 @@ IKARUS_BEGIN_HEADER -/// \brief The common type for all values. +/// \brief The common type for all value data. struct IkarusValue; -/// \brief Visits an entity value, calling the appropriate function for the value's type. +/// \brief Visits an entity value, +/// calling the appropriate function for the value's type. /// \param value The entity value to visit. /// \pre \li Must not be null. -/// \param toggle_visitor The function to call if the value is a toggle value. Skipped if null. -/// \param number_visitor The function to call if the value is a number value. Skipped if null. -/// \param text_visitor The function to call if the value is a text value. Skipped if null. +/// \param toggle_visitor The function to call if the value is a toggle value. +/// \remark Skipped if null. +/// \param number_visitor The function to call if the value is a number value. +/// \remark Skipped if null. +/// \param text_visitor The function to call if the value is a text value. +/// \remark Skipped if null. /// \param data The data passed to the visitor functions. /// \param error_out \see errors.h IKA_API void ikarus_value_visit( @@ -39,16 +56,6 @@ IKA_API void ikarus_value_visit( IkarusErrorData * error_out ); -/// \see ikarus_value_visit -IKA_API void ikarus_value_visit_const( - IkarusValue const * value, - void (*toggle_visitor)(struct IkarusToggleValue const *, void *), - void (*number_visitor)(struct IkarusNumberValue const *, void *), - void (*text_visitor)(struct IkarusTextValue const *, void *), - void * data, - IkarusErrorData * error_out -); - IKARUS_END_HEADER /// @} diff --git a/include/ikarus/values/value_cardinality.h b/include/ikarus/values/value_cardinality.h new file mode 100644 index 0000000..6d5526f --- /dev/null +++ b/include/ikarus/values/value_cardinality.h @@ -0,0 +1,23 @@ +#pragma once + +/// \file value_cardinality.h +/// \author Folling + +/// \addtogroup values Values +/// @{ + +#include + +IKARUS_BEGIN_HEADER + +/// \brief The cardinality of a value. +enum IkarusValueCardinality { + /// \brief Only contains one datapoint + IkarusValueCardinality_Single, + /// \brief Contains any number of datapoints + IkarusValueCardinality_List +}; + +IKARUS_END_HEADER + +/// @} diff --git a/include/ikarus/values/value_type.h b/include/ikarus/values/value_type.h new file mode 100644 index 0000000..caa6165 --- /dev/null +++ b/include/ikarus/values/value_type.h @@ -0,0 +1,198 @@ +#pragma once + +/// \file value_schema.h +/// \author Folling + +/// \addtogroup values Values +/// @{ + +#include +#include +#include + +IKARUS_BEGIN_HEADER + +/// \brief Layouts define the structure and constraints of values. +/// \details Ikarus lets you define any schema for values and add constraints to them. +/// These schemas are assembled hierarchical and are akin to JSON schemas. +/// Layouts may be arbitrarily nested and combined e.g.: +/// Combination, Number, Complex<"Foo":Toggle,"Bar":Text> +struct IkarusValueLayout; +/// \brief A fixed datapoint with a fixed layout. +/// Example: Age: Union> +struct IkarusValueLayoutConstant; +/// \brief A singular datapoint with one of a list of layouts. +/// Example: ChestReward: Combination +struct IkarusValueLayoutCombination; +/// \brief A collection of datapoints with a homogenous layout. +/// Example: Friends: List +struct IkarusValueLayoutList; +/// \brief A collection of nameable datapoints with heterogeneous layouts. +/// Example: GeoLocation: Complex<"Latitude":Number, "Longitude":Number> +struct IkarusValueLayoutComplex; + +/// \brief Defines the type of datapoints. +enum IkarusValueDataType { + /// \brief Boolean datapoints + /// Example: Is the character alive? Yes + Toggle, + /// \brief Numeric datapoints + /// Example: How much does the character weigh? 57kg + Number, + /// \brief Textual datapoints + /// Example: What is the character's maiden name? Sandra + Text, + /// \brief A colour datapoint + /// Example: What colours make up the nation's flag? White/Pink/Blue. + /// \remark Not yet implemented + Colour, + /// \brief A date/time datapoint, interfacing with the calendar and timeline feature. + /// Example: When was the city founded? 12th of January 233 at 2:11 + /// \remark Not yet implemented + Time, + /// \brief A location datapoint, interfacing with the map feature. + /// Example: Where is the city situated? 12.345, 67.890 + /// \remark Not yet implemented + Location, + /// \brief An enum-esque datapoint + /// Example: Of which rarity is the weapon? Normal/Rare/Legendary + /// \remark Not yet implemented + Choice, + /// \brief A datapoint linking to some other object in Ikarus + /// Example: Who wrote this hymn? Peter Parker + /// \remark Not yet implemented + Reference +}; + +/// \brief Stores either a schema or a datatype +struct IkarusValueSchema; + +/// \see ikarus_value_schema_from_layout_const +IkarusValueSchema * ikarus_value_schema_from_layout( + IkarusValueLayout * layout, + IkarusErrorData * error_out +); + +/// \brief Creates a value schema from a layout. +/// \param layout The layout to create the schema from. +/// \pre \li Must not be null. +/// \param error_out \see errors.h +/// \return The created schema or null if an error occurs. +IkarusValueSchema const * ikarus_value_schema_from_layout_const( + IkarusValueLayout const * layout, + IkarusErrorData * error_out +); + +/// \brief Creates a value schema from a datatype. +/// \param type The datatype to create the schema from. +/// \param error_out \see errors.h +/// \return The created schema or null if an error occurs. +IkarusValueSchema * ikarus_value_schema_from_data_type( + IkarusValueDataType type, + IkarusErrorData * error_out +); + +/// \brief Frees a value schema. +/// \param schema The schema to free. +/// \pre \li Must not be null. +/// \remark Must not be accessed after freeing. +void ikarus_value_schema_free(IkarusValueSchema * schema); + +/// \see ikarus_value_schema_visit_const +void ikarus_value_schema_visit( + IkarusValueSchema * schema, + void (*layout_visitor)(IkarusValueLayout * layout), + void (*data_type_visitor)(IkarusValueDataType type), + IkarusErrorData * error_out +); + +/// \brief Visits a value schema. +/// \param schema The schema to visit. +/// \pre \li Must not be null. +/// \param layout_visitor The function to call if the schema is a layout. Skipped if null. +/// \param data_type_visitor The function to call if the schema is a datatype. Skipped if null. +void ikarus_value_schema_visit_const( + IkarusValueSchema const * schema, + void (*layout_visitor)(IkarusValueLayout const * layout), + void (*data_type_visitor)(IkarusValueDataType type), + IkarusErrorData * error_out +); + +/// \brief Creates a constant layout. +/// \param schema The schema of the value. +/// \pre \li Must not be null. +/// \param value The value of the constant. +/// \pre \li Must not be null. +/// \param error_out \see errors.h +IkarusValueLayoutConstant * ikarus_value_layout_constant_create( + IkarusValueSchema * schema, + struct IkarusValue * value, + IkarusErrorData * error_out +); + +/// \brief Gets the underyling schema of a constant layout. +/// \param layout The layout to get the underyling schema of. +/// \pre \li Must not be null. +/// \param error_out \see errors.h +/// \return The underlying schema of the layout or null if an error occurs. +IkarusValueSchema const * ikarus_value_layout_constant_get_underyling_schema( + IkarusValueLayoutConstant const * layout, + IkarusErrorData * error_out +); + +/// \brief Gets the underyling value of a constant layout. +/// \param layout The layout to get the underyling value of. +/// \pre \li Must not be null. +/// \param error_out \see errors.h +/// \return The underlying value of the layout or null if an error occurs. +struct IkarusValue const * ikarus_value_layout_constant_get_underlying_value( + IkarusValueLayoutConstant const * layout, + IkarusErrorData * error_out +); + +/// \brief Creates a combination layout. +/// \param schemas The schemas of the values. +/// \pre \li Must not be null. +/// \param schemas_size The number of schemas. +/// \param error_out \see errors.h +/// \return The created layout or null if an error occurs. +/// \remark The schemas are copied. +IkarusValueLayoutCombination * ikarus_value_layout_combination_create( + IkarusValueSchema * schemas, + size_t schemas_size, + IkarusErrorData * error_out +); + +void ikarus_value_layout_combination_get_schemas( + IkarusValueLayoutCombination const * layout, + IkarusValueSchema ** schemas_out, + size_t * schemas_size_out, + IkarusErrorData * error_out +); + +size_t ikarus_value_layout_combination_get_schemas_count( + IkarusValueLayoutCombination const * layout, + IkarusErrorData * error_out +); + +IkarusValueLayoutList * ikarus_value_layout_list_create( + IkarusValueSchema * schema, + IkarusErrorData * error_out +); + +IkarusValueLayoutComplex * ikarus_value_layout_complex_create( + IkarusValueSchema * schemas, + size_t schemas_size, + IkarusErrorData * error_out +); + +IkarusValueLayoutComplex * ikarus_value_layout_complex_create_named( + IkarusValueSchema * schemas, + char const ** names, + size_t schemas_size, + IkarusErrorData * error_out +); + +IKARUS_END_HEADER + +/// @} diff --git a/src/ikarus/errors.cpp b/src/ikarus/errors.cpp index 35014f8..8f8ff3c 100644 --- a/src/ikarus/errors.cpp +++ b/src/ikarus/errors.cpp @@ -1,13 +1,5 @@ #include "ikarus/errors.h" -#include - -#include - -#include - -#include - char const * ikarus_get_error_info_name(IkarusErrorInfo info) { switch (info) { case IkarusErrorInfo_None: return "None"; diff --git a/src/ikarus/errors.hpp b/src/ikarus/errors.hpp index 0a9941f..e12a68f 100644 --- a/src/ikarus/errors.hpp +++ b/src/ikarus/errors.hpp @@ -78,16 +78,3 @@ inline void safe_strcpy(char * dest, std::string_view src, size_t dest_size) { #define IKARUS_VTRYRV_OR_FAIL(value, ret, msg, err_info, ...) \ IKARUS_VTRYRV_OR_FAIL_IMPL(CPPBASE_UNIQUE_NAME(result), value, ret, msg, err_info, __VA_ARGS__); - -#define IKARUS_FAIL_IF_OBJECT_MISSING_IMPL(var_name, obj, ret) \ - IKARUS_VTRYRV_OR_FAIL( \ - bool const var_name, \ - ret, \ - "unable to check whether object exists: {}", \ - IkarusErrorInfo_Database_QueryFailed, \ - (obj)->project->db->template query_one("SELECT EXISTS(SELECT 1 FROM `objects` WHERE `id` = ?)", (obj)->id) \ - ) \ - \ - IKARUS_FAIL_IF(!(var_name), ret, "object does not exist", IkarusErrorInfo_Client_Misuse); - -#define IKARUS_FAIL_IF_OBJECT_MISSING(obj, ret) IKARUS_FAIL_IF_OBJECT_MISSING_IMPL(CPPBASE_UNIQUE_NAME(exists), obj, ret); diff --git a/src/ikarus/global.cpp b/src/ikarus/global.cpp deleted file mode 100644 index 8b1929a..0000000 --- a/src/ikarus/global.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "ikarus/global.h" - -#include - -void ikarus_free(void * ptr) { - std::free(ptr); -} \ No newline at end of file diff --git a/src/ikarus/id.cpp b/src/ikarus/id.cpp deleted file mode 100644 index 9749667..0000000 --- a/src/ikarus/id.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "ikarus/id.h" - -#include - -uint64_t IKARUS_ID_OBJECT_TYPE_BITS = 8; -uint64_t IKARUS_ID_OBJECT_RANDOM_BITS = sizeof(IkarusId) * 8 - IKARUS_ID_OBJECT_TYPE_BITS; - -IkarusId ikarus_id_from_data_and_type(int64_t data, IkarusObjectType type) { - return data | (static_cast(type) << IKARUS_ID_OBJECT_RANDOM_BITS); -} - -IkarusObjectType ikarus_id_get_object_type(IkarusId id) { - return static_cast(id >> IKARUS_ID_OBJECT_RANDOM_BITS); -} diff --git a/src/ikarus/objects/blueprint.cpp b/src/ikarus/objects/blueprint.cpp index a1cf9e5..a2a5673 100644 --- a/src/ikarus/objects/blueprint.cpp +++ b/src/ikarus/objects/blueprint.cpp @@ -11,24 +11,27 @@ #include #include #include +#include -IkarusBlueprint::IkarusBlueprint(IkarusProject * project, IkarusId id): +IkarusBlueprint::IkarusBlueprint(IkarusProject * project, int64_t id): IkarusObject{project, id} {} +std::string_view IkarusBlueprint::get_table_name() const noexcept { + return "blueprints"; +} + IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project, char const * name, IkarusErrorData * error_out) { IKARUS_FAIL_IF_NULL(project, nullptr); - IKARUS_FAIL_IF_NAME_INVALID_OR_DUPLICATE(name, project, static_cast(nullptr), nullptr); + IKARUS_FAIL_IF_NAME_INVALID(name, nullptr); IKARUS_VTRYRV_OR_FAIL( - IkarusId const id, + int64_t const id, nullptr, "failed to create blueprint: {}", IkarusErrorInfo_Database_QueryFailed, - project->db->transact([name](auto * db) -> cppbase::Result { - TRY(db->execute("INSERT INTO `objects`(`type`) VALUES(?)", IkarusObjectType_Blueprint)); - auto id = ikarus_id_from_data_and_type(db->last_insert_rowid(), IkarusObjectType_Blueprint); - TRY(db->execute("INSERT INTO `blueprints`(`id`, `name`) VALUES(?, ?)", id, name)); - return cppbase::ok(id); + project->db->transact([name](auto * db) -> cppbase::Result { + TRY(db->execute("INSERT INTO `blueprints`(`name`) VALUES(?)", name)); + return cppbase::ok(db->last_insert_rowid()); }) ); @@ -43,13 +46,13 @@ void ikarus_blueprint_delete(IkarusBlueprint * blueprint, IkarusErrorData * erro , "unable to delete blueprint: {}", IkarusErrorInfo_Database_QueryFailed, - blueprint->project->db->execute("DELETE FROM `objects` WHERE `id` = ?", blueprint->id) + blueprint->project->db->execute("DELETE FROM `blueprints` WHERE `id` = ?", blueprint->id) ); blueprint->project->uncache(blueprint); } -IkarusId ikarus_blueprint_get_id(IkarusBlueprint const * blueprint, IkarusErrorData * error_out) { +int64_t ikarus_blueprint_get_id(IkarusBlueprint const * blueprint, IkarusErrorData * error_out) { return ikarus::util::object_get_id(blueprint, error_out); } @@ -79,14 +82,14 @@ void ikarus_blueprint_get_properties( return; } - std::tuple ids_and_types[properties_out_size]; + std::tuple ids_and_types[properties_out_size]; IKARUS_TRYRV_OR_FAIL( , "unable to fetch blueprint properties from database: {}", IkarusErrorInfo_Database_QueryFailed, - blueprint->project->db->query_many_buffered( - "SELECT `id` FROM `properties` WHERE `source` = ?", + blueprint->project->db->query_many_buffered( + "SELECT `id` FROM `properties` WHERE `blueprint` = ?", ids_and_types, properties_out_size, blueprint->id @@ -109,7 +112,7 @@ size_t ikarus_blueprint_get_property_count(IkarusBlueprint const * blueprint, Ik 0, "unable to fetch blueprint property count from database: {}", IkarusErrorInfo_Database_QueryFailed, - blueprint->project->db->query_one("SELECT COUNT(*) FROM `properties` WHERE `source` = ?", blueprint->id) + blueprint->project->db->query_one("SELECT COUNT(*) FROM `properties` WHERE `blueprint` = ?", blueprint->id) ); return ret; @@ -129,13 +132,13 @@ void ikarus_blueprint_get_linked_entities( return; } - IkarusId ids[entities_out_size]; + int64_t ids[entities_out_size]; IKARUS_TRYRV_OR_FAIL( , "unable to fetch blueprint linked entities from database: {}", IkarusErrorInfo_Database_QueryFailed, - blueprint->project->db->query_many_buffered( + blueprint->project->db->query_many_buffered( "SELECT `entity` FROM `entity_blueprint_links` WHERE `blueprint` = ?", ids, entities_out_size, @@ -157,7 +160,8 @@ size_t ikarus_blueprint_get_linked_entity_count(IkarusBlueprint const * blueprin 0, "unable to fetch blueprint linked entity count from database: {}", IkarusErrorInfo_Database_QueryFailed, - blueprint->project->db->query_one("SELECT COUNT(*) FROM `entity_blueprint_links` WHERE `blueprint` = ?", blueprint->id) + blueprint->project->db + ->query_one("SELECT COUNT(`entity`) FROM `entity_blueprint_links` WHERE `blueprint` = ?", blueprint->id) ); return ret; diff --git a/src/ikarus/objects/blueprint.hpp b/src/ikarus/objects/blueprint.hpp index 30c57b0..cd46d62 100644 --- a/src/ikarus/objects/blueprint.hpp +++ b/src/ikarus/objects/blueprint.hpp @@ -2,9 +2,9 @@ #include -struct IkarusBlueprint : IkarusObject { +struct IkarusBlueprint : public IkarusObject { public: - IkarusBlueprint(struct IkarusProject * project, IkarusId id); + IkarusBlueprint(struct IkarusProject * project, int64_t id); IkarusBlueprint(IkarusBlueprint const &) = default; IkarusBlueprint(IkarusBlueprint &&) = default; @@ -15,7 +15,5 @@ public: ~IkarusBlueprint() override = default; public: - inline std::string_view get_table_name() const noexcept override { - return "blueprints"; - } + std::string_view get_table_name() const noexcept override; }; diff --git a/src/ikarus/objects/entity.cpp b/src/ikarus/objects/entity.cpp index e1dbf5a..2df1404 100644 --- a/src/ikarus/objects/entity.cpp +++ b/src/ikarus/objects/entity.cpp @@ -10,22 +10,38 @@ #include #include #include +#include -IkarusEntity * ikarus_entity_create(struct IkarusProject * project, char const * name, IkarusErrorData * error_out) { +IkarusEntity::IkarusEntity(IkarusProject * project, int64_t id): + IkarusObject{project, id} {} + +std::string_view IkarusEntity::get_table_name() const noexcept { + return "entities"; +} + +IkarusEntity * ikarus_entity_create( + struct IkarusProject * project, + char const * name, + IkarusErrorData * error_out +) { IKARUS_FAIL_IF_NULL(project, nullptr); - IKARUS_FAIL_IF_NAME_INVALID_OR_DUPLICATE(name, project, static_cast(nullptr), nullptr); + IKARUS_FAIL_IF_NAME_INVALID(name, nullptr); IKARUS_VTRYRV_OR_FAIL( - IkarusId const id, + int64_t const id, nullptr, "failed to create entity: {}", IkarusErrorInfo_Database_QueryFailed, - project->db->transact([name](auto * db) -> cppbase::Result { - 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`, `name`) VALUES(?, ?)", id, name)); - return cppbase::ok(id); - }) + project->db->transact( + [name](auto * db + ) -> cppbase::Result { + TRY(db->execute( + "INSERT INTO `entities`(`name`) VALUES(?, ?)", + name + )); + return cppbase::ok(db->last_insert_rowid()); + } + ) ); return project->get_entity(id); @@ -39,25 +55,37 @@ void ikarus_entity_delete(IkarusEntity * entity, IkarusErrorData * error_out) { , "unable to delete entity: {}", IkarusErrorInfo_Database_QueryFailed, - entity->project->db->execute("DELETE FROM `objects` WHERE `id` = ?", entity->id) + entity->project->db + ->execute("DELETE FROM `entities` WHERE `id` = ?", entity->id) ); entity->project->uncache(entity); } -IkarusId ikarus_entity_get_id(IkarusEntity const * entity, IkarusErrorData * error_out) { +int64_t +ikarus_entity_get_id(IkarusEntity const * entity, IkarusErrorData * error_out) { return ikarus::util::object_get_id(entity, error_out); } -IkarusProject * ikarus_entity_get_project(IkarusEntity const * entity, IkarusErrorData * error_out) { +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) { +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) { +void ikarus_entity_set_name( + IkarusEntity * entity, + char const * name, + IkarusErrorData * error_out +) { ikarus::util::object_set_name(entity, name, error_out); } @@ -77,7 +105,9 @@ bool ikarus_entity_is_linked_to_blueprint( "unable to check whether entity is linked to blueprint", IkarusErrorInfo_Database_QueryFailed, entity->project->db->query_one( - "SELECT EXISTS(SELECT 1 FROM `entity_blueprint_links` WHERE `entity` = ? AND `blueprint` = ?)", + "SELECT EXISTS(SELECT 1 FROM `entity_blueprint_links` WHERE " + "`entity` = ? AND " + "`blueprint` = ?)", entity->id, blueprint->id ) @@ -86,7 +116,11 @@ bool ikarus_entity_is_linked_to_blueprint( return ret; } -void ikarus_entity_link_to_blueprint(IkarusEntity * entity, struct IkarusBlueprint * blueprint, IkarusErrorData * error_out) { +void ikarus_entity_link_to_blueprint( + IkarusEntity * entity, + struct IkarusBlueprint * blueprint, + IkarusErrorData * error_out +) { IKARUS_FAIL_IF_NULL(entity, ); IKARUS_FAIL_IF_OBJECT_MISSING(entity, ); IKARUS_FAIL_IF_NULL(blueprint, ); @@ -97,14 +131,20 @@ void ikarus_entity_link_to_blueprint(IkarusEntity * entity, struct IkarusBluepri "unable to link entity to blueprint: {}", IkarusErrorInfo_Database_QueryFailed, entity->project->db->execute( - "INSERT INTO `entity_blueprint_links`(`entity`, `blueprint`) VALUES(?, ?) ON CONFLICT(`entity`, `blueprint`) DO NOTHING", + "INSERT INTO `entity_blueprint_links`(`entity`, `blueprint`) " + "VALUES(?, ?) ON " + "CONFLICT(`entity`, `blueprint`) DO NOTHING", entity->id, blueprint->id ) ); } -void ikarus_entity_unlink_from_blueprint(IkarusEntity * entity, struct IkarusBlueprint * blueprint, IkarusErrorData * error_out) { +void ikarus_entity_unlink_from_blueprint( + IkarusEntity * entity, + struct IkarusBlueprint * blueprint, + IkarusErrorData * error_out +) { IKARUS_FAIL_IF_NULL(entity, ); IKARUS_FAIL_IF_OBJECT_MISSING(entity, ); IKARUS_FAIL_IF_NULL(blueprint, ); @@ -114,9 +154,26 @@ void ikarus_entity_unlink_from_blueprint(IkarusEntity * entity, struct IkarusBlu , "unable to unlink entity from blueprint: {}", IkarusErrorInfo_Database_QueryFailed, - entity->project->db - ->execute("DELETE FROM `entity_blueprint_links` WHERE `entity` = ? AND `blueprint` = ?", entity->id, blueprint->id) + entity->project->db->execute( + "DELETE FROM `entity_blueprint_links` WHERE `entity` = ? AND " + "`blueprint` = ?", + entity->id, + blueprint->id + ) ); + + IKARUS_TRYRV_OR_FAIL( + , + "unable to remove entity property values: {}", + IkarusErrorInfo_Database_QueryFailed, + entity->project->db->execute( + "DELETE FROM `entity_property_values` WHERE `entity` = ? AND " + "`property` IN (SELECT " + "`id` FROM `properties` WHERE `blueprint` = ?)", + entity->id, + blueprint->id + ) + ) } void ikarus_entity_get_linked_blueprints( @@ -133,14 +190,15 @@ void ikarus_entity_get_linked_blueprints( return; } - IkarusId ids[blueprints_out_size]; + int64_t ids[blueprints_out_size]; IKARUS_TRYRV_OR_FAIL( , "unable to fetch entity linked blueprints from database: {}", IkarusErrorInfo_Database_QueryFailed, - entity->project->db->query_many_buffered( - "SELECT `blueprint` FROM `entity_blueprint_links` WHERE `entity` = ?", + entity->project->db->query_many_buffered( + "SELECT `blueprint` FROM `entity_blueprint_links` WHERE `entity` = " + "?", ids, blueprints_out_size, entity->id @@ -152,7 +210,10 @@ void ikarus_entity_get_linked_blueprints( } } -size_t ikarus_entity_get_linked_blueprint_count(IkarusEntity const * entity, IkarusErrorData * error_out) { +size_t ikarus_entity_get_linked_blueprint_count( + IkarusEntity const * entity, + IkarusErrorData * error_out +) { IKARUS_FAIL_IF_NULL(entity, 0); IKARUS_FAIL_IF_OBJECT_MISSING(entity, 0); @@ -161,31 +222,144 @@ size_t ikarus_entity_get_linked_blueprint_count(IkarusEntity const * entity, Ika 0, "unable to fetch entity linked blueprint count from database: {}", IkarusErrorInfo_Database_QueryFailed, - entity->project->db->query_one("SELECT COUNT(*) FROM `entity_blueprint_links` WHERE `entity` = ?", entity->id) + entity->project->db->query_one( + "SELECT COUNT(`blueprint`) FROM `entity_blueprint_links` WHERE " + "`entity` = ?", + entity->id + ) ); return ret; } -bool ikarus_entity_has_property(IkarusEntity const * entity, struct IkarusProperty const * property, IkarusErrorData * error_out) { +bool ikarus_entity_has_value( + IkarusEntity const * entity, + char const * name, + IkarusErrorData * error_out +) { + IKARUS_FAIL_IF_NULL(entity, false); + IKARUS_FAIL_IF_OBJECT_MISSING(entity, false); + IKARUS_FAIL_IF_NAME_INVALID(name, false); + + IKARUS_VTRYRV_OR_FAIL( + auto const has_value, + false, + "unable to check whether entity has value: {}", + IkarusErrorInfo_Database_QueryFailed, + entity->project->db->query_one( + "SELECT EXISTS(SELECT 1 FROM `entity_values` WHERE `entity` = ? " + "AND `name` = ?)", + entity->id, + name + ) + ); + + return has_value; +} + +struct IkarusValue * ikarus_entity_get_value( + IkarusEntity const * entity, + char const * name, + IkarusErrorData * error_out +) { + IKARUS_FAIL_IF_NULL(entity, nullptr); + IKARUS_FAIL_IF_OBJECT_MISSING(entity, nullptr); + IKARUS_FAIL_IF_VALUE_MISSING(entity, name, nullptr); + IKARUS_FAIL_IF_NAME_INVALID(name, nullptr); + + auto * value = fetch_value_from_db( + entity->project, + error_out, + "SELECT `value` FROM `entity_values` WHERE `entity` = ? AND `name` = ?", + entity->id, + name + ); + + IKARUS_FAIL_IF_ERROR(nullptr); + + return value; +} + +void ikarus_entity_set_value( + IkarusEntity * entity, + char const * name, + struct IkarusValue const * value, + IkarusErrorData * error_out +) { + IKARUS_FAIL_IF_NULL(entity, ); + IKARUS_FAIL_IF_OBJECT_MISSING(entity, ); + IKARUS_FAIL_IF_NAME_INVALID(name, ); + IKARUS_FAIL_IF_NULL(value, ); + + IKARUS_TRYRV_OR_FAIL( + , + "unable to set entity value: {}", + IkarusErrorInfo_Database_QueryFailed, + entity->project->db->execute( + "INSERT INTO `entity_values`(`entity`, `name`, `value`) VALUES(?1, " + "?2, ?3) ON " + "CONFLICT(`entity`, `name`) DO UPDATE SET `value` = ?3", + entity->id, + name, + boost::json::serialize(value->to_json()) + ) + ); +} + +void ikarus_entity_delete_value( + IkarusEntity * entity, + char const * name, + IkarusErrorData * error_out +) { + IKARUS_FAIL_IF_NULL(entity, ); + IKARUS_FAIL_IF_OBJECT_MISSING(entity, ); + IKARUS_FAIL_IF_VALUE_MISSING(entity, name, ); + IKARUS_FAIL_IF_NAME_INVALID(name, ); + + IKARUS_TRYRV_OR_FAIL( + , + "unable to delete entity value: {}", + IkarusErrorInfo_Database_QueryFailed, + entity->project->db->execute( + "DELETE FROM `entity_values` WHERE `entity` = ? AND `name` = ?", + entity->id, + name + ) + ); +} + +bool ikarus_entity_has_property( + IkarusEntity const * entity, + struct IkarusProperty const * property, + IkarusErrorData * error_out +) { IKARUS_FAIL_IF_NULL(entity, false); IKARUS_FAIL_IF_OBJECT_MISSING(entity, false); IKARUS_FAIL_IF_NULL(property, false); IKARUS_FAIL_IF_OBJECT_MISSING(property, false); + // given that values are loaded lazily we can't just check + // `entity_property_values` here IKARUS_VTRYRV_OR_FAIL( - auto const ret, + auto const has_property, false, "unable to check whether entity has property: {}", IkarusErrorInfo_Database_QueryFailed, entity->project->db->query_one( - "SELECT EXISTS(SELECT 1 FROM `entity_properties` WHERE `entity` = ? AND `property` = ?)", + "SELECT EXISTS(\n" + " SELECT 1\n" + " FROM `entity_blueprint_links`\n" + " JOIN `properties` ON `properties`.`blueprint` = " + "`entity_blueprint_links`.`blueprint`\n" + " WHERE `entity_blueprint_links`.`entity` = ? AND " + "`properties`.`id` = ?\n" + ")", entity->id, property->id ) ) - return ret; + return has_property; } void ikarus_entity_get_properties( @@ -202,19 +376,25 @@ void ikarus_entity_get_properties( return; } - std::tuple ids_and_types[properties_out_size]; + std::tuple ids_and_types[properties_out_size]; + // given that values are loaded lazily we can't just check + // `entity_property_values` here IKARUS_TRYRV_OR_FAIL( , - "unable to fetch entity properties from database: {}", + "unable to fetch properties from entity: {}", IkarusErrorInfo_Database_QueryFailed, - entity->project->db->query_many_buffered( - "SELECT `property`, `type` FROM `properties` WHERE `source` = ?", + entity->project->db->query_many_buffered( + "SELECT `properties`.`id`, `properties`.`type`\n" + "FROM `entity_blueprint_links`\n" + "JOIN `properties` ON `properties`.`blueprint` = " + "`entity_blueprint_links`.`blueprint`\n" + "WHERE `entity_blueprint_links`.`entity` = ?\n", ids_and_types, properties_out_size, entity->id ) - ) + ); for (size_t i = 0; i < properties_out_size; ++i) { auto [id, type] = ids_and_types[i]; @@ -222,23 +402,39 @@ void ikarus_entity_get_properties( } } -size_t ikarus_entity_get_property_count(IkarusEntity const * entity, IkarusErrorData * error_out) { +size_t ikarus_entity_get_property_count( + IkarusEntity const * entity, + IkarusErrorData * error_out +) { IKARUS_FAIL_IF_NULL(entity, 0); IKARUS_FAIL_IF_OBJECT_MISSING(entity, 0); + // given that values are loaded lazily we can't just check + // `entity_property_values` here IKARUS_VTRYRV_OR_FAIL( - size_t const ret, + size_t const count, 0, - "unable to fetch entity property count from database: {}", + "unable to fetch property count from entity: {}", IkarusErrorInfo_Database_QueryFailed, - entity->project->db->query_one("SELECT COUNT(*) FROM `properties` WHERE `source` = ?", entity->id) + entity->project->db->query_one( + "SELECT COUNT(`properties`.`id`)\n" + "FROM `entity_blueprint_links`\n" + "JOIN `properties` ON `properties`.`blueprint` = " + "`entity_blueprint_links`.`blueprint`\n" + "WHERE `entity_blueprint_links`.`entity` = ?\n" + ")", + entity->id + ) ); - return ret; + return count; } -struct IkarusEntityPropertyValue * -ikarus_entity_get_value(IkarusEntity const * entity, struct IkarusProperty const * property, IkarusErrorData * error_out) { +struct IkarusValue * ikarus_entity_get_property_value( + IkarusEntity const * entity, + struct IkarusProperty const * property, + IkarusErrorData * error_out +) { IKARUS_FAIL_IF_NULL(entity, nullptr); IKARUS_FAIL_IF_OBJECT_MISSING(entity, nullptr); IKARUS_FAIL_IF_NULL(property, nullptr); @@ -247,25 +443,27 @@ ikarus_entity_get_value(IkarusEntity const * entity, struct IkarusProperty const auto * value = fetch_value_from_db( entity->project, error_out, - "SELECT IFNULL((SELECT `value` FROM `values` WHERE `entity` = ? AND `property` = ?), (SELECT `default_value` FROM `properties` WHERE `id` = ?))", + "SELECT IFNULL(\n" + " (\n" + " SELECT `value`\n" + " FROM `entity_property_values`\n" + " WHERE `entity` = ?1 AND `property` = ?2\n" + " ),\n" + " (SELECT `default_value` FROM `properties` WHERE `id` = ?2)\n" + ")", entity->id, - property->id, property->id ); IKARUS_FAIL_IF_ERROR(nullptr); - return new IkarusEntityPropertyValue{ - .entity = entity, - .property = property, - .value = value, - }; + return value; } -void ikarus_entity_set_value( +void ikarus_entity_set_property_value( IkarusEntity * entity, struct IkarusProperty const * property, - struct IkarusEntityPropertyValue * value, + struct IkarusValue * value, IkarusErrorData * error_out ) { IKARUS_FAIL_IF_NULL(entity, ); @@ -274,18 +472,17 @@ void ikarus_entity_set_value( IKARUS_FAIL_IF_OBJECT_MISSING(property, ); IKARUS_FAIL_IF_NULL(value, ); - auto value_json_str = boost::json::serialize(value->value->to_json()); - IKARUS_TRYRV_OR_FAIL( , "unable to set entity property value: {}", IkarusErrorInfo_Database_QueryFailed, entity->project->db->execute( - "INSERT INTO `values`(`entity`, `property`, `value`) VALUES(?, ?, ?) ON CONFLICT(`entity`, `property`) DO UPDATE SET `value` = ?", + "INSERT INTO `entity_property_values`(`entity`, `property`, " + "`value`) VALUES(?1, ?2, " + "?3) ON CONFLICT(`entity`, `property`) DO UPDATE SET `value` = ?3", entity->id, property->id, - value_json_str, - value_json_str + boost::json::serialize(value->to_json()) ) ); } diff --git a/src/ikarus/objects/entity.hpp b/src/ikarus/objects/entity.hpp index 586c88f..e3bc035 100644 --- a/src/ikarus/objects/entity.hpp +++ b/src/ikarus/objects/entity.hpp @@ -2,10 +2,9 @@ #include -struct IkarusEntity : IkarusObject { +struct IkarusEntity : public IkarusObject { public: - inline IkarusEntity(struct IkarusProject * project, IkarusId id): - IkarusObject{project, id} {} + inline IkarusEntity(struct IkarusProject * project, int64_t id); IkarusEntity(IkarusEntity const &) = default; IkarusEntity(IkarusEntity &&) = default; @@ -16,7 +15,5 @@ public: ~IkarusEntity() override = default; public: - inline std::string_view get_table_name() const noexcept override { - return "entities"; - } + std::string_view get_table_name() const noexcept override; }; diff --git a/src/ikarus/objects/object.cpp b/src/ikarus/objects/object.cpp index d233783..01747cc 100644 --- a/src/ikarus/objects/object.cpp +++ b/src/ikarus/objects/object.cpp @@ -1,93 +1,7 @@ #include "object.hpp" -#include - -#include - -#include -#include -#include -#include -#include -#include #include -IkarusObject::IkarusObject(IkarusProject * project, IkarusId id): +IkarusObject::IkarusObject(IkarusProject * project, int64_t 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/ikarus/objects/object.hpp b/src/ikarus/objects/object.hpp index 20eed59..96d5911 100644 --- a/src/ikarus/objects/object.hpp +++ b/src/ikarus/objects/object.hpp @@ -2,11 +2,9 @@ #include -#include - -struct IkarusObject { +class IkarusObject { public: - IkarusObject(struct IkarusProject * project, IkarusId id); + IkarusObject(struct IkarusProject * project, int64_t id); IkarusObject(IkarusObject const &) = default; IkarusObject(IkarusObject &&) = default; @@ -21,5 +19,18 @@ public: public: struct IkarusProject * project; - IkarusId id; + int64_t id; }; + +#define IKARUS_FAIL_IF_OBJECT_MISSING_IMPL(var_name, obj, ret) \ + IKARUS_VTRYRV_OR_FAIL( \ + bool const var_name, \ + ret, \ + "unable to check whether object exists: {}", \ + IkarusErrorInfo_Database_QueryFailed, \ + (obj)->project->db->template query_one("SELECT EXISTS(SELECT 1 FROM `objects` WHERE `id` = ?)", (obj)->id) \ + ) \ + \ + IKARUS_FAIL_IF(!(var_name), ret, "object does not exist", IkarusErrorInfo_Client_Misuse); + +#define IKARUS_FAIL_IF_OBJECT_MISSING(obj, ret) IKARUS_FAIL_IF_OBJECT_MISSING_IMPL(CPPBASE_UNIQUE_NAME(exists), obj, ret); diff --git a/src/ikarus/objects/object_type.cpp b/src/ikarus/objects/object_type.cpp deleted file mode 100644 index fb7d825..0000000 --- a/src/ikarus/objects/object_type.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "ikarus/objects/object_type.h" - -char const * ikarus_object_type_to_string(IkarusObjectType type) { - switch (type) { - case IkarusObjectType_None: return "none"; - case IkarusObjectType_Entity: return "entity"; - case IkarusObjectType_Blueprint: return "blueprint"; - case IkarusObjectType_Property: return "property"; - } - - return "unknown"; -} diff --git a/src/ikarus/objects/properties/number_property.cpp b/src/ikarus/objects/properties/number_property.cpp index 43a966c..60c9ccd 100644 --- a/src/ikarus/objects/properties/number_property.cpp +++ b/src/ikarus/objects/properties/number_property.cpp @@ -7,7 +7,7 @@ #include #include -IkarusNumberProperty::IkarusNumberProperty(IkarusProject * project, IkarusId id): +IkarusNumberProperty::IkarusNumberProperty(IkarusProject * project, int64_t id): IkarusProperty{project, id, this} {} IkarusNumberProperty * ikarus_number_property_create( diff --git a/src/ikarus/objects/properties/number_property.hpp b/src/ikarus/objects/properties/number_property.hpp index eddb189..55ff25c 100644 --- a/src/ikarus/objects/properties/number_property.hpp +++ b/src/ikarus/objects/properties/number_property.hpp @@ -1,14 +1,14 @@ #pragma once #include -#include #include +#include -struct IkarusNumberProperty : IkarusProperty { +struct IkarusNumberProperty : public IkarusProperty { public: using value_type = IkarusNumberValue; - constexpr auto static PropertyType = IkarusPropertyType_Number; + constexpr auto static PropertyType = IkarusValueType_Number; public: - IkarusNumberProperty(struct IkarusProject * project, IkarusId id); + IkarusNumberProperty(struct IkarusProject * project, int64_t id); }; diff --git a/src/ikarus/objects/properties/property.cpp b/src/ikarus/objects/properties/property.cpp index 929d3a6..ecc2f3e 100644 --- a/src/ikarus/objects/properties/property.cpp +++ b/src/ikarus/objects/properties/property.cpp @@ -5,12 +5,12 @@ #include #include #include -#include +#include #include #include #include -IkarusProperty::IkarusProperty(IkarusProject * project, IkarusId id, Data data): +IkarusProperty::IkarusProperty(IkarusProject * project, int64_t id, Data data): IkarusObject{project, id}, data{data} {} @@ -28,7 +28,7 @@ IKA_API void ikarus_property_delete(IkarusProperty * property, IkarusErrorData * property->project->uncache(property); } -IkarusId ikarus_property_get_id(IkarusProperty const * property, IkarusErrorData * error_out) { +int64_t ikarus_property_get_id(IkarusProperty const * property, IkarusErrorData * error_out) { return ikarus::util::object_get_id(property, error_out); } @@ -44,19 +44,19 @@ void ikarus_property_set_name(IkarusProperty * property, char const * name, Ikar 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); +IkarusValueType ikarus_property_get_type(IkarusProperty const * property, IkarusErrorData * error_out) { + IKARUS_FAIL_IF_NULL(property, IkarusValueType_Toggle); + IKARUS_FAIL_IF_OBJECT_MISSING(property, IkarusValueType_Toggle); IKARUS_VTRYRV_OR_FAIL( auto const ret, - IkarusPropertyType_Toggle, + IkarusValueType_Toggle, "unable to fetch property type from database: {}", IkarusErrorInfo_Database_QueryFailed, property->project->db->query_one("SELECT `type` FROM `properties` WHERE `id` = ?", property->id) ); - return static_cast(ret); + return static_cast(ret); } IkarusPropertyScope const * ikarus_property_get_scope(IkarusProperty const * property, IkarusErrorData * error_out) { @@ -68,7 +68,7 @@ IkarusPropertyScope const * ikarus_property_get_scope(IkarusProperty const * pro nullptr, "unable to fetch property source from database: {}", IkarusErrorInfo_Database_QueryFailed, - property->project->db->query_one("SELECT `source` FROM `properties` WHERE `id` = ?", property->id) + property->project->db->query_one("SELECT `source` FROM `properties` WHERE `id` = ?", property->id) ); switch (ikarus_id_get_object_type(source)) { @@ -83,7 +83,7 @@ IkarusPropertyScope const * ikarus_property_get_scope(IkarusProperty const * pro } } -IkarusValue * ikarus_property_get_default_value(IkarusProperty const * property, IkarusErrorData * error_out) { +IkarusValueData * ikarus_property_get_default_value(IkarusProperty const * property, IkarusErrorData * error_out) { IKARUS_FAIL_IF_NULL(property, nullptr); IKARUS_FAIL_IF_OBJECT_MISSING(property, nullptr); diff --git a/src/ikarus/objects/properties/property.hpp b/src/ikarus/objects/properties/property.hpp index 5c37d7c..1fd0394 100644 --- a/src/ikarus/objects/properties/property.hpp +++ b/src/ikarus/objects/properties/property.hpp @@ -4,12 +4,12 @@ #include -struct IkarusProperty : IkarusObject { +struct IkarusProperty : public IkarusObject { public: using Data = std::variant; public: - IkarusProperty(struct IkarusProject * project, IkarusId id, Data data); + IkarusProperty(struct IkarusProject * project, int64_t id, Data data); IkarusProperty(IkarusProperty const &) = default; IkarusProperty(IkarusProperty &&) = default; diff --git a/src/ikarus/objects/properties/property_scope.cpp b/src/ikarus/objects/properties/property_scope.cpp deleted file mode 100644 index b8ec32f..0000000 --- a/src/ikarus/objects/properties/property_scope.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "property_scope.hpp" - -#include - -#include -#include - -IkarusPropertyScope::IkarusPropertyScope(Data data): - data{data} {} - -IkarusId IkarusPropertyScope::get_id() const { - return std::visit( - cppbase::overloaded{ - [](IkarusBlueprint const * blueprint) { return blueprint->id; }, - [](IkarusEntity const * entity) { return entity->id; } - }, - data - ); -} - -IkarusPropertyScope * ikarus_property_source_create_blueprint(IkarusBlueprint * blueprint) { - return new IkarusPropertyScope{blueprint}; -} - -IkarusPropertyScope * ikarus_property_source_create_entity(IkarusEntity * entity) { - return new IkarusPropertyScope{entity}; -} - -void ikarus_property_source_visit( - struct IkarusPropertyScope * property_source, - void (*blueprint_visitor)(struct IkarusBlueprint *, void *), - void (*entity_visitor)(struct IkarusEntity *, void *), - void * user_data -) { - 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 IkarusPropertyScope const * property_source, - void (*blueprint_visitor)(struct IkarusBlueprint const *, void *), - void (*entity_visitor)(struct IkarusEntity const *, void *), - void * user_data -) { - 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); } - }, - property_source->data - ); -} diff --git a/src/ikarus/objects/properties/property_scope.hpp b/src/ikarus/objects/properties/property_scope.hpp deleted file mode 100644 index ab8832a..0000000 --- a/src/ikarus/objects/properties/property_scope.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#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/ikarus/objects/properties/text_property.cpp b/src/ikarus/objects/properties/text_property.cpp index 6aaf483..c51d653 100644 --- a/src/ikarus/objects/properties/text_property.cpp +++ b/src/ikarus/objects/properties/text_property.cpp @@ -7,7 +7,7 @@ #include #include -IkarusTextProperty::IkarusTextProperty(IkarusProject * project, IkarusId id): +IkarusTextProperty::IkarusTextProperty(IkarusProject * project, int64_t id): IkarusProperty{project, id, this} {} IkarusTextProperty * ikarus_text_property_create( diff --git a/src/ikarus/objects/properties/text_property.hpp b/src/ikarus/objects/properties/text_property.hpp index aca2cfa..b690cda 100644 --- a/src/ikarus/objects/properties/text_property.hpp +++ b/src/ikarus/objects/properties/text_property.hpp @@ -1,14 +1,14 @@ #pragma once #include -#include +#include #include -struct IkarusTextProperty : IkarusProperty { +struct IkarusTextProperty : public IkarusProperty { public: using value_type = IkarusTextValue; - constexpr auto static PropertyType = IkarusPropertyType_Text; + constexpr auto static PropertyType = IkarusValueType_Text; public: - IkarusTextProperty(struct IkarusProject * project, IkarusId id); + IkarusTextProperty(struct IkarusProject * project, int64_t id); }; diff --git a/src/ikarus/objects/properties/toggle_property.cpp b/src/ikarus/objects/properties/toggle_property.cpp index 2449b39..d1705a2 100644 --- a/src/ikarus/objects/properties/toggle_property.cpp +++ b/src/ikarus/objects/properties/toggle_property.cpp @@ -7,7 +7,7 @@ #include #include -IkarusToggleProperty::IkarusToggleProperty(IkarusProject * project, IkarusId id): +IkarusToggleProperty::IkarusToggleProperty(IkarusProject * project, int64_t id): IkarusProperty{project, id, this} {} IkarusToggleProperty * ikarus_toggle_property_create( diff --git a/src/ikarus/objects/properties/toggle_property.hpp b/src/ikarus/objects/properties/toggle_property.hpp index bf53c19..35575ee 100644 --- a/src/ikarus/objects/properties/toggle_property.hpp +++ b/src/ikarus/objects/properties/toggle_property.hpp @@ -1,14 +1,17 @@ #pragma once #include -#include #include +#include -struct IkarusToggleProperty : IkarusProperty { +struct IkarusToggleProperty { public: using value_type = IkarusToggleValue; - constexpr auto static PropertyType = IkarusPropertyType_Toggle; + constexpr auto static PropertyType = IkarusValueType_Toggle; public: - IkarusToggleProperty(struct IkarusProject * project, IkarusId id); + IkarusToggleProperty(struct IkarusProject * project, int64_t id); + +public: + IkarusProperty * property; }; diff --git a/src/ikarus/objects/properties/util.hpp b/src/ikarus/objects/properties/util.hpp index c095a18..97146f1 100644 --- a/src/ikarus/objects/properties/util.hpp +++ b/src/ikarus/objects/properties/util.hpp @@ -22,15 +22,14 @@ T * create_property( ) { IKARUS_FAIL_IF_NULL(project, nullptr); IKARUS_FAIL_IF_NULL(property_scope, nullptr); - IKARUS_FAIL_IF_PROPERTY_SCOPE_INVALID(property_scope, nullptr); - IKARUS_FAIL_IF_NAME_INVALID_OR_DUPLICATE(name, project, property_scope, nullptr); + IKARUS_FAIL_IF_NAME_INVALID(name, nullptr); IKARUS_VTRYRV_OR_FAIL( - IkarusId const id, + int64_t const id, nullptr, "failed to create property: {}", IkarusErrorInfo_Database_QueryFailed, - project->db->transact([name, property_scope](auto * db) -> cppbase::Result { + project->db->transact([name, property_scope](auto * db) -> cppbase::Result { TRY(db->execute("INSERT INTO `objects`(`type`) VALUES(?)", IkarusObjectType_Property)); auto id = ikarus_id_from_data_and_type(db->last_insert_rowid(), IkarusObjectType_Property); TRY(db->execute( diff --git a/src/ikarus/objects/util.hpp b/src/ikarus/objects/util.hpp index 1de035a..e625f5d 100644 --- a/src/ikarus/objects/util.hpp +++ b/src/ikarus/objects/util.hpp @@ -6,18 +6,12 @@ #include #include -#include -#include -#include -#include -#include -#include #include namespace ikarus::util { template -[[nodiscard]] IkarusId object_get_id(O const * object, IkarusErrorData * error_out) { +[[nodiscard]] int64_t object_get_id(O const * object, IkarusErrorData * error_out) { IKARUS_FAIL_IF_NULL(object, 0); IKARUS_FAIL_IF_OBJECT_MISSING(object, 0); @@ -49,81 +43,14 @@ template 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 const * 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, 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); - -#define IKARUS_FAIL_IF_NAME_INVALID_OR_DUPLICATE(name, project, object, ret, ...) \ - IKARUS_FAIL_IF_NAME_INVALID(name, ret); \ - 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); +#define IKARUS_FAIL_IF_NAME_INVALID(name, ret) IKARUS_FAIL_IF_NULL(name, 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_OR_DUPLICATE(name, object->project, object, ); + IKARUS_FAIL_IF_NAME_INVALID(name, ); IKARUS_TRYRV_OR_FAIL( , diff --git a/src/ikarus/persistence/migrations.hpp b/src/ikarus/persistence/migrations.hpp index a46d1ee..db649a5 100644 --- a/src/ikarus/persistence/migrations.hpp +++ b/src/ikarus/persistence/migrations.hpp @@ -8,11 +8,12 @@ #include namespace ikarus { + CPPBASE_ASSET(m0_initial_layout, "ikarus/persistence/migrations/m0_initial_layout.sql"); class Migration : public sqlitecpp::Migration { public: - Migration(char const * sql, size_t size): + Migration(char const * sql, size_t const size): sql{sql, size} {} ~Migration() override = default; diff --git a/src/ikarus/persistence/migrations/m0_initial_layout.sql b/src/ikarus/persistence/migrations/m0_initial_layout.sql index 9bf3cc7..aa28c8a 100644 --- a/src/ikarus/persistence/migrations/m0_initial_layout.sql +++ b/src/ikarus/persistence/migrations/m0_initial_layout.sql @@ -1,68 +1,51 @@ -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 UNIQUE -) STRICT; - -CREATE UNIQUE INDEX `object_id` ON `objects` (`id`); -CREATE INDEX `object_type` ON `objects` (`type`); - CREATE TABLE `entities` ( - `id` INT, - `name` TEXT NOT NULL, + `id` INTEGER PRIMARY KEY, + `name` TEXT NOT NULL +) STRICT; - PRIMARY KEY (`id`), - UNIQUE (`name`), - FOREIGN KEY (`id`) REFERENCES `objects` (`id`) ON DELETE CASCADE +CREATE TABLE `entity_values` +( + `entity` INTEGER NOT NULL REFERENCES `entities` (`id`) ON DELETE CASCADE, + `name` TEXT NOT NULL, + `type` INT NOT NULL, + `value` TEXT NOT NULL, + + PRIMARY KEY (`entity`, `name`) ) WITHOUT ROWID, STRICT; CREATE TABLE `blueprints` ( - `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 `entity_blueprint_links` -( - `entity` INT NOT NULL, - `blueprint` INT NOT NULL, - - 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; + `id` INTEGER PRIMARY KEY, + `name` TEXT NOT NULL +) STRICT; 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; + `id` INTEGER PRIMARY KEY, + `blueprint` INTEGER NOT NULL REFERENCES `blueprints` (`id`) ON DELETE CASCADE, + `name` TEXT NOT NULL, + `type` INT NOT NULL, + `cardinality` INT NOT NULL, + `default_value` TEXT NOT NULL, + `settings` TEXT NOT NULL +) STRICT; CREATE INDEX `properties_type` ON `properties` (`type`); -CREATE INDEX `properties_source` ON `properties` (`source`); -CREATE TABLE `values` +CREATE TABLE `entity_blueprint_links` ( - `entity` INT NOT NULL, - `property` INT NOT NULL, - `value` TEXT NOT NULL, + `entity` INTEGER NOT NULL REFERENCES `entities` (`id`) ON DELETE CASCADE, + `blueprint` INTEGER NOT NULL REFERENCES `blueprints` (`id`) ON DELETE CASCADE, - PRIMARY KEY (`entity`, `property`), - FOREIGN KEY (`entity`) REFERENCES `entities` (`id`) ON DELETE CASCADE, - FOREIGN KEY (`property`) REFERENCES `properties` (`id`) ON DELETE CASCADE + PRIMARY KEY (`entity`, `blueprint`) +) STRICT; + +CREATE TABLE `entity_property_values` +( + `entity` INTEGER NOT NULL REFERENCES `entities` (`id`) ON DELETE CASCADE, + `property` INTEGER NOT NULL REFERENCES `properties` (`id`) ON DELETE CASCADE, + `value` TEXT NOT NULL, + + PRIMARY KEY (`entity`, `property`) ) WITHOUT ROWID, STRICT; diff --git a/src/ikarus/persistence/project.cpp b/src/ikarus/persistence/project.cpp index 87ebef5..0d5b1e5 100644 --- a/src/ikarus/persistence/project.cpp +++ b/src/ikarus/persistence/project.cpp @@ -22,7 +22,7 @@ IkarusProject::IkarusProject(std::string_view name, std::string_view path, std:: _properties{}, _entities{} {} -IkarusBlueprint * IkarusProject::get_blueprint(IkarusId id) { +IkarusBlueprint * IkarusProject::get_blueprint(int64_t id) { return get_cached_object(id, this->_blueprints); } @@ -30,7 +30,7 @@ auto IkarusProject::uncache(IkarusBlueprint * blueprint) -> void { remove_cached_object(blueprint, _blueprints); } -auto IkarusProject::get_entity(IkarusId id) -> IkarusEntity * { +auto IkarusProject::get_entity(int64_t id) -> IkarusEntity * { return get_cached_object(id, this->_entities); } @@ -38,16 +38,16 @@ auto IkarusProject::uncache(IkarusEntity * entity) -> void { remove_cached_object(entity, _entities); } -auto IkarusProject::get_property(IkarusId id, IkarusPropertyType type) -> IkarusProperty * { +auto IkarusProject::get_property(int64_t id, IkarusValueType type) -> IkarusProperty * { auto const iter = _properties.find(id); if (iter == _properties.cend()) { switch (type) { - case IkarusPropertyType_Toggle: + case IkarusValueType_Toggle: return _properties.emplace(id, std::make_unique(this, id)).first->second.get(); - case IkarusPropertyType_Number: + case IkarusValueType_Number: return _properties.emplace(id, std::make_unique(this, id)).first->second.get(); - case IkarusPropertyType_Text: return _properties.emplace(id, std::make_unique(this, id)).first->second.get(); + case IkarusValueType_Text: return _properties.emplace(id, std::make_unique(this, id)).first->second.get(); } } @@ -212,13 +212,13 @@ void ikarus_project_get_blueprints( return; } - IkarusId ids[blueprints_out_size]; + int64_t ids[blueprints_out_size]; IKARUS_TRYRV_OR_FAIL( , "unable to fetch project blueprints from database: {}", IkarusErrorInfo_Database_QueryFailed, - project->db->query_many_buffered("SELECT `id` FROM `blueprints`", ids, blueprints_out_size) + project->db->query_many_buffered("SELECT `id` FROM `blueprints`", ids, blueprints_out_size) ); for (size_t i = 0; i < blueprints_out_size; ++i) { @@ -253,13 +253,13 @@ void ikarus_project_get_entities( return; } - IkarusId ids[entities_out_size]; + int64_t ids[entities_out_size]; IKARUS_TRYRV_OR_FAIL( , "unable to fetch project entities from database: {}", IkarusErrorInfo_Database_QueryFailed, - project->db->query_many_buffered("SELECT `id` FROM `entities`", ids, entities_out_size) + project->db->query_many_buffered("SELECT `id` FROM `entities`", ids, entities_out_size) ); for (size_t i = 0; i < entities_out_size; ++i) { @@ -293,7 +293,7 @@ struct IkarusEntity * get_entity_by_name(IkarusProject * project, char const * n nullptr, "unable to find entity in database: {}", IkarusErrorInfo_Client_InvalidInput, - project->db->query_one("SELECT `id` FROM `entities` WHERE `name` = ?", name) + project->db->query_one("SELECT `id` FROM `entities` WHERE `name` = ?", name) ); return project->get_entity(id); @@ -310,7 +310,7 @@ get_property_by_name(IkarusProject * project, IkarusPropertyScope * scope, char nullptr, "unable to find property in database: {}", IkarusErrorInfo_Client_InvalidInput, - project->db->query_one( + project->db->query_one( "SELECT `id`, `type` FROM `properties` WHERE `name` = ? AND `scope` = ?", name, scope->get_id() @@ -332,7 +332,7 @@ IkarusBlueprint * get_blueprints_by_name(IkarusProject * project, char const * n nullptr, "unable to find blueprint in database: {}", IkarusErrorInfo_Client_InvalidInput, - project->db->query_one("SELECT `id` FROM `blueprints` WHERE `name` = ?", name) + project->db->query_one("SELECT `id` FROM `blueprints` WHERE `name` = ?", name) ); return project->get_blueprint(id); diff --git a/src/ikarus/persistence/project.hpp b/src/ikarus/persistence/project.hpp index f5a00a1..1dc69dc 100644 --- a/src/ikarus/persistence/project.hpp +++ b/src/ikarus/persistence/project.hpp @@ -1,7 +1,5 @@ #pragma once -#include -#include #include #include @@ -9,8 +7,7 @@ #include #include -#include -#include +#include namespace fs = boost::filesystem; @@ -20,19 +17,19 @@ public: IkarusProject(std::string_view name, std::string_view path, std::unique_ptr && db); public: - [[nodiscard]] auto get_blueprint(IkarusId id) -> struct IkarusBlueprint *; + [[nodiscard]] auto get_blueprint(int64_t id) -> struct IkarusBlueprint *; auto uncache(struct IkarusBlueprint * blueprint) -> void; - [[nodiscard]] auto get_entity(IkarusId id) -> struct IkarusEntity *; + [[nodiscard]] auto get_entity(int64_t id) -> struct IkarusEntity *; auto uncache(struct IkarusEntity * entity) -> void; // TODO improve this to take a template param so that we don't have to cast in e.g. ikarus_toggle_property_create - [[nodiscard]] auto get_property(IkarusId id, IkarusPropertyType type) -> struct IkarusProperty *; + [[nodiscard]] auto get_property(int64_t id, IkarusValueType type) -> struct IkarusProperty *; auto uncache(struct IkarusProperty * property) -> void; private: template - [[nodiscard]] T * get_cached_object(IkarusId id, auto & cache) { + [[nodiscard]] T * get_cached_object(int64_t id, auto & cache) { auto const iter = cache.find(id); if (iter == cache.cend()) { @@ -43,7 +40,7 @@ private: } template - void remove_cached_object(T * object, std::unordered_map> & cache) { + void remove_cached_object(T * object, std::unordered_map> & cache) { cache.erase(object->id); } @@ -53,9 +50,9 @@ public: std::unique_ptr db; private: - std::unordered_map> mutable _blueprints; - std::unordered_map> mutable _properties; - std::unordered_map> mutable _entities; + std::unordered_map> mutable _blueprints; + std::unordered_map> mutable _properties; + std::unordered_map> mutable _entities; }; constexpr std::string_view DB_PROJECT_NAME_KEY = "PROJECT_NAME"; diff --git a/src/ikarus/values/entity_property_value.hpp b/src/ikarus/values/entity_property_value.hpp index f75d6ba..6f70f09 100644 --- a/src/ikarus/values/entity_property_value.hpp +++ b/src/ikarus/values/entity_property_value.hpp @@ -1,7 +1 @@ #pragma once - -struct IkarusEntityPropertyValue { - struct IkarusEntity const * entity; - struct IkarusProperty const * property; - struct IkarusValue const * value; -}; diff --git a/src/ikarus/values/number_value.cpp b/src/ikarus/values/number_value.cpp index 37eab49..41fba42 100644 --- a/src/ikarus/values/number_value.cpp +++ b/src/ikarus/values/number_value.cpp @@ -6,60 +6,60 @@ #include IkarusNumberValue::IkarusNumberValue(): - IkarusValue{this} {} + IkarusValueData{this} {} -IkarusNumberValue * ikarus_number_value_create() { +IkarusNumberValue * ikarus_number_value_data_create() { return new IkarusNumberValue{}; } -double const * ikarus_number_value_get(IkarusNumberValue * value, size_t idx) { - return ikarus_value_base_get(value, idx); +double const * ikarus_number_value_data_get(IkarusNumberValue * value, size_t idx) { + return ikarus_value_data_base_get(value, idx); } -size_t ikarus_number_value_get_size(IkarusNumberValue const * value) { - return ikarus_value_base_get_size(value); +size_t ikarus_number_value_data_get_size(IkarusNumberValue const * value) { + return ikarus_value_data_base_get_size(value); } -void ikarus_number_value_set(IkarusNumberValue * value, size_t idx, double new_data) { - return ikarus_value_base_set(value, idx, new_data); +void ikarus_number_value_data_set(IkarusNumberValue * value, size_t idx, double new_data) { + return ikarus_value_data_base_set(value, idx, new_data); } -void ikarus_number_value_remove(IkarusNumberValue * value, size_t idx) { - return ikarus_value_base_remove(value, idx); +void ikarus_number_value_data_remove(IkarusNumberValue * value, size_t idx) { + return ikarus_value_data_base_remove(value, idx); } -void ikarus_number_value_insert(IkarusNumberValue * value, size_t idx, long double new_data) { - return ikarus_value_base_insert(value, idx, new_data); +void ikarus_number_value_data_insert(IkarusNumberValue * value, size_t idx, long double new_data) { + return ikarus_value_data_base_insert(value, idx, new_data); } -void ikarus_number_value_clear(IkarusNumberValue * value) { - return ikarus_value_base_clear(value); +void ikarus_number_value_data_clear(IkarusNumberValue * value) { + return ikarus_value_data_base_clear(value); } -bool ikarus_number_value_is_undefined(IkarusNumberValue const * value) { - return ikarus_value_base_is_undefined(value); +bool ikarus_number_value_data_is_undefined(IkarusNumberValue const * value) { + return ikarus_value_data_base_is_undefined(value); } -void ikarus_number_value_set_undefined(IkarusNumberValue * value, bool undefined) { - return ikarus_value_base_set_undefined(value, undefined); +void ikarus_number_value_data_set_undefined(IkarusNumberValue * value, bool undefined) { + return ikarus_value_data_base_set_undefined(value, undefined); } -char const * ikarus_number_value_to_string(IkarusNumberValue const * value) { - return ikarus_value_base_to_string(value, [](auto const & value) { return value; }); +char const * ikarus_number_value_data_to_string(IkarusNumberValue const * value) { + return ikarus_value_data_base_to_string(value, [](auto const & value) { return value; }); } -bool ikarus_number_value_is_equal(IkarusNumberValue const * lhs, IkarusNumberValue const * rhs) { - return ikarus_value_base_is_equal(lhs, rhs); +bool ikarus_number_value_data_is_equal(IkarusNumberValue const * lhs, IkarusNumberValue const * rhs) { + return ikarus_value_data_base_is_equal(lhs, rhs); } -IkarusNumberValue * ikarus_number_value_copy(IkarusNumberValue const * value) { - return ikarus_value_base_copy(value); +IkarusNumberValue * ikarus_number_value_data_copy(IkarusNumberValue const * value) { + return ikarus_value_data_base_copy(value); } -struct IkarusValue * ikarus_number_value_to_value(IkarusNumberValue * value) { - return ikarus_value_base_to_value(value); +struct IkarusValueData * ikarus_number_value_data_to_value(IkarusNumberValue * value) { + return ikarus_value_data_base_to_value(value); } -struct IkarusValue const * ikarus_number_value_to_value_const(IkarusNumberValue const * value) { - return ikarus_value_base_to_value_const(value); +struct IkarusValueData const * ikarus_number_value_data_to_value_data_const(IkarusNumberValue const * value) { + return ikarus_value_data_base_to_value_data_const(value); } diff --git a/src/ikarus/values/number_value.hpp b/src/ikarus/values/number_value.hpp index 6c6cb70..bd4bec5 100644 --- a/src/ikarus/values/number_value.hpp +++ b/src/ikarus/values/number_value.hpp @@ -5,7 +5,7 @@ #include -struct IkarusNumberValue : IkarusValue { +struct IkarusNumberValue : IkarusValueData { public: using DataType = double; diff --git a/src/ikarus/values/text_value.cpp b/src/ikarus/values/text_value.cpp index 8235c6d..9400f2e 100644 --- a/src/ikarus/values/text_value.cpp +++ b/src/ikarus/values/text_value.cpp @@ -7,60 +7,60 @@ #include IkarusTextValue::IkarusTextValue(): - IkarusValue{this} {} + IkarusValueData{this} {} -IkarusTextValue * ikarus_text_value_create() { +IkarusTextValue * ikarus_text_value_data_create() { return new IkarusTextValue{}; } -char const * ikarus_text_value_get(IkarusTextValue * value, size_t idx) { - return ikarus_value_base_get(value, idx)->data(); +char const * ikarus_text_value_data_get(IkarusTextValue * value, size_t idx) { + return ikarus_value_data_base_get(value, idx)->data(); } -size_t ikarus_text_value_get_size(IkarusTextValue const * value) { - return ikarus_value_base_get_size(value); +size_t ikarus_text_value_data_get_size(IkarusTextValue const * value) { + return ikarus_value_data_base_get_size(value); } -void ikarus_text_value_set(IkarusTextValue * value, size_t idx, char const * new_data) { - return ikarus_value_base_set(value, idx, new_data); +void ikarus_text_value_data_set(IkarusTextValue * value, size_t idx, char const * new_data) { + return ikarus_value_data_base_set(value, idx, new_data); } -void ikarus_text_value_remove(IkarusTextValue * value, size_t idx) { - return ikarus_value_base_remove(value, idx); +void ikarus_text_value_data_remove(IkarusTextValue * value, size_t idx) { + return ikarus_value_data_base_remove(value, idx); } -void ikarus_text_value_insert(IkarusTextValue * value, size_t idx, char const * new_data) { - return ikarus_value_base_insert(value, idx, new_data); +void ikarus_text_value_data_insert(IkarusTextValue * value, size_t idx, char const * new_data) { + return ikarus_value_data_base_insert(value, idx, new_data); } -void ikarus_text_value_clear(IkarusTextValue * value) { - return ikarus_value_base_clear(value); +void ikarus_text_value_data_clear(IkarusTextValue * value) { + return ikarus_value_data_base_clear(value); } -bool ikarus_text_value_is_undefined(IkarusTextValue const * value) { - return ikarus_value_base_is_undefined(value); +bool ikarus_text_value_data_is_undefined(IkarusTextValue const * value) { + return ikarus_value_data_base_is_undefined(value); } -void ikarus_text_value_set_undefined(IkarusTextValue * value, bool undefined) { - return ikarus_value_base_set_undefined(value, undefined); +void ikarus_text_value_data_set_undefined(IkarusTextValue * value, bool undefined) { + return ikarus_value_data_base_set_undefined(value, undefined); } -char const * ikarus_text_value_to_string(IkarusTextValue const * value) { - return ikarus_value_base_to_string(value, [](auto const & value) { return value; }); +char const * ikarus_text_value_data_to_string(IkarusTextValue const * value) { + return ikarus_value_data_base_to_string(value, [](auto const & value) { return value; }); } -bool ikarus_text_value_is_equal(IkarusTextValue const * lhs, IkarusTextValue const * rhs) { - return ikarus_value_base_is_equal(lhs, rhs); +bool ikarus_text_value_data_is_equal(IkarusTextValue const * lhs, IkarusTextValue const * rhs) { + return ikarus_value_data_base_is_equal(lhs, rhs); } -IkarusTextValue * ikarus_text_value_copy(IkarusTextValue const * value) { - return ikarus_value_base_copy(value); +IkarusTextValue * ikarus_text_value_data_copy(IkarusTextValue const * value) { + return ikarus_value_data_base_copy(value); } -struct IkarusValue * ikarus_text_value_to_value(IkarusTextValue * value) { - return ikarus_value_base_to_value(value); +struct IkarusValueData * ikarus_text_value_data_to_value(IkarusTextValue * value) { + return ikarus_value_data_base_to_value(value); } -struct IkarusValue const * ikarus_text_value_to_value_const(IkarusTextValue const * value) { - return ikarus_value_base_to_value_const(value); +struct IkarusValueData const * ikarus_text_value_data_to_value_data_const(IkarusTextValue const * value) { + return ikarus_value_data_base_to_value_data_const(value); } diff --git a/src/ikarus/values/text_value.hpp b/src/ikarus/values/text_value.hpp index 512bb8d..a1e36ea 100644 --- a/src/ikarus/values/text_value.hpp +++ b/src/ikarus/values/text_value.hpp @@ -4,7 +4,7 @@ #include -struct IkarusTextValue : IkarusValue { +struct IkarusTextValue : IkarusValueData { public: using DataType = std::string; diff --git a/src/ikarus/values/toggle_value.cpp b/src/ikarus/values/toggle_value.cpp index 7bec1f2..fb76e68 100644 --- a/src/ikarus/values/toggle_value.cpp +++ b/src/ikarus/values/toggle_value.cpp @@ -7,60 +7,60 @@ #include IkarusToggleValue::IkarusToggleValue(): - IkarusValue{this} {} + IkarusValueData{this} {} -IkarusToggleValue * ikarus_toggle_value_create() { +IkarusToggleValue * ikarus_toggle_value_data_create() { return new IkarusToggleValue{}; } -bool const * ikarus_toggle_value_get(IkarusToggleValue * value, size_t idx) { - return ikarus_value_base_get(value, idx); +bool const * ikarus_toggle_value_data_get(IkarusToggleValue * value, size_t idx) { + return ikarus_value_data_base_get(value, idx); } -size_t ikarus_toggle_value_get_size(IkarusToggleValue const * value) { - return ikarus_value_base_get_size(value); +size_t ikarus_toggle_value_data_get_size(IkarusToggleValue const * value) { + return ikarus_value_data_base_get_size(value); } -void ikarus_toggle_value_set(IkarusToggleValue * value, size_t idx, bool new_data) { - return ikarus_value_base_set(value, idx, new_data); +void ikarus_toggle_value_data_set(IkarusToggleValue * value, size_t idx, bool new_data) { + return ikarus_value_data_base_set(value, idx, new_data); } -void ikarus_toggle_value_remove(IkarusToggleValue * value, size_t idx) { - return ikarus_value_base_remove(value, idx); +void ikarus_toggle_value_data_remove(IkarusToggleValue * value, size_t idx) { + return ikarus_value_data_base_remove(value, idx); } -void ikarus_toggle_value_insert(IkarusToggleValue * value, size_t idx, bool new_data) { - return ikarus_value_base_insert(value, idx, new_data); +void ikarus_toggle_value_data_insert(IkarusToggleValue * value, size_t idx, bool new_data) { + return ikarus_value_data_base_insert(value, idx, new_data); } -void ikarus_toggle_value_clear(IkarusToggleValue * value) { - return ikarus_value_base_clear(value); +void ikarus_toggle_value_data_clear(IkarusToggleValue * value) { + return ikarus_value_data_base_clear(value); } -bool ikarus_toggle_value_is_undefined(IkarusToggleValue const * value) { - return ikarus_value_base_is_undefined(value); +bool ikarus_toggle_value_data_is_undefined(IkarusToggleValue const * value) { + return ikarus_value_data_base_is_undefined(value); } -void ikarus_toggle_value_set_undefined(IkarusToggleValue * value, bool undefined) { - return ikarus_value_base_set_undefined(value, undefined); +void ikarus_toggle_value_data_set_undefined(IkarusToggleValue * value, bool undefined) { + return ikarus_value_data_base_set_undefined(value, undefined); } -char const * ikarus_toggle_value_to_string(IkarusToggleValue const * value) { - return ikarus_value_base_to_string(value, [](auto const & value) { return value ? "✓" : "✗"; }); +char const * ikarus_toggle_value_data_to_string(IkarusToggleValue const * value) { + return ikarus_value_data_base_to_string(value, [](auto const & value) { return value ? "✓" : "✗"; }); } -bool ikarus_toggle_value_is_equal(IkarusToggleValue const * lhs, IkarusToggleValue const * rhs) { - return ikarus_value_base_is_equal(lhs, rhs); +bool ikarus_toggle_value_data_is_equal(IkarusToggleValue const * lhs, IkarusToggleValue const * rhs) { + return ikarus_value_data_base_is_equal(lhs, rhs); } -IkarusToggleValue * ikarus_toggle_value_copy(IkarusToggleValue const * value) { - return ikarus_value_base_copy(value); +IkarusToggleValue * ikarus_toggle_value_data_copy(IkarusToggleValue const * value) { + return ikarus_value_data_base_copy(value); } -struct IkarusValue * ikarus_toggle_value_to_value(IkarusToggleValue * value) { - return ikarus_value_base_to_value(value); +struct IkarusValueData * ikarus_toggle_value_data_to_value(IkarusToggleValue * value) { + return ikarus_value_data_base_to_value(value); } -struct IkarusValue const * ikarus_toggle_value_to_value_const(IkarusToggleValue const * value) { - return ikarus_value_base_to_value_const(value); +struct IkarusValueData const * ikarus_toggle_value_data_to_value_data_const(IkarusToggleValue const * value) { + return ikarus_value_data_base_to_value_data_const(value); } diff --git a/src/ikarus/values/toggle_value.hpp b/src/ikarus/values/toggle_value.hpp index 6882ecc..fade2c1 100644 --- a/src/ikarus/values/toggle_value.hpp +++ b/src/ikarus/values/toggle_value.hpp @@ -4,7 +4,7 @@ #include -struct IkarusToggleValue : IkarusValue { +struct IkarusToggleValue : IkarusValueData { public: using DataType = bool; diff --git a/src/ikarus/values/value.cpp b/src/ikarus/values/value.cpp index bbea7f3..de57e26 100644 --- a/src/ikarus/values/value.cpp +++ b/src/ikarus/values/value.cpp @@ -3,41 +3,53 @@ #include #include - -// required for header-only inclusion -#include "cppbase/templates.hpp" - #include -#include +// required for header-only inclusion +#include + #include #include #include #include +#include +#include -IkarusValue::IkarusValue(Data data): - data(data) {} +IkarusValue::IkarusValue(Data data, IkarusValueCardinality cardinality): + data{data}, + cardinality{cardinality} {} cppbase::Result IkarusValue::from_json(boost::json::value json) { if (auto const * obj = json.if_object(); obj == nullptr) { return cppbase::err(FromJsonError{}); } else { - boost::int64_t const * type = nullptr; - boost::json::value const * data = nullptr; + int64_t const * type; + int64_t const * cardinality; + boost::json::value const * data; - if (auto const * type_value = obj->if_contains("type"); type_value == nullptr) { + if (auto const * type_value = obj->if_contains(IKARUS_VALUE_JSON_TYPE_KEY); type_value == nullptr) { return cppbase::err(FromJsonError{}); } else if (type = type_value->if_int64(); type == nullptr) { return cppbase::err(FromJsonError{}); } - if (data = obj->if_contains("data"); data == nullptr) { + if (auto const * cardinality_value = obj->if_contains(IKARUS_VALUE_JSON_CARDINALITY_KEY); cardinality_value == nullptr) { + return cppbase::err(FromJsonError{}); + } else if (cardinality = cardinality_value->if_int64(); cardinality == nullptr) { + return cppbase::err(FromJsonError{}); + } else if (*cardinality != IkarusValueCardinality_Single && *cardinality != IkarusValueCardinality_Multiple) { return cppbase::err(FromJsonError{}); } - auto create_value = [data]() -> cppbase::Result { + if (data = obj->if_contains(IKARUS_VALUE_JSON_DATA_KEY); data == nullptr) { + return cppbase::err(FromJsonError{}); + } + + auto create_value = [data, cardinality]() -> cppbase::Result { T * ret = nullptr; + ret->cardinality = *cardinality; + if (data->is_null()) { ret = new T{}; ret->data = boost::variant2::monostate{}; @@ -58,13 +70,13 @@ cppbase::Result IkarusValue::from_jso }; switch (*type) { - case IkarusPropertyType_Toggle: { + case IkarusValueType_Toggle: { return create_value.operator()(); } - case IkarusPropertyType_Number: { + case IkarusValueType_Number: { return create_value.operator()(); } - case IkarusPropertyType_Text: { + case IkarusValueType_Text: { return create_value.operator()(); } default: { @@ -75,18 +87,18 @@ cppbase::Result IkarusValue::from_jso } boost::json::value IkarusValue::to_json() const { - auto type = boost::variant2::visit( + auto type = std::visit( cppbase::overloaded{ - []([[maybe_unused]] IkarusToggleValue const * value) { return IkarusPropertyType_Toggle; }, - []([[maybe_unused]] IkarusNumberValue const * value) { return IkarusPropertyType_Number; }, - []([[maybe_unused]] IkarusTextValue const * value) { return IkarusPropertyType_Text; } + []([[maybe_unused]] IkarusToggleValue const * value) { return IkarusValueType_Toggle; }, + []([[maybe_unused]] IkarusNumberValue const * value) { return IkarusValueType_Number; }, + []([[maybe_unused]] IkarusTextValue const * value) { return IkarusValueType_Text; } }, data ); - auto data_json = boost::variant2::visit( + auto data_json = std::visit( [](T const * value) -> boost::json::value { - return boost::variant2::visit( + return std::visit( cppbase::overloaded{ []([[maybe_unused]] boost::variant2::monostate const & data) -> boost::json::value { return nullptr; }, [](auto const & data) -> boost::json::value { return boost::json::value_from(data); } @@ -98,8 +110,9 @@ boost::json::value IkarusValue::to_json() const { ); return { - {"type", type}, - {"data", data_json} + { IKARUS_VALUE_JSON_TYPE_KEY, type}, + {IKARUS_VALUE_JSON_CARDINALITY_KEY, cardinality}, + { IKARUS_VALUE_JSON_DATA_KEY, data_json} }; } @@ -110,7 +123,7 @@ void ikarus_value_visit( void (*text_visitor)(IkarusTextValue *, void *), void * data ) { - boost::variant2::visit( + std::visit( cppbase::overloaded{ [toggle_visitor, data](IkarusToggleValue * toggle_value) { toggle_visitor(toggle_value, data); }, [number_visitor, data](IkarusNumberValue * number_value) { number_visitor(number_value, data); }, @@ -119,20 +132,3 @@ void ikarus_value_visit( value->data ); } - -void ikarus_value_visit_const( - IkarusValue const * value, - void (*toggle_visitor)(IkarusToggleValue const *, void *), - void (*number_visitor)(IkarusNumberValue const *, void *), - void (*text_visitor)(IkarusTextValue const *, void *), - void * data -) { - boost::variant2::visit( - cppbase::overloaded{ - [toggle_visitor, data](IkarusToggleValue const * toggle_value) { toggle_visitor(toggle_value, data); }, - [number_visitor, data](IkarusNumberValue const * number_value) { number_visitor(number_value, data); }, - [text_visitor, data](IkarusTextValue const * text_value) { text_visitor(text_value, data); } - }, - value->data - ); -} diff --git a/src/ikarus/values/value.hpp b/src/ikarus/values/value.hpp index 1e5791b..07e92fc 100644 --- a/src/ikarus/values/value.hpp +++ b/src/ikarus/values/value.hpp @@ -1,20 +1,24 @@ #pragma once #include -#include #include #include #include +#include + +constexpr auto IKARUS_VALUE_JSON_TYPE_KEY = "type"; +constexpr auto IKARUS_VALUE_JSON_CARDINALITY_KEY = "card"; +constexpr auto IKARUS_VALUE_JSON_DATA_KEY = "data"; struct IkarusValue { public: - using Data = boost::variant2::variant; + using Data = std::variant; constexpr static auto SMALL_VEC_VALUE_SIZE = 8; public: - explicit IkarusValue(Data data); + explicit IkarusValue(Data data, IkarusValueCardinality cardinality); IkarusValue(IkarusValue const &) = default; IkarusValue(IkarusValue &&) noexcept = default; @@ -32,6 +36,7 @@ public: public: Data data; + IkarusValueCardinality cardinality; }; template<> @@ -74,3 +79,20 @@ IkarusValue * fetch_value_from_db(IkarusProject * project, IkarusErrorData * err return ret; } + +#define IKARUS_FAIL_IF_VALUE_MISSING_IMPL(var_name, entity, name, ret) \ + IKARUS_VTRYRV_OR_FAIL( \ + bool const var_name, \ + ret, \ + "unable to check whether value exists: {}", \ + IkarusErrorInfo_Database_QueryFailed, \ + (entity)->project->db->template query_one( \ + "SELECT EXISTS(SELECT 1 FROM `entity_values` WHERE `entity` = ? AND `name` = ?)", \ + (entity)->id, \ + name \ + ) \ + ) \ + \ + IKARUS_FAIL_IF(!(var_name), ret, "entity value does not exist", IkarusErrorInfo_Client_Misuse); + +#define IKARUS_FAIL_IF_VALUE_MISSING(entity, name, ret) IKARUS_FAIL_IF_VALUE_MISSING_IMPL(CPPBASE_UNIQUE_NAME(exists), entity, name, ret); diff --git a/src/ikarus/values/value_base.hpp b/src/ikarus/values/value_base.hpp index d4e6e25..5fa18ae 100644 --- a/src/ikarus/values/value_base.hpp +++ b/src/ikarus/values/value_base.hpp @@ -7,9 +7,10 @@ #include template -typename V::DataType const * ikarus_value_base_get(V * value, size_t idx) { - if (auto * data = - boost::variant2::get_if>(&value->data); +typename V::DataType const * ikarus_value_data_base_get(V * value, size_t idx) { + if (auto * data = boost::variant2::get_if>( + &value->data + ); data != nullptr) { return &(*data)[idx]; } @@ -18,9 +19,10 @@ typename V::DataType const * ikarus_value_base_get(V * value, size_t idx) { } template -size_t ikarus_value_base_get_size(V const * value) { - if (auto * data = - boost::variant2::get_if>(&value->data); +size_t ikarus_value_data_base_get_size(V const * value) { + if (auto * data = boost::variant2::get_if>( + &value->data + ); data != nullptr) { return data->size(); } @@ -29,57 +31,61 @@ size_t ikarus_value_base_get_size(V const * value) { } template -void ikarus_value_base_set(V * value, size_t idx, typename V::DataType new_data) { - if (auto * data = - boost::variant2::get_if>(&value->data); +void ikarus_value_data_base_set(V * value, size_t idx, typename V::DataType new_data) { + if (auto * data = boost::variant2::get_if>( + &value->data + ); data != nullptr) { (*data)[idx] = new_data; } } template -void ikarus_value_base_remove(V * value, size_t idx) { - if (auto * data = - boost::variant2::get_if>(&value->data); +void ikarus_value_data_base_remove(V * value, size_t idx) { + if (auto * data = boost::variant2::get_if>( + &value->data + ); data != nullptr) { data->erase(data->begin() + idx); } } template -void ikarus_value_base_insert(V * value, size_t idx, typename V::DataType new_data) { - if (auto * data = - boost::variant2::get_if>(&value->data); +void ikarus_value_data_base_insert(V * value, size_t idx, typename V::DataType new_data) { + if (auto * data = boost::variant2::get_if>( + &value->data + ); data != nullptr) { data->insert(data->begin() + idx, new_data); } } template -void ikarus_value_base_clear(V * value) { - if (auto * data = - boost::variant2::get_if>(&value->data); +void ikarus_value_data_base_clear(V * value) { + if (auto * data = boost::variant2::get_if>( + &value->data + ); data != nullptr) { data->clear(); } } template -bool ikarus_value_base_is_undefined(V const * value) { +bool ikarus_value_data_base_is_undefined(V const * value) { return boost::variant2::holds_alternative(value->data); } template -void ikarus_value_base_set_undefined(V * value, bool undefined) { +void ikarus_value_data_base_set_undefined(V * value, bool undefined) { if (undefined) { value->data = boost::variant2::monostate{}; } else { - value->data = boost::container::small_vector{}; + value->data = boost::container::small_vector{}; } } template F> -char const * ikarus_value_base_to_string(V const * value, F transformer) { +char const * ikarus_value_data_base_to_string(V const * value, F transformer) { return boost::variant2::visit( cppbase::overloaded{ [](boost::variant2::monostate const &) -> char const * { return nullptr; }, @@ -100,21 +106,21 @@ char const * ikarus_value_base_to_string(V const * value, F transformer) { } template -bool ikarus_value_base_is_equal(V const * lhs, V const * rhs) { +bool ikarus_value_data_base_is_equal(V const * lhs, V const * rhs) { return lhs->data == rhs->data; } template -V * ikarus_value_base_copy(V const * value) { +V * ikarus_value_data_base_copy(V const * value) { return new V{*value}; } template -struct IkarusValue * ikarus_value_base_to_value(V * value) { - return static_cast(value); +struct IkarusValueData * ikarus_value_data_base_to_value(V * value) { + return static_cast(value); } template -struct IkarusValue const * ikarus_value_base_to_value_const(V const * value) { - return static_cast(value); +struct IkarusValueData const * ikarus_value_data_base_to_value_data_const(V const * value) { + return static_cast(value); }