Add default values initialization for structures and new array entries when resizing

This commit is contained in:
Wojtek Figat
2021-01-12 13:49:26 +01:00
parent 45211fa61c
commit d20cbf434f
4 changed files with 61 additions and 3 deletions

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections;
using FlaxEditor.Scripting;
using FlaxEngine;
namespace FlaxEditor.CustomEditors.Editors
@@ -48,6 +49,15 @@ namespace FlaxEditor.CustomEditors.Editors
Array.Copy(array, oldSize - 1, newValues, i, 1);
}
}
else if (newSize > 0)
{
// Initialize new entries with default values
var defaultValue = TypeUtils.GetDefaultValue(new ScriptType(elementType));
for (int i = 0; i < newSize; i++)
{
newValues.SetValue(defaultValue, i);
}
}
SetValue(newValues);
}

View File

@@ -58,7 +58,7 @@ namespace FlaxEditor.CustomEditors.Editors
}
else if (newSize > 0)
{
// Fill new entries
// Fill new entries with default value
var defaultValue = Scripting.TypeUtils.GetDefaultValue(ElementType);
for (int i = oldSize; i < newSize; i++)
{

View File

@@ -59,11 +59,19 @@ namespace FlaxEditor.Scripting
if (type.Type == typeof(MaterialSceneTextures))
return MaterialSceneTextures.BaseColor;
if (type.IsValueType)
return type.CreateInstance();
{
var value = type.CreateInstance();
Utilities.Utils.InitDefaultValues(value);
return value;
}
if (new ScriptType(typeof(object)).IsAssignableFrom(type))
return null;
if (type.CanCreateInstance)
return type.CreateInstance();
{
var value = type.CreateInstance();
Utilities.Utils.InitDefaultValues(value);
return value;
}
throw new NotSupportedException("Cannot create default value for type " + type);
}

View File

@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using FlaxEditor.SceneGraph;
using FlaxEditor.Scripting;
@@ -1732,5 +1733,44 @@ namespace FlaxEditor.Utilities
distance = 0;
return false;
}
/// <summary>
/// Initializes the object fields and properties with their default values based on <see cref="System.ComponentModel.DefaultValueAttribute"/>.
/// </summary>
/// <param name="obj">The object.</param>
public static void InitDefaultValues(object obj)
{
var scriptType = TypeUtils.GetObjectType(obj);
if (!scriptType)
return;
var isStructure = scriptType.IsStructure;
var fields = scriptType.GetFields(BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public);
for (var i = 0; i < fields.Length; i++)
{
var field = fields[i];
var attr = field.GetAttribute<System.ComponentModel.DefaultValueAttribute>();
if (attr != null)
{
field.SetValue(obj, attr.Value);
}
else if (isStructure)
{
// C# doesn't support default values for structure members so initialize them
field.SetValue(obj, TypeUtils.GetDefaultValue(field.ValueType));
}
}
var properties = scriptType.GetProperties(BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public);
for (var i = 0; i < properties.Length; i++)
{
var property = properties[i];
var attr = property.GetAttribute<System.ComponentModel.DefaultValueAttribute>();
if (attr != null)
{
property.SetValue(obj, attr.Value);
}
}
}
}
}