feat: add ReadComponent and ReadSingleton methods

Introduce read-only access methods that return copies of components
to avoid unnecessary modification marking during iteration.
This commit is contained in:
hypercross 2026-07-18 21:24:03 +08:00
parent f1eddc75ae
commit 910fd00a03
1 changed files with 26 additions and 5 deletions

View File

@ -251,14 +251,14 @@ public class World : IDisposable
_changes.Pending.MarkComponentRemoved(entity, typeof(T));
}
/// <summary>
/// <summary>
/// Returns a reference to the component of type <typeparamref name="T"/>
/// for the given entity. Throws if the entity does not have the component.
///
/// During iteration (inside <see cref="ForEach"/> or a <c>Select</c> loop),
/// components accessed through this method are automatically marked as
/// modified when the iteration scope ends. Outside of iteration,
/// <see cref="MarkModified{T}"/> must be called explicitly.
/// During iteration, this access is auto-marked as modified since it
/// returns a mutable ref. Use <see cref="ReadComponent{T}"/> if you
/// only need to read the value.
/// </summary>
public ref T GetComponent<T>(Entity entity) where T : struct
{
@ -267,10 +267,21 @@ public class World : IDisposable
return ref _components.Get<T>(entity);
}
/// <summary>
/// Returns a copy of the component of type <typeparamref name="T"/>
/// for the given entity. Never auto-marks as modified — use this when
/// you only need to read the value.
/// </summary>
public T ReadComponent<T>(Entity entity) where T : struct
{
return _components.Get<T>(entity);
}
/// <summary>
/// Tries to get the component of type <typeparamref name="T"/> for the
/// given entity. Returns true and copies the value to
/// <paramref name="value"/> if the component exists; otherwise returns false.
/// Never auto-marks as modified.
/// </summary>
public bool TryGetComponent<T>(Entity entity, out T value) where T : struct
{
@ -352,7 +363,7 @@ public class World : IDisposable
/// <summary>
/// Returns a reference to the singleton component of type <typeparamref name="T"/>.
/// Throws if the singleton has not been set.
/// Throws if the singleton has not been set. Auto-marks as modified during iteration.
/// </summary>
public ref T GetSingleton<T>() where T : struct
{
@ -360,6 +371,16 @@ public class World : IDisposable
return ref GetComponent<T>(SingletonEntity);
}
/// <summary>
/// Returns a copy of the singleton component of type <typeparamref name="T"/>.
/// Never auto-marks as modified — use this when you only need to read the singleton.
/// </summary>
public T ReadSingleton<T>() where T : struct
{
EnsureSingleton();
return ReadComponent<T>(SingletonEntity);
}
/// <summary>
/// Returns true if a singleton component of type <typeparamref name="T"/> exists.
/// </summary>