perf: cache hash code in QueryDescriptor
fix: notify change buffer when removing components in World docs: add caution about structural changes during ForEach fix: prevent multiple disposals in World
This commit is contained in:
parent
6f9efc050b
commit
dddddbdbd6
|
|
@ -17,10 +17,13 @@ public class QueryDescriptor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlySet<Type> Without { get; }
|
public IReadOnlySet<Type> Without { get; }
|
||||||
|
|
||||||
|
private readonly int _hashCode;
|
||||||
|
|
||||||
internal QueryDescriptor(HashSet<Type> with, HashSet<Type> without)
|
internal QueryDescriptor(HashSet<Type> with, HashSet<Type> without)
|
||||||
{
|
{
|
||||||
With = with;
|
With = with;
|
||||||
Without = without;
|
Without = without;
|
||||||
|
_hashCode = ComputeHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -36,7 +39,9 @@ public class QueryDescriptor
|
||||||
return With.SetEquals(other.With) && Without.SetEquals(other.Without);
|
return With.SetEquals(other.With) && Without.SetEquals(other.Without);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode() => _hashCode;
|
||||||
|
|
||||||
|
private int ComputeHashCode()
|
||||||
{
|
{
|
||||||
var hash = new HashCode();
|
var hash = new HashCode();
|
||||||
foreach (var t in With.OrderBy(t => t.GUID.ToString()))
|
foreach (var t in With.OrderBy(t => t.GUID.ToString()))
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ public class World : IDisposable
|
||||||
private readonly RelationshipIndex _relationships;
|
private readonly RelationshipIndex _relationships;
|
||||||
private readonly ChangeBuffer _changes;
|
private readonly ChangeBuffer _changes;
|
||||||
private bool _singletonCreated;
|
private bool _singletonCreated;
|
||||||
|
private bool _disposed;
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// Tracks entities whose components were accessed via GetComponent<T>
|
// Tracks entities whose components were accessed via GetComponent<T>
|
||||||
|
|
@ -82,6 +83,7 @@ public class World : IDisposable
|
||||||
{
|
{
|
||||||
_relationships.OnRemoved(relType, source, entity);
|
_relationships.OnRemoved(relType, source, entity);
|
||||||
_components.Remove(source, relType);
|
_components.Remove(source, relType);
|
||||||
|
_changes.Pending.MarkComponentRemoved(source, relType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -358,6 +360,13 @@ public class World : IDisposable
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Iterates all entities matching the query, providing ref access to
|
/// Iterates all entities matching the query, providing ref access to
|
||||||
/// one component type.
|
/// one component type.
|
||||||
|
///
|
||||||
|
/// <b>Caution:</b> Adding or removing components (including destroying
|
||||||
|
/// entities) during iteration may cause entities to be skipped or
|
||||||
|
/// processed twice. This is a consequence of the sparse set's
|
||||||
|
/// swap-remove strategy. If you need to make structural changes,
|
||||||
|
/// collect the affected entities first, then apply changes after
|
||||||
|
/// the iteration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ForEach<T1>(
|
public void ForEach<T1>(
|
||||||
QueryDescriptor query,
|
QueryDescriptor query,
|
||||||
|
|
@ -486,6 +495,9 @@ public class World : IDisposable
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
_disposed = true;
|
||||||
_changes.Dispose();
|
_changes.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue