public void Links_EnsureChildLinkByNameWorks() { ModelWithChildLinkByName modelWithChildLinkByName = new UnitTests.ModelWithChildLinkByName(); // Create a simulation ModelWrapper simulation = new ModelWrapper(new Simulation()); simulation.Add(new Clock()); simulation.Add(new MockSummary()); simulation.Add(modelWithChildLinkByName); simulation.Children[2].Add(new Zone() { Name = "zone1" }); // added to modelWithChildLink simulation.Children[2].Add(new Zone() { Name = "zone2" }); // added to modelWithChildLink Links linksAlgorithm = new Links(); linksAlgorithm.Resolve(simulation); // Should find zone2 as a match as it uses the fields name. Assert.AreEqual(modelWithChildLinkByName.zone2.Name, "zone2"); }
public void Links_EnsureChildLinkWorks() { ModelWithChildLink modelWithChildLink = new UnitTests.ModelWithChildLink(); // Create a simulation ModelWrapper simulation = new ModelWrapper(new Simulation()); simulation.Add(new Clock()); simulation.Add(new MockSummary()); simulation.Add(modelWithChildLink); simulation.Children[2].Add(new Zone() { Name = "zone1" }); // added to modelWithChildLink Links linksAlgorithm = new Links(); linksAlgorithm.Resolve(simulation); // Should find zone1 as a match i.e. not use the zones name when doing a match. Assert.AreEqual(modelWithChildLink.zone2.Name, "zone1"); // If we now add another child, resolve should fail as there are two matches. simulation.Children[2].Add(new Zone() { Name = "zone2" }); // added to modelWithChildLink Assert.Throws<Exception>(() => linksAlgorithm.Resolve(simulation) ); }
public void Links_EnsureIFunctionLinksCorrectly() { // Create a tree with a root node for our models. ModelWrapper models = new ModelWrapper(); // Create some models. ModelWrapper simulations = models.Add(new Simulations()); ModelWrapper simulation = simulations.Add(new Simulation()); Clock clock = new Clock(); clock.StartDate = new DateTime(2015, 1, 1); clock.EndDate = new DateTime(2015, 12, 31); simulation.Add(clock); MockSummary summary = new MockSummary(); simulation.Add(summary); simulation.Add(new Zone()); simulation.Add(new Zone()); ModelWrapper links = simulation.Add(new ModelWithIFunctions()); simulation.Add(links); links.Add(new IFunctionProxy() { value = 1 }).Name = "model1"; links.Add(new IFunctionProxy() { value = 2 }).Name = "model2"; links.Add(new IFunctionProxy() { value = 3 }).Name = "model3"; Links linksAlgorithm = new Links(); linksAlgorithm.Resolve(simulations); Assert.AreEqual((links.Model as ModelWithIFunctions).model2.Value, 2); }
public void Links_EnsureOldStyleLinkWorks() { // Create a tree with a root node for our models. ModelWrapper models = new ModelWrapper(); // Create some models. ModelWrapper simulations = models.Add(new Simulations()); ModelWrapper simulation = simulations.Add(new Simulation()); Clock clock = new Clock(); clock.StartDate = new DateTime(2015, 1, 1); clock.EndDate = new DateTime(2015, 12, 31); simulation.Add(clock); MockSummary summary = new MockSummary(); simulation.Add(summary); simulation.Add(new Zone()); simulation.Add(new Zone()); ModelWithLinks links = new ModelWithLinks(); simulation.Add(links); Links linksAlgorithm = new Links(); linksAlgorithm.Resolve(simulations); Assert.AreEqual(links.zones.Length, 2); Assert.NotNull(links.zones[0]); Assert.NotNull(links.zones[1]); }
public void Links_EnsureScopedLinkWorks() { ModelWithScopedLink modelWithScopedLink = new UnitTests.ModelWithScopedLink(); // Create a simulation ModelWrapper simulation = new ModelWrapper(new Simulation()); simulation.Add(new Clock()); simulation.Add(new MockSummary()); simulation.Add(new Zone() { Name = "zone1" }); simulation.Add(new Zone() { Name = "zone2" }); simulation.Children[1].Add(modelWithScopedLink); // added to zone1 Links linksAlgorithm = new Links(); linksAlgorithm.Resolve(simulation); // Should find the closest match. Assert.AreEqual(modelWithScopedLink.zone2.Name, "zone1"); }
/// <summary>Connect all links and events in simulation</summary> public void ConnectLinksAndEvents() { scope = new ScopingRules(); events = new Events(this); events.ConnectEvents(); links = new Core.Links(); links.Resolve(this); }
/// <summary> /// Nulls the link object, which will force it to be recreated when it's needed /// </summary> public void ClearLinks() { links = null; }
/// <summary> /// Prepare the simulation for running. /// </summary> public void Prepare() { // Remove disabled models. RemoveDisabledModels(this); // Standardise the soil. var soils = FindAllDescendants <Soils.Soil>(); foreach (Soils.Soil soil in soils) { SoilStandardiser.Standardise(soil); } // If this simulation was not created from deserialisation then we need // to parent all child models correctly and call OnCreated for each model. bool hasBeenDeserialised = Children.Count > 0 && Children[0].Parent == this; if (!hasBeenDeserialised) { // Parent all models. this.ParentAllDescendants(); // Call OnCreated in all models. foreach (IModel model in FindAllDescendants().ToList()) { model.OnCreated(); } } // Call OnPreLink in all models. // Note the ToList(). This is important because some models can // add/remove models from the simulations tree in their OnPreLink() // method, and FindAllDescendants() is lazy. FindAllDescendants().ToList().ForEach(model => model.OnPreLink()); if (Services == null || Services.Count < 1) { var simulations = FindAncestor <Simulations>(); if (simulations != null) { Services = simulations.GetServices(); } else { Services = new List <object>(); IDataStore storage = this.FindInScope <IDataStore>(); if (storage != null) { Services.Add(this.FindInScope <IDataStore>()); } } } if (!Services.OfType <ScriptCompiler>().Any()) { Services.Add(new ScriptCompiler()); } var links = new Links(Services); var events = new Events(this); try { // Connect all events. events.ConnectEvents(); // Resolve all links links.Resolve(this, true, throwOnFail: true); events.Publish("SubscribeToEvents", new object[] { this, EventArgs.Empty }); } catch (Exception err) { throw new SimulationException("", err, Name, FileName); } }
/// <summary> /// Runs the simulation on the current thread and waits for the simulation /// to complete before returning to caller. Simulation is NOT cloned before /// running. Use instance of Runner to get more options for running a /// simulation or groups of simulations. /// </summary> /// <param name="cancelToken">Is cancellation pending?</param> public void Run(CancellationTokenSource cancelToken = null) { IsRunning = true; // If the cancelToken is null then give it a default one. This can happen // when called from the unit tests. if (cancelToken == null) { cancelToken = new CancellationTokenSource(); } // Remove disabled models. RemoveDisabledModels(this); // If this simulation was not created from deserialisation then we need // to parent all child models correctly and call OnCreated for each model. bool hasBeenDeserialised = Children.Count > 0 && Children[0].Parent == this; if (!hasBeenDeserialised) { // Parent all models. Apsim.ParentAllChildren(this); // Call OnCreated in all models. Apsim.ChildrenRecursively(this).ForEach(m => m.OnCreated()); } if (Services == null || Services.Count < 1) { var simulations = Apsim.Parent(this, typeof(Simulations)) as Simulations; if (simulations != null) { Services = simulations.GetServices(); } else { Services = new List <object>(); IDataStore storage = Apsim.Find(this, typeof(IDataStore)) as IDataStore; if (storage != null) { Services.Add(Apsim.Find(this, typeof(IDataStore))); } Services.Add(new ScriptCompiler()); } } var links = new Links(Services); var events = new Events(this); try { // Connect all events. events.ConnectEvents(); // Resolve all links links.Resolve(this, true); // Invoke our commencing event to let all models know we're about to start. Commencing?.Invoke(this, new EventArgs()); // Begin running the simulation. DoCommence?.Invoke(this, new CommenceArgs() { CancelToken = cancelToken }); } catch (Exception err) { // Exception occurred. Write error to summary. string errorMessage = "ERROR in file: " + FileName + Environment.NewLine + "Simulation name: " + Name + Environment.NewLine; errorMessage += err.ToString(); summary?.WriteError(this, errorMessage); // Rethrow exception throw new Exception(errorMessage, err); } finally { // Signal that the simulation is complete. Completed?.Invoke(this, new EventArgs()); // Disconnect our events. events.DisconnectEvents(); // Unresolve all links. links.Unresolve(this, true); IsRunning = false; } }
/// <summary>Create a links object</summary> private void CreateLinks() { links = new Links(GetServices()); }