001/* Factory that creates the schedule plotter. 002 003@Copyright (c) 2008-2015 The Regents of the University of California. 004All rights reserved. 005 006Permission is hereby granted, without written agreement and without 007license or royalty fees, to use, copy, modify, and distribute this 008software and its documentation for any purpose, provided that the 009above copyright notice and the following two paragraphs appear in all 010copies of this software. 011 012IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 013FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 014ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 015THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 016SUCH DAMAGE. 017 018THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 019INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 020MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 021PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023ENHANCEMENTS, OR MODIFICATIONS. 024 025 PT_COPYRIGHT_VERSION_2 026 COPYRIGHTENDKEY 027 028 029 */ 030package ptolemy.actor.gui; 031 032import java.awt.Frame; 033import java.util.HashMap; 034import java.util.List; 035 036import ptolemy.actor.ActorExecutionAspect; 037import ptolemy.actor.ExecutionAspectListener; 038import ptolemy.kernel.util.IllegalActionException; 039import ptolemy.kernel.util.InternalErrorException; 040import ptolemy.kernel.util.NameDuplicationException; 041import ptolemy.kernel.util.NamedObj; 042import ptolemy.plot.Plot; 043 044/** Factory that creates the plotter for the schedule of actors on a 045 * resource scheduler. 046 * 047 * @author Patricia Derler 048 @version $Id$ 049 @since Ptolemy II 10.0 050 051 @Pt.ProposedRating Red (derler) 052 @Pt.AcceptedRating Red (derler) 053 */ 054public class ExecutionAspectPlotterEditorFactory extends EditorFactory 055 implements ExecutionAspectListener { 056 057 /** 058 * Constructs a SchedulePlotter$SchedulePlotterEditorFactory object. 059 * 060 * @param container 061 * The container. 062 * @param name 063 * The name of the factory. 064 * @exception IllegalActionException 065 * If the factory is not of an acceptable attribute 066 * for the container. 067 * @exception NameDuplicationException 068 * If the name coincides with an attribute already in 069 * the container. 070 */ 071 public ExecutionAspectPlotterEditorFactory(NamedObj container, String name) 072 throws IllegalActionException, NameDuplicationException { 073 super(container, name); 074 } 075 076 /** The plot displayed by this ScheduleFactory. */ 077 public Plot plot; 078 079 /** 080 * Create an editor for configuring the specified object with the 081 * specified parent window. 082 * 083 * @param object 084 * The object to configure. 085 * @param parent 086 * The parent window, or null if there is none. 087 */ 088 @Override 089 public void createEditor(NamedObj object, Frame parent) { 090 try { 091 Configuration configuration = ((TableauFrame) parent) 092 .getConfiguration(); 093 094 //object.getContainer(); 095 096 plot = new Plot(); 097 plot.setTitle("Execution Time Monitor"); 098 plot.setButtons(true); 099 plot.setMarksStyle("none"); 100 plot.setXLabel("platform time"); 101 plot.setYLabel("actor ID"); 102 103 // We put the plotter as a sub-effigy of the toplevel effigy, 104 // so that it closes when the model is closed. 105 Effigy effigy = Configuration.findEffigy(toplevel()); 106 String name = "plotterEffigy" + String.valueOf(id++); 107 PlotEffigy schedulePlotterEffigy = new PlotEffigy(effigy, name); 108 schedulePlotterEffigy.setPlot(plot); 109 schedulePlotterEffigy.setModel(this.getContainer()); 110 schedulePlotterEffigy.identifier 111 .setExpression("Execution Time Monitor"); 112 113 configuration.createPrimaryTableau(schedulePlotterEffigy); 114 115 plot.setVisible(true); 116 117 if (_actors != null) { 118 _initPlot(); 119 } 120 } catch (Throwable throwable) { 121 throw new InternalErrorException(object, throwable, 122 "Cannot create Schedule Plotter"); 123 } 124 } 125 126 /** Plot a new execution event for an actor (i.e. an actor 127 * started/finished execution, was preempted or resumed). 128 * @param actor The actor. 129 * @param physicalTime The physical time when this scheduling event occurred. 130 * @param scheduleEvent The scheduling event. 131 */ 132 @Override 133 public void event(final NamedObj actor, double physicalTime, 134 ExecutionEventType scheduleEvent) { 135 if (plot == null) { 136 return; 137 } 138 139 double x = physicalTime; 140 int actorDataset = _actors.indexOf(actor); 141 if (actorDataset == -1) { 142 return; // actor is not being monitored 143 } 144 if (scheduleEvent == null) { 145 if (_previousY.get(actor) == null) { 146 _previousY.put(actor, (double) actorDataset); 147 } 148 plot.addPoint(actorDataset, x, _previousY.get(actor), true); 149 _previousY.put(actor, (double) actorDataset); 150 } else if (scheduleEvent == ExecutionEventType.START) { 151 plot.addPoint(actorDataset, x, _previousY.get(actor), true); 152 plot.addPoint(actorDataset, x, actorDataset + 0.6, true); 153 _previousY.put(actor, actorDataset + 0.6); 154 } else if (scheduleEvent == ExecutionEventType.STOP) { 155 if (_previousY.get(actor) != actorDataset) { 156 plot.addPoint(actorDataset, x, actorDataset + 0.6, true); 157 plot.addPoint(actorDataset, x, actorDataset, true); 158 } 159 _previousY.put(actor, (double) actorDataset); 160 } else if (scheduleEvent == ExecutionEventType.PREEMPTED) { 161 plot.addPoint(actorDataset, x, actorDataset + 0.6, true); 162 plot.addPoint(actorDataset, x, actorDataset + 0.4, true); 163 _previousY.put(actor, actorDataset + 0.4); 164 } 165 plot.fillPlot(); 166 plot.repaint(); 167 } 168 169 /** Initialize plot. 170 * @param actors Actors scheduled by the resource scheduler associated with 171 * this plot. 172 * @param scheduler Resource Scheduler associated with this plot. 173 */ 174 @Override 175 public void initialize(List<NamedObj> actors, 176 ActorExecutionAspect scheduler) { 177 _actors = actors; 178 _scheduler = scheduler; 179 if (plot != null) { 180 _initPlot(); 181 } 182 } 183 184 /** Contains the actors inside a ptides platform (=platforms). */ 185 protected List<NamedObj> _actors; 186 187 /** Initialize legend. 188 */ 189 private void _initPlot() { 190 plot.clearLegends(); 191 plot.clear(false); 192 plot.addLegend(_actors.size() - 1, _scheduler.getName()); 193 _previousY.put((NamedObj) _scheduler, 194 Double.valueOf(_actors.size() - 1)); 195 plot.clear(false); 196 plot.clearLegends(); 197 198 for (NamedObj actor : _actors) { 199 plot.addLegend(_actors.indexOf(actor), actor.getName()); 200 event(actor, 0.0, null); 201 _previousY.put(actor, Double.valueOf(_actors.indexOf(actor))); 202 } 203 plot.doLayout(); 204 } 205 206 /** The resource scheduler associated with this plot. 207 */ 208 private ActorExecutionAspect _scheduler; 209 210 /** Previous positions of the actor data set. */ 211 private HashMap<NamedObj, Double> _previousY = new HashMap<NamedObj, Double>(); 212 213 /** This static variable is increased by 1 every time a new 214 * SchedulePlotter is generated. The id is assigned as a unique 215 * id to every schedule plotter. 216 */ 217 private static int id = 1; 218}