/// <summary> /// Gets all objects, including class default objects. /// </summary> public static FObjectIterator GetObjectsEx <T>( bool onlyGCedObjects = false, EObjectFlags additionalExclusionFlags = EObjectFlags.NoFlags, EInternalObjectFlags internalExclusionFlags = EInternalObjectFlags.None) where T : UObject { return(GetObjectsEx(UClass.GetClass <T>(), onlyGCedObjects, additionalExclusionFlags, internalExclusionFlags)); }
public string ResolveNameConflict(UField field, string name) { UFunction function = field as UFunction; if (function != null) { // Functions are a special case and must use the base-most function for name resolving. // See above for more info on this. UFunction originalFunction; UClass originalOwner = codeGenerator.GetOriginalFunctionOwner(function, out originalFunction); if (originalOwner != Class) { StructInfo originalOwnerStructInfo = codeGenerator.GetStructInfo(originalOwner); return(originalOwnerStructInfo.ResolveNameConflict(originalFunction, name)); } } string resolvedName; if (conflictInfo.ResolvedName.TryGetValue(field, out resolvedName)) { return(resolvedName); } return(name); }
/// <summary> /// reate a component or subobject /// </summary> /// <typeparam name="TReturnType">class of return type, all overrides must be of this type </typeparam> /// <typeparam name="TClassToConstructByDefault">class to construct by default</typeparam> /// <param name="outer">outer to construct the subobject in </param> /// <param name="subobjectName">name of the new component </param> /// <param name="transient">true if the component is being assigned to a transient property</param> /// <returns></returns> public TReturnType CreateDefaultSubobject <TReturnType, TClassToConstructByDefault>(UObject outer, FName subobjectName, bool transient = false) where TReturnType : UObject where TClassToConstructByDefault : UObject { return(CreateDefaultSubobject(outer, subobjectName, UClass.GetClass <TReturnType>(), UClass.GetClass <TClassToConstructByDefault>(), true, false, transient) as TReturnType); }
public TScriptInterface(T value) { IntPtr interfaceClass = UClass.GetInterfaceClassAddress <T>(); if (interfaceClass == IntPtr.Zero) { Base = default(FScriptInterface); return; } IntPtr objectPointer = value.GetAddress(); if (objectPointer == IntPtr.Zero) { Base = default(FScriptInterface); return; } IntPtr interfacePointer = Native_UObjectBaseUtility.GetNativeInterfaceAddress(objectPointer, interfaceClass); if (interfacePointer == IntPtr.Zero) { Base = default(FScriptInterface); return; } Base = new FScriptInterface(objectPointer, interfacePointer); }
/// <summary> /// Gets the managed type for a given UClass /// </summary> /// <param name="unrealClass">The UClass to get the managed type for</param> /// <returns>The managed type</returns> public static Type GetType(UClass unrealClass) { Type type; classesByAddress.TryGetValue(unrealClass.Address, out type); return(type); }
internal static void RegisterManagedClass(IntPtr classAddress, Type type) { UClass existingClass; if (classes.TryGetValue(type, out existingClass)) { classes.Remove(type); classesByAddress.Remove(existingClass.Address); } seenClasses.Remove(type); classesByAddress[classAddress] = type; UClass unrealClass = GCHelper.Find <UClass>(classAddress); if (unrealClass != null) { classes[type] = unrealClass; } else { classesByAddress.Remove(classAddress); } // If this is an interface add it to UnrealInterfacePool so that we can create instances of this // interface which are implemented in Blueprint if (type.IsInterface) { UnrealInterfacePool.LoadType(type); } }
internal static void Load() { classes.Clear(); classesByAddress.Clear(); seenClasses.Clear(); // Use two passes so that classesByAddress has all available types which are needed when // calling GCHelper.Find() in the second pass // First pass to fill up classesByAddress collection foreach (KeyValuePair <Type, UMetaPathAttribute> nativeType in UnrealTypes.Native) { Type type = nativeType.Key; UMetaPathAttribute attribute = nativeType.Value; if (type.IsSameOrSubclassOf(typeof(UObject)) || type.IsInterface) { IntPtr classAddress = GetClassAddress(attribute.Path); if (classAddress != IntPtr.Zero) { classesByAddress[classAddress] = type; } } } // It should now be safe to access GCHelper (which is required by the second pass to fill // in the classes collection with the managed UClass objects) GCHelper.Available = true; int unknownCount = 0; // Second pass fill up classes collection foreach (KeyValuePair <IntPtr, Type> classByAddress in classesByAddress) { IntPtr classAddress = classByAddress.Key; Type type = classByAddress.Value; UClass unrealClass = GCHelper.Find <UClass>(classAddress); if (unrealClass != null) { classes[type] = unrealClass; } else { unknownCount++; } } if (unknownCount > 0) { // sync classes/classByAddress if some failed to add to the classes collection foreach (KeyValuePair <IntPtr, Type> classByAddress in new Dictionary <IntPtr, Type>(classesByAddress)) { if (!classes.ContainsKey(classByAddress.Value)) { classesByAddress.Remove(classByAddress.Key); } } } }
private bool CanExportStruct(UStruct unrealStruct) { // Ignore UProperty all classes if (unrealStruct.IsChildOf <UProperty>()) { return(false); } // Skip classes which are already defined in this project if (projectDefinedTypes.ContainsKey(unrealStruct.GetPathName())) { return(false); } if (Settings.ExportAllStructures) { return(true); } UClass unrealClass = unrealStruct as UClass; if (unrealClass != null) { if (unrealClass.HasAnyClassFlags(EClassFlags.Deprecated)) { return(false); } // EClassFlags.Transient - should we be checking this } return(true); }
private static T FindOrLoadObject <T>(string pathName) where T : UObject { if (typeof(T) == typeof(UPackage)) { return(FindOrLoadPackage(pathName) as T); } // If there is no dot, add a dot and repeat the object name. int packageDelimPos = pathName.IndexOf('.'); if (packageDelimPos == -1) { int objectNameStart = pathName.LastIndexOf('/'); if (objectNameStart != -1) { pathName += "." + pathName.Substring(objectNameStart + 1); } } UClass unrealClass = UClass.GetClass <T>(); if (unrealClass != null) { unrealClass.GetDefaultObject();// force the CDO to be created if it hasn't already T obj = UObject.LoadObject <T>(null, pathName); if (obj != null) { obj.AddToRoot(); } return(obj); } return(null); }
public static void SetMetaData <T>(IntPtr obj, string key, T value) { string valueStr = null; UClass unrealClass = value as UClass; if (unrealClass != null) { valueStr = unrealClass.GetPathName(); } else { valueStr = value.ToString(); } IntPtr metadata = GetMetaDataFromObj(obj); if (metadata != IntPtr.Zero) { using (FStringUnsafe keyUnsafe = new FStringUnsafe(key)) using (FStringUnsafe valueUnsafe = new FStringUnsafe(key)) { Native.Native_UMetaData.SetValue(metadata, obj, ref keyUnsafe.Array, ref valueUnsafe.Array); } } }
public T GetSubsystem <T>() where T : USubsystem { UClass uclass = UClass.GetClass(typeof(T)); IntPtr system = Native_FSubsystemCollection.GetSubsystem(this.Address, uclass.Address); return(GCHelper.Find <T>(system)); }
internal static IntPtr GetStaticClass(Type type) { if (IsManagedUnrealType(type)) { ManagedUnrealClass baseClass = FindClass(type); if (baseClass != null) { return(baseClass.StaticClass); } baseClass = CreateClass(type); if (baseClass != null) { return(baseClass.StaticClass); } } else { UMetaPathAttribute pathAttribute = type.GetCustomAttribute <UMetaPathAttribute>(); if (pathAttribute != null) { return(UClass.FindClassAddressByPath(pathAttribute.Path)); } } return(IntPtr.Zero); }
public unsafe T GetInterface <T>() where T : class, IInterface { T result = this as T; if (result != null) { return(result); } if (injectedInterfaces == null) { // If the injected interfaces haven't been set up set them up now if (objRef == null) { return(null); } UClass unrealClass = GetClass(); if (unrealClass as USharpClass != null) { // This is a C# defined type. We know if it implements the target interface or not due to the // above "this as T". There isn't any need to inject interfaces into the UObject. return(null); } FScriptArray *interfacesPtr = (FScriptArray *)Native_UClass.Get_InterfacesRef(unrealClass.Address); if (interfacesPtr->ArrayNum != 0) { injectedInterfaces = new Dictionary <Type, IInterface>(); foreach (FImplementedInterface implementedInterface in unrealClass.Interfaces) { if (implementedInterface.InterfaceClassAddress != IntPtr.Zero) { Type type = UClass.GetTypeFromClassAddress(implementedInterface.InterfaceClassAddress); if (type != null) { IInterface instance = UnrealInterfacePool.New(type, objRef); if (instance != null) { injectedInterfaces[type] = instance; if (type == typeof(T)) { result = instance as T; } } } } } } } else { // Try and get the interface from the injected interfaces. IInterface instance; injectedInterfaces.TryGetValue(typeof(T), out instance); result = instance as T; } return(result); }
/// <summary> /// Returns the class UClass if it is loaded. It is not possible to load the class if it is unloaded since we only have the short name. /// </summary> /// <returns></returns> public UClass GetClass() { if (!IsValid) { return(null); } return(UClass.GetClass(AssetClass.ToString())); }
/// <summary> /// This will return whether or not this class implements the passed in class / interface /// </summary> /// <param name="someInterface">the interface to check and see if this class implements it</param> /// <returns></returns> public bool ImplementsInterface(UClass someInterface) { if (someInterface != null && someInterface.HasAnyClassFlags(EClassFlags.Interface)) { return(Native_UClass.ImplementsInterface(Address, someInterface.Address)); } return(false); }
/// <summary> /// Returns an array of classes that were derived from the specified class. /// </summary> /// <param name="classToLookFor">The parent class of the classes to return.</param> /// <param name="recursive">If true, the results will include children of the children classes, recursively. Otherwise, only direct decedents will be included.</param> /// <returns></returns> public static UClass[] GetDerivedClasses(UClass classToLookFor, bool recursive = true) { using (TArrayUnsafe <UClass> result = new TArrayUnsafe <UClass>()) { Native_UObjectHash.GetDerivedClasses(classToLookFor.Address, result.Address, recursive); return(result.ToArray()); } }
/// <summary> /// Gets all objects, including class default objects. /// </summary> public static FObjectIterator GetObjectsEx( UClass unrealClass, bool onlyGCedObjects = false, EObjectFlags additionalExclusionFlags = EObjectFlags.NoFlags, EInternalObjectFlags internalExclusionFlags = EInternalObjectFlags.None) { return(new FObjectIterator(unrealClass, onlyGCedObjects, additionalExclusionFlags, internalExclusionFlags)); }
/// <summary> /// Returns an array of objects of a specific class. Optionally, results can include objects of derived classes as well. /// </summary> /// <param name="classToLookFor">Class of the objects to return.</param> /// <param name="includeDerivedClasses">If true, the results will include objects of child classes as well.</param> /// <param name="additionalExcludeFlags">Objects with any of these flags will be excluded from the results.</param> /// <param name="exclusionInternalFlags">Specifies internal flags to use as a filter for which objects to return</param> /// <returns></returns> public static UObject[] GetObjectsOfClass(UClass classToLookFor, bool includeDerivedClasses = true, EObjectFlags additionalExcludeFlags = EObjectFlags.ClassDefaultObject, EInternalObjectFlags exclusionInternalFlags = EInternalObjectFlags.None) { using (TArrayUnsafe <UObject> result = new TArrayUnsafe <UObject>()) { Native_UObjectHash.GetObjectsOfClass(classToLookFor.Address, result.Address, includeDerivedClasses, additionalExcludeFlags, exclusionInternalFlags); return(result.ToArray()); } }
private bool IsBlueprintVisibleStruct(UStruct unrealStruct) { // All of the available macro tags at: // Engine\Source\Runtime\CoreUObject\Public\UObject\ObjectBase.h // BlueprintType = can use inside a blueprint // Blueprintable = can use as a new blueprint // Blueprintable seems to override NotBlueprintType? // IsBlueprintBase, BlueprintSpawnableComponent // All UBlueprintFunctionLibrary classes are visible in blueprint even if marked as not visible if (unrealStruct.IsChildOf <UBlueprintFunctionLibrary>()) { return(true); } // Action classes are exposed to Blueprint as special nodes. We want the entire class. UClass unrealClass = unrealStruct as UClass; if (unrealClass != null && GetActionFactoryClass(unrealClass) != null) { return(true); } if (unrealStruct.GetBoolMetaDataHierarchical(MDClass.BlueprintSpawnableComponent))// && Struct.IsChildOf<UActorComponent>() { // Are all BlueprintSpawnableComponent classes visible even if marked not? TODO: Check this. return(true); } bool notBlueprintType = false; bool notBlueprintable = false; while (unrealStruct != null) { if (!notBlueprintType && unrealStruct.GetBoolMetaData(MDClass.BlueprintType)) { return(true); } if (!notBlueprintable && unrealStruct.GetBoolMetaData(MDClass.Blueprintable)) { return(true); } if (unrealStruct.GetBoolMetaData(MDClass.NotBlueprintType)) { notBlueprintType = true; } if (unrealStruct.GetBoolMetaData(MDClass.NotBlueprintable)) { notBlueprintable = true; } unrealStruct = unrealStruct.GetSuperStruct(); } return(false); }
public static unsafe void HackVTable(UObject obj) { // This will swap out the vtable entry and store the old one in our managed UClass if (!Native_UObjectBaseUtility.IsA(obj.Address, Runtime.Classes.UClass)) { UClass unrealClass = obj.GetClass(); if (unrealClass.VTableOriginalFunctions == null) { IntPtr *vtable = *(IntPtr **)obj.Address; unrealClass.VTableOriginalFunctions = new Dictionary <int, UClass.VTableOriginalFunc>(); foreach (FunctionRedirect redirect in vtableRedirects) { if (!Native_UObjectBaseUtility.IsA(obj.Address, redirect.Class)) { continue; } IntPtr originalFunctionAddress = vtable[redirect.VTableIndex]; if (originalFunctionAddress != redirect.NativeCallback) { IntPtr originalOwnerClassAddress = FindOriginalVTableOwner( redirect.Class, unrealClass.Address, originalFunctionAddress, redirect.VTableIndex); if (originalOwnerClassAddress != unrealClass.Address) { UClass originalOwnerClass = GCHelper.Find <UClass>(originalOwnerClassAddress); if (originalOwnerClass.VTableOriginalFunctions == null) { HackVTable(originalOwnerClass.GetDefaultObject()); } } IntPtr pageAlignedPtr = FMemory.PageAlignPointer((IntPtr)(&vtable[redirect.VTableIndex])); FMemory.PageProtect(pageAlignedPtr, (IntPtr)IntPtr.Size, true, true); *(&vtable[redirect.VTableIndex]) = redirect.NativeCallback; } else { // The VTable has already been swapped out. Find the original function address. UClass superClass = unrealClass; while ((superClass = superClass.GetSuperClass()) != null && superClass.VTableOriginalFunctions == null) { } Debug.Assert(superClass != null && superClass.VTableOriginalFunctions != null && superClass.VTableOriginalFunctions.ContainsKey(redirect.VTableIndex)); originalFunctionAddress = superClass.VTableOriginalFunctions[redirect.VTableIndex].FuncAddress; } unrealClass.VTableOriginalFunctions.Add(redirect.VTableIndex, new UClass.VTableOriginalFunc(originalFunctionAddress)); } } } }
/// <summary> /// Create a unique name by combining a base name and an arbitrary number string. /// The object name returned is guaranteed not to exist. /// </summary> /// <param name="outer">the outer for the object that needs to be named</param> /// <param name="unrealClass">the class for the object</param> /// <param name="baseName">optional base name to use when generating the unique object name; if not specified, the class's name is used</param> /// <returns>name is the form BaseName_##, where ## is the number of objects of this /// type that have been created since the last time the class was garbage collected.</returns> public static FName MakeUniqueObjectName(ObjectOuter outer, UClass unrealClass, FName baseName = default(FName)) { FName result; Native_UObjectGlobals.MakeUniqueObjectName(outer.Address, unrealClass == null ? IntPtr.Zero : unrealClass.Address, ref baseName, out result); return(result); }
/// <summary> /// Load a class object. /// </summary> public static UClass LoadClass(UClass baseClass, ObjectOuter outer, string name, string filename = null, ELoadFlags loadFlags = ELoadFlags.None) { using (FStringUnsafe nameUnsafe = new FStringUnsafe(name)) using (FStringUnsafe filenameUnsafe = new FStringUnsafe(filename)) { return(GCHelper.Find <UClass>(Native_UObjectGlobals.StaticLoadClass( baseClass.Address, outer.Address, ref nameUnsafe.Array, ref filenameUnsafe.Array, loadFlags, IntPtr.Zero))); } }
public void SetClass(UClass unrealClass) { if (unrealClass != null && !unrealClass.IsA <T>()) { throw new Exception("TAssetClass - tried to set class with the wrong target class type. Expected:" + typeof(T) + " Actual:" + UClass.GetType(unrealClass.Address)); } softObject.Value = unrealClass; }
/// <summary> /// Returns true if this objects class implements the given IInterface derived type /// (call this on UObject instances; if you are working with a UClass call ImplementsInterface() instead).<para/> /// This is the equivalent of UKismetSystemLibrary::DoesImplementInterface(). /// This is also the same as obj.GetClass().ImplementsInterface(). /// </summary> /// <typeparam name="T">The IInterface derived type</typeparam> /// <returns>True if this objects class implements the given IInterface derived type</returns> public bool DoesImplementInterface <T>() where T : IInterface { IntPtr interfaceClass = UClass.GetInterfaceClassAddress <T>(); if (interfaceClass != IntPtr.Zero && Native_UClass.GetClassFlags(interfaceClass).HasFlag(EClassFlags.Interface)) { return(Native_UClass.ImplementsInterface(Native_UObjectBase.GetClass(Address), interfaceClass)); } return(false); }
private static object DynamicInvokeInternal(UClass unrealClass, UObject obj, string functionName, params object[] parameters) { UFunction function = obj.GetClass().FindFunctionByName(new FName(functionName)); if (function == null) { return(null); } return(function.DynamicInvoke(obj, parameters)); }
/// <summary> /// Invokes a UFunction of the given name using the CDO (class default object) /// </summary> public static object DynamicInvokeStatic <T>(string functionName, object[] parameters) where T : UObject { UClass unrealClass = UClass.GetClass <T>(); if (unrealClass != null) { return(DynamicInvokeStatic(unrealClass, functionName, parameters)); } return(null); }
public bool IsA(Type type) { UClass unrealClass = UClass.GetClass(type); if (unrealClass == null) { return(false); } return(Native_UObjectBaseUtility.IsA(Address, unrealClass.Address)); }
/// <summary> /// Traverses the outer chain searching for the next object of a certain type. (T must be derived from UObject) /// </summary> /// <typeparam name="T">class to search for</typeparam> /// <returns>a pointer to the first object in this object's Outer chain which is of the correct type.</returns> public UObject GetTypedOuter <T>() where T : UObject { UClass unrealClass = UClass.GetClass <T>(); if (unrealClass != null) { return(GetTypedOuter(unrealClass)); } return(null); }
/// <summary> /// Returns true if this objects class implements the given IInterface derived type /// (call this on UObject instances; if you are working with a UClass call ImplementsInterface() instead).<para/> /// This is the equivalent of UKismetSystemLibrary::DoesImplementInterface(). /// This is also the same as obj.GetClass().ImplementsInterface(). /// </summary> /// <param name="type">The IInterface derived type</param> /// <returns>True if this objects class implements the given IInterface derived type</returns> public bool DoesImplementInterface(Type type) { UClass interfaceClass = UClass.GetClass(type); if (interfaceClass != null && interfaceClass.ClassFlags.HasFlag(EClassFlags.Interface)) { return(Native_UClass.ImplementsInterface(Native_UObjectBase.GetClass(Address), interfaceClass.Address)); } return(false); }
/// <summary> /// Get default object of a class. /// </summary> public static T GetDefault <T>() where T : UObject { UClass unrealClass = UClass.GetClass <T>(); if (unrealClass != null) { return(unrealClass.GetDefaultObject() as T); } return(null); }