private PositionedObject SetFieldOrPropertyCustomVariable(CustomVariable cv, object valueToSetTo, bool attachAndUnattach, IElement container, ElementRuntime sourceElement, object objectToSetOn, PositionedObject parent, PropertyInfo property, FieldInfo field)
{
if (objectToSetOn != sourceElement && sourceElement.mAssociatedNamedObjectSave.SourceType == SourceType.FlatRedBallType &&
objectToSetOn is PositionedObject && attachAndUnattach)
{
parent = sourceElement;
}
// Not sure if this is the best place to put this, but let's replace "\\n" with "\n"
if (valueToSetTo is string && ((string)valueToSetTo).Contains("\\n"))
{
valueToSetTo = ((string)valueToSetTo).Replace("\\n", "\n");
}
VariableSetArgs vse = new VariableSetArgs();
vse.Value = valueToSetTo;
vse.VariableName = cv.Name;
if (BeforeVariableApply != null)
{
BeforeVariableApply(this, vse);
}
if (property != null)
{
//try
//{
if (cv.GetIsFile())
{
object fileRuntime = null;
if (valueToSetTo is string)
{
ReferencedFileSave rfs = GetReferencedFileFromName(valueToSetTo);
if (rfs == null)
{
fileRuntime = null;
}
else
{
fileRuntime = LoadReferencedFileSave(rfs, true, container);
}
}
else
{
fileRuntime = valueToSetTo;
}
property.SetValue(objectToSetOn, fileRuntime, null);
}
else
{
object convertedValue = valueToSetTo;
if (property.PropertyType == typeof(Microsoft.Xna.Framework.Color) && valueToSetTo is string)
{
convertedValue = PropertyValuePair.ConvertStringToType((string)valueToSetTo, property.PropertyType);
}
if(property.PropertyType == typeof(IList<FlatRedBall.Math.Geometry.Point>))
{
// We may be storing vectors, so if so we need to convert
if (valueToSetTo != null && valueToSetTo is List<Vector2>)
{
List<FlatRedBall.Math.Geometry.Point> converted = new List<FlatRedBall.Math.Geometry.Point>();
foreach(var item in valueToSetTo as List<Vector2>)
{
converted.Add(new Math.Geometry.Point(item.X, item.Y));
}
convertedValue = converted;
}
}
bool shouldSet = true;
if (convertedValue is string &&
(string.IsNullOrEmpty((string)convertedValue)) &&
(
property.PropertyType == typeof(float) ||
property.PropertyType == typeof(bool) ||
property.PropertyType == typeof(long) ||
property.PropertyType == typeof(double) ||
property.PropertyType == typeof(int)))
{
shouldSet = false;
}
if (shouldSet)
{
// It's possible that GlueView
// can set a bad value like float.NaN
// on an X which ultimately makes the engine
// crash hard! If an exception occurs on a property
// set, then we need to catch it and undo the set, then
// throw an exception so that whoever set it can deal with
// the problem.
object oldValue = null;
if(property.CanRead)
{
oldValue = property.GetValue(objectToSetOn, null);
}
try
{
bool wasCustomSet = false;
if (objectToSetOn is PositionedObject)
{
}
else
{
}
property.SetValue(objectToSetOn, convertedValue, null);
}
catch (Exception e)
{
if (property.CanRead)
{
// We failed, so let's set the value back (if we can)
try
{
property.SetValue(objectToSetOn, oldValue, null);
}
catch
{
// do nothing
}
}
//throw new Exception("Error setting " + property.Name + " on " + objectToSetOn + ":\n" + e.ToString());
}
}
}
//}
//catch
//{
// // do nothing for now
//}
}
else if (field != null)
{
field.SetValue(objectToSetOn, valueToSetTo);
}
if (objectToSetOn is PositionedObject)
{
((PositionedObject)objectToSetOn).ForceUpdateDependencies();
}
// If we changed the position of this, we want to make sure to update any
// children before we continue to eliminate errors from repositioning
foreach (PositionedObject childObject in this.Children)
{
childObject.ForceUpdateDependenciesDeep();
}
foreach (ElementRuntime er in this.ContainedElements)
{
er.ForceUpdateDependenciesDeep();
}
if (AfterVariableApply != null)
{
AfterVariableApply(this, vse);
}
return parent;
}