class RelationalClasses extends Object; Struct T_RawClassTreeRecord { var int level; var string ClassName; var string PackageName; var class TClass; }; Struct T_RawClassRecord { var string PackageName; var string ClassName; }; var class Tparent; var array > Tchilds; static function SetClassRelationsTree(LevelInfo L,string baseClass) { local int i; local int PreviousLevel; local string ClassTree; local string ClassList; local array SplitedClassTree; local array SplitedClassList; local array classStack; ClassList = L.ConsoleCommand("obj list class=class"); SplitedClassList = SplitClassesList(ClassList); ClassTree = L.ConsoleCommand("obj classes"); SplitedClassTree = SplitClassesTree(ClassTree,baseClass); FillClassPackages(SplitedClassTree,SplitedClassList); for(i=0;i(DynamicLoadObject(SplitedClassTree[i].PackageName$"."$SplitedClassTree[i].ClassName, class'Object')); classStack[0].TClass.default.Tparent = None; } else { PreviousLevel = classStack[classStack.Length-1].level; if( SplitedClassTree[i].level > PreviousLevel) { classStack.insert(classStack.Length,1); classStack[classStack.Length-1] = SplitedClassTree[i]; } else if( SplitedClassTree[i].level == PreviousLevel) { } else { classStack.Remove(classStack.Length - (PreviousLevel- SplitedClassTree[i].level),(PreviousLevel- SplitedClassTree[i].level)); } classStack[classStack.Length-1].TClass = class(DynamicLoadObject(SplitedClassTree[i].PackageName$"."$SplitedClassTree[i].ClassName, class'Object')); classStack[classStack.Length-1].TClass.default.Tparent = classStack[classStack.Length-2].TClass; classStack[classStack.Length-2].TClass.default.Tchilds.insert(0,1); classStack[classStack.Length-2].TClass.default.Tchilds[0] = classStack[classStack.Length-1].TClass; } } } static function FillClassPackages(out array ClassTree,array ClassRecord) { local int i,j; for(i=0;i SplitClassesTree(string szClasses, string baseClass) { local array Result; local string TmpClass,tempChar; local int precount, curcount, classcount, strLength; local int NbSpaces; local int ClassLevel; local int InitialClassLevel; local bool bSpaceState; local bool bClassFound; strLength = len(szClasses); do { tempChar = Mid(szClasses, curcount, 1); //go up by 1 count if(bSpaceState) { if(tempChar != " ") { bSpaceState=False; } else { NbSpaces++; precount++; } } else { if(tempChar == " " || (curcount==strLength)) { bSpaceState=True; TmpClass = Mid(szClasses, precount, curcount-precount); if(bClassFound || (TmpClass~=baseClass)) { ClassLevel = NbSpaces/2; if(!bClassFound) { InitialClassLevel = ClassLevel; } else if(ClassLevel <= InitialClassLevel) { return Result; } Result.Length = Result.Length+1; Result[classcount].ClassName = TmpClass; Result[classcount].level=ClassLevel - InitialClassLevel; classcount++; bClassFound=True; } precount = curcount+1; NbSpaces=1; } } curcount++; } until(curcount==strLength); return Result; } static function array SplitClassesList(string szClasses) { local array Result; local int IndexFound; local int IndexFound2; local string PkgName; local string ClassName; while(true) { IndexFound = InStr(szClasses,"Class "); if(IndexFound!=-1) { szClasses=Mid(szClasses,IndexFound+6,Len(szClasses)); IndexFound=InStr(szClasses,"."); IndexFound2=InStr(szClasses," "); if(IndexFound2!=-1 && IndexFound2 invalid => stop { warn("Invalid Package/Class format (2)"); break; } } else // package separator not found => invalid => stop { warn("Invalid Package/Class format (3)"); break; } } else // no more Class { break; //abnormal end.. } } return Result; }