sclass RegisteredReference implements IRef {
Meta owner; // all we require is a meta field
A value;
*() {
if (!dynamicObjectIsLoading()) registerRef();
}
void registerRef {
vmBus_send registeringReference(this);
}
*(A *value) {
registerRef();
index();
}
// get owning concept (source)
Concept concept() {
ret Concept.this;
}
// get target
public A get() { ret value; }
bool has() { ret value != null; }
bool set(A a) {
if (a == value) false;
unindex();
value = a;
index();
true;
}
void setIfEmpty(A a) {
if (!has()) set(a);
}
void set(Ref ref) { set(ref.get()); }
void clear() { set((A) null); }
bool validRef() {
ret value != null && _concepts != null && _concepts == value._concepts;
}
// TODO: sync all the indexing and unindexing!?
void index() {
if (validRef()) {
value._addBackRef(this);
change();
}
}
Ref unindex() {
if (validRef()) {
value._removeBackRef(this);
change();
}
this;
}
void unindexAndDrop {
unindex();
_removeRef(this);
}
void change() {
owner?.change();
}
toString { ret ifdef ConceptRef_markInToString "Concept.Ref " + endifdef
str(value); }
}