From 145a48acc9dd2b316a50267324517972d660ed53 Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Sat, 14 Sep 2024 22:25:39 +0300 Subject: [PATCH 01/34] Thing::Say; User API --- include/Langulus/User.hpp | 33 +++++++++++++++++++ source/Thing-Verbs.cpp | 68 ++++++++------------------------------- source/Thing.hpp | 16 ++------- 3 files changed, 50 insertions(+), 67 deletions(-) create mode 100644 include/Langulus/User.hpp diff --git a/include/Langulus/User.hpp b/include/Langulus/User.hpp new file mode 100644 index 0000000..a583f7a --- /dev/null +++ b/include/Langulus/User.hpp @@ -0,0 +1,33 @@ +/// +/// Langulus::Entity +/// Copyright (c) 2013 Dimo Markov +/// Part of the Langulus framework, see https://langulus.com +/// +/// SPDX-License-Identifier: GPL-3.0-or-later +/// +#pragma once +#include "../Entity/Thing.hpp" +#include "../Entity/Module.hpp" + + +namespace Langulus::A +{ + + /// + /// Abstract user module + /// + struct UserModule : virtual Module { + LANGULUS_BASES(Module); + UserModule() : Resolvable {this}, Module {nullptr} {} + }; + + /// + /// Abstract user unit + /// + struct User : virtual Unit { + LANGULUS(PRODUCER) UserModule; + LANGULUS_BASES(Unit); + User() : Resolvable {this} {} + }; + +} // namespace Langulus::A \ No newline at end of file diff --git a/source/Thing-Verbs.cpp b/source/Thing-Verbs.cpp index 5772558..d7e15b3 100644 --- a/source/Thing-Verbs.cpp +++ b/source/Thing-Verbs.cpp @@ -10,54 +10,31 @@ #include #if 0 - #define ENTITY_VERBOSE_ENABLED() 1 - #define ENTITY_VERBOSE_SELF(...) Logger::Verbose(this, ": ", __VA_ARGS__) - #define ENTITY_VERBOSE_SELF_TAB(...) const auto scoped = Logger::VerboseTab(this, ": ", __VA_ARGS__) - #define ENTITY_VERBOSE(...) Logger::Append(__VA_ARGS__) - #define ENTITY_CREATION_VERBOSE_SELF(...) Logger::Verbose(Self(), __VA_ARGS__) - #define ENTITY_SELECTION_VERBOSE_SELF(...) Logger::Verbose(Self(), __VA_ARGS__) + #define SELECT_VERBOSE_SELF(...) Logger::Verbose(Self(), __VA_ARGS__) #else - #define ENTITY_VERBOSE_ENABLED() 0 - #define ENTITY_VERBOSE_SELF(...) LANGULUS(NOOP) - #define ENTITY_VERBOSE_SELF_TAB(...) LANGULUS(NOOP) - #define ENTITY_VERBOSE(...) LANGULUS(NOOP) - #define ENTITY_CREATION_VERBOSE_SELF(...) LANGULUS(NOOP) - #define ENTITY_SELECTION_VERBOSE_SELF(...) LANGULUS(NOOP) + #define SELECT_VERBOSE_SELF(...) LANGULUS(NOOP) #endif namespace Langulus::Entity { - /// Find an AIAD component that can process speech and interpret using it - /// This function completely relies on external modules + /// Interpret and execute a natural message wherever possible in the + /// current context /// @param text - text to execute /// @return the results of the execution - Many Thing::Run(const Lingua& text) { + Many Thing::Say(const Text& text) { if (not text) return {}; - // Message is still contextless, we don't know where exactly to - // interpret it, so create message objects from the hierarchy, - // and try interpreting those to executable temporals - // Each trained AI in the hierarchy will produce its own - // interpretation - auto messages = CreateData( - Construct::From(static_cast(text))); - - Verbs::InterpretAs interpreter; - if (not Flow::DispatchFlat(messages, interpreter)) { - Logger::Error("Messages failed to interpret to temporal: ", messages); + // Push and execute in the active flow + auto flow = GetFlow(); + if (not flow) { + Logger::Error(this, ": No flow - can't execute message: ", text); return {}; } - // Execute the resulting scopes - Many results; - interpreter->ForEach([&](const Flow::Temporal& scope) { - results << Resolvable::Run(scope); - }); - - return Abandon(results); + return flow->Push(Verbs::Do::In(this, text)); } /// Executes a piece of code in the current context @@ -80,23 +57,6 @@ namespace Langulus::Entity } return flow->Push(Verbs::Do::In(this, Abandon(parsed))); - - /*if (not flow->Push(Verbs::Do::In(this, Abandon(parsed)))) { - // Couldn't push verbs - the flow probably has no future link - // points, or we're out of memory? - Logger::Error(this, ": Flow ", *flow, " couldn't Run code: ", code); - return {}; - } - - // Flow has changed, update it as if no time has passed, in order - // to execute any newly added parts, if in the proper time - // context. Anything produced as a side-effect will be returned. - // @attention, if you push a command that has time context before - // the current flow time, you'll be technically rewriting this - // thing's history - the entire timeline will be reverted back, - // and recomputed up to now (if that's possible). - flow->Update({}); - return {};*/ } /// Custom dispatcher, reflected via CT::Dispatcher @@ -179,7 +139,7 @@ namespace Langulus::Entity auto element = part.GetElementResolved(i); Verbs::Select selector {element}; if (not Flow::DispatchFlat(unitBlock, selector)) { - // Abort on first failure + // Abort on first failure localMismatch = true; return Loop::Break; } @@ -220,19 +180,19 @@ namespace Langulus::Entity if (not mismatch) { // We're not seeking an entity, but components/traits if (selectedTraits) { - ENTITY_SELECTION_VERBOSE_SELF(Logger::Green, + SELECT_VERBOSE_SELF(Logger::Green, "Trait(s) selected: ", selectedTraits); verb << selectedTraits; } if (selectedUnits) { - ENTITY_SELECTION_VERBOSE_SELF(Logger::Green, + SELECT_VERBOSE_SELF(Logger::Green, "Unit(s) selected: ", selectedUnits); verb << selectedUnits; } if (selectedEntities) { - ENTITY_SELECTION_VERBOSE_SELF(Logger::Green, + SELECT_VERBOSE_SELF(Logger::Green, "Entity(s) selected: ", selectedEntities); verb << selectedEntities; } diff --git a/source/Thing.hpp b/source/Thing.hpp index cb4c098..d10b7a7 100644 --- a/source/Thing.hpp +++ b/source/Thing.hpp @@ -22,20 +22,10 @@ LANGULUS_DEFINE_TRAIT(Unit, namespace Langulus::Entity { - using UnitList = TMany;// Ref> ; - using UnitMap = TUnorderedMap>;// Ref> > ; + using UnitList = TMany; + using UnitMap = TUnorderedMap>; using TraitMap = TUnorderedMap; - /// A text specialization, dedicated for natural language text - /// It is a placeholder type, that can be extended by external modules - struct Lingua : Text { - LANGULUS(ABSTRACT) true; - LANGULUS_CONVERTS_FROM(); - - private: - using Text::SerializationRules; - }; - /// /// Thing @@ -123,7 +113,7 @@ namespace Langulus::Entity template V& Run(V&); - LANGULUS_API(ENTITY) Many Run(const Lingua&); + LANGULUS_API(ENTITY) Many Say(const Text&); LANGULUS_API(ENTITY) Many Run(const Code&); LANGULUS_API(ENTITY) bool Update(Time); From 9f933d1e82fb553398a75dda67eab3fb77e6f3da Mon Sep 17 00:00:00 2001 From: Epixu Date: Mon, 16 Sep 2024 19:12:45 +0300 Subject: [PATCH 02/34] Reflecting A::UserModule and A::User from the get go --- source/Runtime.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/Runtime.cpp b/source/Runtime.cpp index 0c32097..9aab0a4 100644 --- a/source/Runtime.cpp +++ b/source/Runtime.cpp @@ -20,6 +20,7 @@ #include "../include/Langulus/Input.hpp" #include "../include/Langulus/Life.hpp" #include "../include/Langulus/Network.hpp" +#include "../include/Langulus/User.hpp" #if LANGULUS_OS(WINDOWS) #include @@ -98,6 +99,8 @@ namespace Langulus::Entity (void)MetaDataOf(); (void)MetaDataOf(); (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); VERBOSE(this, ": Initialized"); } From d616f88f10559d9c31ca4cd92a761d16051f3f5d Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Tue, 24 Sep 2024 10:01:57 +0300 Subject: [PATCH 03/34] Properly reflected API; Minor renames --- include/Langulus/UI.hpp | 44 ++++++++++++++++++++--------------------- source/Runtime.cpp | 41 +++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 23 deletions(-) diff --git a/include/Langulus/UI.hpp b/include/Langulus/UI.hpp index 8ef3c0a..05562fe 100644 --- a/include/Langulus/UI.hpp +++ b/include/Langulus/UI.hpp @@ -10,59 +10,59 @@ #include "../Entity/Module.hpp" -namespace Langulus::A::UI +namespace Langulus::A { /// /// Abstract UI module /// - struct Module : virtual A::Module { + struct UIModule : virtual A::Module { LANGULUS_BASES(A::Module); - Module() : Resolvable {this}, A::Module {nullptr} {} + UIModule() : Resolvable {this}, A::Module {nullptr} {} }; /// /// Abstract UI unit /// - struct Unit : virtual A::Unit { - LANGULUS(PRODUCER) UI::Module; + struct UIUnit : virtual A::Unit { + LANGULUS(PRODUCER) UIModule; LANGULUS_BASES(A::Unit); - Unit() : Resolvable {this} {} + UIUnit() : Resolvable {this} {} }; /// /// Abstract UI system /// - struct System : virtual UI::Unit { - LANGULUS_BASES(UI::Unit); - System() : Resolvable {this} {} + struct UISystem : virtual UIUnit { + LANGULUS_BASES(UIUnit); + UISystem() : Resolvable {this} {} }; /// /// Abstract UI button /// - struct Button : virtual UI::Unit { - LANGULUS(PRODUCER) UI::System; - LANGULUS_BASES(UI::Unit); - Button() : Resolvable {this} {} + struct UIButton : virtual UIUnit { + LANGULUS(PRODUCER) UISystem; + LANGULUS_BASES(UIUnit); + UIButton() : Resolvable {this} {} }; /// /// Abstract UI text field /// - struct Text : virtual UI::Unit { - LANGULUS(PRODUCER) UI::System; - LANGULUS_BASES(UI::Unit); - Text() : Resolvable {this} {} + struct UILabel : virtual UIUnit { + LANGULUS(PRODUCER) UISystem; + LANGULUS_BASES(UIUnit); + UILabel() : Resolvable {this} {} }; /// /// Abstract UI input field /// - struct Input : virtual UI::Unit { - LANGULUS(PRODUCER) UI::System; - LANGULUS_BASES(UI::Unit); - Input() : Resolvable {this} {} + struct UIInput : virtual UIUnit { + LANGULUS(PRODUCER) UISystem; + LANGULUS_BASES(UIUnit); + UIInput() : Resolvable {this} {} }; -} // namespace Langulus::A::UI \ No newline at end of file +} // namespace Langulus::A \ No newline at end of file diff --git a/source/Runtime.cpp b/source/Runtime.cpp index 9aab0a4..5bf9b01 100644 --- a/source/Runtime.cpp +++ b/source/Runtime.cpp @@ -82,25 +82,64 @@ namespace Langulus::Entity // mModulesByType - it is indexed by a DMeta // So we make sure that the base modules are defined here (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); - (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); (void)MetaDataOf(); (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); (void)MetaDataOf(); (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); (void)MetaDataOf(); (void)MetaDataOf(); (void)MetaDataOf(); + (void)MetaDataOf(); (void)MetaDataOf(); + VERBOSE(this, ": Initialized"); } From 63a7d844517bf724dac7c462edcff5cec1ba1656 Mon Sep 17 00:00:00 2001 From: Epixu Date: Tue, 24 Sep 2024 16:22:36 +0300 Subject: [PATCH 04/34] Reflecting fundamentals on runtime creation --- source/Runtime.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source/Runtime.cpp b/source/Runtime.cpp index 5bf9b01..c260657 100644 --- a/source/Runtime.cpp +++ b/source/Runtime.cpp @@ -77,6 +77,18 @@ namespace Langulus::Entity Runtime::Runtime(Thing* owner) noexcept : mOwner {owner} { VERBOSE(this, ": Initializing..."); + + // Reflect fundamentals + (void) MetaDataOf(); + (void) MetaDataOf(); + (void) MetaDataOf(); + (void) MetaDataOf(); + (void) MetaDataOf(); + (void) MetaDataOf(); + (void) MetaDataOf(); + (void) MetaDataOf(); + (void) MetaDataOf(); + // We always prefer 'type' definitions that are in the main // boundary, to avoid segfaults when unloading libraries from // mModulesByType - it is indexed by a DMeta From c18dba723c860c0c86ffc6611c663e5fb32b45ef Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Wed, 25 Sep 2024 10:44:08 +0300 Subject: [PATCH 05/34] Registering Math verbs and trais on Runtime init --- source/Runtime.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/source/Runtime.cpp b/source/Runtime.cpp index c260657..16d0600 100644 --- a/source/Runtime.cpp +++ b/source/Runtime.cpp @@ -79,15 +79,18 @@ namespace Langulus::Entity VERBOSE(this, ": Initializing..."); // Reflect fundamentals - (void) MetaDataOf(); - (void) MetaDataOf(); - (void) MetaDataOf(); - (void) MetaDataOf(); - (void) MetaDataOf(); - (void) MetaDataOf(); - (void) MetaDataOf(); - (void) MetaDataOf(); - (void) MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + (void)MetaDataOf(); + + Math::RegisterTraits(); + Math::RegisterVerbs(); // We always prefer 'type' definitions that are in the main // boundary, to avoid segfaults when unloading libraries from From 6ab907a46ff3e15ed8caf9a9fb1f5eadfe1e5363 Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Thu, 26 Sep 2024 09:54:13 +0300 Subject: [PATCH 06/34] Minor changes --- source/Event.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/Event.hpp b/source/Event.hpp index 57c42d4..216772a 100644 --- a/source/Event.hpp +++ b/source/Event.hpp @@ -137,10 +137,10 @@ namespace Langulus EVENT() : Event {} { \ mType = MetaOf(); \ } \ - EVENT(Describe&& desc) { \ + EVENT(Describe descriptor) { \ mType = MetaOf(); \ - desc->ExtractData(mState); \ - desc->ExtractTrait(mPayload); \ + descriptor->ExtractData(mState); \ + descriptor->ExtractTrait(mPayload); \ } \ template \ EVENT(EventState state, T_&&...a) : Event {Forward(a)...} { \ @@ -162,10 +162,10 @@ namespace Langulus EVENT() : Event {} { \ mType = MetaOf(); \ } \ - EVENT(Describe&& desc) { \ + EVENT(Describe descriptor) { \ mType = MetaOf(); \ - desc->ExtractData(mState); \ - desc->ExtractTrait(mPayload); \ + descriptor->ExtractData(mState); \ + descriptor->ExtractTrait(mPayload); \ } \ template \ EVENT(EventState state, T_&&...a) : Event {Forward(a)...} { \ From dda42263b15bc1326d82d00e9defe4679e6ad32b Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Mon, 30 Sep 2024 10:22:28 +0300 Subject: [PATCH 07/34] Fixes --- source/Event.hpp | 4 +++- source/Event.inl | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/source/Event.hpp b/source/Event.hpp index 216772a..f146253 100644 --- a/source/Event.hpp +++ b/source/Event.hpp @@ -69,6 +69,8 @@ namespace Langulus /// Events are often used as arguments for Verbs::Interact /// struct Event { + using Many = Anyness::Many; + LANGULUS_CONVERTS_TO(Anyness::Text); // Event type @@ -88,7 +90,7 @@ namespace Langulus Event(Event&&); template requires CT::UnfoldInsertable Event(T1&&, TN&&...); - Event(Describe&&); + Event(Describe); /// /// Assignment diff --git a/source/Event.inl b/source/Event.inl index f6cfa13..5e7f906 100644 --- a/source/Event.inl +++ b/source/Event.inl @@ -119,7 +119,7 @@ namespace Langulus /// Descriptor-construction /// @param other - event properties and payload to move LANGULUS(INLINED) - Event::Event(Describe&& desc) : Event {} { + Event::Event(Describe desc) : Event {} { LANGULUS_ASSERT(desc->ExtractData(mType), Construct, "Invalid event"); desc->ExtractData(mState); desc->ExtractTrait(mPayload); @@ -140,9 +140,9 @@ namespace Langulus mTimestamp = DeintCast(t1).mTimestamp; mPayload = S::Nest(DeintCast(t1).mPayload); } - else mPayload = Anyness::Many {Forward(t1)}; + else mPayload = Many {Forward(t1)}; } - else mPayload = Anyness::Many {Forward(t1), Forward(tn)...}; + else mPayload = Many {Forward(t1), Forward(tn)...}; } /// Refer-assignment @@ -178,7 +178,7 @@ namespace Langulus mTimestamp = DeintCast(rhs).mTimestamp; mPayload = S::Nest(DeintCast(rhs).mPayload); } - else mPayload = Anyness::Many {S::Nest(rhs)}; + else mPayload = Many {S::Nest(rhs)}; return *this; } From 7c2f1d4f7858835586a6015e0ea4a7192f66b499 Mon Sep 17 00:00:00 2001 From: Epixu Date: Mon, 30 Sep 2024 18:40:04 +0300 Subject: [PATCH 08/34] Fixing parenting --- source/Thing-Verbs.cpp | 2 +- source/Thing.inl | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/source/Thing-Verbs.cpp b/source/Thing-Verbs.cpp index d7e15b3..add59f1 100644 --- a/source/Thing-Verbs.cpp +++ b/source/Thing-Verbs.cpp @@ -133,7 +133,7 @@ namespace Langulus::Entity for (auto& unit : selectedUnits) { bool localMismatch = false; auto unitBlock = unit->GetBlock(); - construct.GetDescriptor().ForEach( + construct->ForEach( [&](const Many& part) { for (Offset i = 0; i < part.GetCount(); ++i) { auto element = part.GetElementResolved(i); diff --git a/source/Thing.inl b/source/Thing.inl index 373f26e..f872bf1 100644 --- a/source/Thing.inl +++ b/source/Thing.inl @@ -572,6 +572,7 @@ namespace Langulus::Entity const auto type = construct.GetType(); const auto producer = type and type->mProducerRetriever ? type->mProducerRetriever() : nullptr; + ENTITY_VERBOSE_SELF( "Acting as producer context for making `", type, "` (at ", Reference(0), " references)" @@ -581,13 +582,17 @@ namespace Langulus::Entity // already added - it will be stripped later, when normalizing // the descriptor when producing the item from a factory Construct descriptor {construct}; - if (not descriptor.GetDescriptor().Get()) { - descriptor << Traits::Parent {this}; + Traits::Parent parent; + if (not descriptor->ExtractTrait(parent)) { + parent = this; + parent.MakeMissing(); + descriptor << parent; ENTITY_VERBOSE_SELF( - "Referenced as Traits::Parent (now at ", Reference(0), - " references)" + "Referenced as Traits::Parent (now at ", + Reference(0), " references)" ); } + else parent << this; if (producer) { // Data has a specific producer, we can narrow the required From e70d8c2ca7e06945e9d4503f50887ff16b818aff Mon Sep 17 00:00:00 2001 From: Epixu Date: Tue, 1 Oct 2024 19:10:51 +0300 Subject: [PATCH 09/34] Minor improvements --- source/Module.hpp | 1 - source/Thing.hpp | 3 +-- source/Unit.hpp | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/source/Module.hpp b/source/Module.hpp index 1ad0f2d..73394fc 100644 --- a/source/Module.hpp +++ b/source/Module.hpp @@ -60,7 +60,6 @@ namespace Langulus::A /// class Module : public virtual Resolvable { LANGULUS(PRODUCER) Entity::Runtime; - LANGULUS(UNINSERTABLE) false; LANGULUS_BASES(Resolvable); private: diff --git a/source/Thing.hpp b/source/Thing.hpp index d10b7a7..006c1ab 100644 --- a/source/Thing.hpp +++ b/source/Thing.hpp @@ -41,10 +41,9 @@ namespace Langulus::Entity { LANGULUS(ABSTRACT) false; LANGULUS(PRODUCER) Thing; - LANGULUS(UNINSERTABLE) false; + LANGULUS(POOL_TACTIC) RTTI::PoolTactic::Type; LANGULUS_BASES(Resolvable); LANGULUS_VERBS(Verbs::Create, Verbs::Select); - LANGULUS(POOL_TACTIC) RTTI::PoolTactic::Type; protected: LANGULUS_API(ENTITY) void ResetRuntime(Runtime*); diff --git a/source/Unit.hpp b/source/Unit.hpp index 2b33dde..f06f30b 100644 --- a/source/Unit.hpp +++ b/source/Unit.hpp @@ -35,7 +35,6 @@ namespace Langulus::A #endif , Entity::SeekInterface { - LANGULUS(UNINSERTABLE) false; LANGULUS_BASES(Resolvable); protected: From 229bb041ccfbee182167a07871412ce853361a5d Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Fri, 4 Oct 2024 11:31:12 +0300 Subject: [PATCH 10/34] Fixing asset data access error --- include/Langulus/Asset.hpp | 22 +++++++++---------- include/Langulus/Asset.inl | 22 +++++++++---------- include/Langulus/Mesh.hpp | 37 ++++++++++++++++++-------------- include/Langulus/Mesh.inl | 43 +++++++++++++++++++------------------- source/Runtime.cpp | 6 ++---- 5 files changed, 66 insertions(+), 64 deletions(-) diff --git a/include/Langulus/Asset.hpp b/include/Langulus/Asset.hpp index 63e760c..4363355 100644 --- a/include/Langulus/Asset.hpp +++ b/include/Langulus/Asset.hpp @@ -26,7 +26,7 @@ namespace Langulus::A Ref mFolder; public: - const Ref& GetFolder() const noexcept; + auto GetFolder() const noexcept -> const Ref&; }; @@ -56,25 +56,25 @@ namespace Langulus::A void Commit(auto&&) const; template - NOD() const Data* GetData(Offset = 0) const noexcept; - NOD() const Data* GetData(TMeta, Offset = 0) const noexcept; + NOD() auto GetData(Offset = 0) const noexcept -> const Data*; + NOD() auto GetData(TMeta, Offset = 0) const noexcept -> const Data*; template - NOD() const DataList* GetDataList() const noexcept; - NOD() const DataList* GetDataList(TMeta) const noexcept; + NOD() auto GetDataList() const noexcept -> const DataList*; + NOD() auto GetDataList(TMeta) const noexcept -> const DataList*; - NOD() DataListMap const& GetDataListMap() const noexcept; + NOD() auto GetDataListMap() const noexcept -> DataListMap const&; protected: template - NOD() Data* GetData(Offset = 0) noexcept; - NOD() Data* GetData(TMeta, Offset = 0) noexcept; + NOD() auto GetData(Offset = 0) noexcept -> Data*; + NOD() auto GetData(TMeta, Offset = 0) noexcept -> Data*; template - NOD() DataList* GetDataList() noexcept; - NOD() DataList* GetDataList(TMeta) noexcept; + NOD() auto GetDataList() noexcept -> DataList*; + NOD() auto GetDataList(TMeta) noexcept -> DataList*; - NOD() DataListMap& GetDataListMap() noexcept; + NOD() auto GetDataListMap() noexcept -> DataListMap&; }; } // namespace Langulus::A diff --git a/include/Langulus/Asset.inl b/include/Langulus/Asset.inl index 541edc8..43a497d 100644 --- a/include/Langulus/Asset.inl +++ b/include/Langulus/Asset.inl @@ -15,7 +15,7 @@ namespace Langulus::A /// Retrieve the asset module's repository folder /// @return a reference to the folder interface LANGULUS(INLINED) - const Ref& AssetModule::GetFolder() const noexcept { + auto AssetModule::GetFolder() const noexcept -> const Ref& { return mFolder; } @@ -23,12 +23,12 @@ namespace Langulus::A /// @attention this doesn't generate any data /// @return a reference to the contents LANGULUS(INLINED) - Asset::DataListMap const& Asset::GetDataListMap() const noexcept { + auto Asset::GetDataListMap() const noexcept -> DataListMap const& { return mDataListMap; } LANGULUS(INLINED) - Asset::DataListMap& Asset::GetDataListMap() noexcept { + auto Asset::GetDataListMap() noexcept -> DataListMap& { return mDataListMap; } @@ -37,7 +37,7 @@ namespace Langulus::A /// @param index - the Nth data associated to the trait /// @return a pointer to the data entry, or nullptr if none exists template LANGULUS(INLINED) - Asset::Data* Asset::GetData(Offset index) noexcept { + auto Asset::GetData(Offset index) noexcept -> Data* { TMeta trait; if constexpr (CT::Trait) trait = MetaTraitOf(); @@ -45,7 +45,7 @@ namespace Langulus::A } template LANGULUS(INLINED) - Asset::Data const* Asset::GetData(Offset index) const noexcept { + auto Asset::GetData(Offset index) const noexcept -> Data const* { return const_cast(this)->GetData(index); } @@ -54,7 +54,7 @@ namespace Langulus::A /// @param index - the Nth data associated to the trait /// @return a pointer to the data entry, or nullptr if none exists LANGULUS(INLINED) - Asset::Data* Asset::GetData(TMeta trait, Offset index) noexcept { + auto Asset::GetData(TMeta trait, Offset index) noexcept -> Data* { if (not Generate(trait, index)) return nullptr; @@ -65,7 +65,7 @@ namespace Langulus::A } LANGULUS(INLINED) - Asset::Data const* Asset::GetData(TMeta trait, Offset index) const noexcept { + auto Asset::GetData(TMeta trait, Offset index) const noexcept -> Data const* { return const_cast(this)->GetData(trait, index); } @@ -73,7 +73,7 @@ namespace Langulus::A /// @tparam T - the trait to search for /// @return a pointer to the data list, or nullptr if none exists template LANGULUS(INLINED) - Asset::DataList* Asset::GetDataList() noexcept { + auto Asset::GetDataList() noexcept -> DataList* { TMeta trait; if constexpr (CT::Trait) trait = MetaTraitOf(); @@ -81,7 +81,7 @@ namespace Langulus::A } template LANGULUS(INLINED) - Asset::DataList const* Asset::GetDataList() const noexcept { + auto Asset::GetDataList() const noexcept -> DataList const* { return const_cast(this)->GetDataList(); } @@ -89,7 +89,7 @@ namespace Langulus::A /// @param trait - the trait to search for /// @return a pointer to the data list, or nullptr if none exists LANGULUS(INLINED) - Asset::DataList* Asset::GetDataList(TMeta trait) noexcept { + auto Asset::GetDataList(TMeta trait) noexcept -> DataList* { if (not const_cast(this)->Generate(trait)) return nullptr; @@ -98,7 +98,7 @@ namespace Langulus::A } LANGULUS(INLINED) - const Asset::DataList* Asset::GetDataList(TMeta trait) const noexcept { + auto Asset::GetDataList(TMeta trait) const noexcept -> const DataList* { return const_cast(this)->GetDataList(trait); } diff --git a/include/Langulus/Mesh.hpp b/include/Langulus/Mesh.hpp index ad88c4c..c0db671 100644 --- a/include/Langulus/Mesh.hpp +++ b/include/Langulus/Mesh.hpp @@ -20,6 +20,8 @@ namespace Langulus /// Vertex/index buffer view /// struct MeshView { + using MapModeType = Math::MapModeType; + // Number of primitives uint32_t mPrimitiveCount = 0; // Starting primitive @@ -33,11 +35,11 @@ namespace Langulus // Double-sidedness bool mBilateral = false; // Texture mapping mode - Math::MapModeType mTextureMapping = Math::MapModeType::Auto; + MapModeType mTextureMapping = MapModeType::Auto; bool operator == (const MeshView&) const noexcept; - NOD() MeshView Decay() const; + NOD() auto Decay() const -> MeshView; NOD() Hash GetHash() const noexcept; }; @@ -51,6 +53,9 @@ namespace Langulus::A /// struct Mesh : Asset { protected: + using MapModeType = Math::MapModeType; + using Vec2u = Math::Vec2u; + using Vec3u = Math::Vec3u; MeshView mView; public: @@ -58,32 +63,32 @@ namespace Langulus::A Mesh() : Resolvable {this} {} template - NOD() bool CheckTopology() const; - NOD() DMeta GetTopology() const noexcept; - NOD() Math::MapModeType GetTextureMapper() const noexcept; + NOD() bool CheckTopology() const; + NOD() auto GetTopology() const noexcept -> DMeta; + NOD() auto GetTextureMapper() const noexcept -> MapModeType; - NOD() MeshView const& GetView() const noexcept; - NOD() MeshView& GetView() noexcept; + NOD() auto GetView() const noexcept -> MeshView const&; + NOD() auto GetView() noexcept -> MeshView&; NOD() virtual Ref GetLOD(const Math::LOD&) const = 0; // Point utilities NOD() bool MadeOfPoints() const noexcept; - NOD() Count GetPointCount() const; + NOD() auto GetPointCount() const -> Count; template NOD() Many GetPointTrait(Offset) const; // Line utilities NOD() bool MadeOfLines() const noexcept; - NOD() Count GetLineCount() const; - NOD() Math::Vec2u GetLineIndices(Offset) const; + NOD() auto GetLineCount() const -> Count; + NOD() auto GetLineIndices(Offset) const -> Vec2u; template NOD() Many GetLineTrait(Offset) const; // Triangle utilities NOD() bool MadeOfTriangles() const noexcept; - NOD() Count GetTriangleCount() const; - NOD() Math::Vec3u GetTriangleIndices(Offset) const; + NOD() auto GetTriangleCount() const -> Count; + NOD() auto GetTriangleIndices(Offset) const -> Vec3u; template NOD() Many GetTriangleTrait(Offset) const; @@ -93,8 +98,8 @@ namespace Langulus::A Count ForEachVertex(auto&&) const; protected: - NOD() Math::Vec2u InnerGetIndices(const Data*, const Math::Vec2u&) const; - NOD() Math::Vec3u InnerGetIndices(const Data*, const Math::Vec3u&) const; + NOD() Vec2u InnerGetIndices(const Data*, const Vec2u&) const; + NOD() Vec3u InnerGetIndices(const Data*, const Vec3u&) const; template Count ForEachVertexInner(Types, auto&& call) const; @@ -105,10 +110,10 @@ namespace Langulus::A template T ForEachVertex_PrepareIndexStream() const; - template + template auto PickVertex(Offset i, const CT::Trait auto& data, const CT::Trait auto& indices) const; - template + template auto GenerateVertex(Offset i, const auto& data, const auto& indices, std::index_sequence&&) const; }; diff --git a/include/Langulus/Mesh.inl b/include/Langulus/Mesh.inl index 5fb6416..0e4a644 100644 --- a/include/Langulus/Mesh.inl +++ b/include/Langulus/Mesh.inl @@ -30,7 +30,7 @@ namespace Langulus /// Decay the geometry view to a list of points /// @return the decayed view LANGULUS(INLINED) - MeshView MeshView::Decay() const { + auto MeshView::Decay() const -> MeshView { LANGULUS_ASSERT(mPrimitiveCount and mTopology, Convert, "Bad vertex view"); if (mTopology->template Is()) return *this; @@ -77,14 +77,14 @@ namespace Langulus::A /// Get the topology of the geometry /// @return the topology type LANGULUS(INLINED) - DMeta Mesh::GetTopology() const noexcept { + auto Mesh::GetTopology() const noexcept -> DMeta { return mView.mTopology; } /// Get the texture mapping mode /// @return the texture mapping mode LANGULUS(INLINED) - Math::MapModeType Mesh::GetTextureMapper() const noexcept { + auto Mesh::GetTextureMapper() const noexcept -> MapModeType { return mView.mTextureMapping; } @@ -100,14 +100,14 @@ namespace Langulus::A /// Get the geometry view (const) /// @return the geometry view LANGULUS(INLINED) - const MeshView& Mesh::GetView() const noexcept { + auto Mesh::GetView() const noexcept -> const MeshView& { return mView; } /// Get the geometry view /// @return the geometry view LANGULUS(INLINED) - MeshView& Mesh::GetView() noexcept { + auto Mesh::GetView() noexcept -> MeshView& { return mView; } @@ -115,7 +115,7 @@ namespace Langulus::A /// @param indices - index buffer /// @param where - line indices /// @return the (eventually indirected) line indices - inline Math::Vec2u Mesh::InnerGetIndices(const Data* indices, const Math::Vec2u& where) const { + inline auto Mesh::InnerGetIndices(const Data* indices, const Vec2u& where) const -> Vec2u { if (not indices or not *indices) return where; @@ -142,14 +142,15 @@ namespace Langulus::A }; } - LANGULUS_THROW(Access, "Trying to get index from incompatible index buffer"); + LANGULUS_THROW(Access, + "Trying to get index from incompatible index buffer"); } /// Helper that indirects in case there is an index buffer /// @param indices - index buffer /// @param where - triangle indices /// @return the (eventually indirected) triangle indices - inline Math::Vec3u Mesh::InnerGetIndices(const Data* indices, const Math::Vec3u& where) const { + inline auto Mesh::InnerGetIndices(const Data* indices, const Vec3u& where) const -> Vec3u { if (not indices or not *indices) return where; @@ -177,7 +178,8 @@ namespace Langulus::A }; } - LANGULUS_THROW(Access, "Trying to get index from incompatible index buffer"); + LANGULUS_THROW(Access, + "Trying to get index from incompatible index buffer"); } /// Is topology a point list? @@ -196,7 +198,7 @@ namespace Langulus::A } template - Anyness::Many Mesh::GetPointTrait(Offset) const { + Many Mesh::GetPointTrait(Offset) const { TODO(); return {}; } @@ -262,8 +264,7 @@ namespace Langulus::A /// Get the point indices of a given line /// @param index - line index /// @return the point indices as a 32bit unsigned 2D vector - inline Math::Vec2u Mesh::GetLineIndices(Offset index) const { - using Math::Vec2u; + inline auto Mesh::GetLineIndices(Offset index) const -> Vec2u { const auto indices = GetData(); if (CheckTopology()) @@ -370,8 +371,7 @@ namespace Langulus::A /// @attention not optimized for iteration /// @param index - triangle index /// @return the indices as a 32bit unsigned 3D vector - inline Math::Vec3u Mesh::GetTriangleIndices(Offset index) const { - using Math::Vec3u; + inline auto Mesh::GetTriangleIndices(Offset index) const -> Vec3u { const auto indices = GetData(0); if (CheckTopology()) { @@ -606,19 +606,18 @@ namespace Langulus::A return {}; if (indices->GetCount() == 1) { - // Single index source will be used for all Ts + // Single index source will be used for all vertex traits return Disown((*indices)[0]); } // Multiple index sequences for different streams // Each sequence should be kept in a corresponding trait - for (auto& group : *indices) { - if (group.IsSimilar()) - return group.Get(); - } - - // No indices for T found - return {}; + T result; + indices->ForEachDeep([&result](const T& trait) noexcept { + result = trait; + return Loop::Break; + }); + return result; } /// Invoke 'call' with the required arguments diff --git a/source/Runtime.cpp b/source/Runtime.cpp index 16d0600..78a2c7d 100644 --- a/source/Runtime.cpp +++ b/source/Runtime.cpp @@ -428,8 +428,7 @@ namespace Langulus::Entity MetaList types; library.mEntry(library.mModuleType, types); if (types.IsEmpty()) { - Logger::Error( - "A module must register at least one type" + Logger::Error("A module must register at least one type" " - the module instantiation type"); (void)UnloadSharedLibrary(library); return {}; @@ -470,8 +469,7 @@ namespace Langulus::Entity mLibraries.Insert(name, library); // Do some info logging - Logger::Info( - "Module `", library.mInfo()->mName, + Logger::Info("Module `", library.mInfo()->mName, "` exposed the following types: ", Logger::DarkGreen); bool first = true; for (auto& t : types) { From df698cd1b98b382963f88b7c6f98e84e8719a076 Mon Sep 17 00:00:00 2001 From: Epixu Date: Fri, 4 Oct 2024 18:10:24 +0300 Subject: [PATCH 11/34] Improved DumpHierarchy --- source/Thing.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/source/Thing.cpp b/source/Thing.cpp index 72a3d32..9c1176e 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -215,24 +215,29 @@ namespace Langulus::Entity /// Dump the entity's hierarchy in log void Thing::DumpHierarchy() const { - const auto tab = Logger::VerboseTab("** ", *this); + const auto tab = Logger::Section(Logger::Intent::Verbose, + Logger::White, Logger::Underline, *this + ); if (mTraits) { - Logger::Verbose(".. contains ", mTraits.GetCount(), " traits:"); + const auto tab2 = Logger::Section(Logger::White, Logger::Underline, + "Traits (", mTraits.GetCount(), "):"); for (auto traitpair : mTraits) { for (auto& trait : traitpair.mValue) - Logger::Verbose(". ", trait); + Logger::Verbose(trait); } } if (mUnitsList) { - Logger::Verbose("++ contains ", mUnitsList.GetCount(), " units:"); + const auto tab2 = Logger::Section(Logger::White, Logger::Underline, + "Units (", mUnitsList.GetCount(), "):"); for (auto& unit : mUnitsList) - Logger::Verbose("+ ", *unit); + Logger::Verbose(*unit); } if (mChildren) { - Logger::Verbose("** contains ", mChildren.GetCount(), " child entities:"); + const auto tab2 = Logger::Section(Logger::White, Logger::Underline, + "Children (", mChildren.GetCount(), "):"); for (auto& child : mChildren) child->DumpHierarchy(); } From e1db05ca1983cfdac3468dce934e9446c00665ad Mon Sep 17 00:00:00 2001 From: Epixu Date: Mon, 7 Oct 2024 18:52:53 +0300 Subject: [PATCH 12/34] Improved logging in release --- source/Thing.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/Thing.cpp b/source/Thing.cpp index 9c1176e..6cf98f8 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -215,9 +215,8 @@ namespace Langulus::Entity /// Dump the entity's hierarchy in log void Thing::DumpHierarchy() const { - const auto tab = Logger::Section(Logger::Intent::Verbose, - Logger::White, Logger::Underline, *this - ); + const auto tab = Logger::Verbose( + Logger::White, Logger::Underline, *this, Logger::Tabs {}); if (mTraits) { const auto tab2 = Logger::Section(Logger::White, Logger::Underline, From 0cff4d88970e47d62dbd41cb5d4e54d2e7d196f1 Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Tue, 8 Oct 2024 12:50:32 +0300 Subject: [PATCH 13/34] Improving abstract file readers and writers --- include/Langulus/IO.hpp | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/include/Langulus/IO.hpp b/include/Langulus/IO.hpp index 5f74c49..f6f0843 100644 --- a/include/Langulus/IO.hpp +++ b/include/Langulus/IO.hpp @@ -68,31 +68,51 @@ namespace Langulus::A template NOD() T ReadAs() const; + + /// /// Abstract file reader stream struct Reader { protected: - File* mFile; - Offset mProgress {}; + Ref mFile; + Offset mProgress {}; public: Reader() = delete; - Reader(File* f) : mFile {f} {} + virtual ~Reader() {}; + + Reader(File* f) + : mFile {f} {} + + Reader(Langulus::Abandoned&& rhs) + : mFile {rhs.Nest(rhs->mFile)} + , mProgress {rhs->mProgress} {} virtual auto Read(Many&) -> Offset = 0; auto GetFile() const noexcept { return mFile; } }; + + /// /// Abstract file writer stream struct Writer { protected: - File* mFile; - Offset mProgress {}; - bool mAppend = false; + Ref mFile; + Offset mProgress {}; + bool mAppend = false; public: Writer() = delete; - Writer(File* f, bool append) : mFile {f}, mAppend {append} {} + virtual ~Writer() {}; + + Writer(File* f, bool append) + : mFile {f} + , mAppend {append} {} + + Writer(Langulus::Abandoned&& rhs) + : mFile {rhs.Nest(rhs->mFile)} + , mProgress {rhs->mProgress} + , mAppend {rhs->mAppend} {} virtual auto Write(const Many&) -> Offset = 0; From 3e19f1b3fdbd6d809248bf1d5487d2f5b859c72f Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Tue, 8 Oct 2024 13:34:55 +0300 Subject: [PATCH 14/34] Cleaning up A::File::Reader and Writer --- include/Langulus/IO.hpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/include/Langulus/IO.hpp b/include/Langulus/IO.hpp index f6f0843..9facc4b 100644 --- a/include/Langulus/IO.hpp +++ b/include/Langulus/IO.hpp @@ -81,11 +81,7 @@ namespace Langulus::A virtual ~Reader() {}; Reader(File* f) - : mFile {f} {} - - Reader(Langulus::Abandoned&& rhs) - : mFile {rhs.Nest(rhs->mFile)} - , mProgress {rhs->mProgress} {} + : mFile {f} {} virtual auto Read(Many&) -> Offset = 0; @@ -106,13 +102,8 @@ namespace Langulus::A virtual ~Writer() {}; Writer(File* f, bool append) - : mFile {f} - , mAppend {append} {} - - Writer(Langulus::Abandoned&& rhs) - : mFile {rhs.Nest(rhs->mFile)} - , mProgress {rhs->mProgress} - , mAppend {rhs->mAppend} {} + : mFile {f} + , mAppend{append} {} virtual auto Write(const Many&) -> Offset = 0; From e7660b3374f40c74d85716426c2dafc5ea9bc031 Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Tue, 8 Oct 2024 14:41:28 +0300 Subject: [PATCH 15/34] Bit of code cleanup --- include/Langulus/IO.hpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/include/Langulus/IO.hpp b/include/Langulus/IO.hpp index 9facc4b..2541009 100644 --- a/include/Langulus/IO.hpp +++ b/include/Langulus/IO.hpp @@ -74,18 +74,20 @@ namespace Langulus::A struct Reader { protected: Ref mFile; - Offset mProgress {}; + Offset mProgress = 0; public: Reader() = delete; - virtual ~Reader() {}; + virtual ~Reader() {} Reader(File* f) : mFile {f} {} virtual auto Read(Many&) -> Offset = 0; - auto GetFile() const noexcept { return mFile; } + auto GetFile() const noexcept -> const Ref& { + return mFile; + } }; @@ -94,12 +96,12 @@ namespace Langulus::A struct Writer { protected: Ref mFile; - Offset mProgress {}; + Offset mProgress = 0; bool mAppend = false; public: Writer() = delete; - virtual ~Writer() {}; + virtual ~Writer() {} Writer(File* f, bool append) : mFile {f} @@ -107,7 +109,9 @@ namespace Langulus::A virtual auto Write(const Many&) -> Offset = 0; - auto GetFile() const noexcept { return mFile; } + auto GetFile() const noexcept -> const Ref& { + return mFile; + } }; NOD() virtual auto NewReader() const -> Ref = 0; From 8d331cbf8f02266fca9c222abb6afac6daf2c07e Mon Sep 17 00:00:00 2001 From: Epixu Date: Wed, 9 Oct 2024 19:28:19 +0300 Subject: [PATCH 16/34] Maintenance --- source/Hierarchy-Seek.inl | 202 ++++------------------------------ source/Hierarchy.hpp | 146 +++++++++---------------- source/Thing-Seek.inl | 225 ++++++++++++++++---------------------- source/Thing-Traits.cpp | 27 ++--- source/Thing.cpp | 80 +++++++------- source/Thing.hpp | 152 ++++++++++++------------- source/Thing.inl | 6 +- source/Unit-Seek.inl | 43 +------- source/Unit.cpp | 25 +++-- source/Unit.hpp | 51 ++++----- 10 files changed, 335 insertions(+), 622 deletions(-) diff --git a/source/Hierarchy-Seek.inl b/source/Hierarchy-Seek.inl index 319685a..dfc42f0 100644 --- a/source/Hierarchy-Seek.inl +++ b/source/Hierarchy-Seek.inl @@ -18,29 +18,6 @@ namespace Langulus::Entity { - /// Find a unit by type and optional offset - /// @tparam SEEK - the direction to seek in - /// @param type - the type of unit to search for - /// @param offset - the match to return - /// @return a pointer to the found unit, or nullptr if not found - TEMPLATE() template LANGULUS(INLINED) - const A::Unit* TME()::SeekUnit(DMeta type, Index offset) const { - return const_cast(static_cast(this)) - ->template SeekUnit(type, offset); - } - - TEMPLATE() template LANGULUS(INLINED) - Decay* TME()::SeekUnit(Index offset) { - return dynamic_cast*>(static_cast(this) - ->template SeekUnit(MetaDataOf>(), offset)); - } - - TEMPLATE() template LANGULUS(INLINED) - const Decay* TME()::SeekUnit(Index offset) const { - return const_cast(this) - ->template SeekUnit(offset); - } - /// Find a unit by type and optional offset, but search first in an /// auxiliary descriptor /// @tparam SEEK - the direction to seek in @@ -49,19 +26,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - const A::Unit* TME()::SeekUnitAux(const Neat& aux, DMeta type, Index offset) const { + auto TME()::SeekUnitAux(const Many& aux, DMeta type, Index offset) const -> const A::Unit* { return const_cast(static_cast(this)) ->template SeekUnitAux(aux, type, offset); } TEMPLATE() template LANGULUS(INLINED) - Decay* TME()::SeekUnitAux(const Neat& aux, Index offset) { + auto TME()::SeekUnitAux(const Many& aux, Index offset) -> Decay* { return dynamic_cast*>(static_cast(this) ->template SeekUnitAux(aux, MetaDataOf>(), offset)); } TEMPLATE() template LANGULUS(INLINED) - const Decay* TME()::SeekUnitAux(const Neat& aux, Index offset) const { + auto TME()::SeekUnitAux(const Many& aux, Index offset) const -> const Decay* { return const_cast(this) ->template SeekUnitAux(aux, offset); } @@ -73,19 +50,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - const A::Unit* TME()::SeekUnitExt(DMeta type, const Neat& ext, Index offset) const { + auto TME()::SeekUnitExt(DMeta type, const Many& ext, Index offset) const -> const A::Unit* { return const_cast(static_cast(this)) ->template SeekUnitExt(type, ext, offset); } TEMPLATE() template LANGULUS(INLINED) - Decay* TME()::SeekUnitExt(const Neat& ext, Index offset) { + auto TME()::SeekUnitExt(const Many& ext, Index offset) -> Decay* { return dynamic_cast*>(static_cast(this) ->template SeekUnitExt(MetaDataOf>(), ext, offset)); } TEMPLATE() template LANGULUS(INLINED) - const Decay* TME()::SeekUnitExt(const Neat& ext, Index offset) const { + auto TME()::SeekUnitExt(const Many& ext, Index offset) const -> const Decay* { return const_cast(this) ->template SeekUnitExt(ext, offset); } @@ -99,45 +76,22 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - const A::Unit* TME()::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) const { + auto TME()::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) const -> const A::Unit* { return const_cast(static_cast(this)) ->template SeekUnitAuxExt(type, aux, ext, offset); } TEMPLATE() template LANGULUS(INLINED) - Decay* TME()::SeekUnitAuxExt(const Neat& aux, const Neat& ext, Index offset) { + auto TME()::SeekUnitAuxExt(const Many& aux, const Many& ext, Index offset) -> Decay* { return dynamic_cast*>(static_cast(this) ->template SeekUnitAuxExt(MetaDataOf>(), aux, ext, offset)); } TEMPLATE() template LANGULUS(INLINED) - const Decay* TME()::SeekUnitAuxExt(const Neat& aux, const Neat& ext, Index offset) const { + auto TME()::SeekUnitAuxExt(const Many& aux, const Many& ext, Index offset) const -> const Decay* { return const_cast(this) ->template SeekUnitAuxExt(aux, ext, offset); } - - /// Find a trait by type and optional offset - /// @tparam SEEK - the direction to seek in - /// @param type - the type of unit to search for - /// @param offset - the match to return - /// @return a pointer to the found unit, or nullptr if not found - TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTrait(TMeta type, Index offset) const { - return const_cast(static_cast(this)) - ->template SeekTrait(type, offset); - } - - TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTrait(Index offset) { - return static_cast(this) - ->template SeekTrait(MetaTraitOf(), offset); - } - - TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTrait(Index offset) const { - return const_cast(this) - ->template SeekTrait(offset); - } /// Find a trait by type and specific properties and optional offset /// @tparam SEEK - the direction to seek in @@ -146,19 +100,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTraitAux(const Neat& aux, TMeta type, Index offset) const { + auto TME()::SeekTraitAux(const Many& aux, TMeta type, Index offset) const -> Trait { return const_cast(static_cast(this)) ->template SeekTraitAux(aux, type, offset); } TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTraitAux(const Neat& aux, Index offset) { + auto TME()::SeekTraitAux(const Many& aux, Index offset) -> Trait { return static_cast(this) ->template SeekTraitAux(aux, MetaTraitOf(), offset); } TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTraitAux(const Neat& aux, Index offset) const { + auto TME()::SeekTraitAux(const Many& aux, Index offset) const -> Trait { return const_cast(this) ->template SeekTraitAux(aux, offset); } @@ -166,13 +120,7 @@ namespace Langulus::Entity TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValue(CT::NotTagged auto& output, Index offset) const { - return static_cast(this) - ->template SeekValue(MetaTraitOf(), output, offset); - } - - TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValueAux(const Neat& aux, CT::NotTagged auto& output, Index offset) const { + bool TME()::SeekValueAux(const Many& aux, CT::NotTagged auto& output, Index offset) const { return static_cast(this) ->template SeekValueAux(MetaTraitOf(), aux, output, offset); } @@ -180,17 +128,7 @@ namespace Langulus::Entity TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValue(CT::Tagged auto& output, Index offset) const { - using T = Deref; - auto lambda = [&]() { - return static_cast(this)->template - SeekValue(MetaTraitOf(), output.mData, offset); - }; - return T::Tags::ForEachOr(lambda); - } - - TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValueAux(const Neat& aux, CT::Tagged auto& output, Index offset) const { + bool TME()::SeekValueAux(const Many& aux, CT::Tagged auto& output, Index offset) const { using T = Deref; auto lambda = [&]() { return static_cast(this)->template @@ -207,55 +145,25 @@ namespace Langulus::Entity /// Available only when managed reflection is enabled /// TEMPLATE() template LANGULUS(INLINED) - A::Unit* TME()::SeekUnit(const Token& dataToken, Index offset) { - return static_cast(this) - ->template SeekUnit(RTTI::GetMetaData(dataToken), offset); - } - - TEMPLATE() template LANGULUS(INLINED) - const A::Unit* TME()::SeekUnit(const Token& dataToken, Index offset) const { - return static_cast(this) - ->template SeekUnit(RTTI::GetMetaData(dataToken), offset); - } - - TEMPLATE() template LANGULUS(INLINED) - A::Unit* TME()::SeekUnitAux(const Neat& aux, const Token& dataToken, Index offset) { + auto TME()::SeekUnitAux(const Many& aux, const Token& dataToken, Index offset) -> A::Unit* { return static_cast(this) ->template SeekUnitAux(aux, RTTI::GetMetaData(dataToken), offset); } TEMPLATE() template LANGULUS(INLINED) - const A::Unit* TME()::SeekUnitAux(const Neat& aux, const Token& dataToken, Index offset) const { + auto TME()::SeekUnitAux(const Many& aux, const Token& dataToken, Index offset) const -> const A::Unit* { return static_cast(this) ->template SeekUnitAux(aux, RTTI::GetMetaData(dataToken), offset); } TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTrait(const Token& traitToken, Index offset) { - return static_cast(this) - ->template SeekTrait(RTTI::GetMetaTrait(traitToken), offset); - } - - TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTrait(const Token& traitToken, Index offset) const { - return static_cast(this) - ->template SeekTrait(RTTI::GetMetaTrait(traitToken), offset); - } - - TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTraitAux(const Neat& aux, const Token& traitToken, Index offset) const { + auto TME()::SeekTraitAux(const Many& aux, const Token& traitToken, Index offset) const -> Trait { return static_cast(this) ->template SeekTraitAux(aux, RTTI::GetMetaTrait(traitToken), offset); } - - TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValue(const Token& traitToken, CT::Data auto& output, Index offset) const { - return static_cast(this) - ->template SeekValue(RTTI::GetMetaTrait(traitToken), output, offset); - } TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValueAux(const Token& traitToken, const Neat& aux, CT::Data auto& output, Index offset) const { + bool TME()::SeekValueAux(const Token& traitToken, const Many& aux, CT::Data auto& output, Index offset) const { return static_cast(this) ->template SeekValueAux(RTTI::GetMetaTrait(traitToken), aux, output, offset); } @@ -270,22 +178,6 @@ namespace Langulus::Entity namespace Langulus::Entity { - /// Find a specific unit, searching into the hierarchy - /// @tparam SEEK - where in the hierarchy are we seeking in? - /// @param meta - the unit to seek for - /// @param offset - which of the matches to return - /// @return the found unit, or nullptr if no such unit was found - template LANGULUS(INLINED) - A::Unit* Hierarchy::SeekUnit(DMeta meta, Index offset) { - for (auto owner : *this) { - A::Unit* result = owner->template SeekUnit(meta, offset); - if (result) - return result; - } - - return nullptr; - } - /// Find a unit by type and index from the hierarchy /// Scan a locally provided descriptor first /// @tparam SEEK - where to seek for the unit @@ -294,7 +186,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - A::Unit* Hierarchy::SeekUnitAux(const Neat& aux, DMeta meta, Index offset) { + auto Hierarchy::SeekUnitAux(const Many& aux, DMeta meta, Index offset) -> A::Unit* { const A::Unit* result {}; // Scan descriptor even if hierarchy is empty @@ -355,7 +247,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - A::Unit* Hierarchy::SeekUnitExt(DMeta type, const Neat& ext, Index offset) { + auto Hierarchy::SeekUnitExt(DMeta type, const Many& ext, Index offset) -> A::Unit* { for (auto owner : *this) { A::Unit* result = owner->template SeekUnitExt(type, ext, offset); if (result) @@ -374,7 +266,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return a pointer to the found unit, or nullptr if not found template LANGULUS(INLINED) - A::Unit* Hierarchy::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) { + auto Hierarchy::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) -> A::Unit* { // Scan descriptor even if hierarchy is empty A::Unit* result {}; aux.ForEachDeep([&](const A::Unit* u) { @@ -400,22 +292,6 @@ namespace Langulus::Entity return SeekUnitExt(type, ext, offset); } - /// Find a trait by type (and index), searching into the hierarchy - /// @tparam SEEK - direction to search at - /// @param meta - the trait to search for - /// @param offset - the offset to apply - /// @return the trait, which is not empty, if trait was found - template LANGULUS(INLINED) - Trait Hierarchy::SeekTrait(TMeta meta, Index offset) { - for (auto owner : *this) { - auto result = owner->template SeekTrait(meta, offset); - if (result) - return result; - } - - return {}; - } - /// Find a trait, searching into the hierarchy (const) /// @tparam SEEK - direction to search at /// @param aux - descriptor to search through @@ -423,7 +299,7 @@ namespace Langulus::Entity /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - Trait Hierarchy::SeekTraitAux(const Neat& aux, TMeta meta, Index offset) { + auto Hierarchy::SeekTraitAux(const Many& aux, TMeta meta, Index offset) -> Trait { // Scan descriptor Trait result; aux.ForEachDeep([&](const Trait& trait) { @@ -447,37 +323,7 @@ namespace Langulus::Entity // Let's delve into the hierarchy return SeekTrait(meta, offset); } - - /// Find a trait by type (and index) from the hierarchy, and attempt - /// converting it to a desired output type - /// Supports pinnable outputs - /// @tparam SEEK - direction to search at - /// @param meta - the trait type to search for - /// @param output - [out] the output - /// @param offset - the number of the matching trait to use - /// @return true if output was rewritten - template LANGULUS(INLINED) - bool Hierarchy::SeekValue(TMeta meta, CT::Data auto& output, Index offset) const { - using D = Deref; - - if constexpr (CT::Pinnable) { - // Never touch pinned values - if (output.mLocked) - return false; - } - - // Let's delve into the hierarchy - for (auto owner : *this) { - if (owner->template SeekValue(meta, output, offset)) { - // Value was found - return true; - } - } - - // If reached, nothing was found - return false; - } - + /// Find a trait by type (and index) from the hierarchy, and attempt /// converting it to a desired output type. Scan the aux container first /// Supports pinnable outputs, and pinnables will be pinned if trait was @@ -489,7 +335,7 @@ namespace Langulus::Entity /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - bool Hierarchy::SeekValueAux(TMeta meta, const Neat& aux, CT::Data auto& output, Index offset) const { + bool Hierarchy::SeekValueAux(TMeta meta, const Many& aux, CT::Data auto& output, Index offset) const { using D = Deref; if constexpr (CT::Pinnable) { diff --git a/source/Hierarchy.hpp b/source/Hierarchy.hpp index 00eae87..9895de8 100644 --- a/source/Hierarchy.hpp +++ b/source/Hierarchy.hpp @@ -34,31 +34,27 @@ namespace Langulus::Entity /// /// Can't use virtuals, because we want these to be template functions, /// so that we retain the most of the static optimizations + /// TODO generalize these when deduce-this has been implemented well /// - /*template - NOD() Unit* SeekUnit(DMeta, Index = IndexFirst) = delete; + /* template - NOD() Unit* SeekUnitAux(const Neat&, DMeta, Index = IndexFirst) = delete; + NOD() Unit* SeekUnitAux(const Many&, DMeta, Index = IndexFirst) = delete; template - NOD() Unit* SeekUnitExt(DMeta, const Neat&, Index = IndexFirst) = delete; + NOD() Unit* SeekUnitExt(DMeta, const Many&, Index = IndexFirst) = delete; template - NOD() Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = IndexFirst) = delete; + NOD() Unit* SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = IndexFirst) = delete; template - NOD() Trait SeekTrait(TMeta, Index = IndexFirst) = delete; - template - NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = IndexFirst) = delete; + NOD() Trait SeekTraitAux(const Many&, TMeta, Index = IndexFirst) = delete; template - bool SeekValue(TMeta, CT::Data auto&, Index = IndexFirst) const = delete; - template - bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = IndexFirst) const = delete; + bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = IndexFirst) const = delete; template NOD() TMany GatherUnits(DMeta) = delete; template - NOD() TMany GatherUnitsExt(DMeta, const Neat&) = delete; + NOD() TMany GatherUnitsExt(DMeta, const Many&) = delete; template NOD() TraitList GatherTraits(TMeta) = delete; @@ -71,82 +67,62 @@ namespace Langulus::Entity /// The rest of these functions are defined for every SeekInterface /// They all use static_cast(this) as execution context for the /// above functions, which should be defined in THIS + /// TODO remove these when deduce-this has been implemented well /// template - NOD() const A::Unit* SeekUnit(DMeta, Index = 0) const; + NOD() auto SeekUnitAux(const Many&, DMeta, Index = 0) const -> const A::Unit*; template - NOD() Decay* SeekUnit(Index = 0); + NOD() auto SeekUnitAux(const Many&, Index = 0) -> Decay*; template - NOD() const Decay* SeekUnit(Index = 0) const; + NOD() auto SeekUnitAux(const Many&, Index = 0) const -> const Decay*; template - NOD() const A::Unit* SeekUnitAux(const Neat&, DMeta, Index = 0) const; + NOD() auto SeekUnitExt(DMeta, const Many&, Index = 0) const -> const A::Unit*; template - NOD() Decay* SeekUnitAux(const Neat&, Index = 0); + NOD() auto SeekUnitExt(const Many&, Index = 0) -> Decay*; template - NOD() const Decay* SeekUnitAux(const Neat&, Index = 0) const; + NOD() auto SeekUnitExt(const Many&, Index = 0) const -> const Decay*; template - NOD() const A::Unit* SeekUnitExt(DMeta, const Neat&, Index = 0) const; + NOD() auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) const -> const A::Unit*; template - NOD() Decay* SeekUnitExt(const Neat&, Index = 0); + NOD() auto SeekUnitAuxExt(const Many&, const Many&, Index = 0) -> Decay*; template - NOD() const Decay* SeekUnitExt(const Neat&, Index = 0) const; + NOD() auto SeekUnitAuxExt(const Many&, const Many&, Index = 0) const -> const Decay*; template - NOD() const A::Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0) const; - template - NOD() Decay* SeekUnitAuxExt(const Neat&, const Neat&, Index = 0); - template - NOD() const Decay* SeekUnitAuxExt(const Neat&, const Neat&, Index = 0) const; - - template - NOD() Trait SeekTrait(TMeta, Index = 0) const; + NOD() auto SeekTraitAux(const Many&, TMeta, Index = 0) const -> Trait; template - NOD() Trait SeekTrait(Index = 0); + NOD() auto SeekTraitAux(const Many&, Index = 0) -> Trait; template - NOD() Trait SeekTrait(Index = 0) const; + NOD() auto SeekTraitAux(const Many&, Index = 0) const -> Trait; - template - NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = 0) const; template - NOD() Trait SeekTraitAux(const Neat&, Index = 0); - template - NOD() Trait SeekTraitAux(const Neat&, Index = 0) const; - - - template - bool SeekValue(CT::NotTagged auto&, Index = IndexFirst) const; - template - bool SeekValueAux(const Neat&, CT::NotTagged auto&, Index = 0) const; - + bool SeekValueAux(const Many&, CT::NotTagged auto&, Index = 0) const; template - bool SeekValue(CT::Tagged auto&, Index = IndexFirst) const; - template - bool SeekValueAux(const Neat&, CT::Tagged auto&, Index = 0) const; - + bool SeekValueAux(const Many&, CT::Tagged auto&, Index = 0) const; template - NOD() TMany GatherUnits(DMeta) const; + NOD() auto GatherUnits(DMeta) const -> TMany; template - NOD() TMany GatherUnits(); + NOD() auto GatherUnits() -> TMany; template - NOD() TMany GatherUnits() const; + NOD() auto GatherUnits() const -> TMany; template - NOD() TMany GatherUnitsExt(DMeta, const Neat&) const; + NOD() auto GatherUnitsExt(DMeta, const Many&) const -> TMany; template - NOD() TMany GatherUnitsExt(const Neat&); + NOD() auto GatherUnitsExt(const Many&) -> TMany; template - NOD() TMany GatherUnitsExt(const Neat&) const; + NOD() auto GatherUnitsExt(const Many&) const -> TMany; template - NOD() TraitList GatherTraits(TMeta) const; + NOD() auto GatherTraits(TMeta) const -> TraitList; template - NOD() TraitList GatherTraits(); + NOD() auto GatherTraits() -> TraitList; template - NOD() TraitList GatherTraits() const; + NOD() auto GatherTraits() const -> TraitList; #if LANGULUS_FEATURE(MANAGED_REFLECTION) @@ -155,40 +131,27 @@ namespace Langulus::Entity /// Available only when managed reflection is enabled /// template - NOD() A::Unit* SeekUnit(const Token&, Index = 0); + NOD() auto SeekUnitAux(const Many&, const Token&, Index = 0) -> A::Unit*; template - NOD() const A::Unit* SeekUnit(const Token&, Index = 0) const; + NOD() auto SeekUnitAux(const Many&, const Token&, Index = 0) const -> const A::Unit*; template - NOD() A::Unit* SeekUnitAux(const Neat&, const Token&, Index = 0); - template - NOD() const A::Unit* SeekUnitAux(const Neat&, const Token&, Index = 0) const; - + NOD() auto SeekTraitAux(const Many&, const Token&, Index = 0) -> Trait; template - NOD() Trait SeekTrait(const Token&, Index = 0); - template - NOD() Trait SeekTrait(const Token&, Index = 0) const; + NOD() auto SeekTraitAux(const Many&, const Token&, Index = 0) const -> Trait; template - NOD() Trait SeekTraitAux(const Neat&, const Token&, Index = 0); - template - NOD() Trait SeekTraitAux(const Neat&, const Token&, Index = 0) const; + bool SeekValueAux(const Token&, const Many&, CT::Data auto&, Index = 0) const; template - bool SeekValue(const Token&, CT::Data auto&, Index = 0) const; + NOD() auto GatherUnits(const Token&) -> TMany; template - bool SeekValueAux(const Token&, const Neat&, CT::Data auto&, Index = 0) const; - - - template - NOD() TMany GatherUnits(const Token&); - template - NOD() TMany GatherUnits(const Token&) const; + NOD() auto GatherUnits(const Token&) const -> TMany; template - NOD() TraitList GatherTraits(const Token&); + NOD() auto GatherTraits(const Token&) -> TraitList; template - NOD() TraitList GatherTraits(const Token&) const; + NOD() auto GatherTraits(const Token&) const -> TraitList; #endif }; @@ -210,33 +173,24 @@ namespace Langulus::Entity /// /// Seek /// - using SeekInterface::SeekUnit; using SeekInterface::SeekUnitAux; using SeekInterface::SeekUnitExt; using SeekInterface::SeekUnitAuxExt; - using SeekInterface::SeekTrait; using SeekInterface::SeekTraitAux; - using SeekInterface::SeekValue; using SeekInterface::SeekValueAux; template - NOD() A::Unit* SeekUnit(DMeta, Index = 0); + NOD() auto SeekUnitAux(const Many&, DMeta, Index = 0) -> A::Unit*; template - NOD() A::Unit* SeekUnitAux(const Neat&, DMeta, Index = 0); + NOD() auto SeekUnitExt(DMeta, const Many&, Index = 0) -> A::Unit*; template - NOD() A::Unit* SeekUnitExt(DMeta, const Neat&, Index = 0); - template - NOD() A::Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0); + NOD() auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) -> A::Unit*; template - NOD() Trait SeekTrait(TMeta, Index = 0); - template - NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = 0); + NOD() auto SeekTraitAux(const Many&, TMeta, Index = 0) -> Trait; template - bool SeekValue(TMeta, CT::Data auto&, Index = 0) const; - template - bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = 0) const; + bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = 0) const; /// /// Gather @@ -246,15 +200,15 @@ namespace Langulus::Entity using SeekInterface::GatherTraits; template - NOD() TMany GatherUnitsExt(DMeta, const Neat&); + NOD() auto GatherUnitsExt(DMeta, const Many&) -> TMany; template - NOD() TMany GatherUnits(DMeta); + NOD() auto GatherUnits(DMeta) -> TMany; template - NOD() TraitList GatherTraits(TMeta); + NOD() auto GatherTraits(TMeta) -> TraitList; template - NOD() TMany GatherValues() const; + NOD() auto GatherValues() const -> TMany; }; } // namespace Langulus::Entity diff --git a/source/Thing-Seek.inl b/source/Thing-Seek.inl index b155c76..1f464dd 100644 --- a/source/Thing-Seek.inl +++ b/source/Thing-Seek.inl @@ -23,44 +23,6 @@ namespace Langulus::Entity { - /// Find a specific unit, searching into the hierarchy - /// @tparam SEEK - where in the hierarchy are we seeking in? - /// @param meta - the unit to seek for - /// @param offset - which of the matches to return - /// @return the found unit, or nullptr if no such unit was found - template - A::Unit* Thing::SeekUnit(DMeta meta, Index offset) { - A::Unit* result = nullptr; - if constexpr (SEEK & Seek::Here) { - // Seek here if requested - result = GetUnitMeta(meta, offset); - if (result) - return result; - } - - if constexpr (SEEK & Seek::Above) { - // Seek in parents up to root, if requested - if (mOwner) { - result = mOwner->template - SeekUnit(meta, offset); - if (result) - return result; - } - } - - if constexpr (SEEK & Seek::Below) { - // Seek children, if requested - for (auto child : mChildren) { - result = child->template - SeekUnit(meta, offset); - if (result) - return result; - } - } - - return nullptr; - } - /// Find a unit by type and index from the hierarchy /// Scan an auxiliary descriptor first /// @tparam SEEK - where to seek for the unit @@ -69,7 +31,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - A::Unit* Thing::SeekUnitAux(const Neat& aux, DMeta meta, Index offset) { + A::Unit* Thing::SeekUnitAux(const Many& aux, DMeta meta, Index offset) { A::Unit* result {}; aux.ForEachDeep([&](const A::Unit* unit) { if (unit->CastsTo(meta)) { @@ -90,7 +52,34 @@ namespace Langulus::Entity // If reached, then no unit was found in the descriptor // Let's delve into the hierarchy - return SeekUnit(meta, offset); + if constexpr (SEEK & Seek::Here) { + // Seek here if requested + result = GetUnitMeta(meta, offset); + if (result) + return result; + } + + if constexpr (SEEK & Seek::Above) { + // Seek in parents up to root, if requested + if (mOwner) { + result = mOwner->template + SeekUnitAux({}, meta, offset); + if (result) + return result; + } + } + + if constexpr (SEEK & Seek::Below) { + // Seek children, if requested + for (auto child : mChildren) { + result = child->template + SeekUnitAux({}, meta, offset); + if (result) + return result; + } + } + + return nullptr; } /// Find a unit by construct and index from the hierarchy @@ -99,7 +88,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - A::Unit* Thing::SeekUnitExt(DMeta type, const Neat& ext, Index offset) { + A::Unit* Thing::SeekUnitExt(DMeta type, const Many& ext, Index offset) { A::Unit* result = nullptr; if constexpr (SEEK & Seek::Here) { // Seek here if requested @@ -139,7 +128,7 @@ namespace Langulus::Entity /// @param offset - the Nth match to return /// @return a pointer to the found unit, or nullptr if not found template LANGULUS(INLINED) - A::Unit* Thing::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) { + A::Unit* Thing::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) { // Scan descriptor even if hierarchy is empty A::Unit* result {}; aux.ForEachDeep([&](const A::Unit* unit) { @@ -164,43 +153,6 @@ namespace Langulus::Entity return SeekUnitExt(type, ext, offset); } - /// Find a trait by type (and index), searching into the hierarchy - /// @tparam SEEK - direction to search at - /// @param meta - the trait to search for - /// @param offset - the offset to apply - /// @return the trait, which is not empty, if trait was found - template - Trait Thing::SeekTrait(TMeta meta, Index offset) { - if constexpr (SEEK & Seek::Here) { - // Seek here if requested - auto output = GetTrait(meta, offset); - if (output) - return Abandon(output); - } - - if constexpr (SEEK & Seek::Above) { - // Seek in parents up to root, if requested - if (mOwner) { - auto output = mOwner->template - SeekTrait(meta, offset); - if (output) - return Abandon(output); - } - } - - if constexpr (SEEK & Seek::Below) { - // Seek children, if requested - for (auto child : mChildren) { - auto output = child->template - SeekTrait(meta, offset); - if (output) - return Abandon(output); - } - } - - return {}; - } - /// Find a trait, searching into the hierarchy (const) /// Scan an auxiliary descriptor first /// @tparam SEEK - direction to search at @@ -209,7 +161,7 @@ namespace Langulus::Entity /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - Trait Thing::SeekTraitAux(const Neat& aux, TMeta meta, Index offset) { + Trait Thing::SeekTraitAux(const Many& aux, TMeta meta, Index offset) { // Scan descriptor Trait result; aux.ForEachDeep([&](const Trait& trait) { @@ -228,72 +180,36 @@ namespace Langulus::Entity // If reached, then no trait was found in the descriptor // Let's delve into the hierarchy - return SeekTrait(meta, offset); - } - - /// Find a trait by type (and index) from the hierarchy, and attempt - /// converting it to a desired output type - /// Supports pinnable outputs - /// @tparam SEEK - direction to search at - /// @param meta - the trait type to search for - /// @param output - [out] the output - /// @param offset - the number of the matching trait to use - /// @return true if output was rewritten - template - bool Thing::SeekValue(TMeta meta, CT::Data auto& output, Index offset) const { - using D = Deref; - - if constexpr (CT::Pinnable) { - // Never touch pinned values - if (output.mLocked) - return false; - } - if constexpr (SEEK & Seek::Here) { // Seek here if requested - auto temp = GetTrait(meta, offset); - try { - if (CT::Pinnable and temp.Is>()) - output = temp.As>(); - else if (not CT::Pinnable and temp.Is()) - output = temp.As(); - else if constexpr (CT::DescriptorMakable) - output = D {Describe(static_cast(temp))}; - else if constexpr (CT::Pinnable) - output = temp.template AsCast>(); - else - output = temp.template AsCast(); - - /*if constexpr (CT::Pinnable) - output = temp.template AsCast>(); - else - output = temp.template AsCast();*/ - return true; - } - catch (...) { } + auto output = GetTrait(meta, offset); + if (output) + return Abandon(output); } if constexpr (SEEK & Seek::Above) { // Seek in parents up to root, if requested if (mOwner) { - if (mOwner->template - SeekValue(meta, output, offset)) - return true; + auto output = mOwner->template + SeekTraitAux({}, meta, offset); + if (output) + return Abandon(output); } } if constexpr (SEEK & Seek::Below) { // Seek children, if requested for (auto child : mChildren) { - if (child->template - SeekValue(meta, output, offset)) - return true; + auto output = child->template + SeekTraitAux({}, meta, offset); + if (output) + return Abandon(output); } } - return false; + return {}; } - + /// Find a value (regardless of trait) from the hierarchy, and attempt /// converting it to a desired output type. Scan the aux container first /// Supports pinnable outputs, and pinnables will be pinned if trait was @@ -305,7 +221,7 @@ namespace Langulus::Entity /// @return true if value has been found and rewritten template LANGULUS(INLINED) bool Thing::SeekValueAux( - TMeta meta, const Neat& aux, CT::Data auto& output, Index offset + TMeta meta, const Many& aux, CT::Data auto& output, Index offset ) const { using D = Deref; @@ -330,7 +246,7 @@ namespace Langulus::Entity // Didn't throw, but we're done only if offset matches done = offset == 0; --offset; - return not done; + return done ? Loop::Break : Loop::Continue; } catch (...) {} } @@ -350,7 +266,7 @@ namespace Langulus::Entity // Didn't throw, but we're done only if offset matches done = offset == 0; --offset; - return not done; + return done ? Loop::Break : Loop::Continue; } catch(...) { } @@ -370,7 +286,50 @@ namespace Langulus::Entity // If reached, then no data was found in the descriptor // Let's delve into the hierarchy - return SeekValue(meta, output, offset); + if constexpr (CT::Pinnable) { + // Never touch pinned values + if (output.mLocked) + return false; + } + + if constexpr (SEEK & Seek::Here) { + // Seek here if requested + auto temp = GetTrait(meta, offset); + try { + if (CT::Pinnable and temp.Is>()) + output = temp.As>(); + else if (not CT::Pinnable and temp.Is()) + output = temp.As(); + else if constexpr (CT::DescriptorMakable) + output = D {Describe(static_cast(temp))}; + else if constexpr (CT::Pinnable) + output = temp.template AsCast>(); + else + output = temp.template AsCast(); + return true; + } + catch (...) { } + } + + if constexpr (SEEK & Seek::Above) { + // Seek in parents up to root, if requested + if (mOwner) { + if (mOwner->template + SeekValueAux(meta, {}, output, offset)) + return true; + } + } + + if constexpr (SEEK & Seek::Below) { + // Seek children, if requested + for (auto child : mChildren) { + if (child->template + SeekValueAux(meta, {}, output, offset)) + return true; + } + } + + return false; } } // namespace Langulus::Entity diff --git a/source/Thing-Traits.cpp b/source/Thing-Traits.cpp index 2b5db03..f8241ae 100644 --- a/source/Thing-Traits.cpp +++ b/source/Thing-Traits.cpp @@ -29,7 +29,7 @@ namespace Langulus::Entity /// @param trait - trait id /// @param offset - offset of result to use /// @return a filled trait if fount, empty if not - Trait Thing::GetTrait(TMeta trait, Index offset) const { + auto Thing::GetTrait(TMeta trait, Index offset) const -> Trait { return GetTrait(Trait::FromMeta(trait, nullptr), offset); } @@ -37,7 +37,7 @@ namespace Langulus::Entity /// @param trait - trait id /// @param offset - offset of result to use /// @return a filled trait if fount, empty if not - Trait Thing::GetTrait(TMeta trait, Index offset) { + auto Thing::GetTrait(TMeta trait, Index offset) -> Trait { return GetTrait(Trait::FromMeta(trait, nullptr), offset); } @@ -45,7 +45,7 @@ namespace Langulus::Entity /// @param id - the trait to search for /// @param index - the index of the trait we seek /// @return a pointer to the trait, or nullptr if not found - Trait* Thing::GetLocalTrait(TMeta id, Index index) { + auto Thing::GetLocalTrait(TMeta id, Index index) -> Trait* { if (id) { // Search a typed trait const auto found = mTraits.FindIt(id); @@ -76,7 +76,7 @@ namespace Langulus::Entity /// @param id - the trait to search for /// @param offset - the index of the trait we seek /// @return a pointer to the trait, or nullptr if not found - const Trait* Thing::GetLocalTrait(TMeta id, Index offset) const { + auto Thing::GetLocalTrait(TMeta id, Index offset) const -> const Trait* { return const_cast(*this).GetLocalTrait(id, offset); } @@ -84,7 +84,7 @@ namespace Langulus::Entity /// @param id - trait to match /// @param index - offset of result to use /// @return a non-empty trait, if found - Trait Thing::GetTrait(const Trait& id, Index index) { + auto Thing::GetTrait(const Trait& id, Index index) -> Trait { if (id.GetTrait()) { // Handle some predefined traits here if (id.template IsTrait()) { @@ -124,14 +124,14 @@ namespace Langulus::Entity /// @param id - trait to match /// @param index - offset of result to use /// @return a non-empty trait, if found - Trait Thing::GetTrait(const Trait& id, Index index) const { + auto Thing::GetTrait(const Trait& id, Index index) const -> Trait { return const_cast(this)->GetTrait(id, index); } /// Add a new trait to the thing /// @param trait - trait to shallow copy /// @return the new trait instance - Trait* Thing::AddTrait(Trait trait) { + auto Thing::AddTrait(Trait trait) -> Trait* { const auto tmeta = trait.GetTrait(); auto found = mTraits.FindIt(tmeta); if (found) { @@ -148,7 +148,7 @@ namespace Langulus::Entity /// Remove a trait from the universal entity /// @param trait - type of trait to remove /// @return the number of removed traits - Count Thing::RemoveTrait(TMeta trait) { + auto Thing::RemoveTrait(TMeta trait) -> Count { const auto found = mTraits.FindIt(trait); if (found) { const auto removed = found.GetValue().GetCount(); @@ -164,7 +164,7 @@ namespace Langulus::Entity /// Remove an exact-matching trait from this entity /// @param trait - type and value to remove /// @return the number of removed traits - Count Thing::RemoveTrait(Trait trait) { + auto Thing::RemoveTrait(Trait trait) -> Count { const auto found = mTraits.FindIt(trait.GetTrait()); if (found) { const auto removed = found.GetValue().Remove(trait); @@ -181,7 +181,7 @@ namespace Langulus::Entity /// A fast check whether traits of the given type are inside this entity /// @param trait - type of trait to check /// @return the number of matching traits - Count Thing::HasTraits(TMeta trait) const { + auto Thing::HasTraits(TMeta trait) const -> Count { const auto found = mTraits.FindIt(trait); return found ? found.GetValue().GetCount() : 0; } @@ -189,7 +189,7 @@ namespace Langulus::Entity /// A fast check whether traits of the given type and value are inside /// @param trait - trait to search for /// @return the number of matching traits - Count Thing::HasTraits(const Trait& trait) const { + auto Thing::HasTraits(const Trait& trait) const -> Count { const auto found = mTraits.FindIt(trait.GetTrait()); if (not found) return 0; @@ -205,7 +205,7 @@ namespace Langulus::Entity /// Get traits /// @return the map of traits LANGULUS_API(ENTITY) - const TraitMap& Thing::GetTraits() const noexcept { + auto Thing::GetTraits() const noexcept -> const TraitMap& { return mTraits; } @@ -223,8 +223,9 @@ namespace Langulus::Entity /// It can reside in one of the units /// @return the name, or empty string if no such trait was found here Text Thing::GetName() const { + Many unused; Text name; - SeekValue(name); + SeekValueAux(name, unused); return name; } diff --git a/source/Thing.cpp b/source/Thing.cpp index 6cf98f8..e0b133b 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -54,9 +54,10 @@ namespace Langulus::Entity /// Construct as a child of another thing /// @param parent - the thing that owns this thing /// @param descriptor - instructions for creating the thing - Thing::Thing(Thing* parent, const Neat& descriptor) + Thing::Thing(Thing* parent, const Many& descriptor) : Resolvable {this} - , mOwner {parent} { + , mOwner {parent} + { if (parent) { parent->AddChild(this); mRuntime = parent->GetRuntime(); @@ -89,14 +90,15 @@ namespace Langulus::Entity /// because 'other' is removed from its children /// @param other - move that entity Thing::Thing(Thing&& other) noexcept - : Resolvable {this} - , mChildren {Move(other.mChildren)} - , mRuntime {Move(other.mRuntime)} - , mFlow {Move(other.mFlow)} + : Resolvable {this} + , mChildren {Move(other.mChildren)} + , mRuntime {Move(other.mRuntime)} + , mFlow {Move(other.mFlow)} , mUnitsAmbiguous {Move(other.mUnitsAmbiguous)} - , mUnitsList {Move(other.mUnitsList)} - , mTraits {Move(other.mTraits)} - , mRefreshRequired {true} { + , mUnitsList {Move(other.mUnitsList)} + , mTraits {Move(other.mTraits)} + , mRefreshRequired{true} + { // Remap children for (auto& child : mChildren) child->mOwner = this; @@ -118,14 +120,15 @@ namespace Langulus::Entity /// because 'other' is duplicated in its children /// @param other - clone that entity Thing::Thing(Abandoned&& other) - : Resolvable {this} - , mChildren {Abandon(other->mChildren)} - , mRuntime {Abandon(other->mRuntime)} - , mFlow {Abandon(other->mFlow)} + : Resolvable {this} + , mChildren {Abandon(other->mChildren)} + , mRuntime {Abandon(other->mRuntime)} + , mFlow {Abandon(other->mFlow)} , mUnitsAmbiguous {Abandon(other->mUnitsAmbiguous)} - , mUnitsList {Abandon(other->mUnitsList)} - , mTraits {Abandon(other->mTraits)} - , mRefreshRequired {true} { + , mUnitsList {Abandon(other->mUnitsList)} + , mTraits {Abandon(other->mTraits)} + , mRefreshRequired{true} + { // Remap children for (auto& child : mChildren) child->mOwner = this; @@ -147,9 +150,10 @@ namespace Langulus::Entity /// because 'other' is duplicated in its children /// @param other - clone that entity Thing::Thing(Cloned&& other) - : Resolvable {this} - , mChildren {Clone(other->mChildren)} - , mRefreshRequired {true} { + : Resolvable {this} + , mChildren {Clone(other->mChildren)} + , mRefreshRequired{true} + { TODO(); //TODO clone flow and runtime if pinned, recreate modules if new runtime, // recreate units and traits, then recreate children @@ -316,7 +320,7 @@ namespace Langulus::Entity /// @param id - the type of the unit /// @param index - the unit index to seek /// @return the unit if found, or nullptr if not - A::Unit* Thing::GetUnitMeta(DMeta id, Index index) { + auto Thing::GetUnitMeta(DMeta id, Index index) -> A::Unit* { if (id) { // Search a typed trait const auto found = mUnitsAmbiguous.FindIt(id); @@ -327,7 +331,7 @@ namespace Langulus::Entity return mUnitsList[index]; } - const A::Unit* Thing::GetUnitMeta(DMeta type, Index offset) const { + auto Thing::GetUnitMeta(DMeta type, Index offset) const -> const A::Unit* { return const_cast(this)->GetUnitMeta(type, offset); } @@ -338,7 +342,7 @@ namespace Langulus::Entity /// @param what - the desired properties of the unit /// @param index - the unit index to seek /// @return the unit if found, or nullptr if not - A::Unit* Thing::GetUnitExt(DMeta meta, const Neat& what, Index index) { + auto Thing::GetUnitExt(DMeta meta, const Many& what, Index index) -> A::Unit* { if (meta) { // Search a typed unit const auto found = mUnitsAmbiguous.FindIt(meta); @@ -371,7 +375,7 @@ namespace Langulus::Entity return nullptr; } - const A::Unit* Thing::GetUnitExt(DMeta meta, const Neat& what, Index index) const { + auto Thing::GetUnitExt(DMeta meta, const Many& what, Index index) const -> const A::Unit* { return const_cast(this)->GetUnitExt(meta, what, index); } @@ -380,31 +384,31 @@ namespace Langulus::Entity /// @param token - the type name of the unit /// @param offset - the unit index /// @return the unit if found, or nullptr if not - A::Unit* Thing::GetUnitMeta(const Token& token, Index offset) { + auto Thing::GetUnitMeta(const Token& token, Index offset) -> A::Unit* { return GetUnitMeta(RTTI::DisambiguateMeta(token), offset); } #endif /// Get the owner /// @return the owner - const Ref& Thing::GetOwner() const noexcept { + auto Thing::GetOwner() const noexcept -> const Ref& { return mOwner; } /// Get children hierarchy /// @return the hierarchy - const Hierarchy& Thing::GetChildren() const noexcept { + auto Thing::GetChildren() const noexcept -> const Hierarchy& { return mChildren; } /// Get a child by index /// @param id - the index to pick /// @return the child entity, or nullptr of none was found - Thing* Thing::GetChild(Index offset) { + auto Thing::GetChild(Index offset) -> Thing* { return mChildren[offset]; } - const Thing* Thing::GetChild(Index offset) const { + auto Thing::GetChild(Index offset) const -> const Thing* { return const_cast(this)->GetChild(offset); } @@ -412,7 +416,7 @@ namespace Langulus::Entity /// @param name - name to seek /// @param offset - offset to seek /// @return the child entity, or nullptr of none was found - Thing* Thing::GetNamedChild(const Token& name, Index offset) { + auto Thing::GetNamedChild(const Token& name, Index offset) -> Thing* { Index matches = 0; for (auto& child : mChildren) { if (child->GetName() == name) { @@ -425,7 +429,7 @@ namespace Langulus::Entity return nullptr; } - const Thing* Thing::GetNamedChild(const Token& name, Index offset) const { + auto Thing::GetNamedChild(const Token& name, Index offset) const -> const Thing* { return const_cast(this)->GetNamedChild(name, offset); } @@ -456,7 +460,7 @@ namespace Langulus::Entity /// Count the number of matching units in this entity /// @param type - the type of units to search for /// @return the number of matching units - Count Thing::HasUnits(DMeta type) const { + auto Thing::HasUnits(DMeta type) const -> Count { const auto found = mUnitsAmbiguous.FindIt(type); return found ? found.GetValue().GetCount() : 0; } @@ -469,19 +473,19 @@ namespace Langulus::Entity /// Get the current runtime /// @return the pointer to the runtime - const Pin>& Thing::GetRuntime() const noexcept { + auto Thing::GetRuntime() const noexcept -> const Pin>& { return mRuntime; } /// Get the current temporal flow /// @return the pointer to the flow - const Pin>& Thing::GetFlow() const noexcept { + auto Thing::GetFlow() const noexcept -> const Pin>& { return mFlow; } /// Create a local runtime for this thing /// @return the new runtime instance, or the old one if already created - Runtime* Thing::CreateRuntime() { + auto Thing::CreateRuntime() -> Runtime* { if (mRuntime.IsLocked()) return &*mRuntime; @@ -498,7 +502,7 @@ namespace Langulus::Entity /// Create a local flow for this thing /// @return the new flow instance, or the old one, if already created - Temporal* Thing::CreateFlow() { + auto Thing::CreateFlow() -> Temporal* { if (mFlow.IsLocked()) return &*mFlow; @@ -517,13 +521,13 @@ namespace Langulus::Entity /// instantiate it for use, if not yet instantiated /// @attention assumes a runtime is available in the hierarchy /// @param module - name of the module - /// @param descriptor - instructions for module setup + /// @param desc - instructions for module setup /// @return the instantiated module interface - A::Module* Thing::LoadMod(const Token& module, const Neat& descriptor) { + auto Thing::LoadMod(const Token& module, const Many& desc) -> A::Module* { const auto runtime = GetRuntime(); LANGULUS_ASSUME(UserAssumes, runtime, "No runtime available for loading a module"); - const auto instance = runtime->InstantiateModule(module, descriptor); + const auto instance = runtime->InstantiateModule(module, desc); LANGULUS_ASSERT(instance, Module, "Missing module"); return instance; } diff --git a/source/Thing.hpp b/source/Thing.hpp index 006c1ab..d45cfe3 100644 --- a/source/Thing.hpp +++ b/source/Thing.hpp @@ -77,7 +77,7 @@ namespace Langulus::Entity public: LANGULUS_API(ENTITY) Thing(); LANGULUS_API(ENTITY) Thing(Describe&&); - LANGULUS_API(ENTITY) Thing(Thing*, const Neat& = {}); + LANGULUS_API(ENTITY) Thing(Thing*, const Many& = {}); LANGULUS_API(ENTITY) Thing(Thing&&) noexcept; LANGULUS_API(ENTITY) Thing(Cloned&&); LANGULUS_API(ENTITY) Thing(Abandoned&&); @@ -98,10 +98,10 @@ namespace Langulus::Entity bool RequiresRefresh() const noexcept; NOD() LANGULUS_API(ENTITY) - const Pin>& GetRuntime() const noexcept; + auto GetRuntime() const noexcept -> const Pin>&; NOD() LANGULUS_API(ENTITY) - const Pin>& GetFlow() const noexcept; + auto GetFlow() const noexcept -> const Pin>&; LANGULUS_API(ENTITY) void Do(Verb&); LANGULUS_API(ENTITY) void Select(Verb&); @@ -130,39 +130,39 @@ namespace Langulus::Entity /// Hierarchy management /// LANGULUS_API(ENTITY) - Runtime* CreateRuntime(); + auto CreateRuntime() -> Runtime*; LANGULUS_API(ENTITY) - Temporal* CreateFlow(); + auto CreateFlow() -> Temporal*; template - Ref CreateChild(T&&...); + auto CreateChild(T&&...) -> Ref; template - Count AddChild(Thing*); + auto AddChild(Thing*) -> Count; template - Count RemoveChild(Thing*); + auto RemoveChild(Thing*) -> Count; LANGULUS_API(ENTITY) - A::Module* LoadMod(const Token&, const Neat& = {}); + auto LoadMod(const Token&, const Many& = {}) -> A::Module*; NOD() LANGULUS_API(ENTITY) - const Ref& GetOwner() const noexcept; + auto GetOwner() const noexcept -> const Ref&; NOD() LANGULUS_API(ENTITY) - const Hierarchy& GetChildren() const noexcept; + auto GetChildren() const noexcept -> const Hierarchy&; NOD() LANGULUS_API(ENTITY) - Thing* GetChild(Index = 0); + auto GetChild(Index = 0) -> Thing*; NOD() LANGULUS_API(ENTITY) - const Thing* GetChild(Index = 0) const; + auto GetChild(Index = 0) const -> const Thing*; NOD() LANGULUS_API(ENTITY) - Thing* GetNamedChild(const Token&, Index = 0); + auto GetNamedChild(const Token&, Index = 0) -> Thing*; NOD() LANGULUS_API(ENTITY) - const Thing* GetNamedChild(const Token&, Index = 0) const; + auto GetNamedChild(const Token&, Index = 0) const -> const Thing*; LANGULUS_API(ENTITY) void DumpHierarchy() const; @@ -172,9 +172,9 @@ namespace Langulus::Entity /// Unit management /// template - Count AddUnit(A::Unit*); + auto AddUnit(A::Unit*) -> Count; template - Count RemoveUnit(A::Unit*); + auto RemoveUnit(A::Unit*) -> Count; template Many CreateUnit(A&&...); @@ -192,38 +192,38 @@ namespace Langulus::Entity NOD() LANGULUS_API(ENTITY) Count HasUnits(DMeta) const; - template - NOD() Count HasUnits() const; + template NOD() + Count HasUnits() const; NOD() LANGULUS_API(ENTITY) - const UnitList& GetUnits() const noexcept; + auto GetUnits() const noexcept -> const UnitList&; NOD() LANGULUS_API(ENTITY) - const UnitMap& GetUnitsMap() const noexcept; + auto GetUnitsMap() const noexcept -> const UnitMap&; NOD() LANGULUS_API(ENTITY) - A::Unit* GetUnitMeta(DMeta, Index = 0); + auto GetUnitMeta(DMeta, Index = 0) -> A::Unit*; NOD() LANGULUS_API(ENTITY) - const A::Unit* GetUnitMeta(DMeta, Index = 0) const; + auto GetUnitMeta(DMeta, Index = 0) const -> const A::Unit*; NOD() LANGULUS_API(ENTITY) - A::Unit* GetUnitExt(DMeta, const Neat&, Index = 0); + auto GetUnitExt(DMeta, const Many&, Index = 0) -> A::Unit*; NOD() LANGULUS_API(ENTITY) - const A::Unit* GetUnitExt(DMeta, const Neat&, Index = 0) const; + auto GetUnitExt(DMeta, const Many&, Index = 0) const -> const A::Unit*; - template - NOD() Decay* GetUnit(Index = 0); - template - NOD() const Decay* GetUnit(Index = 0) const; + template NOD() + auto GetUnit(Index = 0) -> Decay*; + template NOD() + auto GetUnit(Index = 0) const -> const Decay*; #if LANGULUS_FEATURE(MANAGED_REFLECTION) NOD() LANGULUS_API(ENTITY) - A::Unit const* GetUnitMeta(const Token&, Index = 0) const; + auto GetUnitMeta(const Token&, Index = 0) const -> A::Unit const*; NOD() LANGULUS_API(ENTITY) - A::Unit* GetUnitMeta(const Token&, Index = 0); + auto GetUnitMeta(const Token&, Index = 0) -> A::Unit*; - template - NOD() Decay* GetUnitAs(const Token&, Index = 0); + template NOD() + auto GetUnitAs(const Token&, Index = 0) -> Decay*; #endif private: @@ -234,45 +234,38 @@ namespace Langulus::Entity /// /// Trait management /// - LANGULUS_API(ENTITY) Trait* AddTrait(Trait); + LANGULUS_API(ENTITY) auto AddTrait(Trait) -> Trait*; - LANGULUS_API(ENTITY) Count RemoveTrait(TMeta); - LANGULUS_API(ENTITY) Count RemoveTrait(Trait); + LANGULUS_API(ENTITY) auto RemoveTrait(TMeta) -> Count; + LANGULUS_API(ENTITY) auto RemoveTrait(Trait) -> Count; NOD() LANGULUS_API(ENTITY) - Count HasTraits(TMeta) const; - + auto HasTraits(TMeta) const -> Count; NOD() LANGULUS_API(ENTITY) - Count HasTraits(const Trait&) const; + auto HasTraits(const Trait&) const -> Count; NOD() LANGULUS_API(ENTITY) - const TraitMap& GetTraits() const noexcept; + auto GetTraits() const noexcept -> const TraitMap&; NOD() LANGULUS_API(ENTITY) - Trait GetTrait(TMeta, Index = 0) const; - + auto GetTrait(TMeta, Index = 0) const -> Trait; NOD() LANGULUS_API(ENTITY) - Trait GetTrait(TMeta, Index = 0); - + auto GetTrait(TMeta, Index = 0) -> Trait; NOD() LANGULUS_API(ENTITY) - Trait GetTrait(const Trait&, Index = 0) const; - + auto GetTrait(const Trait&, Index = 0) const -> Trait; NOD() LANGULUS_API(ENTITY) - Trait GetTrait(const Trait&, Index = 0); - - template - NOD() Trait GetTrait(Index = 0); + auto GetTrait(const Trait&, Index = 0) -> Trait; + template NOD() + auto GetTrait(Index = 0) -> Trait; NOD() LANGULUS_API(ENTITY) - const Trait* GetLocalTrait(TMeta, Index = 0) const; - + auto GetLocalTrait(TMeta, Index = 0) const -> const Trait*; NOD() LANGULUS_API(ENTITY) - Trait* GetLocalTrait(TMeta, Index = 0); - - template - NOD() Trait* GetLocalTrait(Index = 0); - template - NOD() Trait const* GetLocalTrait(Index = 0) const; + auto GetLocalTrait(TMeta, Index = 0) -> Trait*; + template NOD() + auto GetLocalTrait(Index = 0) -> Trait*; + template NOD() + auto GetLocalTrait(Index = 0) const -> Trait const*; LANGULUS_API(ENTITY) void SetName(const Text&); @@ -283,33 +276,24 @@ namespace Langulus::Entity /// /// Seek /// - using SeekInterface::SeekUnit; using SeekInterface::SeekUnitAux; using SeekInterface::SeekUnitExt; using SeekInterface::SeekUnitAuxExt; - using SeekInterface::SeekTrait; using SeekInterface::SeekTraitAux; - using SeekInterface::SeekValue; using SeekInterface::SeekValueAux; - template - NOD() A::Unit* SeekUnit(DMeta, Index = 0); - template - NOD() A::Unit* SeekUnitAux(const Neat&, DMeta, Index = 0); - template - NOD() A::Unit* SeekUnitExt(DMeta, const Neat&, Index = 0); - template - NOD() A::Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0); + template NOD() + auto SeekUnitAux(const Many&, DMeta, Index = 0) -> A::Unit*; + template NOD() + auto SeekUnitExt(DMeta, const Many&, Index = 0) -> A::Unit*; + template NOD() + auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) -> A::Unit*; - template - NOD() Trait SeekTrait(TMeta, Index = 0); - template - NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = 0); + template NOD() + auto SeekTraitAux(const Many&, TMeta, Index = 0) -> Trait; template - bool SeekValue(TMeta, CT::Data auto&, Index = 0) const; - template - bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = 0) const; + bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = 0) const; /// /// Gather @@ -318,16 +302,16 @@ namespace Langulus::Entity using SeekInterface::GatherUnitsExt; using SeekInterface::GatherTraits; - template - NOD() TMany GatherUnits(DMeta); - template - NOD() TMany GatherUnitsExt(DMeta, const Neat&); + template NOD() + auto GatherUnits(DMeta) -> TMany; + template NOD() + auto GatherUnitsExt(DMeta, const Many&) -> TMany; - template - NOD() TraitList GatherTraits(TMeta); + template NOD() + auto GatherTraits(TMeta) -> TraitList; - template - NOD() TMany GatherValues() const; + template NOD() + auto GatherValues() const -> TMany; }; } // namespace Langulus::Entity \ No newline at end of file diff --git a/source/Thing.inl b/source/Thing.inl index f872bf1..e159916 100644 --- a/source/Thing.inl +++ b/source/Thing.inl @@ -581,8 +581,8 @@ namespace Langulus::Entity // Implicitly add a parent trait to descriptor, if one isn't // already added - it will be stripped later, when normalizing // the descriptor when producing the item from a factory - Construct descriptor {construct}; - Traits::Parent parent; + Construct descriptor = construct; + /*Traits::Parent parent; if (not descriptor->ExtractTrait(parent)) { parent = this; parent.MakeMissing(); @@ -592,7 +592,7 @@ namespace Langulus::Entity Reference(0), " references)" ); } - else parent << this; + else parent << this;*/ if (producer) { // Data has a specific producer, we can narrow the required diff --git a/source/Unit-Seek.inl b/source/Unit-Seek.inl index 8383394..022f701 100644 --- a/source/Unit-Seek.inl +++ b/source/Unit-Seek.inl @@ -13,16 +13,6 @@ namespace Langulus::A { - /// Find a specific unit, searching into the hierarchy - /// @tparam SEEK - where in the hierarchy are we seeking in? - /// @param meta - the unit to seek for - /// @param offset - which of the matches to return - /// @return the found unit, or nullptr if no such unit was found - template LANGULUS(INLINED) - Unit* Unit::SeekUnit(DMeta meta, Index offset) { - return mOwners.template SeekUnit(meta, offset); - } - /// Find a unit by type and index from the hierarchy /// @tparam SEEK - where to seek for the unit /// @param aux - descriptor to search through @@ -30,7 +20,7 @@ namespace Langulus::A /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - Unit* Unit::SeekUnitAux(const Neat& aux, DMeta meta, Index offset) { + Unit* Unit::SeekUnitAux(const Many& aux, DMeta meta, Index offset) { return mOwners.template SeekUnitAux(aux, meta, offset); } @@ -41,7 +31,7 @@ namespace Langulus::A /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - Unit* Unit::SeekUnitExt(DMeta type, const Neat& ext, Index offset) { + Unit* Unit::SeekUnitExt(DMeta type, const Many& ext, Index offset) { return mOwners.template SeekUnitExt(type, ext, offset); } @@ -54,20 +44,10 @@ namespace Langulus::A /// @param offset - the index of the unit to return /// @return a pointer to the found unit, or nullptr if not found template LANGULUS(INLINED) - Unit* Unit::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) { + Unit* Unit::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) { return mOwners.template SeekUnitAuxExt(type, aux, ext, offset); } - /// Find a trait by type (and index), searching into the hierarchy - /// @tparam SEEK - direction to search at - /// @param meta - the trait to search for - /// @param offset - the offset to apply - /// @return the trait, which is not empty, if trait was found - template LANGULUS(INLINED) - Langulus::Trait Unit::SeekTrait(TMeta meta, Index offset) { - return mOwners.template SeekTrait(meta, offset); - } - /// Find a trait, searching into the hierarchy (const) /// @tparam SEEK - direction to search at /// @param aux - descriptor to search through @@ -75,23 +55,10 @@ namespace Langulus::A /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - Langulus::Trait Unit::SeekTraitAux(const Neat& aux, TMeta meta, Index offset) { + Langulus::Trait Unit::SeekTraitAux(const Many& aux, TMeta meta, Index offset) { return mOwners.template SeekTraitAux(aux, meta, offset); } - /// Find a trait by type (and index) from the hierarchy, and attempt - /// converting it to a desired output type - /// Supports pinnable outputs, and won't change anything if D is pinned - /// @tparam SEEK - direction to search at - /// @param meta - the trait type to search for - /// @param output - [out] the output - /// @param offset - the number of the matching trait to use - /// @return true if output was rewritten - template LANGULUS(INLINED) - bool Unit::SeekValue(TMeta meta, CT::Data auto& output, Index offset) const { - return mOwners.template SeekValue(meta, output, offset); - } - /// Find a trait by type (and index) from the hierarchy, and attempt /// converting it to a desired output type. Scan the aux container first /// Supports pinnable outputs, and pinnables will be pinned if trait was @@ -103,7 +70,7 @@ namespace Langulus::A /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - bool Unit::SeekValueAux(TMeta meta, const Neat& aux, CT::Data auto& output, Index offset) const { + bool Unit::SeekValueAux(TMeta meta, const Many& aux, CT::Data auto& output, Index offset) const { return mOwners.template SeekValueAux(meta, aux, output, offset); } diff --git a/source/Unit.cpp b/source/Unit.cpp index 6a7ab7c..58694a6 100644 --- a/source/Unit.cpp +++ b/source/Unit.cpp @@ -12,6 +12,8 @@ using namespace Langulus::A; + +/// Unit destructor decouples from any owners Unit::~Unit() { for (auto entity : mOwners) Decouple(entity); @@ -27,11 +29,11 @@ void Unit::Select(Flow::Verb& verb) { /// Check if this unit has a given set of properties /// @param descriptor - descriptor with required properties /// @return true if the unit has the given properties -bool Unit::CompareDescriptor(const Neat& descriptor) const { +bool Unit::CompareDescriptor(const Many& descriptor) const { // First we compare traits only, all of them must be present bool mismatch = false; Offset memberOffset = 0; - descriptor.ForEach([&](const Anyness::Trait& trait) { + descriptor.ForEachDeep([&](const Anyness::Trait& trait) { if (not GetMember(trait.GetTrait(), memberOffset) .Compare(static_cast(trait))) { mismatch = true; @@ -43,9 +45,9 @@ bool Unit::CompareDescriptor(const Neat& descriptor) const { }); // Then we run another check, based on data types, again, all - // of them must be present, either in trait, or in other form + // of them must be present, either as trait, or in other form memberOffset = 0; - descriptor.ForEachTail([&](const Many& anythingElse) { + descriptor.ForEachDeep([&](const Many& anythingElse) { if (not GetMember(TMeta {}, memberOffset).Compare(anythingElse)) { mismatch = true; return Loop::Break; @@ -60,7 +62,7 @@ bool Unit::CompareDescriptor(const Neat& descriptor) const { /// Get the list of unit owners /// @return the owners -const Hierarchy& Unit::GetOwners() const noexcept { +auto Unit::GetOwners() const noexcept -> const Hierarchy& { return mOwners; } @@ -71,24 +73,29 @@ void Unit::Refresh() {} /// @attention assumes units are correctly coupled and coupling to /// different runtimes should be explicitly disallowed /// @return a pointer to the runtime, if available -Runtime* Unit::GetRuntime() const noexcept { +auto Unit::GetRuntime() const noexcept -> Runtime* { if (not mOwners) return nullptr; return &*mOwners[0]->GetRuntime(); } -/// Couple the component with an entity, extracted from a descriptor's +/// Couple the component with an entity extracted from a descriptor's /// Traits::Parent, if any was defined (always two-sided) /// This will call refresh to all units in that entity on next tick /// @param desc - the descriptor to scan for parents -void Unit::Couple(const Neat& desc) { - // Couple any Thing provided in the descriptor +/// @param fallback - a fallback Thing to couple to (optional) +/// This usually comes from the producer's context. For example, if you +/// don't provide a parent for the renderer, it will be instantiated as +/// a child to the graphics module owner (i.e. the runtime owner) +void Unit::Couple(const Many& desc, const Thing* fallback) { const Thing* owner = nullptr; if (not desc.ExtractTrait(owner)) desc.ExtractData(owner); if (owner and mOwners.Merge(IndexBack, const_cast(owner))) const_cast(owner)->AddUnit(this); + else if (fallback) + const_cast(fallback)->AddUnit(this); } /// Decouple the component from an entity (always two-sided) diff --git a/source/Unit.hpp b/source/Unit.hpp index f06f30b..edec2b8 100644 --- a/source/Unit.hpp +++ b/source/Unit.hpp @@ -63,9 +63,9 @@ namespace Langulus::A virtual void Refresh(); - Runtime* GetRuntime() const noexcept; - const Hierarchy& GetOwners() const noexcept; - bool CompareDescriptor(const Neat&) const; + auto GetRuntime() const noexcept -> Runtime*; + auto GetOwners() const noexcept -> const Hierarchy&; + bool CompareDescriptor(const Many&) const; /// /// Flow @@ -76,33 +76,24 @@ namespace Langulus::A /// /// Seek /// - using SeekInterface::SeekUnit; using SeekInterface::SeekUnitAux; using SeekInterface::SeekUnitExt; using SeekInterface::SeekUnitAuxExt; - using SeekInterface::SeekTrait; using SeekInterface::SeekTraitAux; - using SeekInterface::SeekValue; using SeekInterface::SeekValueAux; - template - NOD() Unit* SeekUnit(DMeta, Index = 0); - template - NOD() Unit* SeekUnitAux(const Neat&, DMeta, Index = 0); - template - NOD() Unit* SeekUnitExt(DMeta, const Neat&, Index = 0); - template - NOD() Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0); + template NOD() + auto SeekUnitAux(const Many&, DMeta, Index = 0) -> Unit*; + template NOD() + auto SeekUnitExt(DMeta, const Many&, Index = 0) -> Unit*; + template NOD() + auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) -> Unit*; - template - NOD() Langulus::Trait SeekTrait(TMeta, Index = 0); - template - NOD() Langulus::Trait SeekTraitAux(const Neat&, TMeta, Index = 0); + template NOD() + auto SeekTraitAux(const Many&, TMeta, Index = 0) -> Langulus::Trait; template - bool SeekValue(TMeta, CT::Data auto&, Index = 0) const; - template - bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = 0) const; + bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = 0) const; /// /// Gather @@ -111,19 +102,19 @@ namespace Langulus::A using SeekInterface::GatherUnitsExt; using SeekInterface::GatherTraits; - template - NOD() TMany GatherUnits(DMeta); - template - NOD() TMany GatherUnitsExt(DMeta, const Neat&); + template NOD() + auto GatherUnits(DMeta) -> TMany; + template NOD() + auto GatherUnitsExt(DMeta, const Many&) -> TMany; - template - NOD() TraitList GatherTraits(TMeta); + template NOD() + auto GatherTraits(TMeta) -> TraitList; - template - NOD() TMany GatherValues() const; + template NOD() + auto GatherValues() const -> TMany; protected: - void Couple(const Neat&); + void Couple(const Many&, const Thing* fallback = nullptr); void Decouple(const Thing*); void ReplaceOwner(const Thing*, const Thing*); }; From a349cf43b05bc3efbb37a3597451752370aff398 Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Thu, 10 Oct 2024 10:00:13 +0300 Subject: [PATCH 17/34] Revert "Maintenance" This reverts commit fbc3d95bd9b38eb7a6cbb50a2e9ba5f3f628abd6. --- source/Hierarchy-Seek.inl | 202 ++++++++++++++++++++++++++++++---- source/Hierarchy.hpp | 146 ++++++++++++++++--------- source/Thing-Seek.inl | 225 ++++++++++++++++++++++---------------- source/Thing-Traits.cpp | 27 +++-- source/Thing.cpp | 80 +++++++------- source/Thing.hpp | 152 +++++++++++++------------ source/Thing.inl | 6 +- source/Unit-Seek.inl | 43 +++++++- source/Unit.cpp | 25 ++--- source/Unit.hpp | 51 +++++---- 10 files changed, 622 insertions(+), 335 deletions(-) diff --git a/source/Hierarchy-Seek.inl b/source/Hierarchy-Seek.inl index dfc42f0..319685a 100644 --- a/source/Hierarchy-Seek.inl +++ b/source/Hierarchy-Seek.inl @@ -18,6 +18,29 @@ namespace Langulus::Entity { + /// Find a unit by type and optional offset + /// @tparam SEEK - the direction to seek in + /// @param type - the type of unit to search for + /// @param offset - the match to return + /// @return a pointer to the found unit, or nullptr if not found + TEMPLATE() template LANGULUS(INLINED) + const A::Unit* TME()::SeekUnit(DMeta type, Index offset) const { + return const_cast(static_cast(this)) + ->template SeekUnit(type, offset); + } + + TEMPLATE() template LANGULUS(INLINED) + Decay* TME()::SeekUnit(Index offset) { + return dynamic_cast*>(static_cast(this) + ->template SeekUnit(MetaDataOf>(), offset)); + } + + TEMPLATE() template LANGULUS(INLINED) + const Decay* TME()::SeekUnit(Index offset) const { + return const_cast(this) + ->template SeekUnit(offset); + } + /// Find a unit by type and optional offset, but search first in an /// auxiliary descriptor /// @tparam SEEK - the direction to seek in @@ -26,19 +49,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAux(const Many& aux, DMeta type, Index offset) const -> const A::Unit* { + const A::Unit* TME()::SeekUnitAux(const Neat& aux, DMeta type, Index offset) const { return const_cast(static_cast(this)) ->template SeekUnitAux(aux, type, offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAux(const Many& aux, Index offset) -> Decay* { + Decay* TME()::SeekUnitAux(const Neat& aux, Index offset) { return dynamic_cast*>(static_cast(this) ->template SeekUnitAux(aux, MetaDataOf>(), offset)); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAux(const Many& aux, Index offset) const -> const Decay* { + const Decay* TME()::SeekUnitAux(const Neat& aux, Index offset) const { return const_cast(this) ->template SeekUnitAux(aux, offset); } @@ -50,19 +73,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitExt(DMeta type, const Many& ext, Index offset) const -> const A::Unit* { + const A::Unit* TME()::SeekUnitExt(DMeta type, const Neat& ext, Index offset) const { return const_cast(static_cast(this)) ->template SeekUnitExt(type, ext, offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitExt(const Many& ext, Index offset) -> Decay* { + Decay* TME()::SeekUnitExt(const Neat& ext, Index offset) { return dynamic_cast*>(static_cast(this) ->template SeekUnitExt(MetaDataOf>(), ext, offset)); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitExt(const Many& ext, Index offset) const -> const Decay* { + const Decay* TME()::SeekUnitExt(const Neat& ext, Index offset) const { return const_cast(this) ->template SeekUnitExt(ext, offset); } @@ -76,22 +99,45 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) const -> const A::Unit* { + const A::Unit* TME()::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) const { return const_cast(static_cast(this)) ->template SeekUnitAuxExt(type, aux, ext, offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAuxExt(const Many& aux, const Many& ext, Index offset) -> Decay* { + Decay* TME()::SeekUnitAuxExt(const Neat& aux, const Neat& ext, Index offset) { return dynamic_cast*>(static_cast(this) ->template SeekUnitAuxExt(MetaDataOf>(), aux, ext, offset)); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAuxExt(const Many& aux, const Many& ext, Index offset) const -> const Decay* { + const Decay* TME()::SeekUnitAuxExt(const Neat& aux, const Neat& ext, Index offset) const { return const_cast(this) ->template SeekUnitAuxExt(aux, ext, offset); } + + /// Find a trait by type and optional offset + /// @tparam SEEK - the direction to seek in + /// @param type - the type of unit to search for + /// @param offset - the match to return + /// @return a pointer to the found unit, or nullptr if not found + TEMPLATE() template LANGULUS(INLINED) + Trait TME()::SeekTrait(TMeta type, Index offset) const { + return const_cast(static_cast(this)) + ->template SeekTrait(type, offset); + } + + TEMPLATE() template LANGULUS(INLINED) + Trait TME()::SeekTrait(Index offset) { + return static_cast(this) + ->template SeekTrait(MetaTraitOf(), offset); + } + + TEMPLATE() template LANGULUS(INLINED) + Trait TME()::SeekTrait(Index offset) const { + return const_cast(this) + ->template SeekTrait(offset); + } /// Find a trait by type and specific properties and optional offset /// @tparam SEEK - the direction to seek in @@ -100,19 +146,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekTraitAux(const Many& aux, TMeta type, Index offset) const -> Trait { + Trait TME()::SeekTraitAux(const Neat& aux, TMeta type, Index offset) const { return const_cast(static_cast(this)) ->template SeekTraitAux(aux, type, offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekTraitAux(const Many& aux, Index offset) -> Trait { + Trait TME()::SeekTraitAux(const Neat& aux, Index offset) { return static_cast(this) ->template SeekTraitAux(aux, MetaTraitOf(), offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekTraitAux(const Many& aux, Index offset) const -> Trait { + Trait TME()::SeekTraitAux(const Neat& aux, Index offset) const { return const_cast(this) ->template SeekTraitAux(aux, offset); } @@ -120,7 +166,13 @@ namespace Langulus::Entity TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValueAux(const Many& aux, CT::NotTagged auto& output, Index offset) const { + bool TME()::SeekValue(CT::NotTagged auto& output, Index offset) const { + return static_cast(this) + ->template SeekValue(MetaTraitOf(), output, offset); + } + + TEMPLATE() template LANGULUS(INLINED) + bool TME()::SeekValueAux(const Neat& aux, CT::NotTagged auto& output, Index offset) const { return static_cast(this) ->template SeekValueAux(MetaTraitOf(), aux, output, offset); } @@ -128,7 +180,17 @@ namespace Langulus::Entity TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValueAux(const Many& aux, CT::Tagged auto& output, Index offset) const { + bool TME()::SeekValue(CT::Tagged auto& output, Index offset) const { + using T = Deref; + auto lambda = [&]() { + return static_cast(this)->template + SeekValue(MetaTraitOf(), output.mData, offset); + }; + return T::Tags::ForEachOr(lambda); + } + + TEMPLATE() template LANGULUS(INLINED) + bool TME()::SeekValueAux(const Neat& aux, CT::Tagged auto& output, Index offset) const { using T = Deref; auto lambda = [&]() { return static_cast(this)->template @@ -145,25 +207,55 @@ namespace Langulus::Entity /// Available only when managed reflection is enabled /// TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAux(const Many& aux, const Token& dataToken, Index offset) -> A::Unit* { + A::Unit* TME()::SeekUnit(const Token& dataToken, Index offset) { + return static_cast(this) + ->template SeekUnit(RTTI::GetMetaData(dataToken), offset); + } + + TEMPLATE() template LANGULUS(INLINED) + const A::Unit* TME()::SeekUnit(const Token& dataToken, Index offset) const { + return static_cast(this) + ->template SeekUnit(RTTI::GetMetaData(dataToken), offset); + } + + TEMPLATE() template LANGULUS(INLINED) + A::Unit* TME()::SeekUnitAux(const Neat& aux, const Token& dataToken, Index offset) { return static_cast(this) ->template SeekUnitAux(aux, RTTI::GetMetaData(dataToken), offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAux(const Many& aux, const Token& dataToken, Index offset) const -> const A::Unit* { + const A::Unit* TME()::SeekUnitAux(const Neat& aux, const Token& dataToken, Index offset) const { return static_cast(this) ->template SeekUnitAux(aux, RTTI::GetMetaData(dataToken), offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekTraitAux(const Many& aux, const Token& traitToken, Index offset) const -> Trait { + Trait TME()::SeekTrait(const Token& traitToken, Index offset) { + return static_cast(this) + ->template SeekTrait(RTTI::GetMetaTrait(traitToken), offset); + } + + TEMPLATE() template LANGULUS(INLINED) + Trait TME()::SeekTrait(const Token& traitToken, Index offset) const { + return static_cast(this) + ->template SeekTrait(RTTI::GetMetaTrait(traitToken), offset); + } + + TEMPLATE() template LANGULUS(INLINED) + Trait TME()::SeekTraitAux(const Neat& aux, const Token& traitToken, Index offset) const { return static_cast(this) ->template SeekTraitAux(aux, RTTI::GetMetaTrait(traitToken), offset); } + + TEMPLATE() template LANGULUS(INLINED) + bool TME()::SeekValue(const Token& traitToken, CT::Data auto& output, Index offset) const { + return static_cast(this) + ->template SeekValue(RTTI::GetMetaTrait(traitToken), output, offset); + } TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValueAux(const Token& traitToken, const Many& aux, CT::Data auto& output, Index offset) const { + bool TME()::SeekValueAux(const Token& traitToken, const Neat& aux, CT::Data auto& output, Index offset) const { return static_cast(this) ->template SeekValueAux(RTTI::GetMetaTrait(traitToken), aux, output, offset); } @@ -178,6 +270,22 @@ namespace Langulus::Entity namespace Langulus::Entity { + /// Find a specific unit, searching into the hierarchy + /// @tparam SEEK - where in the hierarchy are we seeking in? + /// @param meta - the unit to seek for + /// @param offset - which of the matches to return + /// @return the found unit, or nullptr if no such unit was found + template LANGULUS(INLINED) + A::Unit* Hierarchy::SeekUnit(DMeta meta, Index offset) { + for (auto owner : *this) { + A::Unit* result = owner->template SeekUnit(meta, offset); + if (result) + return result; + } + + return nullptr; + } + /// Find a unit by type and index from the hierarchy /// Scan a locally provided descriptor first /// @tparam SEEK - where to seek for the unit @@ -186,7 +294,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - auto Hierarchy::SeekUnitAux(const Many& aux, DMeta meta, Index offset) -> A::Unit* { + A::Unit* Hierarchy::SeekUnitAux(const Neat& aux, DMeta meta, Index offset) { const A::Unit* result {}; // Scan descriptor even if hierarchy is empty @@ -247,7 +355,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - auto Hierarchy::SeekUnitExt(DMeta type, const Many& ext, Index offset) -> A::Unit* { + A::Unit* Hierarchy::SeekUnitExt(DMeta type, const Neat& ext, Index offset) { for (auto owner : *this) { A::Unit* result = owner->template SeekUnitExt(type, ext, offset); if (result) @@ -266,7 +374,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return a pointer to the found unit, or nullptr if not found template LANGULUS(INLINED) - auto Hierarchy::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) -> A::Unit* { + A::Unit* Hierarchy::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) { // Scan descriptor even if hierarchy is empty A::Unit* result {}; aux.ForEachDeep([&](const A::Unit* u) { @@ -292,6 +400,22 @@ namespace Langulus::Entity return SeekUnitExt(type, ext, offset); } + /// Find a trait by type (and index), searching into the hierarchy + /// @tparam SEEK - direction to search at + /// @param meta - the trait to search for + /// @param offset - the offset to apply + /// @return the trait, which is not empty, if trait was found + template LANGULUS(INLINED) + Trait Hierarchy::SeekTrait(TMeta meta, Index offset) { + for (auto owner : *this) { + auto result = owner->template SeekTrait(meta, offset); + if (result) + return result; + } + + return {}; + } + /// Find a trait, searching into the hierarchy (const) /// @tparam SEEK - direction to search at /// @param aux - descriptor to search through @@ -299,7 +423,7 @@ namespace Langulus::Entity /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - auto Hierarchy::SeekTraitAux(const Many& aux, TMeta meta, Index offset) -> Trait { + Trait Hierarchy::SeekTraitAux(const Neat& aux, TMeta meta, Index offset) { // Scan descriptor Trait result; aux.ForEachDeep([&](const Trait& trait) { @@ -323,7 +447,37 @@ namespace Langulus::Entity // Let's delve into the hierarchy return SeekTrait(meta, offset); } - + + /// Find a trait by type (and index) from the hierarchy, and attempt + /// converting it to a desired output type + /// Supports pinnable outputs + /// @tparam SEEK - direction to search at + /// @param meta - the trait type to search for + /// @param output - [out] the output + /// @param offset - the number of the matching trait to use + /// @return true if output was rewritten + template LANGULUS(INLINED) + bool Hierarchy::SeekValue(TMeta meta, CT::Data auto& output, Index offset) const { + using D = Deref; + + if constexpr (CT::Pinnable) { + // Never touch pinned values + if (output.mLocked) + return false; + } + + // Let's delve into the hierarchy + for (auto owner : *this) { + if (owner->template SeekValue(meta, output, offset)) { + // Value was found + return true; + } + } + + // If reached, nothing was found + return false; + } + /// Find a trait by type (and index) from the hierarchy, and attempt /// converting it to a desired output type. Scan the aux container first /// Supports pinnable outputs, and pinnables will be pinned if trait was @@ -335,7 +489,7 @@ namespace Langulus::Entity /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - bool Hierarchy::SeekValueAux(TMeta meta, const Many& aux, CT::Data auto& output, Index offset) const { + bool Hierarchy::SeekValueAux(TMeta meta, const Neat& aux, CT::Data auto& output, Index offset) const { using D = Deref; if constexpr (CT::Pinnable) { diff --git a/source/Hierarchy.hpp b/source/Hierarchy.hpp index 9895de8..00eae87 100644 --- a/source/Hierarchy.hpp +++ b/source/Hierarchy.hpp @@ -34,27 +34,31 @@ namespace Langulus::Entity /// /// Can't use virtuals, because we want these to be template functions, /// so that we retain the most of the static optimizations - /// TODO generalize these when deduce-this has been implemented well /// - /* + /*template + NOD() Unit* SeekUnit(DMeta, Index = IndexFirst) = delete; template - NOD() Unit* SeekUnitAux(const Many&, DMeta, Index = IndexFirst) = delete; + NOD() Unit* SeekUnitAux(const Neat&, DMeta, Index = IndexFirst) = delete; template - NOD() Unit* SeekUnitExt(DMeta, const Many&, Index = IndexFirst) = delete; + NOD() Unit* SeekUnitExt(DMeta, const Neat&, Index = IndexFirst) = delete; template - NOD() Unit* SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = IndexFirst) = delete; + NOD() Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = IndexFirst) = delete; template - NOD() Trait SeekTraitAux(const Many&, TMeta, Index = IndexFirst) = delete; + NOD() Trait SeekTrait(TMeta, Index = IndexFirst) = delete; + template + NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = IndexFirst) = delete; template - bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = IndexFirst) const = delete; + bool SeekValue(TMeta, CT::Data auto&, Index = IndexFirst) const = delete; + template + bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = IndexFirst) const = delete; template NOD() TMany GatherUnits(DMeta) = delete; template - NOD() TMany GatherUnitsExt(DMeta, const Many&) = delete; + NOD() TMany GatherUnitsExt(DMeta, const Neat&) = delete; template NOD() TraitList GatherTraits(TMeta) = delete; @@ -67,62 +71,82 @@ namespace Langulus::Entity /// The rest of these functions are defined for every SeekInterface /// They all use static_cast(this) as execution context for the /// above functions, which should be defined in THIS - /// TODO remove these when deduce-this has been implemented well /// template - NOD() auto SeekUnitAux(const Many&, DMeta, Index = 0) const -> const A::Unit*; + NOD() const A::Unit* SeekUnit(DMeta, Index = 0) const; template - NOD() auto SeekUnitAux(const Many&, Index = 0) -> Decay*; + NOD() Decay* SeekUnit(Index = 0); template - NOD() auto SeekUnitAux(const Many&, Index = 0) const -> const Decay*; + NOD() const Decay* SeekUnit(Index = 0) const; template - NOD() auto SeekUnitExt(DMeta, const Many&, Index = 0) const -> const A::Unit*; + NOD() const A::Unit* SeekUnitAux(const Neat&, DMeta, Index = 0) const; template - NOD() auto SeekUnitExt(const Many&, Index = 0) -> Decay*; + NOD() Decay* SeekUnitAux(const Neat&, Index = 0); template - NOD() auto SeekUnitExt(const Many&, Index = 0) const -> const Decay*; + NOD() const Decay* SeekUnitAux(const Neat&, Index = 0) const; template - NOD() auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) const -> const A::Unit*; + NOD() const A::Unit* SeekUnitExt(DMeta, const Neat&, Index = 0) const; template - NOD() auto SeekUnitAuxExt(const Many&, const Many&, Index = 0) -> Decay*; + NOD() Decay* SeekUnitExt(const Neat&, Index = 0); template - NOD() auto SeekUnitAuxExt(const Many&, const Many&, Index = 0) const -> const Decay*; + NOD() const Decay* SeekUnitExt(const Neat&, Index = 0) const; template - NOD() auto SeekTraitAux(const Many&, TMeta, Index = 0) const -> Trait; + NOD() const A::Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0) const; + template + NOD() Decay* SeekUnitAuxExt(const Neat&, const Neat&, Index = 0); + template + NOD() const Decay* SeekUnitAuxExt(const Neat&, const Neat&, Index = 0) const; + + template + NOD() Trait SeekTrait(TMeta, Index = 0) const; template - NOD() auto SeekTraitAux(const Many&, Index = 0) -> Trait; + NOD() Trait SeekTrait(Index = 0); template - NOD() auto SeekTraitAux(const Many&, Index = 0) const -> Trait; + NOD() Trait SeekTrait(Index = 0) const; + template + NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = 0) const; template - bool SeekValueAux(const Many&, CT::NotTagged auto&, Index = 0) const; + NOD() Trait SeekTraitAux(const Neat&, Index = 0); + template + NOD() Trait SeekTraitAux(const Neat&, Index = 0) const; + + + template + bool SeekValue(CT::NotTagged auto&, Index = IndexFirst) const; + template + bool SeekValueAux(const Neat&, CT::NotTagged auto&, Index = 0) const; + template - bool SeekValueAux(const Many&, CT::Tagged auto&, Index = 0) const; + bool SeekValue(CT::Tagged auto&, Index = IndexFirst) const; + template + bool SeekValueAux(const Neat&, CT::Tagged auto&, Index = 0) const; + template - NOD() auto GatherUnits(DMeta) const -> TMany; + NOD() TMany GatherUnits(DMeta) const; template - NOD() auto GatherUnits() -> TMany; + NOD() TMany GatherUnits(); template - NOD() auto GatherUnits() const -> TMany; + NOD() TMany GatherUnits() const; template - NOD() auto GatherUnitsExt(DMeta, const Many&) const -> TMany; + NOD() TMany GatherUnitsExt(DMeta, const Neat&) const; template - NOD() auto GatherUnitsExt(const Many&) -> TMany; + NOD() TMany GatherUnitsExt(const Neat&); template - NOD() auto GatherUnitsExt(const Many&) const -> TMany; + NOD() TMany GatherUnitsExt(const Neat&) const; template - NOD() auto GatherTraits(TMeta) const -> TraitList; + NOD() TraitList GatherTraits(TMeta) const; template - NOD() auto GatherTraits() -> TraitList; + NOD() TraitList GatherTraits(); template - NOD() auto GatherTraits() const -> TraitList; + NOD() TraitList GatherTraits() const; #if LANGULUS_FEATURE(MANAGED_REFLECTION) @@ -131,27 +155,40 @@ namespace Langulus::Entity /// Available only when managed reflection is enabled /// template - NOD() auto SeekUnitAux(const Many&, const Token&, Index = 0) -> A::Unit*; + NOD() A::Unit* SeekUnit(const Token&, Index = 0); template - NOD() auto SeekUnitAux(const Many&, const Token&, Index = 0) const -> const A::Unit*; + NOD() const A::Unit* SeekUnit(const Token&, Index = 0) const; template - NOD() auto SeekTraitAux(const Many&, const Token&, Index = 0) -> Trait; + NOD() A::Unit* SeekUnitAux(const Neat&, const Token&, Index = 0); + template + NOD() const A::Unit* SeekUnitAux(const Neat&, const Token&, Index = 0) const; + template - NOD() auto SeekTraitAux(const Many&, const Token&, Index = 0) const -> Trait; + NOD() Trait SeekTrait(const Token&, Index = 0); + template + NOD() Trait SeekTrait(const Token&, Index = 0) const; template - bool SeekValueAux(const Token&, const Many&, CT::Data auto&, Index = 0) const; + NOD() Trait SeekTraitAux(const Neat&, const Token&, Index = 0); + template + NOD() Trait SeekTraitAux(const Neat&, const Token&, Index = 0) const; template - NOD() auto GatherUnits(const Token&) -> TMany; + bool SeekValue(const Token&, CT::Data auto&, Index = 0) const; template - NOD() auto GatherUnits(const Token&) const -> TMany; + bool SeekValueAux(const Token&, const Neat&, CT::Data auto&, Index = 0) const; + + + template + NOD() TMany GatherUnits(const Token&); + template + NOD() TMany GatherUnits(const Token&) const; template - NOD() auto GatherTraits(const Token&) -> TraitList; + NOD() TraitList GatherTraits(const Token&); template - NOD() auto GatherTraits(const Token&) const -> TraitList; + NOD() TraitList GatherTraits(const Token&) const; #endif }; @@ -173,24 +210,33 @@ namespace Langulus::Entity /// /// Seek /// + using SeekInterface::SeekUnit; using SeekInterface::SeekUnitAux; using SeekInterface::SeekUnitExt; using SeekInterface::SeekUnitAuxExt; + using SeekInterface::SeekTrait; using SeekInterface::SeekTraitAux; + using SeekInterface::SeekValue; using SeekInterface::SeekValueAux; template - NOD() auto SeekUnitAux(const Many&, DMeta, Index = 0) -> A::Unit*; + NOD() A::Unit* SeekUnit(DMeta, Index = 0); template - NOD() auto SeekUnitExt(DMeta, const Many&, Index = 0) -> A::Unit*; + NOD() A::Unit* SeekUnitAux(const Neat&, DMeta, Index = 0); template - NOD() auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) -> A::Unit*; + NOD() A::Unit* SeekUnitExt(DMeta, const Neat&, Index = 0); + template + NOD() A::Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0); template - NOD() auto SeekTraitAux(const Many&, TMeta, Index = 0) -> Trait; + NOD() Trait SeekTrait(TMeta, Index = 0); + template + NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = 0); template - bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = 0) const; + bool SeekValue(TMeta, CT::Data auto&, Index = 0) const; + template + bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = 0) const; /// /// Gather @@ -200,15 +246,15 @@ namespace Langulus::Entity using SeekInterface::GatherTraits; template - NOD() auto GatherUnitsExt(DMeta, const Many&) -> TMany; + NOD() TMany GatherUnitsExt(DMeta, const Neat&); template - NOD() auto GatherUnits(DMeta) -> TMany; + NOD() TMany GatherUnits(DMeta); template - NOD() auto GatherTraits(TMeta) -> TraitList; + NOD() TraitList GatherTraits(TMeta); template - NOD() auto GatherValues() const -> TMany; + NOD() TMany GatherValues() const; }; } // namespace Langulus::Entity diff --git a/source/Thing-Seek.inl b/source/Thing-Seek.inl index 1f464dd..b155c76 100644 --- a/source/Thing-Seek.inl +++ b/source/Thing-Seek.inl @@ -23,6 +23,44 @@ namespace Langulus::Entity { + /// Find a specific unit, searching into the hierarchy + /// @tparam SEEK - where in the hierarchy are we seeking in? + /// @param meta - the unit to seek for + /// @param offset - which of the matches to return + /// @return the found unit, or nullptr if no such unit was found + template + A::Unit* Thing::SeekUnit(DMeta meta, Index offset) { + A::Unit* result = nullptr; + if constexpr (SEEK & Seek::Here) { + // Seek here if requested + result = GetUnitMeta(meta, offset); + if (result) + return result; + } + + if constexpr (SEEK & Seek::Above) { + // Seek in parents up to root, if requested + if (mOwner) { + result = mOwner->template + SeekUnit(meta, offset); + if (result) + return result; + } + } + + if constexpr (SEEK & Seek::Below) { + // Seek children, if requested + for (auto child : mChildren) { + result = child->template + SeekUnit(meta, offset); + if (result) + return result; + } + } + + return nullptr; + } + /// Find a unit by type and index from the hierarchy /// Scan an auxiliary descriptor first /// @tparam SEEK - where to seek for the unit @@ -31,7 +69,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - A::Unit* Thing::SeekUnitAux(const Many& aux, DMeta meta, Index offset) { + A::Unit* Thing::SeekUnitAux(const Neat& aux, DMeta meta, Index offset) { A::Unit* result {}; aux.ForEachDeep([&](const A::Unit* unit) { if (unit->CastsTo(meta)) { @@ -52,34 +90,7 @@ namespace Langulus::Entity // If reached, then no unit was found in the descriptor // Let's delve into the hierarchy - if constexpr (SEEK & Seek::Here) { - // Seek here if requested - result = GetUnitMeta(meta, offset); - if (result) - return result; - } - - if constexpr (SEEK & Seek::Above) { - // Seek in parents up to root, if requested - if (mOwner) { - result = mOwner->template - SeekUnitAux({}, meta, offset); - if (result) - return result; - } - } - - if constexpr (SEEK & Seek::Below) { - // Seek children, if requested - for (auto child : mChildren) { - result = child->template - SeekUnitAux({}, meta, offset); - if (result) - return result; - } - } - - return nullptr; + return SeekUnit(meta, offset); } /// Find a unit by construct and index from the hierarchy @@ -88,7 +99,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - A::Unit* Thing::SeekUnitExt(DMeta type, const Many& ext, Index offset) { + A::Unit* Thing::SeekUnitExt(DMeta type, const Neat& ext, Index offset) { A::Unit* result = nullptr; if constexpr (SEEK & Seek::Here) { // Seek here if requested @@ -128,7 +139,7 @@ namespace Langulus::Entity /// @param offset - the Nth match to return /// @return a pointer to the found unit, or nullptr if not found template LANGULUS(INLINED) - A::Unit* Thing::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) { + A::Unit* Thing::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) { // Scan descriptor even if hierarchy is empty A::Unit* result {}; aux.ForEachDeep([&](const A::Unit* unit) { @@ -153,6 +164,43 @@ namespace Langulus::Entity return SeekUnitExt(type, ext, offset); } + /// Find a trait by type (and index), searching into the hierarchy + /// @tparam SEEK - direction to search at + /// @param meta - the trait to search for + /// @param offset - the offset to apply + /// @return the trait, which is not empty, if trait was found + template + Trait Thing::SeekTrait(TMeta meta, Index offset) { + if constexpr (SEEK & Seek::Here) { + // Seek here if requested + auto output = GetTrait(meta, offset); + if (output) + return Abandon(output); + } + + if constexpr (SEEK & Seek::Above) { + // Seek in parents up to root, if requested + if (mOwner) { + auto output = mOwner->template + SeekTrait(meta, offset); + if (output) + return Abandon(output); + } + } + + if constexpr (SEEK & Seek::Below) { + // Seek children, if requested + for (auto child : mChildren) { + auto output = child->template + SeekTrait(meta, offset); + if (output) + return Abandon(output); + } + } + + return {}; + } + /// Find a trait, searching into the hierarchy (const) /// Scan an auxiliary descriptor first /// @tparam SEEK - direction to search at @@ -161,7 +209,7 @@ namespace Langulus::Entity /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - Trait Thing::SeekTraitAux(const Many& aux, TMeta meta, Index offset) { + Trait Thing::SeekTraitAux(const Neat& aux, TMeta meta, Index offset) { // Scan descriptor Trait result; aux.ForEachDeep([&](const Trait& trait) { @@ -180,36 +228,72 @@ namespace Langulus::Entity // If reached, then no trait was found in the descriptor // Let's delve into the hierarchy + return SeekTrait(meta, offset); + } + + /// Find a trait by type (and index) from the hierarchy, and attempt + /// converting it to a desired output type + /// Supports pinnable outputs + /// @tparam SEEK - direction to search at + /// @param meta - the trait type to search for + /// @param output - [out] the output + /// @param offset - the number of the matching trait to use + /// @return true if output was rewritten + template + bool Thing::SeekValue(TMeta meta, CT::Data auto& output, Index offset) const { + using D = Deref; + + if constexpr (CT::Pinnable) { + // Never touch pinned values + if (output.mLocked) + return false; + } + if constexpr (SEEK & Seek::Here) { // Seek here if requested - auto output = GetTrait(meta, offset); - if (output) - return Abandon(output); + auto temp = GetTrait(meta, offset); + try { + if (CT::Pinnable and temp.Is>()) + output = temp.As>(); + else if (not CT::Pinnable and temp.Is()) + output = temp.As(); + else if constexpr (CT::DescriptorMakable) + output = D {Describe(static_cast(temp))}; + else if constexpr (CT::Pinnable) + output = temp.template AsCast>(); + else + output = temp.template AsCast(); + + /*if constexpr (CT::Pinnable) + output = temp.template AsCast>(); + else + output = temp.template AsCast();*/ + return true; + } + catch (...) { } } if constexpr (SEEK & Seek::Above) { // Seek in parents up to root, if requested if (mOwner) { - auto output = mOwner->template - SeekTraitAux({}, meta, offset); - if (output) - return Abandon(output); + if (mOwner->template + SeekValue(meta, output, offset)) + return true; } } if constexpr (SEEK & Seek::Below) { // Seek children, if requested for (auto child : mChildren) { - auto output = child->template - SeekTraitAux({}, meta, offset); - if (output) - return Abandon(output); + if (child->template + SeekValue(meta, output, offset)) + return true; } } - return {}; + return false; } - + /// Find a value (regardless of trait) from the hierarchy, and attempt /// converting it to a desired output type. Scan the aux container first /// Supports pinnable outputs, and pinnables will be pinned if trait was @@ -221,7 +305,7 @@ namespace Langulus::Entity /// @return true if value has been found and rewritten template LANGULUS(INLINED) bool Thing::SeekValueAux( - TMeta meta, const Many& aux, CT::Data auto& output, Index offset + TMeta meta, const Neat& aux, CT::Data auto& output, Index offset ) const { using D = Deref; @@ -246,7 +330,7 @@ namespace Langulus::Entity // Didn't throw, but we're done only if offset matches done = offset == 0; --offset; - return done ? Loop::Break : Loop::Continue; + return not done; } catch (...) {} } @@ -266,7 +350,7 @@ namespace Langulus::Entity // Didn't throw, but we're done only if offset matches done = offset == 0; --offset; - return done ? Loop::Break : Loop::Continue; + return not done; } catch(...) { } @@ -286,50 +370,7 @@ namespace Langulus::Entity // If reached, then no data was found in the descriptor // Let's delve into the hierarchy - if constexpr (CT::Pinnable) { - // Never touch pinned values - if (output.mLocked) - return false; - } - - if constexpr (SEEK & Seek::Here) { - // Seek here if requested - auto temp = GetTrait(meta, offset); - try { - if (CT::Pinnable and temp.Is>()) - output = temp.As>(); - else if (not CT::Pinnable and temp.Is()) - output = temp.As(); - else if constexpr (CT::DescriptorMakable) - output = D {Describe(static_cast(temp))}; - else if constexpr (CT::Pinnable) - output = temp.template AsCast>(); - else - output = temp.template AsCast(); - return true; - } - catch (...) { } - } - - if constexpr (SEEK & Seek::Above) { - // Seek in parents up to root, if requested - if (mOwner) { - if (mOwner->template - SeekValueAux(meta, {}, output, offset)) - return true; - } - } - - if constexpr (SEEK & Seek::Below) { - // Seek children, if requested - for (auto child : mChildren) { - if (child->template - SeekValueAux(meta, {}, output, offset)) - return true; - } - } - - return false; + return SeekValue(meta, output, offset); } } // namespace Langulus::Entity diff --git a/source/Thing-Traits.cpp b/source/Thing-Traits.cpp index f8241ae..2b5db03 100644 --- a/source/Thing-Traits.cpp +++ b/source/Thing-Traits.cpp @@ -29,7 +29,7 @@ namespace Langulus::Entity /// @param trait - trait id /// @param offset - offset of result to use /// @return a filled trait if fount, empty if not - auto Thing::GetTrait(TMeta trait, Index offset) const -> Trait { + Trait Thing::GetTrait(TMeta trait, Index offset) const { return GetTrait(Trait::FromMeta(trait, nullptr), offset); } @@ -37,7 +37,7 @@ namespace Langulus::Entity /// @param trait - trait id /// @param offset - offset of result to use /// @return a filled trait if fount, empty if not - auto Thing::GetTrait(TMeta trait, Index offset) -> Trait { + Trait Thing::GetTrait(TMeta trait, Index offset) { return GetTrait(Trait::FromMeta(trait, nullptr), offset); } @@ -45,7 +45,7 @@ namespace Langulus::Entity /// @param id - the trait to search for /// @param index - the index of the trait we seek /// @return a pointer to the trait, or nullptr if not found - auto Thing::GetLocalTrait(TMeta id, Index index) -> Trait* { + Trait* Thing::GetLocalTrait(TMeta id, Index index) { if (id) { // Search a typed trait const auto found = mTraits.FindIt(id); @@ -76,7 +76,7 @@ namespace Langulus::Entity /// @param id - the trait to search for /// @param offset - the index of the trait we seek /// @return a pointer to the trait, or nullptr if not found - auto Thing::GetLocalTrait(TMeta id, Index offset) const -> const Trait* { + const Trait* Thing::GetLocalTrait(TMeta id, Index offset) const { return const_cast(*this).GetLocalTrait(id, offset); } @@ -84,7 +84,7 @@ namespace Langulus::Entity /// @param id - trait to match /// @param index - offset of result to use /// @return a non-empty trait, if found - auto Thing::GetTrait(const Trait& id, Index index) -> Trait { + Trait Thing::GetTrait(const Trait& id, Index index) { if (id.GetTrait()) { // Handle some predefined traits here if (id.template IsTrait()) { @@ -124,14 +124,14 @@ namespace Langulus::Entity /// @param id - trait to match /// @param index - offset of result to use /// @return a non-empty trait, if found - auto Thing::GetTrait(const Trait& id, Index index) const -> Trait { + Trait Thing::GetTrait(const Trait& id, Index index) const { return const_cast(this)->GetTrait(id, index); } /// Add a new trait to the thing /// @param trait - trait to shallow copy /// @return the new trait instance - auto Thing::AddTrait(Trait trait) -> Trait* { + Trait* Thing::AddTrait(Trait trait) { const auto tmeta = trait.GetTrait(); auto found = mTraits.FindIt(tmeta); if (found) { @@ -148,7 +148,7 @@ namespace Langulus::Entity /// Remove a trait from the universal entity /// @param trait - type of trait to remove /// @return the number of removed traits - auto Thing::RemoveTrait(TMeta trait) -> Count { + Count Thing::RemoveTrait(TMeta trait) { const auto found = mTraits.FindIt(trait); if (found) { const auto removed = found.GetValue().GetCount(); @@ -164,7 +164,7 @@ namespace Langulus::Entity /// Remove an exact-matching trait from this entity /// @param trait - type and value to remove /// @return the number of removed traits - auto Thing::RemoveTrait(Trait trait) -> Count { + Count Thing::RemoveTrait(Trait trait) { const auto found = mTraits.FindIt(trait.GetTrait()); if (found) { const auto removed = found.GetValue().Remove(trait); @@ -181,7 +181,7 @@ namespace Langulus::Entity /// A fast check whether traits of the given type are inside this entity /// @param trait - type of trait to check /// @return the number of matching traits - auto Thing::HasTraits(TMeta trait) const -> Count { + Count Thing::HasTraits(TMeta trait) const { const auto found = mTraits.FindIt(trait); return found ? found.GetValue().GetCount() : 0; } @@ -189,7 +189,7 @@ namespace Langulus::Entity /// A fast check whether traits of the given type and value are inside /// @param trait - trait to search for /// @return the number of matching traits - auto Thing::HasTraits(const Trait& trait) const -> Count { + Count Thing::HasTraits(const Trait& trait) const { const auto found = mTraits.FindIt(trait.GetTrait()); if (not found) return 0; @@ -205,7 +205,7 @@ namespace Langulus::Entity /// Get traits /// @return the map of traits LANGULUS_API(ENTITY) - auto Thing::GetTraits() const noexcept -> const TraitMap& { + const TraitMap& Thing::GetTraits() const noexcept { return mTraits; } @@ -223,9 +223,8 @@ namespace Langulus::Entity /// It can reside in one of the units /// @return the name, or empty string if no such trait was found here Text Thing::GetName() const { - Many unused; Text name; - SeekValueAux(name, unused); + SeekValue(name); return name; } diff --git a/source/Thing.cpp b/source/Thing.cpp index e0b133b..6cf98f8 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -54,10 +54,9 @@ namespace Langulus::Entity /// Construct as a child of another thing /// @param parent - the thing that owns this thing /// @param descriptor - instructions for creating the thing - Thing::Thing(Thing* parent, const Many& descriptor) + Thing::Thing(Thing* parent, const Neat& descriptor) : Resolvable {this} - , mOwner {parent} - { + , mOwner {parent} { if (parent) { parent->AddChild(this); mRuntime = parent->GetRuntime(); @@ -90,15 +89,14 @@ namespace Langulus::Entity /// because 'other' is removed from its children /// @param other - move that entity Thing::Thing(Thing&& other) noexcept - : Resolvable {this} - , mChildren {Move(other.mChildren)} - , mRuntime {Move(other.mRuntime)} - , mFlow {Move(other.mFlow)} + : Resolvable {this} + , mChildren {Move(other.mChildren)} + , mRuntime {Move(other.mRuntime)} + , mFlow {Move(other.mFlow)} , mUnitsAmbiguous {Move(other.mUnitsAmbiguous)} - , mUnitsList {Move(other.mUnitsList)} - , mTraits {Move(other.mTraits)} - , mRefreshRequired{true} - { + , mUnitsList {Move(other.mUnitsList)} + , mTraits {Move(other.mTraits)} + , mRefreshRequired {true} { // Remap children for (auto& child : mChildren) child->mOwner = this; @@ -120,15 +118,14 @@ namespace Langulus::Entity /// because 'other' is duplicated in its children /// @param other - clone that entity Thing::Thing(Abandoned&& other) - : Resolvable {this} - , mChildren {Abandon(other->mChildren)} - , mRuntime {Abandon(other->mRuntime)} - , mFlow {Abandon(other->mFlow)} + : Resolvable {this} + , mChildren {Abandon(other->mChildren)} + , mRuntime {Abandon(other->mRuntime)} + , mFlow {Abandon(other->mFlow)} , mUnitsAmbiguous {Abandon(other->mUnitsAmbiguous)} - , mUnitsList {Abandon(other->mUnitsList)} - , mTraits {Abandon(other->mTraits)} - , mRefreshRequired{true} - { + , mUnitsList {Abandon(other->mUnitsList)} + , mTraits {Abandon(other->mTraits)} + , mRefreshRequired {true} { // Remap children for (auto& child : mChildren) child->mOwner = this; @@ -150,10 +147,9 @@ namespace Langulus::Entity /// because 'other' is duplicated in its children /// @param other - clone that entity Thing::Thing(Cloned&& other) - : Resolvable {this} - , mChildren {Clone(other->mChildren)} - , mRefreshRequired{true} - { + : Resolvable {this} + , mChildren {Clone(other->mChildren)} + , mRefreshRequired {true} { TODO(); //TODO clone flow and runtime if pinned, recreate modules if new runtime, // recreate units and traits, then recreate children @@ -320,7 +316,7 @@ namespace Langulus::Entity /// @param id - the type of the unit /// @param index - the unit index to seek /// @return the unit if found, or nullptr if not - auto Thing::GetUnitMeta(DMeta id, Index index) -> A::Unit* { + A::Unit* Thing::GetUnitMeta(DMeta id, Index index) { if (id) { // Search a typed trait const auto found = mUnitsAmbiguous.FindIt(id); @@ -331,7 +327,7 @@ namespace Langulus::Entity return mUnitsList[index]; } - auto Thing::GetUnitMeta(DMeta type, Index offset) const -> const A::Unit* { + const A::Unit* Thing::GetUnitMeta(DMeta type, Index offset) const { return const_cast(this)->GetUnitMeta(type, offset); } @@ -342,7 +338,7 @@ namespace Langulus::Entity /// @param what - the desired properties of the unit /// @param index - the unit index to seek /// @return the unit if found, or nullptr if not - auto Thing::GetUnitExt(DMeta meta, const Many& what, Index index) -> A::Unit* { + A::Unit* Thing::GetUnitExt(DMeta meta, const Neat& what, Index index) { if (meta) { // Search a typed unit const auto found = mUnitsAmbiguous.FindIt(meta); @@ -375,7 +371,7 @@ namespace Langulus::Entity return nullptr; } - auto Thing::GetUnitExt(DMeta meta, const Many& what, Index index) const -> const A::Unit* { + const A::Unit* Thing::GetUnitExt(DMeta meta, const Neat& what, Index index) const { return const_cast(this)->GetUnitExt(meta, what, index); } @@ -384,31 +380,31 @@ namespace Langulus::Entity /// @param token - the type name of the unit /// @param offset - the unit index /// @return the unit if found, or nullptr if not - auto Thing::GetUnitMeta(const Token& token, Index offset) -> A::Unit* { + A::Unit* Thing::GetUnitMeta(const Token& token, Index offset) { return GetUnitMeta(RTTI::DisambiguateMeta(token), offset); } #endif /// Get the owner /// @return the owner - auto Thing::GetOwner() const noexcept -> const Ref& { + const Ref& Thing::GetOwner() const noexcept { return mOwner; } /// Get children hierarchy /// @return the hierarchy - auto Thing::GetChildren() const noexcept -> const Hierarchy& { + const Hierarchy& Thing::GetChildren() const noexcept { return mChildren; } /// Get a child by index /// @param id - the index to pick /// @return the child entity, or nullptr of none was found - auto Thing::GetChild(Index offset) -> Thing* { + Thing* Thing::GetChild(Index offset) { return mChildren[offset]; } - auto Thing::GetChild(Index offset) const -> const Thing* { + const Thing* Thing::GetChild(Index offset) const { return const_cast(this)->GetChild(offset); } @@ -416,7 +412,7 @@ namespace Langulus::Entity /// @param name - name to seek /// @param offset - offset to seek /// @return the child entity, or nullptr of none was found - auto Thing::GetNamedChild(const Token& name, Index offset) -> Thing* { + Thing* Thing::GetNamedChild(const Token& name, Index offset) { Index matches = 0; for (auto& child : mChildren) { if (child->GetName() == name) { @@ -429,7 +425,7 @@ namespace Langulus::Entity return nullptr; } - auto Thing::GetNamedChild(const Token& name, Index offset) const -> const Thing* { + const Thing* Thing::GetNamedChild(const Token& name, Index offset) const { return const_cast(this)->GetNamedChild(name, offset); } @@ -460,7 +456,7 @@ namespace Langulus::Entity /// Count the number of matching units in this entity /// @param type - the type of units to search for /// @return the number of matching units - auto Thing::HasUnits(DMeta type) const -> Count { + Count Thing::HasUnits(DMeta type) const { const auto found = mUnitsAmbiguous.FindIt(type); return found ? found.GetValue().GetCount() : 0; } @@ -473,19 +469,19 @@ namespace Langulus::Entity /// Get the current runtime /// @return the pointer to the runtime - auto Thing::GetRuntime() const noexcept -> const Pin>& { + const Pin>& Thing::GetRuntime() const noexcept { return mRuntime; } /// Get the current temporal flow /// @return the pointer to the flow - auto Thing::GetFlow() const noexcept -> const Pin>& { + const Pin>& Thing::GetFlow() const noexcept { return mFlow; } /// Create a local runtime for this thing /// @return the new runtime instance, or the old one if already created - auto Thing::CreateRuntime() -> Runtime* { + Runtime* Thing::CreateRuntime() { if (mRuntime.IsLocked()) return &*mRuntime; @@ -502,7 +498,7 @@ namespace Langulus::Entity /// Create a local flow for this thing /// @return the new flow instance, or the old one, if already created - auto Thing::CreateFlow() -> Temporal* { + Temporal* Thing::CreateFlow() { if (mFlow.IsLocked()) return &*mFlow; @@ -521,13 +517,13 @@ namespace Langulus::Entity /// instantiate it for use, if not yet instantiated /// @attention assumes a runtime is available in the hierarchy /// @param module - name of the module - /// @param desc - instructions for module setup + /// @param descriptor - instructions for module setup /// @return the instantiated module interface - auto Thing::LoadMod(const Token& module, const Many& desc) -> A::Module* { + A::Module* Thing::LoadMod(const Token& module, const Neat& descriptor) { const auto runtime = GetRuntime(); LANGULUS_ASSUME(UserAssumes, runtime, "No runtime available for loading a module"); - const auto instance = runtime->InstantiateModule(module, desc); + const auto instance = runtime->InstantiateModule(module, descriptor); LANGULUS_ASSERT(instance, Module, "Missing module"); return instance; } diff --git a/source/Thing.hpp b/source/Thing.hpp index d45cfe3..006c1ab 100644 --- a/source/Thing.hpp +++ b/source/Thing.hpp @@ -77,7 +77,7 @@ namespace Langulus::Entity public: LANGULUS_API(ENTITY) Thing(); LANGULUS_API(ENTITY) Thing(Describe&&); - LANGULUS_API(ENTITY) Thing(Thing*, const Many& = {}); + LANGULUS_API(ENTITY) Thing(Thing*, const Neat& = {}); LANGULUS_API(ENTITY) Thing(Thing&&) noexcept; LANGULUS_API(ENTITY) Thing(Cloned&&); LANGULUS_API(ENTITY) Thing(Abandoned&&); @@ -98,10 +98,10 @@ namespace Langulus::Entity bool RequiresRefresh() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetRuntime() const noexcept -> const Pin>&; + const Pin>& GetRuntime() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetFlow() const noexcept -> const Pin>&; + const Pin>& GetFlow() const noexcept; LANGULUS_API(ENTITY) void Do(Verb&); LANGULUS_API(ENTITY) void Select(Verb&); @@ -130,39 +130,39 @@ namespace Langulus::Entity /// Hierarchy management /// LANGULUS_API(ENTITY) - auto CreateRuntime() -> Runtime*; + Runtime* CreateRuntime(); LANGULUS_API(ENTITY) - auto CreateFlow() -> Temporal*; + Temporal* CreateFlow(); template - auto CreateChild(T&&...) -> Ref; + Ref CreateChild(T&&...); template - auto AddChild(Thing*) -> Count; + Count AddChild(Thing*); template - auto RemoveChild(Thing*) -> Count; + Count RemoveChild(Thing*); LANGULUS_API(ENTITY) - auto LoadMod(const Token&, const Many& = {}) -> A::Module*; + A::Module* LoadMod(const Token&, const Neat& = {}); NOD() LANGULUS_API(ENTITY) - auto GetOwner() const noexcept -> const Ref&; + const Ref& GetOwner() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetChildren() const noexcept -> const Hierarchy&; + const Hierarchy& GetChildren() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetChild(Index = 0) -> Thing*; + Thing* GetChild(Index = 0); NOD() LANGULUS_API(ENTITY) - auto GetChild(Index = 0) const -> const Thing*; + const Thing* GetChild(Index = 0) const; NOD() LANGULUS_API(ENTITY) - auto GetNamedChild(const Token&, Index = 0) -> Thing*; + Thing* GetNamedChild(const Token&, Index = 0); NOD() LANGULUS_API(ENTITY) - auto GetNamedChild(const Token&, Index = 0) const -> const Thing*; + const Thing* GetNamedChild(const Token&, Index = 0) const; LANGULUS_API(ENTITY) void DumpHierarchy() const; @@ -172,9 +172,9 @@ namespace Langulus::Entity /// Unit management /// template - auto AddUnit(A::Unit*) -> Count; + Count AddUnit(A::Unit*); template - auto RemoveUnit(A::Unit*) -> Count; + Count RemoveUnit(A::Unit*); template Many CreateUnit(A&&...); @@ -192,38 +192,38 @@ namespace Langulus::Entity NOD() LANGULUS_API(ENTITY) Count HasUnits(DMeta) const; - template NOD() - Count HasUnits() const; + template + NOD() Count HasUnits() const; NOD() LANGULUS_API(ENTITY) - auto GetUnits() const noexcept -> const UnitList&; + const UnitList& GetUnits() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetUnitsMap() const noexcept -> const UnitMap&; + const UnitMap& GetUnitsMap() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetUnitMeta(DMeta, Index = 0) -> A::Unit*; + A::Unit* GetUnitMeta(DMeta, Index = 0); NOD() LANGULUS_API(ENTITY) - auto GetUnitMeta(DMeta, Index = 0) const -> const A::Unit*; + const A::Unit* GetUnitMeta(DMeta, Index = 0) const; NOD() LANGULUS_API(ENTITY) - auto GetUnitExt(DMeta, const Many&, Index = 0) -> A::Unit*; + A::Unit* GetUnitExt(DMeta, const Neat&, Index = 0); NOD() LANGULUS_API(ENTITY) - auto GetUnitExt(DMeta, const Many&, Index = 0) const -> const A::Unit*; + const A::Unit* GetUnitExt(DMeta, const Neat&, Index = 0) const; - template NOD() - auto GetUnit(Index = 0) -> Decay*; - template NOD() - auto GetUnit(Index = 0) const -> const Decay*; + template + NOD() Decay* GetUnit(Index = 0); + template + NOD() const Decay* GetUnit(Index = 0) const; #if LANGULUS_FEATURE(MANAGED_REFLECTION) NOD() LANGULUS_API(ENTITY) - auto GetUnitMeta(const Token&, Index = 0) const -> A::Unit const*; + A::Unit const* GetUnitMeta(const Token&, Index = 0) const; NOD() LANGULUS_API(ENTITY) - auto GetUnitMeta(const Token&, Index = 0) -> A::Unit*; + A::Unit* GetUnitMeta(const Token&, Index = 0); - template NOD() - auto GetUnitAs(const Token&, Index = 0) -> Decay*; + template + NOD() Decay* GetUnitAs(const Token&, Index = 0); #endif private: @@ -234,38 +234,45 @@ namespace Langulus::Entity /// /// Trait management /// - LANGULUS_API(ENTITY) auto AddTrait(Trait) -> Trait*; + LANGULUS_API(ENTITY) Trait* AddTrait(Trait); - LANGULUS_API(ENTITY) auto RemoveTrait(TMeta) -> Count; - LANGULUS_API(ENTITY) auto RemoveTrait(Trait) -> Count; + LANGULUS_API(ENTITY) Count RemoveTrait(TMeta); + LANGULUS_API(ENTITY) Count RemoveTrait(Trait); NOD() LANGULUS_API(ENTITY) - auto HasTraits(TMeta) const -> Count; + Count HasTraits(TMeta) const; + NOD() LANGULUS_API(ENTITY) - auto HasTraits(const Trait&) const -> Count; + Count HasTraits(const Trait&) const; NOD() LANGULUS_API(ENTITY) - auto GetTraits() const noexcept -> const TraitMap&; + const TraitMap& GetTraits() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetTrait(TMeta, Index = 0) const -> Trait; + Trait GetTrait(TMeta, Index = 0) const; + NOD() LANGULUS_API(ENTITY) - auto GetTrait(TMeta, Index = 0) -> Trait; + Trait GetTrait(TMeta, Index = 0); + NOD() LANGULUS_API(ENTITY) - auto GetTrait(const Trait&, Index = 0) const -> Trait; + Trait GetTrait(const Trait&, Index = 0) const; + NOD() LANGULUS_API(ENTITY) - auto GetTrait(const Trait&, Index = 0) -> Trait; - template NOD() - auto GetTrait(Index = 0) -> Trait; + Trait GetTrait(const Trait&, Index = 0); + + template + NOD() Trait GetTrait(Index = 0); NOD() LANGULUS_API(ENTITY) - auto GetLocalTrait(TMeta, Index = 0) const -> const Trait*; + const Trait* GetLocalTrait(TMeta, Index = 0) const; + NOD() LANGULUS_API(ENTITY) - auto GetLocalTrait(TMeta, Index = 0) -> Trait*; - template NOD() - auto GetLocalTrait(Index = 0) -> Trait*; - template NOD() - auto GetLocalTrait(Index = 0) const -> Trait const*; + Trait* GetLocalTrait(TMeta, Index = 0); + + template + NOD() Trait* GetLocalTrait(Index = 0); + template + NOD() Trait const* GetLocalTrait(Index = 0) const; LANGULUS_API(ENTITY) void SetName(const Text&); @@ -276,24 +283,33 @@ namespace Langulus::Entity /// /// Seek /// + using SeekInterface::SeekUnit; using SeekInterface::SeekUnitAux; using SeekInterface::SeekUnitExt; using SeekInterface::SeekUnitAuxExt; + using SeekInterface::SeekTrait; using SeekInterface::SeekTraitAux; + using SeekInterface::SeekValue; using SeekInterface::SeekValueAux; - template NOD() - auto SeekUnitAux(const Many&, DMeta, Index = 0) -> A::Unit*; - template NOD() - auto SeekUnitExt(DMeta, const Many&, Index = 0) -> A::Unit*; - template NOD() - auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) -> A::Unit*; + template + NOD() A::Unit* SeekUnit(DMeta, Index = 0); + template + NOD() A::Unit* SeekUnitAux(const Neat&, DMeta, Index = 0); + template + NOD() A::Unit* SeekUnitExt(DMeta, const Neat&, Index = 0); + template + NOD() A::Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0); - template NOD() - auto SeekTraitAux(const Many&, TMeta, Index = 0) -> Trait; + template + NOD() Trait SeekTrait(TMeta, Index = 0); + template + NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = 0); template - bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = 0) const; + bool SeekValue(TMeta, CT::Data auto&, Index = 0) const; + template + bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = 0) const; /// /// Gather @@ -302,16 +318,16 @@ namespace Langulus::Entity using SeekInterface::GatherUnitsExt; using SeekInterface::GatherTraits; - template NOD() - auto GatherUnits(DMeta) -> TMany; - template NOD() - auto GatherUnitsExt(DMeta, const Many&) -> TMany; + template + NOD() TMany GatherUnits(DMeta); + template + NOD() TMany GatherUnitsExt(DMeta, const Neat&); - template NOD() - auto GatherTraits(TMeta) -> TraitList; + template + NOD() TraitList GatherTraits(TMeta); - template NOD() - auto GatherValues() const -> TMany; + template + NOD() TMany GatherValues() const; }; } // namespace Langulus::Entity \ No newline at end of file diff --git a/source/Thing.inl b/source/Thing.inl index e159916..f872bf1 100644 --- a/source/Thing.inl +++ b/source/Thing.inl @@ -581,8 +581,8 @@ namespace Langulus::Entity // Implicitly add a parent trait to descriptor, if one isn't // already added - it will be stripped later, when normalizing // the descriptor when producing the item from a factory - Construct descriptor = construct; - /*Traits::Parent parent; + Construct descriptor {construct}; + Traits::Parent parent; if (not descriptor->ExtractTrait(parent)) { parent = this; parent.MakeMissing(); @@ -592,7 +592,7 @@ namespace Langulus::Entity Reference(0), " references)" ); } - else parent << this;*/ + else parent << this; if (producer) { // Data has a specific producer, we can narrow the required diff --git a/source/Unit-Seek.inl b/source/Unit-Seek.inl index 022f701..8383394 100644 --- a/source/Unit-Seek.inl +++ b/source/Unit-Seek.inl @@ -13,6 +13,16 @@ namespace Langulus::A { + /// Find a specific unit, searching into the hierarchy + /// @tparam SEEK - where in the hierarchy are we seeking in? + /// @param meta - the unit to seek for + /// @param offset - which of the matches to return + /// @return the found unit, or nullptr if no such unit was found + template LANGULUS(INLINED) + Unit* Unit::SeekUnit(DMeta meta, Index offset) { + return mOwners.template SeekUnit(meta, offset); + } + /// Find a unit by type and index from the hierarchy /// @tparam SEEK - where to seek for the unit /// @param aux - descriptor to search through @@ -20,7 +30,7 @@ namespace Langulus::A /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - Unit* Unit::SeekUnitAux(const Many& aux, DMeta meta, Index offset) { + Unit* Unit::SeekUnitAux(const Neat& aux, DMeta meta, Index offset) { return mOwners.template SeekUnitAux(aux, meta, offset); } @@ -31,7 +41,7 @@ namespace Langulus::A /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - Unit* Unit::SeekUnitExt(DMeta type, const Many& ext, Index offset) { + Unit* Unit::SeekUnitExt(DMeta type, const Neat& ext, Index offset) { return mOwners.template SeekUnitExt(type, ext, offset); } @@ -44,10 +54,20 @@ namespace Langulus::A /// @param offset - the index of the unit to return /// @return a pointer to the found unit, or nullptr if not found template LANGULUS(INLINED) - Unit* Unit::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) { + Unit* Unit::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) { return mOwners.template SeekUnitAuxExt(type, aux, ext, offset); } + /// Find a trait by type (and index), searching into the hierarchy + /// @tparam SEEK - direction to search at + /// @param meta - the trait to search for + /// @param offset - the offset to apply + /// @return the trait, which is not empty, if trait was found + template LANGULUS(INLINED) + Langulus::Trait Unit::SeekTrait(TMeta meta, Index offset) { + return mOwners.template SeekTrait(meta, offset); + } + /// Find a trait, searching into the hierarchy (const) /// @tparam SEEK - direction to search at /// @param aux - descriptor to search through @@ -55,10 +75,23 @@ namespace Langulus::A /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - Langulus::Trait Unit::SeekTraitAux(const Many& aux, TMeta meta, Index offset) { + Langulus::Trait Unit::SeekTraitAux(const Neat& aux, TMeta meta, Index offset) { return mOwners.template SeekTraitAux(aux, meta, offset); } + /// Find a trait by type (and index) from the hierarchy, and attempt + /// converting it to a desired output type + /// Supports pinnable outputs, and won't change anything if D is pinned + /// @tparam SEEK - direction to search at + /// @param meta - the trait type to search for + /// @param output - [out] the output + /// @param offset - the number of the matching trait to use + /// @return true if output was rewritten + template LANGULUS(INLINED) + bool Unit::SeekValue(TMeta meta, CT::Data auto& output, Index offset) const { + return mOwners.template SeekValue(meta, output, offset); + } + /// Find a trait by type (and index) from the hierarchy, and attempt /// converting it to a desired output type. Scan the aux container first /// Supports pinnable outputs, and pinnables will be pinned if trait was @@ -70,7 +103,7 @@ namespace Langulus::A /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - bool Unit::SeekValueAux(TMeta meta, const Many& aux, CT::Data auto& output, Index offset) const { + bool Unit::SeekValueAux(TMeta meta, const Neat& aux, CT::Data auto& output, Index offset) const { return mOwners.template SeekValueAux(meta, aux, output, offset); } diff --git a/source/Unit.cpp b/source/Unit.cpp index 58694a6..6a7ab7c 100644 --- a/source/Unit.cpp +++ b/source/Unit.cpp @@ -12,8 +12,6 @@ using namespace Langulus::A; - -/// Unit destructor decouples from any owners Unit::~Unit() { for (auto entity : mOwners) Decouple(entity); @@ -29,11 +27,11 @@ void Unit::Select(Flow::Verb& verb) { /// Check if this unit has a given set of properties /// @param descriptor - descriptor with required properties /// @return true if the unit has the given properties -bool Unit::CompareDescriptor(const Many& descriptor) const { +bool Unit::CompareDescriptor(const Neat& descriptor) const { // First we compare traits only, all of them must be present bool mismatch = false; Offset memberOffset = 0; - descriptor.ForEachDeep([&](const Anyness::Trait& trait) { + descriptor.ForEach([&](const Anyness::Trait& trait) { if (not GetMember(trait.GetTrait(), memberOffset) .Compare(static_cast(trait))) { mismatch = true; @@ -45,9 +43,9 @@ bool Unit::CompareDescriptor(const Many& descriptor) const { }); // Then we run another check, based on data types, again, all - // of them must be present, either as trait, or in other form + // of them must be present, either in trait, or in other form memberOffset = 0; - descriptor.ForEachDeep([&](const Many& anythingElse) { + descriptor.ForEachTail([&](const Many& anythingElse) { if (not GetMember(TMeta {}, memberOffset).Compare(anythingElse)) { mismatch = true; return Loop::Break; @@ -62,7 +60,7 @@ bool Unit::CompareDescriptor(const Many& descriptor) const { /// Get the list of unit owners /// @return the owners -auto Unit::GetOwners() const noexcept -> const Hierarchy& { +const Hierarchy& Unit::GetOwners() const noexcept { return mOwners; } @@ -73,29 +71,24 @@ void Unit::Refresh() {} /// @attention assumes units are correctly coupled and coupling to /// different runtimes should be explicitly disallowed /// @return a pointer to the runtime, if available -auto Unit::GetRuntime() const noexcept -> Runtime* { +Runtime* Unit::GetRuntime() const noexcept { if (not mOwners) return nullptr; return &*mOwners[0]->GetRuntime(); } -/// Couple the component with an entity extracted from a descriptor's +/// Couple the component with an entity, extracted from a descriptor's /// Traits::Parent, if any was defined (always two-sided) /// This will call refresh to all units in that entity on next tick /// @param desc - the descriptor to scan for parents -/// @param fallback - a fallback Thing to couple to (optional) -/// This usually comes from the producer's context. For example, if you -/// don't provide a parent for the renderer, it will be instantiated as -/// a child to the graphics module owner (i.e. the runtime owner) -void Unit::Couple(const Many& desc, const Thing* fallback) { +void Unit::Couple(const Neat& desc) { + // Couple any Thing provided in the descriptor const Thing* owner = nullptr; if (not desc.ExtractTrait(owner)) desc.ExtractData(owner); if (owner and mOwners.Merge(IndexBack, const_cast(owner))) const_cast(owner)->AddUnit(this); - else if (fallback) - const_cast(fallback)->AddUnit(this); } /// Decouple the component from an entity (always two-sided) diff --git a/source/Unit.hpp b/source/Unit.hpp index edec2b8..f06f30b 100644 --- a/source/Unit.hpp +++ b/source/Unit.hpp @@ -63,9 +63,9 @@ namespace Langulus::A virtual void Refresh(); - auto GetRuntime() const noexcept -> Runtime*; - auto GetOwners() const noexcept -> const Hierarchy&; - bool CompareDescriptor(const Many&) const; + Runtime* GetRuntime() const noexcept; + const Hierarchy& GetOwners() const noexcept; + bool CompareDescriptor(const Neat&) const; /// /// Flow @@ -76,24 +76,33 @@ namespace Langulus::A /// /// Seek /// + using SeekInterface::SeekUnit; using SeekInterface::SeekUnitAux; using SeekInterface::SeekUnitExt; using SeekInterface::SeekUnitAuxExt; + using SeekInterface::SeekTrait; using SeekInterface::SeekTraitAux; + using SeekInterface::SeekValue; using SeekInterface::SeekValueAux; - template NOD() - auto SeekUnitAux(const Many&, DMeta, Index = 0) -> Unit*; - template NOD() - auto SeekUnitExt(DMeta, const Many&, Index = 0) -> Unit*; - template NOD() - auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) -> Unit*; + template + NOD() Unit* SeekUnit(DMeta, Index = 0); + template + NOD() Unit* SeekUnitAux(const Neat&, DMeta, Index = 0); + template + NOD() Unit* SeekUnitExt(DMeta, const Neat&, Index = 0); + template + NOD() Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0); - template NOD() - auto SeekTraitAux(const Many&, TMeta, Index = 0) -> Langulus::Trait; + template + NOD() Langulus::Trait SeekTrait(TMeta, Index = 0); + template + NOD() Langulus::Trait SeekTraitAux(const Neat&, TMeta, Index = 0); template - bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = 0) const; + bool SeekValue(TMeta, CT::Data auto&, Index = 0) const; + template + bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = 0) const; /// /// Gather @@ -102,19 +111,19 @@ namespace Langulus::A using SeekInterface::GatherUnitsExt; using SeekInterface::GatherTraits; - template NOD() - auto GatherUnits(DMeta) -> TMany; - template NOD() - auto GatherUnitsExt(DMeta, const Many&) -> TMany; + template + NOD() TMany GatherUnits(DMeta); + template + NOD() TMany GatherUnitsExt(DMeta, const Neat&); - template NOD() - auto GatherTraits(TMeta) -> TraitList; + template + NOD() TraitList GatherTraits(TMeta); - template NOD() - auto GatherValues() const -> TMany; + template + NOD() TMany GatherValues() const; protected: - void Couple(const Many&, const Thing* fallback = nullptr); + void Couple(const Neat&); void Decouple(const Thing*); void ReplaceOwner(const Thing*, const Thing*); }; From e2f0fa51c40be2a1f7b01c1a2ee8e124324afd24 Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Thu, 10 Oct 2024 11:27:58 +0300 Subject: [PATCH 18/34] Better take on the maintenancy thingy --- source/Hierarchy-Seek.inl | 88 +++++++-------- source/Hierarchy.hpp | 218 +++++++++++++++++++------------------- source/Thing-Seek.inl | 24 ++--- source/Thing-Traits.cpp | 24 ++--- source/Thing.cpp | 76 ++++++------- source/Thing.hpp | 138 +++++++++++------------- source/Thing.inl | 6 +- source/Unit-Seek.inl | 14 +-- source/Unit.cpp | 25 +++-- source/Unit.hpp | 50 ++++----- 10 files changed, 331 insertions(+), 332 deletions(-) diff --git a/source/Hierarchy-Seek.inl b/source/Hierarchy-Seek.inl index 319685a..9581a9d 100644 --- a/source/Hierarchy-Seek.inl +++ b/source/Hierarchy-Seek.inl @@ -24,19 +24,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - const A::Unit* TME()::SeekUnit(DMeta type, Index offset) const { + auto TME()::SeekUnit(DMeta type, Index offset) const -> const A::Unit* { return const_cast(static_cast(this)) ->template SeekUnit(type, offset); } TEMPLATE() template LANGULUS(INLINED) - Decay* TME()::SeekUnit(Index offset) { + auto TME()::SeekUnit(Index offset) -> Decay* { return dynamic_cast*>(static_cast(this) ->template SeekUnit(MetaDataOf>(), offset)); } TEMPLATE() template LANGULUS(INLINED) - const Decay* TME()::SeekUnit(Index offset) const { + auto TME()::SeekUnit(Index offset) const -> const Decay* { return const_cast(this) ->template SeekUnit(offset); } @@ -49,19 +49,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - const A::Unit* TME()::SeekUnitAux(const Neat& aux, DMeta type, Index offset) const { + auto TME()::SeekUnitAux(const Many& aux, DMeta type, Index offset) const -> const A::Unit* { return const_cast(static_cast(this)) ->template SeekUnitAux(aux, type, offset); } TEMPLATE() template LANGULUS(INLINED) - Decay* TME()::SeekUnitAux(const Neat& aux, Index offset) { + auto TME()::SeekUnitAux(const Many& aux, Index offset) -> Decay* { return dynamic_cast*>(static_cast(this) ->template SeekUnitAux(aux, MetaDataOf>(), offset)); } TEMPLATE() template LANGULUS(INLINED) - const Decay* TME()::SeekUnitAux(const Neat& aux, Index offset) const { + auto TME()::SeekUnitAux(const Many& aux, Index offset) const -> const Decay* { return const_cast(this) ->template SeekUnitAux(aux, offset); } @@ -73,19 +73,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - const A::Unit* TME()::SeekUnitExt(DMeta type, const Neat& ext, Index offset) const { + auto TME()::SeekUnitExt(DMeta type, const Many& ext, Index offset) const -> const A::Unit* { return const_cast(static_cast(this)) ->template SeekUnitExt(type, ext, offset); } TEMPLATE() template LANGULUS(INLINED) - Decay* TME()::SeekUnitExt(const Neat& ext, Index offset) { + auto TME()::SeekUnitExt(const Many& ext, Index offset) -> Decay* { return dynamic_cast*>(static_cast(this) ->template SeekUnitExt(MetaDataOf>(), ext, offset)); } TEMPLATE() template LANGULUS(INLINED) - const Decay* TME()::SeekUnitExt(const Neat& ext, Index offset) const { + auto TME()::SeekUnitExt(const Many& ext, Index offset) const -> const Decay* { return const_cast(this) ->template SeekUnitExt(ext, offset); } @@ -99,19 +99,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - const A::Unit* TME()::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) const { + auto TME()::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) const -> const A::Unit* { return const_cast(static_cast(this)) ->template SeekUnitAuxExt(type, aux, ext, offset); } TEMPLATE() template LANGULUS(INLINED) - Decay* TME()::SeekUnitAuxExt(const Neat& aux, const Neat& ext, Index offset) { + auto TME()::SeekUnitAuxExt(const Many& aux, const Many& ext, Index offset) -> Decay* { return dynamic_cast*>(static_cast(this) ->template SeekUnitAuxExt(MetaDataOf>(), aux, ext, offset)); } TEMPLATE() template LANGULUS(INLINED) - const Decay* TME()::SeekUnitAuxExt(const Neat& aux, const Neat& ext, Index offset) const { + auto TME()::SeekUnitAuxExt(const Many& aux, const Many& ext, Index offset) const -> const Decay* { return const_cast(this) ->template SeekUnitAuxExt(aux, ext, offset); } @@ -122,19 +122,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTrait(TMeta type, Index offset) const { + auto TME()::SeekTrait(TMeta type, Index offset) const -> Trait { return const_cast(static_cast(this)) ->template SeekTrait(type, offset); } TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTrait(Index offset) { + auto TME()::SeekTrait(Index offset) -> Trait { return static_cast(this) ->template SeekTrait(MetaTraitOf(), offset); } TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTrait(Index offset) const { + auto TME()::SeekTrait(Index offset) const -> Trait { return const_cast(this) ->template SeekTrait(offset); } @@ -146,19 +146,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTraitAux(const Neat& aux, TMeta type, Index offset) const { + auto TME()::SeekTraitAux(const Many& aux, TMeta type, Index offset) const -> Trait { return const_cast(static_cast(this)) ->template SeekTraitAux(aux, type, offset); } TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTraitAux(const Neat& aux, Index offset) { + auto TME()::SeekTraitAux(const Many& aux, Index offset) -> Trait { return static_cast(this) ->template SeekTraitAux(aux, MetaTraitOf(), offset); } TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTraitAux(const Neat& aux, Index offset) const { + auto TME()::SeekTraitAux(const Many& aux, Index offset) const -> Trait { return const_cast(this) ->template SeekTraitAux(aux, offset); } @@ -172,7 +172,7 @@ namespace Langulus::Entity } TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValueAux(const Neat& aux, CT::NotTagged auto& output, Index offset) const { + bool TME()::SeekValueAux(const Many& aux, CT::NotTagged auto& output, Index offset) const { return static_cast(this) ->template SeekValueAux(MetaTraitOf(), aux, output, offset); } @@ -190,7 +190,7 @@ namespace Langulus::Entity } TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValueAux(const Neat& aux, CT::Tagged auto& output, Index offset) const { + bool TME()::SeekValueAux(const Many& aux, CT::Tagged auto& output, Index offset) const { using T = Deref; auto lambda = [&]() { return static_cast(this)->template @@ -207,43 +207,43 @@ namespace Langulus::Entity /// Available only when managed reflection is enabled /// TEMPLATE() template LANGULUS(INLINED) - A::Unit* TME()::SeekUnit(const Token& dataToken, Index offset) { + auto TME()::SeekUnit(const Token& dataToken, Index offset) -> A::Unit* { return static_cast(this) ->template SeekUnit(RTTI::GetMetaData(dataToken), offset); } TEMPLATE() template LANGULUS(INLINED) - const A::Unit* TME()::SeekUnit(const Token& dataToken, Index offset) const { + auto TME()::SeekUnit(const Token& dataToken, Index offset) const -> const A::Unit* { return static_cast(this) ->template SeekUnit(RTTI::GetMetaData(dataToken), offset); } TEMPLATE() template LANGULUS(INLINED) - A::Unit* TME()::SeekUnitAux(const Neat& aux, const Token& dataToken, Index offset) { + auto TME()::SeekUnitAux(const Many& aux, const Token& dataToken, Index offset) -> A::Unit* { return static_cast(this) ->template SeekUnitAux(aux, RTTI::GetMetaData(dataToken), offset); } TEMPLATE() template LANGULUS(INLINED) - const A::Unit* TME()::SeekUnitAux(const Neat& aux, const Token& dataToken, Index offset) const { + auto TME()::SeekUnitAux(const Many& aux, const Token& dataToken, Index offset) const -> const A::Unit* { return static_cast(this) ->template SeekUnitAux(aux, RTTI::GetMetaData(dataToken), offset); } TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTrait(const Token& traitToken, Index offset) { + auto TME()::SeekTrait(const Token& traitToken, Index offset) -> Trait { return static_cast(this) ->template SeekTrait(RTTI::GetMetaTrait(traitToken), offset); } TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTrait(const Token& traitToken, Index offset) const { + auto TME()::SeekTrait(const Token& traitToken, Index offset) const -> Trait { return static_cast(this) ->template SeekTrait(RTTI::GetMetaTrait(traitToken), offset); } TEMPLATE() template LANGULUS(INLINED) - Trait TME()::SeekTraitAux(const Neat& aux, const Token& traitToken, Index offset) const { + auto TME()::SeekTraitAux(const Many& aux, const Token& traitToken, Index offset) const -> Trait { return static_cast(this) ->template SeekTraitAux(aux, RTTI::GetMetaTrait(traitToken), offset); } @@ -255,7 +255,7 @@ namespace Langulus::Entity } TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValueAux(const Token& traitToken, const Neat& aux, CT::Data auto& output, Index offset) const { + bool TME()::SeekValueAux(const Token& traitToken, const Many& aux, CT::Data auto& output, Index offset) const { return static_cast(this) ->template SeekValueAux(RTTI::GetMetaTrait(traitToken), aux, output, offset); } @@ -276,7 +276,7 @@ namespace Langulus::Entity /// @param offset - which of the matches to return /// @return the found unit, or nullptr if no such unit was found template LANGULUS(INLINED) - A::Unit* Hierarchy::SeekUnit(DMeta meta, Index offset) { + auto Hierarchy::SeekUnit(DMeta meta, Index offset) -> A::Unit* { for (auto owner : *this) { A::Unit* result = owner->template SeekUnit(meta, offset); if (result) @@ -294,8 +294,8 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - A::Unit* Hierarchy::SeekUnitAux(const Neat& aux, DMeta meta, Index offset) { - const A::Unit* result {}; + auto Hierarchy::SeekUnitAux(const Many& aux, DMeta meta, Index offset) -> A::Unit* { + const A::Unit* result = nullptr; // Scan descriptor even if hierarchy is empty if constexpr (SEEK & Seek::Here) { @@ -320,9 +320,8 @@ namespace Langulus::Entity // If reached, then no unit was found in the descriptor // Let's delve into the hierarchy, by scanning for Traits::Parent // and Traits::Child inside the 'aux' - //return SeekValue(meta, output, offset); if constexpr (SEEK & Seek::Above) { - aux.ForEachTrait([&](const Traits::Parent& trait) -> LoopControl { + aux.ForEachDeep([&](const Traits::Parent& trait) -> LoopControl { trait.ForEach([&](const Thing& parent) { if (nullptr != (result = parent.SeekUnit(meta, offset))) // Value was found @@ -334,7 +333,7 @@ namespace Langulus::Entity } if constexpr (SEEK & Seek::Below) { - aux.ForEachTrait([&](const Traits::Child& trait) -> LoopControl { + aux.ForEachDeep([&](const Traits::Child& trait) -> LoopControl { trait.ForEach([&](const Thing& child) { if (nullptr != (result = child.SeekUnit(meta, offset))) // Value was found @@ -355,7 +354,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - A::Unit* Hierarchy::SeekUnitExt(DMeta type, const Neat& ext, Index offset) { + auto Hierarchy::SeekUnitExt(DMeta type, const Many& ext, Index offset) -> A::Unit* { for (auto owner : *this) { A::Unit* result = owner->template SeekUnitExt(type, ext, offset); if (result) @@ -374,9 +373,9 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return a pointer to the found unit, or nullptr if not found template LANGULUS(INLINED) - A::Unit* Hierarchy::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) { + auto Hierarchy::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) -> A::Unit* { // Scan descriptor even if hierarchy is empty - A::Unit* result {}; + A::Unit* result = nullptr; aux.ForEachDeep([&](const A::Unit* u) { if (u->CastsTo(type)) { //TODO check construct arguments @@ -406,7 +405,7 @@ namespace Langulus::Entity /// @param offset - the offset to apply /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - Trait Hierarchy::SeekTrait(TMeta meta, Index offset) { + auto Hierarchy::SeekTrait(TMeta meta, Index offset) -> Trait { for (auto owner : *this) { auto result = owner->template SeekTrait(meta, offset); if (result) @@ -423,7 +422,7 @@ namespace Langulus::Entity /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - Trait Hierarchy::SeekTraitAux(const Neat& aux, TMeta meta, Index offset) { + auto Hierarchy::SeekTraitAux(const Many& aux, TMeta meta, Index offset) -> Trait { // Scan descriptor Trait result; aux.ForEachDeep([&](const Trait& trait) { @@ -489,7 +488,7 @@ namespace Langulus::Entity /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - bool Hierarchy::SeekValueAux(TMeta meta, const Neat& aux, CT::Data auto& output, Index offset) const { + bool Hierarchy::SeekValueAux(TMeta meta, const Many& aux, CT::Data auto& output, Index offset) const { using D = Deref; if constexpr (CT::Pinnable) { @@ -502,7 +501,7 @@ namespace Langulus::Entity if constexpr (SEEK & Seek::Here) { bool done = false; if (meta) { - aux.ForEachTrait([&](const Trait& trait) -> LoopControl { + aux.ForEachDeep([&](const Trait& trait) -> LoopControl { if (trait.IsTrait(meta)) { // Found match try { @@ -568,10 +567,9 @@ namespace Langulus::Entity // If reached, then no trait was found in the descriptor // Let's delve into the hierarchy, by scanning for Traits::Parent // and Traits::Child inside the 'aux' - //return SeekValue(meta, output, offset); bool done = false; if constexpr (SEEK & Seek::Above) { - aux.ForEachTrait([&](const Traits::Parent& trait) -> LoopControl { + aux.ForEachDeep([&](const Traits::Parent& trait) -> LoopControl { trait.ForEach([&](const Thing& parent) { if (parent.SeekValue(meta, output, offset)) { // Value was found @@ -580,12 +578,13 @@ namespace Langulus::Entity } return Loop::Continue; }); + return not done; }); } if constexpr (SEEK & Seek::Below) { - aux.ForEachTrait([&](const Traits::Child& trait) -> LoopControl { + aux.ForEachDeep([&](const Traits::Child& trait) -> LoopControl { trait.ForEach([&](const Thing& child) { if (child.SeekValue(meta, output, offset)) { // Value was found @@ -594,6 +593,7 @@ namespace Langulus::Entity } return Loop::Continue; }); + return not done; }); } diff --git a/source/Hierarchy.hpp b/source/Hierarchy.hpp index 00eae87..22d28fe 100644 --- a/source/Hierarchy.hpp +++ b/source/Hierarchy.hpp @@ -34,6 +34,7 @@ namespace Langulus::Entity /// /// Can't use virtuals, because we want these to be template functions, /// so that we retain the most of the static optimizations + /// TODO generalize these when deduce-this has been implemented well /// /*template NOD() Unit* SeekUnit(DMeta, Index = IndexFirst) = delete; @@ -71,82 +72,83 @@ namespace Langulus::Entity /// The rest of these functions are defined for every SeekInterface /// They all use static_cast(this) as execution context for the /// above functions, which should be defined in THIS + /// TODO generalize these when deduce-this has been implemented well /// - template - NOD() const A::Unit* SeekUnit(DMeta, Index = 0) const; - template - NOD() Decay* SeekUnit(Index = 0); - template - NOD() const Decay* SeekUnit(Index = 0) const; - - template - NOD() const A::Unit* SeekUnitAux(const Neat&, DMeta, Index = 0) const; - template - NOD() Decay* SeekUnitAux(const Neat&, Index = 0); - template - NOD() const Decay* SeekUnitAux(const Neat&, Index = 0) const; - - template - NOD() const A::Unit* SeekUnitExt(DMeta, const Neat&, Index = 0) const; - template - NOD() Decay* SeekUnitExt(const Neat&, Index = 0); - template - NOD() const Decay* SeekUnitExt(const Neat&, Index = 0) const; - - template - NOD() const A::Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0) const; - template - NOD() Decay* SeekUnitAuxExt(const Neat&, const Neat&, Index = 0); - template - NOD() const Decay* SeekUnitAuxExt(const Neat&, const Neat&, Index = 0) const; - - template - NOD() Trait SeekTrait(TMeta, Index = 0) const; - template - NOD() Trait SeekTrait(Index = 0); - template - NOD() Trait SeekTrait(Index = 0) const; - - template - NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = 0) const; - template - NOD() Trait SeekTraitAux(const Neat&, Index = 0); - template - NOD() Trait SeekTraitAux(const Neat&, Index = 0) const; + template NOD() + auto SeekUnit(DMeta, Index = 0) const -> const A::Unit*; + template NOD() + auto SeekUnit(Index = 0) -> Decay*; + template NOD() + auto SeekUnit(Index = 0) const -> const Decay*; + + template NOD() + auto SeekUnitAux(const Many&, DMeta, Index = 0) const -> const A::Unit*; + template NOD() + auto SeekUnitAux(const Many&, Index = 0) -> Decay*; + template NOD() + auto SeekUnitAux(const Many&, Index = 0) const -> const Decay*; + + template NOD() + auto SeekUnitExt(DMeta, const Many&, Index = 0) const -> const A::Unit*; + template NOD() + auto SeekUnitExt(const Many&, Index = 0) -> Decay*; + template NOD() + auto SeekUnitExt(const Many&, Index = 0) const -> const Decay*; + + template NOD() + auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) const -> const A::Unit*; + template NOD() + auto SeekUnitAuxExt(const Many&, const Many&, Index = 0) -> Decay*; + template NOD() + auto SeekUnitAuxExt(const Many&, const Many&, Index = 0) const -> const Decay*; + + template NOD() + auto SeekTrait(TMeta, Index = 0) const -> Trait; + template NOD() + auto SeekTrait(Index = 0) -> Trait; + template NOD() + auto SeekTrait(Index = 0) const -> Trait; + + template NOD() + auto SeekTraitAux(const Many&, TMeta, Index = 0) const -> Trait; + template NOD() + auto SeekTraitAux(const Many&, Index = 0) -> Trait; + template NOD() + auto SeekTraitAux(const Many&, Index = 0) const -> Trait; template bool SeekValue(CT::NotTagged auto&, Index = IndexFirst) const; template - bool SeekValueAux(const Neat&, CT::NotTagged auto&, Index = 0) const; + bool SeekValueAux(const Many&, CT::NotTagged auto&, Index = 0) const; template bool SeekValue(CT::Tagged auto&, Index = IndexFirst) const; template - bool SeekValueAux(const Neat&, CT::Tagged auto&, Index = 0) const; + bool SeekValueAux(const Many&, CT::Tagged auto&, Index = 0) const; - template - NOD() TMany GatherUnits(DMeta) const; - template - NOD() TMany GatherUnits(); - template - NOD() TMany GatherUnits() const; + template NOD() + auto GatherUnits(DMeta) const -> TMany ; + template NOD() + auto GatherUnits() -> TMany; + template NOD() + auto GatherUnits() const -> TMany; - template - NOD() TMany GatherUnitsExt(DMeta, const Neat&) const; - template - NOD() TMany GatherUnitsExt(const Neat&); - template - NOD() TMany GatherUnitsExt(const Neat&) const; + template NOD() + auto GatherUnitsExt(DMeta, const Many&) const -> TMany; + template NOD() + auto GatherUnitsExt(const Many&) -> TMany; + template NOD() + auto GatherUnitsExt(const Many&) const -> TMany; - template - NOD() TraitList GatherTraits(TMeta) const; - template - NOD() TraitList GatherTraits(); - template - NOD() TraitList GatherTraits() const; + template NOD() + auto GatherTraits(TMeta) const -> TraitList; + template NOD() + auto GatherTraits() -> TraitList; + template NOD() + auto GatherTraits() const -> TraitList; #if LANGULUS_FEATURE(MANAGED_REFLECTION) @@ -154,41 +156,41 @@ namespace Langulus::Entity /// Token based interface /// Available only when managed reflection is enabled /// - template - NOD() A::Unit* SeekUnit(const Token&, Index = 0); - template - NOD() const A::Unit* SeekUnit(const Token&, Index = 0) const; - - template - NOD() A::Unit* SeekUnitAux(const Neat&, const Token&, Index = 0); - template - NOD() const A::Unit* SeekUnitAux(const Neat&, const Token&, Index = 0) const; + template NOD() + auto SeekUnit(const Token&, Index = 0) -> A::Unit*; + template NOD() + auto SeekUnit(const Token&, Index = 0) const -> const A::Unit*; + + template NOD() + auto SeekUnitAux(const Many&, const Token&, Index = 0) -> A::Unit*; + template NOD() + auto SeekUnitAux(const Many&, const Token&, Index = 0) const -> const A::Unit*; - template - NOD() Trait SeekTrait(const Token&, Index = 0); - template - NOD() Trait SeekTrait(const Token&, Index = 0) const; + template NOD() + auto SeekTrait(const Token&, Index = 0) -> Trait; + template NOD() + auto SeekTrait(const Token&, Index = 0) const -> Trait; - template - NOD() Trait SeekTraitAux(const Neat&, const Token&, Index = 0); - template - NOD() Trait SeekTraitAux(const Neat&, const Token&, Index = 0) const; + template NOD() + auto SeekTraitAux(const Many&, const Token&, Index = 0) -> Trait; + template NOD() + auto SeekTraitAux(const Many&, const Token&, Index = 0) const -> Trait; template bool SeekValue(const Token&, CT::Data auto&, Index = 0) const; template - bool SeekValueAux(const Token&, const Neat&, CT::Data auto&, Index = 0) const; + bool SeekValueAux(const Token&, const Many&, CT::Data auto&, Index = 0) const; - template - NOD() TMany GatherUnits(const Token&); - template - NOD() TMany GatherUnits(const Token&) const; + template NOD() + auto GatherUnits(const Token&) -> TMany; + template NOD() + auto GatherUnits(const Token&) const -> TMany; - template - NOD() TraitList GatherTraits(const Token&); - template - NOD() TraitList GatherTraits(const Token&) const; + template NOD() + auto GatherTraits(const Token&) -> TraitList; + template NOD() + auto GatherTraits(const Token&) const -> TraitList; #endif }; @@ -219,24 +221,24 @@ namespace Langulus::Entity using SeekInterface::SeekValue; using SeekInterface::SeekValueAux; - template - NOD() A::Unit* SeekUnit(DMeta, Index = 0); - template - NOD() A::Unit* SeekUnitAux(const Neat&, DMeta, Index = 0); - template - NOD() A::Unit* SeekUnitExt(DMeta, const Neat&, Index = 0); - template - NOD() A::Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0); + template NOD() + auto SeekUnit(DMeta, Index = 0) -> A::Unit*; + template NOD() + auto SeekUnitAux(const Many&, DMeta, Index = 0) -> A::Unit*; + template NOD() + auto SeekUnitExt(DMeta, const Many&, Index = 0) -> A::Unit*; + template NOD() + auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) -> A::Unit*; - template - NOD() Trait SeekTrait(TMeta, Index = 0); - template - NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = 0); + template NOD() + auto SeekTrait(TMeta, Index = 0) -> Trait; + template NOD() + auto SeekTraitAux(const Many&, TMeta, Index = 0) -> Trait; template bool SeekValue(TMeta, CT::Data auto&, Index = 0) const; template - bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = 0) const; + bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = 0) const; /// /// Gather @@ -245,16 +247,16 @@ namespace Langulus::Entity using SeekInterface::GatherUnitsExt; using SeekInterface::GatherTraits; - template - NOD() TMany GatherUnitsExt(DMeta, const Neat&); - template - NOD() TMany GatherUnits(DMeta); + template NOD() + auto GatherUnitsExt(DMeta, const Many&) -> TMany; + template NOD() + auto GatherUnits(DMeta) -> TMany; - template - NOD() TraitList GatherTraits(TMeta); + template NOD() + auto GatherTraits(TMeta) -> TraitList; - template - NOD() TMany GatherValues() const; + template NOD() + auto GatherValues() const -> TMany; }; } // namespace Langulus::Entity diff --git a/source/Thing-Seek.inl b/source/Thing-Seek.inl index b155c76..bbe0360 100644 --- a/source/Thing-Seek.inl +++ b/source/Thing-Seek.inl @@ -29,7 +29,7 @@ namespace Langulus::Entity /// @param offset - which of the matches to return /// @return the found unit, or nullptr if no such unit was found template - A::Unit* Thing::SeekUnit(DMeta meta, Index offset) { + auto Thing::SeekUnit(DMeta meta, Index offset) -> A::Unit* { A::Unit* result = nullptr; if constexpr (SEEK & Seek::Here) { // Seek here if requested @@ -69,7 +69,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - A::Unit* Thing::SeekUnitAux(const Neat& aux, DMeta meta, Index offset) { + auto Thing::SeekUnitAux(const Many& aux, DMeta meta, Index offset) -> A::Unit* { A::Unit* result {}; aux.ForEachDeep([&](const A::Unit* unit) { if (unit->CastsTo(meta)) { @@ -99,7 +99,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - A::Unit* Thing::SeekUnitExt(DMeta type, const Neat& ext, Index offset) { + auto Thing::SeekUnitExt(DMeta type, const Many& ext, Index offset) -> A::Unit* { A::Unit* result = nullptr; if constexpr (SEEK & Seek::Here) { // Seek here if requested @@ -139,7 +139,7 @@ namespace Langulus::Entity /// @param offset - the Nth match to return /// @return a pointer to the found unit, or nullptr if not found template LANGULUS(INLINED) - A::Unit* Thing::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) { + auto Thing::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) -> A::Unit* { // Scan descriptor even if hierarchy is empty A::Unit* result {}; aux.ForEachDeep([&](const A::Unit* unit) { @@ -170,7 +170,7 @@ namespace Langulus::Entity /// @param offset - the offset to apply /// @return the trait, which is not empty, if trait was found template - Trait Thing::SeekTrait(TMeta meta, Index offset) { + auto Thing::SeekTrait(TMeta meta, Index offset) -> Trait { if constexpr (SEEK & Seek::Here) { // Seek here if requested auto output = GetTrait(meta, offset); @@ -209,7 +209,7 @@ namespace Langulus::Entity /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - Trait Thing::SeekTraitAux(const Neat& aux, TMeta meta, Index offset) { + auto Thing::SeekTraitAux(const Many& aux, TMeta meta, Index offset) -> Trait { // Scan descriptor Trait result; aux.ForEachDeep([&](const Trait& trait) { @@ -264,10 +264,6 @@ namespace Langulus::Entity else output = temp.template AsCast(); - /*if constexpr (CT::Pinnable) - output = temp.template AsCast>(); - else - output = temp.template AsCast();*/ return true; } catch (...) { } @@ -305,7 +301,7 @@ namespace Langulus::Entity /// @return true if value has been found and rewritten template LANGULUS(INLINED) bool Thing::SeekValueAux( - TMeta meta, const Neat& aux, CT::Data auto& output, Index offset + TMeta meta, const Many& aux, CT::Data auto& output, Index offset ) const { using D = Deref; @@ -330,7 +326,7 @@ namespace Langulus::Entity // Didn't throw, but we're done only if offset matches done = offset == 0; --offset; - return not done; + return done ? Loop::Break : Loop::Continue; } catch (...) {} } @@ -350,9 +346,9 @@ namespace Langulus::Entity // Didn't throw, but we're done only if offset matches done = offset == 0; --offset; - return not done; + return done ? Loop::Break : Loop::Continue; } - catch(...) { } + catch(...) {} return Loop::Continue; }); diff --git a/source/Thing-Traits.cpp b/source/Thing-Traits.cpp index 2b5db03..c8fbd9d 100644 --- a/source/Thing-Traits.cpp +++ b/source/Thing-Traits.cpp @@ -29,7 +29,7 @@ namespace Langulus::Entity /// @param trait - trait id /// @param offset - offset of result to use /// @return a filled trait if fount, empty if not - Trait Thing::GetTrait(TMeta trait, Index offset) const { + auto Thing::GetTrait(TMeta trait, Index offset) const -> Trait { return GetTrait(Trait::FromMeta(trait, nullptr), offset); } @@ -37,7 +37,7 @@ namespace Langulus::Entity /// @param trait - trait id /// @param offset - offset of result to use /// @return a filled trait if fount, empty if not - Trait Thing::GetTrait(TMeta trait, Index offset) { + auto Thing::GetTrait(TMeta trait, Index offset) -> Trait { return GetTrait(Trait::FromMeta(trait, nullptr), offset); } @@ -45,7 +45,7 @@ namespace Langulus::Entity /// @param id - the trait to search for /// @param index - the index of the trait we seek /// @return a pointer to the trait, or nullptr if not found - Trait* Thing::GetLocalTrait(TMeta id, Index index) { + auto Thing::GetLocalTrait(TMeta id, Index index) -> Trait* { if (id) { // Search a typed trait const auto found = mTraits.FindIt(id); @@ -76,7 +76,7 @@ namespace Langulus::Entity /// @param id - the trait to search for /// @param offset - the index of the trait we seek /// @return a pointer to the trait, or nullptr if not found - const Trait* Thing::GetLocalTrait(TMeta id, Index offset) const { + auto Thing::GetLocalTrait(TMeta id, Index offset) const -> const Trait* { return const_cast(*this).GetLocalTrait(id, offset); } @@ -84,7 +84,7 @@ namespace Langulus::Entity /// @param id - trait to match /// @param index - offset of result to use /// @return a non-empty trait, if found - Trait Thing::GetTrait(const Trait& id, Index index) { + auto Thing::GetTrait(const Trait& id, Index index) -> Trait { if (id.GetTrait()) { // Handle some predefined traits here if (id.template IsTrait()) { @@ -124,14 +124,14 @@ namespace Langulus::Entity /// @param id - trait to match /// @param index - offset of result to use /// @return a non-empty trait, if found - Trait Thing::GetTrait(const Trait& id, Index index) const { + auto Thing::GetTrait(const Trait& id, Index index) const -> Trait { return const_cast(this)->GetTrait(id, index); } /// Add a new trait to the thing /// @param trait - trait to shallow copy /// @return the new trait instance - Trait* Thing::AddTrait(Trait trait) { + auto Thing::AddTrait(Trait trait) -> Trait* { const auto tmeta = trait.GetTrait(); auto found = mTraits.FindIt(tmeta); if (found) { @@ -148,7 +148,7 @@ namespace Langulus::Entity /// Remove a trait from the universal entity /// @param trait - type of trait to remove /// @return the number of removed traits - Count Thing::RemoveTrait(TMeta trait) { + auto Thing::RemoveTrait(TMeta trait) -> Count { const auto found = mTraits.FindIt(trait); if (found) { const auto removed = found.GetValue().GetCount(); @@ -164,7 +164,7 @@ namespace Langulus::Entity /// Remove an exact-matching trait from this entity /// @param trait - type and value to remove /// @return the number of removed traits - Count Thing::RemoveTrait(Trait trait) { + auto Thing::RemoveTrait(Trait trait) -> Count { const auto found = mTraits.FindIt(trait.GetTrait()); if (found) { const auto removed = found.GetValue().Remove(trait); @@ -181,7 +181,7 @@ namespace Langulus::Entity /// A fast check whether traits of the given type are inside this entity /// @param trait - type of trait to check /// @return the number of matching traits - Count Thing::HasTraits(TMeta trait) const { + auto Thing::HasTraits(TMeta trait) const -> Count { const auto found = mTraits.FindIt(trait); return found ? found.GetValue().GetCount() : 0; } @@ -189,7 +189,7 @@ namespace Langulus::Entity /// A fast check whether traits of the given type and value are inside /// @param trait - trait to search for /// @return the number of matching traits - Count Thing::HasTraits(const Trait& trait) const { + auto Thing::HasTraits(const Trait& trait) const -> Count { const auto found = mTraits.FindIt(trait.GetTrait()); if (not found) return 0; @@ -205,7 +205,7 @@ namespace Langulus::Entity /// Get traits /// @return the map of traits LANGULUS_API(ENTITY) - const TraitMap& Thing::GetTraits() const noexcept { + auto Thing::GetTraits() const noexcept -> const TraitMap& { return mTraits; } diff --git a/source/Thing.cpp b/source/Thing.cpp index 6cf98f8..73e52b3 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -54,9 +54,10 @@ namespace Langulus::Entity /// Construct as a child of another thing /// @param parent - the thing that owns this thing /// @param descriptor - instructions for creating the thing - Thing::Thing(Thing* parent, const Neat& descriptor) + Thing::Thing(Thing* parent, const Many& descriptor) : Resolvable {this} - , mOwner {parent} { + , mOwner {parent} + { if (parent) { parent->AddChild(this); mRuntime = parent->GetRuntime(); @@ -89,14 +90,15 @@ namespace Langulus::Entity /// because 'other' is removed from its children /// @param other - move that entity Thing::Thing(Thing&& other) noexcept - : Resolvable {this} - , mChildren {Move(other.mChildren)} - , mRuntime {Move(other.mRuntime)} - , mFlow {Move(other.mFlow)} + : Resolvable {this} + , mChildren {Move(other.mChildren)} + , mRuntime {Move(other.mRuntime)} + , mFlow {Move(other.mFlow)} , mUnitsAmbiguous {Move(other.mUnitsAmbiguous)} - , mUnitsList {Move(other.mUnitsList)} - , mTraits {Move(other.mTraits)} - , mRefreshRequired {true} { + , mUnitsList {Move(other.mUnitsList)} + , mTraits {Move(other.mTraits)} + , mRefreshRequired{true} + { // Remap children for (auto& child : mChildren) child->mOwner = this; @@ -118,14 +120,15 @@ namespace Langulus::Entity /// because 'other' is duplicated in its children /// @param other - clone that entity Thing::Thing(Abandoned&& other) - : Resolvable {this} - , mChildren {Abandon(other->mChildren)} - , mRuntime {Abandon(other->mRuntime)} - , mFlow {Abandon(other->mFlow)} + : Resolvable {this} + , mChildren {Abandon(other->mChildren)} + , mRuntime {Abandon(other->mRuntime)} + , mFlow {Abandon(other->mFlow)} , mUnitsAmbiguous {Abandon(other->mUnitsAmbiguous)} - , mUnitsList {Abandon(other->mUnitsList)} - , mTraits {Abandon(other->mTraits)} - , mRefreshRequired {true} { + , mUnitsList {Abandon(other->mUnitsList)} + , mTraits {Abandon(other->mTraits)} + , mRefreshRequired{true} + { // Remap children for (auto& child : mChildren) child->mOwner = this; @@ -147,9 +150,10 @@ namespace Langulus::Entity /// because 'other' is duplicated in its children /// @param other - clone that entity Thing::Thing(Cloned&& other) - : Resolvable {this} - , mChildren {Clone(other->mChildren)} - , mRefreshRequired {true} { + : Resolvable {this} + , mChildren {Clone(other->mChildren)} + , mRefreshRequired{true} + { TODO(); //TODO clone flow and runtime if pinned, recreate modules if new runtime, // recreate units and traits, then recreate children @@ -316,7 +320,7 @@ namespace Langulus::Entity /// @param id - the type of the unit /// @param index - the unit index to seek /// @return the unit if found, or nullptr if not - A::Unit* Thing::GetUnitMeta(DMeta id, Index index) { + auto Thing::GetUnitMeta(DMeta id, Index index) -> A::Unit* { if (id) { // Search a typed trait const auto found = mUnitsAmbiguous.FindIt(id); @@ -327,7 +331,7 @@ namespace Langulus::Entity return mUnitsList[index]; } - const A::Unit* Thing::GetUnitMeta(DMeta type, Index offset) const { + auto Thing::GetUnitMeta(DMeta type, Index offset) const -> const A::Unit* { return const_cast(this)->GetUnitMeta(type, offset); } @@ -338,7 +342,7 @@ namespace Langulus::Entity /// @param what - the desired properties of the unit /// @param index - the unit index to seek /// @return the unit if found, or nullptr if not - A::Unit* Thing::GetUnitExt(DMeta meta, const Neat& what, Index index) { + auto Thing::GetUnitExt(DMeta meta, const Many& what, Index index) -> A::Unit* { if (meta) { // Search a typed unit const auto found = mUnitsAmbiguous.FindIt(meta); @@ -371,7 +375,7 @@ namespace Langulus::Entity return nullptr; } - const A::Unit* Thing::GetUnitExt(DMeta meta, const Neat& what, Index index) const { + auto Thing::GetUnitExt(DMeta meta, const Many& what, Index index) const -> const A::Unit* { return const_cast(this)->GetUnitExt(meta, what, index); } @@ -380,31 +384,31 @@ namespace Langulus::Entity /// @param token - the type name of the unit /// @param offset - the unit index /// @return the unit if found, or nullptr if not - A::Unit* Thing::GetUnitMeta(const Token& token, Index offset) { + auto Thing::GetUnitMeta(const Token& token, Index offset) -> A::Unit* { return GetUnitMeta(RTTI::DisambiguateMeta(token), offset); } #endif /// Get the owner /// @return the owner - const Ref& Thing::GetOwner() const noexcept { + auto Thing::GetOwner() const noexcept -> const Ref& { return mOwner; } /// Get children hierarchy /// @return the hierarchy - const Hierarchy& Thing::GetChildren() const noexcept { + auto Thing::GetChildren() const noexcept -> const Hierarchy& { return mChildren; } /// Get a child by index /// @param id - the index to pick /// @return the child entity, or nullptr of none was found - Thing* Thing::GetChild(Index offset) { + auto Thing::GetChild(Index offset) -> Thing* { return mChildren[offset]; } - const Thing* Thing::GetChild(Index offset) const { + auto Thing::GetChild(Index offset) const -> const Thing* { return const_cast(this)->GetChild(offset); } @@ -412,7 +416,7 @@ namespace Langulus::Entity /// @param name - name to seek /// @param offset - offset to seek /// @return the child entity, or nullptr of none was found - Thing* Thing::GetNamedChild(const Token& name, Index offset) { + auto Thing::GetNamedChild(const Token& name, Index offset) -> Thing* { Index matches = 0; for (auto& child : mChildren) { if (child->GetName() == name) { @@ -425,7 +429,7 @@ namespace Langulus::Entity return nullptr; } - const Thing* Thing::GetNamedChild(const Token& name, Index offset) const { + auto Thing::GetNamedChild(const Token& name, Index offset) const -> const Thing* { return const_cast(this)->GetNamedChild(name, offset); } @@ -456,7 +460,7 @@ namespace Langulus::Entity /// Count the number of matching units in this entity /// @param type - the type of units to search for /// @return the number of matching units - Count Thing::HasUnits(DMeta type) const { + auto Thing::HasUnits(DMeta type) const -> Count { const auto found = mUnitsAmbiguous.FindIt(type); return found ? found.GetValue().GetCount() : 0; } @@ -469,19 +473,19 @@ namespace Langulus::Entity /// Get the current runtime /// @return the pointer to the runtime - const Pin>& Thing::GetRuntime() const noexcept { + auto Thing::GetRuntime() const noexcept -> const Pin>& { return mRuntime; } /// Get the current temporal flow /// @return the pointer to the flow - const Pin>& Thing::GetFlow() const noexcept { + auto Thing::GetFlow() const noexcept -> const Pin>& { return mFlow; } /// Create a local runtime for this thing /// @return the new runtime instance, or the old one if already created - Runtime* Thing::CreateRuntime() { + auto Thing::CreateRuntime() -> Runtime* { if (mRuntime.IsLocked()) return &*mRuntime; @@ -498,7 +502,7 @@ namespace Langulus::Entity /// Create a local flow for this thing /// @return the new flow instance, or the old one, if already created - Temporal* Thing::CreateFlow() { + auto Thing::CreateFlow() -> Temporal* { if (mFlow.IsLocked()) return &*mFlow; @@ -519,7 +523,7 @@ namespace Langulus::Entity /// @param module - name of the module /// @param descriptor - instructions for module setup /// @return the instantiated module interface - A::Module* Thing::LoadMod(const Token& module, const Neat& descriptor) { + auto Thing::LoadMod(const Token& module, const Many& descriptor) -> A::Module* { const auto runtime = GetRuntime(); LANGULUS_ASSUME(UserAssumes, runtime, "No runtime available for loading a module"); diff --git a/source/Thing.hpp b/source/Thing.hpp index 006c1ab..11706eb 100644 --- a/source/Thing.hpp +++ b/source/Thing.hpp @@ -77,7 +77,7 @@ namespace Langulus::Entity public: LANGULUS_API(ENTITY) Thing(); LANGULUS_API(ENTITY) Thing(Describe&&); - LANGULUS_API(ENTITY) Thing(Thing*, const Neat& = {}); + LANGULUS_API(ENTITY) Thing(Thing*, const Many& = {}); LANGULUS_API(ENTITY) Thing(Thing&&) noexcept; LANGULUS_API(ENTITY) Thing(Cloned&&); LANGULUS_API(ENTITY) Thing(Abandoned&&); @@ -98,10 +98,10 @@ namespace Langulus::Entity bool RequiresRefresh() const noexcept; NOD() LANGULUS_API(ENTITY) - const Pin>& GetRuntime() const noexcept; + auto GetRuntime() const noexcept -> const Pin>&; NOD() LANGULUS_API(ENTITY) - const Pin>& GetFlow() const noexcept; + auto GetFlow() const noexcept -> const Pin>&; LANGULUS_API(ENTITY) void Do(Verb&); LANGULUS_API(ENTITY) void Select(Verb&); @@ -130,13 +130,13 @@ namespace Langulus::Entity /// Hierarchy management /// LANGULUS_API(ENTITY) - Runtime* CreateRuntime(); + auto CreateRuntime() -> Runtime*; LANGULUS_API(ENTITY) - Temporal* CreateFlow(); + auto CreateFlow() -> Temporal*; template - Ref CreateChild(T&&...); + auto CreateChild(T&&...) -> Ref; template Count AddChild(Thing*); @@ -144,25 +144,25 @@ namespace Langulus::Entity Count RemoveChild(Thing*); LANGULUS_API(ENTITY) - A::Module* LoadMod(const Token&, const Neat& = {}); + auto LoadMod(const Token&, const Many& = {}) -> A::Module*; NOD() LANGULUS_API(ENTITY) - const Ref& GetOwner() const noexcept; + auto GetOwner() const noexcept -> const Ref&; NOD() LANGULUS_API(ENTITY) - const Hierarchy& GetChildren() const noexcept; + auto GetChildren() const noexcept -> const Hierarchy&; NOD() LANGULUS_API(ENTITY) - Thing* GetChild(Index = 0); + auto GetChild(Index = 0) -> Thing*; NOD() LANGULUS_API(ENTITY) - const Thing* GetChild(Index = 0) const; + auto GetChild(Index = 0) const -> const Thing*; NOD() LANGULUS_API(ENTITY) - Thing* GetNamedChild(const Token&, Index = 0); + auto GetNamedChild(const Token&, Index = 0) -> Thing*; NOD() LANGULUS_API(ENTITY) - const Thing* GetNamedChild(const Token&, Index = 0) const; + auto GetNamedChild(const Token&, Index = 0) const -> const Thing*; LANGULUS_API(ENTITY) void DumpHierarchy() const; @@ -176,13 +176,13 @@ namespace Langulus::Entity template Count RemoveUnit(A::Unit*); - template + template Many CreateUnit(A&&...); - template + template Many CreateUnits(); #if LANGULUS_FEATURE(MANAGED_REFLECTION) - template + template Many CreateUnitToken(const Token&, A&&...); #endif @@ -190,40 +190,38 @@ namespace Langulus::Entity Count RemoveUnits(); NOD() LANGULUS_API(ENTITY) - Count HasUnits(DMeta) const; - - template - NOD() Count HasUnits() const; + auto HasUnits(DMeta) const -> Count; + template NOD() + auto HasUnits() const -> Count; NOD() LANGULUS_API(ENTITY) - const UnitList& GetUnits() const noexcept; + auto GetUnits() const noexcept -> const UnitList&; NOD() LANGULUS_API(ENTITY) - const UnitMap& GetUnitsMap() const noexcept; + auto GetUnitsMap() const noexcept -> const UnitMap&; NOD() LANGULUS_API(ENTITY) - A::Unit* GetUnitMeta(DMeta, Index = 0); + auto GetUnitMeta(DMeta, Index = 0) -> A::Unit*; NOD() LANGULUS_API(ENTITY) - const A::Unit* GetUnitMeta(DMeta, Index = 0) const; + auto GetUnitMeta(DMeta, Index = 0) const -> const A::Unit*; NOD() LANGULUS_API(ENTITY) - A::Unit* GetUnitExt(DMeta, const Neat&, Index = 0); + auto GetUnitExt(DMeta, const Many&, Index = 0) -> A::Unit*; NOD() LANGULUS_API(ENTITY) - const A::Unit* GetUnitExt(DMeta, const Neat&, Index = 0) const; + auto GetUnitExt(DMeta, const Many&, Index = 0) const -> const A::Unit*; - template - NOD() Decay* GetUnit(Index = 0); - template - NOD() const Decay* GetUnit(Index = 0) const; + template NOD() + auto GetUnit(Index = 0) -> Decay*; + template NOD() + auto GetUnit(Index = 0) const -> const Decay*; #if LANGULUS_FEATURE(MANAGED_REFLECTION) NOD() LANGULUS_API(ENTITY) - A::Unit const* GetUnitMeta(const Token&, Index = 0) const; - + auto GetUnitMeta(const Token&, Index = 0) const -> A::Unit const*; NOD() LANGULUS_API(ENTITY) - A::Unit* GetUnitMeta(const Token&, Index = 0); + auto GetUnitMeta(const Token&, Index = 0) -> A::Unit*; - template - NOD() Decay* GetUnitAs(const Token&, Index = 0); + template NOD() + auto GetUnitAs(const Token&, Index = 0) -> Decay*; #endif private: @@ -234,45 +232,37 @@ namespace Langulus::Entity /// /// Trait management /// - LANGULUS_API(ENTITY) Trait* AddTrait(Trait); + LANGULUS_API(ENTITY) auto AddTrait(Trait) -> Trait*; LANGULUS_API(ENTITY) Count RemoveTrait(TMeta); LANGULUS_API(ENTITY) Count RemoveTrait(Trait); NOD() LANGULUS_API(ENTITY) Count HasTraits(TMeta) const; - NOD() LANGULUS_API(ENTITY) Count HasTraits(const Trait&) const; NOD() LANGULUS_API(ENTITY) - const TraitMap& GetTraits() const noexcept; - + auto GetTraits() const noexcept -> const TraitMap&; NOD() LANGULUS_API(ENTITY) - Trait GetTrait(TMeta, Index = 0) const; - + auto GetTrait(TMeta, Index = 0) const -> Trait; NOD() LANGULUS_API(ENTITY) - Trait GetTrait(TMeta, Index = 0); - + auto GetTrait(TMeta, Index = 0) -> Trait; NOD() LANGULUS_API(ENTITY) - Trait GetTrait(const Trait&, Index = 0) const; - + auto GetTrait(const Trait&, Index = 0) const -> Trait; NOD() LANGULUS_API(ENTITY) - Trait GetTrait(const Trait&, Index = 0); - - template - NOD() Trait GetTrait(Index = 0); + auto GetTrait(const Trait&, Index = 0) -> Trait; + template NOD() + auto GetTrait(Index = 0) -> Trait; NOD() LANGULUS_API(ENTITY) - const Trait* GetLocalTrait(TMeta, Index = 0) const; - + auto GetLocalTrait(TMeta, Index = 0) const -> const Trait*; NOD() LANGULUS_API(ENTITY) - Trait* GetLocalTrait(TMeta, Index = 0); - - template - NOD() Trait* GetLocalTrait(Index = 0); - template - NOD() Trait const* GetLocalTrait(Index = 0) const; + auto GetLocalTrait(TMeta, Index = 0) -> Trait*; + template NOD() + auto GetLocalTrait(Index = 0) -> Trait*; + template NOD() + auto GetLocalTrait(Index = 0) const -> Trait const*; LANGULUS_API(ENTITY) void SetName(const Text&); @@ -292,24 +282,24 @@ namespace Langulus::Entity using SeekInterface::SeekValue; using SeekInterface::SeekValueAux; - template - NOD() A::Unit* SeekUnit(DMeta, Index = 0); - template - NOD() A::Unit* SeekUnitAux(const Neat&, DMeta, Index = 0); - template - NOD() A::Unit* SeekUnitExt(DMeta, const Neat&, Index = 0); - template - NOD() A::Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0); + template NOD() + auto SeekUnit(DMeta, Index = 0) -> A::Unit*; + template NOD() + auto SeekUnitAux(const Many&, DMeta, Index = 0) -> A::Unit*; + template NOD() + auto SeekUnitExt(DMeta, const Many&, Index = 0) -> A::Unit*; + template NOD() + auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) -> A::Unit*; - template - NOD() Trait SeekTrait(TMeta, Index = 0); - template - NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = 0); + template NOD() + auto SeekTrait(TMeta, Index = 0) -> Trait; + template NOD() + auto SeekTraitAux(const Many&, TMeta, Index = 0) -> Trait; template bool SeekValue(TMeta, CT::Data auto&, Index = 0) const; template - bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = 0) const; + bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = 0) const; /// /// Gather @@ -319,15 +309,15 @@ namespace Langulus::Entity using SeekInterface::GatherTraits; template - NOD() TMany GatherUnits(DMeta); + auto GatherUnits(DMeta) -> TMany; template - NOD() TMany GatherUnitsExt(DMeta, const Neat&); + auto GatherUnitsExt(DMeta, const Many&) -> TMany; template - NOD() TraitList GatherTraits(TMeta); + auto GatherTraits(TMeta) -> TraitList; template - NOD() TMany GatherValues() const; + auto GatherValues() const -> TMany; }; } // namespace Langulus::Entity \ No newline at end of file diff --git a/source/Thing.inl b/source/Thing.inl index f872bf1..e159916 100644 --- a/source/Thing.inl +++ b/source/Thing.inl @@ -581,8 +581,8 @@ namespace Langulus::Entity // Implicitly add a parent trait to descriptor, if one isn't // already added - it will be stripped later, when normalizing // the descriptor when producing the item from a factory - Construct descriptor {construct}; - Traits::Parent parent; + Construct descriptor = construct; + /*Traits::Parent parent; if (not descriptor->ExtractTrait(parent)) { parent = this; parent.MakeMissing(); @@ -592,7 +592,7 @@ namespace Langulus::Entity Reference(0), " references)" ); } - else parent << this; + else parent << this;*/ if (producer) { // Data has a specific producer, we can narrow the required diff --git a/source/Unit-Seek.inl b/source/Unit-Seek.inl index 8383394..56d421a 100644 --- a/source/Unit-Seek.inl +++ b/source/Unit-Seek.inl @@ -19,7 +19,7 @@ namespace Langulus::A /// @param offset - which of the matches to return /// @return the found unit, or nullptr if no such unit was found template LANGULUS(INLINED) - Unit* Unit::SeekUnit(DMeta meta, Index offset) { + auto Unit::SeekUnit(DMeta meta, Index offset) -> Unit* { return mOwners.template SeekUnit(meta, offset); } @@ -30,7 +30,7 @@ namespace Langulus::A /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - Unit* Unit::SeekUnitAux(const Neat& aux, DMeta meta, Index offset) { + auto Unit::SeekUnitAux(const Many& aux, DMeta meta, Index offset) -> Unit* { return mOwners.template SeekUnitAux(aux, meta, offset); } @@ -41,7 +41,7 @@ namespace Langulus::A /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - Unit* Unit::SeekUnitExt(DMeta type, const Neat& ext, Index offset) { + auto Unit::SeekUnitExt(DMeta type, const Many& ext, Index offset) -> Unit* { return mOwners.template SeekUnitExt(type, ext, offset); } @@ -54,7 +54,7 @@ namespace Langulus::A /// @param offset - the index of the unit to return /// @return a pointer to the found unit, or nullptr if not found template LANGULUS(INLINED) - Unit* Unit::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) { + auto Unit::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) -> Unit* { return mOwners.template SeekUnitAuxExt(type, aux, ext, offset); } @@ -64,7 +64,7 @@ namespace Langulus::A /// @param offset - the offset to apply /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - Langulus::Trait Unit::SeekTrait(TMeta meta, Index offset) { + auto Unit::SeekTrait(TMeta meta, Index offset) -> Langulus::Trait { return mOwners.template SeekTrait(meta, offset); } @@ -75,7 +75,7 @@ namespace Langulus::A /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - Langulus::Trait Unit::SeekTraitAux(const Neat& aux, TMeta meta, Index offset) { + auto Unit::SeekTraitAux(const Many& aux, TMeta meta, Index offset) -> Langulus::Trait { return mOwners.template SeekTraitAux(aux, meta, offset); } @@ -103,7 +103,7 @@ namespace Langulus::A /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - bool Unit::SeekValueAux(TMeta meta, const Neat& aux, CT::Data auto& output, Index offset) const { + bool Unit::SeekValueAux(TMeta meta, const Many& aux, CT::Data auto& output, Index offset) const { return mOwners.template SeekValueAux(meta, aux, output, offset); } diff --git a/source/Unit.cpp b/source/Unit.cpp index 6a7ab7c..42bb3d7 100644 --- a/source/Unit.cpp +++ b/source/Unit.cpp @@ -12,6 +12,8 @@ using namespace Langulus::A; + +/// Unit destructor decouples unit from all owners Unit::~Unit() { for (auto entity : mOwners) Decouple(entity); @@ -27,11 +29,11 @@ void Unit::Select(Flow::Verb& verb) { /// Check if this unit has a given set of properties /// @param descriptor - descriptor with required properties /// @return true if the unit has the given properties -bool Unit::CompareDescriptor(const Neat& descriptor) const { +bool Unit::CompareDescriptor(const Many& descriptor) const { // First we compare traits only, all of them must be present bool mismatch = false; Offset memberOffset = 0; - descriptor.ForEach([&](const Anyness::Trait& trait) { + descriptor.ForEachDeep([&](const Anyness::Trait& trait) { if (not GetMember(trait.GetTrait(), memberOffset) .Compare(static_cast(trait))) { mismatch = true; @@ -42,10 +44,10 @@ bool Unit::CompareDescriptor(const Neat& descriptor) const { return Loop::Continue; }); - // Then we run another check, based on data types, again, all - // of them must be present, either in trait, or in other form + // Then we run another check based on data types, again - all + // of them must be present, either as trait or in other form memberOffset = 0; - descriptor.ForEachTail([&](const Many& anythingElse) { + descriptor.ForEachDeep([&](const Many& anythingElse) { if (not GetMember(TMeta {}, memberOffset).Compare(anythingElse)) { mismatch = true; return Loop::Break; @@ -60,7 +62,7 @@ bool Unit::CompareDescriptor(const Neat& descriptor) const { /// Get the list of unit owners /// @return the owners -const Hierarchy& Unit::GetOwners() const noexcept { +auto Unit::GetOwners() const noexcept -> const Hierarchy& { return mOwners; } @@ -71,7 +73,7 @@ void Unit::Refresh() {} /// @attention assumes units are correctly coupled and coupling to /// different runtimes should be explicitly disallowed /// @return a pointer to the runtime, if available -Runtime* Unit::GetRuntime() const noexcept { +auto Unit::GetRuntime() const noexcept -> Runtime* { if (not mOwners) return nullptr; return &*mOwners[0]->GetRuntime(); @@ -81,14 +83,19 @@ Runtime* Unit::GetRuntime() const noexcept { /// Traits::Parent, if any was defined (always two-sided) /// This will call refresh to all units in that entity on next tick /// @param desc - the descriptor to scan for parents -void Unit::Couple(const Neat& desc) { - // Couple any Thing provided in the descriptor +/// @param fallback - a fallback Thing to couple to (optional) +/// This usually comes from the producer's context. For example, if you +/// don't provide a parent for the renderer, it will be instantiated as +/// a child to the graphics module owner (i.e. the runtime owner) +void Unit::Couple(const Many& desc, const Thing* fallback) { const Thing* owner = nullptr; if (not desc.ExtractTrait(owner)) desc.ExtractData(owner); if (owner and mOwners.Merge(IndexBack, const_cast(owner))) const_cast(owner)->AddUnit(this); + else if (fallback) + const_cast(fallback)->AddUnit(this); } /// Decouple the component from an entity (always two-sided) diff --git a/source/Unit.hpp b/source/Unit.hpp index f06f30b..96a51ed 100644 --- a/source/Unit.hpp +++ b/source/Unit.hpp @@ -63,9 +63,9 @@ namespace Langulus::A virtual void Refresh(); - Runtime* GetRuntime() const noexcept; - const Hierarchy& GetOwners() const noexcept; - bool CompareDescriptor(const Neat&) const; + auto GetRuntime() const noexcept -> Runtime*; + auto GetOwners() const noexcept -> const Hierarchy&; + bool CompareDescriptor(const Many&) const; /// /// Flow @@ -85,24 +85,24 @@ namespace Langulus::A using SeekInterface::SeekValue; using SeekInterface::SeekValueAux; - template - NOD() Unit* SeekUnit(DMeta, Index = 0); - template - NOD() Unit* SeekUnitAux(const Neat&, DMeta, Index = 0); - template - NOD() Unit* SeekUnitExt(DMeta, const Neat&, Index = 0); - template - NOD() Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0); + template NOD() + auto SeekUnit(DMeta, Index = 0) -> Unit*; + template NOD() + auto SeekUnitAux(const Many&, DMeta, Index = 0) -> Unit*; + template NOD() + auto SeekUnitExt(DMeta, const Many&, Index = 0) -> Unit*; + template NOD() + auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) -> Unit*; - template - NOD() Langulus::Trait SeekTrait(TMeta, Index = 0); - template - NOD() Langulus::Trait SeekTraitAux(const Neat&, TMeta, Index = 0); + template NOD() + auto SeekTrait(TMeta, Index = 0) -> Langulus::Trait; + template NOD() + auto SeekTraitAux(const Many&, TMeta, Index = 0) -> Langulus::Trait; template bool SeekValue(TMeta, CT::Data auto&, Index = 0) const; template - bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = 0) const; + bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = 0) const; /// /// Gather @@ -111,19 +111,19 @@ namespace Langulus::A using SeekInterface::GatherUnitsExt; using SeekInterface::GatherTraits; - template - NOD() TMany GatherUnits(DMeta); - template - NOD() TMany GatherUnitsExt(DMeta, const Neat&); + template NOD() + auto GatherUnits(DMeta) -> TMany; + template NOD() + auto GatherUnitsExt(DMeta, const Many&) -> TMany; - template - NOD() TraitList GatherTraits(TMeta); + template NOD() + auto GatherTraits(TMeta) -> TraitList; - template - NOD() TMany GatherValues() const; + template NOD() + auto GatherValues() const -> TMany; protected: - void Couple(const Neat&); + void Couple(const Many&, const Thing* = nullptr); void Decouple(const Thing*); void ReplaceOwner(const Thing*, const Thing*); }; From 47d07d12b7a108132ee58c214566f4c01f619a25 Mon Sep 17 00:00:00 2001 From: Epixu Date: Thu, 10 Oct 2024 12:57:08 +0300 Subject: [PATCH 19/34] Set existing parent only if missing --- source/Thing.inl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/Thing.inl b/source/Thing.inl index e159916..0000687 100644 --- a/source/Thing.inl +++ b/source/Thing.inl @@ -582,7 +582,7 @@ namespace Langulus::Entity // already added - it will be stripped later, when normalizing // the descriptor when producing the item from a factory Construct descriptor = construct; - /*Traits::Parent parent; + Traits::Parent parent; if (not descriptor->ExtractTrait(parent)) { parent = this; parent.MakeMissing(); @@ -592,7 +592,8 @@ namespace Langulus::Entity Reference(0), " references)" ); } - else parent << this;*/ + else if (parent.IsMissing()) + parent << this; if (producer) { // Data has a specific producer, we can narrow the required From b664840c30fa79e909bf5d62006201a5b227eacc Mon Sep 17 00:00:00 2001 From: Epixu Date: Thu, 10 Oct 2024 18:25:57 +0300 Subject: [PATCH 20/34] Some detachment reordering; Further Neat substitutions; Testing Neat/Many descriptors for Things --- source/Module.hpp | 4 ++-- source/Runtime.cpp | 4 ++-- source/Runtime.hpp | 4 ++-- source/Thing.cpp | 31 +++++++++++++++++-------------- source/Thing.hpp | 7 +++---- source/Thing.inl | 2 +- test/TestThing.cpp | 9 ++++++--- 7 files changed, 33 insertions(+), 28 deletions(-) diff --git a/source/Module.hpp b/source/Module.hpp index 73394fc..75227b3 100644 --- a/source/Module.hpp +++ b/source/Module.hpp @@ -93,7 +93,7 @@ namespace Langulus::A }; using EntryFunction = void(*)(DMeta&, MetaList&); - using CreateFunction = Module*(*)(Entity::Runtime*, const Neat&); + using CreateFunction = Module*(*)(Entity::Runtime*, const Many&); using InfoFunction = const Info*(*)(); NOD() Entity::Runtime* GetRuntime() const noexcept { @@ -150,7 +150,7 @@ namespace Langulus::CT \ LANGULUS_EXPORT() \ ::Langulus::A::Module* LANGULUS_MODULE_CREATE() ( \ - ::Langulus::Entity::Runtime* rt, const ::Langulus::Anyness::Neat& desc) { \ + ::Langulus::Entity::Runtime* rt, const ::Langulus::Anyness::Many& desc) { \ static_assert(::Langulus::CT::DerivedFrom, \ "Langulus module class interface " \ #m " doesn't inherit ::Langulus::A::Module"); \ diff --git a/source/Runtime.cpp b/source/Runtime.cpp index 78a2c7d..a178e1f 100644 --- a/source/Runtime.cpp +++ b/source/Runtime.cpp @@ -195,7 +195,7 @@ namespace Langulus::Entity /// @param name - module name /// @param descriptor - module initialization descriptor /// @return the new module instance - A::Module* Runtime::InstantiateModule(const Token& name, const Neat& descriptor) { + A::Module* Runtime::InstantiateModule(const Token& name, const Many& descriptor) { // Load the library if not loaded yet const auto library = LoadSharedLibrary(name); @@ -267,7 +267,7 @@ namespace Langulus::Entity /// @param library - the library handle /// @param descriptor - module initialization descriptor /// @return the new module instance - A::Module* Runtime::InstantiateModule(const SharedLibrary& library, const Neat& descriptor) { + A::Module* Runtime::InstantiateModule(const SharedLibrary& library, const Many& descriptor) { if (not library.IsValid()) return nullptr; diff --git a/source/Runtime.hpp b/source/Runtime.hpp index d6b354b..368ffca 100644 --- a/source/Runtime.hpp +++ b/source/Runtime.hpp @@ -113,10 +113,10 @@ namespace Langulus::Entity NOD() auto GetOwner() const noexcept { return mOwner; } NOD() LANGULUS_API(ENTITY) - A::Module* InstantiateModule(const Token&, const Neat& = {}); + A::Module* InstantiateModule(const Token&, const Many& = {}); NOD() LANGULUS_API(ENTITY) - A::Module* InstantiateModule(const SharedLibrary&, const Neat& = {}); + A::Module* InstantiateModule(const SharedLibrary&, const Many& = {}); NOD() LANGULUS_API(ENTITY) SharedLibrary GetDependency(DMeta) const noexcept; diff --git a/source/Thing.cpp b/source/Thing.cpp index 73e52b3..0ac7e4b 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -91,9 +91,9 @@ namespace Langulus::Entity /// @param other - move that entity Thing::Thing(Thing&& other) noexcept : Resolvable {this} - , mChildren {Move(other.mChildren)} , mRuntime {Move(other.mRuntime)} , mFlow {Move(other.mFlow)} + , mChildren {Move(other.mChildren)} , mUnitsAmbiguous {Move(other.mUnitsAmbiguous)} , mUnitsList {Move(other.mUnitsList)} , mTraits {Move(other.mTraits)} @@ -121,9 +121,9 @@ namespace Langulus::Entity /// @param other - clone that entity Thing::Thing(Abandoned&& other) : Resolvable {this} - , mChildren {Abandon(other->mChildren)} , mRuntime {Abandon(other->mRuntime)} , mFlow {Abandon(other->mFlow)} + , mChildren {Abandon(other->mChildren)} , mUnitsAmbiguous {Abandon(other->mUnitsAmbiguous)} , mUnitsList {Abandon(other->mUnitsList)} , mTraits {Abandon(other->mTraits)} @@ -169,13 +169,21 @@ namespace Langulus::Entity void Thing::Detach() { ENTITY_VERBOSE_SELF_TAB("Destroying (", Reference(0), " uses):"); - if (not mRuntime.IsLocked()) - mRuntime.Reset(); + mTraits.Reset(); + + // Decouple all units from this owner + for (auto& unit : mUnitsList) { + ENTITY_VERBOSE_SELF("Decoupling unit: ", unit); + unit->mOwners.Reset(); + ENTITY_VERBOSE_SELF("...", Reference(0), " uses remain"); + } + + mUnitsList.Reset(); + mUnitsAmbiguous.Reset(); + if (not mFlow.IsLocked()) mFlow.Reset(); - mTraits.Reset(); - // Decouple all children from this for (auto& child : mChildren) { if (child->mOwner) { @@ -188,15 +196,10 @@ namespace Langulus::Entity } } - // Decouple all units from this owner - for (auto& unit : mUnitsList) { - ENTITY_VERBOSE_SELF("Decoupling unit: ", unit); - unit->mOwners.Reset(); - ENTITY_VERBOSE_SELF("...", Reference(0), " uses remain"); - } + mChildren.Reset(); - mUnitsAmbiguous.Reset(); - mUnitsList.Reset(); + if (not mRuntime.IsLocked()) + mRuntime.Reset(); } /// Compare two entities diff --git a/source/Thing.hpp b/source/Thing.hpp index 11706eb..605038e 100644 --- a/source/Thing.hpp +++ b/source/Thing.hpp @@ -50,13 +50,12 @@ namespace Langulus::Entity LANGULUS_API(ENTITY) void ResetFlow(Temporal*); // The order of members is critical! - // Hierarchy should be destroyed last, hence it is the first - // member - Hierarchy mChildren; - // Runtime + // Runtime should be destroyed last, hence it is the first member Pin> mRuntime; // Temporal flow Pin> mFlow; + // Hierarchy + Hierarchy mChildren; // Units indexed by all their relevant reflected bases UnitMap mUnitsAmbiguous; // Units indexed by concrete type, in order of addition diff --git a/source/Thing.inl b/source/Thing.inl index 0000687..0d8ed1c 100644 --- a/source/Thing.inl +++ b/source/Thing.inl @@ -53,7 +53,7 @@ namespace Langulus::Entity ENTITY_VERBOSE_SELF_TAB( "Producing child (at ", Reference(0), " references): "); Ref newThing; - newThing.New(this, Neat {Forward(arguments)...}); + newThing.New(this, Many {Forward(arguments)...}); return Abandon(newThing); } diff --git a/test/TestThing.cpp b/test/TestThing.cpp index 5711a93..242b1b1 100644 --- a/test/TestThing.cpp +++ b/test/TestThing.cpp @@ -8,7 +8,10 @@ #include "Common.hpp" -SCENARIO("Testing Thing", "[thing]") { +TEMPLATE_TEST_CASE("Testing Thing with different kidns of descriptors", + "[thing]", + Many, Neat +) { static Allocator::State memoryState; static_assert(CT::Deep, "Hierarchy must be reflected as deep"); @@ -216,7 +219,7 @@ SCENARIO("Testing Thing", "[thing]") { for (int repeat = 0; repeat != 10; ++repeat) { WHEN(std::string("Creating a Thing by descriptor #") + std::to_string(repeat)) { Logger::Special("Start: Creating a Thing by descriptor"); - Neat descriptor { + TestType descriptor { Traits::Name {"Root"}, Construct::From(), Construct::From(), @@ -312,7 +315,7 @@ SCENARIO("Testing Thing", "[thing]") { } GIVEN("A complex hierarchy with runtime, flow, units, and traits") { - Neat descriptor { + TestType descriptor { Traits::Name {"Root"}, Construct::From(), Construct::From(), From 0df25287fe9ac4dde6fd8d63c843a809e199db11 Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Mon, 14 Oct 2024 19:29:55 +0300 Subject: [PATCH 21/34] Less local construct pointers --- CMakeLists.txt | 4 ++-- source/Thing.cpp | 2 +- source/Thing.inl | 13 ++++--------- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e21612..da62585 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,6 @@ target_compile_definitions(LangulusEntity ) if(LANGULUS_TESTING) - enable_testing() - add_subdirectory(test) + #enable_testing() + #add_subdirectory(test) endif() \ No newline at end of file diff --git a/source/Thing.cpp b/source/Thing.cpp index 0ac7e4b..d4a9349 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -66,7 +66,7 @@ namespace Langulus::Entity if (descriptor) { // Create any subthings/traits/unit in this thing - Verbs::Create creator {&descriptor}; + Verbs::Create creator {descriptor}; Create(creator); } diff --git a/source/Thing.inl b/source/Thing.inl index 0d8ed1c..be297a7 100644 --- a/source/Thing.inl +++ b/source/Thing.inl @@ -608,7 +608,7 @@ namespace Langulus::Entity // Potential unit producers found, attempt creation producers.MakeOr(); - Verbs::Create creator {&descriptor}; + Verbs::Create creator {descriptor}; if (Flow::DispatchFlat(producers, creator)) return Abandon(creator.GetOutput()); @@ -628,7 +628,7 @@ namespace Langulus::Entity // Potential module producers found, attempt creation producers.MakeOr(); - Verbs::Create creator {&descriptor}; + Verbs::Create creator {descriptor}; if (Flow::DispatchFlat(producers, creator)) return Abandon(creator.GetOutput()); @@ -651,7 +651,7 @@ namespace Langulus::Entity if (producers) { // Potential unit producers found, attempt creation there producers.MakeOr(); - Verbs::Create creator {&descriptor}; + Verbs::Create creator {descriptor}; if (Flow::DispatchFlat(producers, creator)) return Abandon(creator.GetOutput()); @@ -671,14 +671,9 @@ namespace Langulus::Entity // such constructor is reflected. If it's a unit, its // descriptor is resposible for registering it with the parent // via the Traits::Parent trait - Verbs::Create creator {&descriptor}; + Verbs::Create creator {descriptor}; if (Verbs::Create::ExecuteStateless(creator)) return Abandon(creator.GetOutput()); - - /*Logger::Error( - "Failed to create `", Logger::PushDarkYellow, - type, Logger::Pop, "` statelessly: ", descriptor - );*/ } LANGULUS_THROW(Construct, "Unable to create data"); From 41326ec3dd18b56825fda308fa53b618bc9b60ca Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Tue, 15 Oct 2024 10:44:54 +0300 Subject: [PATCH 22/34] Minor changes --- source/Thing.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Thing.inl b/source/Thing.inl index be297a7..37a7a60 100644 --- a/source/Thing.inl +++ b/source/Thing.inl @@ -572,6 +572,7 @@ namespace Langulus::Entity const auto type = construct.GetType(); const auto producer = type and type->mProducerRetriever ? type->mProducerRetriever() : nullptr; + Construct descriptor = construct; ENTITY_VERBOSE_SELF( "Acting as producer context for making `", @@ -581,7 +582,6 @@ namespace Langulus::Entity // Implicitly add a parent trait to descriptor, if one isn't // already added - it will be stripped later, when normalizing // the descriptor when producing the item from a factory - Construct descriptor = construct; Traits::Parent parent; if (not descriptor->ExtractTrait(parent)) { parent = this; From 0546726ed07a8cec43f71f5defe5983dcea83494 Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Wed, 16 Oct 2024 11:44:40 +0300 Subject: [PATCH 23/34] Maintenance; Implementing detachment through Reference routines (WIP) --- CMakeLists.txt | 4 +- include/Langulus/Asset.hpp | 6 +- include/Langulus/Asset.inl | 13 ++-- include/Langulus/IO.hpp | 7 ++ include/Langulus/IO.inl | 8 +-- include/Langulus/Image.hpp | 26 ++++---- include/Langulus/Image.inl | 12 ++-- include/Langulus/Material.hpp | 10 +-- include/Langulus/Mesh.hpp | 2 +- source/Thing.cpp | 107 +++++++++++++++++++------------ source/Thing.hpp | 9 ++- source/Thing.inl | 12 ++-- test/TestThing.cpp | 116 ++++++++++++++++------------------ 13 files changed, 182 insertions(+), 150 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index da62585..8e21612 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,6 @@ target_compile_definitions(LangulusEntity ) if(LANGULUS_TESTING) - #enable_testing() - #add_subdirectory(test) + enable_testing() + add_subdirectory(test) endif() \ No newline at end of file diff --git a/include/Langulus/Asset.hpp b/include/Langulus/Asset.hpp index 4363355..df628e1 100644 --- a/include/Langulus/Asset.hpp +++ b/include/Langulus/Asset.hpp @@ -43,17 +43,17 @@ namespace Langulus::A protected: // Map of lists of generated data - mutable DataListMap mDataListMap; + DataListMap mDataListMap; public: Asset() : Resolvable {this} {} - void Detach(); + Count Reference(int); virtual bool Generate(TMeta, Offset = 0) { return true; } template - void Commit(auto&&) const; + void Commit(auto&&); template NOD() auto GetData(Offset = 0) const noexcept -> const Data*; diff --git a/include/Langulus/Asset.inl b/include/Langulus/Asset.inl index 43a497d..b4445a2 100644 --- a/include/Langulus/Asset.inl +++ b/include/Langulus/Asset.inl @@ -114,7 +114,7 @@ namespace Langulus::A /// you don't use factories, and just want some local content /// representation. template LANGULUS(INLINED) - void Asset::Commit(auto&& content) const { + void Asset::Commit(auto&& content) { TMeta trait; if constexpr (CT::Trait) trait = MetaTraitOf(); @@ -128,9 +128,14 @@ namespace Langulus::A } /// Detach the asset - inline void Asset::Detach() { - mDataListMap.Reset(); - ProducedFrom::Detach(); + LANGULUS(INLINED) + Count Asset::Reference(int x) { + if (Unit::Reference(x) == 1) { + mDataListMap.Reset(); + ProducedFrom::Detach(); + } + + return GetReferences(); } } // namespace Langulus::A diff --git a/include/Langulus/IO.hpp b/include/Langulus/IO.hpp index 2541009..641c743 100644 --- a/include/Langulus/IO.hpp +++ b/include/Langulus/IO.hpp @@ -51,6 +51,13 @@ namespace Langulus::A Size mByteCount {}; bool mIsReadOnly {}; + // Parent directory substring, mapped onto mFilePath + Token mParentDirectory; + // File name after all directories, mapped onto mFilePath + Token mFileName; + // The extension of the filename, mapped onto mFilePath + Token mFileExtension; + public: LANGULUS(PRODUCER) FileSystem; LANGULUS_BASES(Unit); diff --git a/include/Langulus/IO.inl b/include/Langulus/IO.inl index 0f62a9e..0fa7155 100644 --- a/include/Langulus/IO.inl +++ b/include/Langulus/IO.inl @@ -15,14 +15,14 @@ namespace Langulus::A /// Get the current working path (where the main exe was executed) /// @return the path LANGULUS(INLINED) - const Path& FileSystem::GetWorkingPath() const noexcept { + auto FileSystem::GetWorkingPath() const noexcept -> const Path& { return mWorkingPath; } /// Get the current data path, like GetWorkingPath() / "data" /// @return the path LANGULUS(INLINED) - const Path& FileSystem::GetDataPath() const noexcept { + auto FileSystem::GetDataPath() const noexcept -> const Path& { return mMainDataPath; } @@ -58,7 +58,7 @@ namespace Langulus::A /// Get the full path of the file /// @return a reference to the path LANGULUS(INLINED) - const Path& File::GetFilePath() const noexcept { + auto File::GetFilePath() const noexcept -> const Path& { return mFilePath; } @@ -88,7 +88,7 @@ namespace Langulus::A /// Get the full path of the folder /// @return a reference to the path LANGULUS(INLINED) - const Path& Folder::GetFolderPath() const noexcept { + auto Folder::GetFolderPath() const noexcept -> const Path& { return mFolderPath; } diff --git a/include/Langulus/Image.hpp b/include/Langulus/Image.hpp index 7dd9237..7f7532d 100644 --- a/include/Langulus/Image.hpp +++ b/include/Langulus/Image.hpp @@ -57,18 +57,18 @@ namespace Langulus::A LANGULUS_BASES(Asset); Image() : Resolvable {this} {} - NOD() virtual Ref GetLOD(const Math::LOD&) const { return {}; } - NOD() virtual void* GetGPUHandle() const noexcept { return nullptr; } + NOD() virtual auto GetLOD(const Math::LOD&) const -> Ref { return {}; } + NOD() virtual auto GetGPUHandle() const noexcept -> void* { return nullptr; } - NOD() DMeta GetFormat() const noexcept; - NOD() ImageView const& GetView() const noexcept; - NOD() ImageView& GetView() noexcept; + NOD() auto GetFormat() const noexcept -> DMeta; + NOD() auto GetView() const noexcept -> ImageView const&; + NOD() auto GetView() noexcept -> ImageView&; template auto ForEachPixel(F&&) const; template class S, CT::Block B> requires CT::Intent> - void Upload(S&&) const; + void Upload(S&&); /// /// Iteration @@ -76,9 +76,9 @@ namespace Langulus::A template struct Iterator; - NOD() auto begin() noexcept -> Iterator; + NOD() auto begin() noexcept -> Iterator; NOD() auto begin() const noexcept -> Iterator; - NOD() auto end() const noexcept -> A::IteratorEnd { return {}; } + NOD() auto end() const noexcept -> A::IteratorEnd { return {}; } }; @@ -108,17 +108,17 @@ namespace Langulus::A constexpr Iterator(Iterator&&) noexcept = default; constexpr Iterator(const A::IteratorEnd&) noexcept; - constexpr Iterator& operator = (const Iterator&) noexcept = default; - constexpr Iterator& operator = (Iterator&&) noexcept = default; + constexpr auto operator = (const Iterator&) noexcept -> Iterator& = default; + constexpr auto operator = (Iterator&&) noexcept -> Iterator& = default; NOD() constexpr bool operator == (const Iterator&) const noexcept; NOD() constexpr bool operator == (const A::IteratorEnd&) const noexcept; // Prefix operator - constexpr Iterator& operator ++ () noexcept; + constexpr auto operator ++ () noexcept -> Iterator&; // Suffix operator - NOD() constexpr Iterator operator ++ (int) noexcept; + NOD() constexpr auto operator ++ (int) noexcept -> Iterator; constexpr explicit operator bool() const noexcept; constexpr operator Iterator() const noexcept requires Mutable; @@ -135,7 +135,7 @@ namespace Langulus::A LANGULUS_BASES(Image); Font() - : Resolvable {this} + : Resolvable {this} , ProducedFrom {nullptr, {}} {} }; diff --git a/include/Langulus/Image.inl b/include/Langulus/Image.inl index a19fafd..91879fe 100644 --- a/include/Langulus/Image.inl +++ b/include/Langulus/Image.inl @@ -84,21 +84,21 @@ namespace Langulus::A /// Get the pixel format of the texture /// @return the pixel format type LANGULUS(INLINED) - DMeta Image::GetFormat() const noexcept { + auto Image::GetFormat() const noexcept -> DMeta { return mView.mFormat; } /// Get the texture view (const) /// @return the texture view LANGULUS(INLINED) - const ImageView& Image::GetView() const noexcept { + auto Image::GetView() const noexcept -> const ImageView& { return mView; } /// Get the texture view /// @return the texture view LANGULUS(INLINED) - ImageView& Image::GetView() noexcept { + auto Image::GetView() noexcept -> ImageView& { return mView; } @@ -157,7 +157,7 @@ namespace Langulus::A /// @param data - the block of data template class S, CT::Block B> requires CT::Intent> LANGULUS(INLINED) - void Image::Upload(S&& data) const { + void Image::Upload(S&& data) { // Check if provided data matches the view requirements LANGULUS_ASSERT(mView.GetBytesize() == data->GetBytesize(), Image, "Data is of the wrong size"); @@ -221,7 +221,7 @@ namespace Langulus::A /// @attention assumes iterator points to a valid element /// @return the modified iterator template LANGULUS(INLINED) - constexpr Image::Iterator& Image::Iterator::operator ++ () noexcept { + constexpr auto Image::Iterator::operator ++ () noexcept -> Iterator& { mValue += mImage->GetView().GetPixelBytesize(); return *this; } @@ -230,7 +230,7 @@ namespace Langulus::A /// @attention assumes iterator points to a valid element /// @return the previous value of the iterator template LANGULUS(INLINED) - constexpr Image::Iterator Image::Iterator::operator ++ (int) noexcept { + constexpr auto Image::Iterator::operator ++ (int) noexcept -> Iterator { const auto backup = *this; operator ++ (); return backup; diff --git a/include/Langulus/Material.hpp b/include/Langulus/Material.hpp index 6603ad9..6762c0e 100644 --- a/include/Langulus/Material.hpp +++ b/include/Langulus/Material.hpp @@ -73,13 +73,13 @@ namespace Langulus LANGULUS_BASES(Asset); using Asset::Asset; - NOD() virtual Ref GetLOD(const Math::LOD&) const = 0; + NOD() virtual auto GetLOD(const Math::LOD&) const -> Ref = 0; - NOD() const TraitList& GetInputs(RefreshRate) const; - NOD() const TraitList& GetInputs(Offset) const; + NOD() auto GetInputs(RefreshRate) const -> const TraitList&; + NOD() auto GetInputs(Offset) const -> const TraitList&; - NOD() const TraitList& GetOutputs(RefreshRate) const; - NOD() const TraitList& GetOutputs(Offset) const; + NOD() auto GetOutputs(RefreshRate) const -> const TraitList&; + NOD() auto GetOutputs(Offset) const -> const TraitList&; protected: mutable TraitList mInputs[RefreshRate::InputCount]; diff --git a/include/Langulus/Mesh.hpp b/include/Langulus/Mesh.hpp index c0db671..10693bd 100644 --- a/include/Langulus/Mesh.hpp +++ b/include/Langulus/Mesh.hpp @@ -70,7 +70,7 @@ namespace Langulus::A NOD() auto GetView() const noexcept -> MeshView const&; NOD() auto GetView() noexcept -> MeshView&; - NOD() virtual Ref GetLOD(const Math::LOD&) const = 0; + NOD() virtual auto GetLOD(const Math::LOD&) const -> Ref = 0; // Point utilities NOD() bool MadeOfPoints() const noexcept; diff --git a/source/Thing.cpp b/source/Thing.cpp index d4a9349..988cf71 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -8,7 +8,7 @@ #include "Thing.hpp" #include "Thing.inl" -#if 0 +#if 1 #define ENTITY_VERBOSE_ENABLED() 1 #define ENTITY_VERBOSE_SELF(...) Logger::Info(this, ": ", __VA_ARGS__) #define ENTITY_VERBOSE_SELF_TAB(...) const auto scoped = Logger::InfoTab(this, ": ", __VA_ARGS__) @@ -26,7 +26,7 @@ namespace Langulus::Entity /// Default-constructor, always creates a parentless root thing Thing::Thing() : Resolvable {this} { - ENTITY_VERBOSE_SELF("Created (root, ", Reference(0), " references)"); + ENTITY_VERBOSE_SELF("Created (root, ", GetReferences(), " references)"); } /// Descriptor-constructor @@ -40,13 +40,13 @@ namespace Langulus::Entity if (mOwner) { ENTITY_VERBOSE_SELF( "Created as child to ", mOwner, - " (", Reference(0), " references; parent now has ", - mOwner->Reference(0), " references)" + " (", GetReferences(), " references; parent now has ", + mOwner->GetReferences(), " references)" ); } else { ENTITY_VERBOSE_SELF( - "Created (root, ", Reference(0), " references)" + "Created (root, ", GetReferences(), " references)" ); } } @@ -73,13 +73,13 @@ namespace Langulus::Entity if (mOwner) { ENTITY_VERBOSE_SELF( "Created as child to ", mOwner, - " (", Reference(0), " references; parent now has ", - mOwner->Reference(0), " references)" + " (", GetReferences(), " references; parent now has ", + mOwner->GetReferences(), " references)" ); } else { ENTITY_VERBOSE_SELF( - "Created (root, ", Reference(0), " references)" + "Created (root, ", GetReferences(), " references)" ); } } @@ -94,8 +94,8 @@ namespace Langulus::Entity , mRuntime {Move(other.mRuntime)} , mFlow {Move(other.mFlow)} , mChildren {Move(other.mChildren)} - , mUnitsAmbiguous {Move(other.mUnitsAmbiguous)} , mUnitsList {Move(other.mUnitsList)} + , mUnitsAmbiguous {Move(other.mUnitsAmbiguous)} , mTraits {Move(other.mTraits)} , mRefreshRequired{true} { @@ -124,8 +124,8 @@ namespace Langulus::Entity , mRuntime {Abandon(other->mRuntime)} , mFlow {Abandon(other->mFlow)} , mChildren {Abandon(other->mChildren)} - , mUnitsAmbiguous {Abandon(other->mUnitsAmbiguous)} , mUnitsList {Abandon(other->mUnitsList)} + , mUnitsAmbiguous {Abandon(other->mUnitsAmbiguous)} , mTraits {Abandon(other->mTraits)} , mRefreshRequired{true} { @@ -160,46 +160,71 @@ namespace Langulus::Entity ENTITY_VERBOSE_SELF("cloned from ", *other); } - /// Destructor - Thing::~Thing() IF_UNSAFE(noexcept) { - Detach(); + Thing::~Thing() { + if (GetReferences()) + Reference(-1); } - - /// A nested call to detach all parents of all children - void Thing::Detach() { - ENTITY_VERBOSE_SELF_TAB("Destroying (", Reference(0), " uses):"); - mTraits.Reset(); + /// Reference and detach all parents of all children + Count Thing::Reference(int x) { + if (Referenced::Reference(x) == 0) { + // Traits might be exposing members in units. Make sure we + // dereference those first + mTraits.Reset(); - // Decouple all units from this owner - for (auto& unit : mUnitsList) { - ENTITY_VERBOSE_SELF("Decoupling unit: ", unit); - unit->mOwners.Reset(); - ENTITY_VERBOSE_SELF("...", Reference(0), " uses remain"); - } + // Decouple all units from this owner because units might get + // destroyed upon destroying mUnitsList and mUnitsAmbiguous + // If they still have owners, they will attempt to Decouple + // themselves from already destroyed mUnitsList/mUnitsAmbiguous + for (auto& unit : mUnitsList) { + ENTITY_VERBOSE_SELF("Decoupling unit: ", unit); + unit->mOwners.Remove(this); + ENTITY_VERBOSE_SELF("...", GetReferences(), " uses remain"); + } - mUnitsList.Reset(); - mUnitsAmbiguous.Reset(); + // The same applies for child things + for (auto& child : mChildren) { + if (child->mOwner) { + ENTITY_VERBOSE_SELF("Decoupling child: ", child); + LANGULUS_ASSUME(DevAssumes, child->mOwner == this, "Parent mismatch"); + child->mOwner.Reset(); + ENTITY_VERBOSE_SELF("...", GetReferences(), " uses remain"); + } + } - if (not mFlow.IsLocked()) - mFlow.Reset(); + /*ENTITY_VERBOSE_SELF_TAB("Detaching (", GetReferences(), " uses):"); - // Decouple all children from this - for (auto& child : mChildren) { - if (child->mOwner) { - ENTITY_VERBOSE_SELF("Decoupling child: ", child); - LANGULUS_ASSUME(DevAssumes, - child->mOwner == this, "Parent mismatch"); - child->mOwner.Reset(); - child->Detach(); - ENTITY_VERBOSE_SELF("...", Reference(0), " uses remain"); + mTraits.Reset(); + + // Decouple all units from this owner + for (auto& unit : mUnitsList) { + ENTITY_VERBOSE_SELF("Decoupling unit: ", unit); + unit->mOwners.Reset(); + ENTITY_VERBOSE_SELF("...", GetReferences(), " uses remain"); } - } - mChildren.Reset(); + mUnitsList.Reset(); + mUnitsAmbiguous.Reset(); + + if (not mFlow.IsLocked()) + mFlow.Reset(); + + // Decouple all children from this + for (auto& child : mChildren) { + if (child->mOwner) { + ENTITY_VERBOSE_SELF("Decoupling child: ", child); + LANGULUS_ASSUME(DevAssumes, child->mOwner == this, + "Parent mismatch"); + child->mOwner.Reset(); + child->Reference(x); + ENTITY_VERBOSE_SELF("...", GetReferences(), " uses remain"); + } + } + + mChildren.Reset();*/ + } - if (not mRuntime.IsLocked()) - mRuntime.Reset(); + return GetReferences(); } /// Compare two entities diff --git a/source/Thing.hpp b/source/Thing.hpp index 605038e..b04d5bc 100644 --- a/source/Thing.hpp +++ b/source/Thing.hpp @@ -56,10 +56,10 @@ namespace Langulus::Entity Pin> mFlow; // Hierarchy Hierarchy mChildren; - // Units indexed by all their relevant reflected bases - UnitMap mUnitsAmbiguous; // Units indexed by concrete type, in order of addition UnitList mUnitsList; + // Units indexed by all their relevant reflected bases + UnitMap mUnitsAmbiguous; // Traits TraitMap mTraits; // Hierarchy requires an update @@ -80,13 +80,12 @@ namespace Langulus::Entity LANGULUS_API(ENTITY) Thing(Thing&&) noexcept; LANGULUS_API(ENTITY) Thing(Cloned&&); LANGULUS_API(ENTITY) Thing(Abandoned&&); - - LANGULUS_API(ENTITY) ~Thing() IF_UNSAFE(noexcept); + LANGULUS_API(ENTITY)~Thing(); template NOD() static Thing Root(CT::String auto&&...); - void Detach(); + LANGULUS_API(ENTITY) Count Reference(int); // Shallow copy is disabled, you should be able only to clone, // move, or abandon diff --git a/source/Thing.inl b/source/Thing.inl index 37a7a60..7decd5a 100644 --- a/source/Thing.inl +++ b/source/Thing.inl @@ -51,7 +51,7 @@ namespace Langulus::Entity template Ref Thing::CreateChild(T&&...arguments) { ENTITY_VERBOSE_SELF_TAB( - "Producing child (at ", Reference(0), " references): "); + "Producing child (at ", GetReferences(), " references): "); Ref newThing; newThing.New(this, Many {Forward(arguments)...}); return Abandon(newThing); @@ -341,7 +341,7 @@ namespace Langulus::Entity mRefreshRequired = true; ENTITY_VERBOSE( - unit, " added as unit (now at ", Reference(0), " references)"); + unit, " added as unit (now at ", GetReferences(), " references)"); return 1; } @@ -428,14 +428,14 @@ namespace Langulus::Entity /// Get the list of units, in order of addition /// @return a reference to the list of units LANGULUS(INLINED) - const UnitList& Thing::GetUnits() const noexcept { + auto Thing::GetUnits() const noexcept -> const UnitList& { return mUnitsList; } /// Get the ambiguous map of units /// @return a reference to the map of units LANGULUS(INLINED) - const UnitMap& Thing::GetUnitsMap() const noexcept { + auto Thing::GetUnitsMap() const noexcept -> const UnitMap& { return mUnitsAmbiguous; } @@ -576,7 +576,7 @@ namespace Langulus::Entity ENTITY_VERBOSE_SELF( "Acting as producer context for making `", - type, "` (at ", Reference(0), " references)" + type, "` (at ", GetReferences(), " references)" ); // Implicitly add a parent trait to descriptor, if one isn't @@ -589,7 +589,7 @@ namespace Langulus::Entity descriptor << parent; ENTITY_VERBOSE_SELF( "Referenced as Traits::Parent (now at ", - Reference(0), " references)" + GetReferences(), " references)" ); } else if (parent.IsMissing()) diff --git a/test/TestThing.cpp b/test/TestThing.cpp index 242b1b1..ed9e185 100644 --- a/test/TestThing.cpp +++ b/test/TestThing.cpp @@ -29,7 +29,7 @@ TEMPLATE_TEST_CASE("Testing Thing with different kidns of descriptors", REQUIRE(not root.GetUnits()); REQUIRE(not root.GetUnitsMap()); REQUIRE(not root.GetTraits()); - REQUIRE(root.Reference(0) == 1); + REQUIRE(root.GetReferences() == 1); } WHEN("Creating a Thing with a parent") { @@ -47,7 +47,7 @@ TEMPLATE_TEST_CASE("Testing Thing with different kidns of descriptors", REQUIRE(not root.GetUnits()); REQUIRE(not root.GetUnitsMap()); REQUIRE(not root.GetTraits()); - REQUIRE(root.Reference(0) == 1); + REQUIRE(root.GetReferences() == 1); REQUIRE(child.GetOwner() == &root); REQUIRE(child.GetRuntime() == nullptr); @@ -59,7 +59,7 @@ TEMPLATE_TEST_CASE("Testing Thing with different kidns of descriptors", REQUIRE(not child.GetUnits()); REQUIRE(not child.GetUnitsMap()); REQUIRE(not child.GetTraits()); - REQUIRE(child.Reference(0) == 1); + REQUIRE(child.GetReferences() == 1); } GIVEN("A root Thing") { @@ -91,7 +91,7 @@ TEMPLATE_TEST_CASE("Testing Thing with different kidns of descriptors", REQUIRE(root.GetChildren().GetCount() == 1); REQUIRE(not root.GetUnits()); REQUIRE(not root.GetTraits()); - REQUIRE(root.Reference(0) == 1); + REQUIRE(root.GetReferences() == 1); auto child1 = root.GetChildren()[0]; REQUIRE(child1 == child); @@ -104,66 +104,62 @@ TEMPLATE_TEST_CASE("Testing Thing with different kidns of descriptors", REQUIRE(not child1->GetChildren()); REQUIRE(not child1->GetUnits()); REQUIRE(not child1->GetTraits()); - REQUIRE(child1->Reference(0) == 2); + REQUIRE(child1->GetReferences() == 2); } WHEN("Adding an existing unit") { TestUnit1 testUnit; auto added = root.AddUnit(&testUnit); - THEN("Properties should match") { - REQUIRE(added == 1); - REQUIRE(root.GetOwner() == nullptr); - REQUIRE(root.GetRuntime() == nullptr); - REQUIRE(root.GetRuntime().IsLocked() == false); - REQUIRE(root.GetFlow() == nullptr); - REQUIRE(root.GetFlow().IsLocked() == false); - REQUIRE(root.RequiresRefresh() == true); - REQUIRE(root.GetChildren().IsEmpty()); - REQUIRE(root.GetUnits().GetCount() == 1); - REQUIRE(root.GetTraits().IsEmpty()); - REQUIRE(root.Reference(0) == 1); - - auto it = root.GetUnits().begin(); - REQUIRE(it->GetType() == MetaOf()); - REQUIRE(*it == &testUnit); - REQUIRE(it->GetOwners().GetCount() == 1); - REQUIRE(it->GetOwners()[0] == &root); - REQUIRE(it->Reference(0) == 1); - } + REQUIRE(added == 1); + REQUIRE(root.GetOwner() == nullptr); + REQUIRE(root.GetRuntime() == nullptr); + REQUIRE(root.GetRuntime().IsLocked() == false); + REQUIRE(root.GetFlow() == nullptr); + REQUIRE(root.GetFlow().IsLocked() == false); + REQUIRE(root.RequiresRefresh() == true); + REQUIRE(root.GetChildren().IsEmpty()); + REQUIRE(root.GetUnits().GetCount() == 1); + REQUIRE(root.GetTraits().IsEmpty()); + REQUIRE(root.GetReferences() == 1); + + auto it = root.GetUnits().begin(); + REQUIRE(it->GetType() == MetaOf()); + REQUIRE(*it == &testUnit); + REQUIRE(it->GetOwners().GetCount() == 1); + REQUIRE(it->GetOwners()[0] == &root); + REQUIRE(it->GetReferences() == 1); } WHEN("Creating a new unit") { auto unit = root.CreateUnit(); - THEN("Properties should match") { - REQUIRE(root.GetOwner() == nullptr); - REQUIRE(root.GetRuntime() == nullptr); - REQUIRE(root.GetRuntime().IsLocked() == false); - REQUIRE(root.GetFlow() == nullptr); - REQUIRE(root.GetFlow().IsLocked() == false); - REQUIRE(root.RequiresRefresh() == true); - REQUIRE(root.GetChildren().IsEmpty()); - REQUIRE(root.GetUnits().GetCount() == 1); - REQUIRE(root.GetTraits().IsEmpty()); - REQUIRE(root.Reference(0) == 1); - - auto it = root.GetUnits().begin(); - REQUIRE(it->GetType() == MetaOf()); - REQUIRE(*it == unit.As()); - - // Kept once in `unit` - // Kept once in root.mUnitsList - // Kept once in root.mUnitsAmbiguous - REQUIRE(unit.GetUses() == 3); - - REQUIRE(Fractalloc::Instance.Find({}, unit.As())->GetUses() == 3); - REQUIRE(unit.As()->Reference(0) == 3); - REQUIRE(Fractalloc::Instance.Find({}, unit.As())->GetUses() == 3); - REQUIRE(it->GetOwners().GetCount() == 1); - REQUIRE(it->GetOwners()[0] == &root); - REQUIRE(it->Reference(0) == 3); - } + REQUIRE(root.GetOwner() == nullptr); + REQUIRE(root.GetRuntime() == nullptr); + REQUIRE(root.GetRuntime().IsLocked() == false); + REQUIRE(root.GetFlow() == nullptr); + REQUIRE(root.GetFlow().IsLocked() == false); + REQUIRE(root.RequiresRefresh() == true); + REQUIRE(root.GetChildren().IsEmpty()); + REQUIRE(root.GetUnits().GetCount() == 1); + REQUIRE(root.GetTraits().IsEmpty()); + REQUIRE(root.GetReferences() == 1); + + auto it = root.GetUnits().begin(); + REQUIRE(it->GetType() == MetaOf()); + REQUIRE(*it == unit.As()); + + // Kept once in `unit` + // Kept once in root.mUnitsList + // Kept once in root.mUnitsAmbiguous + REQUIRE(unit.GetUses() == 3); + + REQUIRE(Fractalloc::Instance.Find({}, unit.As())->GetUses() == 3); + REQUIRE(unit.As()->GetReferences() == 3); + REQUIRE(Fractalloc::Instance.Find({}, unit.As())->GetUses() == 3); + REQUIRE(it->GetOwners().GetCount() == 1); + REQUIRE(it->GetOwners()[0] == &root); + REQUIRE(it->GetReferences() == 3); } WHEN("Adding a trait") { @@ -181,7 +177,7 @@ TEMPLATE_TEST_CASE("Testing Thing with different kidns of descriptors", REQUIRE(not root.GetUnits()); REQUIRE(not root.GetUnitsMap()); REQUIRE(root.GetTraits().GetCount() == 1); - REQUIRE(root.Reference(0) == 1); + REQUIRE(root.GetReferences() == 1); auto it = root.GetTraits().begin(); REQUIRE(it.GetKey() == MetaOf()); @@ -206,7 +202,7 @@ TEMPLATE_TEST_CASE("Testing Thing with different kidns of descriptors", REQUIRE(not root.GetUnitsMap()); REQUIRE(root.GetTraits().GetCount() == 1); REQUIRE(root.GetName() == "Dimo"); - REQUIRE(root.Reference(0) == 1); + REQUIRE(root.GetReferences() == 1); auto it = root.GetTraits().begin(); REQUIRE(it.GetKey() == MetaOf()); @@ -247,7 +243,7 @@ TEMPLATE_TEST_CASE("Testing Thing with different kidns of descriptors", REQUIRE(root.GetUnits().GetCount() == 2); REQUIRE(root.GetTraits().GetCount() == 1); REQUIRE(root.GetName() == "Root"); - REQUIRE(root.Reference(0) == 1); + REQUIRE(root.GetReferences() == 1); auto child1 = root.GetChildren()[0]; REQUIRE(child1->GetOwner() == &root); @@ -269,7 +265,7 @@ TEMPLATE_TEST_CASE("Testing Thing with different kidns of descriptors", // child1's GrandChild2 owner contains 1 reference //--------------------------------------------------- // total: 8 references confirmed - REQUIRE(child1->Reference(0) == 5); + REQUIRE(child1->GetReferences() == 5); auto child2 = root.GetChildren()[1]; REQUIRE(child2->GetOwner() == &root); @@ -282,7 +278,7 @@ TEMPLATE_TEST_CASE("Testing Thing with different kidns of descriptors", REQUIRE(not child2->GetUnits()); REQUIRE(child2->GetTraits().GetCount() == 1); REQUIRE(child2->GetName() == "Child2"); - REQUIRE(child2->Reference(0) == 1); + REQUIRE(child2->GetReferences() == 1); auto grandchild1 = child1->GetChildren()[0]; REQUIRE(grandchild1->GetOwner() == child1); @@ -295,7 +291,7 @@ TEMPLATE_TEST_CASE("Testing Thing with different kidns of descriptors", REQUIRE(not grandchild1->GetUnits()); REQUIRE(grandchild1->GetTraits().GetCount() == 1); REQUIRE(grandchild1->GetName() == "GrandChild1"); - REQUIRE(grandchild1->Reference(0) == 1); + REQUIRE(grandchild1->GetReferences() == 1); auto grandchild2 = child1->GetChildren()[1]; REQUIRE(grandchild2->GetOwner() == child1); @@ -308,7 +304,7 @@ TEMPLATE_TEST_CASE("Testing Thing with different kidns of descriptors", REQUIRE(not grandchild2->GetUnits()); REQUIRE(grandchild2->GetTraits().GetCount() == 1); REQUIRE(grandchild2->GetName() == "GrandChild2"); - REQUIRE(grandchild2->Reference(0) == 1); + REQUIRE(grandchild2->GetReferences() == 1); Logger::Special("End: Creating a Thing by descriptor"); } From 8d47cb56420cf38eeadb38545dbfa250ed5ac4f8 Mon Sep 17 00:00:00 2001 From: Epixu Date: Wed, 16 Oct 2024 19:15:10 +0300 Subject: [PATCH 24/34] Proper Thing::Teardown and Asset::Reference; Common verbosity macros --- include/Langulus/Asset.hpp | 27 ++++---- include/Langulus/Asset.inl | 16 +++-- source/Common.hpp | 16 +++++ source/Thing-Gather.inl | 16 +---- source/Thing-Seek.inl | 16 +---- source/Thing-Traits.cpp | 12 ---- source/Thing-Verbs.cpp | 12 +--- source/Thing.cpp | 131 ++++++++++++++++++------------------- source/Thing.hpp | 3 +- source/Thing.inl | 25 +------ 10 files changed, 114 insertions(+), 160 deletions(-) diff --git a/include/Langulus/Asset.hpp b/include/Langulus/Asset.hpp index df628e1..16f2da4 100644 --- a/include/Langulus/Asset.hpp +++ b/include/Langulus/Asset.hpp @@ -26,6 +26,9 @@ namespace Langulus::A Ref mFolder; public: + // @attention never delete stuff from this call! Do it on + // Update() instead + virtual void RequestGarbageCollection() = 0; auto GetFolder() const noexcept -> const Ref&; }; @@ -56,25 +59,23 @@ namespace Langulus::A void Commit(auto&&); template - NOD() auto GetData(Offset = 0) const noexcept -> const Data*; - NOD() auto GetData(TMeta, Offset = 0) const noexcept -> const Data*; - + NOD() auto GetData(Offset = 0) noexcept -> Data*; template - NOD() auto GetDataList() const noexcept -> const DataList*; - NOD() auto GetDataList(TMeta) const noexcept -> const DataList*; + NOD() auto GetData(Offset = 0) const noexcept -> Data const*; - NOD() auto GetDataListMap() const noexcept -> DataListMap const&; + NOD() auto GetData(TMeta, Offset = 0) noexcept -> Data*; + NOD() auto GetData(TMeta, Offset = 0) const noexcept -> Data const*; - protected: template - NOD() auto GetData(Offset = 0) noexcept -> Data*; - NOD() auto GetData(TMeta, Offset = 0) noexcept -> Data*; - + NOD() auto GetDataList() noexcept -> DataList*; template - NOD() auto GetDataList() noexcept -> DataList*; - NOD() auto GetDataList(TMeta) noexcept -> DataList*; + NOD() auto GetDataList() const noexcept -> DataList const*; + + NOD() auto GetDataList(TMeta) noexcept -> DataList*; + NOD() auto GetDataList(TMeta) const noexcept -> DataList const*; - NOD() auto GetDataListMap() noexcept -> DataListMap&; + NOD() auto GetDataListMap() noexcept -> DataListMap&; + NOD() auto GetDataListMap() const noexcept -> DataListMap const&; }; } // namespace Langulus::A diff --git a/include/Langulus/Asset.inl b/include/Langulus/Asset.inl index b4445a2..50a5266 100644 --- a/include/Langulus/Asset.inl +++ b/include/Langulus/Asset.inl @@ -127,15 +127,23 @@ namespace Langulus::A mDataListMap.Insert(trait, S::Nest(content)); } - /// Detach the asset + /// Reference or dereference the asset + /// @param x - number of references to add/subtract + /// @return the number of remaining references LANGULUS(INLINED) Count Asset::Reference(int x) { - if (Unit::Reference(x) == 1) { + const auto remaining = Unit::Reference(x); + if (remaining == 1 and mProducer) { + // If there's a producer, notify it when references reach 1 + // - it means that the only reference is inside the factory, + // and it's the factory's responsibility to collect garbage, + // most likely on module Update(). + mProducer->RequestGarbageCollection(); mDataListMap.Reset(); - ProducedFrom::Detach(); + ProducedFrom::Teardown(); } - return GetReferences(); + return remaining; } } // namespace Langulus::A diff --git a/source/Common.hpp b/source/Common.hpp index 408211e..dd33ab3 100644 --- a/source/Common.hpp +++ b/source/Common.hpp @@ -33,3 +33,19 @@ namespace Langulus /// Make the rest of the code aware, that Langulus::Entity has been included #define LANGULUS_LIBRARY_ENTITY() 1 + +#if 1 + #define ENTITY_VERBOSE_ENABLED() 1 + #define ENTITY_VERBOSE_SELF(...) Logger::Info(this, ": ", __VA_ARGS__) + #define ENTITY_VERBOSE_SELF_TAB(...) const auto scoped = Logger::InfoTab(this, ": ", __VA_ARGS__) + #define ENTITY_VERBOSE(...) Logger::Append(__VA_ARGS__) + #define ENTITY_CREATION_VERBOSE_SELF(...) Logger::Verbose(Self(), __VA_ARGS__) + #define ENTITY_SELECTION_VERBOSE_SELF(...) Logger::Verbose(Self(), __VA_ARGS__) +#else + #define ENTITY_VERBOSE_ENABLED() 0 + #define ENTITY_VERBOSE_SELF(...) LANGULUS(NOOP) + #define ENTITY_VERBOSE_SELF_TAB(...) LANGULUS(NOOP) + #define ENTITY_VERBOSE(...) LANGULUS(NOOP) + #define ENTITY_CREATION_VERBOSE_SELF(...) LANGULUS(NOOP) + #define ENTITY_SELECTION_VERBOSE_SELF(...) LANGULUS(NOOP) +#endif diff --git a/source/Thing-Gather.inl b/source/Thing-Gather.inl index a9ce6e2..40e75c3 100644 --- a/source/Thing-Gather.inl +++ b/source/Thing-Gather.inl @@ -9,16 +9,6 @@ #include "Thing.hpp" #include "Hierarchy-Gather.inl" -#if 0 - #define ENTITY_VERBOSE_ENABLED() 1 - #define ENTITY_VERBOSE_SELF(...) Logger::Verbose(Self(), __VA_ARGS__) - #define ENTITY_VERBOSE(...) Logger::Append(__VA_ARGS__) -#else - #define ENTITY_VERBOSE_ENABLED() 0 - #define ENTITY_VERBOSE_SELF(...) LANGULUS(NOOP) - #define ENTITY_VERBOSE(...) LANGULUS(NOOP) -#endif - namespace Langulus::Entity { @@ -37,7 +27,7 @@ namespace Langulus::Entity if (found) { auto& list = mUnitsAmbiguous.GetValue(found); for (auto& unit : list) - result << unit/*.Get()*/; + result << unit; } } @@ -186,7 +176,3 @@ namespace Langulus::Entity } } // namespace Langulus::Entity - -#undef ENTITY_VERBOSE_ENABLED -#undef ENTITY_VERBOSE_SELF -#undef ENTITY_VERBOSE diff --git a/source/Thing-Seek.inl b/source/Thing-Seek.inl index bbe0360..fb7bfd0 100644 --- a/source/Thing-Seek.inl +++ b/source/Thing-Seek.inl @@ -9,16 +9,6 @@ #include "Thing.hpp" #include "Hierarchy-Seek.inl" -#if 0 - #define ENTITY_VERBOSE_ENABLED() 1 - #define ENTITY_VERBOSE_SELF(...) Logger::Verbose(Self(), __VA_ARGS__) - #define ENTITY_VERBOSE(...) Logger::Append(__VA_ARGS__) -#else - #define ENTITY_VERBOSE_ENABLED() 0 - #define ENTITY_VERBOSE_SELF(...) LANGULUS(NOOP) - #define ENTITY_VERBOSE(...) LANGULUS(NOOP) -#endif - namespace Langulus::Entity { @@ -369,8 +359,4 @@ namespace Langulus::Entity return SeekValue(meta, output, offset); } -} // namespace Langulus::Entity - -#undef ENTITY_VERBOSE_ENABLED -#undef ENTITY_VERBOSE_SELF -#undef ENTITY_VERBOSE \ No newline at end of file +} // namespace Langulus::Entity \ No newline at end of file diff --git a/source/Thing-Traits.cpp b/source/Thing-Traits.cpp index c8fbd9d..8e0c3e2 100644 --- a/source/Thing-Traits.cpp +++ b/source/Thing-Traits.cpp @@ -9,18 +9,6 @@ #include "Thing.inl" #include "Thing-Seek.inl" -#if 0 - #define ENTITY_VERBOSE_ENABLED() 1 - #define ENTITY_VERBOSE_SELF(...) Logger::Verbose(this, ": ", __VA_ARGS__) - #define ENTITY_VERBOSE_SELF_TAB(...) const auto scoped = Logger::VerboseTab(this, ": ", __VA_ARGS__) - #define ENTITY_VERBOSE(...) Logger::Append(__VA_ARGS__) -#else - #define ENTITY_VERBOSE_ENABLED() 0 - #define ENTITY_VERBOSE_SELF(...) LANGULUS(NOOP) - #define ENTITY_VERBOSE_SELF_TAB(...) LANGULUS(NOOP) - #define ENTITY_VERBOSE(...) LANGULUS(NOOP) -#endif - namespace Langulus::Entity { diff --git a/source/Thing-Verbs.cpp b/source/Thing-Verbs.cpp index add59f1..c03ca62 100644 --- a/source/Thing-Verbs.cpp +++ b/source/Thing-Verbs.cpp @@ -9,12 +9,6 @@ #include "Thing.inl" #include -#if 0 - #define SELECT_VERBOSE_SELF(...) Logger::Verbose(Self(), __VA_ARGS__) -#else - #define SELECT_VERBOSE_SELF(...) LANGULUS(NOOP) -#endif - namespace Langulus::Entity { @@ -180,19 +174,19 @@ namespace Langulus::Entity if (not mismatch) { // We're not seeking an entity, but components/traits if (selectedTraits) { - SELECT_VERBOSE_SELF(Logger::Green, + ENTITY_SELECTION_VERBOSE_SELF(Logger::Green, "Trait(s) selected: ", selectedTraits); verb << selectedTraits; } if (selectedUnits) { - SELECT_VERBOSE_SELF(Logger::Green, + ENTITY_SELECTION_VERBOSE_SELF(Logger::Green, "Unit(s) selected: ", selectedUnits); verb << selectedUnits; } if (selectedEntities) { - SELECT_VERBOSE_SELF(Logger::Green, + ENTITY_SELECTION_VERBOSE_SELF(Logger::Green, "Entity(s) selected: ", selectedEntities); verb << selectedEntities; } diff --git a/source/Thing.cpp b/source/Thing.cpp index 988cf71..da2e96f 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -8,18 +8,6 @@ #include "Thing.hpp" #include "Thing.inl" -#if 1 - #define ENTITY_VERBOSE_ENABLED() 1 - #define ENTITY_VERBOSE_SELF(...) Logger::Info(this, ": ", __VA_ARGS__) - #define ENTITY_VERBOSE_SELF_TAB(...) const auto scoped = Logger::InfoTab(this, ": ", __VA_ARGS__) - #define ENTITY_VERBOSE(...) Logger::Append(__VA_ARGS__) -#else - #define ENTITY_VERBOSE_ENABLED() 0 - #define ENTITY_VERBOSE_SELF(...) LANGULUS(NOOP) - #define ENTITY_VERBOSE_SELF_TAB(...) LANGULUS(NOOP) - #define ENTITY_VERBOSE(...) LANGULUS(NOOP) -#endif - namespace Langulus::Entity { @@ -32,6 +20,8 @@ namespace Langulus::Entity /// Descriptor-constructor /// @param describe - instructions for creating the entity Thing::Thing(Describe&& describe) : Resolvable {this} { + ENTITY_VERBOSE_SELF_TAB("Created from descriptor: ", *describe); + if (*describe) { Verbs::Create creator {&(*describe)}; Create(creator); @@ -58,6 +48,8 @@ namespace Langulus::Entity : Resolvable {this} , mOwner {parent} { + ENTITY_VERBOSE_SELF_TAB("Created manually"); + if (parent) { parent->AddChild(this); mRuntime = parent->GetRuntime(); @@ -111,7 +103,7 @@ namespace Langulus::Entity if (other.mOwner) other.mOwner->RemoveChild(&other); - ENTITY_VERBOSE_SELF("moved from ", other); + ENTITY_VERBOSE_SELF("Moved from ", other); } /// Abandon constructor @@ -141,7 +133,7 @@ namespace Langulus::Entity if (other->mOwner) other->mOwner->RemoveChild(&*other); - ENTITY_VERBOSE_SELF("abandoned from ", *other); + ENTITY_VERBOSE_SELF("Abandoned from ", *other); } /// Clone constructor @@ -157,74 +149,81 @@ namespace Langulus::Entity TODO(); //TODO clone flow and runtime if pinned, recreate modules if new runtime, // recreate units and traits, then recreate children - ENTITY_VERBOSE_SELF("cloned from ", *other); + ENTITY_VERBOSE_SELF("Cloned from ", *other); } + /// Destroy the thing Thing::~Thing() { - if (GetReferences()) - Reference(-1); - } + // First stage destruction that severs all connections + // If Thing was on the stack, this will be the first time it's + // called. If it was on the managed heap, it would've been called + // from the Reference routine + Teardown(); - /// Reference and detach all parents of all children - Count Thing::Reference(int x) { - if (Referenced::Reference(x) == 0) { - // Traits might be exposing members in units. Make sure we - // dereference those first - mTraits.Reset(); + LANGULUS_ASSUME(DevAssumes, GetReferences() <= 1, + "Can't teardown while this Thing is still used", " in ", + GetReferences(), " places" + ); - // Decouple all units from this owner because units might get - // destroyed upon destroying mUnitsList and mUnitsAmbiguous - // If they still have owners, they will attempt to Decouple - // themselves from already destroyed mUnitsList/mUnitsAmbiguous - for (auto& unit : mUnitsList) { - ENTITY_VERBOSE_SELF("Decoupling unit: ", unit); - unit->mOwners.Remove(this); - ENTITY_VERBOSE_SELF("...", GetReferences(), " uses remain"); - } + // Destroy the entire herarchy under this Thing + ENTITY_VERBOSE_SELF_TAB("Destroying..."); - // The same applies for child things + #if LANGULUS(DEBUG) for (auto& child : mChildren) { - if (child->mOwner) { - ENTITY_VERBOSE_SELF("Decoupling child: ", child); - LANGULUS_ASSUME(DevAssumes, child->mOwner == this, "Parent mismatch"); - child->mOwner.Reset(); - ENTITY_VERBOSE_SELF("...", GetReferences(), " uses remain"); + if (child->GetReferences() != 1) { + Logger::Error( + "Child can't be destroyed - it is still referenced ", + child->GetReferences(), " times instead of once: ", child + ); } } - /*ENTITY_VERBOSE_SELF_TAB("Detaching (", GetReferences(), " uses):"); - - mTraits.Reset(); - - // Decouple all units from this owner for (auto& unit : mUnitsList) { - ENTITY_VERBOSE_SELF("Decoupling unit: ", unit); - unit->mOwners.Reset(); - ENTITY_VERBOSE_SELF("...", GetReferences(), " uses remain"); - } - - mUnitsList.Reset(); - mUnitsAmbiguous.Reset(); - - if (not mFlow.IsLocked()) - mFlow.Reset(); - - // Decouple all children from this - for (auto& child : mChildren) { - if (child->mOwner) { - ENTITY_VERBOSE_SELF("Decoupling child: ", child); - LANGULUS_ASSUME(DevAssumes, child->mOwner == this, - "Parent mismatch"); - child->mOwner.Reset(); - child->Reference(x); - ENTITY_VERBOSE_SELF("...", GetReferences(), " uses remain"); + if (unit->GetReferences() > 3) { + Logger::Error( + "Unit can't be destroyed - it is still referenced ", + unit->GetReferences(), " times instead of thrice (or lower): ", unit + ); } } + #endif + } + + /// This is used for first-stage destruction, severing ties to avoid + /// circular dependencies. After this runs, there should be only one + /// reference remaining for this Thing + void Thing::Teardown() { + ENTITY_VERBOSE_SELF_TAB("Teardown initiated..."); + // Reset owner, so that only one reference to this Thing remains + // in the hierarchy: the owner's mChildren + mOwner.Reset(); + + // Traits might be exposing members in units. Make sure we + // dereference those first, so that units have as small number of + // references as possible + ENTITY_VERBOSE_SELF("Tearing off traits (name might change)"); + mTraits.Reset(); - mChildren.Reset();*/ + // Decouple all units from this owner because units might get + // destroyed upon destroying mUnitsList and mUnitsAmbiguous, if + // the Units were created on the stack. + // If they still have owners, they will attempt to Decouple in + // A::Unit::~Unit from already destroyed mUnitsList/Ambiguous + for (auto& unit : mUnitsList) { + ENTITY_VERBOSE_SELF("Tearing off unit: ", unit); + unit->mOwners.Remove(this); + ENTITY_VERBOSE_SELF("...", GetReferences(), " uses remain"); } - return GetReferences(); + // Propagate Teardown through the hierarchy of Things + for (auto& child : mChildren) + child->Teardown(); + + ENTITY_VERBOSE_SELF("Teardown complete: ", GetReferences(), " uses remain"); + LANGULUS_ASSERT(GetReferences() <= 1, Destruct, "After teardown, " + "Thing should have one (or zero) references remaining, from " + "its former owner's mChildren container (if not a root)" + ); } /// Compare two entities diff --git a/source/Thing.hpp b/source/Thing.hpp index b04d5bc..5e36e31 100644 --- a/source/Thing.hpp +++ b/source/Thing.hpp @@ -48,6 +48,7 @@ namespace Langulus::Entity protected: LANGULUS_API(ENTITY) void ResetRuntime(Runtime*); LANGULUS_API(ENTITY) void ResetFlow(Temporal*); + LANGULUS_API(ENTITY) void Teardown(); // The order of members is critical! // Runtime should be destroyed last, hence it is the first member @@ -85,8 +86,6 @@ namespace Langulus::Entity template NOD() static Thing Root(CT::String auto&&...); - LANGULUS_API(ENTITY) Count Reference(int); - // Shallow copy is disabled, you should be able only to clone, // move, or abandon Thing(const Thing&) = delete; diff --git a/source/Thing.inl b/source/Thing.inl index 7decd5a..5c801de 100644 --- a/source/Thing.inl +++ b/source/Thing.inl @@ -10,22 +10,6 @@ #include "Thing-Gather.inl" #include "Thing-Seek.inl" -#if 0 - #define ENTITY_VERBOSE_ENABLED() 1 - #define ENTITY_VERBOSE_SELF(...) Logger::Verbose(this, ": ", __VA_ARGS__) - #define ENTITY_VERBOSE_SELF_TAB(...) const auto scoped = Logger::VerboseTab(this, ": ", __VA_ARGS__) - #define ENTITY_VERBOSE(...) Logger::Append(__VA_ARGS__) - #define ENTITY_CREATION_VERBOSE_SELF(...) Logger::Verbose(Self(), __VA_ARGS__) - #define ENTITY_SELECTION_VERBOSE_SELF(...) Logger::Verbose(Self(), __VA_ARGS__) -#else - #define ENTITY_VERBOSE_ENABLED() 0 - #define ENTITY_VERBOSE_SELF(...) LANGULUS(NOOP) - #define ENTITY_VERBOSE_SELF_TAB(...) LANGULUS(NOOP) - #define ENTITY_VERBOSE(...) LANGULUS(NOOP) - #define ENTITY_CREATION_VERBOSE_SELF(...) LANGULUS(NOOP) - #define ENTITY_SELECTION_VERBOSE_SELF(...) LANGULUS(NOOP) -#endif - namespace Langulus::Entity { @@ -707,11 +691,4 @@ namespace Langulus::A return verb; } -} // namespace Langulus::A - -#undef ENTITY_VERBOSE_ENABLED -#undef ENTITY_VERBOSE_SELF -#undef ENTITY_VERBOSE_SELF_TAB -#undef ENTITY_VERBOSE -#undef ENTITY_CREATION_VERBOSE_SELF -#undef ENTITY_SELECTION_VERBOSE_SELF +} // namespace Langulus::A \ No newline at end of file From 69857d10dde31b893ea44eab00ad4b693f1af8fa Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Thu, 17 Oct 2024 10:29:04 +0300 Subject: [PATCH 25/34] Maintenance --- include/Langulus/Asset.hpp | 2 -- include/Langulus/Asset.inl | 19 ------------------- include/Langulus/IO.hpp | 16 ++++++++-------- source/Runtime.cpp | 24 ++++++++++++------------ source/Runtime.hpp | 38 +++++++++++++++++++------------------- source/Thing.cpp | 16 +++++++++------- 6 files changed, 48 insertions(+), 67 deletions(-) diff --git a/include/Langulus/Asset.hpp b/include/Langulus/Asset.hpp index 16f2da4..7fbefd5 100644 --- a/include/Langulus/Asset.hpp +++ b/include/Langulus/Asset.hpp @@ -51,8 +51,6 @@ namespace Langulus::A public: Asset() : Resolvable {this} {} - Count Reference(int); - virtual bool Generate(TMeta, Offset = 0) { return true; } template diff --git a/include/Langulus/Asset.inl b/include/Langulus/Asset.inl index 50a5266..6facb16 100644 --- a/include/Langulus/Asset.inl +++ b/include/Langulus/Asset.inl @@ -127,23 +127,4 @@ namespace Langulus::A mDataListMap.Insert(trait, S::Nest(content)); } - /// Reference or dereference the asset - /// @param x - number of references to add/subtract - /// @return the number of remaining references - LANGULUS(INLINED) - Count Asset::Reference(int x) { - const auto remaining = Unit::Reference(x); - if (remaining == 1 and mProducer) { - // If there's a producer, notify it when references reach 1 - // - it means that the only reference is inside the factory, - // and it's the factory's responsibility to collect garbage, - // most likely on module Update(). - mProducer->RequestGarbageCollection(); - mDataListMap.Reset(); - ProducedFrom::Teardown(); - } - - return remaining; - } - } // namespace Langulus::A diff --git a/include/Langulus/IO.hpp b/include/Langulus/IO.hpp index 641c743..c444baf 100644 --- a/include/Langulus/IO.hpp +++ b/include/Langulus/IO.hpp @@ -20,6 +20,8 @@ namespace Langulus::A /// Abstract file system module /// struct FileSystem : virtual Module { + LANGULUS_BASES(Module); + protected: // Working directory path // This is the only full path that is exposed to the system, @@ -30,8 +32,6 @@ namespace Langulus::A Path mMainDataPath; public: - LANGULUS_BASES(Module); - NOD() virtual auto GetFile (const Path&) -> Ref = 0; NOD() virtual auto GetFolder(const Path&) -> Ref = 0; @@ -44,6 +44,9 @@ namespace Langulus::A /// Abstract file interface /// struct File : virtual Unit { + LANGULUS(PRODUCER) FileSystem; + LANGULUS_BASES(Unit); + protected: Path mFilePath; bool mExists {}; @@ -59,9 +62,6 @@ namespace Langulus::A Token mFileExtension; public: - LANGULUS(PRODUCER) FileSystem; - LANGULUS_BASES(Unit); - NOD() virtual auto ReadAs (DMeta) const -> Many = 0; NOD() virtual auto RelativeFile (const Path&) const -> Ref = 0; NOD() virtual auto RelativeFolder(const Path&) const -> Ref = 0; @@ -130,15 +130,15 @@ namespace Langulus::A /// Abstract folder interface /// struct Folder : virtual Unit { + LANGULUS(PRODUCER) FileSystem; + LANGULUS_BASES(Unit); + protected: Path mFolderPath; bool mExists = false; bool mIsReadOnly = false; public: - LANGULUS(PRODUCER) FileSystem; - LANGULUS_BASES(Unit); - NOD() virtual auto RelativeFile (const Path&) const -> Ref = 0; NOD() virtual auto RelativeFolder(const Path&) const -> Ref = 0; diff --git a/source/Runtime.cpp b/source/Runtime.cpp index a178e1f..12181bb 100644 --- a/source/Runtime.cpp +++ b/source/Runtime.cpp @@ -183,7 +183,7 @@ namespace Langulus::Entity Logger::Append(library.mKey, " "); Logger::Error(this, ": This likely involves a memory leak, " - "that withholds managed data, reflected by the given modules"); + "that withholds managed data reflected by the given modules"); IF_LANGULUS_MANAGED_MEMORY(Allocator::CollectGarbage()); IF_LANGULUS_MEMORY_STATISTICS(Allocator::DumpPools()); @@ -195,7 +195,7 @@ namespace Langulus::Entity /// @param name - module name /// @param descriptor - module initialization descriptor /// @return the new module instance - A::Module* Runtime::InstantiateModule(const Token& name, const Many& descriptor) { + auto Runtime::InstantiateModule(const Token& name, const Many& descriptor) -> A::Module* { // Load the library if not loaded yet const auto library = LoadSharedLibrary(name); @@ -267,7 +267,7 @@ namespace Langulus::Entity /// @param library - the library handle /// @param descriptor - module initialization descriptor /// @return the new module instance - A::Module* Runtime::InstantiateModule(const SharedLibrary& library, const Many& descriptor) { + auto Runtime::InstantiateModule(const SharedLibrary& library, const Many& descriptor) -> A::Module* { if (not library.IsValid()) return nullptr; @@ -330,7 +330,7 @@ namespace Langulus::Entity /// the RTTI::Boundary /// @return the module handle (OS dependent) LANGULUS(NOINLINE) - Runtime::SharedLibrary Runtime::LoadSharedLibrary(const Token& name) { + auto Runtime::LoadSharedLibrary(const Token& name) -> SharedLibrary { // Check if this library is already loaded const auto preloaded = mLibraries.FindIt(name); if (preloaded) @@ -573,7 +573,7 @@ namespace Langulus::Entity /// Get the dependency module of a given type /// @param type - the type to search for /// @return the shared library handle, you should check if it's valid - Runtime::SharedLibrary Runtime::GetDependency(DMeta type) const noexcept { + auto Runtime::GetDependency(DMeta type) const noexcept -> SharedLibrary { if (type->mLibraryName == RTTI::MainBoundary) return {}; @@ -587,7 +587,7 @@ namespace Langulus::Entity /// Get a module instance by type /// @param type - the type to search for /// @return the module instance - const ModuleList& Runtime::GetModules(DMeta type) const noexcept { + auto Runtime::GetModules(DMeta type) const noexcept -> const ModuleList& { auto found = mModulesByType.FindIt(type); if (found) return found.GetValue(); @@ -600,14 +600,14 @@ namespace Langulus::Entity /// Get the dependency module of a given type by token /// @param token - type token /// @return the shared library handle, you should check if it's valid - Runtime::SharedLibrary Runtime::GetDependencyToken(const Token& token) const noexcept { + auto Runtime::GetDependencyToken(const Token& token) const noexcept -> SharedLibrary { return GetDependency(RTTI::GetMetaData(token)); } /// Get a module instance by type token /// @param token - type token /// @return the module instance, or nullptr if not found - const ModuleList& Runtime::GetModulesToken(const Token& token) const noexcept { + auto Runtime::GetModulesToken(const Token& token) const noexcept -> const ModuleList& { return GetModules(RTTI::GetMetaData(token)); } #endif @@ -634,7 +634,7 @@ namespace Langulus::Entity /// Get a file interface, relying on external modules to find it /// @param path - the path for the file /// @return the file interface, or nullptr if file doesn't exist - Ref Runtime::GetFile(const Path& path) { + auto Runtime::GetFile(const Path& path) -> Ref { auto& fileSystems = GetModules(); LANGULUS_ASSERT(fileSystems, Module, "Can't retrieve file `", path, "` - no file system module available"); @@ -644,7 +644,7 @@ namespace Langulus::Entity /// Get a folder interface, relying on external modules to find it /// @param path - the path for the folder /// @return the folder interface, or nullptr if folder doesn't exist - Ref Runtime::GetFolder(const Path& path) { + auto Runtime::GetFolder(const Path& path) -> Ref { auto& fileSystems = GetModules(); LANGULUS_ASSERT(fileSystems, Module, "Can't retrieve folder `", path, "` - no file system module available"); @@ -653,7 +653,7 @@ namespace Langulus::Entity /// Get the current working path (where the main exe was executed) /// @return the path - const Path& Runtime::GetWorkingPath() const { + auto Runtime::GetWorkingPath() const -> const Path& { auto& fileSystems = GetModules(); LANGULUS_ASSERT(fileSystems, Module, "Can't retrieve working path", " - no file system module available"); @@ -662,7 +662,7 @@ namespace Langulus::Entity /// Get the current data path, like GetWorkingPath() / "data" /// @return the path - const Path& Runtime::GetDataPath() const { + auto Runtime::GetDataPath() const -> const Path& { auto& fileSystems = GetModules(); LANGULUS_ASSERT(fileSystems, Module, "Can't retrieve data path", " - no file system module available"); diff --git a/source/Runtime.hpp b/source/Runtime.hpp index 368ffca..19543cd 100644 --- a/source/Runtime.hpp +++ b/source/Runtime.hpp @@ -61,12 +61,12 @@ namespace Langulus::Entity /// Explicit abandon construction, for optimized containment /// @param other - the library to abandon SharedLibrary(Abandoned&& other) noexcept - : mHandle {other->mHandle} - , mEntry {other->mEntry} - , mCreator {other->mCreator} - , mInfo {other->mInfo} - , mModuleType {other->mModuleType} - , mBoundary {other->mBoundary} + : mHandle {other->mHandle} + , mEntry {other->mEntry} + , mCreator {other->mCreator} + , mInfo {other->mInfo} + , mModuleType {other->mModuleType} + , mBoundary {other->mBoundary} , mMarkedForUnload {other->mMarkedForUnload} {} /// Check if the shared library handle is valid @@ -98,7 +98,7 @@ namespace Langulus::Entity protected: NOD() LANGULUS_API(ENTITY) - SharedLibrary LoadSharedLibrary(const Token&); + auto LoadSharedLibrary(const Token&) -> SharedLibrary; NOD() bool UnloadSharedLibrary(const SharedLibrary&); public: @@ -113,38 +113,38 @@ namespace Langulus::Entity NOD() auto GetOwner() const noexcept { return mOwner; } NOD() LANGULUS_API(ENTITY) - A::Module* InstantiateModule(const Token&, const Many& = {}); + auto InstantiateModule(const Token&, const Many& = {}) -> A::Module*; NOD() LANGULUS_API(ENTITY) - A::Module* InstantiateModule(const SharedLibrary&, const Many& = {}); + auto InstantiateModule(const SharedLibrary&, const Many& = {}) -> A::Module*; NOD() LANGULUS_API(ENTITY) - SharedLibrary GetDependency(DMeta) const noexcept; + auto GetDependency(DMeta) const noexcept -> SharedLibrary; NOD() LANGULUS_API(ENTITY) - const ModuleList& GetModules(DMeta) const noexcept; + auto GetModules(DMeta) const noexcept -> const ModuleList&; - template - NOD() const ModuleList& GetModules() const noexcept { + template NOD() + auto GetModules() const noexcept -> const ModuleList& { return GetModules(MetaDataOf()); } #if LANGULUS_FEATURE(MANAGED_REFLECTION) NOD() LANGULUS_API(ENTITY) - SharedLibrary GetDependencyToken(const Token&) const noexcept; + auto GetDependencyToken(const Token&) const noexcept -> SharedLibrary; NOD() LANGULUS_API(ENTITY) - const ModuleList& GetModulesToken(const Token&) const noexcept; + auto GetModulesToken(const Token&) const noexcept -> const ModuleList&; #endif NOD() LANGULUS_API(ENTITY) - Ref GetFile(const Path&); + auto GetFile(const Path&) -> Ref; NOD() LANGULUS_API(ENTITY) - Ref GetFolder(const Path&); + auto GetFolder(const Path&) -> Ref; NOD() LANGULUS_API(ENTITY) - const Path& GetWorkingPath() const; + auto GetWorkingPath() const -> const Path&; NOD() LANGULUS_API(ENTITY) - const Path& GetDataPath() const; + auto GetDataPath() const -> const Path&; LANGULUS_API(ENTITY) bool Update(Time); diff --git a/source/Thing.cpp b/source/Thing.cpp index da2e96f..90d9a35 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -172,8 +172,8 @@ namespace Langulus::Entity for (auto& child : mChildren) { if (child->GetReferences() != 1) { Logger::Error( - "Child can't be destroyed - it is still referenced ", - child->GetReferences(), " times instead of once: ", child + child, " can't be destroyed - it is still referenced ", + child->GetReferences(), " times instead of once" ); } } @@ -181,8 +181,8 @@ namespace Langulus::Entity for (auto& unit : mUnitsList) { if (unit->GetReferences() > 3) { Logger::Error( - "Unit can't be destroyed - it is still referenced ", - unit->GetReferences(), " times instead of thrice (or lower): ", unit + unit, " can't be destroyed - it is still referenced ", + unit->GetReferences(), " times instead of 3 (or less)" ); } } @@ -193,7 +193,9 @@ namespace Langulus::Entity /// circular dependencies. After this runs, there should be only one /// reference remaining for this Thing void Thing::Teardown() { - ENTITY_VERBOSE_SELF_TAB("Teardown initiated..."); + ENTITY_VERBOSE_SELF_TAB( + "Teardown initiated at ", GetReferences(), " uses..."); + // Reset owner, so that only one reference to this Thing remains // in the hierarchy: the owner's mChildren mOwner.Reset(); @@ -210,9 +212,9 @@ namespace Langulus::Entity // If they still have owners, they will attempt to Decouple in // A::Unit::~Unit from already destroyed mUnitsList/Ambiguous for (auto& unit : mUnitsList) { - ENTITY_VERBOSE_SELF("Tearing off unit: ", unit); + ENTITY_VERBOSE_SELF( + "Tearing off unit ", unit, " at ", unit->GetReferences(), " uses..."); unit->mOwners.Remove(this); - ENTITY_VERBOSE_SELF("...", GetReferences(), " uses remain"); } // Propagate Teardown through the hierarchy of Things From e323bc887090ac9c88f855e7500b1abb1f9f279e Mon Sep 17 00:00:00 2001 From: Epixu Date: Thu, 17 Oct 2024 17:33:18 +0300 Subject: [PATCH 26/34] Mostly maintenance --- include/Langulus/Asset.hpp | 2 +- source/Common.hpp | 2 +- source/Module.hpp | 16 ++++++++++------ source/Runtime.cpp | 15 +++++++++++---- source/Thing.cpp | 24 +++++++++++++----------- source/Unit.hpp | 2 +- 6 files changed, 37 insertions(+), 24 deletions(-) diff --git a/include/Langulus/Asset.hpp b/include/Langulus/Asset.hpp index 7fbefd5..e930b43 100644 --- a/include/Langulus/Asset.hpp +++ b/include/Langulus/Asset.hpp @@ -6,7 +6,7 @@ /// SPDX-License-Identifier: GPL-3.0-or-later /// #pragma once -#include "../Entity/Thing.hpp" +#include "IO.hpp" #include #include diff --git a/source/Common.hpp b/source/Common.hpp index dd33ab3..bfee6c5 100644 --- a/source/Common.hpp +++ b/source/Common.hpp @@ -34,7 +34,7 @@ namespace Langulus /// Make the rest of the code aware, that Langulus::Entity has been included #define LANGULUS_LIBRARY_ENTITY() 1 -#if 1 +#if 0 #define ENTITY_VERBOSE_ENABLED() 1 #define ENTITY_VERBOSE_SELF(...) Logger::Info(this, ": ", __VA_ARGS__) #define ENTITY_VERBOSE_SELF_TAB(...) const auto scoped = Logger::InfoTab(this, ": ", __VA_ARGS__) diff --git a/source/Module.hpp b/source/Module.hpp index 75227b3..53294fd 100644 --- a/source/Module.hpp +++ b/source/Module.hpp @@ -59,17 +59,19 @@ namespace Langulus::A /// External module interface /// class Module : public virtual Resolvable { - LANGULUS(PRODUCER) Entity::Runtime; + public: + using Runtime = Entity::Runtime; + LANGULUS(PRODUCER) Runtime; LANGULUS_BASES(Resolvable); private: // Runtime that owns the module instance - Entity::Runtime* mRuntime; + Runtime* mRuntime; public: - Module(Entity::Runtime* runtime) IF_UNSAFE(noexcept) + Module(Runtime* runtime) IF_UNSAFE(noexcept) : Resolvable {this} - , mRuntime {runtime} {} + , mRuntime {runtime} {} Module() noexcept = delete; Module(const Module&) = delete; @@ -93,14 +95,16 @@ namespace Langulus::A }; using EntryFunction = void(*)(DMeta&, MetaList&); - using CreateFunction = Module*(*)(Entity::Runtime*, const Many&); + using CreateFunction = Module*(*)(Runtime*, const Many&); using InfoFunction = const Info*(*)(); - NOD() Entity::Runtime* GetRuntime() const noexcept { + NOD() auto GetRuntime() const noexcept -> Runtime* { return mRuntime; } public: + virtual void Teardown() = 0; + virtual bool Update(Langulus::Time) { return true; } diff --git a/source/Runtime.cpp b/source/Runtime.cpp index 12181bb..f28a100 100644 --- a/source/Runtime.cpp +++ b/source/Runtime.cpp @@ -46,7 +46,7 @@ //TODO #endif -#if 0 +#if 1 #define VERBOSE(...) Logger::Verbose(__VA_ARGS__) #else #define VERBOSE(...) LANGULUS(NOOP) @@ -162,8 +162,15 @@ namespace Langulus::Entity Runtime::~Runtime() { VERBOSE(this, ": Shutting down..."); - // Cycle through all libraries N^2 times, unloading anything - // that is no longer in use each time + // First-stage destruction: tear down any potential circular + // references + for (auto list : mModules) { + for (auto& mod : list.mValue) + mod->Teardown(); + } + + // Second-stage destruction: cycle through N libraries N^2 + // times, unloading anything that is no longer in use each time auto attempts = mLibraries.GetCount(); while (attempts) { for (auto library : KeepIterator(mLibraries)) { @@ -176,7 +183,7 @@ namespace Langulus::Entity // If after all attempts there's still active libraries, then // something is definitely not right. This will always result in - // a crash, since we can't really throw inside a destructor + // a crash, since we can't really throw inside a destructor. if (mLibraries) { Logger::Error(this, ": Can't unload last module(s): "); for (auto library : mLibraries) diff --git a/source/Thing.cpp b/source/Thing.cpp index 90d9a35..77aa94e 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -168,21 +168,21 @@ namespace Langulus::Entity // Destroy the entire herarchy under this Thing ENTITY_VERBOSE_SELF_TAB("Destroying..."); - #if LANGULUS(DEBUG) + #if ENTITY_VERBOSE_ENABLED() for (auto& child : mChildren) { if (child->GetReferences() != 1) { - Logger::Error( - child, " can't be destroyed - it is still referenced ", - child->GetReferences(), " times instead of once" + Logger::Warning( + child, " can't be destroyed yet - has ", + child->GetReferences(), " uses instead of 1" ); } } for (auto& unit : mUnitsList) { if (unit->GetReferences() > 3) { - Logger::Error( - unit, " can't be destroyed - it is still referenced ", - unit->GetReferences(), " times instead of 3 (or less)" + Logger::Warning( + unit, " can't be destroyed yet - has ", + unit->GetReferences(), " uses instead of 3 (or less)" ); } } @@ -221,11 +221,13 @@ namespace Langulus::Entity for (auto& child : mChildren) child->Teardown(); + if (not mFlow.IsLocked()) + mFlow.Reset(); + + if (not mRuntime.IsLocked()) + mRuntime.Reset(); + ENTITY_VERBOSE_SELF("Teardown complete: ", GetReferences(), " uses remain"); - LANGULUS_ASSERT(GetReferences() <= 1, Destruct, "After teardown, " - "Thing should have one (or zero) references remaining, from " - "its former owner's mChildren container (if not a root)" - ); } /// Compare two entities diff --git a/source/Unit.hpp b/source/Unit.hpp index 96a51ed..5b200ed 100644 --- a/source/Unit.hpp +++ b/source/Unit.hpp @@ -54,7 +54,7 @@ namespace Langulus::A Unit() noexcept : Resolvable {this} {} Unit(const Unit&) = delete; Unit(Unit&&) noexcept = delete; - ~Unit(); + virtual ~Unit(); Unit& operator = (const Unit&) = delete; Unit& operator = (Unit&&) noexcept = delete; From 7ce100a42b44c90ae7acfa72b2215290b4f7e77c Mon Sep 17 00:00:00 2001 From: Epixu Date: Fri, 18 Oct 2024 18:15:55 +0300 Subject: [PATCH 27/34] Removed verbose logging --- include/Langulus/Mesh.inl | 2 +- source/Runtime.cpp | 2 +- source/Thing.cpp | 3 +++ source/Thing.inl | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/Langulus/Mesh.inl b/include/Langulus/Mesh.inl index 0e4a644..63584de 100644 --- a/include/Langulus/Mesh.inl +++ b/include/Langulus/Mesh.inl @@ -722,7 +722,7 @@ namespace Langulus::A else LANGULUS_OOPS(Access, "Unsupported index format"); } - else LANGULUS_ERROR("Unsupported topology"); + else static_assert(false, "Unsupported topology"); } else LANGULUS_OOPS(Access, "Unsupported indexing strategy"); diff --git a/source/Runtime.cpp b/source/Runtime.cpp index f28a100..d92c259 100644 --- a/source/Runtime.cpp +++ b/source/Runtime.cpp @@ -46,7 +46,7 @@ //TODO #endif -#if 1 +#if 0 #define VERBOSE(...) Logger::Verbose(__VA_ARGS__) #else #define VERBOSE(...) LANGULUS(NOOP) diff --git a/source/Thing.cpp b/source/Thing.cpp index 77aa94e..484fbbf 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -215,6 +215,9 @@ namespace Langulus::Entity ENTITY_VERBOSE_SELF( "Tearing off unit ", unit, " at ", unit->GetReferences(), " uses..."); unit->mOwners.Remove(this); + + if (unit->mOwners.IsEmpty()) + unit->mOwners.Reset(); } // Propagate Teardown through the hierarchy of Things diff --git a/source/Thing.inl b/source/Thing.inl index 5c801de..871bbab 100644 --- a/source/Thing.inl +++ b/source/Thing.inl @@ -122,7 +122,7 @@ namespace Langulus::Entity } } } - else LANGULUS_ERROR("Unsupported descriptor"); + else static_assert(false, "Unsupported descriptor"); } /// Add a child From f31ef8f489e82cd04a982bf2f412cc7244197dd1 Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Sun, 20 Oct 2024 10:39:43 +0300 Subject: [PATCH 28/34] Critical leak fix --- source/Thing.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Thing.cpp b/source/Thing.cpp index 484fbbf..fb09fbd 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -211,6 +211,7 @@ namespace Langulus::Entity // the Units were created on the stack. // If they still have owners, they will attempt to Decouple in // A::Unit::~Unit from already destroyed mUnitsList/Ambiguous + mUnitsAmbiguous.Reset(); for (auto& unit : mUnitsList) { ENTITY_VERBOSE_SELF( "Tearing off unit ", unit, " at ", unit->GetReferences(), " uses..."); From cba52773ce7a85c96d887b53c3d7632cecda71c9 Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Sun, 20 Oct 2024 13:42:57 +0300 Subject: [PATCH 29/34] Testing TSet for leaks --- source/Thing.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Thing.hpp b/source/Thing.hpp index 5e36e31..a176764 100644 --- a/source/Thing.hpp +++ b/source/Thing.hpp @@ -23,7 +23,7 @@ namespace Langulus::Entity { using UnitList = TMany; - using UnitMap = TUnorderedMap>; + using UnitMap = TUnorderedMap>; using TraitMap = TUnorderedMap; From cf2290af198fe249cd3ccac5440af5c592cedc7b Mon Sep 17 00:00:00 2001 From: Epixu Date: Mon, 21 Oct 2024 19:04:12 +0300 Subject: [PATCH 30/34] Improved Thing::Say; Improved A::Mind API --- include/Langulus/AI.hpp | 2 ++ source/Thing-Verbs.cpp | 20 ++++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/include/Langulus/AI.hpp b/include/Langulus/AI.hpp index f932e92..8188234 100644 --- a/include/Langulus/AI.hpp +++ b/include/Langulus/AI.hpp @@ -36,6 +36,8 @@ namespace Langulus::A struct Mind : virtual AIUnit { LANGULUS_BASES(AIUnit); Mind() : Resolvable {this} {} + + virtual Many Interpret(const Langulus::Text&) = 0; }; } // namespace Langulus::A \ No newline at end of file diff --git a/source/Thing-Verbs.cpp b/source/Thing-Verbs.cpp index c03ca62..6885dea 100644 --- a/source/Thing-Verbs.cpp +++ b/source/Thing-Verbs.cpp @@ -8,6 +8,7 @@ #include "Thing.hpp" #include "Thing.inl" #include +#include namespace Langulus::Entity @@ -21,14 +22,29 @@ namespace Langulus::Entity if (not text) return {}; - // Push and execute in the active flow + // Get minds from the current context + auto minds = GatherUnits(); + if (not minds) { + Logger::Error(this, ": No minds - can't interpret message: ", text); + return {}; + } + + // Get a flow for executing the interpreted messages auto flow = GetFlow(); if (not flow) { Logger::Error(this, ": No flow - can't execute message: ", text); return {}; } - return flow->Push(Verbs::Do::In(this, text)); + // Interpret by each mind and then execute in flow + Many results; + for (auto& mind : minds) { + auto interpretation = mind->Interpret(text); + if (interpretation) + results << flow->Push(interpretation); + } + + return Abandon(results); } /// Executes a piece of code in the current context From 765eff2ca2c63ab8ca7b4f7303ac2e0e99a355f6 Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Tue, 29 Oct 2024 12:21:14 +0200 Subject: [PATCH 31/34] WASM support --- CMakeLists.txt | 2 +- source/Runtime.cpp | 26 ++++++++++---------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e21612..219de9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ file(GLOB_RECURSE ) # Build and install Entity library -add_library(LangulusEntity ${LANGULUS_LIBRARY_TYPE} +add_langulus_library(LangulusEntity $ $ $<$:$> diff --git a/source/Runtime.cpp b/source/Runtime.cpp index d92c259..321cf8b 100644 --- a/source/Runtime.cpp +++ b/source/Runtime.cpp @@ -26,7 +26,7 @@ #include #endif -#if LANGULUS_OS(LINUX) +#if LANGULUS_OS(LINUX) or LANGULUS_COMPILER(WASM) #include #endif @@ -64,12 +64,10 @@ namespace Langulus::Entity void UnloadSharedLibrary(HMODULE library) { FreeLibrary(library); } - #elif LANGULUS_OS(LINUX) + #else void UnloadSharedLibrary(void* library) { dlclose(library); } - #else - #error Unsupported OS #endif /// Runtime construction @@ -356,6 +354,8 @@ namespace Langulus::Entity path += ".dll"; #elif LANGULUS_OS(LINUX) path += ".so"; + #elif LANGULUS_COMPILER(WASM) + path += ".wasm"; #else #error Unsupported OS #endif @@ -366,10 +366,8 @@ namespace Langulus::Entity // Load the library #if LANGULUS_OS(WINDOWS) const auto dll = LoadLibraryA(path.GetRaw()); - #elif LANGULUS_OS(LINUX) + #else const auto dll = dlopen(path.GetRaw(), RTLD_NOW); - #else - #error Unsupported OS #endif if (not dll) { @@ -395,35 +393,33 @@ namespace Langulus::Entity GetProcAddress(dll, LANGULUS_MODULE_CREATE_TOKEN())); library.mInfo = reinterpret_cast( GetProcAddress(dll, LANGULUS_MODULE_INFO_TOKEN())); - #elif LANGULUS_OS(LINUX) + #else library.mEntry = reinterpret_cast( dlsym(dll, LANGULUS_MODULE_ENTRY_TOKEN())); library.mCreator = reinterpret_cast( dlsym(dll, LANGULUS_MODULE_CREATE_TOKEN())); library.mInfo = reinterpret_cast( dlsym(dll, LANGULUS_MODULE_INFO_TOKEN())); - #else - #error Unsupported OS #endif if (not library.mEntry) { Logger::Error("Module `", path, "` has no valid entry point - ", "the function " LANGULUS_MODULE_ENTRY_TOKEN() " is missing"); - (void)UnloadSharedLibrary(library); + (void) UnloadSharedLibrary(library); return {}; } if (not library.mCreator) { Logger::Error("Module `", path, "` has no valid instantiation point - ", "the function " LANGULUS_MODULE_CREATE_TOKEN() " is missing"); - (void)UnloadSharedLibrary(library); + (void) UnloadSharedLibrary(library); return {}; } if (not library.mInfo) { Logger::Error("Module `", path, "` has no valid information point - ", "the function " LANGULUS_MODULE_INFO_TOKEN() " is missing"); - (void)UnloadSharedLibrary(library); + (void) UnloadSharedLibrary(library); return {}; } @@ -568,11 +564,9 @@ namespace Langulus::Entity #if LANGULUS_OS(WINDOWS) Entity::UnloadSharedLibrary( reinterpret_cast(library.mHandle)); - #elif LANGULUS_OS(LINUX) + #else Entity::UnloadSharedLibrary( reinterpret_cast(library.mHandle)); - #else - #error Unsupported OS #endif return true; } From 81fe9280e9ad40dd0f2e4ee0cf7bf0a2e6b59718 Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Thu, 31 Oct 2024 00:14:47 +0200 Subject: [PATCH 32/34] Emscripten builds; Major CMake reduction --- source/Runtime.cpp | 6 +----- test/CMakeLists.txt | 13 +++---------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/source/Runtime.cpp b/source/Runtime.cpp index 321cf8b..8910741 100644 --- a/source/Runtime.cpp +++ b/source/Runtime.cpp @@ -352,12 +352,8 @@ namespace Langulus::Entity // File postfix #if LANGULUS_OS(WINDOWS) path += ".dll"; - #elif LANGULUS_OS(LINUX) - path += ".so"; - #elif LANGULUS_COMPILER(WASM) - path += ".wasm"; #else - #error Unsupported OS + path += ".so"; #endif // Make sure string ends with terminator diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b1a926e..f32821f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,14 +4,7 @@ file(GLOB_RECURSE *.cpp ) -add_executable(LangulusEntityTest ${LANGULUS_ENTITY_TEST_SOURCES}) - -target_link_libraries(LangulusEntityTest - PRIVATE LangulusEntity - Catch2 -) - -add_test( - NAME LangulusEntityTest - COMMAND LangulusEntityTest +add_langulus_test(LangulusEntityTest + SOURCES ${LANGULUS_ENTITY_TEST_SOURCES} + LIBRARIES LangulusEntity ) \ No newline at end of file From 3091b9c79924025fc282135e243b41ba2ba917ce Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Sun, 3 Nov 2024 21:03:59 +0200 Subject: [PATCH 33/34] Typo fix --- source/Runtime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Runtime.cpp b/source/Runtime.cpp index 8910741..9e855b1 100644 --- a/source/Runtime.cpp +++ b/source/Runtime.cpp @@ -187,7 +187,7 @@ namespace Langulus::Entity for (auto library : mLibraries) Logger::Append(library.mKey, " "); - Logger::Error(this, ": This likely involves a memory leak, " + Logger::Error(this, ": This likely involves a memory leak " "that withholds managed data reflected by the given modules"); IF_LANGULUS_MANAGED_MEMORY(Allocator::CollectGarbage()); From 76f0b6f237e291173f1e5bd224473963d4ccd9b1 Mon Sep 17 00:00:00 2001 From: Epixu Date: Sat, 9 Nov 2024 20:20:45 +0200 Subject: [PATCH 34/34] Updating CI to GCC14, Clang19 and Ubuntu 24.04 --- .github/workflows/ci.yml | 45 +++++++++++++++++++++++----------------- CMakeLists.txt | 16 +++++++------- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 649cc94..c228c62 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,30 +9,30 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04, windows-latest] + os: [ubuntu-24.04, windows-latest] build: [Debug, Release] arch: [x86, x64] - cxx: [g++, clang++-17, ClangCl, v143] + cxx: [g++-14, clang++-19, ClangCl, v143] exclude: - - os: ubuntu-22.04 + - os: ubuntu-24.04 cxx: v143 - - os: ubuntu-22.04 + - os: ubuntu-24.04 cxx: ClangCl - os: windows-latest - cxx: g++ + cxx: g++-14 - os: windows-latest - cxx: clang++-17 + cxx: clang++-19 include: - - cxx: g++ - c: gcc - - cxx: clang++-17 - c: clang-17 - - os: ubuntu-22.04 + - cxx: g++-14 + c: gcc-14 + - cxx: clang++-19 + c: clang-19 + - os: ubuntu-24.04 arch: x86 cmake_args: "-DCMAKE_CXX_FLAGS=-m32" - - os: ubuntu-22.04 + - os: ubuntu-24.04 arch: x64 cmake_args: "-DCMAKE_CXX_FLAGS=-m64" - os: windows-latest @@ -48,21 +48,28 @@ jobs: - name: Clone uses: actions/checkout@v4 - - if: matrix.os == 'ubuntu-22.04' && matrix.arch == 'x86' + - if: matrix.os == 'ubuntu-24.04' && matrix.arch == 'x86' name: Prepare Linux for cross-compilation run: | sudo apt update - sudo apt install g++-multilib + sudo apt install g++-14-multilib - - if: matrix.cxx == 'clang++-17' - name: Installing Clang 17 + - if: matrix.cxx == 'g++-14' + name: Installing G++ 14 + run: | + sudo apt update + sudo apt install gcc-14 g++-14 + + - if: matrix.cxx == 'clang++-19' + name: Installing Clang 19 run: | wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - sudo apt-add-repository "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main" + sudo apt-add-repository "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main" sudo apt update - sudo apt install clang-17 + sudo apt install gcc-14 g++-14 # clang-19 needs stdc++14.2 see https://github.com/llvm/llvm-project/issues/102336 + sudo apt install clang-19 - - if: matrix.os == 'ubuntu-22.04' + - if: matrix.os == 'ubuntu-24.04' name: Configure (Linux) run: > mkdir build && cd build && cmake .. diff --git a/CMakeLists.txt b/CMakeLists.txt index 219de9d..9979036 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,16 +13,16 @@ if(PROJECT_IS_TOP_LEVEL OR NOT LANGULUS) include(LangulusUtilities.cmake) # Add all Langulus libraries - fetch_langulus_module(Core GIT_TAG 393d95b6ab13fc5846bda8a3044e4ca62f02fd5a) - fetch_langulus_module(Logger GIT_TAG 69626cd4c738195df0929a1cd867317422506e61) - fetch_langulus_module(RTTI GIT_TAG 720e675b1ea114156c309fe44871e03557e0a64f) + fetch_langulus_module(Core GIT_TAG 35756f11d2f9c475f27b094b8d4c82cd453969fc) + fetch_langulus_module(Logger GIT_TAG dafbeb825071ec60d8403254143f75606151a7e6) + fetch_langulus_module(RTTI GIT_TAG fc49750884ac943dff4261ac5b8dfb2c148423d7) if(LANGULUS_FEATURE_MANAGED_MEMORY) - fetch_langulus_module(Fractalloc GIT_TAG b4917194b18c139969fb9d0a14bf993ee5f2582a) + fetch_langulus_module(Fractalloc GIT_TAG 66408e8557b1bb3c80615909129342bcebd3fb9f) endif() - fetch_langulus_module(SIMD GIT_TAG 6611cf422e3c8157b88c086f30966afbf4e7dc6c) - fetch_langulus_module(Anyness GIT_TAG 7e433990052d2cf4c1dbd73afdddb1c697d92c56) - fetch_langulus_module(Flow GIT_TAG 4a0b0f349e5a6f543114b9269f96f55adc025a60) - fetch_langulus_module(Math GIT_TAG 1d5612eeccb31b1dc21371977899237330342662) + fetch_langulus_module(SIMD GIT_TAG ead5493049e2800b4c3c02d385c0c6314efac69c) + fetch_langulus_module(Anyness GIT_TAG 46a6513d6bcf3d532e9bf746b50d1299692eb96a) + fetch_langulus_module(Flow GIT_TAG 06000427afccf13016738140d09850f0b8cf837b) + fetch_langulus_module(Math GIT_TAG d25c6d59a8ffd352d94c260d102a53217e12c42d) endif() file(GLOB_RECURSE