-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
i233 Deep Migration Warning #237
Changes from 1 commit
d5fba47
c577163
01a1d34
f055a85
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
using Anvil.CSharp.Logging; | ||
using System; | ||
using System.Reflection; | ||
using Unity.Burst; | ||
using Unity.Collections; | ||
using Unity.Collections.LowLevel.Unsafe; | ||
|
@@ -36,14 +37,14 @@ private static void Init() | |
SharedTypeOffsetInfo.REF.Data = s_TypeOffsetsLookup; | ||
UpdateSharedStatics(); | ||
} | ||
|
||
private static void CurrentDomain_OnDomainUnload(object sender, EventArgs e) | ||
{ | ||
SharedTypeOffsetInfo.REF.Data = default; | ||
SharedEntityOffsetInfo.REF.Data = default; | ||
SharedBlobAssetRefInfo.REF.Data = default; | ||
SharedWeakAssetRefInfo.REF.Data = default; | ||
|
||
if (s_TypeOffsetsLookup.IsCreated) | ||
{ | ||
s_TypeOffsetsLookup.Dispose(); | ||
|
@@ -61,7 +62,7 @@ private static void CurrentDomain_OnDomainUnload(object sender, EventArgs e) | |
s_WeakAssetRefOffsetList.Dispose(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Registers the Type that may contain Entity references so that it can be used with | ||
/// <see cref="PatchEntityReferences{T}"/> to remap Entity references. | ||
|
@@ -72,7 +73,7 @@ public static void RegisterTypeForEntityPatching<T>() | |
{ | ||
RegisterTypeForEntityPatching(typeof(T)); | ||
} | ||
|
||
/// <inheritdoc cref="RegisterTypeForEntityPatching{T}"/> | ||
/// <exception cref="InvalidOperationException"> | ||
/// Occurs when the Type is not a Value type. | ||
|
@@ -84,6 +85,8 @@ public static void RegisterTypeForEntityPatching(Type type) | |
throw new InvalidOperationException($"Type {type.GetReadableName()} must be a value type in order to register for Entity Patching."); | ||
} | ||
|
||
ScanForCollections(string.Empty, type); | ||
|
||
long typeHash = BurstRuntime.GetHashCode64(type); | ||
//We've already added this type, no need to do so again | ||
if (s_TypeOffsetsLookup.ContainsKey(typeHash)) | ||
|
@@ -113,23 +116,43 @@ public static void RegisterTypeForEntityPatching(Type type) | |
new TypeOffsetInfo( | ||
entityOffsetStartIndex, | ||
s_EntityOffsetList.Length)); | ||
|
||
//The size of the underlying data could have changed such that we re-allocated the memory, so we'll update | ||
//our shared statics | ||
UpdateSharedStatics(); | ||
} | ||
|
||
private static void ScanForCollections(string parentPathString, Type type) | ||
{ | ||
//One of these fields might be a collection or contain a collection, best way to tell is to scan it and see if it has a pointer | ||
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); | ||
foreach (FieldInfo field in fields) | ||
{ | ||
Type fieldType = field.FieldType; | ||
if (fieldType.IsPrimitive) | ||
{ | ||
continue; | ||
} | ||
if (fieldType.IsPointer) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know where you want to put this for future reference but we discussed how there may be cases where a pointer is being stored that we do not want to dive into an migrate. Maybe that memory address has already been migrated or something. We want to figure out how to handle these situations. Maybe require developers to annotate unsafe fields with a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool, logged in #233 |
||
{ | ||
Debug.LogWarning($"{parentPathString}/{type.GetReadableName()} has a field named {field.Name} which is a pointer. This is probably a collection. As a result, we cannot automatically patch any entity references inside this collection. It would need to be handled manually until automatic work can handle in from https://github.com/decline-cookies/anvil-unity-dots/issues/233."); | ||
mbaker3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
continue; | ||
} | ||
ScanForCollections($"{parentPathString}/{type.GetReadableName()}", fieldType); | ||
} | ||
} | ||
|
||
private static unsafe void UpdateSharedStatics() | ||
{ | ||
SharedEntityOffsetInfo.REF.Data = new IntPtr(s_EntityOffsetList.GetUnsafePtr()); | ||
SharedBlobAssetRefInfo.REF.Data = new IntPtr(s_BlobAssetRefOffsetList.GetUnsafePtr()); | ||
SharedWeakAssetRefInfo.REF.Data = new IntPtr(s_WeakAssetRefOffsetList.GetUnsafePtr()); | ||
} | ||
|
||
//************************************************************************************************************* | ||
// BURST RUNTIME CALLS | ||
//************************************************************************************************************* | ||
|
||
/// <summary> | ||
/// Checks if the Entity was remapped by Unity during a world transfer. | ||
/// </summary> | ||
|
@@ -194,7 +217,7 @@ public static unsafe void PatchEntityReferences<T>(this ref T instance, ref Nati | |
*entityPtr = EntityRemapUtility.RemapEntity(ref remapArray, *entityPtr); | ||
} | ||
} | ||
|
||
//************************************************************************************************************* | ||
// HELPER TYPES | ||
//************************************************************************************************************* | ||
|
@@ -215,35 +238,33 @@ public TypeOffsetInfo(int entityOffsetStartIndex, int entityOffsetEndIndex) | |
EntityOffsetEndIndex = entityOffsetEndIndex; | ||
} | ||
} | ||
|
||
//************************************************************************************************************* | ||
// SHARED STATIC REQUIREMENTS | ||
//************************************************************************************************************* | ||
|
||
// ReSharper disable once ConvertToStaticClass | ||
// ReSharper disable once ClassNeverInstantiated.Local | ||
private sealed class MigrationUtilContext | ||
{ | ||
private MigrationUtilContext() | ||
{ | ||
} | ||
private MigrationUtilContext() { } | ||
} | ||
|
||
private sealed class SharedTypeOffsetInfo | ||
{ | ||
public static readonly SharedStatic<UnsafeParallelHashMap<long, TypeOffsetInfo>> REF = SharedStatic<UnsafeParallelHashMap<long, TypeOffsetInfo>>.GetOrCreate<MigrationUtilContext, SharedTypeOffsetInfo>(); | ||
} | ||
|
||
private sealed class SharedEntityOffsetInfo | ||
{ | ||
public static readonly SharedStatic<IntPtr> REF = SharedStatic<IntPtr>.GetOrCreate<MigrationUtilContext, SharedEntityOffsetInfo>(); | ||
} | ||
|
||
private sealed class SharedBlobAssetRefInfo | ||
{ | ||
public static readonly SharedStatic<IntPtr> REF = SharedStatic<IntPtr>.GetOrCreate<MigrationUtilContext, SharedBlobAssetRefInfo>(); | ||
} | ||
|
||
private sealed class SharedWeakAssetRefInfo | ||
{ | ||
public static readonly SharedStatic<IntPtr> REF = SharedStatic<IntPtr>.GetOrCreate<MigrationUtilContext, SharedWeakAssetRefInfo>(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a safety only operation? I don't think this would come up uniquely in release
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes for now, but I've noted that it won't be in the full implementation of #233 because we need to store the type offset information.