예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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();
            }
        }
예제 #3
0
 /// <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);
     }
 }
예제 #4
0
 /// <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;
     }
 }
예제 #5
0
        /// <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);
        }
예제 #6
0
 /// <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);
     }
 }
예제 #7
0
        /// <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();
            }
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
 /// <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));
 }
예제 #10
0
 /// <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);
 }