Skip to content

Instantly share code, notes, and snippets.

@cclecle
Created May 24, 2023 23:23
Show Gist options
  • Save cclecle/e0535c04b90cfd88b37e11d9e0f83be7 to your computer and use it in GitHub Desktop.
Save cclecle/e0535c04b90cfd88b37e11d9e0f83be7 to your computer and use it in GitHub Desktop.
RelationalClasses.uc
class RelationalClasses extends Object;
Struct T_RawClassTreeRecord
{
var int level;
var string ClassName;
var string PackageName;
var class<RelationalClasses> TClass;
};
Struct T_RawClassRecord
{
var string PackageName;
var string ClassName;
};
var class<RelationalClasses> Tparent;
var array<class<RelationalClasses> > Tchilds;
static function SetClassRelationsTree(LevelInfo L,string baseClass)
{
local int i;
local int PreviousLevel;
local string ClassTree;
local string ClassList;
local array<T_RawClassTreeRecord> SplitedClassTree;
local array<T_RawClassRecord> SplitedClassList;
local array<T_RawClassTreeRecord> 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<SplitedClassTree.Length;i++)
{
if(classStack.Length == 0)
{
classStack.Length = 1;
classStack[0] = SplitedClassTree[i];
classStack[0].TClass = class<RelationalClasses>(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<RelationalClasses>(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<T_RawClassTreeRecord> ClassTree,array<T_RawClassRecord> ClassRecord)
{
local int i,j;
for(i=0;i<ClassTree.Length;i++)
{
for(j=0;j<ClassRecord.Length;j++)
{
if(ClassTree[i].ClassName == ClassRecord[j].ClassName)
{
ClassTree[i].PackageName = ClassRecord[j].PackageName;
break;
}
}
if(j==ClassRecord.Length)
{
Warn("Class Package not found !! ("@ClassTree[i].ClassName@")");
}
}
}
static function array<T_RawClassTreeRecord> SplitClassesTree(string szClasses, string baseClass)
{
local array<T_RawClassTreeRecord> 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<T_RawClassRecord> SplitClassesList(string szClasses)
{
local array<T_RawClassRecord> 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<IndexFound)
{
break; //End
}
if(IndexFound!=-1) // package separator found
{
PkgName=Left(szClasses,IndexFound);
szClasses=Mid(szClasses,IndexFound,Len(szClasses));
IndexFound=InStr(szClasses," ");
if(IndexFound!=-1) // end of class found
{
ClassName=Mid(szClasses,1,IndexFound-1);
szClasses=Mid(szClasses,IndexFound,Len(szClasses));
Result.insert(0,1);
Result[0].ClassName=ClassName;
Result[0].PackageName=PkgName;
szClasses=szClasses;
}
else // end of class not found => 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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment