Example #1
0
        public static bool Serialise()
        {
            var    serializer = new DataContractSerializer(OM.GetType(), null, Int32.MaxValue, false, false, null, new SharedTypeResolver());
            string xmlString;

            using (var sw = new StringWriter())
            {
                using (var writer = new XmlTextWriter(sw))
                {
                    writer.Formatting = Formatting.Indented;
                    serializer.WriteObject(writer, OM);
                    writer.Flush();
                    xmlString = sw.ToString();
                }
            }


            var xd = new XmlDocument();

            xd.LoadXml(xmlString);

            string filename = SerialiseLocation + "\\XLOM_DataStore.xml";

            xd.Save(filename);

            return(true);
        }
Example #2
0
        } // end of ComputeOmInitFromVectorsPlan()

        /// <summary>
        /// Computes the signs for the plan as computed by GetOmInitFromVectorsPlan().
        ///
        /// Because the basis blades in the domain of 'om' do not have to be in canonical order,
        /// there may be some signs required to correctly executed the plan
        /// </summary>
        /// <param name="S"></param>
        /// <param name="om"></param>
        /// <param name="plan"></param>
        /// <returns>signs for the plan</returns>
        public static double[][] ComputeOmInitFromVectorsSigns(Specification S, OM om, uint[][][] plan)
        {
            double[][] result = new double[S.m_dimension + 1][];

            for (int g = 1; g <= S.m_dimension; g++)
            {
                result[g] = new double[om.DomainForGrade(g).Length];
                for (int d = 0; d < om.DomainForGrade(g).Length; d++)
                {
                    // get domain blade we have to construct
                    RefGA.BasisBlade D = om.DomainForGrade(g)[d];

                    // follow the plan to construct the blade
                    RefGA.BasisBlade P = RefGA.BasisBlade.ONE;
                    for (int p = 0; p < plan[g][d].Length; p++)
                    {
                        G25.Tuple <RefGA.BasisBlade, int, int> info = GetDomainBladeInfo(S, om, plan[g][d][p]);
                        P = RefGA.BasisBlade.op(P, info.Value1);
                    }

                    // compute sign difference & store
                    double s = D.scale / P.scale;
                    result[g][d] = s;
                }
            }

            return(result);
        } // end of ComputeOmInitFromVectorsSigns()
        private void RaiseLineArranged()
        {
            var realizationRect = RealizationRect;

            if (realizationRect.Width != 0.0 || realizationRect.Height != 0.0)
            {
                int realizedElementCount = m_elementManager.GetRealizedElementCount();
                if (realizedElementCount > 0)
                {
                    Debug.Assert(m_firstRealizedDataIndexInsideRealizationWindow != -1 && m_lastRealizedDataIndexInsideRealizationWindow != -1);
                    int countInLine           = 0;
                    var previousElementBounds = m_elementManager.GetLayoutBoundsForDataIndex(m_firstRealizedDataIndexInsideRealizationWindow);
                    var currentLineOffset     = OM.MajorStart(previousElementBounds);
                    var currentLineSize       = OM.MajorSize(previousElementBounds);
                    for (int currentDataIndex = m_firstRealizedDataIndexInsideRealizationWindow; currentDataIndex <= m_lastRealizedDataIndexInsideRealizationWindow; currentDataIndex++)
                    {
                        var currentBounds = m_elementManager.GetLayoutBoundsForDataIndex(currentDataIndex);
                        if (OM.MajorStart(currentBounds) != currentLineOffset)
                        {
                            // Staring a new line
                            m_algorithmCallbacks.Algorithm_OnLineArranged(currentDataIndex - countInLine, countInLine, currentLineSize, m_context);
                            countInLine       = 0;
                            currentLineOffset = OM.MajorStart(currentBounds);
                            currentLineSize   = 0;
                        }

                        currentLineSize = Math.Max(currentLineSize, OM.MajorSize(currentBounds));
                        countInLine++;
                    }

                    // Raise for the last line.
                    m_algorithmCallbacks.Algorithm_OnLineArranged(m_lastRealizedDataIndexInsideRealizationWindow - countInLine + 1, countInLine, currentLineSize, m_context);
                }
            }
        }
        private bool ShouldContinueFillingUpSpace(
            int index,
            GenerateDirection direction)
        {
            bool shouldContinue;

            if (!IsVirtualizingContext)
            {
                shouldContinue = true;
            }
            else
            {
                var realizationRect = m_context.RealizationRect;
                var elementBounds   = m_elementManager.GetLayoutBoundsForDataIndex(index);

                var elementMajorStart = OM.MajorStart(elementBounds);
                var elementMajorEnd   = OM.MajorEnd(elementBounds);
                var rectMajorStart    = OM.MajorStart(realizationRect);
                var rectMajorEnd      = OM.MajorEnd(realizationRect);

                var elementMinorStart = OM.MinorStart(elementBounds);
                var elementMinorEnd   = OM.MinorEnd(elementBounds);
                var rectMinorStart    = OM.MinorStart(realizationRect);
                var rectMinorEnd      = OM.MinorEnd(realizationRect);

                // Ensure that both minor and major directions are taken into consideration so that if the scrolling direction
                // is the same as the flow direction we still stop at the end of the viewport rectangle.
                shouldContinue =
                    (direction == GenerateDirection.Forward && elementMajorStart < rectMajorEnd && elementMinorStart < rectMinorEnd) ||
                    (direction == GenerateDirection.Backward && elementMajorEnd > rectMajorStart && elementMinorEnd > rectMinorStart);
            }

            return(shouldContinue);
        }
Example #5
0
        public static bool Deserialise()
        {
            string filename = SerialiseLocation + "\\XLOM_DataStore.xml";

            var                 deserializer = new DataContractSerializer(OM.GetType(), null, Int32.MaxValue, false, false, null, new SharedTypeResolver());
            FileStream          fs           = new FileStream(filename, FileMode.Open);
            XmlDictionaryReader reader       = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());

            OM = (Dictionary <OMKey, object>)deserializer.ReadObject(reader);
            reader.Close();
            fs.Close();

            return(true);
        }
        public Size Measure(
            Size availableSize,
            VirtualizingLayoutContext context,
            bool isWrapping,
            double minItemSpacing,
            double lineSpacing,
            uint maxItemsPerLine,
            ScrollOrientation orientation,
            bool disableVirtualization,
            string layoutId)
        {
            OM.ScrollOrientation = orientation;

            // If minor size is infinity, there is only one line and no need to align that line.
            m_scrollOrientationSameAsFlow = double.IsInfinity(OM.Minor(availableSize));

            var suggestedAnchorIndex = m_context.RecommendedAnchorIndex;

            if (m_elementManager.IsIndexValidInData(suggestedAnchorIndex))
            {
                var anchorRealized = m_elementManager.IsDataIndexRealized(suggestedAnchorIndex);
                if (!anchorRealized)
                {
                    MakeAnchor(m_context, suggestedAnchorIndex, availableSize);
                }
            }

            m_elementManager.OnBeginMeasure(orientation);

            int anchorIndex = GetAnchorIndex(availableSize, isWrapping, minItemSpacing, layoutId);

            Generate(GenerateDirection.Forward, anchorIndex, availableSize, minItemSpacing, lineSpacing, maxItemsPerLine, disableVirtualization, layoutId);
            Generate(GenerateDirection.Backward, anchorIndex, availableSize, minItemSpacing, lineSpacing, maxItemsPerLine, disableVirtualization, layoutId);
            if (isWrapping && IsReflowRequired)
            {
                var firstElementBounds = m_elementManager.GetLayoutBoundsForRealizedIndex(0);
                OM.SetMinorStart(ref firstElementBounds, 0);
                m_elementManager.SetLayoutBoundsForRealizedIndex(0, firstElementBounds);
                Generate(GenerateDirection.Forward, 0 /*anchorIndex*/, availableSize, minItemSpacing, lineSpacing, maxItemsPerLine, disableVirtualization, layoutId);
            }

            RaiseLineArranged();
            m_collectionChangePending = false;
            m_lastExtent = EstimateExtent(availableSize, layoutId);
            SetLayoutOrigin();

            return(new Size(m_lastExtent.Width, m_lastExtent.Height));
        }
        private void ArrangeVirtualizingLayout(
            Size finalSize,
            LineAlignment lineAlignment,
            bool isWrapping,
            string layoutId)
        {
            // Walk through the realized elements one line at a time and
            // align them, Then call element.Arrange with the arranged bounds.
            int realizedElementCount = m_elementManager.GetRealizedElementCount();

            if (realizedElementCount > 0)
            {
                int    countInLine           = 1;
                var    previousElementBounds = m_elementManager.GetLayoutBoundsForRealizedIndex(0);
                var    currentLineOffset     = OM.MajorStart(previousElementBounds);
                var    spaceAtLineStart      = OM.MinorStart(previousElementBounds);
                double spaceAtLineEnd        = 0;
                double currentLineSize       = OM.MajorSize(previousElementBounds);
                for (int i = 1; i < realizedElementCount; i++)
                {
                    var currentBounds = m_elementManager.GetLayoutBoundsForRealizedIndex(i);
                    if (OM.MajorStart(currentBounds) != currentLineOffset)
                    {
                        spaceAtLineEnd = OM.Minor(finalSize) - OM.MinorStart(previousElementBounds) - OM.MinorSize(previousElementBounds);
                        PerformLineAlignment(i - countInLine, countInLine, spaceAtLineStart, spaceAtLineEnd, currentLineSize, lineAlignment, isWrapping, finalSize, layoutId);
                        spaceAtLineStart  = OM.MinorStart(currentBounds);
                        countInLine       = 0;
                        currentLineOffset = OM.MajorStart(currentBounds);
                        currentLineSize   = 0;
                    }

                    countInLine++; // for current element
                    currentLineSize       = Math.Max(currentLineSize, OM.MajorSize(currentBounds));
                    previousElementBounds = currentBounds;
                }

                // Last line - potentially have a property to customize
                // aligning the last line or not.
                if (countInLine > 0)
                {
                    double spaceAtEnd = OM.Minor(finalSize) - OM.MinorStart(previousElementBounds) - OM.MinorSize(previousElementBounds);
                    PerformLineAlignment(realizedElementCount - countInLine, countInLine, spaceAtLineStart, spaceAtEnd, currentLineSize, lineAlignment, isWrapping, finalSize, layoutId);
                }
            }
        }
Example #8
0
        /// <summary>
        /// 'Plans' how to initialize an outermorphism from vector images.
        ///
        /// The plan is returned in the form of nested array <c>uint[grade][domain][plan steps]</c>.
        /// The <c>plan steps</c> are the bitmaps of the basis blades that should be wedged together
        /// to form the basis blade for <c>grade,domain</c>.
        /// </summary>
        /// <param name="S"></param>
        /// <param name="om"></param>
        /// <returns>plan for initialization of <c>om</c> from vector images.</returns>
        public static uint[][][] ComputeOmInitFromVectorsPlan(Specification S, OM om)
        {
            // keep track of which basis blades are available (domain vectors are the input, so they are always available)
            bool[] availableBasisBlades = new bool[1 << S.m_dimension];
            for (int i = 0; i < om.DomainVectors.Length; i++)
            {
                availableBasisBlades[om.DomainVectors[i].bitmap] = true;
            }

            // for each grade, figure out how to construct the basis blades of that grade from basis blades which are already available
            uint[][][] result = new uint[S.m_dimension + 1][][];
            for (int g = 1; g <= S.m_dimension; g++)
            {
                result[g] = new uint[om.DomainForGrade(g).Length][];
                for (int d = 0; d < om.DomainForGrade(g).Length; d++)
                {
                    RefGA.BasisBlade D = om.DomainForGrade(g)[d];
                    // find the largest part of D which is already known
                    List <uint> plan   = new List <uint>();
                    uint        bitmap = D.bitmap;
                    while (bitmap != 0)
                    {
                        // find first bit, plan it, see if the rest is available
                        uint lowestBitIdx = (uint)RefGA.Bits.LowestOneBit(bitmap);
                        uint lowestBitmap = (uint)(1 << (int)lowestBitIdx);
                        plan.Add(lowestBitmap);
                        bitmap ^= lowestBitmap;

                        if (availableBasisBlades[bitmap]) // if remaining bitmap has already been computed, use that
                        {
                            plan.Add(bitmap);
                            bitmap ^= bitmap;
                        }
                    }

                    // plan for this basis blade is done:
                    result[g][d] = plan.ToArray();
                    availableBasisBlades[D.bitmap] = true;
                }
            }

            return(result);
        } // end of ComputeOmInitFromVectorsPlan()
Example #9
0
        /// <summary>
        /// 'Plans' how to initialize an outermorphism from vector images.
        /// 
        /// The plan is returned in the form of nested array <c>uint[grade][domain][plan steps]</c>.
        /// The <c>plan steps</c> are the bitmaps of the basis blades that should be wedged together
        /// to form the basis blade for <c>grade,domain</c>.
        /// </summary>
        /// <param name="S"></param>
        /// <param name="om"></param>
        /// <returns>plan for initialization of <c>om</c> from vector images.</returns>
        public static uint[][][] ComputeOmInitFromVectorsPlan(Specification S, OM om)
        {
            // keep track of which basis blades are available (domain vectors are the input, so they are always available)
            bool[] availableBasisBlades = new bool[1 << S.m_dimension];
            for (int i = 0; i < om.DomainVectors.Length; i++)
                availableBasisBlades[om.DomainVectors[i].bitmap] = true;

            // for each grade, figure out how to construct the basis blades of that grade from basis blades which are already available
            uint[][][] result = new uint[S.m_dimension + 1][][];
            for (int g = 1; g <= S.m_dimension; g++)
            {
                result[g] = new uint[om.DomainForGrade(g).Length][];
                for (int d = 0; d < om.DomainForGrade(g).Length; d++)
                {

                    RefGA.BasisBlade D = om.DomainForGrade(g)[d];
                    // find the largest part of D which is already known
                    List<uint> plan = new List<uint>();
                    uint bitmap = D.bitmap;
                    while (bitmap != 0)
                    {
                        // find first bit, plan it, see if the rest is available
                        uint lowestBitIdx = (uint)RefGA.Bits.LowestOneBit(bitmap);
                        uint lowestBitmap = (uint)(1 << (int)lowestBitIdx);
                        plan.Add(lowestBitmap);
                        bitmap ^= lowestBitmap;

                        if (availableBasisBlades[bitmap]) // if remaining bitmap has already been computed, use that
                        {
                            plan.Add(bitmap);
                            bitmap ^= bitmap;
                        }
                    }

                    // plan for this basis blade is done:
                    result[g][d] = plan.ToArray();
                    availableBasisBlades[D.bitmap] = true;
                }
            }

            return result;
        }
Example #10
0
        } // end of WriteSetVectorImages()

        private static void WriteOMtoOMcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, OM srcOm, OM dstOm)
        {
            StringBuilder declSB      = cgd.m_declSB;
            StringBuilder defSB       = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;
            string        srcTypeName = FT.GetMangledName(S, srcOm.Name);
            string        dstTypeName = FT.GetMangledName(S, dstOm.Name);

            // write comment
            declSB.AppendLine("/** Copies a " + srcTypeName + " to a " + dstTypeName);
            declSB.AppendLine(" * Warning 1: coordinates which cannot be represented are silenty lost");
            declSB.AppendLine(" * Warning 2: coordinates which are not present in 'src' are set to zero in 'dst'.");
            declSB.AppendLine(" */");

            string funcName = srcTypeName + "_to_" + dstTypeName;

            // do we inline this func?
            string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " ");

            string funcDecl = inlineStr + "void " + funcName + "(" + dstTypeName + " *dst, const " + srcTypeName + " *src)";

            declSB.Append(funcDecl);
            declSB.AppendLine(";");

            defSB.Append(funcDecl);
            {
                defSB.AppendLine(" {");

                Dictionary <Tuple <int, int, int>, Tuple <int, int, double> > D = dstOm.getMapping(srcOm);

                StringBuilder copySB    = new StringBuilder();
                List <string> setToZero = new List <string>();

                // For all grades of som, for all columns, for all rows, check D, get entry, set; otherwise set to null
                // Do not use foreach() on D because we want to fill in coordinates in their proper order.
                for (int gradeIdx = 1; gradeIdx < dstOm.Domain.Length; gradeIdx++)
                {
                    for (int somRangeIdx = 0; somRangeIdx < dstOm.Range[gradeIdx].Length; somRangeIdx++)
                    {
                        for (int somDomainIdx = 0; somDomainIdx < dstOm.Domain[gradeIdx].Length; somDomainIdx++)
                        {
                            Tuple <int, int, int> key = new Tuple <int, int, int>(gradeIdx, somDomainIdx, somRangeIdx);

                            int    somMatrixIdx = dstOm.getCoordinateIndex(gradeIdx, somDomainIdx, somRangeIdx);
                            string dstString    = "dst->m" + gradeIdx + "[" + somMatrixIdx + "] = ";
                            if (D.ContainsKey(key))
                            {
                                Tuple <int, int, double> value = D[key];
                                int    gomMatrixIdx            = srcOm.getCoordinateIndex(gradeIdx, value.Value1, value.Value2);
                                double multiplier       = value.Value3;
                                string multiplierString = (multiplier == 1.0) ? "" : (FT.DoubleToString(S, multiplier) + " * ");

                                copySB.AppendLine("\t" + dstString + multiplierString + " src->m" + gradeIdx + "[" + gomMatrixIdx + "];");
                            }
                            else
                            {
                                setToZero.Add(dstString);
                            }
                        }
                    }
                }

                // append copy statements
                defSB.Append(copySB);

                // append statements to set coordinates to zero
                if (setToZero.Count > 0)
                {
                    int cnt = 0;
                    defSB.Append("\t");
                    foreach (string str in setToZero)
                    {
                        defSB.Append(str);
                        cnt++;
                        if (cnt > 8)
                        {
                            cnt = 0;
                            defSB.AppendLine("");
                            defSB.Append("\t\t");
                        }
                    }
                    defSB.AppendLine(FT.DoubleToString(S, 0.0) + ";");
                }

                defSB.AppendLine("}");
            }
        }
Example #11
0
    public void Trigger(SubtitleController TextDisplay)
    {
        foreach (ExplosiveDamage explosion in explosions)
        {
            if (explosion != null)
            {
                explosion.explode(TextDisplay);
            }
            try {
                if (explosion.GetComponent <Detonator>() != null)
                {
                    explosion.GetComponent <Detonator>().Explode();
                }
            } catch (SystemException e) {
                Debug.LogError("Explosion Failed. DAMNIT IT!");
                Debug.LogError(e.ToString());
            }
        }


        if (QTSEController != null)
        {
            QTSEController.Queue(Spam);
        }
        if (sound != null && soundSource != null)
        {
            soundSource.PlayOneShot(sound);
        }
        if (showText)
        {
            TextDisplay.setLines(Text);
        }
        if (instantiableObject != null)
        {
            for (int i = 0; i < number; i++)
            {
                MonoBehaviour.Instantiate(instantiableObject, (UnityEngine.Random.value * tolerance) + place, new Quaternion(0, 0, 0, 1));
            }
        }

        if (radioWriteStyle == editSettings.append)
        {
            foreach (AudioClip clip in RadioSounds)
            {
                radio.clips.Add(clip);
            }
        }
        if (radioWriteStyle == editSettings.overwrite)
        {
            radio.clips = RadioSounds;
        }
        foreach (DoorControl d in doors)
        {
            d.d.setState(d.open);
        }
        foreach (ObjectManipulation OM in OMs)
        {
            OM.use();
        }
        foreach (UniqueEffect ue in UE)
        {
            ue.trigger();
        }
        foreach (TriggerableEvent TEvent in events)
        {
            TEvent.Trigger(TextDisplay);
        }
    }
Example #12
0
        } // end of ComputeOmInitFromVectorsSigns()

        /// <summary>
        /// Returns info about <c>bitmap</c>.
        ///
        /// If bitmap is not in the domain of <c>om</c>, the basis blade in the returned value will be null,
        /// and the domainIdx will be -1.
        ///
        /// If the grade of the bitmap is 1, the domainIdx will be -1 because it is
        /// assumed to be an input vector.
        /// </summary>
        /// <param name="S"></param>
        /// <param name="om"></param>
        /// <param name="bitmap"></param>
        /// <returns><c>BasisBlade, grade, domainIdx</c> for <c>bitmap</c></returns>
        public static G25.Tuple <RefGA.BasisBlade, int, int> GetDomainBladeInfo(Specification S, OM om, uint bitmap)
        {
            int grade = (int)RefGA.Bits.BitCount(bitmap);

            if (grade == 1)  // basis vector
            {
                return(new G25.Tuple <RefGA.BasisBlade, int, int>(new RefGA.BasisBlade(bitmap), grade, -1));
            }

            // find the bitmap in the domain
            RefGA.BasisBlade B = null;
            int domainIdx      = -1;

            for (int i = 0; i < om.DomainForGrade(grade).Length; i++)
            {
                if (bitmap == om.DomainForGrade(grade)[i].bitmap)
                {
                    domainIdx = i;
                    B         = om.DomainForGrade(grade)[i];
                    break;
                }
            }

            return(new G25.Tuple <RefGA.BasisBlade, int, int>(B, grade, domainIdx));
        } // end of GetDomainBladeInfo()
        private void Generate(
            GenerateDirection direction,
            int anchorIndex,
            Size availableSize,
            double minItemSpacing,
            double lineSpacing,
            uint maxItemsPerLine,
            bool disableVirtualization,
            string layoutId)
        {
            if (anchorIndex != -1)
            {
                int step = (direction == GenerateDirection.Forward) ? 1 : -1;

                int    previousIndex       = anchorIndex;
                int    currentIndex        = anchorIndex + step;
                var    anchorBounds        = m_elementManager.GetLayoutBoundsForDataIndex(anchorIndex);
                double lineOffset          = OM.MajorStart(anchorBounds);
                double lineMajorSize       = OM.MajorSize(anchorBounds);
                uint   countInLine         = 1;
                bool   lineNeedsReposition = false;

                while (m_elementManager.IsIndexValidInData(currentIndex) &&
                       (disableVirtualization || ShouldContinueFillingUpSpace(previousIndex, direction)))
                {
                    // Ensure layout element.
                    m_elementManager.EnsureElementRealized(direction == GenerateDirection.Forward, currentIndex, layoutId);
                    var currentElement = m_elementManager.GetRealizedElement(currentIndex);
                    var desiredSize    = MeasureElement(currentElement, currentIndex, availableSize, m_context);

                    // Lay it out.
                    var  previousElement       = m_elementManager.GetRealizedElement(previousIndex);
                    Rect currentBounds         = new Rect(0, 0, desiredSize.Width, desiredSize.Height);
                    var  previousElementBounds = m_elementManager.GetLayoutBoundsForDataIndex(previousIndex);

                    if (direction == GenerateDirection.Forward)
                    {
                        double remainingSpace = OM.Minor(availableSize) - (OM.MinorStart(previousElementBounds) + OM.MinorSize(previousElementBounds) + minItemSpacing + OM.Minor(desiredSize));
                        if (countInLine >= maxItemsPerLine || m_algorithmCallbacks.Algorithm_ShouldBreakLine(currentIndex, remainingSpace))
                        {
                            // No more space in this row. wrap to next row.
                            OM.SetMinorStart(ref currentBounds, 0);
                            OM.SetMajorStart(ref currentBounds, OM.MajorStart(previousElementBounds) + lineMajorSize + lineSpacing);

                            if (lineNeedsReposition)
                            {
                                // reposition the previous line (countInLine items)
                                for (uint i = 0; i < countInLine; i++)
                                {
                                    var dataIndex = currentIndex - 1 - i;
                                    var bounds    = m_elementManager.GetLayoutBoundsForDataIndex((int)dataIndex);
                                    OM.SetMajorSize(ref bounds, lineMajorSize);
                                    m_elementManager.SetLayoutBoundsForDataIndex((int)dataIndex, bounds);
                                }
                            }

                            // Setup for next line.
                            lineMajorSize       = OM.MajorSize(currentBounds);
                            lineOffset          = OM.MajorStart(currentBounds);
                            lineNeedsReposition = false;
                            countInLine         = 1;
                        }
                        else
                        {
                            // More space is available in this row.
                            OM.SetMinorStart(ref currentBounds, OM.MinorStart(previousElementBounds) + OM.MinorSize(previousElementBounds) + (minItemSpacing));
                            OM.SetMajorStart(ref currentBounds, lineOffset);
                            lineMajorSize       = Math.Max(lineMajorSize, OM.MajorSize(currentBounds));
                            lineNeedsReposition = OM.MajorSize(previousElementBounds) != OM.MajorSize(currentBounds);
                            countInLine++;
                        }
                    }
                    else
                    {
                        // Backward
                        double remainingSpace = OM.MinorStart(previousElementBounds) - (OM.Minor(desiredSize) + minItemSpacing);
                        if (countInLine >= maxItemsPerLine || m_algorithmCallbacks.Algorithm_ShouldBreakLine(currentIndex, remainingSpace))
                        {
                            // Does not fit, wrap to the previous row
                            var availableSizeMinor = OM.Minor(availableSize);
                            OM.SetMinorStart(ref currentBounds, !double.IsInfinity(availableSizeMinor) ? availableSizeMinor - OM.Minor(desiredSize) : 0.0);
                            OM.SetMajorStart(ref currentBounds, lineOffset - OM.Major(desiredSize) - lineSpacing);

                            if (lineNeedsReposition)
                            {
                                var previousLineOffset = OM.MajorStart(m_elementManager.GetLayoutBoundsForDataIndex((int)(currentIndex + countInLine + 1)));
                                // reposition the previous line (countInLine items)
                                for (uint i = 0; i < countInLine; i++)
                                {
                                    var dataIndex = currentIndex + 1 + (int)i;
                                    if (dataIndex != anchorIndex)
                                    {
                                        var bounds = m_elementManager.GetLayoutBoundsForDataIndex(dataIndex);
                                        OM.SetMajorStart(ref bounds, previousLineOffset - lineMajorSize - lineSpacing);
                                        OM.SetMajorSize(ref bounds, lineMajorSize);
                                        m_elementManager.SetLayoutBoundsForDataIndex(dataIndex, bounds);
                                    }
                                }
                            }

                            // Setup for next line.
                            lineMajorSize       = OM.MajorSize(currentBounds);
                            lineOffset          = OM.MajorStart(currentBounds);
                            lineNeedsReposition = false;
                            countInLine         = 1;
                        }
                        else
                        {
                            // Fits in this row. put it in the previous position
                            OM.SetMinorStart(ref currentBounds, OM.MinorStart(previousElementBounds) - OM.Minor(desiredSize) - minItemSpacing);
                            OM.SetMajorStart(ref currentBounds, lineOffset);
                            lineMajorSize       = Math.Max(lineMajorSize, OM.MajorSize(currentBounds));
                            lineNeedsReposition = OM.MajorSize(previousElementBounds) != OM.MajorSize(currentBounds);
                            countInLine++;
                        }
                    }

                    m_elementManager.SetLayoutBoundsForDataIndex(currentIndex, currentBounds);

                    previousIndex = currentIndex;
                    currentIndex += step;
                }

                // If we did not reach the top or bottom of the extent, we realized one
                // extra item before we knew we were outside the realization window. Do not
                // account for that element in the indicies inside the realization window.
                if (direction == GenerateDirection.Forward)
                {
                    int dataCount = m_context.ItemCount;
                    m_lastRealizedDataIndexInsideRealizationWindow = previousIndex == dataCount - 1 ? dataCount - 1 : previousIndex - 1;
                    m_lastRealizedDataIndexInsideRealizationWindow = Math.Max(0, m_lastRealizedDataIndexInsideRealizationWindow);
                }
                else
                {
                    int dataCount = m_context.ItemCount;
                    m_firstRealizedDataIndexInsideRealizationWindow = previousIndex == 0 ? 0 : previousIndex + 1;
                    m_firstRealizedDataIndexInsideRealizationWindow = Math.Min(dataCount - 1, m_firstRealizedDataIndexInsideRealizationWindow);
                }

                m_elementManager.DiscardElementsOutsideWindow(direction == GenerateDirection.Forward, currentIndex);
            }
        }
        private int GetAnchorIndex(
            Size availableSize,
            bool isWrapping,
            double minItemSpacing,
            string layoutId)
        {
            int   anchorIndex    = -1;
            Point anchorPosition = default;

            if (!IsVirtualizingContext)
            {
                // Non virtualizing host, start generating from the element 0
                anchorIndex = ((IVirtualizingLayoutContextOverrides)m_context).ItemCountCore() > 0 ? 0 : -1;
            }
            else
            {
                bool isRealizationWindowConnected = m_elementManager.IsWindowConnected(RealizationRect, OM.ScrollOrientation, m_scrollOrientationSameAsFlow);
                // Item spacing and size in non-virtualizing direction change can cause elements to reflow
                // and get a new column position. In that case we need the anchor to be positioned in the
                // correct column.
                bool needAnchorColumnRevaluation = isWrapping && (
                    OM.Minor(m_lastAvailableSize) != OM.Minor(availableSize) ||
                    m_lastItemSpacing != minItemSpacing ||
                    m_collectionChangePending);

                var suggestedAnchorIndex = m_context.RecommendedAnchorIndex;

                bool isAnchorSuggestionValid = suggestedAnchorIndex >= 0 &&
                                               m_elementManager.IsDataIndexRealized(suggestedAnchorIndex);

                if (isAnchorSuggestionValid)
                {
                    anchorIndex = m_algorithmCallbacks.Algorithm_GetAnchorForTargetElement(
                        suggestedAnchorIndex,
                        availableSize,
                        m_context).Index;

                    if (m_elementManager.IsDataIndexRealized(anchorIndex))
                    {
                        var anchorBounds = m_elementManager.GetLayoutBoundsForDataIndex(anchorIndex);
                        if (needAnchorColumnRevaluation)
                        {
                            // We were provided a valid anchor, but its position might be incorrect because for example it is in
                            // the wrong column. We do know that the anchor is the first element in the row, so we can force the minor position
                            // to start at 0.
                            anchorPosition = OM.MinorMajorPoint(0, OM.MajorStart(anchorBounds));
                        }
                        else
                        {
                            anchorPosition = new Point(anchorBounds.X, anchorBounds.Y);
                        }
                    }
                    else
                    {
                        // It is possible to end up in a situation during a collection change where GetAnchorForTargetElement returns an index
                        // which is not in the realized range. Eg. insert one item at index 0 for a grid layout.
                        // SuggestedAnchor will be 1 (used to be 0) and GetAnchorForTargetElement will return 0 (left most item in row). However 0 is not in the
                        // realized range yet. In this case we realize the gap between the target anchor and the suggested anchor.
                        int firstRealizedDataIndex = m_elementManager.GetDataIndexFromRealizedRangeIndex(0);
                        Debug.Assert(anchorIndex < firstRealizedDataIndex);
                        for (int i = firstRealizedDataIndex - 1; i >= anchorIndex; --i)
                        {
                            m_elementManager.EnsureElementRealized(false /*forward*/, i, layoutId);
                        }

                        var anchorBounds = m_elementManager.GetLayoutBoundsForDataIndex(suggestedAnchorIndex);
                        anchorPosition = OM.MinorMajorPoint(0, OM.MajorStart(anchorBounds));
                    }
                }
                else if (needAnchorColumnRevaluation || !isRealizationWindowConnected)
                {
                    // The anchor is based on the realization window because a connected ItemsRepeater might intersect the realization window
                    // but not the visible window. In that situation, we still need to produce a valid anchor.
                    var anchorInfo = m_algorithmCallbacks.Algorithm_GetAnchorForRealizationRect(availableSize, m_context);
                    anchorIndex    = anchorInfo.Index;
                    anchorPosition = OM.MinorMajorPoint(0, anchorInfo.Offset);
                }
                else
                {
                    // No suggestion - just pick first in realized range
                    anchorIndex = m_elementManager.GetDataIndexFromRealizedRangeIndex(0);
                    var firstElementBounds = m_elementManager.GetLayoutBoundsForRealizedIndex(0);
                    anchorPosition = new Point(firstElementBounds.X, firstElementBounds.Y);
                }
            }

            Debug.Assert(anchorIndex == -1 || m_elementManager.IsIndexValidInData(anchorIndex));
            m_firstRealizedDataIndexInsideRealizationWindow = m_lastRealizedDataIndexInsideRealizationWindow = anchorIndex;
            if (m_elementManager.IsIndexValidInData(anchorIndex))
            {
                if (!m_elementManager.IsDataIndexRealized(anchorIndex))
                {
                    // Disconnected, throw everything and create new anchor
                    m_elementManager.ClearRealizedRange();

                    var anchor = m_context.GetOrCreateElementAt(anchorIndex, ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle);
                    m_elementManager.Add(anchor, anchorIndex);
                }

                var anchorElement = m_elementManager.GetRealizedElement(anchorIndex);
                var desiredSize   = MeasureElement(anchorElement, anchorIndex, availableSize, m_context);
                var layoutBounds  = new Rect(anchorPosition.X, anchorPosition.Y, desiredSize.Width, desiredSize.Height);
                m_elementManager.SetLayoutBoundsForDataIndex(anchorIndex, layoutBounds);
            }
            else
            {
                // Throw everything away
                m_elementManager.ClearRealizedRange();
            }

            // TODO: Perhaps we can track changes in the property setter
            m_lastAvailableSize = availableSize;
            m_lastItemSpacing   = minItemSpacing;

            return(anchorIndex);
        }
Example #15
0
        /// <summary>
        /// Returns info about <c>bitmap</c>. 
        /// 
        /// If bitmap is not in the domain of <c>om</c>, the basis blade in the returned value will be null,
        /// and the domainIdx will be -1.
        /// 
        /// If the grade of the bitmap is 1, the domainIdx will be -1 because it is
        /// assumed to be an input vector.
        /// </summary>
        /// <param name="S"></param>
        /// <param name="om"></param>
        /// <param name="bitmap"></param>
        /// <returns><c>BasisBlade, grade, domainIdx</c> for <c>bitmap</c></returns>
        public static G25.Tuple<RefGA.BasisBlade, int, int> GetDomainBladeInfo(Specification S, OM om, uint bitmap)
        {
            int grade = (int)RefGA.Bits.BitCount(bitmap);

            if (grade == 1)  // basis vector
                return new G25.Tuple<RefGA.BasisBlade, int, int>(new RefGA.BasisBlade(bitmap), grade, -1);

            // find the bitmap in the domain
            RefGA.BasisBlade B = null;
            int domainIdx = -1;
            for (int i = 0; i < om.DomainForGrade(grade).Length; i++)
            {
                if (bitmap == om.DomainForGrade(grade)[i].bitmap)
                {
                    domainIdx = i;
                    B = om.DomainForGrade(grade)[i];
                    break;
                }
            }

            return new G25.Tuple<RefGA.BasisBlade, int, int>(B, grade, domainIdx);
        }
Example #16
0
        public static void WriteOMtoOMcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, OM srcOm, OM dstOm)
        {
            StringBuilder declSB = cgd.m_declSB;
            StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;
            string srcTypeName = FT.GetMangledName(S, srcOm.Name);
            string dstTypeName = FT.GetMangledName(S, dstOm.Name);
            bool writeDecl = S.OutputC();

            string funcName = GetFunctionName(S, (S.OutputC() ? "" : dstTypeName), "set", srcTypeName + "_to_" + dstTypeName);

            // do we inline this func?
            string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " ");
            string dstArgStr = (S.OutputC()) ? (dstTypeName + " *dst, ") : "";
            string refStr = (S.OutputC()) ? "*" : ((S.OutputCpp()) ? "&" : "");
            string CONST = (S.OutputCppOrC()) ? "const " : "";

            string funcDecl = inlineStr + "void " + funcName + "(" + dstArgStr + CONST + srcTypeName + " " + refStr + "src)";

            // write comment, function declaration
            Comment comment = new Comment("Copies a " + srcTypeName + " to a " + dstTypeName + "\n" +
                "Warning 1: coordinates which cannot be represented are silenty lost.\n" +
                "Warning 2: coordinates which are not present in 'src' are set to zero in 'dst'.\n");
            if (writeDecl)
            {
                comment.Write(declSB, S, 0);
                declSB.Append(funcDecl);
                declSB.AppendLine(";");
            }

            if (S.OutputCSharpOrJava())
                comment.Write(defSB, S, 0);

            defSB.Append(funcDecl);
            {
                defSB.AppendLine(" {");

                Dictionary<Tuple<int, int, int>, Tuple<int, int, double>> D = dstOm.getMapping(srcOm);

                StringBuilder copySB = new StringBuilder();
                List<string> setToZero = new List<string>();

                string matrixStr = (S.OutputC()) ? "m" : "m_m";
                string dstMatrixStr = (S.OutputC()) ? "dst->" + matrixStr : matrixStr;
                string ptrStr = (S.OutputC()) ? "->" : ".";

                // For all grades of som, for all columns, for all rows, check D, get entry, set; otherwise set to null
                // Do not use foreach() on D because we want to fill in coordinates in their proper order.
                for (int gradeIdx = 1; gradeIdx < dstOm.Domain.Length; gradeIdx++)
                {
                    for (int somRangeIdx = 0; somRangeIdx < dstOm.Range[gradeIdx].Length; somRangeIdx++)
                    {
                        for (int somDomainIdx = 0; somDomainIdx < dstOm.Domain[gradeIdx].Length; somDomainIdx++)
                        {
                            Tuple<int, int, int> key = new Tuple<int, int, int>(gradeIdx, somDomainIdx, somRangeIdx);

                            int somMatrixIdx = dstOm.getCoordinateIndex(gradeIdx, somDomainIdx, somRangeIdx);
                            string dstString = dstMatrixStr + gradeIdx + "[" + somMatrixIdx + "] = ";
                            if (D.ContainsKey(key))
                            {
                                Tuple<int, int, double> value = D[key];
                                int gomMatrixIdx = srcOm.getCoordinateIndex(gradeIdx, value.Value1, value.Value2);
                                double multiplier = value.Value3;
                                string multiplierString = (multiplier == 1.0) ? "" : (FT.DoubleToString(S, multiplier) + " * ");

                                copySB.AppendLine("\t" + dstString + multiplierString + " src" + ptrStr + matrixStr + gradeIdx + "[" + gomMatrixIdx + "];");
                            }
                            else
                            {
                                setToZero.Add(dstString);
                            }
                        }
                    }
                }

                // append copy statements
                defSB.Append(copySB);

                // append statements to set coordinates to zero
                if (setToZero.Count > 0)
                {
                    int cnt = 0;
                    defSB.Append("\t");
                    foreach (string str in setToZero)
                    {
                        defSB.Append(str);
                        cnt++;
                        if (cnt > 8)
                        {
                            cnt = 0;
                            defSB.AppendLine("");
                            defSB.Append("\t\t");
                        }
                    }
                    defSB.AppendLine(FT.DoubleToString(S, 0.0) + ";");
                }

                defSB.AppendLine("}");
            }
        }
        // Align elements within a line. Note that this does not modify LayoutBounds. So if we get
        // repeated measures, the LayoutBounds remain the same in each layout.
        private void PerformLineAlignment(
            int lineStartIndex,
            int countInLine,
            double spaceAtLineStart,
            double spaceAtLineEnd,
            double lineSize,
            LineAlignment lineAlignment,
            bool isWrapping,
            Size finalSize,
            string layoutId)
        {
            for (int rangeIndex = lineStartIndex; rangeIndex < lineStartIndex + countInLine; ++rangeIndex)
            {
                var bounds = m_elementManager.GetLayoutBoundsForRealizedIndex(rangeIndex);
                OM.SetMajorSize(ref bounds, lineSize);

                if (!m_scrollOrientationSameAsFlow)
                {
                    // Note: Space at start could potentially be negative
                    if (spaceAtLineStart != 0 || spaceAtLineEnd != 0)
                    {
                        double totalSpace = spaceAtLineStart + spaceAtLineEnd;
                        switch (lineAlignment)
                        {
                        case LineAlignment.Start:
                        {
                            OM.SetMinorStart(ref bounds, OM.MinorStart(bounds) - spaceAtLineStart);
                            break;
                        }

                        case LineAlignment.End:
                        {
                            OM.SetMinorStart(ref bounds, OM.MinorStart(bounds) + spaceAtLineEnd);
                            break;
                        }

                        case LineAlignment.Center:
                        {
                            OM.SetMinorStart(ref bounds, OM.MinorStart(bounds) - spaceAtLineStart);
                            OM.SetMinorStart(ref bounds, OM.MinorStart(bounds) + totalSpace / 2);
                            break;
                        }

                        case LineAlignment.SpaceAround:
                        {
                            double interItemSpace = countInLine >= 1 ? totalSpace / (countInLine * 2) : 0;
                            OM.SetMinorStart(ref bounds, OM.MinorStart(bounds) - spaceAtLineStart);
                            OM.SetMinorStart(ref bounds, OM.MinorStart(bounds) + interItemSpace * ((rangeIndex - lineStartIndex + 1) * 2 - 1));
                            break;
                        }

                        case LineAlignment.SpaceBetween:
                        {
                            double interItemSpace = countInLine > 1 ? totalSpace / (countInLine - 1) : 0;
                            OM.SetMinorStart(ref bounds, OM.MinorStart(bounds) - spaceAtLineStart);
                            OM.SetMinorStart(ref bounds, OM.MinorStart(bounds) + interItemSpace * (rangeIndex - lineStartIndex));
                            break;
                        }

                        case LineAlignment.SpaceEvenly:
                        {
                            double interItemSpace = countInLine >= 1 ? totalSpace / (countInLine + 1) : 0;
                            OM.SetMinorStart(ref bounds, OM.MinorStart(bounds) - spaceAtLineStart);
                            OM.SetMinorStart(ref bounds, OM.MinorStart(bounds) + interItemSpace * (rangeIndex - lineStartIndex + 1));
                            break;
                        }
                        }
                    }
                }

                bounds.X -= m_lastExtent.X;
                bounds.Y -= m_lastExtent.Y;

                if (!isWrapping)
                {
                    OM.SetMinorSize(ref bounds, Math.Max(OM.MinorSize(bounds), OM.Minor(finalSize)));
                }

                var element = m_elementManager.GetAt(rangeIndex);

                element.Arrange(bounds);
            }
        }
Example #18
0
        /// <summary>
        /// Computes the signs for the plan as computed by GetOmInitFromVectorsPlan().
        /// 
        /// Because the basis blades in the domain of 'om' do not have to be in canonical order,
        /// there may be some signs required to correctly executed the plan
        /// </summary>
        /// <param name="S"></param>
        /// <param name="om"></param>
        /// <param name="plan"></param>
        /// <returns>signs for the plan</returns>
        public static double[][] ComputeOmInitFromVectorsSigns(Specification S, OM om, uint[][][] plan)
        {
            double[][] result = new double[S.m_dimension + 1][];

            for (int g = 1; g <= S.m_dimension; g++)
            {
                result[g] = new double[om.DomainForGrade(g).Length];
                for (int d = 0; d < om.DomainForGrade(g).Length; d++)
                {
                    // get domain blade we have to construct
                    RefGA.BasisBlade D = om.DomainForGrade(g)[d];

                    // follow the plan to construct the blade
                    RefGA.BasisBlade P = RefGA.BasisBlade.ONE;
                    for (int p = 0; p < plan[g][d].Length; p++)
                    {
                        G25.Tuple<RefGA.BasisBlade, int, int> info = GetDomainBladeInfo(S, om, plan[g][d][p]);
                        P = RefGA.BasisBlade.op(P, info.Value1);
                    }

                    // compute sign difference & store
                    double s = D.scale / P.scale;
                    result[g][d] = s;
                }
            }

            return result;
        }
Example #19
0
        public void AddVariable(string id, string value, OM.WixAuthoringOM.Bundle.Variable.VariableElement.VariableDataType type)
        {
            OM.WixAuthoringOM.Bundle.Variable.VariableElement varElement = new OM.WixAuthoringOM.Bundle.Variable.VariableElement();
            varElement.Name = id;
            varElement.Value = value;
            varElement.Type = type;

            Wix.Bundle.Variables.Add(varElement);
        }