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; } } }