Skip to content

Commit

Permalink
Merge pull request #197 from notgiven688/prog3
Browse files Browse the repository at this point in the history
  • Loading branch information
notgiven688 authored Oct 28, 2024
2 parents 48a9cf6 + c13cfbc commit 18f8360
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 50 deletions.
29 changes: 19 additions & 10 deletions src/Jitter2/Collision/DynamicTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ void SetTime(Timings type)
if (multiThread)
{
const int taskThreshold = 24;
int numTasks = Math.Clamp(proxies.Active / taskThreshold, 1, ThreadPool.Instance.ThreadCount);
Parallel.ForBatch(0, proxies.Active, numTasks, scanOverlapsPre);
int numTasks = Math.Clamp(proxies.ActiveCount / taskThreshold, 1, ThreadPool.Instance.ThreadCount);
Parallel.ForBatch(0, proxies.ActiveCount, numTasks, scanOverlapsPre);

SetTime(Timings.ScanOverlapsPre);

Expand All @@ -180,13 +180,13 @@ void SetTime(Timings type)

SetTime(Timings.UpdateProxies);

Parallel.ForBatch(0, proxies.Active, numTasks, scanOverlapsPost);
Parallel.ForBatch(0, proxies.ActiveCount, numTasks, scanOverlapsPost);

SetTime(Timings.ScanOverlapsPost);
}
else
{
scanOverlapsPre(new Parallel.Batch(0, proxies.Active));
scanOverlapsPre(new Parallel.Batch(0, proxies.ActiveCount));
SetTime(Timings.ScanOverlapsPre);

var sl = lists[0];
Expand All @@ -199,7 +199,7 @@ void SetTime(Timings type)

SetTime(Timings.UpdateProxies);

scanOverlapsPost(new Parallel.Batch(0, proxies.Active));
scanOverlapsPost(new Parallel.Batch(0, proxies.ActiveCount));
SetTime(Timings.ScanOverlapsPost);
}
}
Expand Down Expand Up @@ -405,20 +405,29 @@ public void Query<T>(T hits, in JBBox box) where T : ICollection<IDynamicTreePro
/// <summary>
/// Randomly removes and adds entities to the tree to facilitate optimization.
/// </summary>
/// <param name="sweeps">The number of optimization iterations to perform. The default value is 100.</param>
public void Optimize(int sweeps = 100)
/// <param name="sweeps">The number of times to iterate over all proxies in the tree. Must be greater than zero.</param>
/// <param name="chance">The chance of a proxy to be removed and re-added to the tree for each sweep. Must be between 0 and 1.</param>
public void Optimize(int sweeps = 100, float chance = 0.01f)
{
optimizeRandom ??= new Random(0);
Optimize(optimizeRandom, sweeps, chance);
}

/// <inheritdoc cref="Optimize(int, float)" />
/// <param name="random">Provide an instance of a random class.</param>
public void Optimize(Random random, int sweeps, float chance)
{
if (sweeps <= 0) throw new ArgumentOutOfRangeException(nameof(sweeps), "Sweeps must be greater than zero.");
if (chance < 0 || chance > 1) throw new ArgumentOutOfRangeException(nameof(chance), "Chance must be between 0 and 1.");

Stack<IDynamicTreeProxy> temp = new();
for (int e = 0; e < sweeps; e++)
{
for (int i = 0; i < proxies.Count; i++)
{
var proxy = proxies[i];

if (optimizeRandom.NextDouble() > 0.01d) continue;
if (random.NextDouble() > chance) continue;

var proxy = proxies[i];
temp.Push(proxy);
InternalRemoveProxy(proxy);
}
Expand Down
28 changes: 13 additions & 15 deletions src/Jitter2/DataStructures/ActiveList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public ReadOnlyActiveList(ActiveList<T> list)
this.list = list;
}

public int Active => list.Active;
public int Active => list.ActiveCount;
public int Count => list.Count;

public T this[int i] => list[i];
Expand Down Expand Up @@ -114,18 +114,14 @@ public void Reset()

private T[] elements;

public int Active { get; private set; }
public int ActiveCount { get; private set; }

public ActiveList(int initialSize = 1024)
{
elements = new T[initialSize];
}

public T this[int i]
{
get => elements[i];
set => elements[i] = value;
}
public T this[int i] => elements[i];

public void Clear()
{
Expand All @@ -136,11 +132,13 @@ public void Clear()
}

Count = 0;
Active = 0;
ActiveCount = 0;
}

public int Count { get; private set; }

public Span<T> AsSpan() => this.elements.AsSpan(0, Count);

public void Add(T element, bool active = false)
{
Debug.Assert(element.ListIndex == -1);
Expand Down Expand Up @@ -170,17 +168,17 @@ public bool IsActive(T element)
Debug.Assert(element.ListIndex != -1);
Debug.Assert(elements[element.ListIndex] == element);

return (element.ListIndex < Active);
return (element.ListIndex < ActiveCount);
}

public bool MoveToActive(T element)
{
Debug.Assert(element.ListIndex != -1);
Debug.Assert(elements[element.ListIndex] == element);

if (element.ListIndex < Active) return false;
Swap(Active, element.ListIndex);
Active += 1;
if (element.ListIndex < ActiveCount) return false;
Swap(ActiveCount, element.ListIndex);
ActiveCount += 1;
return true;
}

Expand All @@ -189,9 +187,9 @@ public bool MoveToInactive(T element)
Debug.Assert(element.ListIndex != -1);
Debug.Assert(elements[element.ListIndex] == element);

if (element.ListIndex >= Active) return false;
Active -= 1;
Swap(Active, element.ListIndex);
if (element.ListIndex >= ActiveCount) return false;
ActiveCount -= 1;
Swap(ActiveCount, element.ListIndex);
return true;
}

Expand Down
4 changes: 2 additions & 2 deletions src/Jitter2/Parallelization/ParallelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ public static int ParallelForBatch<T>(this ReadOnlyActiveList<T> list, int taskT
public static int ParallelForBatch<T>(this ActiveList<T> list, int taskThreshold,
Action<Parallel.Batch> action, bool execute = true) where T : class, IListIndex
{
int numTasks = list.Active / taskThreshold + 1;
int numTasks = list.ActiveCount / taskThreshold + 1;
numTasks = Math.Min(numTasks, ThreadPool.Instance.ThreadCount);

Parallel.ForBatch(0, list.Active, numTasks, action, execute);
Parallel.ForBatch(0, list.ActiveCount, numTasks, action, execute);

return numTasks;
}
Expand Down
24 changes: 12 additions & 12 deletions src/Jitter2/UnmanagedMemory/UnmanagedActiveList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public sealed unsafe class UnmanagedActiveList<T> : IDisposable where T : unmana
private T* memory;
private T** handles;

private int active;
private int activeCount;

private int size;

Expand Down Expand Up @@ -121,12 +121,12 @@ public void Free(JHandle<T> handle)
/// <summary>
/// A span for all elements marked as active.
/// </summary>
public Span<T> Active => new(memory, active);
public Span<T> Active => new(memory, activeCount);

/// <summary>
/// A span for all elements marked as inactive.
/// </summary>
public Span<T> Inactive => new(&memory[active], Count - active);
public Span<T> Inactive => new(&memory[activeCount], Count - activeCount);

/// <summary>
/// A span for all elements.
Expand All @@ -149,7 +149,7 @@ public JHandle<T> GetHandle(ref T t)
public bool IsActive(JHandle<T> handle)
{
Debug.Assert(*handle.Pointer - memory < Count);
return (nint)(*handle.Pointer) - (nint)memory < active * sizeof(T);
return (nint)(*handle.Pointer) - (nint)memory < activeCount * sizeof(T);
}

/// <summary>
Expand All @@ -159,24 +159,24 @@ public void MoveToActive(JHandle<T> handle)
{
Debug.Assert(*handle.Pointer - memory < Count);

if ((nint)(*handle.Pointer) - (nint)memory < active * sizeof(T)) return;
(**handle.Pointer, memory[active]) = (memory[active], **handle.Pointer);
if ((nint)(*handle.Pointer) - (nint)memory < activeCount * sizeof(T)) return;
(**handle.Pointer, memory[activeCount]) = (memory[activeCount], **handle.Pointer);
handles[Unsafe.Read<int>(*handle.Pointer)] = *handle.Pointer;
handles[Unsafe.Read<int>(&memory[active])] = &memory[active];
active += 1;
handles[Unsafe.Read<int>(&memory[activeCount])] = &memory[activeCount];
activeCount += 1;
}

/// <summary>
/// Moves an object from active to inactive.
/// </summary>
public void MoveToInactive(JHandle<T> handle)
{
if ((nint)(*handle.Pointer) - (nint)memory >= active * sizeof(T)) return;
if ((nint)(*handle.Pointer) - (nint)memory >= activeCount * sizeof(T)) return;

active -= 1;
(**handle.Pointer, memory[active]) = (memory[active], **handle.Pointer);
activeCount -= 1;
(**handle.Pointer, memory[activeCount]) = (memory[activeCount], **handle.Pointer);
handles[Unsafe.Read<int>(*handle.Pointer)] = *handle.Pointer;
handles[Unsafe.Read<int>(&memory[active])] = &memory[active];
handles[Unsafe.Read<int>(&memory[activeCount])] = &memory[activeCount];
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions src/Jitter2/World.Step.cs
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ private void ForeachActiveBody(bool multiThread)
}
else
{
Parallel.Batch batch = new(0, bodies.Active);
Parallel.Batch batch = new(0, bodies.ActiveCount);
UpdateBodiesCallback(batch);
}
}
Expand Down Expand Up @@ -763,7 +763,7 @@ private void DetectCollisions(bool multiThread)

private void CheckDeactivation()
{
for (int i = 0; i < islands.Active; i++)
for (int i = 0; i < islands.ActiveCount; i++)
{
Island island = islands[i];

Expand Down
18 changes: 9 additions & 9 deletions src/JitterTests/SequentialTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,40 +33,40 @@ public static void AddRemoveTest()
ActiveList<Number> ts = new();

Assert.That(ts.Count, Is.EqualTo(0));
Assert.That(ts.Active, Is.EqualTo(0));
Assert.That(ts.ActiveCount, Is.EqualTo(0));

ts.Add(num5);

Assert.That(ts.Count, Is.EqualTo(1));
Assert.That(ts.Active, Is.EqualTo(0));
Assert.That(ts.ActiveCount, Is.EqualTo(0));

ts.MoveToInactive(num5);

Assert.That(ts.Count, Is.EqualTo(1));
Assert.That(ts.Active, Is.EqualTo(0));
Assert.That(ts.ActiveCount, Is.EqualTo(0));

ts.MoveToActive(num5);

Assert.That(ts.Count, Is.EqualTo(1));
Assert.That(ts.Active, Is.EqualTo(1));
Assert.That(ts.ActiveCount, Is.EqualTo(1));

ts.Remove(num5);

Assert.That(ts.Count, Is.EqualTo(0));
Assert.That(ts.Active, Is.EqualTo(0));
Assert.That(ts.ActiveCount, Is.EqualTo(0));

ts.Add(num5, true);

Assert.That(ts.Count, Is.EqualTo(1));
Assert.That(ts.Active, Is.EqualTo(1));
Assert.That(ts.ActiveCount, Is.EqualTo(1));

ts.Add(num1);
ts.Add(num2);
ts.Add(num3);
ts.Add(num4);

Assert.That(ts.Count, Is.EqualTo(5));
Assert.That(ts.Active, Is.EqualTo(1));
Assert.That(ts.ActiveCount, Is.EqualTo(1));

ts.MoveToActive(num2);
ts.MoveToActive(num1);
Expand All @@ -75,10 +75,10 @@ public static void AddRemoveTest()
ts.MoveToInactive(num5);

Assert.That(ts.Count, Is.EqualTo(4));
Assert.That(ts.Active, Is.EqualTo(2));
Assert.That(ts.ActiveCount, Is.EqualTo(2));

List<Number> elements = new();
for (int i = 0; i < ts.Active; i++)
for (int i = 0; i < ts.ActiveCount; i++)
{
elements.Add(ts[i]);
}
Expand Down

0 comments on commit 18f8360

Please sign in to comment.