예제 #1
0
        protected void OnSetupInstance()
        {
            Type type             = GetType();
            Type serializableType = typeof(Serializable);

            // Only do this for user types.
            if (type.Assembly == serializableType.Assembly || !type.IsSubclassOf(serializableType))
            {
                return;
            }

            AttributeMap allAttributes = Context.AllAttributes;

            // And only once per type.
            if (allAttributes.ContainsKey(GetTypeHash()))
            {
                return;
            }

            // Register field attributes of this class
            foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                if (field.DeclaringType?.Assembly == serializableType.Assembly)
                {
                    continue;
                }

                if (field.IsNotSerialized)
                {
                    continue;
                }

                var attribute = Attribute.GetCustomAttribute(field, typeof(SerializeFieldAttribute)) as SerializeFieldAttribute;
                if (field.IsPrivate && attribute == null)
                {
                    continue;
                }

                Type fieldType = field.FieldType;
                if (fieldType.IsEnum)
                {
                    fieldType = Enum.GetUnderlyingType(fieldType);
                }
                VariantType variantType = Variant.GetVariantType(fieldType);

                // TODO: Support VariantType.VarPtr
                if (variantType == VariantType.VarNone || variantType == VariantType.VarPtr || variantType == VariantType.VarVoidPtr)
                {
                    // Incompatible type.
                    Log.Warning($"Trying to register attribute {field.DeclaringType?.FullName}.{field.Name} which has incompatible type {field.FieldType.Name}.");
                    continue;
                }

                StringList enumNames = _emptyStringList;
                if (field.FieldType.IsEnum)
                {
                    enumNames = new StringList();
                    foreach (string name in field.FieldType.GetEnumNames())
                    {
                        enumNames.Add(name);
                    }
                }

                var accessor     = new VariantFieldAccessor(field, variantType);
                var defaultValue = new Variant();
                try
                {
                    accessor.Get(this, defaultValue);
                }
                catch (ArgumentNullException)
                {
                    defaultValue = new Variant(variantType);
                }
                string attributeName = attribute?.Name ?? field.Name;
                var    info          = new AttributeInfo(accessor.VariantType, attributeName, accessor, enumNames, defaultValue,
                                                         attribute?.Mode ?? AttributeMode.AmDefault);
                Context.RegisterAttribute(GetTypeHash(), info);
            }

            // Register property attributes of this class
            foreach (PropertyInfo property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                if (property.DeclaringType?.Assembly == serializableType.Assembly)
                {
                    continue;
                }

                // Private (even if partially) properties are not serialized by default.
                var attribute = Attribute.GetCustomAttribute(property, typeof(SerializeFieldAttribute)) as SerializeFieldAttribute;
                if ((property.GetMethod.IsPrivate || property.SetMethod.IsPrivate) && attribute == null)
                {
                    continue;
                }

                if (!property.CanRead || !property.CanWrite)
                {
                    Log.Warning($"Trying to register attribute {property.DeclaringType?.FullName}.{property.Name} which is not readable and writable.");
                    continue;
                }

                Type propertyType = property.PropertyType;
                if (propertyType.IsEnum)
                {
                    propertyType = Enum.GetUnderlyingType(propertyType);
                }
                VariantType variantType = Variant.GetVariantType(propertyType);

                // TODO: Support VariantType.VarPtr
                if (variantType == VariantType.VarNone || variantType == VariantType.VarPtr || variantType == VariantType.VarVoidPtr)
                {
                    // Incompatible type.
                    Log.Warning($"Trying to register attribute {property.DeclaringType?.FullName}.{property.Name} which has incompatible type {property.PropertyType.Name}.");
                    continue;
                }

                StringList enumNames = _emptyStringList;
                if (property.PropertyType.IsEnum)
                {
                    enumNames = new StringList();
                    foreach (string name in property.PropertyType.GetEnumNames())
                    {
                        enumNames.Add(name);
                    }
                }

                var accessor     = new VariantPropertyAccessor(property, variantType);
                var defaultValue = new Variant();
                try
                {
                    accessor.Get(this, defaultValue);
                }
                catch (ArgumentNullException)
                {
                    defaultValue = new Variant(variantType);
                }

                string attributeName = attribute?.Name ?? property.Name;
                var    info          = new AttributeInfo(accessor.VariantType, attributeName, accessor, enumNames, defaultValue,
                                                         attribute?.Mode ?? AttributeMode.AmDefault);
                Context.RegisterAttribute(GetTypeHash(), info);
            }
        }
예제 #2
0
        public override void Get(Serializable ptr, Variant dest)
        {
            switch (VariantType)
            {
            case VariantType.VarNone:
                dest.Clear();
                break;

            case VariantType.VarInt:
                dest.Set((int)_field.GetValue(ptr));
                break;

            case VariantType.VarBool:
                dest.Set((bool)_field.GetValue(ptr));
                break;

            case VariantType.VarFloat:
                dest.Set((float)_field.GetValue(ptr));
                break;

            case VariantType.VarVector2:
                dest.Set((Vector2)_field.GetValue(ptr));
                break;

            case VariantType.VarVector3:
                dest.Set((Vector3)_field.GetValue(ptr));
                break;

            case VariantType.VarVector4:
                dest.Set((Vector4)_field.GetValue(ptr));
                break;

            case VariantType.VarQuaternion:
                dest.Set((Quaternion)_field.GetValue(ptr));
                break;

            case VariantType.VarColor:
                dest.Set((Color)_field.GetValue(ptr));
                break;

            case VariantType.VarString:
                dest.Set((string)_field.GetValue(ptr));
                break;

            case VariantType.VarBuffer:
                dest.Set((UCharArray)_field.GetValue(ptr));
                break;

            case VariantType.VarVoidPtr:
                dest.Set((IntPtr)_field.GetValue(ptr));
                break;

            case VariantType.VarResourceRef:
                dest.Set((ResourceRef)_field.GetValue(ptr));
                break;

            case VariantType.VarResourceRefList:
                dest.Set((ResourceRefList)_field.GetValue(ptr));
                break;

            case VariantType.VarVariantList:
                dest.Set((VariantList)_field.GetValue(ptr));
                break;

            case VariantType.VarVariantMap:
                dest.Set((VariantMap)_field.GetValue(ptr));
                break;

            case VariantType.VarIntRect:
                dest.Set((IntRect)_field.GetValue(ptr));
                break;

            case VariantType.VarIntVector2:
                dest.Set((IntVector2)_field.GetValue(ptr));
                break;

            case VariantType.VarPtr:
                dest.Set((RefCounted)_field.GetValue(ptr));
                break;

            case VariantType.VarMatrix3:
                dest.Set((Matrix3)_field.GetValue(ptr));
                break;

            case VariantType.VarMatrix3x4:
                dest.Set((Matrix3x4)_field.GetValue(ptr));
                break;

            case VariantType.VarMatrix4:
                dest.Set((Matrix4)_field.GetValue(ptr));
                break;

            case VariantType.VarDouble:
                dest.Set((double)_field.GetValue(ptr));
                break;

            case VariantType.VarStringList:
                dest.Set((StringList)_field.GetValue(ptr));
                break;

            case VariantType.VarRect:
                dest.Set((Rect)_field.GetValue(ptr));
                break;

            case VariantType.VarIntVector3:
                dest.Set((IntVector3)_field.GetValue(ptr));
                break;

            case VariantType.VarInt64:
                dest.Set((long)_field.GetValue(ptr));
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
예제 #3
0
파일: Serializable.cs 프로젝트: yazici/rbfx
        protected void OnSetupInstance()
        {
            var type             = GetType();
            var serializableType = typeof(Serializable);

            // Only do this for user types.
            if (type.Assembly == serializableType.Assembly || !type.IsSubclassOf(serializableType))
            {
                return;
            }

            var context       = GetContext();
            var allAttributes = context.GetAllAttributes();

            // And only once per type.
            if (allAttributes.ContainsKey(GetTypeHash()))
            {
                return;
            }

            // Register attributes of this class
            foreach (var field in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                if (field.DeclaringType?.Assembly == serializableType.Assembly)
                {
                    continue;
                }

                if (field.IsNotSerialized)
                {
                    continue;
                }

                var attribute = Attribute.GetCustomAttribute(field, typeof(SerializeFieldAttribute)) as SerializeFieldAttribute;
                if (field.IsPrivate && attribute == null)
                {
                    continue;
                }

                var fieldType = field.FieldType;
                if (field.FieldType.IsEnum)
                {
                    fieldType = Enum.GetUnderlyingType(fieldType);
                }
                var variantType = Variant.GetVariantType(fieldType);
                if (variantType == VariantType.VarNone)
                {
                    // Incompatible type.
                    continue;
                }

                // TODO: This needs more work. Serializable should automatically serialize instances of Serializable.
                if (variantType == VariantType.VarPtr)
                {
                    continue;
                }

                // No way to serialize that in any meaningful way.
                if (variantType == VariantType.VarVoidptr)
                {
                    continue;
                }

                var enumNames = _emptyStringVector;
                if (field.FieldType.IsEnum)
                {
                    enumNames = new StringVector();
                    foreach (var name in field.FieldType.GetEnumNames())
                    {
                        enumNames.Add(name);
                    }
                }

                var accessor     = new VariantFieldAccessor(field, variantType);
                var defaultValue = new Variant();
                accessor.Get(this, defaultValue);

                var attributeName = attribute?.Name ?? field.Name;
                var info          = new AttributeInfo(accessor.VariantType, attributeName, accessor, enumNames, defaultValue,
                                                      attribute?.Mode ?? AttributeMode.AmDefault);
                context.RegisterAttribute(GetTypeHash(), info);
            }
        }
예제 #4
0
        public override void Set(Serializable ptr, Variant src)
        {
            if (src == null || src.VariantType == VariantType.VarNone)
            {
                _field.SetValue(ptr, null);
                return;
            }

            switch (VariantType)
            {
            case VariantType.VarNone:
                // Undetermined field type.
                return;

            case VariantType.VarInt:
                _field.SetValue(ptr, src.Int);
                break;

            case VariantType.VarBool:
                _field.SetValue(ptr, src.Bool);
                break;

            case VariantType.VarFloat:
                _field.SetValue(ptr, src.Float);
                break;

            case VariantType.VarVector2:
                _field.SetValue(ptr, src.Vector2);
                break;

            case VariantType.VarVector3:
                _field.SetValue(ptr, src.Vector3);
                break;

            case VariantType.VarVector4:
                _field.SetValue(ptr, src.Vector4);
                break;

            case VariantType.VarQuaternion:
                _field.SetValue(ptr, src.Quaternion);
                break;

            case VariantType.VarColor:
                _field.SetValue(ptr, src.Color);
                break;

            case VariantType.VarString:
                _field.SetValue(ptr, src.String);
                break;

            case VariantType.VarBuffer:
                _field.SetValue(ptr, new UCharArray(src.Buffer));
                break;

            case VariantType.VarVoidPtr:
                _field.SetValue(ptr, src.VoidPtr);
                break;

            case VariantType.VarResourceRef:
                _field.SetValue(ptr, new ResourceRef(src.ResourceRef));
                break;

            case VariantType.VarResourceRefList:
                _field.SetValue(ptr, new ResourceRefList(src.ResourceRefList.Type, src.ResourceRefList.Names));
                break;

            case VariantType.VarVariantList:
                _field.SetValue(ptr, new VariantList(src.VariantList));
                break;

            case VariantType.VarVariantMap:
                _field.SetValue(ptr, new VariantMap(src.VariantMap));
                break;

            case VariantType.VarIntRect:
                _field.SetValue(ptr, src.IntRect);
                break;

            case VariantType.VarIntVector2:
                _field.SetValue(ptr, src.IntVector2);
                break;

            case VariantType.VarPtr:
                _field.SetValue(ptr, src.Ptr);
                break;

            case VariantType.VarMatrix3:
                _field.SetValue(ptr, src.Matrix3);
                break;

            case VariantType.VarMatrix3x4:
                _field.SetValue(ptr, src.Matrix3x4);
                break;

            case VariantType.VarMatrix4:
                _field.SetValue(ptr, src.Matrix4);
                break;

            case VariantType.VarDouble:
                _field.SetValue(ptr, src.Double);
                break;

            case VariantType.VarStringList:
                _field.SetValue(ptr, new StringList(src.StringList));
                break;

            case VariantType.VarRect:
                _field.SetValue(ptr, src.Rect);
                break;

            case VariantType.VarIntVector3:
                _field.SetValue(ptr, src.IntVector3);
                break;

            case VariantType.VarInt64:
                _field.SetValue(ptr, src.Int64);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
예제 #5
0
파일: Serializable.cs 프로젝트: yazici/rbfx
        public override void Set(Serializable ptr, Variant src)
        {
            if (src == null || src.GetVariantType() == VariantType.VarNone)
            {
                _field.SetValue(ptr, null);
                return;
            }

            switch (VariantType)
            {
            case VariantType.VarNone:
                // Undetermined field type.
                return;

            case VariantType.VarInt:
                _field.SetValue(ptr, src.GetInt());
                break;

            case VariantType.VarBool:
                _field.SetValue(ptr, src.GetBool());
                break;

            case VariantType.VarFloat:
                _field.SetValue(ptr, src.GetFloat());
                break;

            case VariantType.VarVector2:
                _field.SetValue(ptr, src.GetVector2());
                break;

            case VariantType.VarVector3:
                _field.SetValue(ptr, src.GetVector3());
                break;

            case VariantType.VarVector4:
                _field.SetValue(ptr, src.GetVector4());
                break;

            case VariantType.VarQuaternion:
                _field.SetValue(ptr, src.GetQuaternion());
                break;

            case VariantType.VarColor:
                _field.SetValue(ptr, src.GetColor());
                break;

            case VariantType.VarString:
                _field.SetValue(ptr, src.GetString());
                break;

            case VariantType.VarBuffer:
                _field.SetValue(ptr, src.GetBuffer());
                break;

            case VariantType.VarVoidptr:
                _field.SetValue(ptr, src.GetVoidPtr());
                break;

            case VariantType.VarResourceref:
                _field.SetValue(ptr, src.GetResourceRef());
                break;

            case VariantType.VarResourcereflist:
                _field.SetValue(ptr, src.GetResourceRefList());
                break;

            case VariantType.VarVariantvector:
                _field.SetValue(ptr, src.GetVariantVector());
                break;

            case VariantType.VarVariantmap:
                _field.SetValue(ptr, src.GetVariantMap());
                break;

            case VariantType.VarIntrect:
                _field.SetValue(ptr, src.GetIntRect());
                break;

            case VariantType.VarIntvector2:
                _field.SetValue(ptr, src.GetIntVector2());
                break;

            case VariantType.VarPtr:
                _field.SetValue(ptr, src.GetPtr());
                break;

            case VariantType.VarMatrix3:
                _field.SetValue(ptr, src.GetMatrix3());
                break;

            case VariantType.VarMatrix3x4:
                _field.SetValue(ptr, src.GetMatrix3x4());
                break;

            case VariantType.VarMatrix4:
                _field.SetValue(ptr, src.GetMatrix4());
                break;

            case VariantType.VarDouble:
                _field.SetValue(ptr, src.GetDouble());
                break;

            case VariantType.VarStringvector:
                _field.SetValue(ptr, src.GetStringVector());
                break;

            case VariantType.VarRect:
                _field.SetValue(ptr, src.GetRect());
                break;

            case VariantType.VarIntvector3:
                _field.SetValue(ptr, src.GetIntVector3());
                break;

            case VariantType.VarInt64:
                _field.SetValue(ptr, src.GetInt64());
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }