Files
crtr/Assets/Cryville/Crtr/Event/ContainerHandler.cs
2022-12-23 16:28:48 +08:00

165 lines
5.0 KiB
C#

using Cryville.Common;
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>
public Transform gogroup;
public readonly Dictionary<int, Anchor> Anchors = new Dictionary<int, Anchor>();
protected Transform a_cur;
protected Transform a_head;
protected Transform a_tail;
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;
}
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;
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 Transform RegisterAnchor(int name) {
var go = new GameObject("." + IdentifierManager.SharedInstance.Retrieve(name)).transform;
go.SetParent(gogroup, false);
Anchors.Add(name, new Anchor() { Transform = go });
return go;
}
/// <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);
Awoken = true; Alive = true;
OpenAnchor(_a_head);
}
protected virtual void Awake(ContainerState s) {
CloseAnchor(_a_head);
}
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();
}
}
public virtual void Update(ContainerState s, StampedEvent ev) {
bool flag = !Awoken && s.CloneType >= 2 && s.CloneType < 16;
if (flag) PreAwake(s);
if (s.CloneType == 0) {
ts.Bus.PushTempEvent(new StampedEvent.Anchor { Time = s.Time, Container = s.Container, Name = _a_cur });
}
if (s.CloneType <= 2) if (gogroup) skinContainer.MatchDynamic(s);
if (flag) Awake(s);
}
public virtual void ExUpdate(ContainerState s, StampedEvent ev) {
if (ev is StampedEvent.Anchor) { OpenAnchor(((StampedEvent.Anchor)ev).Name); }
if (s.CloneType <= 2) if (gogroup) skinContainer.MatchDynamic(s);
if (ev is StampedEvent.Anchor) { CloseAnchor(((StampedEvent.Anchor)ev).Name); }
}
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) skinContainer.MatchDynamic(s);
}
}
public virtual void Anchor() { }
protected void OpenAnchor(int name) {
if (Anchors.ContainsKey(name)) Anchors[name].Open();
}
protected void CloseAnchor(int name) {
if (Anchors.ContainsKey(name)) Anchors[name].Close();
}
}
}