From 26633fee1c3c3f0d2d0cc909ab73d69afab94f87 Mon Sep 17 00:00:00 2001 From: Dimo Markov Date: Mon, 4 Mar 2024 18:13:38 +0200 Subject: [PATCH] Renames; Improved Run methods; Proper detachment of units/things --- source/External.hpp | 4 +-- source/Hierarchy.hpp | 6 ++-- source/Runtime.cpp | 4 +-- source/Runtime.hpp | 4 +-- source/Thing-Traits.cpp | 15 ++++++---- source/Thing-Verbs.cpp | 19 +++++++++---- source/Thing.cpp | 44 +++++++++++++++++++---------- source/Thing.hpp | 11 ++++---- source/Thing.inl | 61 ++++++++++++++++++++++++++--------------- source/Unit.cpp | 30 +++++++++++++++----- source/Unit.hpp | 2 +- test/Main.hpp | 8 ++++-- test/TestThing.cpp | 45 +++++++++++++++++++----------- 13 files changed, 165 insertions(+), 88 deletions(-) diff --git a/source/External.hpp b/source/External.hpp index 4ff8a32..ec72e33 100644 --- a/source/External.hpp +++ b/source/External.hpp @@ -373,8 +373,8 @@ namespace Langulus::A virtual Offset Write(const Any&) = 0; }; - NOD() virtual Ptr NewReader() = 0; - NOD() virtual Ptr NewWriter(bool append) = 0; + NOD() virtual Ref NewReader() = 0; + NOD() virtual Ref NewWriter(bool append) = 0; }; /// diff --git a/source/Hierarchy.hpp b/source/Hierarchy.hpp index b3ee0ab..dbec184 100644 --- a/source/Hierarchy.hpp +++ b/source/Hierarchy.hpp @@ -18,15 +18,17 @@ namespace Langulus::Anyness /// Execute a verb for all elements inside a type-erased constant block /// @param verb - the verb to execute template - void TAny::Run(Flow::Verb& verb) const { + Flow::Verb& TAny::Run(Flow::Verb& verb) const { Flow::DispatchDeep(*this, verb); + return verb; } /// Execute a verb for all elements inside a type-erased block /// @param verb - the verb to execute template - void TAny::Run(Flow::Verb& verb) { + Flow::Verb& TAny::Run(Flow::Verb& verb) { Flow::DispatchDeep(*this, verb); + return verb; } } // namespace Langulus::Anyness diff --git a/source/Runtime.cpp b/source/Runtime.cpp index bbf1adf..34ad835 100644 --- a/source/Runtime.cpp +++ b/source/Runtime.cpp @@ -497,7 +497,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 - Ptr Runtime::GetFile(const Path& path) { + Ref Runtime::GetFile(const Path& path) { auto& fileSystems = GetModules(); LANGULUS_ASSERT(fileSystems, Module, "Can't retrieve file `", path, "` - no file system module available"); @@ -507,7 +507,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 - Ptr Runtime::GetFolder(const Path& path) { + Ref Runtime::GetFolder(const Path& path) { auto& fileSystems = GetModules(); LANGULUS_ASSERT(fileSystems, Module, "Can't retrieve folder `", path, "` - no file system module available"); diff --git a/source/Runtime.hpp b/source/Runtime.hpp index 24ba899..728afe4 100644 --- a/source/Runtime.hpp +++ b/source/Runtime.hpp @@ -135,9 +135,9 @@ namespace Langulus::Entity #endif NOD() LANGULUS_API(ENTITY) - Ptr GetFile(const Path&); + Ref GetFile(const Path&); NOD() LANGULUS_API(ENTITY) - Ptr GetFolder(const Path&); + Ref GetFolder(const Path&); NOD() LANGULUS_API(ENTITY) const Path& GetWorkingPath() const; NOD() LANGULUS_API(ENTITY) diff --git a/source/Thing-Traits.cpp b/source/Thing-Traits.cpp index 39ad991..c103483 100644 --- a/source/Thing-Traits.cpp +++ b/source/Thing-Traits.cpp @@ -12,11 +12,16 @@ #if 0 #define ENTITY_VERBOSE_ENABLED() 1 - #define ENTITY_VERBOSE_SELF(...) Logger::Verbose(Self(), __VA_ARGS__) - #define ENTITY_VERBOSE(...) Logger::Append(__VA_ARGS__) + #define ENTITY_VERBOSE_SELF(...) \ + Logger::Verbose(this, ": ", __VA_ARGS__) + #define ENTITY_VERBOSE_SELF_TAB(...) \ + const auto scoped = Logger::Verbose(this, ": ", __VA_ARGS__, Logger::Tabs {}) + #define ENTITY_VERBOSE(...) \ + Logger::Append(__VA_ARGS__) #else #define ENTITY_VERBOSE_ENABLED() 0 #define ENTITY_VERBOSE_SELF(...) + #define ENTITY_VERBOSE_SELF_TAB(...) #define ENTITY_VERBOSE(...) #endif @@ -162,7 +167,7 @@ namespace Langulus::Entity mTraits.Insert(tmeta, trait); mRefreshRequired = true; - ENTITY_VERBOSE(trait << " added"); + ENTITY_VERBOSE_SELF(trait, " added"); return &mTraits[tmeta].Last(); } @@ -174,7 +179,7 @@ namespace Langulus::Entity if (found) { const auto removed = found.mValue->GetCount(); mTraits.RemoveIt(found); - ENTITY_VERBOSE_SELF(trait << " removed"); + ENTITY_VERBOSE_SELF(trait, " removed"); mRefreshRequired = true; return removed; } @@ -190,7 +195,7 @@ namespace Langulus::Entity if (found) { const auto removed = found.mValue->Remove(trait); if (removed) { - ENTITY_VERBOSE_SELF(trait << " removed"); + ENTITY_VERBOSE_SELF(trait, " removed"); mRefreshRequired = true; return removed; } diff --git a/source/Thing-Verbs.cpp b/source/Thing-Verbs.cpp index aa748db..c718895 100644 --- a/source/Thing-Verbs.cpp +++ b/source/Thing-Verbs.cpp @@ -10,15 +10,23 @@ #include "Runtime.hpp" #include + #if 0 #define ENTITY_VERBOSE_ENABLED() 1 - #define ENTITY_VERBOSE_SELF(...) Logger::Verbose(Self(), __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 ENTITY_VERBOSE_SELF(...) \ + Logger::Verbose(this, ": ", __VA_ARGS__) + #define ENTITY_VERBOSE_SELF_TAB(...) \ + const auto scoped = Logger::Verbose(this, ": ", __VA_ARGS__, Logger::Tabs {}) + #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(...) + #define ENTITY_VERBOSE_SELF_TAB(...) #define ENTITY_VERBOSE(...) #define ENTITY_CREATION_VERBOSE_SELF(...) #define ENTITY_SELECTION_VERBOSE_SELF(...) @@ -68,8 +76,7 @@ namespace Langulus::Entity // Dispatch to entity first, using reflected and default verbs, // but disallowing custom dispatch, because we're currently in it // and there's a potential for infinite regress - Resolvable::Run(verb); - if (verb.IsDone()) + if (Resolvable::Run(verb).IsDone()) return; // If verb is still not satisfied, dispatch to ALL units diff --git a/source/Thing.cpp b/source/Thing.cpp index 4c4c002..ff04360 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -32,7 +32,7 @@ namespace Langulus::Entity /// Default-constructor, always creates a parentless root thing Thing::Thing() : Resolvable {MetaOf()} { - ENTITY_VERBOSE_SELF("Created (root, ", GetReferences(), " references)"); + ENTITY_VERBOSE_SELF("Created (root, ", Reference(0), " references)"); } /// Descriptor-constructor @@ -47,12 +47,13 @@ namespace Langulus::Entity if (mOwner) { ENTITY_VERBOSE_SELF( "Created as child to ", mOwner, - " (", GetReferences(), " references)" + " (", Reference(0), " references; parent now has ", + mOwner->Reference(0), " references)" ); } else { ENTITY_VERBOSE_SELF( - "Created (root, ", GetReferences(), " references)" + "Created (root, ", Reference(0), " references)" ); } } @@ -78,12 +79,13 @@ namespace Langulus::Entity if (mOwner) { ENTITY_VERBOSE_SELF( "Created as child to ", mOwner, - " (", GetReferences(), " references)" + " (", Reference(0), " references; parent now has ", + mOwner->Reference(0), " references)" ); } else { ENTITY_VERBOSE_SELF( - "Created (root, ", GetReferences(), " references)" + "Created (root, ", Reference(0), " references)" ); } } @@ -156,7 +158,7 @@ namespace Langulus::Entity , mChildren {Clone(other->mChildren)} , mRefreshRequired {true} { TODO(); - // clone flow and runtime if pinned, recreate modules if new runtime, + //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); } @@ -164,22 +166,31 @@ namespace Langulus::Entity /// Destructor Thing::~Thing() IF_UNSAFE(noexcept) { Detach(); - LANGULUS_ASSUME(DevAssumes, GetReferences() == 1, "Bad reference count"); + + /*if (Reference(0) == 1) { + // If after detaching the entire hierarchy, there's still one + // reference remaining, then we're sure that this reference is + // because the Thing is on the stack + //TODO requires the destruction of the hierarchy, too? othwise some member could still hold a ref to this thing? + //TODO alternatively, items without jurisdiction are never referenced, so we could detect things on the stack, by comparing references before and after Detach() + //TODO eventually we can just do Fractalloc::CheckAuthority(this) + Reference(-1); + }*/ } /// A nested call to detach all parents of all children void Thing::Detach() { - ENTITY_VERBOSE_SELF_TAB("Decoupling (", GetReferences(), " uses):"); + ENTITY_VERBOSE_SELF_TAB("Destroying (", Reference(0), " uses):"); // The thing might be on the stack, make sure we decouple it from // its owner, if that's the case - if (mOwner and GetReferences() > 1) { + /*if (mOwner and Reference(0)) { ENTITY_VERBOSE_SELF("Decoupling from owner: ", *mOwner); IF_SAFE(Count removed = ) mOwner->RemoveChild(this); LANGULUS_ASSUME(DevAssumes, removed, "Parent is missing"); - ENTITY_VERBOSE_SELF("...", GetReferences(), " uses "); - } + ENTITY_VERBOSE_SELF("...", Reference(0), " uses "); + }*/ // Decouple all children from this for (auto& child : mChildren) { @@ -188,7 +199,7 @@ namespace Langulus::Entity LANGULUS_ASSUME(DevAssumes, child->mOwner == this, "Parent mismatch"); child->mOwner.Reset(); - ENTITY_VERBOSE_SELF("...", GetReferences(), " uses remain"); + ENTITY_VERBOSE_SELF("...", Reference(0), " uses remain"); } } @@ -196,11 +207,13 @@ namespace Langulus::Entity for (auto& unit : mUnitsList) { ENTITY_VERBOSE_SELF("Decoupling unit: ", unit); unit->mOwners.Remove(this); - ENTITY_VERBOSE_SELF("...", GetReferences(), " uses remain"); + ENTITY_VERBOSE_SELF("...", Reference(0), " uses remain"); } - for (auto& child : mChildren) + for (auto& child : mChildren) { child->Detach(); + ENTITY_VERBOSE_SELF("...", Reference(0), " uses remain"); + } } /// Compare two entities @@ -521,7 +534,8 @@ namespace Langulus::Entity /// @param descriptor - instructions for the entity's creation /// @return the new child instance Ref Thing::CreateChild(const Neat& descriptor) { - ENTITY_VERBOSE_SELF_TAB("Producing child: "); + ENTITY_VERBOSE_SELF_TAB( + "Producing child (at ", Reference(0), " references): "); Ref newThing; newThing.New(this, descriptor); return Abandon(newThing); diff --git a/source/Thing.hpp b/source/Thing.hpp index 3145932..3172435 100644 --- a/source/Thing.hpp +++ b/source/Thing.hpp @@ -65,9 +65,9 @@ namespace Langulus::Entity // Runtime should be destroyed last, hence it is the first member // Runtime - Pin> mRuntime; + Pin> mRuntime; // Temporal flow - Pin> mFlow; + Pin> mFlow; // Hierarchy Hierarchy mChildren; // Units indexed by all their relevant reflected bases @@ -94,7 +94,9 @@ 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); + void Detach(); // Shallow copy is disabled, you should be able only to clone, // move, or abandon @@ -112,7 +114,7 @@ namespace Langulus::Entity LANGULUS_API(ENTITY) void Create(Verb&); template - Any RunIn(CT::VerbBased auto&); + auto& RunIn(CT::VerbBased auto&); LANGULUS_API(ENTITY) Any Run(const Lingua&); @@ -165,9 +167,6 @@ namespace Langulus::Entity LANGULUS_API(ENTITY) void DumpHierarchy() const; - protected: - void Detach(); - public: /// /// Unit management diff --git a/source/Thing.inl b/source/Thing.inl index 6da3e2f..09544b1 100644 --- a/source/Thing.inl +++ b/source/Thing.inl @@ -15,13 +15,20 @@ #if 0 #define ENTITY_VERBOSE_ENABLED() 1 - #define ENTITY_VERBOSE_SELF(...) Logger::Verbose(Self(), __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 ENTITY_VERBOSE_SELF(...) \ + Logger::Verbose(this, ": ", __VA_ARGS__) + #define ENTITY_VERBOSE_SELF_TAB(...) \ + const auto scoped = Logger::Verbose(this, ": ", __VA_ARGS__, Logger::Tabs {}) + #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(...) + #define ENTITY_VERBOSE_SELF_TAB(...) #define ENTITY_VERBOSE(...) #define ENTITY_CREATION_VERBOSE_SELF(...) #define ENTITY_SELECTION_VERBOSE_SELF(...) @@ -176,20 +183,19 @@ namespace Langulus::Entity /// @param verb - the verb to execute /// @return verb output template - Any Thing::RunIn(CT::VerbBased auto& verb) { + auto& Thing::RunIn(CT::VerbBased auto& verb) { if constexpr (SEEK & Seek::Here) { // Execute here Do(verb); if (verb.IsDone()) - return verb.GetOutput(); + return verb; } if constexpr (SEEK & Seek::Above) { // Execute in parents up to root, if requested if (mOwner) { - mOwner->template RunIn(verb); - if (verb.IsDone()) - return verb.GetOutput(); + if (mOwner->template RunIn(verb).IsDone()) + return verb; } } @@ -198,14 +204,12 @@ namespace Langulus::Entity for (auto& child : mChildren) { Verb local {verb}; local.ShortCircuit(false); - verb << Abandon(child->template RunIn(local)); + verb << Abandon( + child->template RunIn(local).GetOutput()); } - - if (verb.IsDone()) - return verb.GetOutput(); } - return {}; + return verb; } /// Register unit by all its bases in mUnitsAmbiguous @@ -280,7 +284,9 @@ namespace Langulus::Entity mUnitsList << unit; AddUnitBases(unit, meta); mRefreshRequired = true; - ENTITY_VERBOSE(unit, " added as unit"); + + ENTITY_VERBOSE( + unit, " added as unit (now at ", Reference(0), " references)"); return 1; } @@ -490,16 +496,26 @@ namespace Langulus::Entity Any Thing::CreateData(const Construct& construct) { LANGULUS_ASSUME(UserAssumes, construct.GetType(), "Invalid construct type"); + 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 `", + type, "` (at ", Reference(0), " references)" + ); // 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 - if (not descriptor.GetDescriptor().Get()) + Construct descriptor {construct}; + if (not descriptor.GetDescriptor().Get()) { descriptor << Traits::Parent {this}; + ENTITY_VERBOSE_SELF( + "Referenced as Traits::Parent (now at ", Reference(0), + " references)" + ); + } if (producer) { // Data has a specific producer, we can narrow the required @@ -600,26 +616,27 @@ namespace Langulus::Entity /// @param verb - the verb to execute /// @return the verb output template - Any Unit::RunIn(CT::VerbBased auto& verb) { + auto& Unit::RunIn(CT::VerbBased auto& verb) { if (not mOwners) { Logger::Warning(Self(), "No owners available for executing: ", verb); - return false; + return verb; } // Dispatch to all owner, accumulate outputs for (auto& owner : mOwners) { - Verb local {verb}; + auto local = verb; local.ShortCircuit(false); - verb << Abandon(owner->template RunIn(local)); + verb << Abandon(owner->template RunIn(local).GetOutput()); } - return verb.GetOutput(); + return verb; } } // namespace Langulus::Entity #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 diff --git a/source/Unit.cpp b/source/Unit.cpp index 07106d0..1d0fba8 100644 --- a/source/Unit.cpp +++ b/source/Unit.cpp @@ -37,14 +37,30 @@ Unit::Unit(Unit&& other) noexcept Unit::~Unit() { // The unit might be on the stack, make sure we decouple it from // all its owners, if that's the case - if (GetReferences() > 1) { - for (auto owner : mOwners) - owner->RemoveUnit(this); - } + //if (Reference(0) == mOwners.GetCount() + 1) { + // After removing + //} + - // Then, the unit should have exactly one reference left - LANGULUS_ASSUME(DevAssumes, GetReferences() < 2, - "Unit destroyed while still in use"); + //if (Reference(-1)) { + /*for (auto owner : mOwners) + owner->RemoveUnit(this); + //} + + if (Reference(0) == 1) { + // If after detaching the entire hierarchy, there's still one + // reference remaining, then we're sure that this reference is + // because the Thing is on the stack + //TODO requires the destruction of the hierarchy, too? othwise some member could still hold a ref to this thing? + //TODO alternatively, items without jurisdiction are never referenced, so we could detect things on the stack, by comparing references before and after Detach() + //TODO eventually we can just do Fractalloc::CheckAuthority(this) + Reference(-1); + }*/ + + /*auto heap = Fractalloc::Instance.Find(GetType(), this); + if (not heap) { + // The unit is on the stack, or outside jurisdiction + }*/ } /// Default unit selection simply relays to the owner diff --git a/source/Unit.hpp b/source/Unit.hpp index 39f8e95..0a4953b 100644 --- a/source/Unit.hpp +++ b/source/Unit.hpp @@ -64,7 +64,7 @@ namespace Langulus::Entity /// Flow /// template - Any RunIn(CT::VerbBased auto&); + auto& RunIn(CT::VerbBased auto&); /// /// Seek diff --git a/test/Main.hpp b/test/Main.hpp index fec0dbd..21518f6 100644 --- a/test/Main.hpp +++ b/test/Main.hpp @@ -25,7 +25,9 @@ class TestUnit1 final : public Unit { TestUnit1(Describe&& describe) : Unit {MetaOf(), *describe} {} - ~TestUnit1() {} + ~TestUnit1() { + Logger::Verbose(this, ": destroying..."); + } void Refresh() {} }; @@ -42,7 +44,9 @@ class TestUnit2 final : public Unit { TestUnit2(Describe&& describe) : Unit {MetaOf(), *describe} {} - ~TestUnit2() {} + ~TestUnit2() { + Logger::Verbose(this, ": destroying..."); + } void Refresh() {} }; \ No newline at end of file diff --git a/test/TestThing.cpp b/test/TestThing.cpp index f0199d6..53d8c71 100644 --- a/test/TestThing.cpp +++ b/test/TestThing.cpp @@ -32,7 +32,7 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(not root.mUnitsList); REQUIRE(not root.mUnitsAmbiguous); REQUIRE(not root.mTraits); - REQUIRE(root.GetReferences() == 1); + REQUIRE(root.Reference(0) == 1); } WHEN("Creating a Thing with a parent") { @@ -50,7 +50,7 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(not root.mUnitsList); REQUIRE(not root.mUnitsAmbiguous); REQUIRE(not root.mTraits); - REQUIRE(root.GetReferences() == 1); + REQUIRE(root.Reference(0) == 1); REQUIRE(child.mOwner == &root); REQUIRE(child.mRuntime == nullptr); @@ -62,7 +62,7 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(not child.mUnitsList); REQUIRE(not child.mUnitsAmbiguous); REQUIRE(not child.mTraits); - REQUIRE(child.GetReferences() == 1); + REQUIRE(child.Reference(0) == 1); } GIVEN("A root Thing") { @@ -94,7 +94,7 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(root.mChildren.GetCount() == 1); REQUIRE(not root.mUnitsList); REQUIRE(not root.mTraits); - REQUIRE(root.GetReferences() == 1); + REQUIRE(root.Reference(0) == 1); auto child1 = root.mChildren[0]; REQUIRE(child1 == child); @@ -107,7 +107,7 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(not child1->mChildren); REQUIRE(not child1->mUnitsList); REQUIRE(not child1->mTraits); - REQUIRE(child1->GetReferences() == 3); + REQUIRE(child1->Reference(0) == 3); } WHEN("Adding an existing unit") { @@ -125,14 +125,14 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(root.mChildren.IsEmpty()); REQUIRE(root.mUnitsList.GetCount() == 1); REQUIRE(root.mTraits.IsEmpty()); - REQUIRE(root.GetReferences() == 1); + REQUIRE(root.Reference(0) == 1); auto it = root.mUnitsList.begin(); REQUIRE(it->GetType() == MetaOf()); REQUIRE(*it == &testUnit); REQUIRE(it->mOwners.GetCount() == 1); REQUIRE(it->mOwners[0] == &root); - REQUIRE(it->GetReferences() == 1); + REQUIRE(it->Reference(0) == 1); } } @@ -149,14 +149,18 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(root.mChildren.IsEmpty()); REQUIRE(root.mUnitsList.GetCount() == 1); REQUIRE(root.mTraits.IsEmpty()); - REQUIRE(root.GetReferences() == 1); + REQUIRE(root.Reference(0) == 1); auto it = root.mUnitsList.begin(); REQUIRE(it->GetType() == MetaOf()); REQUIRE(*it == unit.As()); + 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->mOwners.GetCount() == 1); REQUIRE(it->mOwners[0] == &root); - REQUIRE(it->GetReferences() == 3); + REQUIRE(it->Reference(0) == 3); } } @@ -175,7 +179,7 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(not root.mUnitsList); REQUIRE(not root.mUnitsAmbiguous); REQUIRE(root.mTraits.GetCount() == 1); - REQUIRE(root.GetReferences() == 1); + REQUIRE(root.Reference(0) == 1); auto it = root.mTraits.begin(); REQUIRE(*it.mKey == MetaOf()); @@ -200,7 +204,7 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(not root.mUnitsAmbiguous); REQUIRE(root.mTraits.GetCount() == 1); REQUIRE(root.GetName() == "Dimo"); - REQUIRE(root.GetReferences() == 1); + REQUIRE(root.Reference(0) == 1); auto it = root.mTraits.begin(); REQUIRE(*it.mKey == MetaOf()); @@ -241,7 +245,7 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(root.mUnitsList.GetCount() == 2); REQUIRE(root.mTraits.GetCount() == 1); REQUIRE(root.GetName() == "Root"); - REQUIRE(root.GetReferences() == 1); + REQUIRE(root.Reference(0) == 1); auto child1 = root.mChildren[0]; REQUIRE(child1->mOwner == &root); @@ -254,7 +258,16 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(child1->mUnitsList.GetCount() == 2); REQUIRE(child1->mTraits.GetCount() == 1); REQUIRE(child1->GetName() == "Child1"); - REQUIRE(child1->GetReferences() == 6); + + // the child1 container has 1 reference + // the root.mChildren[0] contains 1 reference + // child1's TestUnit1 owner contains 1 references from owner + // child1's TestUnit2 owner contains 1 reference from owner + // child1's GrandChild1 owner contains 1 reference + // child1's GrandChild2 owner contains 1 reference + //--------------------------------------------------- + // total: 8 references confirmed + REQUIRE(child1->Reference(0) == 6); auto child2 = root.mChildren[1]; REQUIRE(child2->mOwner == &root); @@ -267,7 +280,7 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(not child2->mUnitsList); REQUIRE(child2->mTraits.GetCount() == 1); REQUIRE(child2->GetName() == "Child2"); - REQUIRE(child2->GetReferences() == 2); + REQUIRE(child2->Reference(0) == 2); auto grandchild1 = child1->mChildren[0]; REQUIRE(grandchild1->mOwner == child1); @@ -280,7 +293,7 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(not grandchild1->mUnitsList); REQUIRE(grandchild1->mTraits.GetCount() == 1); REQUIRE(grandchild1->GetName() == "GrandChild1"); - REQUIRE(grandchild1->GetReferences() == 2); + REQUIRE(grandchild1->Reference(0) == 2); auto grandchild2 = child1->mChildren[1]; REQUIRE(grandchild2->mOwner == child1); @@ -293,7 +306,7 @@ SCENARIO("Testing Thing", "[thing]") { REQUIRE(not grandchild2->mUnitsList); REQUIRE(grandchild2->mTraits.GetCount() == 1); REQUIRE(grandchild2->GetName() == "GrandChild2"); - REQUIRE(grandchild2->GetReferences() == 2); + REQUIRE(grandchild2->Reference(0) == 2); Logger::Special("End: Creating a Thing by descriptor"); }