Exemple #1
0
KAI_BEGIN

Pathname GetFullname(const Object &Q)
{
	if (!Q.Valid())
		return Pathname();

	return GetFullname(GetStorageBase(Q));
}
Exemple #2
0
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);
}
Exemple #3
0
void Registry::TriColor()
{
	// this is a magic number. the higher it is, the more objects may be deleted in this call
	// the cost has to be paid at some point, so this number really means "how much do I want
	// to spread out cost of GC over time versus memory use".
	//
	// if you have lots of memory, set max_cycles to 1. (or zero!). if not, set it higher
	// until you can fit memory usage into a sequence of frames.
	//
	// see also https://github.com/cschladetsch/Monotonic 
	const int max_cycles = 17;
	if (gc_trace_level >= 1)
	{
		KAI_TRACE_3(instances.size(), grey.size(), white.size());
	}

	int cycle = 0;
	for (; cycle < max_cycles; ++cycle)
	{
#ifdef KAI_DEBUG_REGISTRY
		if (gc_trace_level > 2) 
			TraceTriColor();
#endif

		if (grey.empty())
		{
			ReleaseWhite();
			break;
		}

		ColoredSet::iterator iter = grey.begin();
		Handle handle = *iter;
		grey.erase(iter);
		StorageBase *base = GetStorageBase(handle);
		if (base == 0)
			continue;

		base->MakeReachableGrey();
		base->SetColor(ObjectColor::Black);
	}

	if (gc_trace_level >= 1)
		KAI_TRACE() << "TriColor: " << cycle << " passes";
}
Exemple #4
0
void Registry::MarkAll(StorageBase &root, bool marked)
{
	MarkObject(root, marked);
	const Dictionary &dict = root.GetDictionary();
	Dictionary::const_iterator C = dict.begin(), D = dict.end();
	for (; C != D; ++C)
	{
		Object const &child = C->second;
		StorageBase *base = GetStorageBase(child.GetHandle());
		if (base == 0)
			continue;

		if (base->IsManaged())
			MarkObject(*base, marked);

		if (base->GetSwitches() & IObject::NoRecurse)
			continue;

		MarkAll(*base, marked);
	}
}
Exemple #5
0
Pathname GetFullname(const StorageBase &Q)
{
	nstd::list<String> parentage;
	Label const &label = Q.GetLabel();
	if (!label.ToString().empty())
		parentage.push_back(label.ToString());

	Object parent = Q.GetParent();
	for (; parent.Valid(); parent = parent.GetParent())
		parentage.push_front(GetStorageBase(parent).GetLabel().ToString());

	StringStream path;
	if (!parentage.empty())
		;//path << "[anon]";
	else
		path.Append('/');

	foreach (String const &name, parentage)
	{
		path.Append(name);
		path.Append('/');
	}