1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
#include "stdafx.h"
#include "RefSource.h"
#include "Reference.h"
#include "Exception.h"
#include "DelegatedRef.h"
#include "Core/Array.h"
#include "Core/StrBuf.h"
#include "Core/Str.h"
namespace code {
RefSource::RefSource() : cont(null) {
refs = new (this) WeakSet<Reference>();
}
RefSource::RefSource(Content *content) : cont(content) {
refs = new (this) WeakSet<Reference>();
if (cont)
atomicWrite(cont->cOwner, this);
}
void RefSource::set(Content *to) {
if (cont != to) {
assert(to->cOwner == null, L"Multiple owners of a single Content object.");
if (cont)
atomicWrite(cont->cOwner, (RefSource *)null);
if (to)
atomicWrite(to->cOwner, this);
cont = to;
}
update();
}
void RefSource::clear() {
if (cont)
atomicWrite(cont->cOwner, (RefSource *)null);
cont = null;
update();
}
void RefSource::update() {
const void *addr = address();
WeakSet<Reference>::Iter i = refs->iter();
while (Reference *ref = i.next())
ref->moved(addr);
}
RefSource *RefSource::findActual() {
if (cont)
if (RefSource *r = cont->stolenBy())
return r->findActual();
return this;
}
void RefSource::setPtr(const void *to) {
set(new (this) StaticContent(to));
}
void RefSource::steal(RefSource *from) {
const void *addr = address();
WeakSet<Reference>::Iter i = from->refs->iter();
while (Reference *ref = i.next()) {
refs->put(ref);
ref->to = this;
ref->moved(addr);
}
from->refs->clear();
// Keep 'from' updated while it is alive. Otherwise any 'Ref' instances will not be updated.
from->set(new (this) StolenContent(this));
}
void RefSource::toS(StrBuf *to) const {
*to << title();
}
/**
* NameRefSource.
*/
StrRefSource::StrRefSource(const wchar *title) : RefSource() {
name = new (this) Str(title);
}
StrRefSource::StrRefSource(const wchar *title, Content *content) : RefSource(content) {
name = new (this) Str(title);
}
StrRefSource::StrRefSource(Str *title) : RefSource(), name(title) {}
StrRefSource::StrRefSource(Str *title, Content *content) : RefSource(content), name(title) {}
Str *StrRefSource::title() const {
return name;
}
}
|