/// <summary> /// Finds the first native (non-managed) class for this managed class. This also caches the native parent /// class constructor for calling the parent constructor and setting it as the fallback constructor on hotreload. /// </summary> public void ResolveNativeParentClass() { NativeParentClassConstructor = IntPtr.Zero; if (Address == IntPtr.Zero) { return; } // We could possibly update this code to do a deep search for the first non-C# class (e.g. C# : X : C# : X : UObject). // We aren't currently calling the parent constructor in a way which would allow this. If we supported it as-is the C# // constructors would get called multiple times when calling the parent constructor. IntPtr parentClass = Native_UClass.GetSuperClass(Address); while (parentClass != IntPtr.Zero) { if (!Native_UObjectBaseUtility.IsA(parentClass, Runtime.Classes.USharpClass)) { NativeParentClass = parentClass; NativeParentClassConstructor = Native_UClass.Get_ClassConstructor(parentClass); break; } parentClass = Native_UClass.GetSuperClass(parentClass); } Debug.Assert(NativeParentClass != IntPtr.Zero); }
private static unsafe IntPtr FindOriginalVTableOwner(IntPtr baseMostClass, IntPtr ownerClass, IntPtr functionAddress, int vtableIndex) { // Don't search lower than the target base if (ownerClass == baseMostClass) { return(ownerClass); } IntPtr originalOwner = ownerClass; while ((ownerClass = Native_UClass.GetSuperClass(ownerClass)) != IntPtr.Zero) { IntPtr obj = Native_UClass.GetDefaultObject(ownerClass, true); IntPtr *vtable = *(IntPtr **)obj; if (vtable[vtableIndex] == functionAddress) { originalOwner = ownerClass; } // Don't search lower than the target base if (ownerClass == baseMostClass) { return(ownerClass); } } return(originalOwner); }
private IntPtr FindFirstNonUSharpClassParentClass(IntPtr unrealClass) { IntPtr sharpStaticClass = Native_USharpClass.StaticClass(); while (unrealClass != IntPtr.Zero && !Native_UObjectBaseUtility.IsA(unrealClass, sharpStaticClass)) { unrealClass = Native_UClass.GetSuperClass(unrealClass); } return(unrealClass); }
private IntPtr FindFirstNativeParentClass(IntPtr unrealClass) { IntPtr sharpStaticClass = Native_USharpClass.StaticClass(); while (unrealClass != IntPtr.Zero && (!Native_UClass.HasAnyClassFlags(unrealClass, EClassFlags.Native) || Native_UObjectBaseUtility.IsA(unrealClass, sharpStaticClass))) { unrealClass = Native_UClass.GetSuperClass(unrealClass); } return(unrealClass); }
private void Constructor(IntPtr objectInitializerPtr) { Native_UClass.Call_ClassConstructor(ParentClass, objectInitializerPtr); FObjectInitializer objectInitializer = new FObjectInitializer(objectInitializerPtr); IntPtr sharpStaticClass = Native_USharpClass.StaticClass(); IntPtr unrealClass = Native_FObjectInitializer.GetClass(objectInitializerPtr); IntPtr sharpClass = unrealClass; while (sharpClass != IntPtr.Zero && !Native_UObjectBaseUtility.IsA(sharpClass, sharpStaticClass)) { sharpClass = Native_UClass.GetSuperClass(sharpClass); } System.Diagnostics.Debug.Assert(sharpClass != IntPtr.Zero); }
private static void MetaDataMergeClassCategories(IntPtr metadata, IntPtr obj, Dictionary <FName, string> values) { // Copying the logic in FClassDeclarationMetaData::MergeClassCategories // Engine\Source\Programs\UnrealHeaderTool\Private\ClassDeclarationMetaData.cpp // ShowFunctions HideFunctions // HideCategories ShowCategories ShowSubCatgories // AutoExpandCategories AutoCollapseCategories // - How is ShowFunctions / HideFunctions used? Hiding a function doesn't seem to hide it from being // visible in the actions list in Blueprint. If it isn't super important we could skip it. // - ShowCategories / HideCategories is important // Maybe cache these lists and clear them for each type HashSet <string> showCategories = new HashSet <string>(); HashSet <string> hideCategories = new HashSet <string>(); HashSet <string> showSubCategories = new HashSet <string>(); HashSet <string> showFunctions = new HashSet <string>(); HashSet <string> hideFunctions = new HashSet <string>(); HashSet <string> autoExpandCategories = new HashSet <string>(); HashSet <string> autoCollapseCategories = new HashSet <string>(); HashSet <string> dontAutoCollapseCategories = new HashSet <string>(); HashSet <string> classGroupNames = new HashSet <string>(); GetMetaDataItems(UMeta.GetKeyName(MDClass.ShowCategories), values, showCategories); GetMetaDataItems(UMeta.GetKeyName(MDClass.HideCategories), values, hideCategories); GetMetaDataItems(UMeta.GetKeyName(MDClass.ShowFunctions), values, showFunctions); GetMetaDataItems(UMeta.GetKeyName(MDClass.HideFunctions), values, hideFunctions); GetMetaDataItems(UMeta.GetKeyName(MDClass.AutoExpandCategories), values, autoExpandCategories); GetMetaDataItems(UMeta.GetKeyName(MDClass.AutoCollapseCategories), values, autoCollapseCategories); GetMetaDataItems(UMeta.GetKeyName(MDClass.DontAutoCollapseCategories), values, dontAutoCollapseCategories); GetMetaDataItems(UMeta.GetKeyName(MDClass.ClassGroupNames), values, classGroupNames); IntPtr parentClass = Native_UClass.GetSuperClass(obj); HashSet <string> parentHideCategories = new HashSet <string>(); HashSet <string> parentShowSubCatgories = new HashSet <string>(); HashSet <string> parentHideFunctions = new HashSet <string>(); HashSet <string> parentAutoExpandCategories = new HashSet <string>(); HashSet <string> parentAutoCollapseCategories = new HashSet <string>(); GetParentMetaDataItems(metadata, parentClass, UMeta.GetKeyName(MDClass.HideCategories), parentHideCategories); GetParentMetaDataItems(metadata, parentClass, UMeta.GetKeyName(MDClass.ShowCategories), parentShowSubCatgories); GetParentMetaDataItems(metadata, parentClass, UMeta.GetKeyName(MDClass.HideFunctions), parentHideFunctions); GetParentMetaDataItems(metadata, parentClass, UMeta.GetKeyName(MDClass.AutoExpandCategories), parentAutoExpandCategories); GetParentMetaDataItems(metadata, parentClass, UMeta.GetKeyName(MDClass.AutoCollapseCategories), parentAutoCollapseCategories); // Add parent categories. We store the opposite of HideCategories and HideFunctions in a separate array anyway. MetaDataMergeCollection(hideCategories, parentHideCategories); MetaDataMergeCollection(showSubCategories, parentShowSubCatgories); MetaDataMergeCollection(hideFunctions, parentHideFunctions); MetaDataMergeShowCategories(showCategories, hideCategories, showSubCategories); // Merge ShowFunctions and HideFunctions foreach (string value in showFunctions) { hideFunctions.Remove(value); } //showFunctions.Clear(); // Merge DontAutoCollapseCategories and AutoCollapseCategories foreach (string value in dontAutoCollapseCategories) { autoCollapseCategories.Remove(value); } //dontAutoCollapseCategories.Clear(); // The original function then merges ShowFunctions / HideFunctions again? (ShowFunctions will now be empty) // Merge AutoExpandCategories and AutoCollapseCategories (we still want to keep AutoExpandCategories though!) foreach (string value in autoExpandCategories) { autoCollapseCategories.Remove(value); parentAutoCollapseCategories.Remove(value); } // Do the same as above but the other way around foreach (string value in autoCollapseCategories) { autoExpandCategories.Remove(value); parentAutoExpandCategories.Remove(value); } // Once AutoExpandCategories and AutoCollapseCategories for THIS class have been parsed, add the parent inherited categories MetaDataMergeCollection(autoCollapseCategories, parentAutoCollapseCategories); MetaDataMergeCollection(autoExpandCategories, parentAutoExpandCategories); SetOrClearMetaDataClassCollection(MDClass.ClassGroupNames, values, classGroupNames); SetOrClearMetaDataClassCollection(MDClass.AutoCollapseCategories, values, autoCollapseCategories); SetOrClearMetaDataClassCollection(MDClass.HideCategories, values, hideCategories); SetOrClearMetaDataClassCollection(MDClass.ShowCategories, values, showSubCategories); SetOrClearMetaDataClassCollection(MDClass.HideFunctions, values, hideFunctions); SetOrClearMetaDataClassCollection(MDClass.AutoExpandCategories, values, autoExpandCategories); }
public UClass GetSuperClass() { return(GCHelper.Find <UClass>(Native_UClass.GetSuperClass(Address))); }