Code structure cleanup.
This commit is contained in:
116
Assets/Cryville/Crtr/Skin/EffectInstance.cs
Normal file
116
Assets/Cryville/Crtr/Skin/EffectInstance.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Crtr.Skin.Components;
|
||||
using Cryville.Crtr.Event;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Skin {
|
||||
public class EffectInstance : ISkinnableGroup, IComparable<EffectInstance> {
|
||||
readonly EffectDefinition _def;
|
||||
readonly SkinContainer _skinContainer;
|
||||
public Transform RootTransform { get; private set; }
|
||||
readonly SkinComponent[] _comps;
|
||||
public EffectInstance(EffectDefinition def) {
|
||||
_def = def;
|
||||
_skinContainer = new SkinContainer(this, _def.elements);
|
||||
RootTransform = new GameObject("effect:" + GetHashCode().ToString(CultureInfo.InvariantCulture)).transform;
|
||||
SkinContext = new SkinContext(RootTransform);
|
||||
PdtEvaluator.Instance.ContextCascadeInsertBlock();
|
||||
_skinContainer.MatchStatic();
|
||||
PdtEvaluator.Instance.ContextCascadeDiscardBlock();
|
||||
_comps = RootTransform.GetComponentsInChildren<SkinComponent>();
|
||||
foreach (var i in _comps) i.Init();
|
||||
_durationOp = new PropOp.Float(v => _duration = v);
|
||||
}
|
||||
public void Rewind(double time, Transform target) {
|
||||
_startTime = time;
|
||||
foreach (var i in _comps) i.Rewind(time, target);
|
||||
}
|
||||
Transform _currentTarget;
|
||||
Identifier _currentStateName = Identifier.Empty;
|
||||
EffectState _currentState;
|
||||
ChartEvent _ctxev;
|
||||
ContainerState _ctxstate;
|
||||
internal static readonly int _VAR_EFFECT_INDEX = IdentifierManager.Shared.Request("effect_index");
|
||||
readonly PropStores.Float _indexst = new PropStores.Float();
|
||||
public float Index {
|
||||
get { return _indexst.Value; }
|
||||
set { _indexst.Value = value; }
|
||||
}
|
||||
double _startTime;
|
||||
float _duration;
|
||||
readonly PropOp _durationOp;
|
||||
public double EndTime { get { return _startTime + _duration; } }
|
||||
public void Tick(double time) {
|
||||
foreach (var i in _comps) i.Tick(_skinContainer, time);
|
||||
}
|
||||
public bool CanEmit() {
|
||||
return _currentStateName.Key == 0 || _currentState.rewind.Key != 0;
|
||||
}
|
||||
public void OnEmit(double time, Transform target) {
|
||||
_currentTarget = target;
|
||||
_ctxev = PdtEvaluator.Instance.ContextEvent;
|
||||
_ctxstate = PdtEvaluator.Instance.ContextState;
|
||||
_skinContainer.MatchDynamic(0, true);
|
||||
if (_currentStateName.Key == 0) {
|
||||
EnterState(_def.init, time, _currentTarget, true);
|
||||
}
|
||||
else {
|
||||
if (_currentState.rewind.Key == 0) throw new InvalidOperationException("Cannot rewind");
|
||||
EnterState(_currentState.rewind, time, _currentTarget, true);
|
||||
}
|
||||
}
|
||||
void EnterState(Identifier name, double time, Transform target, bool emitting) {
|
||||
_currentStateName = name;
|
||||
_currentState = _def.states[name];
|
||||
Rewind(time, target);
|
||||
RootTransform.gameObject.SetActive(true);
|
||||
PdtEvaluator.Instance.ContextCascadeInsert();
|
||||
PdtEvaluator.Instance.ContextCascadeUpdate(_VAR_EFFECT_INDEX, _indexst.Source);
|
||||
PdtEvaluator.Instance.Evaluate(_durationOp, _currentState.duration);
|
||||
_skinContainer.MatchDynamic(1, emitting);
|
||||
PdtEvaluator.Instance.ContextCascadeDiscard();
|
||||
}
|
||||
public bool OnStateDone() {
|
||||
if (_currentState.next.Key == 0) {
|
||||
RootTransform.gameObject.SetActive(false);
|
||||
_currentStateName = Identifier.Empty;
|
||||
_currentState = null;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
PdtEvaluator.Instance.ContextEvent = _ctxev;
|
||||
PdtEvaluator.Instance.ContextState = _ctxstate;
|
||||
EnterState(_currentState.next, EndTime, _currentTarget, false);
|
||||
PdtEvaluator.Instance.ContextEvent = null;
|
||||
PdtEvaluator.Instance.ContextState = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public void Dispose() {
|
||||
GameObject.Destroy(RootTransform.gameObject);
|
||||
}
|
||||
|
||||
public string TypeName { get { throw new InvalidOperationException("Type name undefined"); } }
|
||||
public SkinContext SkinContext { get; private set; }
|
||||
public int AtAnchorDynamicLevel { get { return 1; } }
|
||||
public int OpenedAnchorName { get { return _currentStateName.Key; } }
|
||||
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<Anchor> 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());
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user