private static IntPtr GetStruct(string path, bool canBeNull = false) { IntPtr address = NativeReflection.FindObject(UScriptStruct, IntPtr.Zero, path, false); Debug.Assert(address != IntPtr.Zero || canBeNull); return(address); }
// Is there any benefit of writing a loader for UFunction here? Native types will be loaded in the module // is loaded and Blueprint function delegates would be loaded with the owning class. /// <summary> /// Gets the UFunction address for the given path (e.g. "/Script/Engine.Actor:SetOwner") /// </summary> /// <param name="path">The path of the UFunction</param> /// <returns>The address of the UFunction for the given path</returns> public static IntPtr GetFunctionAddress(string path) { IntPtr address = NativeReflection.FindObject(Classes.UFunction, IntPtr.Zero, path, false); if (address == IntPtr.Zero) { // To resolve this a call to FCoreRedirects.GetRedirectedName would be required with a UProperty type? // - Or this just isn't possible to resolve. // TODO: Attempt trying to create a redirected delegate in C++ and see what happens and how to resolve it. } return(address); }
/// <summary> /// Gets the UClass address for the given path (e.g. "/Script/Engine.Actor") /// </summary> /// <param name="path">The path of the object/class</param> /// <returns>The UClass address</returns> public static IntPtr GetClassAddress(string path) { IntPtr address = NativeReflection.FindObject(Classes.UClass, IntPtr.Zero, path, false); if (address == IntPtr.Zero) { FName newPath = FLinkerLoad.FindNewNameForClass(new FName(path), false); if (newPath != FName.None) { address = NativeReflection.FindObject(Classes.UClass, IntPtr.Zero, newPath.ToString(), false); } } return(address); }
internal static IntPtr GetEnum(Type type) { if (IsManagedUnrealType(type)) { } else { UMetaPathAttribute pathAttribute = type.GetCustomAttribute <UMetaPathAttribute>(); if (pathAttribute != null) { return(NativeReflection.FindObject(Native_UEnum.StaticClass(), IntPtr.Zero, pathAttribute.Path, true)); } } return(IntPtr.Zero); }
/// <summary> /// Gets the UProperty address for the given path (e.g. "/Script/Engine.Actor:bReplicates") /// </summary> /// <param name="path">The path of the UProperty</param> /// <returns>The address of the UProperty for the given path</returns> public static IntPtr GetPropertyAddress(string path) { return(NativeReflection.FindObject(Classes.UProperty, IntPtr.Zero, path, false)); }
public static ManagedUnrealClass CreateClass(Type type) { ManagedUnrealClass existingClass = FindClass(type); if (existingClass != null) { if (!FBuild.WithHotReload) { // TODO: Add support for hotreloading C# classes when WITH_HOT_RELOAD isn't available // - WITH_HOT_RELOAD will be false on shipping, monolithic and server builds // - Would need to make a copy of FHotReloadClassReinstancer (or just use it directly if // it doesn't depend on WITH_HOT_RELOAD and gets compiled into builds) // - Would likely break blueprint classes which depend on any C# classes reinstanced in this way return(existingClass); } existingClass.Clear(); HotReloadClassCount++; } if (!type.IsSubclassOf(typeof(UObject))) { return(null); } USharpPathAttribute pathAttribute = type.GetCustomAttribute <USharpPathAttribute>(); if (pathAttribute == null || string.IsNullOrEmpty(pathAttribute.Path)) { return(null); } IntPtr parentClass = GetStaticClass(type.BaseType); if (parentClass == IntPtr.Zero) { return(null); } string root, directory, moduleName, className, memberName; FPackageName.GetPathInfo(pathAttribute.Path, out root, out directory, out moduleName, out className, out memberName); string packageName = "/" + root + "/" + directory; if (string.IsNullOrEmpty(moduleName) || string.IsNullOrEmpty(className)) { return(null); } IntPtr package = NativeReflection.FindObject(Native_UPackage.StaticClass(), IntPtr.Zero, packageName, true); if (package == IntPtr.Zero) { package = NativeReflection.CreatePackage(IntPtr.Zero, packageName); Native_UPackage.SetPackageFlags(package, EPackageFlags.CompiledIn); // TODO: Find how to create a proper guid for a package (UHT CodeGenerator.cpp seems to use a crc of generated code) using (System.Security.Cryptography.SHA256 sha256 = System.Security.Cryptography.SHA256.Create()) { byte[] hash = sha256.ComputeHash(Encoding.ASCII.GetBytes(packageName)); // Truncate the hash byte[] buffer = new byte[16]; Buffer.BlockCopy(hash, 0, buffer, 0, buffer.Length); Native_UPackage.SetGuid(package, new Guid(buffer)); } } ManagedUnrealClass managedUnrealClass = null; if (existingClass != null) { managedUnrealClass = existingClass; } else { managedUnrealClass = new ManagedUnrealClass(type, packageName, className, parentClass); } managedUnrealClass.StaticClass = USharpClass.CreateClassPtr( managedUnrealClass.PackageName, managedUnrealClass.ClassName, (uint)Native_UStruct.GetPropertiesSize(managedUnrealClass.ParentClass), EClassFlags.None, EClassCastFlags.None, managedUnrealClass.ConfigName, managedUnrealClass.ParentClass, managedUnrealClass.WithinClass, managedUnrealClass.ClassConstructor, managedUnrealClass.ClassVTableHelperCtorCaller, managedUnrealClass.ClassAddReferencedObjects); Native_UObjectBase.UObjectForceRegistration(managedUnrealClass.StaticClass); if (existingClass == null) { Classes.Add(type, managedUnrealClass); ClassesByAddress.Add(managedUnrealClass.StaticClass, managedUnrealClass); } managedUnrealClass.Initialize(); return(managedUnrealClass); }