diff --git a/headers/private/shared/Referenceable.h b/headers/private/shared/Referenceable.h index 27ddcd32a6..4defe8b320 100644 --- a/headers/private/shared/Referenceable.h +++ b/headers/private/shared/Referenceable.h @@ -9,16 +9,14 @@ #include -namespace BPrivate { - -class Referenceable { +class BReferenceable { public: - Referenceable( + BReferenceable( bool deleteWhenUnreferenced = true); // TODO: The parameter is deprecated. // Override LastReferenceReleased() // instead! - virtual ~Referenceable(); + virtual ~BReferenceable(); void AcquireReference(); bool ReleaseReference(); @@ -42,21 +40,116 @@ protected: void -Referenceable::AddReference() +BReferenceable::AddReference() { AcquireReference(); } bool -Referenceable::RemoveReference() +BReferenceable::RemoveReference() { return ReleaseReference(); } +// BReference +template +class BReference { +public: + BReference() + : fObject(NULL) + { + } + + BReference(Type* object, bool alreadyHasReference = false) + : fObject(NULL) + { + SetTo(object, alreadyHasReference); + } + + BReference(const BReference& other) + : fObject(NULL) + { + SetTo(other.fObject); + } + + ~BReference() + { + Unset(); + } + + void SetTo(Type* object, bool alreadyHasReference = false) + { + if (object != NULL && !alreadyHasReference) + object->AddReference(); + + Unset(); + + fObject = object; + } + + void Unset() + { + if (fObject) { + fObject->RemoveReference(); + fObject = NULL; + } + } + + Type* Get() const + { + return fObject; + } + + Type* Detach() + { + Type* object = fObject; + fObject = NULL; + return object; + } + + Type& operator*() const + { + return *fObject; + } + + Type* operator->() const + { + return fObject; + } + + BReference& operator=(const BReference& other) + { + SetTo(other.fObject); + return *this; + } + + bool operator==(const BReference& other) const + { + return (fObject == other.fObject); + } + + bool operator!=(const BReference& other) const + { + return (fObject != other.fObject); + } + +private: + Type* fObject; +}; + + +// #pragma mark Obsolete API + +// TODO: To be phased out! + + +namespace BPrivate { + + // Reference -template +template class Reference { public: Reference() @@ -141,12 +234,13 @@ private: Type* fObject; }; + +typedef BReferenceable Referenceable; + } // namespace BPrivate using BPrivate::Referenceable; using BPrivate::Reference; -typedef BPrivate::Referenceable BReferenceable; - #endif // _REFERENCEABLE_H diff --git a/src/kits/support/Referenceable.cpp b/src/kits/support/Referenceable.cpp index 51d6fb6874..92d6cc53c7 100644 --- a/src/kits/support/Referenceable.cpp +++ b/src/kits/support/Referenceable.cpp @@ -6,20 +6,20 @@ #include -Referenceable::Referenceable(bool deleteWhenUnreferenced) +BReferenceable::BReferenceable(bool deleteWhenUnreferenced) : fReferenceCount(1), fDeleteWhenUnreferenced(deleteWhenUnreferenced) { } -Referenceable::~Referenceable() +BReferenceable::~BReferenceable() { } void -Referenceable::AcquireReference() +BReferenceable::AcquireReference() { if (atomic_add(&fReferenceCount, 1) == 0) FirstReferenceAcquired(); @@ -27,7 +27,7 @@ Referenceable::AcquireReference() bool -Referenceable::ReleaseReference() +BReferenceable::ReleaseReference() { bool unreferenced = (atomic_add(&fReferenceCount, -1) == 1); if (unreferenced) @@ -37,13 +37,13 @@ Referenceable::ReleaseReference() void -Referenceable::FirstReferenceAcquired() +BReferenceable::FirstReferenceAcquired() { } void -Referenceable::LastReferenceReleased() +BReferenceable::LastReferenceReleased() { if (fDeleteWhenUnreferenced) delete this;