From a23160f9f726ef070d481fa65bfff79bdcdd0aa3 Mon Sep 17 00:00:00 2001 From: Ryan Schmidt Date: Sun, 24 Jun 2018 13:58:26 -0400 Subject: [PATCH] add fGameObjectPool, allows for re-use of GOs where we need a set of similar objects (eg like a bunch of polylines) --- GameObjectSet.cs | 5 --- platform/fGameObjectPool.cs | 79 +++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 platform/fGameObjectPool.cs diff --git a/GameObjectSet.cs b/GameObjectSet.cs index 63ec5cd..55399fc 100644 --- a/GameObjectSet.cs +++ b/GameObjectSet.cs @@ -125,11 +125,6 @@ public virtual fGameObject AppendUnityPrimitiveGO(string name, PrimitiveType eTy } - public virtual void RemoveGO(GameObject go) - { - vObjects.Remove(go); - go.transform.SetParent(null); - } public virtual void RemoveGO(fGameObject go) { vObjects.Remove(go); diff --git a/platform/fGameObjectPool.cs b/platform/fGameObjectPool.cs new file mode 100644 index 0000000..43351d6 --- /dev/null +++ b/platform/fGameObjectPool.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using g3; + +namespace f3 +{ + /// + /// Pool of re-usable fGameObject instances, allocated by factory function you must provide to constructor. + /// Unused GOs are automatically parented to per-instance hidden parent GO, to avoid cluttering scene. + /// When a GO is freed, it is hidden. + /// When a GO is allocated from pool, it is set to have no parent, visible, and transform is cleared. + /// If ReinitializeF is set, this is also called on re-used GOs (*not* called on newly-allocated GOs as + /// you can do that in your FactoryF) + /// + public class fGameObjectPool where T : fGameObject + { + public Func AllocatorFactoryF; + public Action ReinitializeF; + + fGameObject pool_parent; + + List Allocated; + List Free; + + public fGameObjectPool(Func factoryF) + { + Allocated = new List(); + Free = new List(); + + pool_parent = GameObjectFactory.CreateParentGO("pool_parent"); + + AllocatorFactoryF = factoryF; + } + + + public void Destroy() + { + foreach (var go in Allocated) + go.Destroy(); + Allocated.Clear(); + Free.Clear(); + pool_parent.Destroy(); + } + + + public T Allocate() + { + if (Free.Count > 0) { + T go = Free[Free.Count - 1]; + Free.RemoveAt(Free.Count - 1); + go.SetParent(null); + go.SetVisible(true); + go.SetLocalFrame(Frame3f.Identity); + go.SetLocalScale(1.0f); + if (ReinitializeF != null) + ReinitializeF(go); + return go; + } else { + T go = AllocatorFactoryF(); + Allocated.Add(go); + return go; + } + } + + + public void FreeAll() + { + foreach (T go in Allocated) { + if (go.IsVisible()) { + go.SetVisible(false); + go.SetParent(pool_parent); + } + } + Free.Clear(); + Free.AddRange(Allocated); + } + + } +}