using System;
using System.Collections.Generic;
using UnityEditor.Build.Pipeline.Interfaces;
using UnityEngine;
namespace UnityEditor.Build.Pipeline
{
///
/// Basic implementation of IBuildContext. Stores data generated during a build.
///
///
public class BuildContext : IBuildContext
{
internal Dictionary m_ContextObjects;
///
/// Default constructor
///
public BuildContext()
{
m_ContextObjects = new Dictionary();
}
///
/// Default constructor, adds the passed in parameters to the context.
///
/// The set of initial parameters to add to the context.
public BuildContext(params IContextObject[] buildParams)
{
m_ContextObjects = new Dictionary();
if (buildParams == null)
return;
foreach (var buildParam in buildParams)
{
if (buildParam != null)
SetContextObject(buildParam);
}
}
///
public void SetContextObject(IContextObject contextObject) where T : IContextObject
{
if (contextObject == null)
throw new ArgumentNullException("contextObject");
var type = typeof(T);
if (!type.IsInterface)
throw new InvalidOperationException(string.Format("Passed in type '{0}' is not an interface.", type));
if (!(contextObject is T))
throw new InvalidOperationException(string.Format("'{0}' is not of passed in type '{1}'.", contextObject.GetType(), type));
m_ContextObjects[typeof(T)] = contextObject;
}
///
public void SetContextObject(Type type, IContextObject contextObject)
{
if (contextObject == null)
throw new ArgumentNullException("contextObject");
if (!type.IsInterface)
throw new InvalidOperationException(string.Format("Passed in type '{0}' is not an interface.", type));
if (!type.IsInstanceOfType(contextObject))
throw new InvalidOperationException(string.Format("'{0}' is not of passed in type '{1}'.", contextObject.GetType(), type));
m_ContextObjects[type] = contextObject;
}
private IEnumerable WalkAssignableTypes(IContextObject contextObject)
{
var iCType = typeof(IContextObject);
foreach (Type t in contextObject.GetType().GetInterfaces())
{
if (iCType.IsAssignableFrom(t) && t != iCType)
yield return t;
}
for (var current = contextObject.GetType(); current != null; current = current.BaseType)
if (iCType.IsAssignableFrom(current) && current != iCType)
yield return current;
}
///
public void SetContextObject(IContextObject contextObject)
{
if (contextObject == null)
throw new ArgumentNullException("contextObject");
List types = new List(WalkAssignableTypes(contextObject));
if (types.Count == 0)
throw new Exception($"Could not determine context object type for object of type {contextObject.GetType().FullName}");
types.ForEach(x => m_ContextObjects[x] = contextObject);
}
///
public bool ContainsContextObject() where T : IContextObject
{
return ContainsContextObject(typeof(T));
}
///
public bool ContainsContextObject(Type type)
{
if (type == null)
throw new ArgumentNullException("type");
return m_ContextObjects.ContainsKey(type);
}
///
public T GetContextObject() where T : IContextObject
{
return (T)GetContextObject(typeof(T));
}
///
public IContextObject GetContextObject(Type type)
{
if (type == null)
throw new ArgumentNullException("type");
if (!m_ContextObjects.ContainsKey(type))
throw new Exception($"Object of Type {type} was not available within the BuildContext");
return m_ContextObjects[type];
}
///
public bool TryGetContextObject(out T contextObject) where T : IContextObject
{
IContextObject cachedContextObject;
if (m_ContextObjects.TryGetValue(typeof(T), out cachedContextObject) && cachedContextObject is T)
{
contextObject = (T)cachedContextObject;
return true;
}
contextObject = default(T);
return false;
}
///
public bool TryGetContextObject(Type type, out IContextObject contextObject)
{
IContextObject cachedContextObject;
if (m_ContextObjects.TryGetValue(type, out cachedContextObject) && type.IsInstanceOfType(cachedContextObject))
{
contextObject = cachedContextObject;
return true;
}
contextObject = null;
return false;
}
}
}