Beispiel #1
0
 /// <summary>
 /// Disconnect from Echelon, enabling ConnectToEchelon to be called again.
 /// </summary>
 public static void DestroyEchelonCommunicator()
 {
     if (Echelon != null)
     {
         Echelon.Disconnect();
         Echelon = null;
     }
 }
Beispiel #2
0
        /// <summary>
        /// Generate the feint dummy rendering for the passed in symbol.
        /// </summary>
        /// <param name="ms">
        /// The military symbol for which to provide the feint dummy rendering.
        /// </param>
        /// <param name="height">
        /// The height at which to provide the feint dummy rendering.
        /// </param>
        /// <returns>
        /// The graphics Path object that represents the feint dummy rendering.
        /// </returns>
        private static Path GenerateFeintDummy(MilSymbol ms, ref double height)
        {
            if (!string.IsNullOrEmpty(Echelon.GetEchelonSymbol(ms.SymbolCode)))
            {
                height = ms.Bounds.Top;
            }

            if (SymbolData.IsTopFlat(ms.SymbolCode))
            {
                double minimum = ms.BaseRect.Top;
                if (height >= minimum)
                {
                    height = minimum - 28;
                }
            }

            double bottom = height + 23;

            height = height - 27;
            const double Wide = 126;

            var st = new Style(typeof(Shape))
            {
                BasedOn = SymbolData.GetStyle("BS10")
            };

            st.SetDashArray(3, 1);

            return(new Path
            {
                Style = st,
                Data = new PathGeometry
                {
                    Figures = new PathFigureCollection
                    {
                        new PathFigure
                        {
                            StartPoint = new Point(-Wide, bottom),
                            Segments = new PathSegmentCollection
                            {
                                new LineSegment {
                                    Point = new Point(0.0, height)
                                },
                                new LineSegment {
                                    Point = new Point(Wide, bottom)
                                }
                            }
                        }
                    }
                }
            });
        }
        /// <summary>
        /// Get the combined modifier code for the coding scheme.
        /// </summary>
        /// <param name="symbolCode">the symbol code</param>
        /// <returns>a friendly name for the combined modifier code</returns>
        public static string GetName(string symbolCode)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(string.Empty);
            }

            char leadCode  = ModifierCode.GetCode(symbolCode);
            char trailCode = Echelon.GetCode(symbolCode);

            if (leadCode == ModifierCode.Mobility || leadCode == ModifierCode.Towed)
            {
                return(Mobility.GetName(symbolCode));
            }

            if (leadCode == ModifierCode.Installation)
            {
                return((trailCode == 'B') ? "Feint Dummy Installation" : "Installation");
            }

            string mod = ModifierCode.GetName(symbolCode);
            string ech = Echelon.GetName(symbolCode);

            if (string.IsNullOrEmpty(mod) || string.IsNullOrEmpty(ech))
            {
                return(string.Empty);
            }

            if (mod == "None" && ech == "None")
            {
                return(string.Empty);
            }

            if (mod == "None")
            {
                return(ech);
            }

            if (ech == "None")
            {
                return(mod);
            }

            return(mod + "\n" + ech);
        }
Beispiel #4
0
        public void EchelonTest()
        {
            char gc = Echelon.GetCode(string.Empty);

            Assert.AreEqual(gc, (char)0);
            gc = Echelon.GetCode(null);
            Assert.AreEqual(gc, (char)0);
            gc = Echelon.GetCode("qqqqqqqqqqqqqqq");
            Assert.AreEqual(gc, 'Q');
            string str = Echelon.GetName(string.Empty);

            Assert.AreEqual(str, string.Empty);
            str = Echelon.GetName(null);
            Assert.AreEqual(str, string.Empty);
            str = Echelon.GetName("qqqqqqqqqqqqqqq");
            Assert.AreEqual(str, string.Empty);
            str = Echelon.GetName("qqpqqqqqqqqhqqq");
            Assert.AreEqual(str, "Brigade");
        }
Beispiel #5
0
        /// <summary>
        /// Always generates the entire symbol.
        /// The symbol code should not change very often.
        /// </summary>
        private void GenerateSymbol()
        {
            try
            {
                // Only draw after we have the symbol code, if drawing via method call
                if (this.suppressRefresh)
                {
                    return;
                }

                string symbolCode = this.SymbolCode;

                // Reinitialize
                this.IsDirty  = true;       // set a dirty flag to indicate the symbol needs updating
                this.bounds   = Rect.Empty;
                this.BaseRect = Rect.Empty;
                this.Children.Clear();      // tried to cheap this one out - but that doesn't work well
                this.elements.Clear();

                // Get the base symbol from "the" resource dictionary
                var baseSymbol = new MilSymbolBase(symbolCode, this.LineBrush, this.FillBrush);
                if (baseSymbol.Empty)
                {
                    return;
                }

                this.AddChild("Base", baseSymbol);

                var styles = MilLabels.GetStyles(this.LabelStyle);

                // There is only label decoration for weather codes
                int schemeKey = CodingScheme.GetCode(symbolCode);
                if (schemeKey == CodingScheme.Weather || schemeKey == CodingScheme.TacticalGraphics)
                {
                    this.GenerateLabels(styles);
                    return;
                }

                // Add in the echelon marking.
                // "high" is the maximum height from the decoration
                this.high = Echelon.Generate(this, symbolCode);

                // Draw headquarters, feint dummy, task force, and installation.
                // "high" is the maximum height from the decoration
                this.high = MilHats.Generate(this, symbolCode);

                // Take care of any Joker, Faker, or Exercise character
                this.AddChild(
                    "JFE", MilLabels.GenerateJokerFakerExercise(symbolCode, this.labels, styles[MilLabels.BigLabels]));

                // Add the black ribbon on the base symbol for space
                this.AddChild("Space", MilSymbolBase.GenerateSpace(symbolCode));

                // Indicate whether the entity is damaged or destroyed
                this.AddChild("OC", StatusOperationalCapacity.Generate(symbolCode));

                // Add the mobility to the base of the symbol
                this.AddChild("Mobility", DrawMobility.GenerateMobility(symbolCode));

                // We have to (re)generate the labels because the symbol code extent may be different
                this.GenerateLabels(styles);
            }
            catch (Exception ex)
            {
                Log.WriteMessage(LogLevel.Error, "Unable to construct military symbol", ex);
            }
        }
Beispiel #6
0
        /// <summary>
        /// The main zone generating method.
        /// </summary>
        /// <param name="mg">
        /// The MilGraphic associated with the zone to be generated.
        /// </param>
        /// <param name="isClosed">
        /// Whether or not the zone outline is to be closed since this method can be used for polylines as well.
        /// </param>
        /// <param name="count">
        /// The count of the map locations making up the zone.
        /// </param>
        /// <param name="anchors">
        /// The map locations making up the zone.
        /// </param>
        /// <param name="pointAnchors">
        /// The locations in ResourceDictionary space.
        /// </param>
        /// <returns>
        /// A Path representing the map locations, to be associated with the MilGraphic.
        /// </returns>
        public static Path GenerateLines(
            MilGraphic mg,
            bool isClosed,        // do we close the boundary
            int count,            // the number of transformed points to use in boundary
            IList <ILocation> anchors,
            out IList <Point> pointAnchors)
        {
            IList <Point> pointCp1 = null;
            IList <Point> pointCp2 = null;

            pointAnchors = MapHelper.LatLonsToPixels(anchors, 2.0);

            // Need to convert the cardinal spline points into Bezier spline control points
            if (mg.IsSpline)
            {
                ClosedBezierSpline.GetCurveControlPoints(count, pointAnchors, out pointCp1, out pointCp2);
            }

            ScaleData(pointAnchors, pointCp1, pointCp2);

            // Generate Bezier or line segments for insertion into a figure collection
            PathFigureCollection figures;

            if (mg.IsSpline)
            {
                figures = new PathFigureCollection
                {
                    new PathFigure
                    {
                        Segments = GenerateBezierSegments(count, pointAnchors, pointCp1, pointCp2, isClosed)
                    }
                };
            }
            else
            {
                switch (mg.StencilType)
                {
                case "ObstacleZone":
                case "ObstacleBelt":
                    pointAnchors.Add(pointAnchors[0]);
                    figures = MilLine.GenerateDecoratedSegments(
                        mg, DecoratedType.Triangular, false, count + 1, pointAnchors);
                    pointAnchors.RemoveAt(count);
                    break;

                case "ObstacleRestrictedArea":
                case "ObstacleFreeArea":
                    pointAnchors.Add(pointAnchors[0]);
                    figures = MilLine.GenerateDecoratedSegments(
                        mg, DecoratedType.Triangular, true, count + 1, pointAnchors);
                    pointAnchors.RemoveAt(count);
                    break;

                case "Boundaries":
                    figures = MilLine.GenerateDecoratedSegments(mg, DecoratedType.Echelon, true, count, pointAnchors);
                    var labels      = new[] { mg.LabelT, Echelon.GetEchelonSymbol(mg.SymbolCode), mg.LabelT1 };
                    int figureCount = figures.Count;
                    for (int i = 0; i < figureCount - 1; i++)
                    {
                        var pls = figures[i].Segments[0] as PolyLineSegment;
                        if (pls == null)
                        {
                            continue;
                        }

                        var pc = pls.Points.Count - 1;
                        if (pc > 0)
                        {
                            mg.AddChild(
                                "Label" + i,
                                MilLine.GenerateLabels(
                                    mg, labels, pls.Points[pc], pls.Points[pc - 1], pointAnchors[0], new Point(1.0, 0.5)));
                        }
                    }

                    break;

                default:
                    figures = new PathFigureCollection
                    {
                        new PathFigure
                        {
                            Segments = GeneratePolygonSegments(count, pointAnchors)
                        }
                    };
                    break;
                }
            }

            // In most cases we have a single figure
            figures[0].StartPoint = pointAnchors[0];
            figures[0].IsClosed   = isClosed;

            var path = new Path
            {
                Data = new PathGeometry {
                    Figures = figures
                },
                Style = mg.ContentControl.UnframedLine
            };

            if (mg.StencilType == "ObstacleRestrictedArea")
            {
                path.Fill = HatchBrush(mg.ContentControl.Brush);
            }
#if WINDOWS_UWP
            path.SetBinding(Shape.StrokeThicknessProperty, new Binding()
            {
                Path = new PropertyPath("LineThickness"), Source = mg.ContentControl
            });
#else
            path.SetBinding(Shape.StrokeThicknessProperty, new Binding("LineThickness")
            {
                Source = mg.ContentControl
            });
#endif
            return(path);
        }
Beispiel #7
0
        /// <summary>
        /// Generates the correct combination of task force, installation, and feint dummy for a symbol.
        /// </summary>
        /// <param name="ms">
        /// The symbol to which the generated rendering is attached.
        /// </param>
        /// <param name="symbolCode">
        /// The symbol code for the given symbol
        /// </param>
        /// <returns>
        /// The maximum height of the generated rendering.
        /// </returns>
        internal static double Generate(MilSymbol ms, string symbolCode)
        {
            // This is the maximum height generated by this combination of pieces
            Rect r = ms.BaseRect;

            if (r.IsEmpty)
            {
                return(0);
            }

            double height = r.Top;

            if (!SymbolData.Check(ref symbolCode))
            {
                return(height);
            }

            char code = ModifierCode.GetCode(symbolCode);

            switch (code)
            {
            case ModifierCode.Headquarters:     // headquarters
                ms.AddChild("HQ", GenerateHeadquarters(ms));
                break;

            case ModifierCode.TaskForceHeadquarters:     // task force, headquarters
                ms.AddChild("TF", GenerateTaskForce(ms, out height));
                ms.AddChild("HQ", GenerateHeadquarters(ms));
                break;

            case ModifierCode.FeintDummyHeadquarters:     // feint dummy, headquarters
                ms.AddChild("FD", GenerateFeintDummy(ms, ref height));
                ms.AddChild("HQ", GenerateHeadquarters(ms));
                break;

            case ModifierCode.FeintDummyTaskForceHeadquarters:     // feint dummy, task force, headquarters
                ms.AddChild("TF", GenerateTaskForce(ms, out height));
                ms.AddChild("FD", GenerateFeintDummy(ms, ref height));
                ms.AddChild("HQ", GenerateHeadquarters(ms));
                break;

            case ModifierCode.TaskForce:     // task force
                ms.AddChild("TF", GenerateTaskForce(ms, out height));
                break;

            case ModifierCode.FeintDummy:     // feint dummy
                ms.AddChild("FD", GenerateFeintDummy(ms, ref height));
                break;

            case ModifierCode.FeintDummyTaskForce:     // feint dummy/task force
                ms.AddChild("TF", GenerateTaskForce(ms, out height));
                ms.AddChild("FD", GenerateFeintDummy(ms, ref height));
                break;

            case ModifierCode.Installation:     // installation
                ms.AddChild("Installation", GenerateInstallation(ms, out height));

                // There is an unfortunate overloading of the echelon character in the standard
                if (Echelon.GetCode(symbolCode) == 'B')
                {
                    ms.AddChild("FD", GenerateFeintDummy(ms, ref height));
                }

                break;

            case ModifierCode.Mobility:  // mobility
            case ModifierCode.Towed:     // towed
                break;
            }

            return(height);
        }
Beispiel #8
0
        /// <summary>
        /// Stop all services and dispose of them. This should be called once before the game
        /// exits. It can be called repeatedly to destroy re-created resources.
        /// </summary>
        public static void StopAllServices()
        {
            try
            {
                Game.Dispose();
            }
            catch (Exception) { }
            finally
            {
                Game = null;
            }

            try
            {
                Resources.Dispose();
            }
            catch (Exception) { }
            finally
            {
                Resources = null;
            }

            StateManager = null;
            try
            {
                Echelon.Dispose();
            }
            catch (Exception) { }
            finally
            {
                Echelon = null;
            }

            try
            {
                Theater.Dispose();
            }
            catch (Exception) { }
            finally
            {
                Theater = null;
            }

            try
            {
                AudioManager.Dispose();
            }
            catch (Exception) { }
            finally
            {
                AudioManager = null;
            }

            try
            {
                MP3Player.Dispose();
            }
            catch (Exception) { }
            finally
            {
                MP3Player = null;
            }

            try
            {
                Logger.Close();
            }
            catch (Exception) { }
            finally
            {
                Logger = null;
            }
        }