Пример #1
0
        public override void WriteClass(RedBaseClass cls)
        {
            if (cls is IRedCustomData customCls)
            {
                customCls.CustomWrite(this);
                return;
            }

            _writer.Write((byte)0);

            var typeInfo = RedReflection.GetTypeInfo(cls.GetType());

            foreach (var propertyInfo in typeInfo.GetWritableProperties())
            {
                var value = propertyInfo.GetValue(cls);
                if (!typeInfo.SerializeDefault && RedReflection.IsDefault(cls.GetType(), propertyInfo, value))
                {
                    continue;
                }

                var redTypeName = RedReflection.GetRedTypeFromCSType(propertyInfo.Type, propertyInfo.Flags.Clone());

                CNameRef.Add(_writer.BaseStream.Position, propertyInfo.RedName);
                _writer.Write(GetStringIndex(propertyInfo.RedName));
                CNameRef.Add(_writer.BaseStream.Position, redTypeName);
                _writer.Write(GetStringIndex(redTypeName));

                var sizePos = _writer.BaseStream.Position;
                _writer.Write(0);
                Write((IRedType)value);
                var endPos       = _writer.BaseStream.Position;
                var bytesWritten = (uint)(endPos - sizePos);

                _writer.BaseStream.Position = sizePos;
                _writer.Write(bytesWritten);
                _writer.BaseStream.Position = endPos;
            }

            _writer.Write((ushort)0);

            if (cls is IRedAppendix app)
            {
                app.Write(this);
            }
        }
Пример #2
0
        public RedBaseClass ReadClass(Type type)
        {
            var instance = RedTypeManager.Create(type);

            var baseOff    = BaseStream.Position;
            var fieldCount = _reader.ReadUInt16();
            //var unk = _reader.ReadUInt16();
            var fields = BaseStream.ReadStructs <Package04FieldHeader>(fieldCount);

            foreach (var f in fields)
            {
                var varName  = GetStringValue(f.nameID);
                var typeName = GetStringValue(f.typeID);
                var(fieldType, flags) = RedReflection.GetCSTypeFromRedType(typeName);

                var prop = RedReflection.GetPropertyByRedName(type, varName);

                IRedType value;

                BaseStream.Position = baseOff + f.offset;
                if (prop == null)
                {
                    value = Read(fieldType, 0, Flags.Empty);
                    RedReflection.AddDynamicProperty(instance, varName, value);
                }
                else
                {
                    if (fieldType != prop.Type)
                    {
                        var propName = $"{RedReflection.GetRedTypeFromCSType(instance.GetType())}.{varName}";
                        throw new InvalidRTTIException(propName, prop.Type, fieldType);
                    }

                    value = Read(prop.Type, 0, flags);
                    prop.SetValue(instance, value);
                }
            }

            return(instance);
        }
Пример #3
0
        public bool ReadVariable(RedBaseClass cls)
        {
            var nameId = _reader.ReadUInt16();

            if (nameId == 0)
            {
                return(false);
            }
            var varName = GetStringValue(nameId);

            // Read Type
            var typeId   = _reader.ReadUInt16();
            var typename = GetStringValue(typeId);

            // Read Size
            var sizepos = _reader.BaseStream.Position;
            var size    = _reader.ReadUInt32();

            var(type, flags) = RedReflection.GetCSTypeFromRedType(typename);

            IRedType value;
            var      prop = RedReflection.GetPropertyByRedName(cls.GetType(), varName);

            if (prop == null)
            {
                value = Read(type, size - 4, flags);

                RedReflection.AddDynamicProperty(cls, varName, value);
            }
            else
            {
                value = Read(prop.Type, size - 4, prop.Flags.Clone());

                var typeInfo = RedReflection.GetTypeInfo(cls.GetType());

                var propName = $"{RedReflection.GetRedTypeFromCSType(cls.GetType())}.{varName}";
                if (type != prop.Type)
                {
                    throw new InvalidRTTIException(propName, prop.Type, type);
                }

#if DEBUG
                if (!typeInfo.SerializeDefault && !prop.SerializeDefault && RedReflection.IsDefault(cls.GetType(), varName, value))
                {
                    throw new InvalidParsingException($"Invalid default val for: \"{propName}\"");
                }
#endif

                prop.SetValue(cls, value);
            }

            PostProcess();

            return(true);

            void PostProcess()
            {
                if (value is IRedBufferPointer buf)
                {
                    buf.GetValue().ParentTypes.Add($"{cls.GetType().Name}.{varName}");
                }

                if (value is IRedArray arr)
                {
                    if (typeof(IRedBufferPointer).IsAssignableFrom(arr.InnerType))
                    {
                        foreach (IRedBufferPointer entry in arr)
                        {
                            entry.GetValue().ParentTypes.Add($"{cls.GetType().Name}.{varName}");
                        }
                    }
                }
            }
        }
Пример #4
0
        public void WriteWidgetAttributes(XmlWriter writer, IRedType value, string property = "")
        {
            if (property != "")
            {
                property += ".";
            }

            var childSets = new List <IRedType>();

            var pis = RedReflection.GetTypeInfo(value.GetType()).PropertyInfos;

            pis.Sort((a, b) => a.Name.CompareTo(b.Name));
            pis.ForEach((pi) =>
            {
                IRedType propertyValue;
                if (pi.RedName == null)
                {
                    propertyValue = (IRedType)value.GetType().GetProperty(pi.Name).GetValue(value, null);
                }
                else
                {
                    propertyValue = (IRedType)pi.GetValue((RedBaseClass)value);
                }
                var redType = RedReflection.GetRedTypeFromCSType(pi.Type);
                if (!RedReflection.IsDefault(value.GetType(), pi, propertyValue))
                {
                    var propertyName = pi.RedName;
                    switch (propertyName)
                    {
                    case "children":
                    case "backendData":
                    case "parentWidget":
                        return;

                    default:
                        break;
                    }

                    switch (propertyValue)
                    {
                    case IRedBaseHandle handle:
                        var resolvedValue = handle.GetValue();
                        if (resolvedValue is inkWidget widget)
                        {
                            writer.WriteAttributeString(property + propertyName + "Path", widget.GetPath());
                        }
                        else
                        {
                            WriteWidgetAttributes(writer, resolvedValue, property + propertyName);
                        }
                        break;

                    case inkWidgetReference inkRef:
                        if (inkRef.Widget != null && inkRef.Widget.GetValue() is inkWidget widgetRef)
                        {
                            writer.WriteAttributeString(property + propertyName, widgetRef.GetPath());
                        }
                        break;

                    case CArray <CHandle <inkIEffect> > :
                    case CArray <CHandle <inkWidgetLogicController> > :
                    case CArray <CHandle <inkUserData> > :
                        childSets.Add(propertyValue);
                        break;

                    case CArray <inkPropertyBinding> ary:
                        //writer.WriteStartElement("bindings");
                        foreach (var ipb in ary)
                        {
                            //writer.WriteStartElement("propertyBinding");
                            writer.WriteAttributeString(ipb.PropertyName + ".binding", ipb.StylePath);
                            //writer.WriteEndElement();
                        }
                        //writer.WriteEndElement();
                        break;

                    case inkMargin margin:
                        writer.WriteAttributeString(property + propertyName, margin.Left + "," + margin.Top + "," + margin.Right + "," + margin.Bottom);
                        break;

                    case inkUITransform:
                    case inkWidgetLayout:
                    case textWrappingInfo:
                        WriteWidgetAttributes(writer, propertyValue, property + propertyName);
                        break;

                    case LocalizationString lockey:
                        writer.WriteAttributeString(property + propertyName, lockey.Value.ToString());
                        break;

                    case HDRColor color:
                        writer.WriteAttributeString(property + propertyName, $"color(srgb {color.Red} {color.Green} {color.Blue} / {color.Alpha})");
                        //writer.WriteAttributeString(property + propertyName + ".Red", color.Red.ToString());
                        //writer.WriteAttributeString(property + propertyName + ".Green", color.Green.ToString());
                        //writer.WriteAttributeString(property + propertyName + ".Blue", color.Blue.ToString());
                        //writer.WriteAttributeString(property + propertyName + ".Alpha", color.Alpha.ToString());
                        break;

                    case Vector2 vector2:
                        writer.WriteAttributeString(property + propertyName, $"{vector2.X},{vector2.Y}");
                        //writer.WriteAttributeString(property + propertyName + ".X", vector2.X.ToString());
                        //writer.WriteAttributeString(property + propertyName + ".Y", vector2.Y.ToString());
                        break;

                    default:
                        writer.WriteAttributeString(property + propertyName, propertyValue.ToString());
                        break;
                    }
                }
            });

            foreach (var childSet in childSets)
            {
                switch (childSet)
                {
                case CArray <CHandle <inkIEffect> > effects:

                    writer.WriteStartElement("effects");
                    foreach (var handle in effects)
                    {
                        var effect = handle.GetValue();
                        if (effect != null)
                        {
                            writer.WriteStartElement(effect.GetType().Name);
                            WriteWidgetAttributes(writer, effect);
                            writer.WriteEndElement();
                        }
                    }
                    writer.WriteEndElement();
                    break;

                case CArray <CHandle <inkWidgetLogicController> > controllers:

                    writer.WriteStartElement("secondaryControllers");
                    foreach (var handle in controllers)
                    {
                        var controller = handle.GetValue();
                        if (controller != null)
                        {
                            writer.WriteStartElement(controller.GetType().Name);
                            WriteWidgetAttributes(writer, controller);
                            writer.WriteEndElement();
                        }
                    }
                    writer.WriteEndElement();
                    break;

                case CArray <CHandle <inkUserData> > ary:

                    writer.WriteStartElement("userData");
                    foreach (var handle in ary)
                    {
                        var item = handle.GetValue();
                        if (item != null)
                        {
                            writer.WriteStartElement(item.GetType().Name);
                            WriteWidgetAttributes(writer, item);
                            writer.WriteEndElement();
                        }
                    }
                    writer.WriteEndElement();
                    break;
                }
            }
        }