/// <summary> /// returns our Guid /// </summary> /// <returns></returns> public Guid GetGuid() { Guid result; Native_UPackage.GetGuid(Address, out result); return(result); }
private static void SetAllMetaData(IntPtr obj, ManagedUnrealReflectionBase field, UMeta.Target target) { if (!FBuild.WithEditor || !metaDataEnabled || field == null || string.IsNullOrEmpty(field.Path)) { return; } IntPtr outermost = Native_UObjectBaseUtility.GetOutermost(obj); IntPtr metadata = outermost == IntPtr.Zero ? IntPtr.Zero : Native_UPackage.GetMetaData(outermost); if (metadata == IntPtr.Zero) { return; } Dictionary <FName, string> values = null; if (!metaDataMap.TryGetValue(field.Path.ToLower(), out values)) { values = new Dictionary <FName, string>(); } switch (target) { // Class / interface case UMeta.Target.Class: case UMeta.Target.Interface: // See GetMetadataKeyword (Engine\Source\Programs\UnrealHeaderTool\Private\BaseParser.cpp) // "NotBlueprintable" removes "NotBlueprintable" and adds "IsBlueprintBase=false" // "Blueprintable" and adds "IsBlueprintBase=true" // "BlueprintInternalUseOnly" adds "BlueprintType" if (!values.ContainsKey(UMeta.GetKeyName(MDClass.IsBlueprintBase))) { if (values.ContainsKey(UMeta.GetKeyName(MDClass.Blueprintable))) { values[UMeta.GetKeyName(MDClass.IsBlueprintBase)] = "true"; } else if (values.ContainsKey(UMeta.GetKeyName(MDClass.NotBlueprintable))) { values[UMeta.GetKeyName(MDClass.IsBlueprintBase)] = "false"; } } MetaDataMergeClassCategories(metadata, obj, values); break; } SetMetaDataBlueprintability(values, target, field as ManagedUnrealTypeInfo); using (TArrayUnsafe <FName> keysUnsafe = new TArrayUnsafe <FName>()) using (TArrayUnsafe <string> valuesUnsafe = new TArrayUnsafe <string>()) { keysUnsafe.AddRange(values.Keys.ToArray()); valuesUnsafe.AddRange(values.Values.ToArray()); Native_UMetaData.SetObjectValues(metadata, obj, keysUnsafe.Address, valuesUnsafe.Address); } }
private IntPtr CreateProperty(IntPtr outer, PropertyInfo propertyInfo) { // Note that HeaderParser.cpp and UObjectGlobals.cpp use "new" instead of NewObject for creating properties // KismetCompilerMisc.cpp uses NewObject // The "new" initialization sets the offset and adds the property to the owner which in the case of UStruct // does the following: // void UStruct::AddCppProperty(UProperty* Property) { Property->Next = Children; Children = Property; } USharpPathAttribute pathAttribute = propertyInfo.GetCustomAttribute <USharpPathAttribute>(); if (pathAttribute == null) { return(IntPtr.Zero); } string root, directory, moduleName, typeName, propertyName; FPackageName.GetPathInfo(pathAttribute.Path, out root, out directory, out moduleName, out typeName, out propertyName); if (string.IsNullOrEmpty(propertyName)) { return(IntPtr.Zero); } IntPtr property = CreateProperty(outer, propertyInfo.PropertyType, propertyName, pathAttribute.PropertyType, pathAttribute.InnerPropertyType1, pathAttribute.InnerPropertyType2); if (property == IntPtr.Zero) { return(IntPtr.Zero); } if (FBuild.WithMetaData) { IntPtr outermost = Native_UObjectBaseUtility.GetOutermost(property); IntPtr metadata = outermost == IntPtr.Zero ? IntPtr.Zero : Native_UPackage.GetMetaData(outermost); if (metadata != IntPtr.Zero) { string categoryName = null; //propertyInfo.GetCustomAttribute if (string.IsNullOrEmpty(categoryName)) { categoryName = "Default"; } SetMetaData(metadata, property, "Category", categoryName); } } return(property); }
/// <summary> /// Marks this package as being fully loaded. /// </summary> public void MarkAsFullyLoaded() { Native_UPackage.MarkAsFullyLoaded(Address); }
/// <summary> /// Wait for any SAVE_Async file writes to complete /// </summary> public static void WaitForAsyncFileWrites() { Native_UPackage.WaitForAsyncFileWrites(); }
/// <summary> /// Gets the package flags. /// </summary> /// <returns>The package flags.</returns> public EPackageFlags GetPackageFlags() { return(Native_UPackage.GetPackageFlags(Address)); }
/// <summary> /// Used to safely check whether all of the passed in flags are set. /// </summary> /// <param name="flagsToCheck">Package flags to check for</param> /// <returns>true if all of the passed in flags are set (including no flags passed in), false otherwise</returns> public bool HasAllPackagesFlags(EPackageFlags flagsToCheck) { return(Native_UPackage.HasAllPackagesFlags(Address, flagsToCheck)); }
/// <summary> /// Set the specified flags to false. Does not affect any other flags. /// </summary> /// <param name="newFlags">Package flags to disable</param> public void ClearPackageFlags(EPackageFlags newFlags) { Native_UPackage.ClearPackageFlags(Address, newFlags); }
/// <summary> /// Set the specified flags to true. Does not affect any other flags. /// </summary> /// <param name="newFlags">Package flags to enable</param> public void SetPackageFlags(EPackageFlags newFlags) { Native_UPackage.SetPackageFlags(Address, newFlags); }
/// <summary> /// Fully loads this package. Safe to call multiple times and won't clobber already loaded assets. /// </summary> public void FullyLoad() { Native_UPackage.FullyLoad(Address); }
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); }