示例#1
0
        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);
        }
示例#2
0
        private static void LoadInternal(Assembly thisAssembly, Assembly assembly)
        {
            if (processedAssemblies.Contains(assembly))
            {
                return;
            }
            processedAssemblies.Add(assembly);

            bool referencesThisAssembly = false;

            if (assembly == thisAssembly)
            {
                referencesThisAssembly = true;
            }
            else
            {
                foreach (AssemblyName assemblyName in assembly.GetReferencedAssemblies())
                {
                    if (assemblyName.FullName == thisAssembly.FullName)
                    {
                        referencesThisAssembly = true;
                        break;
                    }
                }
            }
            if (!referencesThisAssembly)
            {
                return;
            }

            List <Type> types = new List <Type>();
            Dictionary <Type, UMetaPathAttribute>  nativeTypes  = new Dictionary <Type, UMetaPathAttribute>();
            Dictionary <Type, USharpPathAttribute> managedTypes = new Dictionary <Type, USharpPathAttribute>();
            Type assemblyModuleInfoType = null;

            foreach (Type type in assembly.GetTypes())
            {
                UUnrealTypePathAttribute pathAttribute = type.GetCustomAttribute <UUnrealTypePathAttribute>(false);
                if (pathAttribute != null && !string.IsNullOrEmpty(pathAttribute.Path))
                {
                    USharpPathAttribute sharpPathAttribute = pathAttribute as USharpPathAttribute;
                    if (sharpPathAttribute != null)
                    {
                        AllByPath[pathAttribute.Path]     = type;
                        ManagedByPath[pathAttribute.Path] = type;

                        All[type]     = sharpPathAttribute;
                        Managed[type] = sharpPathAttribute;

                        types.Add(type);
                        managedTypes[type] = sharpPathAttribute;
                    }
                    else
                    {
                        UMetaPathAttribute metaPathAttribute = pathAttribute as UMetaPathAttribute;
                        if (metaPathAttribute != null)
                        {
                            AllByPath[pathAttribute.Path]    = type;
                            NativeByPath[pathAttribute.Path] = type;

                            All[type]    = metaPathAttribute;
                            Native[type] = metaPathAttribute;

                            types.Add(type);
                            nativeTypes[type] = metaPathAttribute;
                        }
                    }
                }

                if (typeof(ISerializedManagedUnrealModuleInfo).IsAssignableFrom(type) &&
                    type != typeof(ISerializedManagedUnrealModuleInfo))
                {
                    assemblyModuleInfoType = type;
                }
            }

            if (types.Count > 0)
            {
                Assemblies[assembly]             = types;
                AssembliesManagedTypes[assembly] = managedTypes;
                AssembliesNativeTypes[assembly]  = nativeTypes;
                if (assemblyModuleInfoType != null)
                {
                    AssemblySerializedModuleInfo[assembly] = assemblyModuleInfoType;
                }
            }
        }
示例#3
0
        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);
        }