Esempio n. 1
0
        public DataArray Serialize()
        {
            var array = new DataArray();

            array.AddNode(new DataAtom(xP));
            array.AddNode(new DataAtom(yP));
            array.AddNode(new DataAtom(tolerance));
            array.AddNode(new DataAtom(target.ToArgb()));
            array.AddNode(new DataAtom(midiNote));
            return(array);
        }
Esempio n. 2
0
        private static DataArray NamedArray(string name, DataArray siblings)
        {
            var array = new DataArray();

            array.AddNode(DataSymbol.Symbol(name));
            foreach (var n in siblings.Children)
            {
                array.AddNode(n);
            }
            return(array);
        }
Esempio n. 3
0
        public static DataArray MakeMoggDta(DataArray array)
        {
            var moggDta    = new DataArray();
            var trackArray = new DataArray();

            trackArray.AddNode(DataSymbol.Symbol("tracks"));
            var trackSubArray = trackArray.AddNode(new DataArray());

            foreach (var child in array.Array("song").Array("tracks").Array(1).Children)
            {
                if (child is DataArray a && a.Children[1] is DataArray b && b.Count > 0)
                {
                    trackSubArray.AddNode(child);
                }
            }
            var totalTracks = array.Array("song").Array("pans").Array(1).Children.Count;
            // Get the last track number. This is based on the assumption that the tracks are in order
            // We have to filter out empty track arrays because GHtoRB(?) does stuff like (keys ()) instead
            // of leaving out the keys array entirely
            var lastTrack = ((trackSubArray.Children
                              .Where(x => x is DataArray dx ? dx.Array(1).Children.Count > 0 : false)
                              .Last() as DataArray)
                             .Array(1).Children.Last() as DataAtom).Int;
            var crowdChannel = array.Array("song").Array("crowd_channels")?.Int(1);

            if (crowdChannel != null)
            {
                if (crowdChannel == lastTrack + 2)
                {
                    trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})"));
                }
                else if (crowdChannel == lastTrack + 3)
                {
                    trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})"));
                }
                trackSubArray.AddNode(DTX.FromDtaString($"crowd ({crowdChannel} {crowdChannel + 1})"));
            }
            else
            {
                if (totalTracks == lastTrack + 2)
                {
                    trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})"));
                }
                else if (totalTracks == lastTrack + 3)
                {
                    trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})"));
                }
            }
            moggDta.AddNode(trackArray);
            moggDta.AddNode(array.Array("song").Array("pans"));
            moggDta.AddNode(array.Array("song").Array("vols"));
            return(moggDta);
        }
Esempio n. 4
0
        private static DataArray NamedItem(string name, DataNode value)
        {
            if (value is DataArray da)
            {
                return(NamedArray(name, da));
            }
            var array = new DataArray();

            array.AddNode(DataSymbol.Symbol(name));
            array.AddNode(value);
            return(array);
        }
Esempio n. 5
0
        private void Serialize(string filename)
        {
            var data = new DataArray();

            data.AddNode(DataSymbol.Symbol("points"));
            foreach (var p in points)
            {
                data.AddNode(p.p.Serialize());
            }
            using (var writer = new System.IO.StreamWriter(filename))
            {
                writer.Write(data.ToString());
            }
        }
Esempio n. 6
0
        public static DataArray MakeMoggDta(DataArray array)
        {
            var moggDta    = new DataArray();
            var trackArray = new DataArray();

            trackArray.AddNode(DataSymbol.Symbol("tracks"));
            var trackSubArray = trackArray.AddNode(new DataArray());

            foreach (var child in array.Array("song").Array("tracks").Array(1).Children)
            {
                trackSubArray.AddNode(child);
            }
            var totalTracks = array.Array("song").Array("pans").Array(1).Children.Count;
            var lastTrack   = ((trackSubArray.Children.Last() as DataArray)
                               .Array(1).Children.Last() as DataAtom).Int;
            var crowdChannel = array.Array("song").Array("crowd_channels")?.Int(1);

            if (crowdChannel != null)
            {
                if (crowdChannel == lastTrack + 2)
                {
                    trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})"));
                }
                else if (crowdChannel == lastTrack + 3)
                {
                    trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})"));
                }
                trackSubArray.AddNode(DTX.FromDtaString($"crowd ({crowdChannel} {crowdChannel + 1})"));
            }
            else
            {
                if (totalTracks == lastTrack + 2)
                {
                    trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})"));
                }
                else if (totalTracks == lastTrack + 3)
                {
                    trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})"));
                }
            }
            moggDta.AddNode(trackArray);
            moggDta.AddNode(array.Array("song").Array("pans"));
            moggDta.AddNode(array.Array("song").Array("vols"));
            return(moggDta);
        }
Esempio n. 7
0
File: DTX.cs Progetto: maxton/DtxCS
        private static void AddLiteral(DataArray current, string tmp_literal)
        {
            int   tmp_int;
            float tmp_float;

            if (int.TryParse(tmp_literal, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tmp_int))
            {
                current.AddNode(new DataAtom(tmp_int));
            }
            else if (float.TryParse(tmp_literal, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out tmp_float))
            {
                current.AddNode(new DataAtom(tmp_float));
            }
            else if (tmp_literal[0] == '$')
            {
                current.AddNode(DataVariable.Var(tmp_literal.Substring(1)));
            }
            else
            {
                current.AddNode(DataSymbol.Symbol(tmp_literal));
            }
        }
Esempio n. 8
0
        static GameObject[] ExtractVenuePropAnimsFromMidi(MidiFile mf)
        {
            var   objs      = new List <GameObject>();
            short index     = 1;
            var   editorCom = new Component
            {
                Rev      = 3,
                Name1    = "Editor",
                Name2    = "Editor",
                Unknown2 = 2,
                Props    = new[] { new Property("capabilities", new UIntValue(62)) }
            };

            objs.Add(new GameObject
            {
                Id = new GameObjectId {
                    Index = 0, Layer = 0
                },
                Rev        = 2,
                Name       = "root",
                Components = new[]
                {
                    editorComponent,
                    entityHeaderComponent,
                    new Component
                    {
                        Rev      = 3,
                        Name1    = "PropAnim",
                        Name2    = "PropAnim",
                        Unknown2 = 0,
                        Props    = StructValue.FromData(
                            StructType.FromData(DTX.FromDtaString(
                                                    @"(props 
                            (frame_range_start float)
                            (frame_range_end float)
                            (time_units int)
                            (is_looping bool))")),
                            DTX.FromDtaString(
                                @"(frame_range_start 3.402823E+38)
                          (frame_range_end -3.402823E+38)
                          (time_units 0)
                          (is_looping 0)")).Props
                    }
                }
            });
            var tracks  = new Midi.MidiHelper().ProcessTracks(mf);
            var partMap = new Dictionary <string, string> {
                { "PART BASS", "bass_intensity" },
                { "PART GUITAR", "guitar_intensity" },
                { "PART DRUMS", "drum_intensity" },
                { "PART VOCALS", "mic_intensity" },
#if DEBUG
                { "PART KEYS", "keyboard_intensity" },
#endif
            };
            var intensityMap = new Dictionary <string, string>
            {
                // All
                { "[idle_realtime]", "idle_realtime" },
                { "[idle]", "idle" },
                { "[idle_intense]", "idle_intense" },
                { "[play]", "play" },
                { "[mellow]", "mellow" },
                { "[intense]", "intense" },
                // Guitar/bass only
                { "[play_solo]", "play_solo" },
                // Vocal only
                { "[tambourine_start]", "tambourine_start" },
                { "[tambourine_end]", "tambourine_end" },
                { "[cowbell_start]", "cowbell_start" },
                { "[cowbell_end]", "cowbell_end" },
                { "[clap_start]", "clap_start" },
                { "[clap_end]", "clap_end" },
                // Drum only
                { "[ride_side_true]", "ride_side_true" },
                { "[ride_side_false]", "ride_side_false" },
            };

            void AddAnimTrack(StructValue props)
            {
                objs.Add(new GameObject
                {
                    Id = new GameObjectId {
                        Index = index, Layer = index++
                    },
                    Rev        = 2,
                    Name       = "Keys type 11",
                    Components = new[]
                    {
                        editorCom,
                        new Component
                        {
                            Rev      = 3,
                            Name1    = "PropKeysSymCom",
                            Name2    = "PropKeys",
                            Unknown2 = 0,
                            Props    = props.Props
                        }
                    }
                });
            }

            StructValue MakeAnimProps(string drivenProp, List <Tuple <float, string> > frames)
            {
                var propkeys = DTX.FromDtaString(
                    "(keys ()) " +
                    "(interpolation 0) " +
                    $"(driven_prop (0 0 RBVenueAuthoring 0 1 {drivenProp}))");
                var keyframes = propkeys.Array("keys").Array(1);

                foreach (var(frame, key) in frames)
                {
                    var keyframe = new DataArray();
                    keyframe.AddNode(new DataAtom(frame));
                    keyframe.AddNode(DataSymbol.Symbol(key));
                    keyframes.AddNode(keyframe);
                }
                return(StructValue.FromData(propKeysType, propkeys));
            }

            foreach (var track in tracks)
            {
                if (!partMap.ContainsKey(track.Name))
                {
                    continue;
                }
                var frames = new List <Tuple <float, string> >();
                foreach (var n in track.Items)
                {
                    if (n is Midi.MidiText t)
                    {
                        if (intensityMap.ContainsKey(t.Text))
                        {
                            frames.Add(Tuple.Create((float)n.StartTicks / mf.TicksPerQN, intensityMap[t.Text]));
                        }
                    }
                }
                AddAnimTrack(MakeAnimProps(partMap[track.Name], frames));
            }
            AddAnimTrack(MakeAnimProps("shot_bg", new List <Tuple <float, string> > {
                Tuple.Create(0f, "coop_all_far")
            }));
            AddAnimTrack(MakeAnimProps("shot_bk", new List <Tuple <float, string> > {
                Tuple.Create(0f, "coop_all_far")
            }));
            AddAnimTrack(MakeAnimProps("shot_gk", new List <Tuple <float, string> > {
                Tuple.Create(0f, "coop_all_far")
            }));
            AddAnimTrack(MakeAnimProps("crowd", new List <Tuple <float, string> > {
                Tuple.Create(0f, "crowd_realtime")
            }));
            AddAnimTrack(MakeAnimProps("world_event", new List <Tuple <float, string> > {
                Tuple.Create(0f, "none")
            }));
            //AddAnimTrack(MakeAnimProps("part2_sing", new List<Tuple<float, string>> {Tuple.Create(0f, "singalong_off") }));
            //AddAnimTrack(MakeAnimProps("part3_sing", new List<Tuple<float, string>> {Tuple.Create(0f, "singalong_off") }));
            //AddAnimTrack(MakeAnimProps("part4_sing", new List<Tuple<float, string>> {Tuple.Create(0f, "singalong_off") }));
            AddAnimTrack(MakeAnimProps("lightpreset", new List <Tuple <float, string> > {
                Tuple.Create(0f, "silhouettes")
            }));
            AddAnimTrack(MakeAnimProps("postproc", new List <Tuple <float, string> > {
                Tuple.Create(0f, "profilm_a")
            }));
            AddAnimTrack(MakeAnimProps("lightpreset_keyframe", new List <Tuple <float, string> > {
                Tuple.Create(0f, "next")
            }));
            AddAnimTrack(MakeAnimProps("spot_bass", new List <Tuple <float, string> > {
                Tuple.Create(0f, "off")
            }));
            AddAnimTrack(MakeAnimProps("spot_guitar", new List <Tuple <float, string> > {
                Tuple.Create(0f, "off")
            }));
            AddAnimTrack(MakeAnimProps("spot_drums", new List <Tuple <float, string> > {
                Tuple.Create(0f, "off")
            }));
            //AddAnimTrack(MakeAnimProps("spot_keyboard", new List<Tuple<float, string>> {Tuple.Create(0f, "off") }));
            AddAnimTrack(MakeAnimProps("spot_vocal", new List <Tuple <float, string> > {
                Tuple.Create(0f, "off")
            }));
            //AddAnimTrack(MakeAnimProps("shot_5", new List<Tuple<float, string>> {Tuple.Create(0f, "coop_all_far") }));
            AddAnimTrack(MakeAnimProps("stagekit_fog", new List <Tuple <float, string> > {
                Tuple.Create(0f, "off")
            }));
            return(objs.ToArray());
        }
Esempio n. 9
0
        public static DataArray MakeMoggDta(DataArray array, float volumeAdjustment)
        {
            var moggDta    = new DataArray();
            var trackArray = new DataArray();

            trackArray.AddNode(DataSymbol.Symbol("tracks"));
            var trackSubArray = trackArray.AddNode(new DataArray());

            foreach (var child in array.Array("song").Array("tracks").Array(1).Children)
            {
                if (child is DataArray a && a.Children[1] is DataArray b && b.Count > 0)
                {
                    if (a.Symbol(0).Name == "drum")
                    {
                        switch (b.Count)
                        {
                        //Mix0 (2 channel) Whole kit in a stereo stream
                        case 2:
                            trackSubArray.AddNode(DTX.FromDtaString("drum (0 1)"));
                            break;

                        //Mix1 (4 channel) Mono kick, Mono Snare, Stereo Kit
                        case 4:
                            trackSubArray.AddNode(DTX.FromDtaString("drum (0)"));
                            trackSubArray.AddNode(DTX.FromDtaString("drum (1)"));
                            trackSubArray.AddNode(DTX.FromDtaString("drum (2 3)"));
                            break;

                        //Mix2 (5 channel) Mono kick, Stereo Snare, Stereo Kit
                        case 5:
                            trackSubArray.AddNode(DTX.FromDtaString("drum (0)"));
                            trackSubArray.AddNode(DTX.FromDtaString("drum (1 2)"));
                            trackSubArray.AddNode(DTX.FromDtaString("drum (3 4)"));
                            break;

                        //Mix3 (6 channel) Stereo kick, Stereo Snare, Stereo Kit
                        case 6:
                            trackSubArray.AddNode(DTX.FromDtaString("drum (0 1)"));
                            trackSubArray.AddNode(DTX.FromDtaString("drum (2 3)"));
                            trackSubArray.AddNode(DTX.FromDtaString("drum (4 5)"));
                            break;

                        //Mix4 (3 channel) Mono kick, Stereo Snare+Kit
                        case 3:
                            trackSubArray.AddNode(DTX.FromDtaString("drum (0)"));
                            trackSubArray.AddNode(DTX.FromDtaString("drum (1 2)"));
                            break;

                        default:
                            throw new Exception("You have too many or too few drum tracks. What are you doing?");
                        }
                    }
                    else
                    {
                        trackSubArray.AddNode(child);
                    }
                }
            }
            var totalTracks = array.Array("song").Array("pans").Array(1).Children.Count;
            // Get the last track number. This is based on the assumption that the tracks are in order
            // We have to filter out empty track arrays because GHtoRB(?) does stuff like (keys ()) instead
            // of leaving out the keys array entirely
            var lastTrack = ((trackSubArray.Children
                              .Where(x => x is DataArray dx ? dx.Array(1).Children.Count > 0 : false)
                              .Last() as DataArray)
                             .Array(1).Children.Last() as DataAtom).Int;
            var crowdChannel = array.Array("song").Array("crowd_channels")?.Int(1);

            if (crowdChannel != null)
            {
                if (crowdChannel == lastTrack + 2)
                {
                    trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})"));
                }
                else if (crowdChannel == lastTrack + 3)
                {
                    trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})"));
                }
                trackSubArray.AddNode(DTX.FromDtaString($"crowd ({crowdChannel} {crowdChannel + 1})"));
            }
            else
            {
                if (totalTracks == lastTrack + 2)
                {
                    trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})"));
                }
                else if (totalTracks == lastTrack + 3)
                {
                    trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})"));
                }
            }
            moggDta.AddNode(trackArray);
            moggDta.AddNode(array.Array("song").Array("pans"));

            // Process (vols (...))
            var vols    = array.Array("song").Array("vols");
            var newVols = new DataArray();

            newVols.AddNode(DataSymbol.Symbol("vols"));
            var volsArray = new DataArray();

            for (int i = 0; i < vols.Array(1).Count; i++)
            {
                volsArray.AddNode(new DataAtom(vols.Array(1).Number(i) + volumeAdjustment));
            }
            newVols.AddNode(volsArray);
            moggDta.AddNode(newVols);

            return(moggDta);
        }
Esempio n. 10
0
File: DTX.cs Progetto: maxton/DtxCS
        /// <summary>
        /// Parses the string as DTA elements, adding each one to the given root array.
        /// </summary>
        /// <param name="data">string of DTA info</param>
        /// <param name="root">top-level array to add the string to</param>
        private static void ParseString(string data, DataArray root)
        {
            ParseState state = ParseState.whitespace;

            data += " "; // this ensures we parse the whole string...
            DataArray current     = root;
            string    tmp_literal = "";
            int       line        = 1;

            for (int i = 0; i < data.Length; i++)
            {
                if (data[i] == '\uFEFF')
                {
                    continue;
                }
                if (data[i] == '\n')
                {
                    line++;
                }
                switch (state)
                {
                case ParseState.whitespace:
                    switch (data[i])
                    {
                    case '\'':
                        tmp_literal = "";
                        state       = ParseState.in_symbol;
                        break;

                    case '"':
                        tmp_literal = "";
                        state       = ParseState.in_string;
                        break;

                    case ';':
                        tmp_literal = "";
                        state       = ParseState.in_comment;
                        break;

                    case ' ':
                    case '\r':
                    case '\n':
                    case '\t':
                        continue;

                    case '}':
                    case ')':
                    case ']':
                        if (data[i] != current.ClosingChar || current.Parent == null)
                        {
                            throw new Exception($"Mismatched closing brace encountered at line {line}.");
                        }
                        current = current.Parent;
                        break;

                    case '(':
                        current = (DataArray)current.AddNode(new DataArray());
                        break;

                    case '{':
                        current = (DataArray)current.AddNode(new DataCommand());
                        break;

                    case '[':
                        current = (DataArray)current.AddNode(new DataMacroDefinition());
                        break;

                    default:
                        state       = ParseState.in_literal;
                        tmp_literal = new string(data[i], 1);
                        continue;
                    }
                    break;

                case ParseState.in_string:
                    switch (data[i])
                    {
                    case '"':
                        current.AddNode(new DataAtom(tmp_literal));
                        state = ParseState.whitespace;
                        break;

                    default:
                        tmp_literal += data[i];
                        continue;
                    }
                    break;

                case ParseState.in_literal:
                    switch (data[i])
                    {
                    case ' ':
                    case '\r':
                    case '\n':
                    case '\t':
                        AddLiteral(current, tmp_literal);
                        state = ParseState.whitespace;
                        break;

                    case '}':
                    case ')':
                    case ']':
                        AddLiteral(current, tmp_literal);
                        if (data[i] != current.ClosingChar)
                        {
                            throw new Exception("Mismatched brace types encountered.");
                        }
                        current = current.Parent;
                        state   = ParseState.whitespace;
                        break;

                    case '(':
                        AddLiteral(current, tmp_literal);
                        current = (DataArray)current.AddNode(new DataArray());
                        break;

                    case '{':
                        AddLiteral(current, tmp_literal);
                        current = (DataArray)current.AddNode(new DataCommand());
                        break;

                    case '[':
                        AddLiteral(current, tmp_literal);
                        current = (DataArray)current.AddNode(new DataMacroDefinition());
                        break;

                    default:
                        tmp_literal += data[i];
                        continue;
                    }
                    break;

                case ParseState.in_symbol:
                    switch (data[i])
                    {
                    case ' ':
                    case '\r':
                    case '\n':
                    case '\t':
                        throw new Exception("Whitespace encountered in symbol.");

                    case '}':
                    case ')':
                    case ']':
                        current.AddNode(DataSymbol.Symbol(tmp_literal));
                        if (data[i] != current.ClosingChar)
                        {
                            throw new Exception("Mismatched brace types encountered.");
                        }
                        current = current.Parent;
                        state   = ParseState.whitespace;
                        break;

                    case '\'':
                        current.AddNode(DataSymbol.Symbol(tmp_literal));
                        state = ParseState.whitespace;
                        break;

                    default:
                        tmp_literal += data[i];
                        continue;
                    }
                    break;

                case ParseState.in_comment:
                    switch (data[i])
                    {
                    case '\r':
                    case '\n':
                        state = ParseState.whitespace;
                        break;

                    default:
                        continue;
                    }
                    break;
                }
            }
        }
Esempio n. 11
0
File: DTX.cs Progetto: maxton/DtxCS
        static DataArray parse_children(System.IO.Stream s, uint numChildren, DataType type = DataType.ARRAY, int version = 1)
        {
            DataArray ret = type == DataType.MACRO ? new DataMacroDefinition()
                            : type == DataType.COMMAND ? new DataCommand()
                            : new DataArray();

            while (numChildren-- > 0)
            {
                DataType t = (DataType)s.ReadInt32LE();
                switch (t)
                {
                case DataType.INT:
                    ret.AddNode(new DataAtom(s.ReadInt32LE()));
                    break;

                case DataType.FLOAT:
                    ret.AddNode(new DataAtom(s.ReadFloat()));
                    break;

                case DataType.VARIABLE:
                    ret.AddNode(DataVariable.Var(s.ReadLengthUTF8()));
                    break;

                case DataType.SYMBOL:
                    ret.AddNode(DataSymbol.Symbol(s.ReadLengthUTF8()));
                    break;

                case DataType.ARRAY:
                case DataType.COMMAND:
                case DataType.MACRO:
                    if (version == 2)
                    {
                        s.Position += 4;
                        uint   nC  = s.ReadUInt32LE();
                        ushort unk = s.ReadUInt16LE();
                        ret.AddNode(parse_children(s, nC, t, version));
                    }
                    else if (version == 3)
                    {
                        s.Position += 4;
                        ushort nC = s.ReadUInt16LE();
                        s.Position += 2;
                        ret.AddNode(parse_children(s, nC, t, version));
                    }
                    else
                    {
                        ushort nC = s.ReadUInt16LE(); // numChildren
                        s.Position += 4;              // id
                        ret.AddNode(parse_children(s, nC, t, version));
                    }
                    break;

                case DataType.STRING:
                    ret.AddNode(new DataAtom(s.ReadLengthUTF8()));
                    break;

                case DataType.EMPTY:
                    s.Position += 4;
                    break;

                case DataType.DEFINE:
                    var constant = s.ReadLengthUTF8();
                    numChildren--;
                    var definition = parse_children(s, 1, DataType.ARRAY, version).Array(0);
                    ret.AddNode(new DataDefine(constant, definition));
                    break;

                case DataType.IFDEF:
                    ret.AddNode(new DataIfDef(s.ReadLengthUTF8()));
                    break;

                case DataType.IFNDEF:
                    ret.AddNode(new DataIfNDef(s.ReadLengthUTF8()));
                    break;

                case DataType.ELSE:
                    s.Position += 4;
                    ret.AddNode(new DataElse());
                    break;

                case DataType.ENDIF:
                    s.Position += 4;
                    ret.AddNode(new DataEndIf());
                    break;

                case DataType.INCLUDE:
                    ret.AddNode(new DataInclude(s.ReadLengthUTF8()));
                    break;

                case DataType.MERGE:
                    ret.AddNode(new DataMerge(s.ReadLengthUTF8()));
                    break;

                case DataType.AUTORUN:
                    s.Position += 4;
                    ret.AddNode(new DataAutorun());
                    break;

                case DataType.UNDEF:
                    ret.AddNode(new DataUndef(s.ReadLengthUTF8()));
                    break;

                default:
                    throw new Exception("Unhandled DTB DataType " + Enum.GetName(typeof(DataType), t));
                }
            }
            return(ret);
        }
Esempio n. 12
0
        public static DataArray Serialize(this IDataSerializable obj)
        {
            var array = new DataArray();

            foreach (var field in obj.GetType().GetProperties())
            {
                var name = CamelToSnake(field.Name);
                if (field.PropertyType.IsGenericType)
                {
                    var gtd  = field.PropertyType.GetGenericTypeDefinition();
                    var args = field.PropertyType.GetGenericArguments();
                    if (gtd == typeof(List <>))
                    {
                        // Add list elements
                        if (!typeof(IDataSerializable).IsAssignableFrom(args[0]))
                        {
                            throw new NotImplementedException("Cannot handle non-serializable types in lists yet");
                        }
                        var listArray   = new DataArray();
                        var value       = (IList)field.GetValue(obj, null);
                        var typename    = CamelToSnake(args[0].Name);
                        var namedValues = field.GetCustomAttributes(typeof(AnonymousListAttribute), true).Length == 0;
                        foreach (var f in value)
                        {
                            var valueNode = SerializeObject(f);
                            listArray.AddNode(namedValues ? NamedItem(typename, valueNode) : valueNode);
                        }
                        array.AddNode(NamedItem(name, listArray));
                    }
                    else if (gtd == typeof(Dictionary <,>))
                    {
                        // Add dictionary elements
                        if (args[0] != typeof(string))
                        {
                            throw new NotImplementedException("Cannot serialize dictionaries with non-string keys");
                        }
                        if (!typeof(IDataSerializable).IsAssignableFrom(args[1]))
                        {
                            throw new NotImplementedException("Cannot handle non-serializable types in dictionaries yet");
                        }
                        var dictArray = new DataArray();
                        var value     = (IDictionary)field.GetValue(obj, null);
                        foreach (var k in value.Keys)
                        {
                            dictArray.AddNode(NamedItem((string)k, SerializeObject(value[k])));
                        }
                        array.AddNode(NamedItem(name, dictArray));
                    }
                    else if (gtd == typeof(Tuple <,>))
                    {
                        var tupleArray = new DataArray();
                        tupleArray.AddNode(new DataAtom(name));
                        var tuple = field.GetValue(obj, null) as ITuple;
                        for (var i = 0; i < tuple.Length; i++)
                        {
                            tupleArray.AddNode(SerializeObject(tuple[i]));
                        }
                        array.AddNode(tupleArray);
                    }
                    else if (gtd == typeof(Nullable <>))
                    {
                        var value = field.GetValue(obj, null);
                        if (value != null)
                        {
                            array.AddNode(NamedItem(name, SerializeObject(value)));
                        }
                    }
                    else
                    {
                        throw new NotImplementedException("Generic type support for " + field.PropertyType.FullName + " not implemented");
                    }
                }
                else
                {
                    array.AddNode(NamedItem(name, SerializeObject(field.GetValue(obj, null))));
                }
            }
            return(array);
        }