#region usings using System.Collections.Generic; using System.Collections.ObjectModel; using SM.Base.Drawing; using SM.Base.Window; using SM.Base.Window.Contexts; #endregion namespace SM.Base.Scene { /// /// Contains a list of show items. /// public abstract class GenericItemCollection : List, IShowItem, IShowCollection, IScriptable, IFixedScriptable { private readonly List _scriptableObjects = new List(); private readonly List _fixedScriptables = new List(); /// /// Currently active script objects. /// public ReadOnlyCollection ScriptableObjects => new ReadOnlyCollection(_scriptableObjects); /// public bool UpdateActive { get; set; } = true; /// public List Objects => this; /// public object Parent { get; set; } /// public string Name { get; set; } = "Unnamed Item Collection"; /// public ICollection Flags { get; set; } = new List {"collection"}; /// public bool Active { get; set; } = true; /// public bool RenderActive { get; set; } = true; /// public virtual void FixedUpdate(FixedUpdateContext context) { if (!Active || !UpdateActive) return; for (int i = 0; i < _fixedScriptables.Count; i++) { _fixedScriptables[i].FixedUpdate(context); } } /// public virtual void Draw(DrawContext context) { if (!Active || !RenderActive) return; for (var i = 0; i < Objects.Count; i++) { if (!this[i].Active || !this[i].RenderActive) continue; this[i].Draw(context); } } /// public virtual void Update(UpdateContext context) { if (!Active || !UpdateActive) return; for (var i = 0; i < _scriptableObjects.Count; i++) { if (!_scriptableObjects[i].Active || !_scriptableObjects[i].UpdateActive) continue; _scriptableObjects[i].Update(context); } } /// public virtual void OnAdded(object sender) { } /// public virtual void OnRemoved(object sender) { } /// /// Adds a item to the draw and the script collection, when applicable. /// public void Add(params IShowItem[] items) { foreach (var item in items) { AddObject(item); if (item is IScriptable scriptable) AddScript(scriptable); if (item is IFixedScriptable fixedScriptable) _fixedScriptables.Add(fixedScriptable); } } /// /// Adds the object to the collection. /// /// public void AddObject(IShowItem item) { base.Add(item); item.Parent = this; item.OnAdded(this); } /// /// Adds the script to the collection. /// /// public void AddScript(IScriptable item) { _scriptableObjects.Add(item); if (item is IFixedScriptable fs) _fixedScriptables.Add(fs); } /// /// Removes an object from the drawing list. /// If the object is a scriptable object, it will remove the object from that list as well. /// /// public void Remove(params IShowItem[] items) { foreach (var item in items) { RemoveObject(item); if (item is IScriptable scriptable) RemoveScript(scriptable); if (item is IFixedScriptable fixedScriptable) _fixedScriptables.Remove(fixedScriptable); } } /// /// Remove the object from the draw collection. /// /// public void RemoveObject(IShowItem item) { base.Remove(item); item.Parent = null; item.OnRemoved(this); } /// /// Remove the object from the script collection. /// /// public void RemoveScript(IScriptable item) { _scriptableObjects.Remove(item); if (item is IFixedScriptable fs) _fixedScriptables.Remove(fs); } /// /// Returns all objects in the drawing list. /// Not reclusive. /// /// If true, it will add collections as well. /// public ICollection GetAllItems(bool includeCollections = false) { List items = new List(); for (var i = 0; i < Count; i++) { if (!includeCollections && this[i] is IShowCollection) continue; items.Add(this[i]); } return items; } /// /// Returns a object with this name or the default, if not available. /// Not reclusive. /// /// /// public IShowItem GetItemByName(string name) { IShowItem obj = default; for (var i = 0; i < Count; i++) if (this[i].Name == name) { obj = this[i]; break; } return obj; } /// /// Returns a object with this name or the default if not available. /// Not reclusive. /// /// Type of return public TGetItem GetItemByName(string name) where TGetItem : IShowItem { return (TGetItem) GetItemByName(name); } /// /// Returns all object that have this flag. /// Only in this list. /// public ICollection GetItemsWithFlag(string flag) { var list = new List(); for (var i = 0; i < Count; i++) { var obj = this[i]; if (obj.Flags == null) continue; if (obj.Flags.Contains(flag)) list.Add(obj); } return list; } } /// /// Contains a list of show items with transformation. /// /// The type of transformation. public abstract class GenericItemCollection : GenericItemCollection, IShowTransformItem where TTransformation : GenericTransformation, new() { /// /// Transformation of the collection /// public TTransformation Transform { get; set; } = new TTransformation(); /// public override void Draw(DrawContext context) { Transform.LastMaster = context.ModelMatrix; context.ModelMatrix = Transform.MergeMatrix(context.ModelMatrix); base.Draw(context); } } }