Restructure event/container system.

This commit is contained in:
2023-01-31 15:53:43 +08:00
parent 9700992c3a
commit a1ce459a0e
9 changed files with 241 additions and 223 deletions

View File

@@ -3,6 +3,7 @@
using Cryville.Common;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace Cryville.Crtr.Event {
@@ -16,9 +17,7 @@ namespace Cryville.Crtr.Event {
public Dictionary<EventContainer, ContainerState> Children
= new Dictionary<EventContainer, ContainerState>();
readonly HashSet<EventContainer> WorkingChildren
= new HashSet<EventContainer>();
readonly HashSet<EventContainer> InvalidatedChildren
HashSet<EventContainer> ActiveChildren
= new HashSet<EventContainer>();
public Dictionary<Type, List<ContainerState>> TypedChildren
= new Dictionary<Type, List<ContainerState>>();
@@ -30,26 +29,45 @@ namespace Cryville.Crtr.Event {
return Children[ev];
}
void NotifyWorkingChanged(EventContainer key) {
InvalidatedChildren.Add(key);
}
void ValidateChildren() {
foreach (var cev in InvalidatedChildren)
if (Children[cev].Working && !WorkingChildren.Contains(cev)) WorkingChildren.Add(cev);
else if (!Children[cev].Working && WorkingChildren.Contains(cev)) WorkingChildren.Remove(cev);
InvalidatedChildren.Clear();
}
public bool Active { get; set; }
private bool m_Working;
public bool Working {
get { return m_Working; }
set {
m_Working = value;
if (Parent != null) Parent.NotifyWorkingChanged(Container);
Bus.NotifyWorkingChanged(this);
private bool m_active;
public bool Active {
get { return m_active; }
private set {
if (m_active == value) return;
m_active = value;
if (!m_active && CloneType == 1) Dispose();
if (Parent != null) {
if (m_active) Parent.ActiveChildren.Add(Container);
else Parent.ActiveChildren.Remove(Container);
}
Bus.NotifyActiveChanged(this);
}
}
private bool m_lActive;
public bool LogicalActive {
get { return m_lActive; }
set {
if (m_lActive == value) return;
m_lActive = value;
UpdateActive();
if (m_lActive) Handler.StartLogicalUpdate(this);
else Handler.EndLogicalUpdate(this);
}
}
private bool m_pActive;
public bool PhysicalActive {
get { return m_pActive; }
set {
if (m_pActive == value) return;
m_pActive = value;
UpdateActive();
if (m_pActive) Handler.StartPhysicalUpdate(this);
else Handler.EndPhysicalUpdate(this);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void UpdateActive() { Active = m_lActive || m_pActive; }
public byte CloneType;
public ContainerState rootPrototype = null;
private ContainerState prototype = null;
@@ -112,6 +130,8 @@ namespace Cryville.Crtr.Event {
AddChild(child.Key, cc, r);
}
r.ActiveChildren = new HashSet<EventContainer>();
var pms = new Dictionary<StampedEvent, RealtimeMotionValue>(Math.Max(4, PlayingMotions.Count));
foreach (var m in PlayingMotions)
pms.Add(m.Key, m.Value);
@@ -128,7 +148,10 @@ namespace Cryville.Crtr.Event {
}
public void CopyTo(byte ct, ContainerState dest) {
dest.Working = Working;
dest.m_lActive = m_lActive;
dest.m_pActive = m_pActive;
dest.m_active = m_active;
if (dest.m_active) dest.Bus.NotifyActiveChanged(dest);
foreach (var mv in Values) {
RealtimeMotionValue dv;
@@ -145,11 +168,15 @@ namespace Cryville.Crtr.Event {
cv.Value.CopyTo(dv);
}
if (ct != 1) foreach (var cev in WorkingChildren)
foreach (var cev in dest.ActiveChildren) {
if (!ActiveChildren.Contains(cev))
Children[cev].CopyTo(ct, dest.Children[cev]);
}
dest.ActiveChildren.Clear();
foreach (var cev in ActiveChildren) {
dest.ActiveChildren.Add(cev);
Children[cev].CopyTo(ct, dest.Children[cev]);
else foreach (var child in Children)
child.Value.CopyTo(ct, dest.Children[child.Key]);
dest.ValidateChildren();
}
dest.PlayingMotions.Clear();
foreach (var m in PlayingMotions) dest.PlayingMotions.Add(m.Key, m.Value);
@@ -312,9 +339,9 @@ namespace Cryville.Crtr.Event {
bool breakflag = false;
public void Break() {
Handler.EndUpdate(this);
// Handler.EndLogicalUpdate(this);
breakflag = true;
Working = false;
// LogicalActive = false;
}
public void Discard(StampedEvent ev) {
@@ -339,33 +366,26 @@ namespace Cryville.Crtr.Event {
else if (ev.Unstamped is EventContainer) {
var cev = (EventContainer)ev.Unstamped;
var ccs = GetChild(cev);
ccs.Working = true;
ccs.StartUpdate();
ccs.LogicalActive = true;
UpdateMotions();
if (!cev.IsLong) {
ccs.Working = false;
ccs.BroadcastEndUpdate();
if (CloneType == 1) ccs.Dispose();
ccs.LogicalActive = false;
}
}
else if (ev.Unstamped is InstantEvent) {
var tev = (InstantEvent)ev.Unstamped;
if (tev.IsRelease) {
var nev = tev.Original;
if (nev is Chart.Motion) {
Update(ev);
var mv = PlayingMotions[ev.Origin];
if (mv.CloneTypeFlag == CloneType) RMVPool.Return(mv);
PlayingMotions.Remove(ev.Origin);
}
else if (nev is EventContainer) {
var cev = (EventContainer)ev.Origin.Unstamped;
var ccs = GetChild(cev);
UpdateMotions();
ccs.Working = false;
ccs.BroadcastEndUpdate();
if (CloneType == 1) ccs.Dispose();
}
else if (ev.Unstamped is ReleaseEvent) {
var tev = (ReleaseEvent)ev.Unstamped;
var nev = tev.Original;
if (nev is Chart.Motion) {
Update(ev);
var mv = PlayingMotions[ev.Origin];
if (mv.CloneTypeFlag == CloneType) RMVPool.Return(mv);
PlayingMotions.Remove(ev.Origin);
}
else if (nev is EventContainer) {
var cev = (EventContainer)ev.Origin.Unstamped;
var ccs = GetChild(cev);
UpdateMotions();
ccs.LogicalActive = false;
}
}
Update(ev.Unstamped == null || ev.Unstamped.Priority >= 0 ? ev : null);
@@ -373,12 +393,10 @@ namespace Cryville.Crtr.Event {
else Update(null);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Update(StampedEvent ev) {
UpdateMotions();
if (ev == null || ev.Unstamped != null) Handler.Update(this, ev);
else Handler.ExUpdate(this, ev);
foreach (var m in PlayingMotions)
Handler.MotionUpdate(CloneType, (Chart.Motion)m.Key.Unstamped);
Handler.Update(this, ev);
}
private void UpdateMotions() {
@@ -423,14 +441,17 @@ namespace Cryville.Crtr.Event {
}
}
public void StartUpdate() {
Handler.StartUpdate(this);
public void EndPreGraphicalUpdate() {
Handler.SetPreGraphicalActive(false, this);
foreach (var ls in ActiveChildren) {
Children[ls].EndPreGraphicalUpdate();
}
}
public void BroadcastEndUpdate() {
Handler.EndUpdate(this);
foreach (var ls in Children.Values) {
if (ls.Working) ls.BroadcastEndUpdate();
public void EndGraphicalUpdate() {
Handler.SetGraphicalActive(false, this);
foreach (var ls in ActiveChildren) {
Children[ls].EndGraphicalUpdate();
}
}