Refactored Bindings.cs to use reflection and internal methods for logic / setting values.

This commit is contained in:
Michael Smith 2016-02-29 18:17:34 -08:00
parent cf189fb075
commit 0994750fb4
3 changed files with 82 additions and 36 deletions

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -8,20 +9,90 @@ namespace OSCADSharp.Scripting
{ {
internal class Bindings internal class Bindings
{ {
#region Fields
private Dictionary<string, Binding> bindings = new Dictionary<string, Binding>(); private Dictionary<string, Binding> bindings = new Dictionary<string, Binding>();
internal void Add(Binding binding) private Dictionary<string, string> propertyNametoOpenSCADFieldMappings = new Dictionary<string, string>();
#endregion
#region Constructors
public Bindings(Dictionary<string, string> mappings)
{
this.propertyNametoOpenSCADFieldMappings = mappings;
}
#endregion
#region Private Methods
private void SetProperty<T>(T instance, string property, Variable variable)
{
PropertyInfo[] properties;
properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
for (int i = properties.Length - 1; i >= 0; i--)
{
var prop = properties[i];
if (prop.Name.ToLower() == property.ToLower())
{
prop.SetValue(instance, variable.Value);
}
}
}
/// <summary>
/// Returns true if this set of bindings can map the specified property to an OpenSCAD field
/// </summary>
/// <param name="propertyName"></param>
/// <returns></returns>
private bool HasMapping(string propertyName)
{
return this.propertyNametoOpenSCADFieldMappings.ContainsKey(propertyName.ToLower());
}
/// <summary>
/// Returns the corresponding OpenSCAD output field name for
/// a given property name
/// </summary>
/// <param name="propertyName"></param>
/// <returns></returns>
private string PropertyToOpenSCADField(string propertyName)
{
return this.propertyNametoOpenSCADFieldMappings[propertyName.ToLower()];
}
private void Add(Binding binding)
{ {
bindings[binding.OpenSCADFieldName] = binding; bindings[binding.OpenSCADFieldName] = binding;
} }
#endregion
internal bool Contains(string property) #region Internal API
internal void Add<T>(T instance, string propertyName, Variable variable)
{ {
return bindings.ContainsKey(property); if (!this.HasMapping(propertyName))
{
throw new KeyNotFoundException(String.Format("No bindable property matching the name {0} was found"));
}
//Assign mapping r -> radius -> variable
var binding = new Binding()
{
OpenSCADFieldName = this.PropertyToOpenSCADField(propertyName),
BoundVariable = variable
};
//Set value of property to variable value
this.SetProperty<T>(instance, propertyName, variable);
this.Add(binding);
} }
internal Binding Get(string property) internal bool Contains(string propertyName)
{ {
return bindings[property]; return bindings.ContainsKey(propertyName);
} }
internal Binding Get(string propertyName)
{
return bindings[propertyName];
}
#endregion
} }
} }

View File

@ -13,11 +13,10 @@ namespace OSCADSharp.Scripting
internal class StatementBuilder internal class StatementBuilder
{ {
private StringBuilder SB { get; set; } = new StringBuilder(); private StringBuilder SB { get; set; } = new StringBuilder();
private Bindings bindings; private Bindings bindings = null;
internal StatementBuilder() internal StatementBuilder()
{ {
this.bindings = new Bindings();
} }
internal StatementBuilder(Bindings bindings) internal StatementBuilder(Bindings bindings)
@ -59,7 +58,7 @@ namespace OSCADSharp.Scripting
private bool shouldUseBinding(string name) private bool shouldUseBinding(string name)
{ {
return this.bindings.Contains(name); return this.bindings != null && this.bindings.Contains(name);
} }
/// <summary> /// <summary>

View File

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using OSCADSharp.Spatial; using OSCADSharp.Spatial;
using OSCADSharp.Scripting; using OSCADSharp.Scripting;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Reflection;
namespace OSCADSharp.Solids namespace OSCADSharp.Solids
{ {
@ -120,11 +121,10 @@ namespace OSCADSharp.Solids
new Vector3(this.Radius, this.Radius, this.Radius)); new Vector3(this.Radius, this.Radius, this.Radius));
} }
private Bindings bindings = new Bindings(); private Bindings bindings = new Bindings(new Dictionary<string, string>()
private static Dictionary<string, string> bindingMapping = new Dictionary<string, string>()
{ {
{ "radius", "r" } { "radius", "r" }
}; });
/// <summary> /// <summary>
/// Binds a a variable to a property on this object /// Binds a a variable to a property on this object
@ -134,31 +134,7 @@ namespace OSCADSharp.Solids
/// literal value of the property</param> /// literal value of the property</param>
public void Bind(string property, Variable variable) public void Bind(string property, Variable variable)
{ {
this.bindings.Add<Sphere>(this, property, variable);
string lowercaseProp = property.ToLower();
if (!bindingMapping.ContainsKey(lowercaseProp))
{
throw new KeyNotFoundException(String.Format("No bindable property matching the name {0} was found"));
}
//Set value of property to variable value
this.setValueForBinding(lowercaseProp, variable);
//Assign mapping r -> radius -> variable
var binding = new Binding()
{
OpenSCADFieldName = bindingMapping[lowercaseProp],
BoundVariable = variable
};
this.bindings.Add(binding);
}
private void setValueForBinding(string property, Variable variable)
{
if (property == "radius") {
this.Radius = Convert.ToDouble(variable.Value);
}
} }
#endregion #endregion
} }