private void UpdateViewInternal() { if (HeadlessMode) { SpaceTime.ClearChanges(); return; } if (SpaceTime.AddedElements.Count == 0 && SpaceTime.ChangedElements.Count == 0 && SpaceTime.RemovedElements.Count == 0) { return; } resetHandle.Reset(); Application.InvokeNextCycle(() => { foreach (var e in SpaceTime.AddedElements) { var renderer = thingBinder.Bind(e, SpaceTime); renderers.Add(e, renderer); this.Controls.Add(renderer); SizeAndLocate(renderer); OnBind.Fire(e); renderer.OnRender(); } foreach (var e in SpaceTime.ChangedElements) { SizeAndLocate(renderers[e]); renderers[e].OnRender(); } foreach (var e in SpaceTime.RemovedElements) { var renderer = renderers[e]; renderers.Remove(e); Controls.Remove(renderer); } if (resizedSinceLastRender) { foreach (var r in renderers.Values) { SizeAndLocate(r); } } Application.Paint(); resetHandle.Set(); }); resetHandle.WaitOne(); resizedSinceLastRender = false; SpaceTime.ClearChanges(); AfterUpdate.Fire(); }
private void UpdateViewInternal(bool force) { foreach (var element in SpaceTime.AddedElements) { Application.QueueAction(() => { var renderer = thingBinder.Bind(element, SpaceTime); renderers.Add(element, renderer); this.Controls.Add(renderer); SizeAndLocate(renderer); renderer.OnRender(); }); } foreach (var t in SpaceTime.ChangedElements) { Application.QueueAction(() => { var renderer = renderers[t]; SizeAndLocate(renderer); renderer.OnRender(); }); } foreach (var t in SpaceTime.RemovedElements) { Application.QueueAction(() => { var renderer = renderers[t]; renderers.Remove(t); Controls.Remove(renderer); }); } if (force || resizedSinceLastRender) { foreach (var renderer in renderers.Values) { Application.QueueAction(() => { SizeAndLocate(renderer); }); } } resizedSinceLastRender = false; SpaceTime.ClearChanges(); Application.Paint(); }
public SpacetimePanel(int w, int h, SpaceTime time = null) { this.Width = w; this.Height = h; Background = ConsoleColor.White; renderers = new Dictionary <SpacialElement, SpacialElementRenderer>(); thingBinder = new SpacialElementBinder(); this.SpaceTime = time ?? new SpaceTime(w, h, increment: TimeSpan.FromSeconds(.05)); this.SpaceTime.QueueAction(() => { RealTimeViewing = new RealTimeViewingFunction(this.SpaceTime) { Enabled = true }; this.SpaceTime.ChangeTrackingEnabled = true; this.SpaceTime.AfterTick.SubscribeForLifetime(() => UpdateView(false), this.LifetimeManager); RealTimeViewing.Behind.SubscribeForLifetime((isBehind) => { Application?.QueueAction(() => { Background = isBehind ? ConsoleColor.DarkYellow : ConsoleColor.White; }); }, LifetimeManager); }); this.AddedToVisualTree.SubscribeForLifetime(() => { LifetimeManager.Manage(Application.SetInterval(() => { RealTimeViewing?.Evaluate(); }, TimeSpan.FromSeconds(.1))); }, this.LifetimeManager); this.SpaceTime.UnhandledException.SubscribeForLifetime((ex) => { Application?.QueueAction(() => { throw new AggregateException(ex); }); }, this.LifetimeManager); this.SubscribeForLifetime(nameof(Bounds), () => { resizedSinceLastRender = false; }, this.LifetimeManager); }
public SpaceTimePanel(int w, int h, SpaceTime time = null) { this.Width = w; this.Height = h; Background = ConsoleColor.White; renderers = new Dictionary <SpacialElement, SpacialElementRenderer>(); thingBinder = new SpacialElementBinder(); resetHandle = new AutoResetEvent(false); this.SpaceTime = time; if (this.SpaceTime == null) { this.SpaceTime = new SpaceTime(w, h, increment: TimeSpan.FromSeconds(.05)); this.OnDisposed(() => { if (this.SpaceTime.IsRunning) { this.SpaceTime.Stop(); } this.SpaceTime = null; }); } this.SpaceTime.Invoke(() => { RealTimeViewing = new RealTimeViewingFunction(this.SpaceTime) { Enabled = true }; this.SpaceTime.EndOfCycle.SubscribeForLifetime(() => UpdateViewInternal(), this); }); this.AddedToVisualTree.SubscribeForLifetime(() => { this.OnDisposed(() => resetHandle.Set()); }, this); this.SubscribeForLifetime(nameof(Bounds), () => { resizedSinceLastRender = false; }, this); }
public static HitPrediction PredictHit(SpaceTime r, SpacialElement Target, List <Type> hitDetectionTypes, List <SpacialElement> hitDetectionExclusions, float dx, float dy) { if (Math.Abs(dx) <= 1 && Math.Abs(dy) <= 1) { return(PredictHitInternal(r, Target, hitDetectionTypes, hitDetectionExclusions, dx, dy)); } HitPrediction latestResult = null; for (var i = 1; i <= 10; i++) { var dxP = Approach(0, dx, dx / 10 * i); var dyP = Approach(0, dy, dy / 10 * i); latestResult = PredictHitInternal(r, Target, hitDetectionTypes, hitDetectionExclusions, dxP, dyP); if (latestResult.Type != HitType.None) { return(latestResult); } } return(latestResult); }
public SpacialElementRenderer Bind(SpacialElement t, SpaceTime spaceTime) { if (t.Renderer != null) { t.Renderer.Element = t; t.Renderer.OnBind(); return(t.Renderer); } Type binding; if (Bindings.TryGetValue(t.GetType(), out binding) == false) { binding = typeof(SpacialElementRenderer); } SpacialElementRenderer ret = Activator.CreateInstance(binding) as SpacialElementRenderer; ret.Element = t; ret.Spacetime = spaceTime; ret.OnBind(); return(ret); }
public SpacetimePanel(int w, int h, SpaceTime time = null) { this.Width = w; this.Height = h; Background = ConsoleColor.White; renderers = new Dictionary <SpacialElement, SpacialElementRenderer>(); thingBinder = new SpacialElementBinder(); resetHandle = new AutoResetEvent(false); this.SpaceTime = time ?? new SpaceTime(w, h, increment: TimeSpan.FromSeconds(.05)); this.SpaceTime.QueueAction(() => { RealTimeViewing = new RealTimeViewingFunction(this.SpaceTime) { Enabled = true }; this.SpaceTime.ChangeTrackingEnabled = true; this.SpaceTime.AfterTick.SubscribeForLifetime(() => UpdateViewInternal(), this); }); this.AddedToVisualTree.SubscribeForLifetime(() => { this.SpaceTime.Application = this.Application; this.OnDisposed(() => resetHandle.Set()); }, this); this.SpaceTime.UnhandledException.SubscribeForLifetime((ex) => { resetHandle.Set(); Application?.QueueAction(() => { throw new AggregateException(ex); }); }, this); this.SubscribeForLifetime(nameof(Bounds), () => { resizedSinceLastRender = false; }, this); }
public static HitPrediction PredictHit(SpaceTime r, SpacialElement Target, List <Type> hitDetectionTypes, float dx, float dy) { HitPrediction prediction = new HitPrediction(); if (dx == 0 && dy == 0) { prediction.Direction = Direction.None; prediction.Type = HitType.None; return(prediction); } if (dy > 0 && Target.Bottom() + dy >= r.Height) { prediction.Direction = Direction.Down; prediction.Type = HitType.Boundary; prediction.BoundsOfItemBeingHit = Rectangular.Create(Target.Left + dx, r.Bounds.Height + dy, 1, 1); return(prediction); } else if (dx < 0 && Target.Left + dx <= 0) { prediction.Direction = Direction.Left; prediction.Type = HitType.Boundary; prediction.BoundsOfItemBeingHit = Rectangular.Create(-dx, Target.Top + dy, 1, 1); return(prediction); } else if (dy < 0 && Target.Top + dy <= 0) { prediction.Direction = Direction.Up; prediction.Type = HitType.Boundary; prediction.BoundsOfItemBeingHit = Rectangular.Create(Target.Left + dx, -dy, 1, 1); return(prediction); } else if (dx > 0 && Target.Right() + dx >= r.Width) { prediction.Direction = Direction.Right; prediction.Type = HitType.Boundary; prediction.BoundsOfItemBeingHit = Rectangular.Create(r.Width + dx, Target.Top + dy, 1, 1); return(prediction); } var testArea = Rectangular.Create(Target.Left + dx, Target.Top + dy, Target.Width, Target.Height); var match = (from t in r.Elements where t.IsOneOfThese(hitDetectionTypes) && Target != t && testArea.NumberOfPixelsThatOverlap(t) > 0 select t).OrderBy(t => t.Center().CalculateDistanceTo(Target.Center())); if (match.Count() == 0) { prediction.Direction = Direction.None; prediction.Type = HitType.None; } else { prediction.ElementHit = match.First(); prediction.Type = HitType.Element; prediction.Direction = testArea.GetHitDirection(match.First().Bounds); prediction.BoundsOfItemBeingHit = prediction.ElementHit.Bounds; } return(prediction); }