using Cryville.Common; using Cryville.Crtr.Components; using System; using System.Collections.Generic; using System.Globalization; using UnityEngine; namespace Cryville.Crtr { public class EffectInstance : ISkinnableGroup, IComparable { readonly EffectDefinition _def; readonly SkinContainer _skinContainer; public Transform RootTransform { get; private set; } public EffectInstance(EffectDefinition def) { _def = def; _skinContainer = new SkinContainer(_def.elements); RootTransform = new GameObject("effect:" + GetHashCode().ToString(CultureInfo.InvariantCulture)).transform; SkinContext = new SkinContext(RootTransform); ChartPlayer.etor.ContextCascadeInsertBlock(); _skinContainer.MatchStatic(this); ChartPlayer.etor.ContextCascadeDiscardBlock(); foreach (var i in RootTransform.GetComponentsInChildren()) i.Init(); _indexSrc = new PropSrc.Float(() => Index); _durationOp = new PropOp.Float(v => _duration = v); } private float m_index; public float Index { get { return m_index; } set { if (m_index == value) return; m_index = value; _indexSrc.Invalidate(); } } internal static readonly int _VAR_EFFECT_INDEX = IdentifierManager.SharedInstance.Request("effect_index"); readonly PropSrc _indexSrc; double _startTime; float _duration; readonly PropOp _durationOp; public double EndTime { get { return _startTime + _duration; } } public void OnEmit(double time) { _startTime = time; RootTransform.gameObject.SetActive(true); ChartPlayer.etor.ContextCascadeInsert(); ChartPlayer.etor.ContextCascadeUpdate(_VAR_EFFECT_INDEX, _indexSrc); ChartPlayer.etor.Evaluate(_durationOp, _def.duration); _skinContainer.MatchDynamic(this, 0); ChartPlayer.etor.ContextCascadeDiscard(); } public void OnDone() { RootTransform.gameObject.SetActive(false); } public void Dispose() { GameObject.Destroy(RootTransform.gameObject); } public string TypeName { get { throw new InvalidOperationException("Type name undefined"); } } public SkinContext SkinContext { get; private set; } public Anchor OpenedAnchor { get { throw new InvalidOperationException("Anchor not supported"); } } public void PushAnchorEvent(double time, int name) { throw new InvalidOperationException("Anchor not supported"); } public void RegisterAnchor(int name) { throw new InvalidOperationException("Anchor not supported"); } public bool TryGetAnchorsByName(int name, out IReadOnlyCollection result) { throw new InvalidOperationException("Anchor not supported"); } public int CompareTo(EffectInstance other) { int r = EndTime.CompareTo(other.EndTime); if (r != 0) return r; return GetHashCode().CompareTo(other.GetHashCode()); } } }