Files
LuaCsForBarotraumaEP/Libraries/MonoGame.Framework/Src/MonoGame.Framework.Content.Pipeline/Graphics/VertexChannelGeneric.cs
2019-06-25 16:00:44 +03:00

242 lines
8.5 KiB
C#

// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using Microsoft.Xna.Framework.Design;
using Microsoft.Xna.Framework.Graphics.PackedVector;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace Microsoft.Xna.Framework.Content.Pipeline.Graphics
{
/// <summary>
/// Provides methods and properties for maintaining a vertex channel.
/// This is a generic implementation of VertexChannel and, therefore, can handle strongly typed content data.
/// </summary>
public sealed class VertexChannel<T> : VertexChannel, IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable
{
List<T> items;
/// <summary>
/// Gets the strongly-typed list for the base class to access.
/// </summary>
internal override IList Items
{
get
{
return items;
}
}
/// <summary>
/// Gets the type of data contained in this channel.
/// </summary>
public override Type ElementType
{
get
{
return typeof(T);
}
}
/// <summary>
/// Gets or sets the element at the specified index.
/// </summary>
public new T this[int index]
{
get
{
return items[index];
}
set
{
items[index] = value;
}
}
/// <summary>
/// true if this object is read-only; false otherwise.
/// </summary>
bool ICollection<T>.IsReadOnly
{
get
{
return false;
}
}
/// <summary>
/// Creates an instance of VertexChannel.
/// </summary>
/// <param name="name">Name of the channel.</param>
internal VertexChannel(string name)
: base(name)
{
items = new List<T>();
}
static VertexChannel()
{
// Some platforms (such as Windows Store) don't support TypeConverter, which
// is normally referenced with an attribute on the target type. To keep them
// out of the main assembly, they are registered here before their use.
//TypeDescriptor.AddAttributes(typeof(Single), new TypeConverterAttribute(typeof(SingleTypeConverter)));
TypeDescriptor.AddAttributes(typeof(Vector2), new TypeConverterAttribute(typeof(Vector2TypeConverter)));
TypeDescriptor.AddAttributes(typeof(Vector3), new TypeConverterAttribute(typeof(Vector3TypeConverter)));
TypeDescriptor.AddAttributes(typeof(Vector4), new TypeConverterAttribute(typeof(Vector4TypeConverter)));
//TypeDescriptor.AddAttributes(typeof(IPackedVector), new TypeConverterAttribute(typeof(PackedVectorTypeConverter)));
}
/// <summary>
/// Determines whether the specified element is in the channel.
/// </summary>
/// <param name="item">Element being searched for.</param>
/// <returns>true if the element is present; false otherwise.</returns>
public bool Contains(T item)
{
return items.Contains(item);
}
/// <summary>
/// Copies the elements of the channel to an array, starting at the specified index.
/// </summary>
/// <param name="array">Array that will receive the copied channel elements.</param>
/// <param name="arrayIndex">Starting index for copy operation.</param>
public void CopyTo(T[] array, int arrayIndex)
{
items.CopyTo(array, arrayIndex);
}
/// <summary>
/// Gets an enumerator interface for reading channel content.
/// </summary>
/// <returns>Enumeration of the channel content.</returns>
public new IEnumerator<T> GetEnumerator()
{
return items.GetEnumerator();
}
/// <summary>
/// Gets the index of the specified item.
/// </summary>
/// <param name="item">Item whose index is to be retrieved.</param>
/// <returns>Index of specified item.</returns>
public int IndexOf(T item)
{
return items.IndexOf(item);
}
/// <summary>
/// Inserts the range of values from the enumerable into the channel.
/// </summary>
/// <param name="index">The zero-based index at which the new elements should be inserted.</param>
/// <param name="data">The data to insert into the channel.</param>
internal override void InsertRange(int index, IEnumerable data)
{
if ((index < 0) || (index > items.Count))
throw new ArgumentOutOfRangeException("index");
if (data == null)
throw new ArgumentNullException("data");
if (!(data is IEnumerable<T>))
throw new ArgumentException("data");
items.InsertRange(index, (IEnumerable<T>)data);
}
/// <summary>
/// Reads channel content and automatically converts it to the specified vector format.
/// </summary>
/// <typeparam name="TargetType">Target vector format for the converted channel data.</typeparam>
/// <returns>The converted channel data.</returns>
public override IEnumerable<TargetType> ReadConvertedContent<TargetType>()
{
if (typeof(TargetType).IsAssignableFrom(typeof(T)))
return items.Cast<TargetType>();
return Convert<TargetType>(items);
}
private static IEnumerable<TargetType> Convert<TargetType>(IEnumerable<T> items)
{
// The following formats are supported:
// - Single
// - Vector2 Structure
// - Vector3 Structure
// - Vector4 Structure
// - Any implementation of IPackedVector Interface.
var converter = TypeDescriptor.GetConverter(typeof(T));
if (!converter.CanConvertTo(typeof(TargetType)))
{
// If you got this exception, check out the static constructor above
// to make sure your type is registered.
throw new NotImplementedException(
string.Format("TypeConverter for {0} -> {1} is not implemented.",
typeof(T).Name, typeof(TargetType).Name));
}
foreach (var item in items)
yield return (TargetType)converter.ConvertTo(item, typeof(TargetType));
}
/// <summary>
/// Adds a new element to the end of the collection.
/// </summary>
/// <param name="value">The element to add.</param>
void ICollection<T>.Add(T value)
{
((ICollection<T>)Items).Add(value);
}
/// <summary>
/// Removes all elements from the collection.
/// </summary>
void ICollection<T>.Clear()
{
Items.Clear();
}
/// <summary>
/// Removes a specified element from the collection.
/// </summary>
/// <param name="value">The element to remove.</param>
/// <returns>true if the channel was removed; false otherwise.</returns>
bool ICollection<T>.Remove(T value)
{
return ((ICollection<T>)Items).Remove(value);
}
/// <summary>
/// Inserts an element into the collection at the specified position.
/// </summary>
/// <param name="index">Index at which to insert the element.</param>
/// <param name="value">The element to insert.</param>
void IList<T>.Insert(int index, T value)
{
Items.Insert(index, value);
}
/// <summary>
/// Removes the element at the specified index position.
/// </summary>
/// <param name="index">Index of the element to remove.</param>
void IList<T>.RemoveAt(int index)
{
Items.RemoveAt(index);
}
/// <summary>
/// Removes a range of values from the channel.
/// </summary>
/// <param name="index">The zero-based starting index of the range of elements to remove.</param>
/// <param name="count"> The number of elements to remove.</param>
internal override void RemoveRange(int index, int count)
{
items.RemoveRange(index, count);
}
}
}