185 lines
5.8 KiB
C#
185 lines
5.8 KiB
C#
using Cryville.Common;
|
|
using Cryville.Common.Buffers;
|
|
using Cryville.Crtr.Components;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using UnityEngine;
|
|
|
|
namespace Cryville.Crtr.Event {
|
|
public abstract class ContainerHandler : IDisposable {
|
|
/// <summary>
|
|
/// Prehandling <see cref="ContainerState"/>, prehandling the events.
|
|
/// </summary>
|
|
public ContainerState ps;
|
|
|
|
/// <summary>
|
|
/// Backward <see cref="ContainerState"/>, disposing events at the backward clipping plane, firing anchor state and temporary state.
|
|
/// </summary>
|
|
public ContainerState bs;
|
|
|
|
/// <summary>
|
|
/// Current <see cref="ContainerState"/>, handling events occuring at the current time.
|
|
/// </summary>
|
|
public ContainerState cs;
|
|
|
|
/// <summary>
|
|
/// Anchor <see cref="ContainerState"/>, computing the start position of the temporary state.
|
|
/// </summary>
|
|
public ContainerState ns;
|
|
|
|
/// <summary>
|
|
/// Temporary <see cref="ContainerState"/>, rendering events between the clipping planes.
|
|
/// </summary>
|
|
public ContainerState ts;
|
|
|
|
/// <summary>
|
|
/// <see cref="GameObject"/> group, the <see cref="Transform"/> containing all the generated elements in the <see cref="ContainerHandler"/>.
|
|
/// </summary>
|
|
protected Transform gogroup;
|
|
public SkinContext SkinContext;
|
|
|
|
public Vector3 Position { get; protected set; }
|
|
public Quaternion Rotation { get; protected set; }
|
|
public bool Alive { get; private set; }
|
|
public bool Awoken { get; private set; }
|
|
public bool Disposed { get; private set; }
|
|
|
|
public EventContainer Container {
|
|
get { return cs.Container; }
|
|
}
|
|
|
|
SkinContainer skinContainer;
|
|
protected Judge judge;
|
|
public void AttachSystems(PdtSkin skin, Judge judge) {
|
|
skinContainer = new SkinContainer(skin);
|
|
this.judge = judge;
|
|
}
|
|
|
|
public ContainerHandler() { }
|
|
public abstract string TypeName {
|
|
get;
|
|
}
|
|
public readonly Dictionary<int, List<Anchor>> Anchors = new Dictionary<int, List<Anchor>>();
|
|
public Anchor OpenedAnchor;
|
|
protected Anchor a_cur;
|
|
protected Anchor a_head;
|
|
protected Anchor a_tail;
|
|
protected readonly static int _a_cur = IdentifierManager.SharedInstance.Request("cur");
|
|
protected readonly static int _a_head = IdentifierManager.SharedInstance.Request("head");
|
|
protected readonly static int _a_tail = IdentifierManager.SharedInstance.Request("tail");
|
|
public virtual void PreInit() {
|
|
gogroup = new GameObject(TypeName + ":" + Container.GetHashCode().ToString(CultureInfo.InvariantCulture)).transform;
|
|
SkinContext = new SkinContext(gogroup);
|
|
if (cs.Parent != null)
|
|
gogroup.SetParent(cs.Parent.Handler.gogroup, false);
|
|
a_cur = RegisterAnchor(_a_cur);
|
|
a_head = RegisterAnchor(_a_head);
|
|
a_tail = RegisterAnchor(_a_tail);
|
|
}
|
|
protected Anchor RegisterAnchor(int name, bool hasPropSrcs = false) {
|
|
var go = new GameObject("." + IdentifierManager.SharedInstance.Retrieve(name)).transform;
|
|
go.SetParent(gogroup, false);
|
|
var result = new Anchor(name, go, hasPropSrcs);
|
|
List<Anchor> list;
|
|
if (!Anchors.TryGetValue(name, out list))
|
|
Anchors.Add(name, list = new List<Anchor>());
|
|
list.Add(result);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called upon StartUpdate of ps 17.
|
|
/// </summary>
|
|
public virtual void Init() {
|
|
skinContainer.MatchStatic(ps);
|
|
foreach (var i in gogroup.GetComponentsInChildren<SkinComponent>())
|
|
i.Init();
|
|
}
|
|
public virtual void PostInit() {
|
|
gogroup.gameObject.SetActive(false);
|
|
}
|
|
public virtual void Dispose() {
|
|
if (Disposed) return;
|
|
Disposed = true;
|
|
if (gogroup)
|
|
GameObject.Destroy(gogroup.gameObject);
|
|
// gogroup.gameObject.SetActive(false);
|
|
Alive = false;
|
|
}
|
|
protected virtual void PreAwake(ContainerState s) {
|
|
if (gogroup) {
|
|
gogroup.gameObject.SetActive(true);
|
|
OpenAnchor(a_head);
|
|
}
|
|
Awoken = true; Alive = true;
|
|
}
|
|
protected virtual void Awake(ContainerState s) {
|
|
if (gogroup) CloseAnchor();
|
|
}
|
|
protected virtual void GetPosition(ContainerState s) { }
|
|
public virtual void StartUpdate(ContainerState s) {
|
|
if (s.CloneType >= 2 && s.CloneType < 16) {
|
|
PreAwake(s);
|
|
Awake(s);
|
|
}
|
|
else if (s.CloneType == 17) {
|
|
Init();
|
|
}
|
|
}
|
|
static readonly SimpleObjectPool<StampedEvent.Anchor> anchorEvPool
|
|
= new SimpleObjectPool<StampedEvent.Anchor>(1024);
|
|
protected void PushAnchorEvent(double time, Anchor anchor) {
|
|
var tev = anchorEvPool.Rent();
|
|
tev.Time = time;
|
|
tev.Container = Container;
|
|
tev.Target = anchor;
|
|
ts.Bus.PushTempEvent(tev);
|
|
}
|
|
public virtual void Update(ContainerState s, StampedEvent ev) {
|
|
bool flag = !Awoken && s.CloneType >= 2 && s.CloneType < 16;
|
|
if (flag) PreAwake(s);
|
|
if (gogroup && s.CloneType <= 2) skinContainer.MatchDynamic(s);
|
|
if (flag) Awake(s);
|
|
}
|
|
public virtual void ExUpdate(ContainerState s, StampedEvent ev) {
|
|
if (ev is StampedEvent.Anchor) {
|
|
var tev = (StampedEvent.Anchor)ev;
|
|
if (gogroup) {
|
|
OpenAnchor(tev.Target);
|
|
#if UNITY_5_6_OR_NEWER
|
|
tev.Target.Transform.SetPositionAndRotation(Position, Rotation);
|
|
#else
|
|
tev.Target.Transform.position = GetCurrentWorldPoint();
|
|
tev.Target.Transform.rotation = Quaternion.Euler(s.Direction);
|
|
#endif
|
|
skinContainer.MatchDynamic(s);
|
|
CloseAnchor();
|
|
}
|
|
anchorEvPool.Return(tev);
|
|
}
|
|
}
|
|
public virtual void MotionUpdate(byte ct, Chart.Motion ev) { }
|
|
public virtual void EndUpdate(ContainerState s) {
|
|
if (s.CloneType < 16) {
|
|
Awoken = false;
|
|
if (gogroup && s.CloneType <= 2) {
|
|
OpenAnchor(a_tail);
|
|
skinContainer.MatchDynamic(s);
|
|
CloseAnchor();
|
|
}
|
|
}
|
|
}
|
|
public virtual void Anchor() {
|
|
if (cs.Working) PushAnchorEvent(cs.Time, a_cur);
|
|
}
|
|
protected void OpenAnchor(Anchor anchor) {
|
|
if (OpenedAnchor != null) throw new InvalidOperationException("An anchor has been opened");
|
|
OpenedAnchor = anchor;
|
|
}
|
|
protected void CloseAnchor() {
|
|
OpenedAnchor = null;
|
|
}
|
|
}
|
|
}
|