From fbf4be340e89a07b2258a5583605a60eb09a2dda Mon Sep 17 00:00:00 2001 From: NathanKell Date: Mon, 4 Dec 2023 01:55:26 -0800 Subject: [PATCH] Add CachedObject and ResettableCachedObject which I wrote for Kerbalism. A simple object cache to lower GC overhead. --- Source/ROUtils/CachedObject.cs | 113 +++++++++++++++++++++++++++++++++ Source/ROUtils/ROUtils.csproj | 1 + 2 files changed, 114 insertions(+) create mode 100644 Source/ROUtils/CachedObject.cs diff --git a/Source/ROUtils/CachedObject.cs b/Source/ROUtils/CachedObject.cs new file mode 100644 index 0000000..264b99f --- /dev/null +++ b/Source/ROUtils/CachedObject.cs @@ -0,0 +1,113 @@ +using UnityEngine; +using System.Collections.Generic; +using System; + +namespace ROUtils +{ + /// + /// This lets us use CachedObject to + /// avoid retyping the caching code + /// + public interface IResettable + { + void Reset(); + } + + /// + /// A simple object cache, will support any class + /// with a parameterless constructor + /// + /// + public class CachedObject where T : class, new() + { + protected List objects = new List(); + protected int active = 0; + + /// + /// Returns a new T from the cache or, if there aren't + /// any free, creates a new one and adds it to the cache + /// + /// + public T Next() + { + if (active < objects.Count) + return objects[active++]; + + var next = new T(); + ++active; + objects.Add(next); + return next; + } + + /// + /// Frees an object, returning it to the cache + /// and compacting the active set + /// + /// + /// true if the object is found in the cache + public bool Free(T obj) + { + for (int i = active; i-- > 0;) + { + var o = objects[i]; + if (o == obj) + { + --active; + objects[i] = objects[active]; + objects[active] = obj; + return true; + } + } + + return false; + } + + /// + /// Fully clears the cache. This will expose the objects to GC! + /// + public void Clear() + { + objects.Clear(); + active = 0; + } + } + + /// + /// A simple object cache, will support any class with + /// a parameterless constructor that implements IResettable. + /// It will reset objects when freeing them, and adds the Reset + /// method that resets all objects but leaves them in the cache + /// + /// + public class ResettableCachedObject : CachedObject where T : class, IResettable, new() + { + /// + /// Frees an object, resetting it, returning it + /// to the cache, and compacting the active set + /// + /// + /// true if the object is found in the cache + public new bool Free(T obj) + { + if (base.Free(obj)) + { + obj.Reset(); + return true; + } + + return false; + } + + /// + /// Resets all objects in the cache and + /// makes them all available + /// + public void Reset() + { + for (int i = active; i-- > 0;) + objects[i].Reset(); + + active = 0; + } + } +} diff --git a/Source/ROUtils/ROUtils.csproj b/Source/ROUtils/ROUtils.csproj index d5d5ec1..c916fd8 100644 --- a/Source/ROUtils/ROUtils.csproj +++ b/Source/ROUtils/ROUtils.csproj @@ -124,6 +124,7 @@ +