Skip to content

Commit ed8c0c9

Browse files
committed
Version 0.13.3 Release [Bugfix]
Bugfix release
1 parent e8809e9 commit ed8c0c9

19 files changed

+646
-156
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ You can find changelogs for the individual modules in the [official Latios
1010
Framework Documentation
1111
repository](https://github.com/Dreaming381/Latios-Framework-Documentation).
1212

13+
## [0.13.3] – 2025-8-16
14+
15+
Officially supports Entities [1.3.14]
16+
17+
### Changed
18+
19+
- Updated Core to v0.13.3
20+
- Updated Psyshock to v0.13.3
21+
1322
## [0.13.2] – 2025-8-3
1423

1524
Officially supports Entities [1.3.14]

Core/Authoring/BakerInterfaceSupport.cs

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,44 @@ namespace Latios.Authoring
99
{
1010
public static class BakerInterfaceSupport
1111
{
12+
/// <summary>
13+
/// Retrieves all components of the authoring type. If the passed in authoring is the primary, returns true.
14+
/// Use this method to determine if you should bake an aggregate of multiple authoring components to combine
15+
/// them into a DynamicBuffer or something.
16+
/// </summary>
17+
/// <typeparam name="T">The type of Component that is being baked</typeparam>
18+
/// <param name="authoring">The authoring component passed into the baker</param>
19+
/// <param name="allAuthorings">An output list of all components of the authoring's type, including derived components.
20+
/// This list is reused by multiple bakers and its contents are only valid within the lifecycle of the current Bake() call.</param>
21+
/// <returns>True if this particular authoring component is the one that should be in control of baking all the components</returns>
22+
public static bool ShouldBakeAll<T>(this IBaker baker, T authoring, out List<T> allAuthorings) where T : Component
23+
{
24+
allAuthorings = CachedList<T>.list;
25+
baker.GetComponents(allAuthorings);
26+
if (allAuthorings.Count == 0)
27+
return false;
28+
return authoring == allAuthorings[0];
29+
}
30+
31+
/// <summary>
32+
/// Retrieves all components of the authoring type. If the passed in authoring is the primary, returns true.
33+
/// Use this method to determine if you should bake an aggregate of multiple authoring components to combine
34+
/// them into a DynamicBuffer or something.
35+
/// </summary>
36+
/// <typeparam name="T">The type of component casted to the interface that is being baked</typeparam>
37+
/// <param name="authoring">The authoring component passed into the baker</param>
38+
/// <param name="allAuthorings">An output list of all components of the authoring's type, including derived components.
39+
/// This list is reused by multiple bakers and its contents are only valid within the lifecycle of the current Bake() call.</param>
40+
/// <returns>True if this particular authoring component is the one that should be in control of baking all the components</returns>
41+
public static bool ShouldBakeAllInterface<T>(this IBaker baker, T authoring, out List<T> allAuthorings)
42+
{
43+
allAuthorings = CachedList<T>.list;
44+
baker.GetComponents(allAuthorings);
45+
if (allAuthorings.Count == 0)
46+
return false;
47+
return authoring.Equals(allAuthorings[0]);
48+
}
49+
1250
/// <summary>
1351
/// Retrieves the component of Type T in the GameObject
1452
/// </summary>
@@ -123,7 +161,7 @@ public static T GetComponentInParent<T>(this IBaker baker, Component component)
123161
public static T GetComponentInParent<T>(this IBaker baker, GameObject gameObject)
124162
{
125163
foreach (var type in InterfaceState<T>.implementingComponents)
126-
type.GetComponents(baker, gameObject);
164+
type.GetComponentInParent(baker, gameObject);
127165
return gameObject.GetComponentInParent<T>(true);
128166
}
129167

@@ -162,7 +200,7 @@ public static void GetComponentsInParent<T>(this IBaker baker, Component compone
162200
public static void GetComponentsInParent<T>(this IBaker baker, GameObject gameObject, List<T> components)
163201
{
164202
foreach (var type in InterfaceState<T>.implementingComponents)
165-
type.GetComponents(baker, gameObject);
203+
type.GetComponentsInParent(baker, gameObject);
166204
gameObject.GetComponentsInParent(true, components);
167205
}
168206

@@ -201,7 +239,7 @@ public static T GetComponentInChildren<T>(this IBaker baker, Component component
201239
public static T GetComponentInChildren<T>(this IBaker baker, GameObject gameObject)
202240
{
203241
foreach (var type in InterfaceState<T>.implementingComponents)
204-
type.GetComponents(baker, gameObject);
242+
type.GetComponentInChildren(baker, gameObject);
205243
return gameObject.GetComponentInChildren<T>(true);
206244
}
207245

@@ -239,7 +277,7 @@ public static void GetComponentsInChildren<T>(this IBaker baker, Component refCo
239277
public static void GetComponentsInChildren<T>(this IBaker baker, GameObject gameObject, List<T> components)
240278
{
241279
foreach (var type in InterfaceState<T>.implementingComponents)
242-
type.GetComponents(baker, gameObject);
280+
type.GetComponentsInChildren(baker, gameObject);
243281
gameObject.GetComponentsInChildren(true, components);
244282
}
245283

@@ -315,6 +353,11 @@ public override void GetComponentsInParent(IBaker baker, GameObject gameObject)
315353
}
316354
}
317355
}
356+
357+
static class CachedList<T>
358+
{
359+
public static List<T> list = new List<T>();
360+
}
318361
}
319362
}
320363

Core/GameplayToolkit/ComponentBroker.cs

Lines changed: 196 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -602,48 +602,181 @@ public DynamicBuffer<T> GetBufferIgnoreParallelSafety<T>(Entity entity) where T
602602
}
603603
}
604604

605-
// Todo: These are disabled as they are not atomic
606-
//public EnabledRefRO<T> GetEnabledROIgnoreParallelSafety<T>(Entity entity) where T : unmanaged, IEnableableComponent
607-
//{
608-
// var typeIndex = TypeManager.GetTypeIndex<T>().Index;
609-
// CheckTypeIndexIsInComponentList(typeIndex);
610-
// fixed (DynamicComponentTypeHandle* c0Ptr = &c0)
611-
// {
612-
// ref var handle = ref c0Ptr[handleIndices[typeIndex].index];
613-
// if (entity == currentEntity)
614-
// {
615-
// var mask = currentChunk.GetEnabledMask(ref handle);
616-
// return mask.GetOptionalEnabledRefRO<T>(currentIndexInChunk);
617-
// }
618-
// else
619-
// {
620-
// var info = esil[entity];
621-
// var mask = info.Chunk.GetEnabledMask(ref handle);
622-
// return mask.GetOptionalEnabledRefRO<T>(info.IndexInChunk);
623-
// }
624-
// }
625-
//}
626-
//
627-
//public EnabledRefRW<T> GetEnabledRWIgnoreParallelSafety<T>(Entity entity) where T : unmanaged, IEnableableComponent
628-
//{
629-
// var typeIndex = TypeManager.GetTypeIndex<T>().Index;
630-
// CheckTypeIndexIsInComponentList(typeIndex);
631-
// fixed (DynamicComponentTypeHandle* c0Ptr = &c0)
632-
// {
633-
// ref var handle = ref c0Ptr[handleIndices[typeIndex].index];
634-
// if (entity == currentEntity)
635-
// {
636-
// var mask = currentChunk.GetEnabledMask(ref handle);
637-
// return mask.GetOptionalEnabledRefRW<T>(currentIndexInChunk);
638-
// }
639-
// else
640-
// {
641-
// var info = esil[entity];
642-
// var mask = info.Chunk.GetEnabledMask(ref handle);
643-
// return mask.GetOptionalEnabledRefRW<T>(info.IndexInChunk);
644-
// }
645-
// }
646-
//}
605+
/// <summary>
606+
/// Gets the readonly pointer to either the IComponentData or ISharedComponentData
607+
/// </summary>
608+
/// <param name="entity">The entity to get the component from</param>
609+
/// <param name="typeIndex">The type of component to get</param>
610+
/// <returns>A pointer to the component, or null if the component is not present</returns>
611+
public void* GetUnsafeComponentPtrRO(Entity entity, TypeIndex typeIndex)
612+
{
613+
CheckTypeIndexIsInComponentList(typeIndex);
614+
CheckTypeNotBuffer(typeIndex);
615+
616+
if (typeIndex.IsSharedComponentType)
617+
{
618+
fixed (DynamicSharedComponentTypeHandle* s0Ptr = &s0)
619+
{
620+
ref var handle = ref s0Ptr[handleIndices[typeIndex].index];
621+
void* ptr = default;
622+
if (entity == currentEntity)
623+
{
624+
ptr = currentChunk.GetDynamicSharedComponentDataAddress(ref handle);
625+
}
626+
else
627+
{
628+
var info = esil[entity];
629+
ptr = info.Chunk.GetDynamicSharedComponentDataAddress(ref handle);
630+
}
631+
return ptr;
632+
}
633+
}
634+
635+
var typeSize = TypeManager.GetTypeInfo(typeIndex).TypeSize;
636+
fixed (DynamicComponentTypeHandle* c0Ptr = &c0)
637+
{
638+
ref var handle = ref c0Ptr[handleIndices[typeIndex].index];
639+
if (entity == currentEntity)
640+
{
641+
var array = currentChunk.GetDynamicComponentDataArrayReinterpret<byte>(ref handle, typeSize);
642+
if (array.Length == 0)
643+
return null;
644+
return (byte*)array.GetUnsafeReadOnlyPtr() + typeSize * currentIndexInChunk;
645+
}
646+
else
647+
{
648+
CheckSafeAccessForForeignEntity(ref handle);
649+
var info = esil[entity];
650+
var array = info.Chunk.GetDynamicComponentDataArrayReinterpret<byte>(ref handle, typeSize);
651+
if (array.Length == 0)
652+
return null;
653+
return (byte*)array.GetUnsafeReadOnlyPtr() + typeSize * info.IndexInChunk;
654+
}
655+
}
656+
}
657+
658+
/// <summary>
659+
/// Gets the read-write pointer to either the IComponentData or ISharedComponentData
660+
/// </summary>
661+
/// <param name="entity">The entity to get the component from</param>
662+
/// <param name="typeIndex">The type of component to get</param>
663+
/// <returns>A pointer to the component, or null if the component is not present</returns>
664+
public void* GetUnsafeComponentPtrRW(Entity entity, TypeIndex typeIndex)
665+
{
666+
CheckTypeIndexIsInComponentList(typeIndex);
667+
CheckTypeNotBuffer(typeIndex);
668+
CheckTypeNotShared(typeIndex);
669+
670+
var typeSize = TypeManager.GetTypeInfo(typeIndex).TypeSize;
671+
fixed (DynamicComponentTypeHandle* c0Ptr = &c0)
672+
{
673+
ref var handle = ref c0Ptr[handleIndices[typeIndex].index];
674+
if (entity == currentEntity)
675+
{
676+
var array = currentChunk.GetDynamicComponentDataArrayReinterpret<byte>(ref handle, typeSize);
677+
if (array.Length == 0)
678+
return null;
679+
return (byte*)array.GetUnsafePtr() + typeSize * currentIndexInChunk;
680+
}
681+
else
682+
{
683+
CheckSafeAccessForForeignEntity(ref handle);
684+
var info = esil[entity];
685+
var array = info.Chunk.GetDynamicComponentDataArrayReinterpret<byte>(ref handle, typeSize);
686+
if (array.Length == 0)
687+
return null;
688+
return (byte*)array.GetUnsafePtr() + typeSize * info.IndexInChunk;
689+
}
690+
}
691+
}
692+
693+
/// <summary>
694+
/// Gets the readonly pointer to either the IComponentData or ISharedComponentData,
695+
/// ignoring parallel safety checks as if [NativeDisableParallelForRestriction] was used
696+
/// </summary>
697+
/// <param name="entity">The entity to get the component from</param>
698+
/// <param name="typeIndex">The type of component to get</param>
699+
/// <returns>A pointer to the component, or null if the component is not present</returns>
700+
public void* GetUnsafeComponentPtrROIgnoreParallelSafety(Entity entity, TypeIndex typeIndex)
701+
{
702+
CheckTypeIndexIsInComponentList(typeIndex);
703+
CheckTypeNotBuffer(typeIndex);
704+
705+
if (typeIndex.IsSharedComponentType)
706+
{
707+
fixed (DynamicSharedComponentTypeHandle* s0Ptr = &s0)
708+
{
709+
ref var handle = ref s0Ptr[handleIndices[typeIndex].index];
710+
void* ptr = default;
711+
if (entity == currentEntity)
712+
{
713+
ptr = currentChunk.GetDynamicSharedComponentDataAddress(ref handle);
714+
}
715+
else
716+
{
717+
var info = esil[entity];
718+
ptr = info.Chunk.GetDynamicSharedComponentDataAddress(ref handle);
719+
}
720+
return ptr;
721+
}
722+
}
723+
724+
var typeSize = TypeManager.GetTypeInfo(typeIndex).TypeSize;
725+
fixed (DynamicComponentTypeHandle* c0Ptr = &c0)
726+
{
727+
ref var handle = ref c0Ptr[handleIndices[typeIndex].index];
728+
if (entity == currentEntity)
729+
{
730+
var array = currentChunk.GetDynamicComponentDataArrayReinterpret<byte>(ref handle, typeSize);
731+
if (array.Length == 0)
732+
return null;
733+
return (byte*)array.GetUnsafeReadOnlyPtr() + typeSize * currentIndexInChunk;
734+
}
735+
else
736+
{
737+
var info = esil[entity];
738+
var array = info.Chunk.GetDynamicComponentDataArrayReinterpret<byte>(ref handle, typeSize);
739+
if (array.Length == 0)
740+
return null;
741+
return (byte*)array.GetUnsafeReadOnlyPtr() + typeSize * info.IndexInChunk;
742+
}
743+
}
744+
}
745+
746+
/// <summary>
747+
/// Gets the read-write pointer to either the IComponentData or ISharedComponentData,
748+
/// ignoring parallel safety checks as if [NativeDisableParallelForRestriction] was used
749+
/// </summary>
750+
/// <param name="entity">The entity to get the component from</param>
751+
/// <param name="typeIndex">The type of component to get</param>
752+
/// <returns>A pointer to the component, or null if the component is not present</returns>
753+
public void* GetUnsafeComponentPtrRWIgnoreParallelSafety(Entity entity, TypeIndex typeIndex)
754+
{
755+
CheckTypeIndexIsInComponentList(typeIndex);
756+
CheckTypeNotBuffer(typeIndex);
757+
CheckTypeNotShared(typeIndex);
758+
759+
var typeSize = TypeManager.GetTypeInfo(typeIndex).TypeSize;
760+
fixed (DynamicComponentTypeHandle* c0Ptr = &c0)
761+
{
762+
ref var handle = ref c0Ptr[handleIndices[typeIndex].index];
763+
if (entity == currentEntity)
764+
{
765+
var array = currentChunk.GetDynamicComponentDataArrayReinterpret<byte>(ref handle, typeSize);
766+
if (array.Length == 0)
767+
return null;
768+
return (byte*)array.GetUnsafePtr() + typeSize * currentIndexInChunk;
769+
}
770+
else
771+
{
772+
var info = esil[entity];
773+
var array = info.Chunk.GetDynamicComponentDataArrayReinterpret<byte>(ref handle, typeSize);
774+
if (array.Length == 0)
775+
return null;
776+
return (byte*)array.GetUnsafePtr() + typeSize * info.IndexInChunk;
777+
}
778+
}
779+
}
647780
#endregion
648781

649782
#region Constructor, Update, and Dispose
@@ -1116,6 +1249,27 @@ void CheckSafeAccessForForeignEntity(ref DynamicComponentTypeHandle handle)
11161249
"Attempted to access a component from an external entity inside a parallel job. This is not thread-safe. Call SetupEntity() to specify an entity that is safe to access in a parallel job, such as one from an IJobChunk or IJobEntity");
11171250
#endif
11181251
}
1252+
1253+
[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
1254+
void CheckTypeNotBuffer(TypeIndex typeIndex)
1255+
{
1256+
if (typeIndex.IsBuffer)
1257+
throw new System.ArgumentOutOfRangeException($"The specified TypeIndex is for a DynamicBuffer, which is not supported in this operation.");
1258+
}
1259+
1260+
[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
1261+
void CheckTypeNotShared(TypeIndex typeIndex)
1262+
{
1263+
if (typeIndex.IsSharedComponentType)
1264+
throw new System.ArgumentOutOfRangeException($"The specified TypeIndex is for a SharedComponent, which is not supported in this operation.");
1265+
}
1266+
1267+
[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
1268+
void CheckTypeIsBuffer(TypeIndex typeIndex)
1269+
{
1270+
if (!typeIndex.IsBuffer)
1271+
throw new System.ArgumentOutOfRangeException($"The specified TypeIndex is not for a DynamicBuffer, and a DynamicBuffer type is required for this operation.");
1272+
}
11191273
#endregion
11201274
}
11211275

0 commit comments

Comments
 (0)