Implement coevent.

This commit is contained in:
2023-01-09 16:28:36 +08:00
parent 0a1e512f41
commit 4e851d9b73
3 changed files with 59 additions and 23 deletions

View File

@@ -10,11 +10,13 @@ namespace Cryville.Crtr.Event {
private set;
}
ContainerState RootState;
/// <summary>
/// event => the container state that handles the event
/// </summary>
readonly Dictionary<ChartEvent, ContainerState> table
readonly Dictionary<ChartEvent, ContainerState> containerMap
= new Dictionary<ChartEvent, ContainerState>();
readonly Dictionary<ChartEvent, StampedEvent> map
= new Dictionary<ChartEvent, StampedEvent>();
public Dictionary<EventContainer, List<StampedEvent>> coeventMap
= new Dictionary<EventContainer, List<StampedEvent>>();
public HashSet<ChartEvent> coevents = new HashSet<ChartEvent>();
public List<StampedEvent> stampedEvents = new List<StampedEvent>();
readonly List<EventBatch> batches = new List<EventBatch>();
@@ -41,16 +43,17 @@ namespace Cryville.Crtr.Event {
}
foreach (var ev in c.Events) {
if (ev.time == null) {
coevents.Add(ev);
ev.time = c.time;
if (ev is EventContainer)
ev.endtime = c.endtime;
}
if (ev.IsLong) {
events.Add(ev.ReleaseEvent);
table.Add(ev.ReleaseEvent, cs);
containerMap.Add(ev.ReleaseEvent, cs);
}
events.Add(ev);
table.Add(ev, cs);
containerMap.Add(ev, cs);
if (ev is EventContainer)
AddEventContainer((EventContainer)ev, cs);
}
@@ -69,7 +72,7 @@ namespace Cryville.Crtr.Event {
beat = ebeat;
foreach (var ev in batch) {
EventContainer con = null;
if (table.ContainsKey(ev)) con = table[ev].Container;
if (containerMap.ContainsKey(ev)) con = containerMap[ev].Container;
var sev = new StampedEvent() {
Time = etime,
Unstamped = ev,
@@ -77,11 +80,19 @@ namespace Cryville.Crtr.Event {
};
if (ev is InstantEvent) {
var tev = (InstantEvent)ev;
var pev = stampedEvents.First(tpev => tpev.Unstamped == tev.Original);
var pev = map[tev.Original];
pev.Subevents.Add(sev);
sev.Origin = pev;
}
stampedEvents.Add(sev);
if (con != null && coevents.Contains(ev)) {
List<StampedEvent> cevs;
if (!coeventMap.TryGetValue(con, out cevs)) {
coeventMap.Add(con, cevs = new List<StampedEvent>());
}
cevs.Add(sev);
}
else stampedEvents.Add(sev);
map.Add(ev, sev);
if (ev is Chart.Signature) {
var tev = (Chart.Signature)ev;
if (tev.tempo != null) tempo = (float)tev.tempo;
@@ -110,16 +121,7 @@ namespace Cryville.Crtr.Event {
}
public EventBus Batch() {
stampedEvents.Sort((a, b) => {
int u = a.CompareTo(b);
if (u != 0) return u;
if (a.Unstamped != null && b.Unstamped != null)
if (table.ContainsKey(a.Unstamped) && table.ContainsKey(b.Unstamped)) {
u = table[a.Unstamped].Depth.CompareTo(table[b.Unstamped].Depth);
if (u != 0) return u;
}
return a.GetHashCode().CompareTo(b.GetHashCode());
});
stampedEvents.Sort(CompareStampedEvents);
var cb = new EventBatch(stampedEvents[0].Time);
foreach (var ev in stampedEvents) {
if (ev.Time != cb.Time) {
@@ -127,10 +129,37 @@ namespace Cryville.Crtr.Event {
cb = new EventBatch(ev.Time);
}
cb.Enqueue(ev);
BatchCoevents(ev);
}
batches.Add(cb);
Bus = new EventBus(chart, RootState, batches);
return Bus;
}
void BatchCoevents(StampedEvent ev, List<StampedEvent> ocevs = null) {
if (!(ev.Unstamped is EventContainer)) return;
List<StampedEvent> cevs;
if (coeventMap.TryGetValue((EventContainer)ev.Unstamped, out cevs)) {
var rootFlag = ocevs == null;
if (rootFlag) ev.Coevents = ocevs = new List<StampedEvent>();
foreach (var cev in cevs) {
ocevs.Add(cev);
BatchCoevents(cev, ocevs);
}
ocevs.Add(ev);
if (rootFlag) ocevs.Sort(CompareStampedEvents);
}
}
int CompareStampedEvents(StampedEvent a, StampedEvent b) {
int u = a.CompareTo(b);
if (u != 0) return u;
if (a.Unstamped != null && b.Unstamped != null)
if (containerMap.ContainsKey(a.Unstamped) && containerMap.ContainsKey(b.Unstamped)) {
u = containerMap[a.Unstamped].Depth.CompareTo(containerMap[b.Unstamped].Depth);
if (u != 0) return u;
}
return a.GetHashCode().CompareTo(b.GetHashCode());
}
}
}

View File

@@ -119,9 +119,16 @@ namespace Cryville.Crtr.Event {
var batch = events[EventId];
for (var i = 0; i < batch.Count; i++) {
var ev = batch[i];
if (ev.Container != null) {
EnsureActivity(ev.Container);
states[ev.Container].Handle(ev);
if (ev.Coevents == null) {
if (ev.Container != null) {
EnsureActivity(ev.Container);
states[ev.Container].Handle(ev);
}
}
else foreach (var cev in ev.Coevents) {
if (cev.Container == null) continue;
EnsureActivity(cev.Container);
states[cev.Container].Handle(cev);
}
if (ev.Unstamped is EventContainer) {
if (ev.Container != null) EnsureActivity((EventContainer)ev.Unstamped);

View File

@@ -9,7 +9,7 @@ namespace Cryville.Crtr {
public EventContainer Container;
public StampedEvent Origin;
public List<StampedEvent> Subevents = new List<StampedEvent>();
private StampedEvent attev = null;
public List<StampedEvent> Coevents;
private StampedEvent relev = null;
public double Duration {