port from perforce

This commit is contained in:
2026-04-18 22:31:51 +02:00
commit 8d0ab5b7cc
8409 changed files with 3972376 additions and 0 deletions

View File

@@ -0,0 +1,164 @@
using System.Collections.Generic;
namespace Aiwaz.Common.Animations
{
struct AnimationInterval
{
public AnimationInterval(double argBegin, double argEnd)
{
begin = argBegin;
end = argEnd;
}
public double begin;
public double end;
}
class ForwardComparer : IComparer<AnimationInterval>
{
public int Compare(AnimationInterval a, AnimationInterval b)
{
return a.begin < b.begin ? -1 : (a.begin > b.begin ? 1 : 0);
}
}
class BackwardComparer : IComparer<AnimationInterval>
{
public int Compare(AnimationInterval a, AnimationInterval b)
{
return a.end > b.end ? -1 : (a.end > b.end ? 1 : 0);
}
}
public static class AnimationManager
{
private static SortedList<AnimationInterval, List<Pair<Animation, uint>>> forwardSortedAnimations = new SortedList<AnimationInterval, List<Pair<Animation, uint>>>(new ForwardComparer());
private static SortedList<AnimationInterval, List<Pair<Animation, uint>>> backwardSortedAnimations = new SortedList<AnimationInterval, List<Pair<Animation, uint>>>(new BackwardComparer());
private static SortedList<AnimationInterval, List<Pair<Animation, uint>>> realTimeAnimations = new SortedList<AnimationInterval, List<Pair<Animation, uint>>>(new ForwardComparer());
private static SortedList<double, List<Pair<Event, uint>>> demoTimeEvents = new SortedList<double, List<Pair<Event, uint>>>();
private static SortedList<double, List<Pair<Event, uint>>> realTimeEvents = new SortedList<double, List<Pair<Event, uint>>>();
private static double previousDemoTime;
private static double previousRealTime;
public static void AddDemoTimeAnimation(double argBeginTime, double argEndTime, Animation argAnimation, uint argUserData)
{
forwardSortedAnimations[new AnimationInterval(argBeginTime, argEndTime)].Add(new Pair<Animation, uint>(argAnimation, argUserData));
backwardSortedAnimations[new AnimationInterval(argBeginTime, argEndTime)].Add(new Pair<Animation, uint>(argAnimation, argUserData));
}
public static void AddRealTimeAnimation(double argBeginTime, double argEndTime, Animation argAnimation, uint argUserData)
{
realTimeAnimations[new AnimationInterval(argBeginTime, argEndTime)].Add(new Pair<Animation, uint>(argAnimation, argUserData));
}
public static void AddDemoTimeEvent(double argTime, Event argEvent, uint argUserData)
{
demoTimeEvents[argTime].Add(new Pair<Event, uint>(argEvent, argUserData));
}
public static void AddRealTimeEvent(double argTime, Event argEvent, uint argUserData)
{
realTimeEvents[argTime].Add(new Pair<Event, uint>(argEvent, argUserData));
}
public static void Animate()
{
double demoTime = Timeline.DemoTime;
double realTime = Timeline.RealTime;
// Gather all active animations, they are the ones that started before now and end after now.
// Do this for both the demo time and real time.
List<Pair<Pair<Animation, uint>, double>> lk_ActiveAnimations = new List<Pair<Pair<Animation, uint>, double>>();
// Demo time animations: Demo time can go backwards, so search from both directions
if (Timeline.SpeedAndDirection > 0)
{
foreach (var entry in forwardSortedAnimations)
{
if (entry.Key.begin <= demoTime && entry.Key.end >= demoTime)
{
foreach (var animation in entry.Value)
{
lk_ActiveAnimations.Add(new Pair<Pair<Animation, uint>, double>(animation, (demoTime - entry.Key.begin) / (entry.Key.end - entry.Key.begin)));
}
}
if (entry.Key.begin > demoTime)
break;
}
}
else if (Timeline.SpeedAndDirection < 0)
{
foreach (var entry in backwardSortedAnimations)
{
if (entry.Key.end >= demoTime && entry.Key.begin <= demoTime)
{
foreach (var animation in entry.Value)
{
lk_ActiveAnimations.Add(new Pair<Pair<Animation, uint>, double>(animation, (demoTime - entry.Key.begin) / (entry.Key.end - entry.Key.begin)));
}
}
if (entry.Key.end < demoTime)
break;
}
}
// Real time animations: The time that we know doesn't allow us to travel to the past, so just check into the future:
foreach (var entry in realTimeAnimations)
{
if (entry.Key.begin <= demoTime && entry.Key.end >= demoTime)
{
foreach (var animation in entry.Value)
{
lk_ActiveAnimations.Add(new Pair<Pair<Animation, uint>, double>(animation, (demoTime - entry.Key.begin) / (entry.Key.end - entry.Key.begin)));
}
}
if (entry.Key.begin > demoTime)
break;
}
// Now that we know what animations correspond to this time, animate them!
foreach (var anim in lk_ActiveAnimations)
{
anim.First.First.Animate(anim.Second, anim.First.Second);
}
// Fire all events that happened since last time:
foreach (var entry in demoTimeEvents)
{
double time = entry.Key;
foreach (var evt in entry.Value)
{
if ((Timeline.SpeedAndDirection > 0) && (time >= previousDemoTime && time <= demoTime))
{
evt.First.Do(evt.Second);
}
else if ((Timeline.SpeedAndDirection < 0) && (time <= previousDemoTime && time >= demoTime))
{
evt.First.Undo(evt.Second);
}
}
}
foreach (var entry in realTimeEvents)
{
double time = entry.Key;
foreach (var evt in entry.Value)
{
if (time >= previousDemoTime && time <= demoTime)
{
evt.First.Do(evt.Second);
}
}
}
previousDemoTime = demoTime;
previousRealTime = realTime;
}
}
}