/// <summary> /// Adds a model as a child to a parent model. Will throw if not allowed. /// </summary> /// <param name="modelToAdd">The model to add.</param> /// <param name="parent">The parent model to add it to.</param> public static IModel Add(IModel modelToAdd, IModel parent) { if (parent.ReadOnly) { throw new Exception(string.Format("Unable to modify {0} - it is read-only.", parent.Name)); } if (modelToAdd is Simulations s && s.Children.Count == 1) { modelToAdd = s.Children[0]; } modelToAdd.Parent = parent; Apsim.ParentAllChildren(modelToAdd); parent.Children.Add(modelToAdd as Model); // Ensure the model name is valid. EnsureNameIsUnique(modelToAdd); // Call OnCreated modelToAdd.OnCreated(); Apsim.ChildrenRecursively(modelToAdd).ForEach(m => m.OnCreated()); Apsim.ClearCaches(modelToAdd); return(modelToAdd); }
/// <summary>Perform the actual replacement.</summary> private void ReplaceModel(IModel match) { // Fixme - this code should be in Structure.cs. IModel newModel = Apsim.Clone(replacement); int index = match.Parent.Children.IndexOf(match as Model); match.Parent.Children.Insert(index, newModel as Model); newModel.Parent = match.Parent; newModel.Name = match.Name; newModel.Enabled = match.Enabled; // If a resource model (e.g. maize) is copied into replacements, and its // property values changed, these changed values will be overriden with the // 'accepted' values from the official maize model when the simulation is // run, because the model's resource name is not null. This can be manually // rectified by editing the json, but such an intervention shouldn't be // necessary. if (newModel is ModelCollectionFromResource resourceModel) { resourceModel.ResourceName = null; } match.Parent.Children.Remove(match as Model); Apsim.ClearCaches(match); // Don't call newModel.Parent.OnCreated(), because if we're replacing // a child of a resource model, the resource model's OnCreated event // will make it reread the resource string and replace this child with // the 'official' child from the resource. newModel.OnCreated(); foreach (var model in newModel.FindAllDescendants().ToList()) { model.OnCreated(); } }
/// <summary>Undo the command</summary> /// <param name="commandHistory">The command history instance</param> public void Undo(CommandHistory commandHistory) { if (this.modelWasRemoved) { this.parent.Children.Insert(pos, this.modelToDelete as Model); this.explorerView.Tree.AddChild(this.parent.FullPath, nodeDescription, pos); Apsim.ClearCaches(this.modelToDelete); } }
/// <summary>Undo the command</summary> /// <param name="tree">A tree view to which the changes will be applied.</param> /// <param name="modelChanged">Action to be performed if/when a model is changed.</param> public void Undo(ITreeView tree, Action <object> modelChanged) { if (modelWasRemoved) { parent.Children.Insert(Pos, this.modelToDelete as Model); Apsim.ClearCaches(this.modelToDelete); tree.AddChild(this.parent.FullPath, nodeDescription, Pos); tree.SelectedNode = modelToDelete.FullPath; } }
/// <summary> /// Adds a model as a child to a parent model. Will throw if not allowed. /// </summary> /// <param name="modelToAdd">The model to add.</param> /// <param name="parent">The parent model to add it to.</param> public static IModel Add(IModel modelToAdd, IModel parent) { if (parent.ReadOnly) { throw new Exception(string.Format("Unable to modify {0} - it is read-only.", parent.Name)); } if (modelToAdd is Simulations s && s.Children.Count == 1) { modelToAdd = s.Children[0]; } modelToAdd.Parent = parent; modelToAdd.ParentAllDescendants(); parent.Children.Add(modelToAdd); // Ensure the model name is valid. EnsureNameIsUnique(modelToAdd); // Call OnCreated modelToAdd.OnCreated(); foreach (IModel model in modelToAdd.FindAllDescendants().ToList()) { model.OnCreated(); } // If the model is being added at runtime then need to resolve links and events. Simulation parentSimulation = parent.FindAncestor <Simulation>(); if (parentSimulation != null && parentSimulation.IsRunning) { var links = new Links(parentSimulation.Services); links.Resolve(modelToAdd, true); var events = new Events(modelToAdd); events.ConnectEvents(); // Call StartOfSimulation events events.PublishToModelAndChildren("StartOfSimulation", new object[] { parent, new EventArgs() }); } Apsim.ClearCaches(modelToAdd); return(modelToAdd); }
/// <summary>Move a model from one parent to another.</summary> /// <param name="model">The model to move.</param> /// <param name="newParent">The new parente for the model.</param> public static void Move(IModel model, IModel newParent) { // Remove old model. if (model.Parent.Children.Remove(model as Model)) { // Clear the cache for all models in scope of the model to be moved. // The models in scope will be different after the move so we will // need to do this again after we move the model. Apsim.ClearCaches(model); newParent.Children.Add(model as Model); model.Parent = newParent; EnsureNameIsUnique(model); Apsim.ClearCaches(model); } else { throw new Exception("Cannot move model " + model.Name); } }
/// <summary>Perform the actual replacement.</summary> private void ReplaceModel(IModel match) { // Fixme - this code should be in Structure.cs. IModel newModel = Apsim.Clone(replacement); int index = match.Parent.Children.IndexOf(match as Model); match.Parent.Children.Insert(index, newModel as Model); newModel.Parent = match.Parent; newModel.Name = match.Name; newModel.Enabled = match.Enabled; match.Parent.Children.Remove(match as Model); Apsim.ClearCaches(match); // Don't call newModel.Parent.OnCreated(), because if we're replacing // a child of a resource model, the resource model's OnCreated event // will make it reread the resource string and replace this child with // the 'official' child from the resource. foreach (var model in Apsim.ChildrenRecursively(newModel.Parent)) { model.OnCreated(); } }
/// <summary> /// Adds a model as a child to a parent model. Will throw if not allowed. /// </summary> /// <param name="modelToAdd">The model to add.</param> /// <param name="parent">The parent model to add it to.</param> public static IModel Add(IModel modelToAdd, IModel parent) { if (parent.ReadOnly) { throw new Exception(string.Format("Unable to modify {0} - it is read-only.", parent.Name)); } if (modelToAdd is Simulations s && s.Children.Count == 1) { modelToAdd = s.Children[0]; } modelToAdd.Parent = parent; Apsim.ParentAllChildren(modelToAdd); parent.Children.Add(modelToAdd as Model); // Ensure the model name is valid. EnsureNameIsUnique(modelToAdd); // Call OnCreated modelToAdd.OnCreated(); Apsim.ChildrenRecursively(modelToAdd).ForEach(m => m.OnCreated()); // If the model is being added at runtime then need to resolve links and events. var parentSimulation = Apsim.Parent(parent, typeof(Simulation)) as Simulation; if (parentSimulation != null && parentSimulation.IsRunning) { var links = new Links(parentSimulation.Services); links.Resolve(modelToAdd, true); var events = new Events(modelToAdd); events.ConnectEvents(); } Apsim.ClearCaches(modelToAdd); return(modelToAdd); }
/// <summary>Deletes the specified model.</summary> /// <param name="model">The model.</param> public static bool Delete(IModel model) { Apsim.ClearCaches(model); return(model.Parent.Children.Remove(model as Model)); }
/// <summary>Renames a new model.</summary> /// <param name="model">The model to rename.</param> /// <param name="newName">The new name for the model.</param> /// <returns>The newly created model.</returns> public static void Rename(IModel model, string newName) { model.Name = newName; EnsureNameIsUnique(model); Apsim.ClearCaches(model); }