public virtual void OnDeserialize(BinaryReader stream, StringCacheTable cache_table)
        {
            var count = stream.ReadInt32();

            for (int i = 0; i < count; i++)
            {
                var command = CommandDeserializtionFactory.Create(stream, cache_table);
                AddCommand(command);//todo: use AddCommandRange()
            }

            //ImageFilePath=stream.ReadString();
            ImageFilePath = cache_table[stream.ReadUInt32()];

            FromOsbFile.OnDeserialize(stream);
            FrameStartTime.OnDeserialize(stream);
            FrameEndTime.OnDeserialize(stream);
            layer = (Layer)stream.ReadByte();
            Z.OnDeserialize(stream);

            Postion.OnDeserialize(stream, cache_table);
            Scale.OnDeserialize(stream, cache_table);
            Color.OnDeserialize(stream, cache_table);
            OriginOffset.OnDeserialize(stream, cache_table);
            Rotate.OnDeserialize(stream);

            IsAdditive.OnDeserialize(stream);
            IsHorizonFlip.OnDeserialize(stream);
            IsVerticalFlip.OnDeserialize(stream);

            FileLine.OnDeserialize(stream);

            //try to rebuild base trasform reset action
            var pos      = Postion;
            var start    = FrameStartTime;
            var end      = FrameEndTime;
            var color    = Color;
            var scale    = Scale;
            var additive = IsAdditive;
            var rotate   = Rotate;
            var horizon  = IsHorizonFlip;
            var vertical = IsVerticalFlip;

            BaseTransformResetAction += (StoryboardObject obj) =>
            {
                obj.Postion        = pos;
                obj.FrameStartTime = start;
                obj.FrameEndTime   = end;
                obj.Color          = color;
                obj.Scale          = scale;
                obj.IsAdditive     = additive;
                obj.IsHorizonFlip  = horizon;
                obj.IsVerticalFlip = vertical;
                obj.Rotate         = rotate;
            };
        }
        /* Binary Layout:
         * int: Addable command count
         * ~~~~ : command binary data
         * ....
         */

        public virtual void OnSerialize(BinaryWriter stream, StringCacheTable cache_table)
        {
            /*
             * 因为BaseTransformResetAction无法被序列化,因此只能先计算出来然后再将物件的各个变换值作为反序列化时生成新的初始化回调
             */
            ResetTransform();

            //normal commands
            var commands = CommandMap.Values.SelectMany(l => l).Where(x => !(x is LoopSubTimelineCommand || x is TriggerSubTimelineCommand));

            stream.Write(commands.Count());

            foreach (var command in commands)
            {
                command.OnSerialize(stream, cache_table);
            }

            //ImageFilePath.OnSerialize(stream);
            var image_string_id = cache_table[ImageFilePath];

            stream.Write(image_string_id);

            FromOsbFile.OnSerialize(stream);
            FrameStartTime.OnSerialize(stream);
            FrameEndTime.OnSerialize(stream);
            ((byte)layer).OnSerialize(stream);
            Z.OnSerialize(stream);

            Postion.OnSerialize(stream, cache_table);
            Scale.OnSerialize(stream, cache_table);
            Color.OnSerialize(stream, cache_table);
            OriginOffset.OnSerialize(stream, cache_table);
            Rotate.OnSerialize(stream);

            IsAdditive.OnSerialize(stream);
            IsHorizonFlip.OnSerialize(stream);
            IsVerticalFlip.OnSerialize(stream);

            FileLine.OnSerialize(stream);
        }