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) { this(null, value); } *(Meta *owner, A *value) { index(); registerRef(); } // get owning object (source) Meta owner() { ret owner; } // 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(IRef ref) { set(ref == null ?: ref.get()); } void clear() { set((A) null); } // can override bool validRef() { true; } // TODO: sync all the indexing and unindexing!? void index() { if (!validRef()) ret; var br = lookupInterface IHasBackRefs(get()); br?._registerBackRef(this); } void unindex() { if (!validRef()) ret; var br = lookupInterface IHasBackRefs(get()); br?._unregisterBackRef(this); } void change {} toString { ret ifdef RegisteredReference_markInToString "RegisteringReference " + endifdef str(value); } }