Example #1
0
        private static bool StructHasGetTypeHash(IntPtr unrealStruct)
        {
            if (Native_UObjectBaseUtility.IsNative(unrealStruct))
            {
                IntPtr cppStructOps = Native_UScriptStruct.GetCppStructOps(unrealStruct);
                return(cppStructOps != IntPtr.Zero && Native_ICppStructOps.HasGetTypeHash(cppStructOps));
            }
            else
            {
                // if every member can be hashed (or is a UBoolProperty, which is specially
                // handled by UScriptStruct::GetStructTypeHash) then we can hash the struct:

                var fieldIterator = new NativeReflection.NativeFieldIterator(Classes.UProperty, unrealStruct);
                foreach (IntPtr property in fieldIterator)
                {
                    if (Native_UObjectBaseUtility.IsA(property, Classes.UBoolProperty))
                    {
                        continue;
                    }
                    else
                    {
                        if (!PropertyHasGetTypeHash(property))
                        {
                            return(false);
                        }
                    }
                }
                return(true);
            }
        }
Example #2
0
        /// <summary>
        /// Compare this structure
        /// </summary>
        /// <returns>true if the copy was handled, otherwise it will fall back to UStructProperty::Identical</returns>
        public bool Identical(IntPtr a, IntPtr b, uint portFlags, out bool outResult)
        {
            csbool outResultTemp;
            bool   result = Native_ICppStructOps.Identical(Address, a, b, portFlags, out outResultTemp);

            outResult = outResultTemp;
            return(result);
        }
Example #3
0
        /// <summary>
        /// Returns the size of the struct using ICppStructOps, otherwise falls back to GetStructureSize().
        /// </summary>
        /// <returns></returns>
        public int GetStructSize()
        {
            UScriptStruct scriptStruct = this as UScriptStruct;

            if (scriptStruct != null)
            {
                IntPtr cppStructOps = Native_UScriptStruct.GetCppStructOps(scriptStruct.Address);
                if (cppStructOps != IntPtr.Zero)
                {
                    return(Native_ICppStructOps.GetSize(cppStructOps));
                }
            }
            return(GetStructureSize());
        }
Example #4
0
        /// <summary>
        /// Checks if the given UScriptStruct address is POD and has a zero constructor (initializes to zero).
        ///
        /// NOTE: A struct could be PlainOldData but unsafe to zero initialize due to having a non-zero constructor / EForceInit constructor.
        /// </summary>
        internal static bool IsPODZeroInit(IntPtr unrealStruct)
        {
            if (unrealStruct != IntPtr.Zero && Native_UObjectBaseUtility.IsA(unrealStruct, Classes.UScriptStruct))
            {
                EStructFlags structFlags = Native_UScriptStruct.Get_StructFlags(unrealStruct);

                IntPtr cppStructOps = Native_UScriptStruct.GetCppStructOps(unrealStruct);
                if (cppStructOps != IntPtr.Zero)
                {
                    bool isPlainOldData     = Native_ICppStructOps.IsPlainOldData(cppStructOps);
                    bool hasZeroConstructor = Native_ICppStructOps.HasZeroConstructor(cppStructOps);
                    bool hasNoopConstructor = Native_ICppStructOps.HasNoopConstructor(cppStructOps);

                    if (!hasZeroConstructor && structFlags.HasFlag(EStructFlags.ZeroConstructor))
                    {
                        // This struct flag could have been set in the zero constructor check in UScriptStruct::PrepareCppStructOps
                        hasZeroConstructor = true;
                    }

                    if (isPlainOldData && hasZeroConstructor && !hasNoopConstructor)
                    {
                        return(true);
                    }

                    if (isPlainOldData && !hasZeroConstructor)
                    {
                        if (hasNoopConstructor)
                        {
                            // The struct has a no-op constructor and takes EForceInit to init
                            return(false);
                        }

                        // This is a copy of a check made in UScriptStruct::PrepareCppStructOps to check if the struct constructs to zero
                        // if (CppStructOps->IsPlainOldData() && !CppStructOps->HasZeroConstructor()) { ... }

                        int    size   = Native_ICppStructOps.GetSize(cppStructOps);
                        IntPtr buffer = FMemory.Malloc(size);
                        FMemory.Memzero(buffer, size);
                        Native_ICppStructOps.Construct(cppStructOps, buffer);
                        Native_ICppStructOps.Construct(cppStructOps, buffer);// slightly more like to catch "internal counters" if we do this twice

                        bool isZeroConstruct = true;
                        unsafe
                        {
                            byte *bufferPtr = (byte *)buffer;
                            for (int i = 0; i < size; i++)
                            {
                                if (bufferPtr[i] != 0)
                                {
                                    isZeroConstruct = false;
                                    break;
                                }
                            }
                        }

                        FMemory.Free(buffer);

                        if (isZeroConstruct)
                        {
                            // "Native struct %s has DISCOVERED zero construction. Size = %d"
                            System.Diagnostics.Debugger.Break();
                            return(true);
                        }
                    }
                    return(false);
                }
                else
                {
                    // Only treat it as blittable if it is POD and has a zero constructor
                    return(structFlags.HasFlag(EStructFlags.IsPlainOldData | EStructFlags.ZeroConstructor));
                }
            }
            return(false);
        }
Example #5
0
 /// <summary>
 /// Call the C++ destructor
 /// </summary>
 public void Destruct(IntPtr dest)
 {
     Native_ICppStructOps.Destruct(Address, dest);
 }
Example #6
0
 /// <summary>
 /// Calls GetTypeHash if enabled
 /// </summary>
 public uint GetTypeHash(IntPtr src)
 {
     return(Native_ICppStructOps.GetTypeHash(Address, src));
 }
Example #7
0
 /// <summary>
 /// Copy this structure
 /// </summary>
 /// <returns>true if the copy was handled, otherwise it will fall back to CopySingleValue</returns>
 public bool Copy(IntPtr dest, IntPtr src, int arrayDim)
 {
     return(Native_ICppStructOps.Copy(Address, dest, src, arrayDim));
 }