Exemple #1
0
        /// <summary>
        /// 更新物件,因为是增量更新维护,所以current_time递减或变小时,必须先Flush()后Update().
        /// </summary>
        /// <param name="current_time"></param>
        public void Update(float current_time)
        {
            if (current_time < prev_time)
            {
                Flush();
            }
            else
            {
                UpdatingStoryboardObjects.RemoveAll((obj) => (current_time > obj.FrameEndTime || current_time < obj.FrameStartTime) &&
                                                    (obj.CurrentUpdater = null) == null /*clean CurrentUpdater*/);
            }

            prev_time = current_time;

            bool hasAdded = Scan(current_time);

            if (hasAdded)
            {
                UpdatingStoryboardObjects.Sort((a, b) =>
                {
                    return(a.Z - b.Z);
                });
            }

            var need_parallel = UpdatingStoryboardObjects.Count >= Setting.ParallelUpdateObjectsLimitCount && Setting.ParallelUpdateObjectsLimitCount != 0;

            ParallelableForeachExecutor.Foreach(need_parallel, UpdatingStoryboardObjects, obj => obj.Update(current_time));
        }
        /*
         *  MX,0,94938,130595,320     ---simplify--->     MX,0,94938,94938,320,320
         *
         *  it could avoid a part cause about command conflict:
         *  MX,0,94938,130595,320
         *  M,20,95008,95078,320,240,322.9271,226.3689
         *  M,20,95078,95148,322.9271,226.3689,320.6659,236.2696
         *  M,20,95148,95218,320.6659,236.2696,321.3301,232.5321
         */

        private void TrimHoldingStatusCommand(IEnumerable <StoryboardObject> storyboard_objects, ref int effect_count)
        {
            var x = 0;

            ParallelableForeachExecutor.Foreach(true, storyboard_objects, obj =>
            {
                foreach (CommandTimeline timeline in obj.CommandMap.Values)
                {
                    if (!timeline.Overlay)
                    {
                        continue;
                    }

                    for (int i = 0; i < timeline.Count; i++)
                    {
                        if (timeline[i] is ValueCommand cmd)
                        {
                            if (cmd.EqualityComparer.Equals(cmd.GetEndValue(), cmd.GetStartValue()) && cmd.Easing == EasingTypes.None)
                            {
                                timeline.Remove(cmd);
                                cmd.EndTime = cmd.StartTime;
                                timeline.Add(cmd);

                                x++;
                            }
                        }
                    }
                }
            });

            effect_count = x;
        }
Exemple #3
0
        /// <summary>
        /// 计算Fade时间轴,优化物件的FrameStartTime/EndTime,避免不必要的计算
        /// 点名批评 -> 181957
        ///
        ///
        ///Sprite,Foreground,Centre,"sb\light.png",320,240
        /// S,0,0,,0.22        <----Non-optimze obj.FrameStartTime
        /// MX,0,0,,278
        /// F,0,126739,,0            <----Kill by Optimzer
        /// F,0,208016,,0.7,1           <----Actual obj.FrameStartTime
        /// C,0,208016,,255,255,255
        /// P,0,208016,,A
        /// MY,0,208016,209286,520,-40   <----Actual obj.FrameEndTime
        ///
        /// </summary>
        /// <param name="Storyboard_objects"></param>
        /// <param name="effect_count"></param>
        public void TrimFrameTime(IEnumerable <StoryboardObject> Storyboard_objects, ref int effect_count)
        {
            var t = 0;

            ParallelableForeachExecutor.Foreach(true, Storyboard_objects, obj => {
                if (obj == null ||
                    obj is StoryboardAnimation || //qnmd
                    !obj.CommandMap.TryGetValue(Event.Fade, out var fade_list) ||
                    fade_list.Count == 0 ||
                    fade_list.Overlay ||
                    fade_list.Count <= 1
                    )
                {
                    return;
                }

                var first_fade = fade_list.First() as FadeCommand;

                if (first_fade != null)
                {
                    FadeCommand front_fade = null;

                    if ((first_fade.EndTime == 0 || first_fade.StartTime == first_fade.EndTime) && //是否为立即命令(dutation=0)
                        first_fade.EndValue == 0) //是否是隐藏的
                    {
                        if (fade_list.Skip(1).First() is FadeCommand second_fade)
                        {
                            front_fade = second_fade;
                        }
                    }
                    else if (first_fade.StartValue == 0)
                    {
                        front_fade = first_fade;
                    }

                    if (front_fade != null && obj.FrameStartTime <= front_fade.StartTime)
                    {
                        var trigger_time    = obj.ContainTrigger ? obj.CommandMap[Event.Trigger].Min(x => x.StartTime) : int.MaxValue;
                        var trim_start_time = Math.Min(trigger_time, front_fade.StartTime);

                        obj.BaseTransformResetAction += x => x.FrameStartTime = trim_start_time;
                        obj.FrameStartTime            = trim_start_time;
                        Suggest(obj, $"FrameTime可优化成{front_fade.StartTime}");
                        t++;
                    }
                }

                var last_fade = fade_list.Last() as FadeCommand;

                if (last_fade != null && last_fade.EndValue == 0)
                {
                    obj.FrameEndTime = last_fade.EndTime;
                    Suggest(obj, $"EndTime可优化成{last_fade.StartTime}.");
                    t++;
                }
            });

            effect_count = t;
        }
        public void CombineCommands(IEnumerable <StoryboardObject> Storyboard_objects, ref int effect_count)
        {
            var t = 0;

            ParallelableForeachExecutor.Foreach(true, Storyboard_objects, obj =>
            {
                foreach (var pair in obj.CommandMap)
                {
                    var real_timeline = pair.Value;

                    //立即求值
                    var normal_timeline = pair.Value.OfType <ValueCommand>().ToArray();

                    if (normal_timeline.Length == 0)
                    {
                        continue;
                    }

                    //ValueCommand<TYPE_VALUE>我敲里吗
                    var type             = normal_timeline.First().GetType();
                    var end_value_prop   = type.GetField("EndValue");
                    var start_value_prop = type.GetField("StartValue");

                    for (int i = 0; i < normal_timeline.Count() - 1; i++)
                    {
                        var cmd      = normal_timeline[i];
                        var next_cmd = normal_timeline[i + 1];

                        if ((cmd.Easing == next_cmd.Easing) &&
                            (cmd.EndTime == next_cmd.StartTime) &&
                            (end_value_prop.GetValue(cmd) == start_value_prop.GetValue(next_cmd)))
                        {
                            //combine
                            var new_cmd = (ValueCommand)type.Assembly.CreateInstance(type.FullName);

                            new_cmd.EndTime   = next_cmd.EndTime;
                            new_cmd.StartTime = cmd.StartTime;
                            new_cmd.Easing    = cmd.Easing;
                            end_value_prop.SetValue(new_cmd, end_value_prop.GetValue(next_cmd));
                            start_value_prop.SetValue(new_cmd, start_value_prop.GetValue(cmd));

                            //remove old
                            var index = real_timeline.IndexOf(cmd);
                            real_timeline.Remove(cmd);
                            real_timeline.Remove(next_cmd);

                            //insert new
                            real_timeline.Add(new_cmd);

                            //skip next command
                            i++;

                            t++;
                        }
                    }
                }
            });
            effect_count = t;
        }
Exemple #5
0
        /// <summary>
        /// 将时间轴单个立即命令直接应用到物件上,减少物件执行命令频率
        /// 点名批评 -> 181957
        ///
        ///Sprite,Foreground,Centre,"sb\light.png",320,240
        /// S,0,0,,0.22        <---- Set as Object.Scale inital value by Optimzer
        /// MX,0,0,,278        <---- Set as Object.Position.X inital value by Optimzer
        /// F,0,126739,,0
        /// F,0,208016,,0.7,1
        /// C,0,208016,,255,255,255
        /// P,0,208016,,A             <---- Set as Object.IsAdditive value by Optimzer
        /// MY,0,208016,209286,520,-40
        ///
        /// </summary>
        /// <param name="Storyboard_objects"></param>
        /// <param name="effect_count"></param>
        public void TrimInitalEffect(IEnumerable <StoryboardObject> Storyboard_objects, ref int effect_count)
        {
            var events = Enum.GetValues(typeof(Event));


            var t = 0;

            ParallelableForeachExecutor.Foreach(true, Storyboard_objects, obj =>
            {
                //物件命令数量!=0 且 无Trigger对应类型的子命令
                foreach (var timeline in obj.CommandMap.Where(x => x.Value.Count == 1 && ((!obj.ContainTrigger) || (
                                                                                              !obj.CommandMap[Event.Trigger]
                                                                                              .OfType <GroupCommand>()
                                                                                              .SelectMany(
                                                                                                  l => l.SubCommands
                                                                                                  .Where(w => w.Key == x.Key)).Select(m => m.Value)
                                                                                              .Any()))).Select(e => e.Value))
                {
                    Command cmd = timeline.FirstOrDefault();

                    if (cmd.EndTime <= obj.FrameStartTime &&
                        cmd.StartTime == cmd.EndTime
                        //C,0,0,,0,0,0,226,172,247
                        && ((cmd is ValueCommand) /*&&(vcmd.EqualityComparer.Equals(vcmd.GetEndValue(), vcmd.GetStartValue()))*/ ||
                            cmd is StateCommand))
                    {
                        /*
                         * 低于时间或者初始变化值 都相同 的命令可以直接应用到物件上
                         */

                        timeline.Remove(cmd);

                        obj.BaseTransformResetAction += (target) =>
                        {
                            cmd.Execute(target, cmd.EndTime + 1);
                        };

                        t++;
                    }
                }

                //去掉没有命令的时间轴
                foreach (Event e in events)
                {
                    if (obj.CommandMap.TryGetValue(e, out var timeline) && timeline.Count == 0)
                    {
                        obj.CommandMap.Remove(e);
                        t++;
                    }
                }
            });

            effect_count = t;
        }
        /// <summary>
        /// 删除无用的命令,即理论上根本不会被执行到的命令
        /// 点名批评 -> 381480
        ///
        ///
        /// </summary>
        /// <param name="Storyboard_objects"></param>
        /// <param name="effect_count"></param>
        public void RemoveUnusedCommand(IEnumerable <StoryboardObject> Storyboard_objects, ref int effect_count)
        {
            Event[] skip_event = new[] { Event.Loop, Event.Trigger };

            var z = 0;

            ParallelableForeachExecutor.Foreach(true, Storyboard_objects, obj =>
            {
                foreach (var timeline in obj.CommandMap.Where(x => !skip_event.Contains(x.Key)).Select(x => x.Value))
                {
                    for (int i = 0; timeline.Overlay && i < timeline.Count - 1; i++)
                    {
                        var cmd = timeline[i];

                        /*
                         *(cmd)      : |--------------------------|
                         *(next_cmd) :             |--------------|       <--- Killed , biatch
                         */
                        for (int t = i + 1; timeline.Overlay && t < timeline.Count; t++)
                        {
                            var next_cmd = timeline[t];

                            if (next_cmd.StartTime > cmd.EndTime)
                            {
                                break;
                            }

                            if (
                                next_cmd.EndTime <= cmd.EndTime &&
                                next_cmd.EndTime != next_cmd.StartTime &&
                                cmd.CompareTo(next_cmd) <= 0)
                            {
                                timeline.Remove(next_cmd);

                                Log.Debug($"Remove unused command ({next_cmd}) in ({obj}),compare with ({cmd})");
                                Suggest(next_cmd, $"此命令被\"{cmd}\"命令覆盖而不被执行到,可删除");
                                z++;
                            }
                        }
                    }
                }
            });
            effect_count = z;
        }