From 0994750fb478bcf2f82072c293d52639cfdc5327 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Mon, 29 Feb 2016 18:17:34 -0800 Subject: [PATCH] Refactored Bindings.cs to use reflection and internal methods for logic / setting values. --- OSCADSharp/OSCADSharp/Scripting/Bindings.cs | 81 +++++++++++++++++-- .../OSCADSharp/Scripting/StatementBuilder.cs | 5 +- OSCADSharp/OSCADSharp/Solids/Sphere.cs | 32 +------- 3 files changed, 82 insertions(+), 36 deletions(-) diff --git a/OSCADSharp/OSCADSharp/Scripting/Bindings.cs b/OSCADSharp/OSCADSharp/Scripting/Bindings.cs index 30b09eb..0397485 100644 --- a/OSCADSharp/OSCADSharp/Scripting/Bindings.cs +++ b/OSCADSharp/OSCADSharp/Scripting/Bindings.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; @@ -8,20 +9,90 @@ namespace OSCADSharp.Scripting { internal class Bindings { + #region Fields private Dictionary bindings = new Dictionary(); - internal void Add(Binding binding) + private Dictionary propertyNametoOpenSCADFieldMappings = new Dictionary(); + #endregion + + #region Constructors + public Bindings(Dictionary mappings) + { + this.propertyNametoOpenSCADFieldMappings = mappings; + } + #endregion + + #region Private Methods + private void SetProperty(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); + } + } + } + + /// + /// Returns true if this set of bindings can map the specified property to an OpenSCAD field + /// + /// + /// + private bool HasMapping(string propertyName) + { + return this.propertyNametoOpenSCADFieldMappings.ContainsKey(propertyName.ToLower()); + } + + /// + /// Returns the corresponding OpenSCAD output field name for + /// a given property name + /// + /// + /// + private string PropertyToOpenSCADField(string propertyName) + { + return this.propertyNametoOpenSCADFieldMappings[propertyName.ToLower()]; + } + + private void Add(Binding binding) { bindings[binding.OpenSCADFieldName] = binding; } + #endregion - internal bool Contains(string property) + #region Internal API + internal void Add(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(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 } } diff --git a/OSCADSharp/OSCADSharp/Scripting/StatementBuilder.cs b/OSCADSharp/OSCADSharp/Scripting/StatementBuilder.cs index a8615d5..1a4410d 100644 --- a/OSCADSharp/OSCADSharp/Scripting/StatementBuilder.cs +++ b/OSCADSharp/OSCADSharp/Scripting/StatementBuilder.cs @@ -13,11 +13,10 @@ namespace OSCADSharp.Scripting internal class StatementBuilder { private StringBuilder SB { get; set; } = new StringBuilder(); - private Bindings bindings; + private Bindings bindings = null; internal StatementBuilder() { - this.bindings = new Bindings(); } internal StatementBuilder(Bindings bindings) @@ -59,7 +58,7 @@ namespace OSCADSharp.Scripting private bool shouldUseBinding(string name) { - return this.bindings.Contains(name); + return this.bindings != null && this.bindings.Contains(name); } /// diff --git a/OSCADSharp/OSCADSharp/Solids/Sphere.cs b/OSCADSharp/OSCADSharp/Solids/Sphere.cs index a9b131b..5cbb331 100644 --- a/OSCADSharp/OSCADSharp/Solids/Sphere.cs +++ b/OSCADSharp/OSCADSharp/Solids/Sphere.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using OSCADSharp.Spatial; using OSCADSharp.Scripting; using System.Collections.Concurrent; +using System.Reflection; namespace OSCADSharp.Solids { @@ -120,11 +121,10 @@ namespace OSCADSharp.Solids new Vector3(this.Radius, this.Radius, this.Radius)); } - private Bindings bindings = new Bindings(); - private static Dictionary bindingMapping = new Dictionary() + private Bindings bindings = new Bindings(new Dictionary() { { "radius", "r" } - }; + }); /// /// Binds a a variable to a property on this object @@ -134,31 +134,7 @@ namespace OSCADSharp.Solids /// literal value of the property public void Bind(string property, Variable 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); - } + this.bindings.Add(this, property, variable); } #endregion }