+ Adjusted StatementBuilder to conditionally use bindings

+ Added Binding.cs
+ Added initial variable binding implementation to Sphere.cs
This commit is contained in:
Michael Smith 2016-02-27 15:55:13 -08:00
parent 59e1042345
commit 7e7affcad4
6 changed files with 78 additions and 13 deletions

View File

@ -127,9 +127,10 @@ namespace OSCADSharp.UnitTests
var sphere = new Sphere();
sphere.Bind("Radius", Variables.Global["mySphereRadius"]);
Assert.IsTrue(sphere.Radius == radius);
string script = sphere.ToString();
// Assert.IsTrue(script.Contains("r = mySphereRadius"));
Assert.IsTrue(script.Contains("r = mySphereRadius"));
}
}
}

View File

@ -48,7 +48,7 @@
<Compile Include="Files\IFileInvoker.cs" />
<Compile Include="Files\IFileWriter.cs" />
<Compile Include="Ids.cs" />
<Compile Include="Scripting\BindingMapper.cs" />
<Compile Include="Scripting\Binding.cs" />
<Compile Include="Scripting\Bindings.cs" />
<Compile Include="Scripting\IBindable.cs" />
<Compile Include="Scripting\SingleStatementObject.cs" />

View File

@ -6,10 +6,9 @@ using System.Threading.Tasks;
namespace OSCADSharp.Scripting
{
internal class BindingMapper
internal class Binding
{
public string OpenSCADFieldName { get; set; }
public List<string> BindingOptions { get; set; }
public Dictionary<string, Func<object, string>> BindingTransformers { get; set; }
public Variable BoundVariable { get; set; }
}
}

View File

@ -8,12 +8,20 @@ namespace OSCADSharp.Scripting
{
internal class Bindings
{
internal List<BindingMapper> Mappers { get; set; } = new List<BindingMapper>();
private Dictionary<string, Variable> bindings = new Dictionary<string, Variable>();
internal void Add(string property, Variable variable)
private Dictionary<string, Binding> bindings = new Dictionary<string, Binding>();
internal void Add(Binding binding)
{
bindings[property] = variable;
bindings[binding.OpenSCADFieldName] = binding;
}
internal bool Contains(string property)
{
return bindings.ContainsKey(property);
}
internal Binding Get(string property)
{
return bindings[property];
}
}
}

View File

@ -13,6 +13,18 @@ namespace OSCADSharp.Scripting
internal class StatementBuilder
{
private StringBuilder SB { get; set; } = new StringBuilder();
private Bindings bindings;
internal StatementBuilder()
{
this.bindings = new Bindings();
}
internal StatementBuilder(Bindings bindings)
{
this.bindings = bindings;
}
/// <summary>
/// Special append method for conditionally adding value-pairs
@ -22,6 +34,8 @@ namespace OSCADSharp.Scripting
/// <param name="prefixWithComma">(optional) Flag indicating whether a comma should be added before the value-pair</param>
public void AppendValuePairIfExists(string name, object value, bool prefixWithComma = false)
{
bool useBinding = this.shouldUseBinding(name);
if (!String.IsNullOrEmpty(value?.ToString()))
{
if (prefixWithComma)
@ -31,10 +45,23 @@ namespace OSCADSharp.Scripting
SB.Append(name);
SB.Append(" = ");
SB.Append(value);
if(useBinding)
{
SB.Append(this.bindings.Get(name).BoundVariable.Name);
}
else
{
SB.Append(value);
}
}
}
private bool shouldUseBinding(string name)
{
return this.bindings.Contains(name);
}
/// <summary>
/// Pass-through for StringBuilder.Append
/// </summary>

View File

@ -5,6 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using OSCADSharp.Spatial;
using OSCADSharp.Scripting;
using System.Collections.Concurrent;
namespace OSCADSharp.Solids
{
@ -71,7 +72,7 @@ namespace OSCADSharp.Solids
/// <returns>Script for this object</returns>
public override string ToString()
{
StatementBuilder sb = new StatementBuilder();
StatementBuilder sb = new StatementBuilder(this.bindings);
sb.Append("sphere(");
sb.AppendValuePairIfExists("r", this.Radius);
sb.AppendValuePairIfExists("$fn", this.Resolution, true);
@ -120,6 +121,11 @@ namespace OSCADSharp.Solids
}
private Bindings bindings = new Bindings();
private static Dictionary<string, string> bindingMapping = new Dictionary<string, string>()
{
{ "radius", "r" }
};
/// <summary>
/// Binds a a variable to a property on this object
/// </summary>
@ -128,7 +134,31 @@ namespace OSCADSharp.Solids
/// literal value of the property</param>
public void Bind(string property, Variable variable)
{
this.bindings.Add(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
}