Author Topic: scan_for_destructed_objects() sefun  (Read 3306 times)

Offline chaos

  • BFF
  • ***
  • Posts: 291
  • Job, school, social life, sleep. Pick 2.5.
    • View Profile
    • Lost Souls
scan_for_destructed_objects() sefun
« on: April 22, 2009, 08:18:10 PM »
This is my scan_for_destructed_objects() sefun, used to examine a complex data structure to cause any references to destructed objects within it to be examined by the driver, so that the reference will be freed and the destructed object hopefully allowed to be deallocated (when all other references to it are also cleaned up).

First argument is whatever we want to scan.  Second argument is optional, and should probably be left to internal use, but can be used to send an array of values that shouldn't be looked at, if encountered.  Return value is true if any circular references were encountered in the course of events (so this function can also be used to non-destructively check for the existence of circular references).

Both versions presume the existence of
Code: [Select]
#define True  1
#define False 0
#define Null  (-1)
which I keep in my system global include.  The LDmud version also needs
Code: [Select]
#define array *
This code is released into the public domain.

LDmud version:

Code: [Select]
varargs status scan_for_destructed_objects(mixed what, mixed array pointers) {
    pointers ||= ({});
    if(member(pointers, what) != Null)
        return True;
    status out = False;
    switch(typeof(what)) {
    case T_MAPPING                          :
        pointers += ({ what });
        switch(widthof(what)) {
        case 0                              :
            foreach(mixed key : what) {
                switch(typeof(key)) {
                case T_MAPPING              :
                case T_QUOTED_ARRAY         :
                case T_POINTER              :
                    if(scan_for_destructed_objects(key, pointers))
                        out = True;
                    break;
                }
            }
            break;
        case 1                              :
            foreach(mixed key, mixed val : what) {
                switch(typeof(key)) {
                case T_MAPPING              :
                case T_QUOTED_ARRAY         :
                case T_POINTER              :
                    if(scan_for_destructed_objects(key, pointers))
                        out = True;
                    break;
                }
                switch(typeof(val)) {
                case T_MAPPING              :
                case T_QUOTED_ARRAY         :
                case T_POINTER              :
                    if(scan_for_destructed_objects(val, pointers))
                        out = True;
                    break;
                }
            }
            break;
        default                             :
            int width = widthof(what);
            foreach(mixed key, mixed val : what) {
                switch(typeof(key)) {
                case T_MAPPING              :
                case T_QUOTED_ARRAY         :
                case T_POINTER              :
                    if(scan_for_destructed_objects(key, pointers))
                        out = True;
                    break;
                }
                switch(typeof(val)) {
                case T_MAPPING              :
                case T_QUOTED_ARRAY         :
                case T_POINTER              :
                    if(scan_for_destructed_objects(val, pointers))
                        out = True;
                    break;
                }
                for(int ix = width - 1; ix >= 2; ix--) {
                    mixed wval = what[key, ix];
                    switch(typeof(wval)) {
                    case T_MAPPING          :
                    case T_QUOTED_ARRAY     :
                    case T_POINTER          :
                        if(scan_for_destructed_objects(wval, pointers))
                            out = True;
                        break;
                    }
                }
            }
            break;
        }
        break;
    case T_QUOTED_ARRAY                     :
        do
            what = unquote(what);
        while(typeof(what) == T_QUOTED_ARRAY);
        // fallthrough
    case T_POINTER                          :
        pointers += ({ what });
        foreach(mixed item : what) {
            switch(typeof(item)) {
            case T_MAPPING                  :
            case T_QUOTED_ARRAY             :
            case T_POINTER                  :
                if(scan_for_destructed_objects(item, pointers))
                    out = True;
                break;
            }
        }
        break;
    }
    return out;
}

Untested attempt at a MudOS/FLuffOS port:

Code: [Select]
varargs status scan_for_destructed_objects(mixed what, mixed array pointers) {
    pointers ||= ({});
    if(member(pointers, what) != Null)
        return True;
    status out = False;
    switch(typeof(what)) {
    case T_MAPPING                          :
        pointers += ({ what });
        foreach(mixed key, mixed val : what) {
            switch(typeof(key)) {
            case T_MAPPING              :
            case T_POINTER              :
                if(scan_for_destructed_objects(key, pointers))
                    out = True;
                break;
            }
            switch(typeof(val)) {
            case T_MAPPING              :
            case T_POINTER              :
                if(scan_for_destructed_objects(val, pointers))
                    out = True;
                break;
            }
        }
        break;
    }
    case T_POINTER                          :
        pointers += ({ what });
        foreach(mixed item : what) {
            switch(typeof(item)) {
            case T_MAPPING                  :
            case T_POINTER                  :
                if(scan_for_destructed_objects(item, pointers))
                    out = True;
                break;
            }
        }
        break;
    }
    return out;
}