diff --git a/OpenRA.FileFormats/Primitives/ActionQueue.cs b/OpenRA.FileFormats/Primitives/ActionQueue.cs index 6396085d8d..e88c87fa9f 100644 --- a/OpenRA.FileFormats/Primitives/ActionQueue.cs +++ b/OpenRA.FileFormats/Primitives/ActionQueue.cs @@ -18,23 +18,45 @@ namespace OpenRA.FileFormats public class ActionQueue { object syncRoot = new object(); - Action actions = () => { }; + PriorityQueue actions = new PriorityQueue(); - public void Add(Action a) + public void Add(Action a) { Add(a, 0); } + public void Add(Action a, int delay) { lock (syncRoot) - actions += a; + actions.Add(new DelayedAction(a, Environment.TickCount + delay)); } public void PerformActions() { - Action a; + Action a = () => {}; lock (syncRoot) { - a = actions; - actions = () => { }; + var t = Environment.TickCount; + while (!actions.Empty && actions.Peek().Time <= t) + { + var da = actions.Pop(); + a += da.Action; + } } a(); } } + + struct DelayedAction : IComparable + { + public int Time; + public Action Action; + + public DelayedAction(Action action, int time) + { + Action = action; + Time = time; + } + + public int CompareTo(DelayedAction other) + { + return Math.Sign(Time - other.Time); + } + } } diff --git a/OpenRA.FileFormats/Primitives/PriorityQueue.cs b/OpenRA.FileFormats/Primitives/PriorityQueue.cs index cffe23a32a..75d3d7423e 100644 --- a/OpenRA.FileFormats/Primitives/PriorityQueue.cs +++ b/OpenRA.FileFormats/Primitives/PriorityQueue.cs @@ -62,6 +62,7 @@ namespace OpenRA.FileFormats return At(lastLevel, lastIndex); } + public T Peek() { return At(0,0); } public T Pop() { if (level == 0 && index == 0) diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index a01943d2e7..5dc3685f41 100755 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -123,8 +123,9 @@ namespace OpenRA }, parent, id); } - static ActionQueue afterTickActions = new ActionQueue(); - public static void RunAfterTick(Action a) { afterTickActions.Add(a); } + static ActionQueue delayedActions = new ActionQueue(); + public static void RunAfterTick(Action a) { delayedActions.Add(a); } + public static void RunAfterDelay(int delay, Action a) { delayedActions.Add(a, delay); } static void Tick( OrderManager orderManager, Viewport viewPort ) { @@ -150,7 +151,7 @@ namespace OpenRA PerfHistory.items["render_widgets"].Tick(); PerfHistory.items["render_flip"].Tick(); - afterTickActions.PerformActions(); + delayedActions.PerformActions(); } static void Tick( OrderManager orderManager ) diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs b/OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs index 45892e6f95..fb7bac7120 100644 --- a/OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs +++ b/OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs @@ -36,15 +36,13 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic { Sound.Play("batlcon1.aud"); resumeDisabled = true; - world.WorldActor.QueueActivity(new Wait(30)); - world.WorldActor.QueueActivity(new CallFunc(() => mpe.Fade(CncMenuPaletteEffect.EffectType.Black))); - world.WorldActor.QueueActivity(new Wait(mpe.Info.FadeLength)); - world.WorldActor.QueueActivity(new CallFunc(() => + Game.RunAfterDelay(1200, () => mpe.Fade(CncMenuPaletteEffect.EffectType.Black)); + Game.RunAfterDelay(1200 + 40 * mpe.Info.FadeLength, () => { Game.Disconnect(); Widget.ResetAll(); Game.LoadShellMap(); - })); + }); }; Action doNothing = () => {};