Skip to content

Commit

Permalink
libcore|Profiles: Audiences for profile addition/removal; profiles ar…
Browse files Browse the repository at this point in the history
…e deletable
  • Loading branch information
skyjake committed Mar 9, 2016
1 parent 91ce931 commit 44051d3
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
6 changes: 5 additions & 1 deletion doomsday/sdk/libcore/include/de/data/profiles.h
Expand Up @@ -21,6 +21,7 @@

#include <de/String>
#include <de/Info>
#include <de/Deletable>
#include <functional>

namespace de {
Expand All @@ -42,7 +43,7 @@ class DENG2_PUBLIC Profiles
* Base class for profiles. The derived class implements this with the
* appropriate contents and serialization. @ingroup data
*/
class DENG2_PUBLIC AbstractProfile
class DENG2_PUBLIC AbstractProfile : public Deletable
{
public:
AbstractProfile();
Expand Down Expand Up @@ -98,6 +99,9 @@ class DENG2_PUBLIC Profiles

DENG2_ERROR(NotFoundError);

DENG2_DEFINE_AUDIENCE2(Addition, void profileAdded (AbstractProfile &prof))
DENG2_DEFINE_AUDIENCE2(Removal, void profileRemoved(AbstractProfile &prof))

public:
Profiles();

Expand Down
57 changes: 53 additions & 4 deletions doomsday/sdk/libcore/src/data/profiles.cpp
Expand Up @@ -31,6 +31,7 @@ static String nameToKey(String const &name)
}

DENG2_PIMPL(Profiles)
, DENG2_OBSERVES(Deletable, Deletion)
{
typedef QMap<String, AbstractProfile *> Profiles;
Profiles profiles;
Expand All @@ -53,10 +54,48 @@ DENG2_PIMPL(Profiles)
}
profiles.insert(key, profile);
profile->setOwner(thisPublic);
profile->audienceForDeletion += this;

DENG2_FOR_PUBLIC_AUDIENCE2(Addition, i)
{
i->profileAdded(*profile);
}
}

void remove(AbstractProfile &profile)
{
profile.audienceForDeletion -= this;
profile.setOwner(nullptr);
profiles.remove(nameToKey(profile.name()));

DENG2_FOR_PUBLIC_AUDIENCE2(Removal, i)
{
i->profileRemoved(profile);
}
}

void objectWasDeleted(Deletable *obj)
{
// At this point the AbstractProfile itself is already deleted.
QMutableMapIterator<String, AbstractProfile *> iter(profiles);
while(iter.hasNext())
{
iter.next();
if(iter.value() == obj)
{
iter.remove();
break;
}
}
}

void clear()
{
for(auto *prof : profiles)
{
prof->audienceForDeletion -= this;
prof->setOwner(nullptr);
}
qDeleteAll(profiles.values());
profiles.clear();
}
Expand Down Expand Up @@ -110,8 +149,13 @@ DENG2_PIMPL(Profiles)
<< file.description() << er.asText();
}
}
DENG2_PIMPL_AUDIENCE(Addition)
DENG2_PIMPL_AUDIENCE(Removal)
};

DENG2_AUDIENCE_METHOD(Profiles, Addition)
DENG2_AUDIENCE_METHOD(Profiles, Removal)

Profiles::Profiles()
: d(new Instance(this))
{}
Expand Down Expand Up @@ -188,8 +232,7 @@ void Profiles::remove(AbstractProfile &profile)
{
DENG2_ASSERT(&profile.owner() == this);

d->profiles.remove(nameToKey(profile.name()));
profile.setOwner(nullptr);
d->remove(profile);
}

void Profiles::serialize() const
Expand Down Expand Up @@ -277,7 +320,13 @@ DENG2_PIMPL(Profiles::AbstractProfile)

Instance(Public *i) : Base(i) {}

~Instance() {}
~Instance()
{
if(owner)
{
owner->remove(self);
}
}
};

Profiles::AbstractProfile::AbstractProfile()
Expand All @@ -289,7 +338,7 @@ Profiles::AbstractProfile::~AbstractProfile()

void Profiles::AbstractProfile::setOwner(Profiles *owner)
{
DENG2_ASSERT(d->owner == nullptr);
DENG2_ASSERT(d->owner != owner);
d->owner = owner;
}

Expand Down

0 comments on commit 44051d3

Please sign in to comment.