view dwt/dwthelper/WeakHashMap.d @ 226:6da025bf255e

some fixes
author Frank Benoit <benoit@tionex.de>
date Fri, 11 Apr 2008 17:50:39 +0200
parents d0081b1505da
children 695802b523c0
line wrap: on
line source

module dwt.dwthelper.WeakHashMap;


private {
    alias void delegate(Object) DisposeEvt;
    extern (C) void  rt_attachDisposeEvent( Object obj, DisposeEvt evt );
    extern (C) void  rt_detachDisposeEvent( Object obj, DisposeEvt evt );
}


/+
    Is not yet 'weak'
+/
class WeakHashMap {

    static class Ref {
        size_t ptr;
        this(Object k){
            ptr = cast(size_t)cast(void*)k;
        }
        override hash_t toHash(){
            return cast(hash_t)ptr;
        }
        override int opEquals( Object o ){
            if( auto other = cast(Ref)o ){
                return ptr is other.ptr;
            }
            return false;
        }
    }

    private Ref unhookKey;

    private void unhook(Object o) {
        unhookKey.ptr = cast(size_t)cast(void*)o;
        if( auto p = unhookKey in data ){
            rt_detachDisposeEvent(o, &unhook);
            data.remove( unhookKey );
        }
    }

    Object[ Ref ] data;
    ClassInfo gcLock;
    this(){
        unhookKey = new Ref(null);
        gcLock = ClassInfo.find( "gcx.GCLock" );
    }

    public void add (Object key, Object element){
        auto k = new Ref(key);
        rt_attachDisposeEvent(key, &unhook);
        data[ k ] = element;
    }
    public void removeKey (Object key){
        scope k = new Ref(key);
        if( auto p = k in data ){
            data.remove( k );
            rt_detachDisposeEvent(key, &unhook);
        }
    }
    public Object get(Object key){
        scope k = new Ref(key);
        if( auto p = k in data ){
            return *p;
        }
        return null;
    }
}