From 0989c4660ce6197caa7b1ed2ee777e6764c99b6a Mon Sep 17 00:00:00 2001 From: Michael L Smith Date: Mon, 29 Feb 2016 21:16:21 -0800 Subject: [PATCH] + Implemented Cube size bindings and synonyms for them --- .../OSCADSharp.UnitTests/Solids/CubeTests.cs | 41 ++++++++++++ .../OSCADSharp/Bindings/BindableVector.cs | 24 +++++++ OSCADSharp/OSCADSharp/Bindings/Bindings.cs | 63 ++++++++++++++----- OSCADSharp/OSCADSharp/Solids/Cube.cs | 40 ++++++++---- 4 files changed, 142 insertions(+), 26 deletions(-) diff --git a/OSCADSharp/OSCADSharp.UnitTests/Solids/CubeTests.cs b/OSCADSharp/OSCADSharp.UnitTests/Solids/CubeTests.cs index abf63a4..25d31e0 100644 --- a/OSCADSharp/OSCADSharp.UnitTests/Solids/CubeTests.cs +++ b/OSCADSharp/OSCADSharp.UnitTests/Solids/CubeTests.cs @@ -3,6 +3,7 @@ using System.Text; using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; using OSCADSharp.Solids; +using OSCADSharp.Scripting; namespace OSCADSharp.UnitTests { @@ -103,5 +104,45 @@ namespace OSCADSharp.UnitTests Assert.AreEqual(new Vector3(2.5, 2.5, 10), obj.Bounds().TopRight); Assert.AreEqual(new Vector3(-2.5, -2.5, -10), obj.Bounds().BottomLeft); } + + [TestMethod] + public void Cube_Size_XYZBindingsAppearInOutput() + { + Variable xValue = new Variable("xVal", 10.125); + Variable yValue = new Variable("yVal", 15.5); + Variable zValue = new Variable("zVal", 25); + + var obj = new Cube(); + obj.Bind("Size.X", xValue); + obj.Bind("Size.Y", yValue); + obj.Bind("Size.Z", zValue); + + string script = obj.ToString(); + + Assert.AreEqual(Convert.ToDouble(xValue.Value), obj.Size.X); + Assert.AreEqual(Convert.ToDouble(yValue.Value), obj.Size.Y); + Assert.AreEqual(Convert.ToDouble(zValue.Value), obj.Size.Z); + Assert.IsTrue(script.Contains("size = [xVal, yVal, zVal]")); + } + + [TestMethod] + public void Cube_Size_LengthWidthHeightindingsAppearInOutput() + { + Variable xValue = new Variable("xVal", 10.125); + Variable yValue = new Variable("yVal", 15.5); + Variable zValue = new Variable("zVal", 25); + + var obj = new Cube(); + obj.Bind("Length", xValue); + obj.Bind("Width", yValue); + obj.Bind("Height", zValue); + + string script = obj.ToString(); + + Assert.AreEqual(Convert.ToDouble(xValue.Value), obj.Size.X); + Assert.AreEqual(Convert.ToDouble(yValue.Value), obj.Size.Y); + Assert.AreEqual(Convert.ToDouble(zValue.Value), obj.Size.Z); + Assert.IsTrue(script.Contains("size = [xVal, yVal, zVal]")); + } } } diff --git a/OSCADSharp/OSCADSharp/Bindings/BindableVector.cs b/OSCADSharp/OSCADSharp/Bindings/BindableVector.cs index 5ea06d0..84654f7 100644 --- a/OSCADSharp/OSCADSharp/Bindings/BindableVector.cs +++ b/OSCADSharp/OSCADSharp/Bindings/BindableVector.cs @@ -16,6 +16,30 @@ namespace OSCADSharp.Bindings { "z", "z" } }); + public BindableVector(Vector3 vector, Dictionary synonyms = null) : this(vector.X, vector.Y, vector.Z) + { + } + + public BindableVector(double x = 0, double y = 0, double z = 0, Dictionary synonyms = null) + { + this.X = x; + this.Y = y; + this.Z = z; + + this.setSynonyms(synonyms); + } + + private void setSynonyms(Dictionary synonyms) + { + if (synonyms == null) + return; + + foreach (KeyValuePair item in synonyms) + { + this.bindings.Synonym(item.Value, item.Key); + } + } + public void Bind(string property, Variable variable) { this.bindings.Add(this, property, variable); diff --git a/OSCADSharp/OSCADSharp/Bindings/Bindings.cs b/OSCADSharp/OSCADSharp/Bindings/Bindings.cs index 1fbd505..5c5efd3 100644 --- a/OSCADSharp/OSCADSharp/Bindings/Bindings.cs +++ b/OSCADSharp/OSCADSharp/Bindings/Bindings.cs @@ -13,9 +13,15 @@ namespace OSCADSharp.Bindings #region Fields private Dictionary bindings = new Dictionary(); private Dictionary propertyNametoOpenSCADFieldMappings = new Dictionary(); + private Dictionary synonyms = new Dictionary(); #endregion - + #region Constructors + public Bindings() + { + this.propertyNametoOpenSCADFieldMappings = new Dictionary(); + } + public Bindings(Dictionary mappings) { this.propertyNametoOpenSCADFieldMappings = mappings; @@ -23,7 +29,7 @@ namespace OSCADSharp.Bindings #endregion #region Private Methods - private void SetProperty(T instance, string property, Variable variable) + private void setProperty(T instance, string property, Variable variable) { PropertyInfo[] properties; properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); @@ -31,7 +37,11 @@ namespace OSCADSharp.Bindings for (int i = properties.Length - 1; i >= 0; i--) { var prop = properties[i]; - if (prop.Name.ToLower() == property.ToLower()) + string lProperty = property.ToLower(); + if (this.hasMatchingSynonym(lProperty)) + lProperty = this.synonyms[lProperty]; + + if (prop.Name.ToLower() == lProperty) { prop.SetValue(instance, variable.Value); } @@ -43,9 +53,10 @@ namespace OSCADSharp.Bindings /// /// /// - private bool HasMapping(string propertyName) + private bool hasMapping(string propertyName) { - return this.propertyNametoOpenSCADFieldMappings.ContainsKey(propertyName.ToLower()); + return this.propertyNametoOpenSCADFieldMappings.ContainsKey(propertyName.ToLower()) + || this.hasMatchingSynonym(propertyName.ToLower()); } /// @@ -54,21 +65,38 @@ namespace OSCADSharp.Bindings /// /// /// - private string PropertyToOpenSCADField(string propertyName) + private string propertyToOpenSCADField(string propertyName) { - return this.propertyNametoOpenSCADFieldMappings[propertyName.ToLower()]; + string lpropertyName = propertyName.ToLower(); + if (this.hasMatchingSynonym(lpropertyName)) + { + return this.synonymToOpenScadField(lpropertyName); + } + + return this.propertyNametoOpenSCADFieldMappings[lpropertyName]; } - private void Add(Binding binding) + private void add(Binding binding) { bindings[binding.OpenSCADFieldName] = binding; } + + + private bool hasMatchingSynonym(string synonymName) + { + return this.synonyms.ContainsKey(synonymName); + } + + private string synonymToOpenScadField(string synonymName) + { + return this.propertyToOpenSCADField(this.synonyms[synonymName]); + } #endregion #region Internal API internal void Add(T instance, string propertyName, Variable variable) { - if (!this.HasMapping(propertyName)) + if (!this.hasMapping(propertyName)) { throw new KeyNotFoundException(String.Format("No bindable property matching the name {0} was found")); } @@ -76,24 +104,29 @@ namespace OSCADSharp.Bindings //Assign mapping r -> radius -> variable var binding = new Binding() { - OpenSCADFieldName = this.PropertyToOpenSCADField(propertyName), + OpenSCADFieldName = this.propertyToOpenSCADField(propertyName), BoundVariable = variable }; //Set value of property to variable value - this.SetProperty(instance, propertyName, variable); - this.Add(binding); + this.setProperty(instance, propertyName, variable); + this.add(binding); } - internal bool Contains(string propertyName) + internal bool Contains(string openScadFieldName) { - return bindings.ContainsKey(propertyName); + return bindings.ContainsKey(openScadFieldName); } internal Binding Get(string propertyName) { return bindings[propertyName]; - } + } + + internal void Synonym(string propertyName, string alternateName) + { + this.synonyms[alternateName] = propertyName; + } #endregion } } diff --git a/OSCADSharp/OSCADSharp/Solids/Cube.cs b/OSCADSharp/OSCADSharp/Solids/Cube.cs index c9ecc63..958e009 100644 --- a/OSCADSharp/OSCADSharp/Solids/Cube.cs +++ b/OSCADSharp/OSCADSharp/Solids/Cube.cs @@ -15,10 +15,16 @@ namespace OSCADSharp.Solids public class Cube : OSCADObject, IBindable { #region Attributes + private Vector3 size = new BindableVector(1, 1, 1, sizeSynonyms); + /// /// The Size of the cube in terms of X/Y/Z units /// - public Vector3 Size { get; set; } = new Vector3(1, 1, 1); + public Vector3 Size + { + get { return this.size; } + set { this.size = new BindableVector(value, sizeSynonyms); } + } /// /// If True, the center of the cube will be at 0, 0, 0 @@ -43,7 +49,7 @@ namespace OSCADSharp.Solids /// Indicates whether the cube should be centered on the origin public Cube(Vector3 size = null, bool center = false) { - this.Size = size ?? new Vector3(1, 1, 1); + this.Size = new BindableVector(size, sizeSynonyms) ?? new BindableVector(1, 1, 1, sizeSynonyms); this.Center = center; } @@ -71,9 +77,8 @@ namespace OSCADSharp.Solids /// Script for this object public override string ToString() { - return String.Format("cube(size = [{0}, {1}, {2}], center = {3}); {4}", - this.Size.X.ToString(), this.Size.Y.ToString(), this.Size.Z.ToString(), - this.Center.ToString().ToLower(), Environment.NewLine); ; + return String.Format("cube(size = {0}, center = {1}); {2}", + this.Size.ToString(), this.Center.ToString().ToLower(), Environment.NewLine); ; } /// @@ -127,11 +132,16 @@ namespace OSCADSharp.Solids } } - private Bindings.Bindings bindings = new Bindings.Bindings(new Dictionary() + private Bindings.Bindings bindings = new Bindings.Bindings(); + private static readonly Dictionary sizeSynonyms = new Dictionary() { - { "center", "center" }, - { "size", "size" } - }); + {"size.x", "x" }, + {"size.y", "y" }, + {"size.z", "z" }, + {"length", "x" }, + {"width", "y" }, + {"height", "z" } + }; /// /// Binds a a variable to a property on this object @@ -141,8 +151,16 @@ namespace OSCADSharp.Solids /// literal value of the property public void Bind(string property, Variable variable) { - throw new NotImplementedException(); - //this.bindings.Add(this, property, variable); + if (sizeSynonyms.ContainsKey(property.ToLower())) + { + BindableVector vec; + if (this.size is BindableVector) + vec = this.Size as BindableVector; + else + vec = new BindableVector(this.size); + + vec.Bind(property, variable); + } } #endregion }