nl.tudelft.goal.SimpleIDE.actions.RunAction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of simpleidemodules Show documentation
Show all versions of simpleidemodules Show documentation
An IDE for GOAL based on JEdit.
The newest version!
/**
* GOAL interpreter that facilitates developing and executing GOAL multi-agent
* programs. Copyright (C) 2011 K.V. Hindriks, W. Pasman
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*/
package nl.tudelft.goal.SimpleIDE.actions;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.JOptionPane;
import javax.swing.tree.TreeNode;
import goal.core.agent.Agent;
import goal.core.runtime.RuntimeEvent;
import goal.core.runtime.RuntimeEvent.EventType;
import goal.core.runtime.RuntimeEventObserver;
import goal.core.runtime.RuntimeManager;
import goal.tools.DebugRun;
import goal.tools.IDEGOALInterpreter;
import goal.tools.debugger.IDEDebugger;
import goal.tools.debugger.SteppingDebugger.RunMode;
import goal.tools.errorhandling.Resources;
import goal.tools.errorhandling.Warning;
import goal.tools.errorhandling.WarningStrings;
import goal.tools.errorhandling.exceptions.GOALException;
import goal.tools.errorhandling.exceptions.GOALRunFailedException;
import languageTools.program.mas.AgentDefinition;
import languageTools.program.mas.MASProgram;
import nl.tudelft.goal.SimpleIDE.EditManager;
import nl.tudelft.goal.SimpleIDE.IDEMainPanel;
import nl.tudelft.goal.SimpleIDE.IDENode;
import nl.tudelft.goal.SimpleIDE.IDEState;
import nl.tudelft.goal.SimpleIDE.IconFactory;
import nl.tudelft.goal.SimpleIDE.IdeFiles;
import nl.tudelft.goal.SimpleIDE.ProcessNode;
import nl.tudelft.goal.SimpleIDE.TextEditorInterface;
import nl.tudelft.goal.SimpleIDE.filenodes.AbstractFileNode;
import nl.tudelft.goal.SimpleIDE.filenodes.MASNode;
/**
* Run a process or mas file. IDE figures out whether run or pause action is
* appropriate
*
* @author W.Pasman 20jun2011
*/
public class RunAction extends GOALAction {
private static final long serialVersionUID = 701784252328131654L;
public RunAction() {
setIcon(IconFactory.RUN.getIcon());
setShortcut('R');
setDescription("Launch multi-agent system"); //$NON-NLS-1$
}
@Override
public void eventOccured(IDEState currentState, Object evt) {
boolean enabled = false;
if (currentState.getViewMode() == IDEMainPanel.EDIT_VIEW) {
List extends AbstractFileNode> sel = currentState.getSelectedFileNodes();
if (!sel.isEmpty()) {
enabled = updateState(sel.get(0));
}
} else {
// debug mode
List extends IDENode> sel = currentState.getSelectedProcessNodes();
if (!sel.isEmpty()) {
enabled = updateState(sel.get(0));
}
}
setActionEnabled(enabled);
}
private boolean updateState(AbstractFileNode node) {
if (node.getParentMASNode() == null || getCurrentState().getRuntime() != null) {
return false;
}
if (!IdeFiles.getInstance().getErrors(node.getParentMASNode().getBaseFile()).isEmpty()) {
return false;
}
setDescription("Launch multi-agent system");
return true;
}
private boolean updateState(IDENode node) {
switch (node.getType()) {
case MAS_PROCESS:
setDescription("Run all agents"); //$NON-NLS-1$
return ((ProcessNode) node).getProcessRunMode() != RunMode.RUNNING;
case AGENT_PROCESS:
setDescription("Run agent"); //$NON-NLS-1$
return ((ProcessNode) node).getProcessRunMode() != RunMode.RUNNING;
case ENVIRONMENT_PROCESS:
setDescription("Run environment"); //$NON-NLS-1$
return ((ProcessNode) node).getProcessRunMode() != RunMode.RUNNING;
default:
return false;
}
}
@Override
protected void execute(TreeNode selectedNode, ActionEvent ae) throws GOALException {
// Check first whether we're in edit view and a MAS is already running.
// In that case, simply switch view to debug view.
if (getCurrentState().getViewMode() == IDEMainPanel.EDIT_VIEW && getCurrentState().getRuntime() != null) {
getIDE().getMainPanel().switchView();
return;
}
if (selectedNode instanceof AbstractFileNode) {
// run a MAS file
run((AbstractFileNode) selectedNode);
} else {
// run a Process node
run((IDENode) selectedNode);
}
}
/**
*
* @param node
* @throws GOALException
*/
private void run(IDENode node) throws GOALException {
if (getCurrentState().getViewMode() == IDEMainPanel.DEBUG_VIEW) {
// user runs a process node. Restart it and we're done
getIDE().getMainPanel().getProcessPanel().runProcessNode((ProcessNode) node);
return;
}
}
private void run(AbstractFileNode node) throws GOALRunFailedException {
// TODO: only require to save only used files.
if (!checkAllSaved()) {
// Do nothing if the user canceled the save all action.
return;
}
// If the node is the root node, check if there is a single unique
// MAS we can launch.
MASNode masnode = node.getParentMASNode();
if (masnode == null) {
new Warning(Resources.get(WarningStrings.FAILED_RUN_NO_MAS)).emit();
return;
}
// Parse MAS file. Ensures latest version is ran.
File masFile = masnode.getBaseFile();
DebugRun run = new DebugRun(masFile);
if (!run.getErrors().isEmpty()) {
new Warning(Resources.get(WarningStrings.FAILED_RUN_MAS_ERRORS)).emit();
return;
}
MASProgram masProg = run.getProgram();
Set definitions = new HashSet<>();
for (String name : masProg.getAgentNames()) {
definitions.add(masProg.getAgentDefinition(name));
}
// disable editing of all involved files.
for (AgentDefinition agentDef : definitions) {
TextEditorInterface editor = EditManager.getInstance()
.getEditorPane(agentDef.getSourceInfo().getSource().toString());
// TODO: QUICK HACK. #1717. We need to lock ALL files, not
// just agent files.
if (editor != null) {
editor.setEditable(false);
}
}
// Launch the MAS.
try {
// update all breakpoints
for (File file : IdeFiles.getInstance().getUsedFiles(masProg)) {
EditManager.getInstance().updateBreakpoints(file);
}
run.buildRuntime();
RuntimeManager runtime = run.getManager();
// Update view.
getCurrentState().setRuntime(run);
getIDE().getMainPanel().getProcessPanel().init();
getIDE().getMainPanel().switchView();
// Subscribe feedback and process panels as observers.
runtime.addObserver(getIDE().getMainPanel().getFeedbackPanel());
runtime.addObserver(getIDE().getMainPanel().getProcessPanel());
// connect the breakpoints. Unfortunately we need a listener and 15
// lines for that...
runtime.addObserver(new RuntimeEventObserver() {
@SuppressWarnings("unchecked")
@Override
public void eventOccured(RuntimeManager, ?> source, RuntimeEvent event) {
if (event.getType() == EventType.AGENT_IS_LOCAL_AND_READY) {
final Agent agent = (Agent) event.getSource();
agent.getController().keepDataOnTermination();
agent.getController().getDebugger()
.setBreakpoints(getCurrentState().getBreakpointManager().getBreakpoints());
agent.getController().getDebugger().step(); // SimpleIDE
// always
// wants to
// start
// stepping
}
}
});
runtime.start(false);
} catch (Exception e) { // TODO: distinguish between types of
// exceptions...
new Warning(Resources.get(WarningStrings.FAILED_RUN_MAS), e).emit();
for (TextEditorInterface editor : EditManager.getInstance().getEditors()) {
editor.setEditable(true);
}
}
}
/**
* Save all files.
*
* @return {@code false} if user cancelled or a problem while saving
* occurred; {@code true} otherwise.
*/
private boolean checkAllSaved() {
if (EditManager.getInstance().isDirty()) { // content has been
// edited
int selection = JOptionPane.showConfirmDialog(getCurrentState().getRootComponent(),
"Save all files?\n" //$NON-NLS-1$
+ "Some files were edited but are not yet saved. " //$NON-NLS-1$
+ "All files must be saved before launching.", //$NON-NLS-1$
"Save all files?", JOptionPane.OK_CANCEL_OPTION); //$NON-NLS-1$
switch (selection) {
case JOptionPane.CANCEL_OPTION:
// cancel -> exit
return false;
case JOptionPane.OK_OPTION:
// OK -> save all and continue
try {
EditManager.getInstance().saveAll();
} catch (GOALException e) {
new Warning(Resources.get(WarningStrings.FAILED_SAVEALL), e).emit();
return false;
}
break;
}
}
return true;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy