void Registry::Delete(Object const &object) { #ifdef KAI_DEBUG if (IsWatching(object)) KAI_TRACE() << object.GetHandle(); #endif Delete(object.GetHandle()); }
void StorageBase::AddedToContainer(Object const &container) { if (container.GetHandle() == GetHandle()) KAI_THROW_1(InternalError, "Can't add a container to itself"); containers.push_back(container.GetHandle()); if (IsWhite()) SetGrey(); }
void StorageBase::Set(const Label &name, Object const &child) { if (child.GetHandle() == GetHandle()) KAI_THROW_1(InternalError, "Recursion"); // mark the object as being altered SetDirty(); // set a property if it exists ClassBase const *klass = GetClass(); if (klass->HasProperty(name)) { klass->GetProperty(name).SetValue(*this, child); return; } // otherwise this is a child object. remove any existing child Remove(name); // update the child object if (!child.Exists()) { Dictionary::iterator ch = dictionary.find(name); if (ch != dictionary.end()) dictionary.erase(ch); return; } StorageBase &base = KAI_NAMESPACE(GetStorageBase(child)); base.SetLabel(name); base.SetParentHandle(GetHandle()); bool clean = base.IsClean(); bool konst = base.IsConst(); bool managed = base.IsManaged(); base.switches = switches; // inherit properties of parent... if (clean) // ...but preserve cleanliness base.switches |= IObject::Clean; else base.switches &= ~IObject::Clean; if (konst) // ...and constness base.switches |= IObject::Const; if (managed) // ...and managed base.switches |= IObject::Managed; // add it to this dictionary, inform it of being added to a container dictionary[name] = child; base.AddedToContainer(*this); }
KAI_BEGIN void StorageBase::Detach(Object const &Q) { Dictionary::const_iterator A = dictionary.begin(), B = dictionary.end(); for (; A != B; ++A) { if (A->second.GetHandle() == Q.GetHandle()) { Detach(A->first); return; } } }
void StorageBase::RemovedFromContainer(Object const &container) { ObjectColor::Color color = ObjectColor::White; StorageBase *parent = GetRegistry()->GetStorageBase(GetParentHandle()); bool parent_is_black = parent && parent->IsBlack(); if (parent_is_black) color = ObjectColor::Grey; bool removed = false; auto iter = containers.begin(), end = containers.end(); for (; iter != end; ) { StorageBase *base = GetRegistry()->GetStorageBase(*iter); if (!base) { iter = containers.erase(iter); continue; } if (!removed && *iter == container.GetHandle()) { iter = containers.erase(iter); removed = true; if (parent_is_black) { // if removed from container and parent is black early out break; } else { // we need to check for other black parents to enforce the TriColor invariant continue; } } if (base->IsBlack()) { color = ObjectColor::Grey; parent_is_black = true; // if any parent container is black, and we have already removed from the // given container, we can early out if (removed) break; } ++iter; } SetColorRecursive(color); }
foreach (Object cont, contained) { graph << object_id << " -> " << cont.GetHandle().GetValue() << "[style=dotted]\n"; graph << cont; }
foreach (Object prop, props) { //graph << object_id << "[label=\"" << prop.GetLabel() << "\"]\n"; graph << object_id << " -> " << prop.GetHandle().GetValue() << "[style=dashed]\n"; graph << prop; }