// Copyright (C) 2019-2021 Alexander Bogarsukov. All rights reserved.
// See the LICENSE.md file in the project root for more information.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityFx.Outline
{
///
/// A serializable collection of outline layers.
///
///
///
///
[CreateAssetMenu(fileName = "OutlineLayerCollection", menuName = "UnityFx/Outline/Outline Layer Collection")]
public sealed class OutlineLayerCollection : ScriptableObject, IList, IReadOnlyList
{
#region data
[SerializeField, HideInInspector]
private List _layers = new List();
[SerializeField, HideInInspector]
private int _ignoreLayerMask;
#endregion
#region interface
///
/// Gets or sets layer mask to use for ignored components in layer game objects.
///
public int IgnoreLayerMask
{
get
{
return _ignoreLayerMask;
}
set
{
if (_ignoreLayerMask != value)
{
_ignoreLayerMask = value;
foreach (var layer in _layers)
{
layer.UpdateRenderers(value);
}
}
}
}
///
/// Gets number of game objects in the layers.
///
public int NumberOfObjects
{
get
{
var result = 0;
foreach (var layer in _layers)
{
result += layer.Count;
}
return result;
}
}
///
/// Gets a layer with the specified index. If layer at the does not exist, creates one.
///
public OutlineLayer GetOrAddLayer(int index)
{
if (index < 0)
{
throw new ArgumentOutOfRangeException(nameof(index));
}
while (index >= _layers.Count)
{
_layers.Add(new OutlineLayer(this));
}
return _layers[index];
}
///
/// Adds a new layer.
///
public OutlineLayer AddLayer()
{
var layer = new OutlineLayer(this);
_layers.Add(layer);
return layer;
}
///
/// Gets the objects for rendering.
///
public void GetRenderObjects(IList renderObjects)
{
foreach (var layer in _layers)
{
layer.GetRenderObjects(renderObjects);
}
}
///
/// Removes the specified from layers.
///
/// A to remove.
public void Remove(GameObject go)
{
foreach (var layer in _layers)
{
if (layer.Remove(go))
{
break;
}
}
}
///
/// Removes all game objects registered in layers.
///
public void ClearLayerContent()
{
foreach (var layer in _layers)
{
layer.Clear();
}
}
#endregion
#region internals
internal void Reset()
{
foreach (var layer in _layers)
{
layer.Reset();
}
}
#endregion
#region ScriptableObject
private void OnEnable()
{
foreach (var layer in _layers)
{
layer.Clear();
layer.SetCollection(this);
}
}
#endregion
#region IList
///
public OutlineLayer this[int layerIndex]
{
get
{
return _layers[layerIndex];
}
set
{
if (value is null)
{
throw new ArgumentNullException("layer");
}
if (layerIndex < 0 || layerIndex >= _layers.Count)
{
throw new ArgumentOutOfRangeException(nameof(layerIndex));
}
if (_layers[layerIndex] != value)
{
value.SetCollection(this);
_layers[layerIndex].SetCollection(null);
_layers[layerIndex] = value;
}
}
}
///
public int IndexOf(OutlineLayer layer)
{
if (layer != null)
{
return _layers.IndexOf(layer);
}
return -1;
}
///
public void Insert(int index, OutlineLayer layer)
{
if (layer is null)
{
throw new ArgumentNullException(nameof(layer));
}
if (layer.ParentCollection != this)
{
layer.SetCollection(this);
_layers.Insert(index, layer);
}
}
///
public void RemoveAt(int index)
{
if (index >= 0 && index < _layers.Count)
{
_layers[index].SetCollection(null);
_layers.RemoveAt(index);
}
}
#endregion
#region ICollection
///
public int Count => _layers.Count;
///
public bool IsReadOnly => false;
///
public void Add(OutlineLayer layer)
{
if (layer is null)
{
throw new ArgumentNullException(nameof(layer));
}
if (layer.ParentCollection != this)
{
layer.SetCollection(this);
_layers.Add(layer);
}
}
///
public bool Remove(OutlineLayer layer)
{
if (_layers.Remove(layer))
{
layer.SetCollection(null);
return true;
}
return false;
}
///
public void Clear()
{
if (_layers.Count > 0)
{
foreach (var layer in _layers)
{
layer.SetCollection(null);
}
_layers.Clear();
}
}
///
public bool Contains(OutlineLayer layer)
{
if (layer is null)
{
return false;
}
return _layers.Contains(layer);
}
///
public void CopyTo(OutlineLayer[] array, int arrayIndex)
{
_layers.CopyTo(array, arrayIndex);
}
#endregion
#region IEnumerable
///
public IEnumerator GetEnumerator()
{
return _layers.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _layers.GetEnumerator();
}
#endregion
#region implementation
#endregion
}
}