Skip to content

Commit

Permalink
updated documentation about thread safety (closes #128)
Browse files Browse the repository at this point in the history
  • Loading branch information
Doraku committed Sep 17, 2021
1 parent 909f992 commit f25440b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 6 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -583,9 +583,22 @@ ISystem<float> system = new VelocitySystem(world, runner);
system.Update(elaspedTime);
```
It is safe to run a system with multithreading when:
* for an AEntitySetSystem
* for an AEntitySetSystem or an AEntityMultiMapSystem
* each entity can be safely updated separately with no dependency to an other entity
* there is no new Set, Remove or Dispose action on entity (only read or update)
* there is no composition altering operation done on a world nor on an entity. Here is a list of non thread safe operations you shouldn't do, see [Command](#Overview_Command) for how to perform such operations safely:
* Create an Entity
* SetMaxCapacity on a World
* Optimize a World
* TrimExcess a World
* Dispose an Entity
* Set/SameAs/SameAsWorld a component on an Entity or a World
* Remove a component on an Entity or a World
* Enable an Entity
* Disable an Entity
* Enable a component on an Entity
* Disable a component on an Entity
* NotifyChanged a component on an Entity
* CopyTo an Entity
* for an AComponentSystem
* each component can be safely updated separately with no dependency to an other component

Expand Down
12 changes: 12 additions & 0 deletions source/DefaultEcs/Entity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ private void InnerSet<T>(bool isNew)

/// <summary>
/// Enables the current <see cref="Entity"/> so it can appear in <see cref="EntitySet"/>.
/// This method is not thread safe.
/// </summary>
/// <exception cref="InvalidOperationException"><see cref="Entity"/> was not created from a <see cref="DefaultEcs.World"/>.</exception>
public void Enable()
Expand All @@ -114,6 +115,7 @@ public void Enable()

/// <summary>
/// Disables the current <see cref="Entity"/> so it does not appear in <see cref="EntitySet"/>.
/// This method is not thread safe.
/// </summary>
/// <exception cref="InvalidOperationException"><see cref="Entity"/> was not created from a <see cref="DefaultEcs.World"/>.</exception>
public void Disable()
Expand All @@ -139,6 +141,7 @@ public void Disable()
/// <summary>
/// Enables the current <see cref="Entity"/> component of type <typeparamref name="T"/> so it can appear in <see cref="EntitySet"/>.
/// Does nothing if current <see cref="Entity"/> does not have a component of type <typeparamref name="T"/>.
/// This method is not thread safe.
/// </summary>
/// <typeparam name="T">The type of the component.</typeparam>
/// <exception cref="InvalidOperationException"><see cref="Entity"/> was not created from a <see cref="DefaultEcs.World"/>.</exception>
Expand All @@ -160,6 +163,7 @@ public void Enable<T>()
/// <summary>
/// Disables the current <see cref="Entity"/> component of type <typeparamref name="T"/> so it does not appear in <see cref="EntitySet"/>.
/// Does nothing if current <see cref="Entity"/> does not have a component of type <typeparamref name="T"/>.
/// This method is not thread safe.
/// </summary>
/// <typeparam name="T">The type of the component.</typeparam>
/// <exception cref="InvalidOperationException"><see cref="Entity"/> was not created from a <see cref="DefaultEcs.World"/>.</exception>
Expand All @@ -177,6 +181,7 @@ public void Disable<T>()

/// <summary>
/// Sets the value of the component of type <typeparamref name="T"/> on the current <see cref="Entity"/>.
/// This method is not thread safe.
/// </summary>
/// <typeparam name="T">The type of the component.</typeparam>
/// <param name="component">The value of the component.</param>
Expand All @@ -191,6 +196,7 @@ public void Set<T>(in T component)

/// <summary>
/// Sets the value of the component of type <typeparamref name="T"/> to its default value on the current <see cref="Entity"/>.
/// This method is not thread safe.
/// </summary>
/// <typeparam name="T">The type of the component.</typeparam>
/// <exception cref="InvalidOperationException"><see cref="Entity"/> was not created from a <see cref="DefaultEcs.World"/>.</exception>
Expand All @@ -199,6 +205,7 @@ public void Set<T>(in T component)

/// <summary>
/// Sets the value of the component of type <typeparamref name="T"/> on the current <see cref="Entity"/> to the same instance of an other <see cref="Entity"/>.
/// This method is not thread safe.
/// </summary>
/// <typeparam name="T">The type of the component.</typeparam>
/// <param name="reference">The other <see cref="Entity"/> used as reference.</param>
Expand All @@ -217,6 +224,7 @@ public void SetSameAs<T>(in Entity reference)

/// <summary>
/// Sets the value of the component of type <typeparamref name="T"/> on the current <see cref="Entity"/> to the same instance of an other <see cref="Entity"/>.
/// This method is not thread safe.
/// </summary>
/// <typeparam name="T">The type of the component.</typeparam>
/// <exception cref="InvalidOperationException"><see cref="Entity"/> was not created from a <see cref="DefaultEcs.World"/>.</exception>
Expand All @@ -232,6 +240,7 @@ public void SetSameAsWorld<T>()

/// <summary>
/// Removes the component of type <typeparamref name="T"/> on the current <see cref="Entity"/>.
/// This method is not thread safe.
/// </summary>
/// <typeparam name="T">The type of the component.</typeparam>
public void Remove<T>()
Expand All @@ -247,6 +256,7 @@ public void Remove<T>()

/// <summary>
/// Notifies the value of the component of type <typeparamref name="T"/> has changed.
/// This method is not thread safe.
/// </summary>
/// <typeparam name="T">The type of the component.</typeparam>
/// <exception cref="InvalidOperationException"><see cref="Entity"/> was not created from a <see cref="DefaultEcs.World"/>.</exception>
Expand Down Expand Up @@ -279,6 +289,7 @@ public void NotifyChanged<T>()

/// <summary>
/// Creates a copy of current <see cref="Entity"/> with all of its components in the given <see cref="DefaultEcs.World"/> using the given <see cref="ComponentCloner"/>.
/// This method is not thread safe.
/// </summary>
/// <param name="world">The <see cref="DefaultEcs.World"/> instance to which copy current <see cref="Entity"/> and its components.</param>
/// <param name="cloner">The <see cref="ComponentCloner"/> to use to copy the components.</param>
Expand Down Expand Up @@ -314,6 +325,7 @@ public Entity CopyTo(World world, ComponentCloner cloner)

/// <summary>
/// Creates a copy of current <see cref="Entity"/> with all of its components in the given <see cref="DefaultEcs.World"/>.
/// This method is not thread safe.
/// </summary>
/// <param name="world">The <see cref="DefaultEcs.World"/> instance to which copy current <see cref="Entity"/> and its components.</param>
/// <returns>The created <see cref="Entity"/> in the given <see cref="DefaultEcs.World"/>.</returns>
Expand Down
9 changes: 5 additions & 4 deletions source/DefaultEcs/IPublisherExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
using DefaultEcs.Internal.Helper;

namespace DefaultEcs
{ /// <summary>
/// Specifies that the method should be automatically subscribed when its parent type or instance is called with <see cref="IPublisherExtension"/>.
/// The decorated method should be of the type <see cref="MessageHandler{T}"/>.
/// </summary>
{
/// <summary>
/// Specifies that the method should be automatically subscribed when its parent type or instance is called with <see cref="IPublisherExtension"/>.
/// The decorated method should be of the type <see cref="MessageHandler{T}"/>.
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public sealed class SubscribeAttribute : Attribute
{ }
Expand Down
10 changes: 10 additions & 0 deletions source/DefaultEcs/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ private void On(in EntityDisposedMessage message)

/// <summary>
/// Creates a new instance of the <see cref="Entity"/> struct.
/// This method is not thread safe.
/// </summary>
/// <returns>The created <see cref="Entity"/>.</returns>
/// <exception cref="InvalidOperationException">Max number of <see cref="Entity"/> reached.</exception>
Expand All @@ -270,6 +271,7 @@ public Entity CreateEntity()
/// <summary>
/// Sets up the current <see cref="World"/> to handle component of type <typeparamref name="T"/> with a different maximum count than <see cref="MaxCapacity"/>.
/// If the type of component is already handled by the current <see cref="World"/>, does nothing.
/// This method is not thread safe.
/// </summary>
/// <typeparam name="T">The type of component.</typeparam>
/// <param name="maxCapacity">The maximum number of component of type <typeparamref name="T"/> that can exist in this <see cref="World"/>.</param>
Expand Down Expand Up @@ -310,6 +312,7 @@ public bool SetMaxCapacity<T>(int maxCapacity)

/// <summary>
/// Sets the value of the component of type <typeparamref name="T"/> on the current <see cref="World"/>.
/// This method is not thread safe.
/// </summary>
/// <typeparam name="T">The type of the component.</typeparam>
/// <param name="component">The value of the component.</param>
Expand All @@ -318,6 +321,7 @@ public bool SetMaxCapacity<T>(int maxCapacity)

/// <summary>
/// Sets the value of the component of type <typeparamref name="T"/> to its default value on the current <see cref="World"/>.
/// This method is not thread safe.
/// </summary>
/// <typeparam name="T">The type of the component.</typeparam>
/// <exception cref="InvalidOperationException">Max number of component of type <typeparamref name="T"/> reached.</exception>
Expand All @@ -343,6 +347,7 @@ public bool SetMaxCapacity<T>(int maxCapacity)

/// <summary>
/// Removes the component of type <typeparamref name="T"/> on the current <see cref="World"/>.
/// This method is not thread safe.
/// </summary>
/// <typeparam name="T">The type of the component.</typeparam>
public void Remove<T>() => ComponentManager<T>.Get(WorldId)?.Remove(0);
Expand All @@ -369,6 +374,7 @@ public bool SetMaxCapacity<T>(int maxCapacity)
/// <summary>
/// Sorts current instance inner storage so accessing <see cref="Entity"/> and their components from <see cref="EntitySet"/> and <see cref="EntityMultiMap{TKey}"/> always move forward in memory.
/// This method will return once <paramref name="mainAction"/> is executed even if the optimization process has not finished.
/// This method is not thread safe.
/// </summary>
/// <param name="runner">The <see cref="IParallelRunner"/> to process this operation in parallel.</param>
/// <param name="mainAction">An <see cref="Action"/> to execute on the main thread while the optimization is in process.</param>
Expand All @@ -383,6 +389,7 @@ public void Optimize(IParallelRunner runner, Action mainAction)

/// <summary>
/// Sorts current instance inner storage so accessing <see cref="Entity"/> and their components from <see cref="EntitySet"/> and <see cref="EntityMultiMap{TKey}"/> always move forward in memory.
/// This method is not thread safe.
/// </summary>
/// <param name="runner">The <see cref="IParallelRunner"/> to process this operation in parallel.</param>
public void Optimize(IParallelRunner runner)
Expand All @@ -395,11 +402,13 @@ public void Optimize(IParallelRunner runner)

/// <summary>
/// Sorts current instance inner storage so accessing <see cref="Entity"/> and their components from <see cref="EntitySet"/> and <see cref="EntityMultiMap{TKey}"/> always move forward in memory.
/// This method is not thread safe.
/// </summary>
public void Optimize() => Optimize(DefaultParallelRunner.Default);

/// <summary>
/// Resizes inner storage to exactly the number of <typeparamref name="T"/> components this <see cref="World"/> contains.
/// This method is not thread safe.
/// </summary>
public void TrimExcess<T>()
{
Expand All @@ -409,6 +418,7 @@ public void TrimExcess<T>()

/// <summary>
/// Resizes all inner storage to exactly the number of <see cref="Entity"/> and components this <see cref="World"/> contains.
/// This method is not thread safe.
/// </summary>
public void TrimExcess()
{
Expand Down

0 comments on commit f25440b

Please sign in to comment.