Exemple #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="Property"></param>
        /// <returns></returns>
        private void CascadeProperty(ICssProperty Property)
        {
            // Extract this property from every CssPropertySet that has a value for it
            //var propertyList = CssRules.Values.Select(propSet => { return propSet[Property.CssName]; }).ToList();

            var propertyList = new List <ICssProperty>(4);

            foreach (var propSet in CssRules.Values)
            {
                propertyList.Add(propSet[Property.CssName]);
            }

            // Order these properties according to CSS 3.0 specifications
            propertyList.Sort(CssPropertyComparator.Instance);

            // Cascade this list and get what CSS calls the 'Specified' value
            ICssProperty Value = Property;

            foreach (ICssProperty o in propertyList)
            {
                /*var cascade = Value.CascadeAsync(o);
                 * Task.WhenAll(cascade).Wait();// we HAVE to wait here
                 * if (cascade.Result) break;// stop cascading the instant we find a set value*/
                var changed = Value.Cascade(o);
                if (changed)
                {
                    break;         // stop cascading the instant we find a set value
                }
            }

            string SourceState = Value.Source.ToString();

            Cascaded.Set(Property.CssName, Value);
        }
Exemple #2
0
        /// <summary>
        /// Resolves all Css properties to their specified values by cascading
        /// </summary>
        public void Cascade()
        {
            /* XXX: LOTS of room for speed improvement here. We should avoid using LINQ statements in performance critical areas like this. */
            var benchmark_id = Benchmark.Start("style-cascade");

            // Get a list of only the properties with an Assigned value
            AsyncCountdownEvent ctdn = null;

            /*
             * HashSet<AtomicName<ECssPropertyID>> targetFields = new HashSet<AtomicName<ECssPropertyID>>();
             * List<HashSet<AtomicName<ECssPropertyID>>> allFields = CssRules.Values.Select(x => { return x.SetProperties; }).ToList();
             */
            var targetFields = new FlagCollection <ECssPropertyID>((int)ECssPropertyID.MAX_VALUE);
            List <FlagCollection <ECssPropertyID> > allFields = CssRules.Values.Select(x => { return(x.SetProperties); }).ToList();

            // Remove duplicates
            //foreach (HashSet<AtomicName<ECssPropertyID>> fields in allFields)
            foreach (FlagCollection <ECssPropertyID> fields in allFields)
            {
                targetFields.And(fields);
            }

            if (targetFields.ActiveFlags > 0)
            {
                // Cascade all those set values
                ctdn = new AsyncCountdownEvent(targetFields.ActiveFlags);

                // Loop over all target properties
                foreach (int flagIndex in targetFields)
                //Parallel.ForEach(targetFields, async (AtomicString propName) =>
                {
                    try
                    {
                        AtomicName <ECssPropertyID> propName = new AtomicName <ECssPropertyID>(flagIndex);
                        // Extract this property from every CssPropertySet that has a value for it
                        var propertyList = CssRules.Values.Select(x => { return(x.Get(propName)); }).ToList();

                        // Order these properties according to CSS 3.0 specifications
                        propertyList.Sort(CssPropertyComparator.Instance);

                        /*
                         * // Because cascading overwrites an existing value with the one from the next propertyset we need to reverse this list.
                         * propertyList.Reverse();*/

                        // Cascade this list and get what CSS calls the 'Specified' value
                        ICssProperty Value = Cascaded.Get(propName);
                        foreach (ICssProperty o in propertyList)
                        {
                            //bool b = await Value.CascadeAsync(o);
                            bool b = Value.Cascade(o);
                            if (b)
                            {
                                break;   // stop cascading the instant we find a set value
                            }
                        }

                        string SourceState = Value.Source.ToString();
                        //await Cascaded.Set(propName, Value);
                        Cascaded.Set(propName, Value);
                    }
                    finally
                    {
                        ctdn.Signal();
                    }

                    //});
                }

                ctdn.WaitAsync().Wait();
            }

            // Recalculate ALL properties
            var PropList = Cascaded.GetAll().ToList();

            /*ctdn = new AsyncCountdownEvent(PropList.Count);
             * Parallel.For(0, PropList.Count, (int i) =>
             * {
             *  ICssProperty prop = PropList[i];
             *  // We always want to compute these now to get their values resolved. otherwise any with just assigned values will not interpret and output computed values.
             *  prop.Update(ComputeNow: true);
             *  ctdn.Signal();
             * });
             * ctdn.WaitAsync().Wait();*/


            for (int i = 0; i < PropList.Count; i++)
            {
                ICssProperty prop = PropList[i];
                // We always want to compute these now to get their values resolved. otherwise any with just assigned values will not interpret and output computed values.
                prop.Update(ComputeNow: true);
            }


            // Any values that changed due to this cascade should have thrown a property change event to let the style system know what it needs to update

            // Remove cascade flag
            ClearFlag(EPropertySystemDirtFlags.NeedsToCascade);
            Benchmark.Stop(benchmark_id);
        }