using Cryville.Common.Pdt; using Cryville.Crtr.Components; using Cryville.Crtr.Event; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using UnityEngine; namespace Cryville.Crtr { public class SkinSelectors { readonly SkinSelector[] selectors; readonly string[] annotations; public SkinSelectors(IEnumerable s, IEnumerable a) { selectors = s.ToArray(); annotations = a.ToArray(); } public override string ToString() { if (selectors.Length == 0) return ""; bool flag = false; string r = ""; foreach (var a in annotations) { if (flag) r += " " + a; else { r += a; flag = true; } } foreach (var s in selectors) { if (flag) r += " " + s.ToString(); else { r += s.ToString(); flag = true; } } return r; } public void Optimize(PdtEvaluatorBase etor) { for (int i = 0; i < selectors.Length; i++) { selectors[i].Optimize(etor); } } public bool IsStatic { get { foreach (var s in selectors) { if (!s.IsStatic) return false; } return true; } } public Transform MatchStatic(ContainerState h, Transform anchor) { foreach (var s in selectors) { anchor = s.Match(h, anchor); if (anchor == null) return null; } return anchor; } public bool IsUpdatable(ContainerState h) { foreach (var s in selectors) if (!s.IsUpdatable(h)) return false; return true; } public Transform MatchDynamic(ContainerState h, Transform anchor) { foreach (var s in selectors) { anchor = s.Match(h, anchor, true); if (anchor == null) return null; } return anchor; } } public abstract class SkinSelector { protected SkinSelector() { } public abstract bool IsStatic { get; } public virtual void Optimize(PdtEvaluatorBase etor) { } public abstract Transform Match(ContainerState h, Transform a, bool dyn = false); public virtual bool IsUpdatable(ContainerState h) { return true; } public class CreateObject : SkinSelector { public CreateObject() { } public override bool IsStatic { get { return true; } } public override Transform Match(ContainerState h, Transform a, bool dyn = false) { if (dyn) throw new InvalidOperationException("Object creation in dynamic context is not allowed"); var obj = new GameObject("__obj__"); obj.transform.SetParent(a, false); obj.AddComponent(); return obj.transform; } } public class Anchor : SkinSelector { public string Name { get; private set; } public Anchor(string name) { Name = name; } public override bool IsStatic { get { return true; } } public override Transform Match(ContainerState h, Transform a, bool dyn = false) { return h.Handler.Anchors[Name].Transform; } public override bool IsUpdatable(ContainerState h) { return h.Handler.Anchors[Name].Opened; } } public class Property : SkinSelector { readonly PdtExpression _exp; readonly PdtOperator _op; bool _flag; public Property(PdtExpression exp) { _exp = exp; _op = new PropOp.Boolean(v => _flag = v); } public override void Optimize(PdtEvaluatorBase etor) { etor.Optimize(_exp); } public override bool IsStatic { get { return _exp.IsConstant; } } public override Transform Match(ContainerState h, Transform a, bool dyn = false) { ChartPlayer.etor.ContextTransform = a; try { ChartPlayer.etor.Evaluate(_op, _exp); return _flag ? a : null; } catch (Exception) { throw new SelectorNotStaticException(); } finally { ChartPlayer.etor.ContextTransform = null; } } } public class State : SkinSelector { public State(string state) { } public override bool IsStatic { get { return false; } } public override Transform Match(ContainerState h, Transform a, bool dyn = false) { return null; // TODO } } public class ElementType : SkinSelector { readonly string _type; public ElementType(string type) { _type = type; } public override bool IsStatic { get { return true; } } public override Transform Match(ContainerState h, Transform a, bool dyn = false) { return h.Handler.TypeName == _type ? a : null; } } } public class SelectorNotStaticException : Exception { public SelectorNotStaticException() : base("The selector is not static") { } public SelectorNotStaticException(string message) : base(message) { } public SelectorNotStaticException(string message, Exception innerException) : base(message, innerException) { } protected SelectorNotStaticException(SerializationInfo info, StreamingContext context) : base(info, context) { } } }