Skip to content

Commit

Permalink
Added extension method to generate a descriptive system group heirarc…
Browse files Browse the repository at this point in the history
…hy (#6)
  • Loading branch information
m3taphysics authored Nov 1, 2023
1 parent 195bdd3 commit 486a989
Show file tree
Hide file tree
Showing 11 changed files with 291 additions and 0 deletions.
45 changes: 45 additions & 0 deletions Arch.SystemGroups.Tests/DescriptorTests/DescriptorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Arch.SystemGroups.DefaultSystemGroups;
using Arch.SystemGroups.Descriptors;
using Arch.SystemGroups.Tests.NestedGroups;
using Arch.SystemGroups.Tests.TestSetup1;
using NSubstitute;

namespace Arch.SystemGroups.Tests.DescriptorTests;

public class DescriptorTests
{
private ArchSystemsWorldBuilder<TestWorld> _worldBuilder;

[SetUp]
public void SetUp()
{
_worldBuilder = new ArchSystemsWorldBuilder<TestWorld>(new TestWorld(), Substitute.For<IPlayerLoop>());
SystemGroups.InitSystemGroupSystemTest.InjectToWorld(ref _worldBuilder);
PhysicsSystemGroupSystemTest.InjectToWorld(ref _worldBuilder);
PostPhysicsSystemGroupSystemTest.InjectToWorld(ref _worldBuilder);
PostRenderingSystemGroupSystemTest.InjectToWorld(ref _worldBuilder);
PresentationSystemGroupSystemTest.InjectToWorld(ref _worldBuilder);
SimulationSystemGroupSystemTest.InjectToWorld(ref _worldBuilder);
}

[Test]
[TestCase(nameof(InitializationSystemGroup))]
[TestCase(nameof(PhysicsSystemGroup))]
[TestCase(nameof(PostPhysicsSystemGroup))]
[TestCase(nameof(PostRenderingSystemGroup))]
[TestCase(nameof(SimulationSystemGroup))]
public void CreatesSystemDescriptorInEachGroup(string group)
{
var systemGroupWorld = _worldBuilder.Finish();
var descriptor = systemGroupWorld.GenerateDescriptors();
Assert.That(descriptor.Where(x => x.Name == group).Count(), Is.EqualTo(1));
}

[Test]
public void CreatesAllSystemDescriptors()
{
var systemGroupWorld = _worldBuilder.Finish();
var descriptor = systemGroupWorld.GenerateDescriptors();
Assert.That(descriptor.Count, Is.EqualTo(6));
}
}
34 changes: 34 additions & 0 deletions Arch.SystemGroups.Tests/DescriptorTests/NestedDescriptorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Arch.SystemGroups.DefaultSystemGroups;
using Arch.SystemGroups.Descriptors;
using Arch.SystemGroups.Tests.NestedGroups;
using Arch.SystemGroups.Tests.TestSetup1;
using NSubstitute;

namespace Arch.SystemGroups.Tests.DescriptorTests;

public class NestedDescriptorTests
{
private ArchSystemsWorldBuilder<TestWorld> _worldBuilder;

[SetUp]
public void SetUp()
{
_worldBuilder = new ArchSystemsWorldBuilder<TestWorld>(new TestWorld(), Substitute.For<IPlayerLoop>());
SystemInNestedGroup.InjectToWorld(ref _worldBuilder);
}
[Test]
public void NestedSystemGroupsAreCreated()
{
var systemGroupWorld = _worldBuilder.Finish();
var simulationSystemGroup =
systemGroupWorld.GenerateDescriptors().FirstOrDefault(x => x.Name == nameof(SimulationSystemGroup));
var root = simulationSystemGroup.Groups.First();
var firstLevel = root.Groups.First();
var secondLevel = firstLevel.Groups.First();

Assert.That(root.Name, Is.EqualTo(nameof(RootGroup)));
Assert.That(firstLevel.Name, Is.EqualTo(nameof(NestedGroup1)));
Assert.That(secondLevel.Name, Is.EqualTo(nameof(NestedGroup2)));
Assert.That(secondLevel.Systems.First().Name, Is.EqualTo(nameof(SystemInNestedGroup)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Arch.System;
using Arch.SystemGroups.DefaultSystemGroups;
using Arch.SystemGroups.Tests.TestSetup1;

namespace Arch.SystemGroups.Tests.DescriptorTests.SystemGroups
{
[UpdateInGroup(typeof(InitializationSystemGroup))]
public partial class InitSystemGroupSystemTest : BaseSystem<TestWorld, float>
{
public InitSystemGroupSystemTest(TestWorld world) : base(world)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Arch.System;
using Arch.SystemGroups.DefaultSystemGroups;
using Arch.SystemGroups.Tests.TestSetup1;

namespace Arch.SystemGroups.Tests.DescriptorTests
{
[UpdateInGroup(typeof(PhysicsSystemGroup))]
public partial class PhysicsSystemGroupSystemTest : BaseSystem<TestWorld, float>
{
public PhysicsSystemGroupSystemTest(TestWorld world) : base(world)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Arch.System;
using Arch.SystemGroups.DefaultSystemGroups;
using Arch.SystemGroups.Tests.TestSetup1;

namespace Arch.SystemGroups.Tests.DescriptorTests
{
[UpdateInGroup(typeof(PostPhysicsSystemGroup))]
public partial class PostPhysicsSystemGroupSystemTest : BaseSystem<TestWorld, float>
{
public PostPhysicsSystemGroupSystemTest(TestWorld world) : base(world)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Arch.System;
using Arch.SystemGroups.DefaultSystemGroups;
using Arch.SystemGroups.Tests.TestSetup1;

namespace Arch.SystemGroups.Tests.DescriptorTests
{
[UpdateInGroup(typeof(PostRenderingSystemGroup))]
public partial class PostRenderingSystemGroupSystemTest : BaseSystem<TestWorld, float>
{
public PostRenderingSystemGroupSystemTest(TestWorld world) : base(world)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Arch.System;
using Arch.SystemGroups.DefaultSystemGroups;
using Arch.SystemGroups.Tests.TestSetup1;

namespace Arch.SystemGroups.Tests.DescriptorTests
{
[UpdateInGroup(typeof(PresentationSystemGroup))]
public partial class PresentationSystemGroupSystemTest : BaseSystem<TestWorld, float>
{
public PresentationSystemGroupSystemTest(TestWorld world) : base(world)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Arch.System;
using Arch.SystemGroups.DefaultSystemGroups;
using Arch.SystemGroups.Tests.TestSetup1;

namespace Arch.SystemGroups.Tests.DescriptorTests
{
[UpdateInGroup(typeof(SimulationSystemGroup))]
public partial class SimulationSystemGroupSystemTest : BaseSystem<TestWorld, float>
{
public SimulationSystemGroupSystemTest(TestWorld world) : base(world)
{
}
}
}
26 changes: 26 additions & 0 deletions Arch.SystemGroups/Descriptors/SystemDescriptor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/// <summary>
///
/// </summary>
public struct SystemDescriptor
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="name">Name of the system</param>
/// <param name="throttlingEnabled">Is throttling enabled for this system</param>
public SystemDescriptor(string name, bool throttlingEnabled)
{
Name = name;
ThrottlingEnabled = throttlingEnabled;
}

/// <summary>
/// Name of the system
/// </summary>
public string Name { get; }

/// <summary>
/// Is throttling enabled for this system
/// </summary>
public bool ThrottlingEnabled { get; }
}
37 changes: 37 additions & 0 deletions Arch.SystemGroups/Descriptors/SystemGroupDescriptor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Collections.Generic;

namespace Arch.SystemGroups.Descriptors;

/// <summary>
/// Descriptor for a SystemGroup
/// </summary>
public struct SystemGroupDescriptor
{
/// <summary>
///
/// </summary>
/// <param name="name">name of the system group</param>
/// <param name="systems">a list of systems within this group</param>
/// <param name="groups">A list of subGroups within this group</param>
public SystemGroupDescriptor(string name, IReadOnlyList<SystemDescriptor> systems, IReadOnlyList<SystemGroupDescriptor> groups)
{
Name = name;
Systems = systems;
Groups = groups;
}

/// <summary>
/// Name of this SystemGroup
/// </summary>
public string Name { get; }

/// <summary>
/// Systems within this group
/// </summary>
public IReadOnlyList<SystemDescriptor> Systems { get; }

/// <summary>
/// Sub Groups within this group
/// </summary>
public IReadOnlyList<SystemGroupDescriptor> Groups { get; }
}
65 changes: 65 additions & 0 deletions Arch.SystemGroups/Descriptors/SystemGroupWorldExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.Collections.Generic;
using JetBrains.Annotations;

namespace Arch.SystemGroups.Descriptors;

/// <summary>
/// Extensions for SystemGroupWorld
/// </summary>
public static class SystemGroupWorldExtensions
{
/// <summary>
/// Generate the descriptor for the SystemGroupWorld
/// </summary>
/// <param name="world"></param>
[UsedImplicitly]
public static IReadOnlyList<SystemGroupDescriptor> GenerateDescriptors(this SystemGroupWorld world)
{
var descriptors = new List<SystemGroupDescriptor>();
// Foreach system group such as initialization, simulation, presentation
foreach (var worldSystemGroup in world.SystemGroups)
{
descriptors.Add(GenerateGroupDescriptor(worldSystemGroup.GetType().Name, worldSystemGroup.Nodes));
}

return descriptors;
}

/// <summary>
/// Generate the descriptor for the SystemGroup
/// </summary>
/// <param name="name">Name of the system group</param>
/// <param name="nodes">List of nodes within the system group</param>
private static SystemGroupDescriptor GenerateGroupDescriptor(string name, IReadOnlyList<ExecutionNode<float>> nodes)
{
var groupSystems = new List<SystemDescriptor>();
var groupNestedGroups = new List<SystemGroupDescriptor>();
GenerateNestedGroupDescriptors(nodes, groupSystems, groupNestedGroups);
return new SystemGroupDescriptor(name, groupSystems, groupNestedGroups
);
}

/// <summary>
/// Generate the descriptor for the SystemGroupWorld
/// </summary>
/// <param name="nodes"></param>
/// <param name="groupSystems"></param>
/// <param name="groupNestedGroups"></param>
/// <returns></returns>
private static void GenerateNestedGroupDescriptors(IReadOnlyList<ExecutionNode<float>> nodes,
List<SystemDescriptor> groupSystems, List<SystemGroupDescriptor> groupNestedGroups)
{
if(nodes is null) return;
foreach (var node in nodes)
{
if (node.IsGroup)
{
groupNestedGroups.Add(GenerateGroupDescriptor(node.CustomGroup.GetType().Name, node.CustomGroup.Nodes));
}
else
{
groupSystems.Add(new SystemDescriptor(node.System.GetType().Name, node.ThrottlingEnabled));
}
}
}
}

0 comments on commit 486a989

Please sign in to comment.