Separate dynamic anchors.

This commit is contained in:
2023-01-31 15:15:13 +08:00
parent 776a615464
commit e109e0bd24
3 changed files with 52 additions and 42 deletions

View File

@@ -8,6 +8,7 @@ using UnityEngine;
namespace Cryville.Crtr.Event { namespace Cryville.Crtr.Event {
public abstract class ContainerHandler { public abstract class ContainerHandler {
#region Struct
public ContainerHandler() { } public ContainerHandler() { }
public abstract string TypeName { get; } public abstract string TypeName { get; }
@@ -60,6 +61,7 @@ namespace Cryville.Crtr.Event {
} }
public readonly Dictionary<int, List<Anchor>> Anchors = new Dictionary<int, List<Anchor>>(); public readonly Dictionary<int, List<Anchor>> Anchors = new Dictionary<int, List<Anchor>>();
public readonly Dictionary<int, Anchor> DynamicAnchors = new Dictionary<int, Anchor>();
public Anchor OpenedAnchor; public Anchor OpenedAnchor;
protected Anchor a_cur; protected Anchor a_cur;
protected Anchor a_head; 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_cur = IdentifierManager.SharedInstance.Request("cur");
protected readonly static int _a_head = IdentifierManager.SharedInstance.Request("head"); protected readonly static int _a_head = IdentifierManager.SharedInstance.Request("head");
protected readonly static int _a_tail = IdentifierManager.SharedInstance.Request("tail"); protected readonly static int _a_tail = IdentifierManager.SharedInstance.Request("tail");
public virtual void PreInit() { public Anchor RegisterAnchor(int name, bool dyn = false, int propSrcCount = 0) {
gogroup = new GameObject(TypeName + ":" + Container.GetHashCode().ToString(CultureInfo.InvariantCulture)).transform; var strname = IdentifierManager.SharedInstance.Retrieve(name);
SkinContext = new SkinContext(gogroup); var go = new GameObject("." + strname).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);
}
public Anchor RegisterAnchor(int name, int propSrcCount = 0) {
var go = new GameObject("." + IdentifierManager.SharedInstance.Retrieve(name)).transform;
go.SetParent(gogroup, false); go.SetParent(gogroup, false);
var result = new Anchor(name, go, propSrcCount); 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<Anchor> list; List<Anchor> list;
if (!Anchors.TryGetValue(name, out list)) if (!Anchors.TryGetValue(name, out list))
Anchors.Add(name, list = new List<Anchor>()); Anchors.Add(name, list = new List<Anchor>());
list.Add(result); list.Add(result);
return 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
/// <summary> #region Logic
/// Called upon StartUpdate of ps 17. /// Called upon StartUpdate of ps 17.
/// </summary> 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() { public virtual void Init() {
skinContainer.MatchStatic(ps); skinContainer.MatchStatic(ps);
foreach (var i in gogroup.GetComponentsInChildren<SkinComponent>()) foreach (var i in gogroup.GetComponentsInChildren<SkinComponent>())
@@ -126,28 +141,6 @@ namespace Cryville.Crtr.Event {
Init(); Init();
} }
} }
static readonly SimpleObjectPool<StampedEvent.Anchor> anchorEvPool
= new SimpleObjectPool<StampedEvent.Anchor>(1024);
public void PushAnchorEvent(double time, int name) {
List<Anchor> 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) { public virtual void Update(ContainerState s, StampedEvent ev) {
bool flag = !Awoken && s.CloneType >= 2 && s.CloneType < 16; bool flag = !Awoken && s.CloneType >= 2 && s.CloneType < 16;
if (flag) PreAwake(s); if (flag) PreAwake(s);
@@ -182,16 +175,33 @@ namespace Cryville.Crtr.Event {
} }
} }
} }
#region Anchor
public virtual void Anchor() { public virtual void Anchor() {
skinContainer.MatchDynamic(cs); skinContainer.MatchDynamic(cs);
if (cs.Working) PushAnchorEvent(cs.Time, a_cur); if (cs.Working) PushAnchorEvent(cs.Time, a_cur);
static readonly SimpleObjectPool<StampedEvent.Anchor> anchorEvPool
= new SimpleObjectPool<StampedEvent.Anchor>(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) { void PushAnchorEvent(double time, Anchor anchor, int priority = 0, bool forced = false) {
if (OpenedAnchor != null) throw new InvalidOperationException("An anchor has been opened"); var tev = anchorEvPool.Rent();
OpenedAnchor = anchor; tev.Time = time;
tev.Container = Container;
tev.Target = anchor;
tev.CanDiscard = !forced;
tev.SetPriority(priority);
ts.Bus.PushTempEvent(tev);
} }
protected void CloseAnchor() { public virtual void Discard(ContainerState s, StampedEvent ev) {
OpenedAnchor = null; if (ev is StampedEvent.Anchor) {
anchorEvPool.Return((StampedEvent.Anchor)ev);
}
} }
#endregion
#endregion
} }
} }

View File

@@ -31,7 +31,7 @@ namespace Cryville.Crtr {
public int Result { get; private set; } public int Result { get; private set; }
PropSrc _resultPropSrc; PropSrc _resultPropSrc;
public JudgeState(NoteHandler handler, int name) { 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) { public void MarkJudged(float abs, float rel, int result) {
AbsoluteTime = abs; AbsoluteTime = abs;

View File

@@ -68,7 +68,7 @@ namespace Cryville.Crtr {
} }
public override bool IsValueRequired { get { return false; } } public override bool IsValueRequired { get { return false; } }
public override void ExecuteStatic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) { 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) { public override void ExecuteDynamic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
throw new InvalidOperationException("Anchor creation in dynamic context is not allowed"); throw new InvalidOperationException("Anchor creation in dynamic context is not allowed");