Esempio n. 1
0
 public ChainBasedGenerator(TLayout initialLayout, IGeneratorPlanner <TLayout, TNode> generatorPlanner, List <Chain <TNode> > chains, ILayoutEvolver <TLayout, TNode> layoutEvolver, ILayoutConverter <TLayout, TOutputLayout> layoutConverter)
 {
     this.initialLayout    = initialLayout;
     this.generatorPlanner = generatorPlanner;
     this.chains           = chains;
     this.layoutEvolver    = layoutEvolver;
     this.layoutConverter  = layoutConverter;
 }
        public IList <TOutputLayout> GetLayouts(TMapDescription mapDescription, int numberOfLayouts)
        {
            var graph = mapDescription.GetGraph();

            if (graph.VerticesCount < 2)
            {
                throw new ArgumentException("Given mapDescription must contain at least two nodes.", nameof(mapDescription));
            }

            if (!graphUtils.IsConnected(graph))
            {
                throw new ArgumentException("Given mapDescription must represent a connected graph.", nameof(mapDescription));
            }

            if (!graphUtils.IsPlanar(graph))
            {
                throw new ArgumentException("Given mapDescription must represent a planar graph.", nameof(mapDescription));
            }

            // Create instances and inject the random generator and the cancellation token if possible
            configurationSpaces = configurationSpacesCreator(mapDescription);
            TryInjectRandomAndCancellationToken(configurationSpaces);

            chainDecomposition = chainDecompositionCreator(mapDescription);
            TryInjectRandomAndCancellationToken(chainDecomposition);

            initialLayout = initialLayoutCreator(mapDescription);
            TryInjectRandomAndCancellationToken(initialLayout);

            generatorPlanner = generatorPlannerCreator(mapDescription);
            TryInjectRandomAndCancellationToken(generatorPlanner);

            layoutOperations = layoutOperationsCreator(mapDescription, configurationSpaces);
            TryInjectRandomAndCancellationToken(layoutOperations);

            layoutConverter = layoutConverterCreator(mapDescription, configurationSpaces);
            TryInjectRandomAndCancellationToken(layoutConverter);

            layoutEvolver = layoutEvolverCreator(mapDescription, layoutOperations);
            TryInjectRandomAndCancellationToken(layoutEvolver);

            // Restart stopwatch
            stopwatch.Restart();

            chains  = chainDecomposition.GetChains(graph);
            context = new GeneratorContext();

            RegisterEventHandlers();

            // TODO: handle number of layouts to be evolved - who should control that? generator or planner?
            // TODO: handle context.. this is ugly
            var layouts = generatorPlanner.Generate(initialLayout, numberOfLayouts, chains.Count,
                                                    (layout, chainNumber, numOfLayouts) => layoutEvolver.Evolve(AddChain(layout, chainNumber), chains[chainNumber], numOfLayouts), context);

            // Stop stopwatch and prepare benchmark info
            stopwatch.Stop();
            timeTotal    = stopwatch.ElapsedMilliseconds;
            layoutsCount = layouts.Count;

            // Reset cancellation token if it was already used
            if (CancellationToken.HasValue && CancellationToken.Value.IsCancellationRequested)
            {
                CancellationToken = null;
            }

            return(layouts.Select(x => layoutConverter.Convert(x, true)).ToList());
        }
Esempio n. 3
0
        private static void StoreChildNodeInfo(XmlNode xn, string className, XmlDocConfigureDlg.LayoutTreeNode ltn, ILayoutConverter converter)
        {
            string  sField   = XmlUtils.GetMandatoryAttributeValue(xn, "field");
            XmlNode xnCaller = converter.LayoutLevels.PartRef;

            if (xnCaller == null)
            {
                xnCaller = ltn.Configuration;
            }
            bool hideConfig = xnCaller == null ? false : XmlUtils.GetOptionalBooleanAttributeValue(xnCaller, "hideConfig", false);

            // Insert any special configuration appropriate for this property...unless the caller is hidden, in which case,
            // we don't want to configure it at all.
            if (!ltn.IsTopLevel && !hideConfig)
            {
                if (sField == "Senses" && (ltn.ClassName == "LexEntry" || ltn.ClassName == "LexSense"))
                {
                    ltn.ShowSenseConfig = true;
                }
                else if (sField == "ReferringSenses" && ltn.ClassName == "ReversalIndexEntry")
                {
                    ltn.ShowSenseConfig = true;
                }
                if (sField == "MorphoSyntaxAnalysis" && ltn.ClassName == "LexSense")
                {
                    ltn.ShowGramInfoConfig = true;
                }
                if (sField == "VisibleComplexFormBackRefs" || sField == "ComplexFormsNotSubentries")
                {
                    //The existence of the attribute is important for this setting, not its value!
                    var sShowAsIndentedPara = XmlUtils.GetAttributeValue(ltn.Configuration, "showasindentedpara");
                    ltn.ShowComplexFormParaConfig = !String.IsNullOrEmpty(sShowAsIndentedPara);
                }
            }
            bool fRecurse = XmlUtils.GetOptionalBooleanAttributeValue(ltn.Configuration, "recurseConfig", true);

            if (!fRecurse)
            {
                // We don't want to recurse forever just because senses have subsenses, which
                // can have subsenses, which can ...
                // Or because entries have subentries (in root type layouts)...
                ltn.UseParentConfig = true;
                return;
            }
            var    sLayout        = XmlVc.GetLayoutName(xn, xnCaller);
            var    clidDst        = 0;
            string sClass         = null;
            string sTargetClasses = null;

            try
            {
                // Failure should be fairly unusual, but, for example, part MoForm-Jt-FormEnvPub attempts to display
                // the property PhoneEnv inside an if that checks that the MoForm is one of the subclasses that has
                // the PhoneEnv property. MoForm itself does not.
                if (!((IFwMetaDataCacheManaged)converter.Cache.DomainDataByFlid.MetaDataCache).FieldExists(className, sField, true))
                {
                    return;
                }
                var flid = converter.Cache.DomainDataByFlid.MetaDataCache.GetFieldId(className, sField, true);
                var type = (CellarPropertyType)converter.Cache.DomainDataByFlid.MetaDataCache.GetFieldType(flid);
                Debug.Assert(type >= CellarPropertyType.MinObj);
                if (type >= CellarPropertyType.MinObj)
                {
                    var mdc = converter.Cache.MetaDataCacheAccessor;
                    sTargetClasses = XmlUtils.GetOptionalAttributeValue(xn, "targetclasses");
                    clidDst        = mdc.GetDstClsId(flid);
                    if (clidDst == 0)
                    {
                        sClass = XmlUtils.GetOptionalAttributeValue(xn, "targetclass");
                    }
                    else
                    {
                        sClass = mdc.GetClassName(clidDst);
                    }
                    if (clidDst == StParaTags.kClassId)
                    {
                        string sClassT = XmlUtils.GetOptionalAttributeValue(xn, "targetclass");
                        if (!String.IsNullOrEmpty(sClassT))
                        {
                            sClass = sClassT;
                        }
                    }
                }
            }
            catch
            {
                return;
            }
            if (clidDst == MoFormTags.kClassId && !sLayout.StartsWith("publi"))
            {
                return;                 // ignore the layouts used by the LexEntry-Jt-Headword part.
            }
            if (String.IsNullOrEmpty(sLayout) || String.IsNullOrEmpty(sClass))
            {
                return;
            }
            if (sTargetClasses == null)
            {
                sTargetClasses = sClass;
            }
            string[] rgsClasses = sTargetClasses.Split(new[] { ',', ' ' },
                                                       StringSplitOptions.RemoveEmptyEntries);
            XmlNode subLayout = null;

            if (rgsClasses.Length > 0)
            {
                subLayout = converter.GetLayoutElement(rgsClasses[0], sLayout);
            }

            if (subLayout != null)
            {
                int iStart = ltn.Nodes.Count;
                int cNodes = subLayout.ChildNodes.Count;
                AddChildNodes(subLayout, ltn, iStart, converter);

                bool fRepeatedConfig = XmlUtils.GetOptionalBooleanAttributeValue(xn, "repeatedConfig", false);
                if (fRepeatedConfig)
                {
                    return;                             // repeats an earlier part element (probably as a result of <if>s)
                }
                for (int i = 1; i < rgsClasses.Length; i++)
                {
                    XmlNode mergedLayout = converter.GetLayoutElement(rgsClasses[i], sLayout);
                    if (mergedLayout != null && mergedLayout.ChildNodes.Count == cNodes)
                    {
                        AddChildNodes(mergedLayout, ltn, iStart, converter);
                    }
                }
            }
            else
            {
                // The "layout" in a part node can actually refer directly to another part, so check
                // for that possibility.
                var subPart = converter.GetPartElement(rgsClasses[0], sLayout) ?? converter.GetPartElement(className, sLayout);
                if (subPart == null && !sLayout.EndsWith("-en"))
                {
                    // Complain if we can't find either a layout or a part, and the name isn't tagged
                    // for a writing system.  (We check only for English, being lazy.)
                    var msg = String.Format("Missing jtview layout for class=\"{0}\" name=\"{1}\"",
                                            rgsClasses[0], sLayout);
                    converter.LogConversionError(msg);
                }
            }
        }
Esempio n. 4
0
 /// <summary>
 /// Walk the tree of child nodes, storing information for each &lt;obj&gt; or &lt;seq&gt;
 /// node.
 /// </summary>
 private static void ProcessChildNodes(XmlNodeList xmlNodeList, string className, XmlDocConfigureDlg.LayoutTreeNode ltn, ILayoutConverter converter)
 {
     foreach (XmlNode xn in xmlNodeList)
     {
         if (xn is XmlComment)
         {
             continue;
         }
         if (xn.Name == "obj" || xn.Name == "seq" || xn.Name == "objlocal")
         {
             StoreChildNodeInfo(xn, className, ltn, converter);
         }
         else
         {
             ProcessChildNodes(xn.ChildNodes, className, ltn, converter);
         }
     }
 }
Esempio n. 5
0
        internal static void BuildTreeFromLayoutAndParts(XmlNode configurationLayoutsNode, ILayoutConverter converter)
        {
            var layoutTypes = new List <XmlNode>();

            layoutTypes.AddRange(configurationLayoutsNode.ChildNodes.OfType <XmlNode>().Where(x => x.Name == "layoutType"));
            Debug.Assert(layoutTypes.Count > 0);
            var xnConfig = layoutTypes[0].SelectSingleNode("configure");

            Debug.Assert(xnConfig != null);
            var configClass = XmlUtils.GetMandatoryAttributeValue(xnConfig, "class");

            foreach (var xn in converter.GetLayoutTypes())
            {
                var xnConfigure = xn.SelectSingleNode("configure");
                if (XmlUtils.GetMandatoryAttributeValue(xnConfigure, "class") == configClass)
                {
                    layoutTypes.Add(xn);
                }
            }
            foreach (var xnLayoutType in layoutTypes)
            {
                if (xnLayoutType is XmlComment || xnLayoutType.Name != "layoutType")
                {
                    continue;
                }
                string sLabel = XmlUtils.GetAttributeValue(xnLayoutType, "label");
                if (sLabel == "$wsName")                 // if the label for the layout matches $wsName then this is a reversal index layout
                {
                    string sLayout = XmlUtils.GetAttributeValue(xnLayoutType, "layout");
                    Debug.Assert(sLayout.EndsWith("-$ws"));
                    bool fReversalIndex = true;
                    foreach (XmlNode config in xnLayoutType.ChildNodes)
                    {
                        if (config is XmlComment || config.Name != "configure")
                        {
                            continue;
                        }
                        string sClass = XmlUtils.GetAttributeValue(config, "class");
                        if (sClass != "ReversalIndexEntry")
                        {
                            fReversalIndex = false;
                            break;
                        }
                    }
                    if (!fReversalIndex)
                    {
                        continue;
                    }
                    foreach (IReversalIndex ri in converter.Cache.LangProject.LexDbOA.CurrentReversalIndices)
                    {
                        var ws     = converter.Cache.ServiceLocator.WritingSystemManager.Get(ri.WritingSystem);
                        var sWsTag = ws.Id;
                        converter.ExpandWsTaggedNodes(sWsTag);                          // just in case we have a new index.
                        // Create a copy of the layoutType node for the specific writing system.
                        var xnRealLayout = CreateWsSpecficLayoutType(xnLayoutType, ws.DisplayLabel, sLayout.Replace("$ws", sWsTag), sWsTag);
                        var rgltnStyle   = BuildLayoutTree(xnRealLayout, converter);
                        converter.AddDictionaryTypeItem(xnRealLayout, rgltnStyle);
                    }
                }
                else
                {
                    var rgltnStyle = BuildLayoutTree(xnLayoutType, converter);
                    if (rgltnStyle.Count > 0)
                    {
                        converter.AddDictionaryTypeItem(xnLayoutType, rgltnStyle);
                    }
                }
            }
        }
Esempio n. 6
0
        internal static void AddChildNodes(XmlNode layout, XmlDocConfigureDlg.LayoutTreeNode ltnParent, int iStart, ILayoutConverter converter)
        {
            bool           fMerging  = iStart < ltnParent.Nodes.Count;
            string         className = XmlUtils.GetMandatoryAttributeValue(layout, "class");
            List <XmlNode> nodes     = PartGenerator.GetGeneratedChildren(layout, converter.Cache,
                                                                          new[] { "ref", "label" });

            foreach (XmlNode node in nodes)
            {
                XmlNode subLayout;
                if (node.Name == "sublayout")
                {
                    Debug.Assert(!fMerging);
                    string subLayoutName = XmlUtils.GetOptionalAttributeValue(node, "name", null);
                    if (subLayoutName == null)
                    {
                        subLayout = node;                         // a sublayout lacking a name contains the part refs directly.
                    }
                    else
                    {
                        subLayout = converter.GetLayoutElement(className, subLayoutName);
                    }
                    if (subLayout != null)
                    {
                        AddChildNodes(subLayout, ltnParent, ltnParent.Nodes.Count, converter);
                    }
                }
                else if (node.Name == "part")
                {
                    // Check whether this node has already been added to this parent.  Don't add
                    // it if it's already there!
                    XmlDocConfigureDlg.LayoutTreeNode ltnOld = FindMatchingNode(ltnParent, node);
                    if (ltnOld != null)
                    {
                        continue;
                    }
                    string  sRef = XmlUtils.GetMandatoryAttributeValue(node, "ref");
                    XmlNode part = converter.GetPartElement(className, sRef);
                    if (part == null && sRef != "$child")
                    {
                        continue;
                    }
                    bool fHide = XmlUtils.GetOptionalBooleanAttributeValue(node, "hideConfig", false);
                    XmlDocConfigureDlg.LayoutTreeNode ltn;
                    var cOrig = 0;
                    if (!fHide)
                    {
                        ltn = new XmlDocConfigureDlg.LayoutTreeNode(node, converter, className)
                        {
                            OriginalIndex    = ltnParent.Nodes.Count,
                            ParentLayout     = layout,
                            HiddenNode       = converter.LayoutLevels.HiddenPartRef,
                            HiddenNodeLayout = converter.LayoutLevels.HiddenLayout
                        };
                        if (!String.IsNullOrEmpty(ltn.LexRelType))
                        {
                            converter.BuildRelationTypeList(ltn);
                        }
                        if (!String.IsNullOrEmpty(ltn.EntryType))
                        {
                            converter.BuildEntryTypeList(ltn, ltnParent.LayoutName);
                        }
                        //if (fMerging)
                        //((LayoutTreeNode)ltnParent.Nodes[iNode]).MergedNodes.Add(ltn);
                        //else
                        ltnParent.Nodes.Add(ltn);
                    }
                    else
                    {
                        Debug.Assert(!fMerging);
                        ltn   = ltnParent;
                        cOrig = ltn.Nodes.Count;
                        if (className == "StTxtPara")
                        {
                            ltnParent.HiddenChildLayout = layout;
                            ltnParent.HiddenChild       = node;
                        }
                    }
                    try
                    {
                        converter.LayoutLevels.Push(node, layout);
                        var fOldAdding = ltn.AddingSubnodes;
                        ltn.AddingSubnodes = true;
                        if (part != null)
                        {
                            ProcessChildNodes(part.ChildNodes, className, ltn, converter);
                        }
                        ltn.OriginalNumberOfSubnodes = ltn.Nodes.Count;
                        ltn.AddingSubnodes           = fOldAdding;
                        if (fHide)
                        {
                            var cNew = ltn.Nodes.Count - cOrig;
                            if (cNew > 1)
                            {
                                var msg = String.Format("{0} nodes for a hidden PartRef ({1})!", cNew, node.OuterXml);
                                converter.LogConversionError(msg);
                            }
                        }
                    }
                    finally
                    {
                        converter.LayoutLevels.Pop();
                    }
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Builds control tree nodes based on a configure element
        /// </summary>
        private static XmlDocConfigureDlg.LayoutTreeNode BuildMainLayout(XmlNode config, ILayoutConverter converter)
        {
            var mainLayoutNode = new XmlDocConfigureDlg.LayoutTreeNode(config, converter, null);

            converter.SetOriginalIndexForNode(mainLayoutNode);
            string  className  = mainLayoutNode.ClassName;
            string  layoutName = mainLayoutNode.LayoutName;
            XmlNode layout     = converter.GetLayoutElement(className, layoutName);

            if (layout == null)
            {
                var msg = String.Format("Cannot configure layout {0} of class {1} because it does not exist", layoutName, className);
                converter.LogConversionError(msg);
                return(null);
            }
            mainLayoutNode.ParentLayout = layout;               // not really the parent layout, but the parent of this node's children
            string sVisible = XmlUtils.GetAttributeValue(layout, "visibility");

            mainLayoutNode.Checked = sVisible != "never";
            AddChildNodes(layout, mainLayoutNode, mainLayoutNode.Nodes.Count, converter);
            mainLayoutNode.OriginalNumberOfSubnodes = mainLayoutNode.Nodes.Count;
            return(mainLayoutNode);
        }
Esempio n. 8
0
        /// <summary>
        /// Configure LayoutType via its child configure nodes
        /// </summary>
        internal static List <XmlDocConfigureDlg.LayoutTreeNode> BuildLayoutTree(XmlNode xnLayoutType, ILayoutConverter converter)
        {
            var treeNodeList = new List <XmlDocConfigureDlg.LayoutTreeNode>();

            foreach (XmlNode config in xnLayoutType.ChildNodes)
            {               // expects a configure element
                if (config is XmlComment || config.Name != "configure")
                {
                    continue;
                }
                var ltn = BuildMainLayout(config, converter);
                if (ltn != null)
                {
                    if (XmlUtils.GetOptionalBooleanAttributeValue(config, "hideConfig", false))
                    {
                        treeNodeList.AddRange(Enumerable.Cast <XmlDocConfigureDlg.LayoutTreeNode>(ltn.Nodes));
                    }
                    else
                    {
                        treeNodeList.Add(ltn);
                    }
                }
            }
            return(treeNodeList);
        }