/// <summary>Startup the run.</summary> public void StartRun() { timer = new Stopwatch(); timer.Start(); ConnectLinksAndEvents(); _IsRunning = true; Locater.Clear(); if (Commencing != null) { Commencing.Invoke(this, new EventArgs()); } }
/// <summary>Startup the run.</summary> public void StartRun() { timer = new Stopwatch(); timer.Start(); Apsim.ConnectEvents(this); Apsim.ResolveLinks(this); foreach (Model child in Apsim.ChildrenRecursively(this)) { Apsim.ConnectEvents(child); Apsim.ResolveLinks(child); } _IsRunning = true; Locater.Clear(); if (Commencing != null) { Commencing.Invoke(this, new EventArgs()); } }
/// <summary>Startup the run.</summary> public void StartRun() { timer = new Stopwatch(); timer.Start(); Apsim.ConnectEvents(this); Apsim.ResolveLinks(this); foreach (Model child in Apsim.ChildrenRecursively(this)) { Apsim.ConnectEvents(child); Apsim.ResolveLinks(child); } _IsRunning = true; Locater.Clear(); Console.WriteLine("Running: " + Path.GetFileNameWithoutExtension(FileName) + " - " + Name); if (Commencing != null) { Commencing.Invoke(this, new EventArgs()); } }
/// <summary>Constructor</summary> public Simulation() { locater = new Locater(); }
/// <summary> /// Clears the existing Scoping Rules /// </summary> public void ClearCaches() { Scope.Clear(); Locater.Clear(); }
/// <summary>Sets the value of a variable. Will throw if variable doesn't exist.</summary> /// <param name="namePath">The name of the object to set</param> /// <param name="value">The value to set the property to</param> public void Set(string namePath, object value) { Locater.Set(namePath, this, value); }
/// <summary>Get the underlying variable object for the given path.</summary> /// <param name="namePath">The name of the variable to return</param> /// <returns>The found object or null if not found</returns> public IVariable GetVariableObject(string namePath) { return(Locater.GetInternal(namePath, this)); }
/// <summary>Gets the value of a variable or model.</summary> /// <param name="namePath">The name of the object to return</param> /// <returns>The found object or null if not found</returns> public object Get(string namePath) { return(Locater.Get(namePath, this)); }
/// <summary> /// Internal [link] resolution algorithm. /// </summary> /// <param name="obj"></param> /// <param name="scope">The scoping rules to use to resolve links.</param> private void ResolveInternal(object obj, ScopingRules scope) { foreach (IVariable field in GetAllDeclarations(GetModel(obj), GetModel(obj).GetType(), BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public, allLinks: true)) { LinkAttribute link = field.GetAttribute(typeof(LinkAttribute)) as LinkAttribute; if (link != null) { Type fieldType = field.DataType; if (fieldType.IsArray) { fieldType = fieldType.GetElementType(); } else if (field.DataType.Name.StartsWith("List") && field.DataType.GenericTypeArguments.Length == 1) { fieldType = field.DataType.GenericTypeArguments[0]; } List <object> matches; matches = services.FindAll(s => fieldType.IsAssignableFrom(s.GetType())); if (matches.Count == 0 && obj is IModel) { Simulation parentSimulation = Apsim.Parent(obj as IModel, typeof(Simulation)) as Simulation; if (fieldType.IsAssignableFrom(typeof(ILocator)) && parentSimulation != null) { matches.Add(new Locator(obj as IModel)); } else if (fieldType.IsAssignableFrom(typeof(IEvent)) && parentSimulation != null) { matches.Add(new Events(obj as IModel)); } } if (matches.Count == 0) { if (link is ParentLinkAttribute) { matches = new List <object>(); matches.Add(GetParent(obj, fieldType)); } else if (link is LinkByPathAttribute) { var locater = new Locater(); object match = locater.Get((link as LinkByPathAttribute).Path, obj as Model); if (match != null) { matches.Add(match); } } else if (link.IsScoped(field)) { matches = scope.FindAll(obj as IModel).Cast <object>().ToList(); } else { matches = GetChildren(obj); } } matches.RemoveAll(match => !fieldType.IsAssignableFrom(GetModel(match).GetType())); if (link.UseNameToMatch(field)) { matches.RemoveAll(match => !StringUtilities.StringsAreEqual(GetName(match), field.Name)); } if (field.DataType.IsArray) { Array array = Array.CreateInstance(fieldType, matches.Count); for (int i = 0; i < matches.Count; i++) { array.SetValue(GetModel(matches[i]), i); } field.Value = array; } else if (field.DataType.Name.StartsWith("List") && field.DataType.GenericTypeArguments.Length == 1) { var listType = typeof(List <>); var constructedListType = listType.MakeGenericType(fieldType); IList array = Activator.CreateInstance(constructedListType) as IList; for (int i = 0; i < matches.Count; i++) { array.Add(GetModel(matches[i])); } field.Value = array; } else if (matches.Count == 0) { if (!link.IsOptional) { throw new Exception("Cannot find a match for link " + field.Name + " in model " + GetFullName(obj)); } } else if (matches.Count >= 2 && !link.IsScoped(field)) { throw new Exception(string.Format(": Found {0} matches for link {1} in model {2} !", matches.Count, field.Name, GetFullName(obj))); } else { field.Value = GetModel(matches[0]); } } } }
/// <summary>Constructor</summary> public Simulation() { locater = new Locater(); scope = new ScopingRules(); }
/// <summary> /// Internal [link] resolution algorithm. /// </summary> /// <param name="obj"></param> /// <param name="scope">The scoping rules to use to resolve links.</param> /// <param name="throwOnFail">Should all links be considered optional?</param> private void ResolveInternal(object obj, ScopingRules scope, bool throwOnFail) { if (obj is Models.Management.RotationManager) { } foreach (IVariable field in GetAllDeclarations(GetModel(obj), GetModel(obj).GetType(), BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public, allLinks: true)) { LinkAttribute link = field.GetAttribute(typeof(LinkAttribute)) as LinkAttribute; if (link != null) { Type fieldType = field.DataType; if (fieldType.IsArray) { fieldType = fieldType.GetElementType(); } else if (field.DataType.Name.StartsWith("List") && field.DataType.GenericTypeArguments.Length == 1) { fieldType = field.DataType.GenericTypeArguments[0]; } List <object> matches; matches = services.FindAll(s => fieldType.IsAssignableFrom(s.GetType())); if (matches.Count == 0 && obj is IModel) { Simulation parentSimulation = (obj as IModel).FindAncestor <Simulation>(); if (typeof(ILocator).IsAssignableFrom(fieldType) && parentSimulation != null) { matches.Add(new Locator(obj as IModel)); } else if (typeof(IEvent).IsAssignableFrom(fieldType) && parentSimulation != null) { matches.Add(new Events(obj as IModel)); } } if (matches.Count == 0) { if (link.Type == LinkType.Ancestor) { matches = new List <object>(); if (obj is IModel model) { IModel ancestor = GetParent(model, fieldType); if (ancestor == null) { throw new Exception($"Unable to resolve link {field.Name} in model {model.FullPath}: {model.Name} has no ancestors of type {fieldType.Name}"); } matches.Add(ancestor); } else { throw new Exception($"Unable to resolve ancestor link {field.Name} in object of type {obj.GetType()}: object is not a model"); } } else if (link.Type == LinkType.Path) { var locater = new Locater(); object match = locater.Get(link.Path, obj as Model); if (match != null) { matches.Add(match); } } else if (link.Type == LinkType.Scoped) { matches = scope.FindAll(obj as IModel).Cast <object>().ToList(); } else { matches = GetChildren(obj); } } matches.RemoveAll(match => !fieldType.IsAssignableFrom(GetModel(match).GetType())); if (link.ByName) { matches.RemoveAll(match => !StringUtilities.StringsAreEqual(GetName(match), field.Name)); } if (field.DataType.IsArray) { Array array = Array.CreateInstance(fieldType, matches.Count); for (int i = 0; i < matches.Count; i++) { array.SetValue(GetModel(matches[i]), i); } field.Value = array; } else if (field.DataType.Name.StartsWith("List") && field.DataType.GenericTypeArguments.Length == 1) { var listType = typeof(List <>); var constructedListType = listType.MakeGenericType(fieldType); IList array = Activator.CreateInstance(constructedListType) as IList; for (int i = 0; i < matches.Count; i++) { array.Add(GetModel(matches[i])); } field.Value = array; } else if (matches.Count == 0 && !throwOnFail) { if (!link.IsOptional) { throw new Exception("Cannot find a match for link " + field.Name + " in model " + GetFullName(obj)); } } else if (matches.Count >= 2 && link.Type != LinkType.Scoped) { throw new Exception(string.Format(": Found {0} matches for link {1} in model {2} !", matches.Count, field.Name, GetFullName(obj))); } else { field.Value = GetModel(matches[0]); } } } }