Initial checkin of unified hierarchy of WPILib 2015

This commit is contained in:
Brad Miller
2013-12-15 18:30:16 -05:00
commit 3178911eef
1560 changed files with 410007 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
package edu.wpi.first.wpilib.plugins.cpp;
import java.io.File;
import java.util.Properties;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.ui.IStartup;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
import edu.wpi.first.wpilib.plugins.core.ant.AntPropertiesParser;
import edu.wpi.first.wpilib.plugins.cpp.installer.CPPInstaller;
import edu.wpi.first.wpilib.plugins.cpp.preferences.PreferenceConstants;
/**
* The activator class controls the plug-in life cycle
*/
public class WPILibCPPPlugin extends AbstractUIPlugin implements IStartup {
// The plug-in ID
public static final String PLUGIN_ID = "WPILib_CPP_Robot_Development"; //$NON-NLS-1$
// The shared instance
private static WPILibCPPPlugin plugin;
/**
* The constructor
*/
public WPILibCPPPlugin() {
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static WPILibCPPPlugin getDefault() {
return plugin;
}
public String getDefaultToolchainVersion() {
return "arm-none-linux-gnueabi-4.4.1";
}
public String getToolchain() {
return WPILibCore.getDefault().getWPILibBaseDir()
+ File.separator + "toolchains" + File.separator + getPreferenceStore().getString(PreferenceConstants.TOOLCHAIN_VERSION);
}
public String getCurrentVersion() {
try {
Properties props = new AntPropertiesParser(WPILibCPPPlugin.class.getResourceAsStream("/resources/configuration.properties")).getProperties();
if (props.getProperty("version").startsWith("$")) {
return "DEVELOPMENT";
} else {
return props.getProperty("version");
}
} catch (CoreException e) {
return "DEVELOPMENT";
}
}
public String getCPPDir() {
return WPILibCore.getDefault().getWPILibBaseDir()
+ File.separator + "cpp" + File.separator + getPreferenceStore().getString(PreferenceConstants.LIBRARY_VERSION);
}
@Override
public void earlyStartup() {
new CPPInstaller(getCurrentVersion()).installIfNecessary();
}
}

View File

@@ -0,0 +1,46 @@
package edu.wpi.first.wpilib.plugins.cpp.installer;
import java.io.InputStream;
import java.util.Properties;
import org.eclipse.jface.preference.IPreferenceStore;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
import edu.wpi.first.wpilib.plugins.core.installer.AbstractInstaller;
import edu.wpi.first.wpilib.plugins.cpp.WPILibCPPPlugin;
import edu.wpi.first.wpilib.plugins.cpp.preferences.PreferenceConstants;
/**
* Installs the given version of WPILib into the correct location. Where the
* install directory is usually ~/wpilib/cpp/version.
*
* @author alex
*/
public class CPPInstaller extends AbstractInstaller {
public CPPInstaller(String version) {
super(version);
}
@Override
protected String getFeatureName() {
return "cpp";
}
@Override
protected void updateInstalledVersion(String version) {
IPreferenceStore prefs = WPILibCPPPlugin.getDefault().getPreferenceStore();
if (prefs.getBoolean(PreferenceConstants.UPDATE_LIBRARY_VERSION)) {
System.out.println("Forcing library version to "+version);
Properties props = WPILibCore.getDefault().getProjectProperties(null);
props.setProperty("cpp-version", version);
WPILibCore.getDefault().saveGlobalProperties(props);
prefs.setValue(PreferenceConstants.LIBRARY_VERSION, version);
}
}
@Override
protected InputStream getInstallResourceStream() {
return CPPInstaller.class.getResourceAsStream("/resources/cpp.zip");
}
}

View File

@@ -0,0 +1,184 @@
package edu.wpi.first.wpilib.plugins.cpp.launching;
import java.io.File;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.launch.remote.IRemoteConnectionConfigurationConstants;
import org.eclipse.core.internal.resources.Resource;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.ILaunchShortcut;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.PlatformUI;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
import edu.wpi.first.wpilib.plugins.core.launching.AntLauncher;
import edu.wpi.first.wpilib.plugins.cpp.WPILibCPPPlugin;
/**
* Launch shortcut base functionality, common for deploying to the robot.
* Retrieves the project the operation is being called on, and runs the correct
* ant targets based on polymorphically determined data values
*
* @author Ryan O'Meara
* @author Alex Henning
*/
@SuppressWarnings("restriction")
public class DeployLaunchShortcut implements ILaunchShortcut {
//Class constants - used to delineate types for launch shortcuts
public static final String DEPLOY_TYPE = "edu.wpi.first.wpilib.plugins.core.deploy";
private static final String ANT_SERVER_THREAD_NAME = "Ant Build Server Connection";
private static ILaunch lastDeploy = null;
/**
* Returns the launch type of the shortcut that was used, one of the constants
* defined in BaseLaunchShortcut
* @return Launch shortcut type
*/
public String getLaunchType() {return DEPLOY_TYPE;}
@Override
public void launch(ISelection selection, String mode) {
//Extract resource from selection
StructuredSelection sel = (StructuredSelection)selection;
IProject activeProject = null;
if (sel.getFirstElement() instanceof IProject) {
activeProject = (IProject) sel.getFirstElement();
} else {
return;
}
//Run config using project found in extracted resource, with indicated mode
runConfig(activeProject, mode);
}
@Override
public void launch(IEditorPart editor, String mode) {
//Extract resource from editor
if(editor != null){
IFileEditorInput input = (IFileEditorInput)editor.getEditorInput();
IFile file = input.getFile();
IProject activeProject = file.getProject();
//If editor existed, run config using extracted resource in indicated mode
runConfig(activeProject, mode);
}else{
System.err.println("editor was null");
}
}
/**
* Runs the ant script using the correct target for the indicated mode (deploy to cRIO or just compile)
* @param activeProj The project that the script will be run on/from
* @param mode The mode it will be run in (ILaunchManager.RUN_MODE or ILaunchManager.DEBUG_MODE)
*/
public void runConfig(IProject activeProj, String mode){
String targets = "deploy";
if(mode.equals(ILaunchManager.RUN_MODE)){
if(getLaunchType().equals(DEPLOY_TYPE)){
targets = "deploy";
}
} else if ((mode.equals(ILaunchManager.DEBUG_MODE))&&(getLaunchType().equals(DEPLOY_TYPE))) {
targets = "debug-deploy";
try{
PlatformUI.getWorkbench().showPerspective(IDebugUIConstants.ID_DEBUG_PERSPECTIVE,
PlatformUI.getWorkbench().getActiveWorkbenchWindow());
}catch(Exception e){}
}
if((lastDeploy != null)&&(!lastDeploy.isTerminated())){
System.out.println("Last deploy running");
//Find the server connection thread and kill it
Vector<ThreadGroup> threadGroups = new Vector<ThreadGroup>();
ThreadGroup root = Thread.currentThread().getThreadGroup().getParent();
while (root.getParent() != null) {root = root.getParent();}
threadGroups.add(root);
ThreadGroup threadGroup = threadGroups.remove(0);
int numThreads = threadGroup.activeCount();
Thread[] threads = new Thread[numThreads*100];
numThreads = threadGroup.enumerate(threads, true);
for(Thread current: threads){
if(current != null){
if(current.getName().equals(ANT_SERVER_THREAD_NAME)){
try{
//Manually end thread and then try terminating launch
Method stopMethod = current.getClass().getMethod("stop");
stopMethod.invoke(current);
lastDeploy.terminate();
break;
}catch(Exception e){e.printStackTrace();}
}
}
}
System.out.println("Waiting");
try{wait(1000);}catch(Exception e){}
}
if (mode.equals(ILaunchManager.RUN_MODE)) {
System.out.println("Running ant file: " + activeProj.getLocation().toOSString() + File.separator + "build.xml");
System.out.println("Targets: " + targets + ", Mode: " + mode);
lastDeploy = AntLauncher.runAntFile(new File (activeProj.getLocation().toOSString() + File.separator + "build.xml"), targets, null, mode);
} else if((mode.equals(ILaunchManager.DEBUG_MODE))&&(getLaunchType().equals(DEPLOY_TYPE))) {
ILaunchConfigurationWorkingCopy config;
try {
config = getRemoteDebugConfig(activeProj);
//config.doSave(); // NOTE: For debugging
startDebugConfig(config, lastDeploy);
} catch (CoreException e) {
System.err.println("Debug attach failed.");
e.printStackTrace();
}
}
try {
activeProj.refreshLocal(Resource.DEPTH_INFINITE, null);
} catch (Exception e) {}
}
private ILaunchConfigurationWorkingCopy getRemoteDebugConfig(IProject activeProj) throws CoreException {
ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
ILaunchConfigurationType type = manager.getLaunchConfigurationType(ICDTLaunchConfigurationConstants.ID_LAUNCH_C_REMOTE_APP);
int teamNumber = WPILibCore.getDefault().getTeamNumber(activeProj);
String remote_connection = RSEUtils.getTarget(teamNumber).getName();
ILaunchConfigurationWorkingCopy config = type.newInstance(null, "Debug "+activeProj.getName());
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, activeProj.getName());
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, "Debug/FRCUserProgram");
config.setAttribute(DebugPlugin.getUniqueIdentifier() + ".ATTR_TARGET_PATH", "/home/admin/FRCUserProgram");
config.setAttribute("org.eclipse.cdt.debug.mi.core.DEBUG_NAME", WPILibCPPPlugin.getDefault().getToolchain()+"/bin/arm-none-linux-gnueabi-gdb");
config.setAttribute("org.eclipse.cdt.dsf.gdb.DEBUG_NAME", WPILibCPPPlugin.getDefault().getToolchain()+"/bin/arm-none-linux-gnueabi-gdb");
config.setAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION, remote_connection);
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ID, "org.eclipse.rse.remotecdt.RemoteGDBDebugger");
Map<String, String> launchers = new HashMap<String, String>();
launchers.put("[debug]", "org.eclipse.rse.remotecdt.launch");
config.setAttribute(DebugPlugin.getUniqueIdentifier() + ".preferred_launchers", launchers);
return config;
}
private void startDebugConfig(final ILaunchConfigurationWorkingCopy config, ILaunch deploy) throws CoreException {
config.launch(ILaunchManager.DEBUG_MODE, null);
}
}

View File

@@ -0,0 +1,53 @@
package edu.wpi.first.wpilib.plugins.cpp.launching;
import java.util.Arrays;
import org.eclipse.rse.core.IRSESystemType;
import org.eclipse.rse.core.PasswordPersistenceManager;
import org.eclipse.rse.core.RSECorePlugin;
import org.eclipse.rse.core.model.IHost;
import org.eclipse.rse.core.model.ISystemProfile;
import org.eclipse.rse.core.model.ISystemRegistry;
import org.eclipse.rse.core.model.SystemSignonInformation;
public class RSEUtils {
public static IHost getTarget(int teamNumber) {
// The ip address based on the team number
String hostName = "10."+(teamNumber/100)+"."+(teamNumber%100)+".2";
String connectionName = "Team "+teamNumber;
// get the singleton RSE registry
try {
RSECorePlugin.waitForInitCompletion();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
ISystemRegistry registry = RSECorePlugin.getDefault().getSystemRegistry();
// get the default profile, used to store connections
System.out.println("Profiles: "+Arrays.toString(registry.getActiveSystemProfiles()));
ISystemProfile profile = registry.getActiveSystemProfiles()[0];
// see if a host object already exists for "build.eclipse.org"
IHost host = registry.getHost(profile, connectionName);
if (host == null) {
// if there's no host then we will create it
try {
// create the host object as an SSH Only connection
IRSESystemType systemType =
RSECorePlugin.getTheCoreRegistry().getSystemTypeById("org.eclipse.rse.systemtype.ssh");
host = registry.createHost(profile.getName(), systemType, connectionName, hostName,
"The remote target for debugging the robot for team "+teamNumber+".");
host.setDefaultUserId("admin");
SystemSignonInformation info = new SystemSignonInformation(hostName, "admin",
"XX", systemType);
PasswordPersistenceManager.getInstance().add(info, true, false);
} catch (Exception e) {
e.printStackTrace();
}
}
return host;
}
}

View File

@@ -0,0 +1,118 @@
package edu.wpi.first.wpilib.plugins.cpp.preferences;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
import edu.wpi.first.wpilib.plugins.core.preferences.ComboFieldEditor;
import edu.wpi.first.wpilib.plugins.cpp.WPILibCPPPlugin;
/**
* This class represents a preference page that
* is contributed to the Preferences dialog. By
* subclassing <samp>FieldEditorPreferencePage</samp>, we
* can use the field support built into JFace that allows
* us to create a page that is small and knows how to
* save, restore and apply itself.
* <p>
* This page is used to modify preferences only. They
* are stored in the preference store that belongs to
* the main plug-in class. That way, preferences can
* be accessed directly via the preference store.
*/
public class CPPPreferencePage
extends FieldEditorPreferencePage
implements IWorkbenchPreferencePage {
ComboFieldEditor toolchainVersionEditor;
BooleanFieldEditor autoUpdateToolchainEditor;
private ComboFieldEditor wpiLibVersionEditor;
private BooleanFieldEditor autoUpdateEditor;
public CPPPreferencePage() {
super(GRID);
setPreferenceStore(WPILibCPPPlugin.getDefault().getPreferenceStore());
setDescription("Change workspace level settings for C++.");
}
/**
* Creates the field editors. Field editors are abstractions of
* the common GUI blocks needed to manipulate various types
* of preferences. Each field editor knows how to save and
* restore itself.
*/
public void createFieldEditors() {
wpiLibVersionEditor = new ComboFieldEditor(PreferenceConstants.LIBRARY_VERSION,
"&Library Version:", getFieldEditorParent(), getInstalledVersions());
addField(wpiLibVersionEditor);
autoUpdateEditor = new BooleanFieldEditor(PreferenceConstants.UPDATE_LIBRARY_VERSION,
"&Auto Update Library Version", getFieldEditorParent());
addField(autoUpdateEditor);
toolchainVersionEditor = new ComboFieldEditor(PreferenceConstants.TOOLCHAIN_VERSION,
"&Toolchain Version:", getFieldEditorParent(), getInstalledToolchains());
addField(toolchainVersionEditor);
autoUpdateToolchainEditor = new BooleanFieldEditor(PreferenceConstants.UPDATE_TOOLCHAIN_VERSION,
"&Auto Update Toolchain Version", getFieldEditorParent());
addField(autoUpdateToolchainEditor);
}
private List<String> getInstalledVersions() {
File[] dirs = new File(WPILibCore.getDefault().getWPILibBaseDir()+File.separator+"cpp")
.listFiles(new FileFilter() {
@Override public boolean accept(File f) {
return f.isDirectory();
}
});
List<String> versions = new ArrayList<String>();
for (File dir : dirs) {
versions.add(dir.getName());
}
Collections.sort(versions);
return versions;
}
private List<String> getInstalledToolchains() {
File[] dirs = new File(WPILibCore.getDefault().getWPILibBaseDir()+File.separator+"toolchains")
.listFiles(new FileFilter() {
@Override public boolean accept(File f) {
return f.isDirectory();
}
});
List<String> versions = new ArrayList<String>();
for (File dir : dirs) {
versions.add(dir.getName());
}
Collections.sort(versions);
return versions;
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
*/
public void init(IWorkbench workbench) {
System.out.println("Preferences initialized.");
Properties props = WPILibCore.getDefault().getProjectProperties(null);
getPreferenceStore().setValue(PreferenceConstants.LIBRARY_VERSION,
props.getProperty("cpp-version", WPILibCPPPlugin.getDefault().getCurrentVersion()));
}
@Override public void performApply() {
performOk();
}
@Override public boolean performOk() {
Properties props = WPILibCore.getDefault().getProjectProperties(null);
props.setProperty("cpp-version", wpiLibVersionEditor.getChoice());
WPILibCore.getDefault().saveGlobalProperties(props);
return super.performOk();
}
}

View File

@@ -0,0 +1,11 @@
package edu.wpi.first.wpilib.plugins.cpp.preferences;
/**
* Constant definitions for plug-in preferences
*/
public class PreferenceConstants {
public static final String LIBRARY_VERSION = "libraryVersionPreference";
public static final String UPDATE_LIBRARY_VERSION = "udpateLibraryVersionPreference";
public static final String TOOLCHAIN_VERSION = "toolchainVersionPreference";
public static final String UPDATE_TOOLCHAIN_VERSION = "udpateToolchainVersionPreference";
}

View File

@@ -0,0 +1,28 @@
package edu.wpi.first.wpilib.plugins.cpp.preferences;
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
import org.eclipse.jface.preference.IPreferenceStore;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
import edu.wpi.first.wpilib.plugins.cpp.WPILibCPPPlugin;
/**
* Class used to initialize default preference values.
*/
public class PreferenceInitializer extends AbstractPreferenceInitializer {
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
*/
public void initializeDefaultPreferences() {
IPreferenceStore store = WPILibCPPPlugin.getDefault().getPreferenceStore();
store.setDefault(PreferenceConstants.LIBRARY_VERSION,
WPILibCore.getDefault().getProjectProperties(null)
.getProperty("cpp-version", WPILibCPPPlugin.getDefault().getCurrentVersion()));
store.setDefault(PreferenceConstants.UPDATE_LIBRARY_VERSION, true);
store.setDefault(PreferenceConstants.TOOLCHAIN_VERSION, WPILibCPPPlugin.getDefault().getDefaultToolchainVersion());
store.setDefault(PreferenceConstants.UPDATE_TOOLCHAIN_VERSION, true);
}
}

View File

@@ -0,0 +1,49 @@
package edu.wpi.first.wpilib.plugins.cpp.wizards.examples;
import java.util.List;
import java.util.Map;
import edu.wpi.first.wpilib.plugins.core.wizards.IExampleProject;
import edu.wpi.first.wpilib.plugins.cpp.wizards.newproject.CPPProjectType;
public class ExampleCPPProject extends CPPProjectType implements IExampleProject {
private String name, description;
private List<String> tags;
private List<String> directories;
private List<ExportFile> files;
public ExampleCPPProject(String name, String description, List<String> tags,
List<String> directories, List<ExportFile> files) {
this.name = name;
this.description = description;
this.tags = tags;
this.directories = directories;
this.files = files;
}
public String getName() {
return name;
}
public String getContent() {
return "<h1>"+name+"</h1><p>"+description+"</p>";
}
public List<String> getTags() {
return tags;
}
@Override
public String[] getFolders(String packageName) {
return directories.toArray(new String[0]);
}
@Override
public Map<String, String> getFiles(String packageName) {
Map<String, String> files = super.getFiles(packageName);
for (ExportFile file : this.files) {
files.put(file.destination, file.source);
}
return files;
}
}

View File

@@ -0,0 +1,65 @@
package edu.wpi.first.wpilib.plugins.cpp.wizards.examples;
import java.net.URL;
import java.util.List;
import java.util.Properties;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.wizard.IWizardPage;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
import edu.wpi.first.wpilib.plugins.core.wizards.ExampleWizard;
import edu.wpi.first.wpilib.plugins.core.wizards.IExampleProject;
import edu.wpi.first.wpilib.plugins.core.wizards.IExampleProject.ExportFile;
import edu.wpi.first.wpilib.plugins.core.wizards.NewProjectMainPage;
import edu.wpi.first.wpilib.plugins.core.wizards.ProjectCreationUtils;
import edu.wpi.first.wpilib.plugins.cpp.WPILibCPPPlugin;
import edu.wpi.first.wpilib.plugins.cpp.wizards.newproject.WPIRobotCPPProjectCreator;
public class ExampleCPPWizard extends ExampleWizard {
private NewProjectMainPage detailsPage;
/**
* Constructor for SampleNewWizard.
*/
public ExampleCPPWizard() {
super();
setNeedsProgressMonitor(true);
}
@Override
protected void doFinish(IExampleProject ex, String teamNumber) throws CoreException {
Properties props = WPILibCore.getDefault().getProjectProperties(null);
props.setProperty("team-number", teamNumber);
WPILibCore.getDefault().saveGlobalProperties(props);
final String projectName = detailsPage.getProjectName();
ProjectCreationUtils.createProject(new WPIRobotCPPProjectCreator(projectName, ex));
}
@Override
protected IWizardPage getDetailsPage() {
if (detailsPage != null) return detailsPage;
detailsPage = new NewProjectMainPage(selection, getTeamNumberPage());
detailsPage.setTitle("Create Example Robot Java Project");
detailsPage.setDescription("This wizard creates a new example project based on your selection.");
detailsPage.setShowPackage(false);
return detailsPage;
}
@Override
public IExampleProject makeExampleProject(String name, String description,
List<String> tags, List<String> folders, List<ExportFile> files) {
return new ExampleCPPProject(name, description, tags, folders, files);
}
@Override
public URL getResourceURL() {
return WPILibCPPPlugin.getDefault().getBundle().getEntry("/resources/templates/examples");
}
@Override
public String getXMLFile() {
return "examples.xml";
}
}

View File

@@ -0,0 +1,9 @@
package edu.wpi.first.wpilib.plugins.cpp.wizards.file_template;
public class CommandGroupWizard extends FileTemplateWizard {
public CommandGroupWizard() {
super("CommandGroup", "command-based/CommandGroup", "Commands");
}
}

View File

@@ -0,0 +1,9 @@
package edu.wpi.first.wpilib.plugins.cpp.wizards.file_template;
public class CommandWizard extends FileTemplateWizard {
public CommandWizard() {
super("Command", "command-based/Command", "Commands");
}
}

View File

@@ -0,0 +1,135 @@
package edu.wpi.first.wpilib.plugins.cpp.wizards.file_template;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.model.ICContainer;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWizard;
import edu.wpi.first.wpilib.plugins.core.wizards.ProjectCreationUtils;
import edu.wpi.first.wpilib.plugins.cpp.WPILibCPPPlugin;
public class FileTemplateWizard extends Wizard implements INewWizard {
private String type, source, ending;
private FileTemplateWizardMainPage page;
private ISelection selection;
private IProject project;
/**
* Constructor for SampleNewWizard.
*/
public FileTemplateWizard(String type, String source, String ending) {
super();
setNeedsProgressMonitor(true);
this.type = type;
this.source = source;
this.ending = ending;
}
/**
* Adding the page to the wizard.
*/
public void addPages() {
page = new FileTemplateWizardMainPage(type, project, ending, selection);
addPage(page);
}
/**
* This method is called when 'Finish' button is pressed in
* the wizard. We will create an operation and run it
* using wizard as execution context.
*/
public boolean performFinish() {
final IProject project = page.getProject();
final String className = page.getClassName();
final String folderName = page.getFolder();
System.out.println("Class: "+className+" Folder: "+folderName);
IRunnableWithProgress op = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException {
try {
doFinish(project, className, folderName, monitor);
} catch (CoreException e) {
throw new InvocationTargetException(e);
} finally {
monitor.done();
}
}
};
try {
getContainer().run(true, false, op);
} catch (InterruptedException e) {
return false;
} catch (InvocationTargetException e) {
Throwable realException = e.getTargetException();
MessageDialog.openError(getShell(), "Error", realException.getMessage());
return false;
}
return true;
}
/**
* The worker method. It will find the container, create the
* file if missing or just replace its contents, and open
* the editor on the newly created file.
*/
private void doFinish(IProject project, String className, String folderName, IProgressMonitor monitor) throws CoreException {
Map<String, String> map = new HashMap<String, String>();
map.put("$classname", className);
map.put("$folder", folderName);
String filepath = folderName+File.separator+className;
try {
// Create Header
URL url = new URL(WPILibCPPPlugin.getDefault().getBundle().getEntry("/resources/templates/"), source+".h");
ProjectCreationUtils.createTemplateFile(project, filepath+".h", url, map);
// Create CPP file
url = new URL(WPILibCPPPlugin.getDefault().getBundle().getEntry("/resources/templates/"), source+".cpp");
ProjectCreationUtils.createTemplateFile(project, filepath+".cpp", url, map);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* We will accept the selection in the workbench to see if
* we can initialize from it.
* @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
*/
public void init(IWorkbench workbench, IStructuredSelection selection) {
this.selection = selection;
System.out.println(selection);
Object element = ((StructuredSelection) selection).getFirstElement();
System.out.println(element.getClass());
if (element instanceof IResource) {
project = ((IResource) element).getProject();
} else if (element instanceof ISourceRoot) {
project = ((ISourceRoot) element).getCProject().getProject();
} else if (element instanceof ITranslationUnit) {
project = ((ITranslationUnit) element).getCProject().getProject();
} else if (element instanceof ISourceRoot) {
project = ((ISourceRoot) element).getCProject().getProject();
} else if (element instanceof ICContainer) {
project = ((ICContainer) element).getCProject().getProject();
} else System.out.println("Element not instance of IResource: "+element.getClass());
}
}

View File

@@ -0,0 +1,179 @@
package edu.wpi.first.wpilib.plugins.cpp.wizards.file_template;
import java.io.File;
import org.eclipse.cdt.core.CCProjectNature;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.IDialogPage;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import edu.wpi.first.wpilib.plugins.core.nature.FRCProjectNature;
import edu.wpi.first.wpilib.plugins.core.wizards.IProjectFilter;
import edu.wpi.first.wpilib.plugins.core.wizards.ProjectComboField;
/**
* The "New" wizard page allows setting the container for the new file as well
* as the file name. The page will only accept file name without the extension
* OR with the extension that matches the expected one (mpe).
*/
public class FileTemplateWizardMainPage extends WizardPage {
private IProject project;
private String ending;
private ProjectComboField projectsCombo;
private Text classNameText;
private Text folderText;
/**
* Constructor for SampleNewWizardPage.
*
* @param pageName
*/
public FileTemplateWizardMainPage(String type, IProject project, String ending, ISelection selection) {
super("wizardPage");
setTitle("Create New "+type);
setDescription("This wizard creates a new "+type.toLowerCase()+" from a template.");
this.project = project;
this.ending = ending;
}
/**
* @see IDialogPage#createControl(Composite)
*/
public void createControl(Composite parent) {
Composite container = new Composite(parent, SWT.NULL);
GridLayout layout = new GridLayout();
container.setLayout(layout);
layout.numColumns = 2;
layout.verticalSpacing = 9;
Label label = new Label(container, SWT.NULL);
label.setText("Pro&ject:");
projectsCombo = new ProjectComboField(container, SWT.BORDER | SWT.SINGLE,
new IProjectFilter() {
@Override public boolean accept(IProject project) {
try {
return project.hasNature(FRCProjectNature.FRC_PROJECT_NATURE)
&& project.hasNature(CCProjectNature.C_NATURE_ID);
} catch (CoreException e) {
e.printStackTrace();
return false;
}
}
});
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
projectsCombo.setLayoutData(gd);
projectsCombo.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
dialogChanged();
}
});
label = new Label(container, SWT.NULL);
label.setText("Class &Name:");
classNameText = new Text(container, SWT.BORDER | SWT.SINGLE);
gd = new GridData(GridData.FILL_HORIZONTAL);
classNameText.setLayoutData(gd);
classNameText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
dialogChanged();
}
});
label = new Label(container, SWT.NULL);
label.setText("&Folder:");
folderText = new Text(container, SWT.BORDER | SWT.SINGLE);
gd = new GridData(GridData.FILL_HORIZONTAL);
folderText.setLayoutData(gd);
folderText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
dialogChanged();
}
});
initialize();
dialogChanged();
setControl(container);
}
/**
* Tests if the current workbench selection is a suitable container to use.
*/
private void initialize() {
projectsCombo.setProject(project);
folderText.setText(getDefaultFolder());
}
/**
* Ensures that both text fields are set.
*/
private void dialogChanged() {
String className = getClassName();
String folder = getFolder();
// Update the default package if necessary
if (project == null || !project.equals(projectsCombo.getProject())) {
String oldDefault = getDefaultFolder();
project = projectsCombo.getProject();
if (folder.equals(oldDefault)) {
folderText.setText(getDefaultFolder());
}
}
if (!projectsCombo.isValid()) {
updateStatus("Must select a project.");
return;
}
if (className.length() == 0) {
updateStatus("Class name must be specified");
return;
}
if (!className.matches("^([a-zA-Z_]{1}[a-zA-Z0-9_]*)$")) {
updateStatus("Must be a valid java class name");
return;
}
if (folder.length() == 0) {
updateStatus("Package must be specified");
return;
}
updateStatus(null);
}
private void updateStatus(String message) {
setErrorMessage(message);
setPageComplete(message == null);
}
public IProject getProject() {
return projectsCombo.getProject();
}
public String getClassName() {
return classNameText.getText();
}
public String getFolder() {
return folderText.getText();
}
public String getDefaultFolder() {
System.out.println("Project: "+project);
return "src"+File.separator+ending;
}
}

View File

@@ -0,0 +1,9 @@
package edu.wpi.first.wpilib.plugins.cpp.wizards.file_template;
public class PIDSubsystemWizard extends FileTemplateWizard {
public PIDSubsystemWizard() {
super("PIDSubsystem", "command-based/PIDSubsystem", "Subsystems");
}
}

View File

@@ -0,0 +1,9 @@
package edu.wpi.first.wpilib.plugins.cpp.wizards.file_template;
public class SubsystemWizard extends FileTemplateWizard {
public SubsystemWizard() {
super("Subsystem", "command-based/Subsystem", "Subsystems");
}
}

View File

@@ -0,0 +1,9 @@
package edu.wpi.first.wpilib.plugins.cpp.wizards.file_template;
public class TriggerWizard extends FileTemplateWizard {
public TriggerWizard() {
super("Trigger", "command-based/Trigger", "Triggers");
}
}

View File

@@ -0,0 +1,75 @@
package edu.wpi.first.wpilib.plugins.cpp.wizards.newproject;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import edu.wpi.first.wpilib.plugins.core.wizards.ProjectType;
import edu.wpi.first.wpilib.plugins.cpp.WPILibCPPPlugin;
public class CPPProjectType implements ProjectType {
static ProjectType SIMPLE = new CPPProjectType() {
@Override public Map<String, String> getFiles(String packageName) {
Map<String, String> files = super.getFiles(packageName);
files.put("src/Robot.cpp", "simple/Robot.cpp");
return files;
}
};
static ProjectType ITERATIVE = new CPPProjectType() {
@Override public Map<String, String> getFiles(String packageName) {
Map<String, String> files = super.getFiles(packageName);
files.put("src/Robot.cpp", "iterative/Robot.cpp");
return files;
}
};
static ProjectType COMMAND_BASED = new CPPProjectType() {
@Override public String[] getFolders(String packageName) {
String[] paths = {"src",
"src/Commands",
"src/Subsystems",
"src/Triggers"};
return paths;
}
@Override public Map<String, String> getFiles(String packageName) {
Map<String, String> files = super.getFiles(packageName);
files.put("src/Robot.cpp", "command-based/Robot.cpp");
files.put("src/OI.h", "command-based/OI.h");
files.put("src/OI.cpp", "command-based/OI.cpp");
files.put("src/RobotMap.h", "command-based/RobotMap.h");
files.put("src/CommandBase.cpp", "command-based/CommandBase.cpp");
files.put("src/CommandBase.h", "command-based/CommandBase.h");
files.put("src/Subsystems/ExampleSubsystem.h", "command-based/ExampleSubsystem.h");
files.put("src/Subsystems/ExampleSubsystem.cpp", "command-based/ExampleSubsystem.cpp");
files.put("src/Commands/ExampleCommand.h", "command-based/ExampleCommand.h");
files.put("src/Commands/ExampleCommand.cpp", "command-based/ExampleCommand.cpp");
return files;
}
};
@SuppressWarnings("serial")
static Map<String, ProjectType> TYPES = new HashMap<String, ProjectType>() {{
put(ProjectType.SIMPLE, SIMPLE);
put(ProjectType.ITERATIVE, ITERATIVE);
put(ProjectType.COMMAND_BASED, COMMAND_BASED);
}};
@Override
public String[] getFolders(String packageName) {
String[] paths = {"src"};
return paths;
}
@Override
public Map<String, String> getFiles(String packageName) {
HashMap<String, String> files = new HashMap<String, String>();
files.put("build.xml", "build.xml");
files.put("build.properties", "build.properties");
files.put(".cproject", ".cproject");
return files;
}
@Override
public URL getBaseURL() {
return WPILibCPPPlugin.getDefault().getBundle().getEntry("/resources/templates/");
}
}

View File

@@ -0,0 +1,120 @@
package edu.wpi.first.wpilib.plugins.cpp.wizards.newproject;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWizard;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
import edu.wpi.first.wpilib.plugins.core.wizards.NewProjectMainPage;
import edu.wpi.first.wpilib.plugins.core.wizards.ProjectCreationUtils;
import edu.wpi.first.wpilib.plugins.core.wizards.ProjectType;
import edu.wpi.first.wpilib.plugins.core.wizards.TeamNumberPage;
/**
*
* Example Docs:
* This is a sample new wizard. Its role is to create a new file
* resource in the provided container. If the container resource
* (a folder or a project) is selected in the workspace
* when the wizard is opened, it will accept it as the target
* container. The wizard creates one file with the extension
* "mpe". If a sample multi-page editor (also available
* as a template) is registered for the same extension, it will
* be able to open it.
*/
public class NewCPPWizard extends Wizard implements INewWizard {
private NewProjectMainPage page;
private ISelection selection;
private TeamNumberPage teamNumberPage;
/**
* Constructor for SampleNewWizard.
*/
public NewCPPWizard() {
super();
setNeedsProgressMonitor(true);
}
/**
* Adding the page to the wizard.
*/
public void addPages() {
if (TeamNumberPage.needsTeamNumberPage()) {
teamNumberPage = new TeamNumberPage(selection);
addPage(teamNumberPage);
}
page = new NewProjectMainPage(selection, teamNumberPage);
page.setTitle("Create New Robot C++ Project");
page.setDescription("This wizard creates a new Robot C++ Project configured to use WPILib for programming FRC robots.");
page.setShowPackage(false);
page.setProjectTypes(CPPProjectType.TYPES);
addPage(page);
}
/**
* This method is called when 'Finish' button is pressed in
* the wizard. We will create an operation and run it
* using wizard as execution context.
*/
public boolean performFinish() {
final String projectName = page.getProjectName();
final String teamNumber = TeamNumberPage.getTeamNumberFromPage(teamNumberPage);
final ProjectType projectType = page.getProjectType();
System.out.println("Project: "+projectName+" Project Type: "+projectType);
IRunnableWithProgress op = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException {
try {
doFinish(projectName, teamNumber, projectType, monitor);
} catch (CoreException e) {
throw new InvocationTargetException(e);
} finally {
monitor.done();
}
}
};
try {
getContainer().run(true, false, op);
} catch (InterruptedException e) {
return false;
} catch (InvocationTargetException e) {
Throwable realException = e.getTargetException();
MessageDialog.openError(getShell(), "Error", realException.getMessage());
return false;
}
return true;
}
/**
* The worker method. It will find the container, create the
* file if missing or just replace its contents, and open
* the editor on the newly created file.
*/
private void doFinish(String projectName, String teamNumber, ProjectType projectType, IProgressMonitor monitor) throws CoreException {
Properties props = WPILibCore.getDefault().getProjectProperties(null);
props.setProperty("team-number", teamNumber);
WPILibCore.getDefault().saveGlobalProperties(props);
ProjectCreationUtils.createProject(new WPIRobotCPPProjectCreator(projectName, projectType));
}
/**
* We will accept the selection in the workbench to see if
* we can initialize from it.
* @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
*/
public void init(IWorkbench workbench, IStructuredSelection selection) {
this.selection = selection;
}
}

View File

@@ -0,0 +1,92 @@
package edu.wpi.first.wpilib.plugins.cpp.wizards.newproject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.build.core.scannerconfig.ScannerConfigNature;
import org.eclipse.cdt.core.CCProjectNature;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.managedbuilder.core.ManagedCProjectNature;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import edu.wpi.first.wpilib.plugins.core.nature.FRCProjectNature;
import edu.wpi.first.wpilib.plugins.core.wizards.IProjectCreator;
import edu.wpi.first.wpilib.plugins.core.wizards.ProjectType;
import edu.wpi.first.wpilib.plugins.cpp.WPILibCPPPlugin;
public class WPIRobotCPPProjectCreator implements IProjectCreator {
String projectName;
ProjectType projectType;
public WPIRobotCPPProjectCreator(String projectName, ProjectType projectType) {
this.projectName = projectName;
this.projectType = projectType;
}
@Override
public String getName() {
return projectName;
}
@Override
public String getPackageName() {
return ""; // C++ doesn't have the equivalent of a project name
}
@Override
public Map<String, String> getValues() {
Map<String, String> vals = new HashMap<String, String>();
vals.put("$project", projectName);
vals.put("$toolchain", WPILibCPPPlugin.getDefault().getToolchain());
vals.put("$cpp-location", WPILibCPPPlugin.getDefault().getCPPDir());
return vals;
}
@Override
public List<String> getNatures() {
List<String> natures = new ArrayList<>();
natures.add(CCProjectNature.C_NATURE_ID);
natures.add(CCProjectNature.CC_NATURE_ID);
natures.add(ManagedCProjectNature.MNG_NATURE_ID);
natures.add(ScannerConfigNature.NATURE_ID);
natures.add(FRCProjectNature.FRC_PROJECT_NATURE);
return natures;
}
@Override
public ProjectType getProjectType() {
return projectType;
}
@Override
public void initialize(IProject project) {
try {
CCorePlugin.getDefault().createCDTProject(project.getDescription(), project, null);
project.open(null);
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//config.getToolChain().getOptionById("cdt.managedbuild.option.gnu.cross.prefix").setValue(prefix);
//config.getToolChain().getOptionById("cdt.managedbuild.option.gnu.cross.path").setValue(path);
}
@Override
public void finalize(IProject project) throws CoreException {
updateVariables(project);
// Freshen the index because otherwise it's red and angry
ICElement[] projects = {CCorePlugin.getDefault().getCoreModel().create(project)};
CCorePlugin.getIndexManager().update(projects, IIndexManager.UPDATE_ALL | IIndexManager.UPDATE_EXTERNAL_FILES_FOR_PROJECT);
}
private void updateVariables(IProject project) throws CoreException {
// TODO: implement C++ equivalent
}
}

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="athena-project-build" default="deploy">
<!-- Load Tasks -->
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="${wpilib.ant.dir}/ant-contrib.jar"/>
</classpath>
</taskdef>
<taskdef resource="net/jtools/classloadertask/antlib.xml" classpath="${classloadertask.jar}"/>
<classloader loader="system" classpath="${jsch.jar}"/>
<target name="clean" description="Clean up all build and distribution artifacts.">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
</target>
<!-- Targets -->
<target name="get-target-ip">
<math result="ip.upper" operand1="${team-number}" operation="/" operand2="100" datatype="int"/>
<math result="ip.lower" operand1="${team-number}" operation="%" operand2="100" datatype="int"/>
<property name="target" value="10.${ip.upper}.${ip.lower}.2" />
<echo>Target IP: ${target}</echo>
</target>
<!-- <target name="compile" description="Compile the source code."> -->
<!-- <mkdir dir="${build.dir}"/> -->
<!-- <echo>[athena-compile] Compiling ${src.dir} with classpath=${classpath} to ${build.dir}</echo> -->
<!-- <javac srcdir="${src.dir}" -->
<!-- destdir="${build.dir}" -->
<!-- includeAntRuntime="no" -->
<!-- includeJavaRuntime="no" -->
<!-- classpath="${classpath}" -->
<!-- target="1.7" -->
<!-- source="1.7" -->
<!-- debug="true"> -->
<!-- </javac> -->
<!-- </target> -->
<!-- <target name="jar" depends="compile"> -->
<!-- <echo>[athena-jar] Making jar ${dist.jar}.</echo> -->
<!-- <mkdir dir="${dist.dir}" /> -->
<!-- <jar destfile="${dist.jar}" update="false"> -->
<!-- <manifest> -->
<!-- <attribute name="Main-Class" value="${main}"/> -->
<!-- <attribute name="Class-Path" value="."/> -->
<!-- </manifest> -->
<!-- <fileset dir="${build.dir}" includes="**"/> -->
<!-- <zipgroupfileset file="${networktables.jar}" /> -->
<!-- </jar> -->
<!-- </target> -->
<target name="deploy" depends="get-target-ip" description="Deploy the progam and start it running.">
<echo>[athena-deploy] Killing running program</echo>
<sshexec host="${target}"
username="${username}"
password="${password}"
trust="true"
command="killall FRCUserProgram; sleep 1"/>
<echo>[athena-deploy] Copying code over.</echo>
<scp file="${out.exe}" todir="${username}@${target}:${deploy.dir}"
password="${password}" trust="true"/>
<scp file="${wpilib.ant.dir}/runcppprogram" todir="${username}@${target}:${deploy.dir}"
password="${password}" trust="true"/>
<scp file="${wpilib.ant.dir}/runjavaprogram" todir="${username}@${target}:${deploy.dir}"
password="${password}" trust="true"/>
<echo>[athena-deploy] Starting program.</echo>
<sshexec host="${target}"
username="${username}"
password="${password}"
trust="true"
command="chmod a+x run*program; ${deploy.run.command}"/>
</target>
<target name="debug-deploy" depends="get-target-ip" description="Deploy the jar and start the program running in debug mode.">
<echo>[athena-deploy] Killing running program</echo>
<sshexec host="${target}"
username="${username}"
password="${password}"
trust="true"
command="killall FRCUserProgram; sleep 1"/>
<echo>[athena-debug-deploy] Copying code over.</echo>
<scp file="${dist.jar}" todir="${username}@${target}:${deploy.dir}"
password="${password}" trust="true"/>
<scp file="${wpilib.ant.dir}/debugcppprogram" todir="${username}@${target}:${deploy.dir}"
password="${password}" trust="true"/>
<scp file="${wpilib.ant.dir}/debugjavaprogram" todir="${username}@${target}:${deploy.dir}"
password="${password}" trust="true"/>
<echo>[athena-debug-deploy] Starting program.</echo>
<sshexec host="${target}"
username="${username}"
password="${password}"
trust="true"
command="chmod a+x debug*program; ${deploy.debug.command}"/>
</target>
</project>

View File

@@ -0,0 +1,6 @@
#. ./.profile
killall java
sleep 1
nohup java -Djna.library.path=$LD_LIBRARY_PATH -Xmx32M -agentlib:jdwp=transport=dt_socket,address=8348,server=y,suspend=y -jar FRCUserProgram.jar edu.wpi.first.wpilibj.unittests.RunTests

View File

@@ -0,0 +1,6 @@
#. ./.profile
killall java
killall FRCUserProgram
sleep 1
chmod +x ./FRCUserProgram
nohup ./FRCUserProgram

View File

@@ -0,0 +1,5 @@
#. ./.profile
killall java
killall FRCUserProgram
sleep 1
nohup java -Djna.library.path=$LD_LIBRARY_PATH -Xmx32M -jar FRCUserProgram.jar