public SubExpressionUpdate(ICalculator calculator, IFunction callFunction, string val, int propIndex, IVariable relative) { if (propIndex == -1 && callFunction is IVariableReferencePropertyUsage) { if (val != relative.Name) { // Compute dependicy properties before returning the variable // in order to receive correct values. object var = calculator.ComputeVariable(val, null); string[] props = ((IVariableReferencePropertyUsage)callFunction).GetDependices(var.GetType()); if (props != null) { foreach (string prop in props) { Expression exp = calculator.GetExpressionObject(val + "." + prop); if (exp != null) m_expressionList.Add(exp); } } } } else if (propIndex > 0) { // Compute property dependices before this. string name = val.Substring(0, propIndex); if (name != relative.Name) { object var = calculator.ComputeVariable(name, null); if (var is IOptimizable) { IOptimizable opt = (IOptimizable)var; PropertyDependicy[] deps = opt.PropertyDependices; string prop = val.Substring(propIndex + 1); if (deps != null) { Expression[] exps = new Expression[1]; foreach (PropertyDependicy dep in deps) { if (dep.ParentProperty == prop) { Expression exp = calculator.GetExpressionObject(name + "." + dep.ChildProperty); if (exp != null) m_expressionList.Add(exp); } } } } } } }
//Get a table with all expressions. public Expression[] GetExpressions() { Expression[] expressions = new Expression[m_expressions.Count]; m_expressions.Values.CopyTo(expressions, 0); return expressions; }
//Computes the value and puts the result to property. public void Assign(string key, string expression) { string name = key.Substring(0, key.LastIndexOf(PROPERTY_CHAR)); string prop = key.Substring(key.LastIndexOf(PROPERTY_CHAR) + 1); IVariable var = base.Variable(name); try { System.Reflection.PropertyInfo propertyInfo = var.GetType().GetProperty(prop); Type type = propertyInfo.PropertyType; object calcValue = this.Compute(expression, var); if (object.ReferenceEquals(type, typeof(float))) { calcValue = Convert.ToSingle(calcValue); } else if (object.ReferenceEquals(type, typeof(int))) { calcValue = Convert.ToInt32(calcValue); } else if (!object.ReferenceEquals(type, typeof(string)) && calcValue is string) { calcValue = Convert.ToString(calcValue); } var.GetType().InvokeMember(prop, System.Reflection.BindingFlags.SetProperty, null, var, new object[] {calcValue}); } catch (Exception ex) { //Collection exceptions. if (ex is ExpressionException) { m_exceptions.AddException((ExpressionException)ex); } else if (ex is MissingMemberException) { //Incompatible datatype between property and expression. ExpressionException expressionException = new ExpressionException("Expression result is not compatible with property", 0, expression.Length); Expression exp = new Expression(); exp.SetExpression(key, expression, this); expressionException.Expression = exp; m_exceptions.AddException(expressionException); } } }
//Add a new expression. public void AddExpression(string key, string expression) { Expression expr = new Expression(); expr.SetExpression(key, expression, this); this.m_expressions.Add(key, expr); }
public Expression[] GetExpressions() { //(16.10.2006 09:02) //Make thread safe. lock (this) { //Create a list with indirect expressions last. int directCount = m_direct.Count; Expression[] exps = new Expression[directCount]; m_direct.CopyTo(exps, 0); return exps; } }
public void Add(string key, Expression exp) { //(16.10.2006 09:02) //Make thread safe. lock (this) { if (!m_computing.Contains(key)) { m_computing.Add(key, key); m_direct.Enqueue(exp); //Reset the buffer before computing. exp.ResetBuffer(); } } }
//Copies the optimize info to another optimize manager so //optimzing is not necessary. Expressions should be exactly the same. public void CopyInfoTo(OptimizeManager optimizeManager) { //Set the expressions that is not optimizable. Expression[] notOptimizables = new Expression[this.m_notOptimizables.Length]; Calculator calc = optimizeManager.Calculator; for (int i = 0; i < this.m_notOptimizables.Length; i++) { notOptimizables[i] = calc.GetExpressionObject(this.m_notOptimizables[i].Key); } optimizeManager.m_notOptimizables = notOptimizables; optimizeManager.m_eventGraph = new Hashtable(); foreach (DictionaryEntry entry in this.m_eventGraph) { ArrayList events = (ArrayList)entry.Value; ArrayList newEvents = new ArrayList(); foreach (Expression exp in events) newEvents.Add(calc.GetExpressionObject(exp.Key)); optimizeManager.m_eventGraph[entry.Key] = newEvents; } //Set the object map. IVariable[] variables = optimizeManager.Calculator.GetVariables(); foreach (IVariable variable in variables) { if (variable is IOptimizable) ((IOptimizable)variable).PropertyChanged += new PropertyChangedEventHandler(optimizeManager.PropertyChanged); } //Copy object references. optimizeManager.m_objectReferences = new ArrayList(); foreach (string objectReference in this.m_objectReferences) optimizeManager.m_objectReferences.Add(objectReference); //Clone compute list. //Shares indirection info, which makes computation faster in the start. // optimizeManager.m_computeList = this.m_computeList.Clone(); optimizeManager.m_computeList = new ComputeList(); }