From e109e0bd2424be5c09af1b9b0b32d860b0838c8a Mon Sep 17 00:00:00 2001 From: PopSlime Date: Tue, 31 Jan 2023 15:15:13 +0800 Subject: [PATCH] Separate dynamic anchors. --- .../Cryville/Crtr/Event/ContainerHandler.cs | 90 ++++++++++--------- Assets/Cryville/Crtr/NoteHandler.cs | 2 +- Assets/Cryville/Crtr/SkinPropertyKey.cs | 2 +- 3 files changed, 52 insertions(+), 42 deletions(-) diff --git a/Assets/Cryville/Crtr/Event/ContainerHandler.cs b/Assets/Cryville/Crtr/Event/ContainerHandler.cs index edb8282..8f985c2 100644 --- a/Assets/Cryville/Crtr/Event/ContainerHandler.cs +++ b/Assets/Cryville/Crtr/Event/ContainerHandler.cs @@ -8,6 +8,7 @@ using UnityEngine; namespace Cryville.Crtr.Event { public abstract class ContainerHandler { + #region Struct public ContainerHandler() { } public abstract string TypeName { get; } @@ -60,6 +61,7 @@ namespace Cryville.Crtr.Event { } public readonly Dictionary> Anchors = new Dictionary>(); + public readonly Dictionary DynamicAnchors = new Dictionary(); public Anchor OpenedAnchor; protected Anchor a_cur; protected Anchor a_head; @@ -67,29 +69,42 @@ namespace Cryville.Crtr.Event { 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); - } - public Anchor RegisterAnchor(int name, int propSrcCount = 0) { - var go = new GameObject("." + IdentifierManager.SharedInstance.Retrieve(name)).transform; + public Anchor RegisterAnchor(int name, bool dyn = false, int propSrcCount = 0) { + var strname = IdentifierManager.SharedInstance.Retrieve(name); + var go = new GameObject("." + strname).transform; go.SetParent(gogroup, false); var result = new Anchor(name, go, propSrcCount); + if (dyn) { + if (DynamicAnchors.ContainsKey(name)) + throw new ArgumentException(string.Format("The anchor \"{0}\" already exists", strname)); + DynamicAnchors.Add(name, result); + } List list; if (!Anchors.TryGetValue(name, out list)) Anchors.Add(name, list = new List()); list.Add(result); return result; } + protected void OpenAnchor(Anchor anchor) { + if (OpenedAnchor != null) throw new InvalidOperationException("An anchor has been opened"); + OpenedAnchor = anchor; + } + protected void CloseAnchor() { + OpenedAnchor = null; + } + #endregion - /// + #region Logic /// Called upon StartUpdate of ps 17. - /// + 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, true); + a_tail = RegisterAnchor(_a_tail, true); + } public virtual void Init() { skinContainer.MatchStatic(ps); foreach (var i in gogroup.GetComponentsInChildren()) @@ -126,28 +141,6 @@ namespace Cryville.Crtr.Event { Init(); } } - static readonly SimpleObjectPool anchorEvPool - = new SimpleObjectPool(1024); - public void PushAnchorEvent(double time, int name) { - List anchors; - if (!Anchors.TryGetValue(name, out anchors)) - throw new ArgumentException(string.Format("Specified anchor \"{0}\" not found", IdentifierManager.SharedInstance.Retrieve(name))); - if (anchors.Count != 1) - throw new InvalidOperationException(string.Format("Cannot set a static anchor \"{0}\"", IdentifierManager.SharedInstance.Retrieve(name))); - PushAnchorEvent(time, anchors[0]); - } - 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 Discard(ContainerState s, StampedEvent ev) { - if (ev is StampedEvent.Anchor) { - anchorEvPool.Return((StampedEvent.Anchor)ev); - } - } public virtual void Update(ContainerState s, StampedEvent ev) { bool flag = !Awoken && s.CloneType >= 2 && s.CloneType < 16; if (flag) PreAwake(s); @@ -182,16 +175,33 @@ namespace Cryville.Crtr.Event { } } } + #region Anchor public virtual void Anchor() { skinContainer.MatchDynamic(cs); if (cs.Working) PushAnchorEvent(cs.Time, a_cur); + static readonly SimpleObjectPool anchorEvPool + = new SimpleObjectPool(1024); + public void PushAnchorEvent(double time, int name) { + Anchor anchor; + if (!DynamicAnchors.TryGetValue(name, out anchor)) + throw new ArgumentException(string.Format("Specified anchor \"{0}\" not found", IdentifierManager.SharedInstance.Retrieve(name))); + PushAnchorEvent(time, anchor); } - protected void OpenAnchor(Anchor anchor) { - if (OpenedAnchor != null) throw new InvalidOperationException("An anchor has been opened"); - OpenedAnchor = anchor; + void PushAnchorEvent(double time, Anchor anchor, int priority = 0, bool forced = false) { + var tev = anchorEvPool.Rent(); + tev.Time = time; + tev.Container = Container; + tev.Target = anchor; + tev.CanDiscard = !forced; + tev.SetPriority(priority); + ts.Bus.PushTempEvent(tev); } - protected void CloseAnchor() { - OpenedAnchor = null; + public virtual void Discard(ContainerState s, StampedEvent ev) { + if (ev is StampedEvent.Anchor) { + anchorEvPool.Return((StampedEvent.Anchor)ev); + } } + #endregion + #endregion } } diff --git a/Assets/Cryville/Crtr/NoteHandler.cs b/Assets/Cryville/Crtr/NoteHandler.cs index 4f1bffd..b0f9dba 100644 --- a/Assets/Cryville/Crtr/NoteHandler.cs +++ b/Assets/Cryville/Crtr/NoteHandler.cs @@ -31,7 +31,7 @@ namespace Cryville.Crtr { public int Result { get; private set; } PropSrc _resultPropSrc; public JudgeState(NoteHandler handler, int name) { - StaticAnchor = handler.RegisterAnchor(handler.judge.judgeMap[name], 3); + StaticAnchor = handler.RegisterAnchor(handler.judge.judgeMap[name], false, 3); } public void MarkJudged(float abs, float rel, int result) { AbsoluteTime = abs; diff --git a/Assets/Cryville/Crtr/SkinPropertyKey.cs b/Assets/Cryville/Crtr/SkinPropertyKey.cs index 3c24d65..a6f511f 100644 --- a/Assets/Cryville/Crtr/SkinPropertyKey.cs +++ b/Assets/Cryville/Crtr/SkinPropertyKey.cs @@ -68,7 +68,7 @@ namespace Cryville.Crtr { } public override bool IsValueRequired { get { return false; } } public override void ExecuteStatic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) { - state.Handler.RegisterAnchor(Name); + state.Handler.RegisterAnchor(Name, true); } public override void ExecuteDynamic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) { throw new InvalidOperationException("Anchor creation in dynamic context is not allowed");