Пример #1
0
        public async Task NextFrame()
        {
            // PrevInteractedElement = InteractedElement;
            const int elmtsToTriggerCleanup = 100;
            const int elmtsToCleanup        = 50;

            var undrawnElements = ImElements.Values.Where(elmt => elmt.ImState == ImElement.State.NotDrawn)
                                  .Take(elmtsToTriggerCleanup).ToList();

            if (undrawnElements.Count == elmtsToTriggerCleanup)
            {
                foreach (var elmt in undrawnElements.Take(elmtsToCleanup))
                {
                    elmt.Unsubber(elmt.WpfElement, elmt.Handler);
                    ImElements.Remove(elmt.ID);
                }
            }

            InteractedElementId = null;
            WpfElement[] sortedWpfElements = ImElements.Values.Where(x => x.ImState == ImElement.State.Drawn)
                                             .OrderBy(c => c.SortKey).Select(c => c.WpfElement).ToArray();
            var wpfElementsChanged = DisplayedElements.Count != sortedWpfElements.Length ||
                                     !Enumerable.Zip(
                DisplayedElements.OfType <WpfElement>(),
                sortedWpfElements,
                (c1, c2) => c1 == c2).All(b => b);

            if (wpfElementsChanged)
            {
                DisplayedElements.Clear();
                foreach (var item in sortedWpfElements)
                {
                    DisplayedElements.Add(item);
                }
            }

            // Automatically go to next frame for each requested redraw
            if (RemainingRedraws <= 0)
            {
                RemainingRedraws = 0;
                await TCS.Task;
                TCS = new TaskCompletionSource <bool>();
            }
            else
            {
                RemainingRedraws--;
            }

            foreach (var elmt in ImElements.Values)
            {
                elmt.ImState = ImElement.State.NotDrawn;
                elmt.SortKey = 999999;
            }
        }
Пример #2
0
        ///// <summary>
        ///// If the point is in a hall, just return it. Else, move the point so that it is
        ///// inside the nearest hall.
        ///// </summary>
        ///// <param name="p"></param>
        ///// <returns></returns>
        //public Point RebasePointToHall(Point testPoint)
        //{
        //    // We have the hall outlines, 

        //    Tuple<Point, double> prevNearestWall = null;
        //    foreach (var x in elements.Where(p => p.IsHall.Value))
        //    {
        //        var nearestWall = x.GetClosestWallIntersection(testPoint);
        //        if (nearestWall.Item2 <= 0)
        //        {
        //            return testPoint;
        //        }
        //        else if (prevNearestWall == null || nearestWall.Item2 < prevNearestWall.Item2)
        //        {
        //            prevNearestWall = nearestWall;
        //        }
        //    }

        //    return prevNearestWall.Item1;
        //}

        //public Point? GetRoomLocation(int room)
        //{
        //    Point loc;
        //    return (RoomLocations.TryGetValue(room, out loc) ? (Point?)loc : null);
        //}

        public async Task Render(UIElementCollection childCollection, Transform textRotation,
            Action<BoundingRectangle, double, double> mapBounds,
            Func<Action, Task> dispatcher, RoomInfo location,
            FrameworkElement overlay)
        {
            // Use the whole object to allow the overlay to render in the meantime.
            if (overlay.ActualWidth == 0 || overlay.ActualHeight == 0)
            {
#if NETFX_CORE
                EventHandler<object> foo = null;
                foo = (object sender, object e) =>
#else
                EventHandler foo = null;
                foo = (object sender, EventArgs e) =>
#endif
                {
                    mapBounds(buildingBounds, overlay.ActualWidth, overlay.ActualHeight);
                    overlay.LayoutUpdated -= foo;
                };
                overlay.LayoutUpdated += foo;
            }
            else
            {
                await dispatcher(() => mapBounds(buildingBounds, overlay.ActualWidth, overlay.ActualHeight));
            }

            // Do the rooms first
            foreach (var description in elements
                .Where(p => p.Parent == ParentType.Labels || p.Parent == ParentType.Rooms)
                .Where(p => p.Type != ElementType.Text))
            {
                await this.checkRunActions(50, () => RenderElement(childCollection, textRotation, description), dispatcher);
            }

            // Then the text on top
            foreach (var description in elements
                .Where(p => p.Parent == ParentType.Labels || p.Parent == ParentType.Rooms)
                .Where(p => p.Type == ElementType.Text))
            {
                await this.checkRunActions(50, () => RenderElement(childCollection, textRotation, description), dispatcher);
            }

            // Highlight the correct room
            await this.checkRunActions(1, () =>
               {
                   var roomElement = childCollection.OfType<Path>().FirstOrDefault(p => ToInt(p.Tag as string) == location.Room);
                   if (roomElement != null)
                   {
                       roomElement.Fill = new SolidColorBrush(Colors.Magenta);
                   }
               }, dispatcher);

            foreach (var description in elements.Where(p => p.Parent == ParentType.Background))
            {
                // Fewer because these paths are more complex
                //   await this.checkRunActions(50, () => RenderElement(childCollection, textRotation, description), dispatcher);
            }

            await this.checkRunActions(0, () => { }, dispatcher);
        }