Compare commits

..

1 Commits

Author SHA1 Message Date
Alex Henning
8856927fd8 Added support for Jenkins to generate doxygen.
Change-Id: I2febfe42cc9301446f796376cfe8e1ef6744f19a
2014-08-12 15:06:43 -04:00
2797 changed files with 415622 additions and 102833 deletions

View File

@@ -1,89 +0,0 @@
---
Language: Cpp
BasedOnStyle: Google
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IndentCaseLabels: true
IndentWidth: 2
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 8
UseTab: Never
...

195
.gitignore vendored
View File

@@ -1,81 +1,21 @@
# WPIlib Specific
dependency-reduced-pom.xml
/wpilibj/src/athena/cpp/nivision/*.c
/wpilibj/src/athena/cpp/nivision/*.cpp
/wpilibj/src/athena/cpp/nivision/*.s
/wpilibj/src/athena/cpp/nivision/*_arm.ini
/wpilibj/src/athena/cpp/nivision/*.java
/wpilibj/src/athena/cpp/nivision/nivision_funcs.txt
/wpilibj/src/athena/cpp/nivision/imaqdx_funcs.txt
/wpilibj/src/shared/java/edu/wpi/first/wpilibj/util/WPILibVersion.java
/wpilibc/shared/src/WPILibVersion.cpp
doxygen.log
# Created by the jenkins test script
test-reports
# IntelliJ
*.iml
.idea/
# Created by http://www.gitignore.io
### Linux ###
wpilibc/build/
hal/build/
networktables/cpp/build/
build/
networktables/OutlineViewer/nbproject/private
*~
target/
dist/
bin/
.project
.cproject
.settings/
.classpath
**/dependency-reduced-pom.xml
# KDE directory preferences
.directory
### Windows ###
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
### OSX ###
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Java ###
#Java File extentions
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
@@ -83,110 +23,3 @@ Temporary Items
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### C++ ###
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Compiled Dynamic libraries
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
### CMake ###
CMakeCache.txt
CMakeFiles
cmake_install.cmake
install_manifest.txt
### Gradle ###
.gradle
build/
# Ignore Gradle GUI config
gradle-app.setting
### Vagrant ###
.vagrant/
### Eclipse ###
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
### Python ###
*.pyc
__pycache__
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse
#catkin stuff
package.xml
# Doxygen stuff
NO
# Simulation folder stuff
!simulation/install_resources/*
# VSCode
.vscode/
#classpaths and projects
.project
.classpath

5
.gitreview Normal file
View File

@@ -0,0 +1,5 @@
[gerrit]
host=usfirst.collab.net
port=29418
project=allwpilib
defaultbranch=master

View File

@@ -1,65 +0,0 @@
cExtensions {
}
cppHeaderExtensions {
h
inc
}
cppSrcExtensions {
cpp
}
otherExtensions {
java
}
genFolderExclude {
FRC_FPGA_ChipObject
NetworkCommunication
ctre
frccansae
gtest
i2clib
msgs
ni-libraries
ni/vision
spilib
wpilibj/src/athena/cpp/nivision
visa
}
genFileExclude {
NIIMAQdx\.h$
can_proto\.h$
nivision\.h$
}
modifiableFolderExclude {
\.git
wpilibj/src/athena/cpp/include
wpilibj/src/athena/cpp/lib
}
modifiableFileExclude {
\.patch$
\.png$
\.py$
\.so$
}
includeRelated {
}
includeCSys {
}
includeCppSys {
}
includeOtherLibs {
}
includeProject {
^ctre/
}

View File

@@ -1,6 +0,0 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST {year}. All Rights Reserved.{padding}*/
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/

View File

@@ -1,24 +0,0 @@
sudo: required
dist: trusty
language: java
before_install:
- sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list'
- wget http://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add -
- sudo add-apt-repository ppa:wpilib/toolchain -y
- sudo apt-get update -q || true
- sudo apt-get install frc-toolchain libgazebo7-dev protobuf-compiler libprotobuf-dev python3 clang-format-3.8 -y
install:
- pip3 install wpiformat
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
script:
- wpiformat
- git --no-pager diff --exit-code HEAD # Ensure formatter made no changes
- ./gradlew build -PmakeSim

29
Building.md Normal file
View File

@@ -0,0 +1,29 @@
Building everything requires Maven
mvn package -DembeddedJDKHome=/home/patrick/Downloads/arm-jdk1.7.0_45/
TODO... Explain maven....
TODO.. how to import into eclipse correctly...
Building C++ only
------------------
C++ requires cmake if not run from maven, and is much faster.
Make a new directory and then run:
```
mkdir build && cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../arm-toolchain.cmake
make # multicore add -j(num of cpu cores + 1), so -j3 on dual core for faster compile
make install DESTDIR=/some/dir/you/want/to/put/all/headers/and/libs #optional
``
Alternatively, if you like IDEs, you can import it directly into QtDeveloper, or a number of other IDEs such as Code::Blocks or Eclipse. See CMake documentation for details.
Eclipse demo:
```
cd ..
mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../allwpilib/arm-toolchain.cmake .. -G "Eclipse CDT4 - Unix Makefiles"
```
and then import that directory into eclipse. Eclipse will detect a CDT project and standard tools will work.
GCC versions
------------
Update arm-toolchain.cmake if the triplet changes (eg using Ubuntu repo arm compiler is arm-linux-gnueabi) or in a non-standard location. Currently it assumes that the compiler is on the path.

View File

@@ -1,39 +1,13 @@
cmake_minimum_required(VERSION 2.8)
project(AllC++Sim)
project(All-WPILib)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat=2 -Wall -Wextra -Wno-unused-parameter -fPIC")
SET(CMAKE_SKIP_BUILD_RPATH TRUE)
include(CheckCXXCompilerFlag)
include (FindPkgConfig)
include(GNUInstallDirs)
#check for depenedencies
find_package(gazebo REQUIRED)
find_package(Boost COMPONENTS system filesystem REQUIRED)
#on windows we produce .dlls with no prefix
if(WIN32)
#allows us to define constexpr and noexcept in macros
#since msvc 2013 doesn't support them
add_definitions(-D_ALLOW_KEYWORD_MACROS)
# defines things like M_PI
add_definitions(-D_USE_MATH_DEFINES)
# get rid of min max macros on windows
add_definitions(-DNOMINMAX)
add_definitions(-DWIN32_LEAN_AND_MEAN)
SET(CMAKE_FIND_LIBRARY_PREFIXES "")
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".dll")
endif()
if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFRC_SIMULATOR /MDd /Zi")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++1y -DFRC_SIMULATOR -Wno-unused-parameter -pthread -fPIC -fpermissive")
endif()
include_directories("build")
add_subdirectory(simulation/gz_msgs)
add_subdirectory(wpilibc/sim)
add_subdirectory(simulation/frc_gazebo_plugins)
file(GLOB_RECURSE NI_LIBS ni-libraries/*.so*)
get_filename_component(WPILIB_INCLUDES wpilibc/wpilibC++/include REALPATH)
get_filename_component(HAL_API_INCLUDES hal/include REALPATH)
get_filename_component(NWT_API_INCLUDES networktables/cpp/include REALPATH)
add_subdirectory(hal)
add_subdirectory(networktables/cpp)
add_subdirectory(wpilibc)

View File

@@ -1,56 +0,0 @@
# Contributing to WPILib
So you want to contribute your changes back to WPILib. Great! We have a few contributing rules that will help you make sure your changes will be accepted into the project. Please remember to follow the rules written here, and behave with Gracious Professionalism.
- [General Contribution Rules](#general-contribution-rules)
- [What to Contribute](#what-to-contribute)
- [Coding Guidelines](#coding-guidelines)
- [Submitting Changes](#submitting-changes)
- [Pull Request Format](#pull-request-format)
- [Merge Process](#merge-process)
- [Licensing](#licensing)
## General Contribution Rules
- Everything in the library must work for the 3000+ teams that will be using it.
- We need to be able to maintain submitted changes, even if you are no longer working on the project.
- Tool suite changes must be generally useful to a broad range of teams
- Excluding bug fixes, changes in one language generally need to have corresponding changes in other languages.
- Some features, such the addition of C++11 for WPILibC or Functional Interfaces for WPILibJ, are specific to that version of WPILib only.
- Substantial changes often need to have corresponding LabVIEW changes. To do this, we will work with NI on these large changes.
- Changes should have tests.
- Code should be well documented.
- This often involves ScreenSteps. To add content to ScreenSteps, we will work with you to get the appropriate articles written.
## What to Contribute
- Bug reports and fixes
- We will generally accept bug fixes without too much question. If they are only implemented for one language, we will implement them for any other necessary languages. Bug reports are also welcome, please submit them to our GitHub issue tracker.
- While we do welcome improvements to the API, there are a few important rules to consider:
- Features must be added to both WPILibC and WPILibJ, with rare exceptions.
- During competition season, we will not merge any new feature additions. We want to ensure that the API is stable during the season to help minimize issues for teams.
- Ask about large changes before spending a bunch of time on them! You can create a new issue on our GitHub tracker for feature request/discussion and talk about it with us there.
- Features that make it easier for teams with less experience to be more successful are more likely to be accepted.
- Features in WPILib should be broadly applicable to all teams. Anything that is team specific should not be submitted.
- As a rule, we are happy with the general structure of WPILib. We are not interested in major rewrites of all of WPILib. We are open to talking about ideas, but backwards compatibility is very important for WPILib, so be sure to keep this in mind when proposing major changes.
- Generally speaking, we do not accept code for specific sensors. We have to be able to test the sensor in hardware on the WPILib test bed. Additionally, hardware availability for teams is important. Therefore, as a general rule, the library only directly supports hardware that is in the Kit of Parts. If you are a company interested in getting a sensor into the Kit of Parts, please contact FIRST directly at frcparts@firstinspires.org.
## Coding Guidelines
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running wpiformat is required for all contributions and is enforced by our continuous integration system.
While the library should be fully formatted according to the styles, additional elements of the style guide were not followed when the library was initially created. All new code should follow the guidelines. If you are looking for some easy ramp-up tasks, finding areas that don't follow the style guide and fixing them is very welcome.
## Submitting Changes
### Pull Request Format
Changes should be submitted as a Pull Request against the master branch of WPILib. For most changes, we ask that you squash your changes down to a single commit. For particularly large changes, multiple commits are ok, but assume one commit unless asked otherwise. No change will be merged unless it is up to date with the current master. We will also not merge any changes with merge commits in them; please rebase off of master before submitting a pull request. We do this to make sure that the git history isn't too cluttered.
### Merge Process
When you first submit changes, Travis-CI will attempt to run `./gradlew check` on your change. If this fails, you will need to fix any issues that it sees. Once Travis passes, we will begin the review process in more earnest. One or more WPILib team members will review your change. This will be a back-and-forth process with the WPILib team and the greater community. Once we are satisfied that your change is ready, we will allow our Jenkins instance to test it. This will run the full gamut of checks, including integration tests on actual hardware. Once all tests have passed and the team is satisfied, we will merge your change into the WPILib repository.
## Licensing
By contributing to WPILib, you agree that your code will be distributed with WPILib, and licensed under the license for the WPILib project. You should not contribute code that you do not have permission to relicense in this manner. This includes code that is licensed under the GPL that you do not have permission to relicense, as WPILib is not released under a copyleft license. Our license is the 3-clause BSD license, which you can find [here](license.txt).

110
README.md
View File

@@ -1,110 +0,0 @@
# WPILib Project
[![Build Status](https://travis-ci.org/wpilibsuite/allwpilib.svg?branch=master)](https://travis-ci.org/wpilibsuite/allwpilib)
Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WPILibC projects. These are the core libraries for creating robot programs for the roboRIO.
- [WPILib Mission](#wpilib-mission)
- [Building WPILib](#building-wpilib)
- [Requirements](#requirements)
- [Setup](#setup)
- [Building](#building)
- [Publishing](#publishing)
- [Structure and Organization](#structure-and-organization)
- [Contributing to WPILib](#contributing-to-wpilib)
## WPILib Mission
The WPILib Mission is to enable FIRST Robotics teams to focus on writing game-specific software rather than focussing on hardware details - "raise the floor, don't lower the ceiling". We work to enable teams with limited programming knowledge and/or mentor experience to be as successful as possible, while not hampering the abilities of teams with more advanced programming capabilities. We support Kit of Parts control system components directly in the library. We also strive to keep parity between major features of each language (Java, C++, and NI's LabVIEW), so that teams aren't at a disadvantage for choosing a specific programming language. WPILib is an open source project, licensed under the BSD 3-clause license. You can find a copy of the license [here](license.txt).
# Building WPILib
Using Gradle makes building WPILib very straightforward. It only has a few dependencies on outside tools, such as the ARM cross compiler for creating roboRIO binaries.
## Requirements
- [ARM Compiler Toolchain](http://first.wpi.edu/FRC/roborio/toolchains/)
- Doxygen (Only required if you want to build the C++ documentation)
- [wpiformat](https://github.com/wpilibsuite/styleguide)
## Setup
Clone the WPILib repository. If the toolchains are not installed, install them, and make sure they are available on the system PATH.
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/master/README.md) for wpiformat setup instructions.
## Building
All build steps are executed using the Gradle wrapper, `gradlew`. Each target that Gradle can build is referred to as a task. The most common Gradle task to use is `build`. This will build all the outputs created by WPILib. To run, open a console and cd into the cloned WPILib directory. Then:
```bash
./gradlew build
```
To build a specific subproject, such as WPILibC, you must access the subproject and run the build task only on that project. Accessing a subproject in Gradle is quite easy. Simply use `:subproject_name:task_name` with the Gradle wrapper. For example, building just WPILibC:
```bash
./gradlew :wpilibc:build
```
If you have installed the FRC Toolchain to a directory other than the default, or if the Toolchain location is not on your System PATH, you can pass the `toolChainPath` property to specify where it is located. Example:
```bash
./gradlew build -PtoolChainPath=some/path/to/frc/toolchain/bin
```
If you also want simulation to be built, add -PmakeSim. This requires gazebo_transport. We have tested on 14.04 and 15.05, but any correct install of Gazebo should work, even on Windows if you build Gazebo from source. Correct means CMake needs to be able to find gazebo-config.cmake. See [The Gazebo website](https://gazebosim.org/) for installation instructions.
```bash
./gradlew build -PmakeSim
```
If you prefer to use CMake directly, the you can still do so.
The common CMake tasks are wpilibcSim, frc_gazebo_plugins, and gz_msgs
```bash
mkdir build #run this in the root of allwpilib
cd build
cmake ..
make
```
The gradlew wrapper only exists in the root of the main project, so be sure to run all commands from there. All of the subprojects have build tasks that can be run. Gradle automatically determines and rebuilds dependencies, so if you make a change in the HAL and then run `./gradlew :wpilibc:build`, the HAL will be rebuilt, then WPILibC.
There are a few tasks other than `build` available. To see them, run the meta-task `tasks`. This will print a list of all available tasks, with a description of each task.
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat` on Windows or `python3 -m wpiformat` on other platforms.
## Publishing
If you are building to test with the Eclipse plugins or just want to export the build as a Maven-style dependency, simply run the `publish` task. This task will publish all available packages to ~/releases/maven/development. If you need to publish the project to a different repo, you can specify it with `-Prepo=repo_name`. Valid options are:
- development - The default repo.
- beta - Publishes to ~/releases/maven/beta.
- stable - Publishes to ~/releases/maven/stable.
- release - Publishes to ~/releases/maven/release.
The following maven targets a published by this task:
- edu.wpi.first.wpilib.cmake:cpp-root:1.0.0 - roboRIO C++
- edu.wpi.first.wpilibc.simulation:WPILibCSim:0.1.0 - Simulation C++
- edu.wpi.first.wpilibj:wpilibJavaFinal:0.1.0-SNAPSHOT - roboRIO Java
- edu.wpi.first.wpilibj:wpilibJavaSim:0.1.0-SNAPSHOT - Simulation Java
- edu.wpi.first.wpilibj.simulation:SimDS:0.1.0-SNAPSHOT - The driverstation for controlling simulation.
- org.gazebosim:JavaGazebo:0.1.0-SNAPSHOT - Gazebo protocol for Java.
## Structure and Organization
The main WPILib code you're probably looking for is in WPILibJ and WPILibC. Those directories are split into shared, sim, and athena. Athena contains the WPILib code meant to run on your roboRIO. Sim is WPILib code meant to run on your computer with Gazebo, and shared is code shared between the two. Shared code must be platform-independent, since it will be compiled with both the ARM cross-compiler and whatever desktop compiler you are using (g++, msvc, etc...).
The Simulation directory contains extra simulation tools and libraries, such as gz_msgs and JavaGazebo. See sub-directories for more information.
The integration test directories for C++ and Java contain test code that runs on our test-system. When you submit code for review, it is tested by those programs. If you add new functionality you should make sure to write tests for it so we don't break it in the future.
The hal directory contains more C++ code meant to run on the roboRIO. HAL is an acronym for "Hardware Abstraction Layer", and it interfaces with the NI Libraries. The NI Libraries contain the low-level code for controlling devices on your robot. The NI Libraries are found in the ni-libraries folder.
The [styleguide repository](https://github.com/wpilibsuite/styleguide) contains our style guides for C++ and Java code. Anything submitted to the WPILib project needs to follow the code style guides outlined in there. For details about the style, please see the contributors document [here](CONTRIBUTING.md#coding-guidelines).
# Contributing to WPILib
See [CONTRIBUTING.md](CONTRIBUTING.md).

View File

@@ -1,9 +1,10 @@
cmake_minimum_required(VERSION 2.8)
INCLUDE(CMakeForceCompiler)
set(ARM_PREFIX arm-frc-linux-gnueabi)
set(ARM_PREFIX arm-none-linux-gnueabi)
set(CMAKE_SYSTEM_NAME Linux)
CMAKE_FORCE_CXX_COMPILER(${ARM_PREFIX}-g++ GNU)
CMAKE_FORCE_C_COMPILER(${ARM_PREFIX}-gcc GNU)
set(CMAKE_CXX_FLAGS "-std=c++1y -Wformat=2 -Wall -Wextra -Werror -pedantic -Wno-psabi" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "-march=armv7-a -mcpu=cortex-a9 -mfloat-abi=softfp -Wall -Wno-psabi" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -g" CACHE STRING "" FORCE) # still want debugging for release?
SET(CMAKE_FIND_ROOT_PATH $ENV{USER_HOME}/wpilib/toolchains/arm-none-linux-gnueabi-4.4.1/arm-none-linux-gnueabi/libc)

View File

@@ -1,69 +0,0 @@
plugins {
id 'net.ltgt.errorprone' version '0.0.8'
id 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin' version '1.6'
}
// Ensure that the WPILibVersioningPlugin is setup by setting the release type, if releaseType wasn't
// already specified on the command line
if (!hasProperty('releaseType')) {
WPILibVersion {
releaseType = 'dev'
}
}
def enableSimulation = hasProperty('makeSim')
ext.simulationInstallDir = "$rootDir/build/install/simulation"
allprojects {
ext.enableSimulation = enableSimulation
repositories {
mavenCentral()
}
ext.ntcoreDep = { lang, classifier, extension = null ->
return "edu.wpi.first.wpilib.networktables.$lang:NetworkTables:+:$classifier${extension == null ? '' : '@' + extension}"
}
ext.cscoreDep = { lang, classifier, extension = null ->
return "edu.wpi.cscore.$lang:cscore:+:$classifier${extension == null ? '' : '@' + extension}"
}
ext.wpiUtilDep = { classifier ->
return "edu.wpi.first.wpilib:wpiutil:+:$classifier@zip"
}
}
subprojects {
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'checkstyle'
checkstyle {
toolVersion = "6.18"
configFile = new File(rootDir, "styleguide/checkstyle.xml")
}
ext.armBuild = true
// Disables doclint in java 8.
if (JavaVersion.current().isJava8Compatible()) {
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
}
}
ext.setupWpilibRepo = { publishing ->
publishing.repositories.maven {
url = WPILibVersion.mavenLocalUrl
}
}
}
apply from: 'cppSettings.gradle'
apply from: 'ni-libraries/ni-libraries.gradle'
task wrapper(type: Wrapper) {
gradleVersion = '3.3'
}

2
cmake/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*~
target/

151
cmake/pom.xml Normal file
View File

@@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.wpi.first.wpilib.cmake</groupId>
<artifactId>cpp-root</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<profiles>
<profile>
<id>unix-properties</id>
<properties>
<cmakeGenerator>Unix Makefiles</cmakeGenerator>
</properties>
<activation>
<os>
<family>unix</family>
</os>
</activation>
</profile>
<profile>
<id>MAC-properties</id>
<properties>
<cmakeGenerator>Unix Makefiles</cmakeGenerator>
</properties>
<activation>
<os>
<family>mac</family>
</os>
</activation>
</profile>
<profile>
<id>windows-properties</id>
<properties>
<cmakeGenerator>MSYS Makefiles</cmakeGenerator>
</properties>
<activation>
<os>
<family>windows</family>
</os>
</activation>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>com.googlecode.cmake-maven-project</groupId>
<artifactId>cmake-maven-plugin</artifactId>
<version>2.8.11-b4</version>
<executions>
<execution>
<id>cmake</id>
<phase>generate-resources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<options>
<option>-DCMAKE_TOOLCHAIN_FILE=../../../arm-toolchain.cmake</option>
<option>-DCMAKE_INSTALL_PREFIX=target-root</option>
</options>
</configuration>
</execution>
<execution>
<id>cmake2</id>
<phase>generate-resources</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<target>install</target>
</configuration>
</execution>
</executions>
<configuration>
<sourcePath>..</sourcePath>
<targetPath>${project.build.directory}/cmake</targetPath>
<projectDirectory>${project.build.directory}/cmake</projectDirectory>
<generator>${cmakeGenerator}</generator>
<buildType>release</buildType>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<!-- Set time stamp and version properties. -->
<execution>
<id>set-version-info</id>
<goals>
<goal>run</goal>
</goals>
<phase>process-sources</phase>
<configuration>
<target>
<tstamp>
<format property="timestamp" pattern="yyyy/MM/dd HH:mm:ss z"/>
</tstamp>
<tstamp>
<format property="version-info" pattern="yyyy.MMdd.HHmmss"/>
</tstamp>
<property name="version" value="${version-info}.${build-number}"/>
</target>
<exportAntProperties>true</exportAntProperties>
</configuration>
</execution>
<!-- Unzip the include files for cpp.zip. -->
<execution>
<id>unzip-cpp-includes</id>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo file="${project.build.directory}/cmake/target-root/so.properties">cpp-sos=${version-info}</echo>
<zip destfile="${project.build.directory}/${project.build.finalName}.zip" basedir="${project.build.directory}/cmake/target-root" />
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<id>zip-cpp-includes</id>
<phase>compile</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.build.finalName}.zip</file>
<type>zip</type>
</artifact>
<artifact>
<file>${project.build.directory}/cmake/target-root/lib/libHALAthena.a</file>
<type>a</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

18
cmake/run-cpp-tests.sh Executable file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Temporary method to deploy C++ integration tests to the RoboRIO
if [ $(which sshpass) ]
then
# Send stderr to /dev/null - the only thing printed to it is the login prompt
sshpass -p "" ssh admin@10.1.90.2 killall FRCUserProgram java 2> /dev/null
sshpass -p "" scp target/cmake/wpilibc/wpilibC++IntegrationTests/FRCUserProgram admin@10.1.90.2:/home/admin 2> /dev/null
sshpass -p "" ssh admin@10.1.90.2 ./FRCUserProgram --gtest_color=yes $* 2> /dev/null
else
ssh admin@10.1.90.2 killall FRCUserProgram
scp target/cmake/wpilibc/wpilibC++IntegrationTests/FRCUserProgram admin@10.1.90.2:/home/admin
ssh admin@10.1.90.2 ./FRCUserProgram --gtest_color=yes $*
fi

View File

@@ -1,46 +0,0 @@
:: This file is a helper for allC++Sim
::
:: Usage: cd /build && ../configure
::
:: WARNING -- this is only temporary, and only meant for debug, and only works on my computer
@set WS=C:\Users\peter\gz-ws
@set BOOST_PATH=%WS%\boost_1_56_0
@set BOOST_LIBRARY_DIR=%BOOST_PATH%\lib64-msvc-12.0
@set PROTOBUF_PATH=%WS%\protobuf-2.6.0-win64-vc12
@set OGRE_PATH=%WS%\ogre_src_v1-8-1-vc12-x64-release-debug\build\install\Debug
@set OGRE_INCLUDE_DIR=%OGRE_PATH%\include;%OGRE_PATH%\include\OGRE;%OGRE_PATH%\include\OGRE\RTShaderSystem;%OGRE_PATH%\include\OGRE\Terrain;%OGRE_PATH%\include\OGRE\Paging
@set OGRE_LIBRARY_DIR=%OGRE_PATH%\lib\Debug
set OGRE_LIB_SUFFIX=_d.lib
@set OGRE_LIBS=%OGRE_LIBRARY_DIR%\OgreMain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreOverlay%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreRTShaderSystem%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreTerrain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgrePaging%OGRE_LIB_SUFFIX%
@set OGRE_LIBS=%OGRE_LIBRARY_DIR%\OgreMain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreRTShaderSystem%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreTerrain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgrePaging%OGRE_LIB_SUFFIX%
@set FREEIMAGE_PATH=%WS%\FreeImage-vc12-x64-release-debug
@set FREEIMAGE_INCLUDE_DIR=%FREEIMAGE_PATH%\Source
@set TBB_PATH=%WS%\tbb43_20141023oss
@set TBB_INCLUDEDIR=%TBB_PATH%\include
@set DLFCN_WIN32_PATH=%WS%\dlfcn-win32-vc12-x64-release-debug\build\install\Debug
@set DLFCN_WIN32_INCLUDE_DIR=%DLFCN_WIN32_PATH%\include
@set TINY_XML_INCLUDE_DIR=%WS%\sdformat\src\win\tinyxml
@set GAZEBO_PATH=%WS%\gazebo\build\install\Debug\lib\cmake\gazebo
@set SDFORMAT_PATH=%WS%\sdformat\build\install\Debug\lib\cmake\sdformat
@set IGNITION-MATH_PATH=%WS%\ign-math\build\install\Debug\lib\cmake\ignition-math2
@set INCLUDE=%TINY_XML_INCLUDE_DIR%;%FREEIMAGE_INCLUDE_DIR%;%TBB_INCLUDEDIR%;%DLFCN_WIN32_INCLUDE_DIR%;%INCLUDE%
@set LIB=%LIB%
cmake -G "NMake Makefiles"^
-DCMAKE_INSTALL_PREFIX=build^
-DCMAKE_PREFIX_PATH="%GAZEBO_PATH%;%SDFORMAT_PATH%;%IGNITION-MATH_PATH%"^
-DOGRE_FOUND=1^
-DOGRE_INCLUDE_DIRS="%OGRE_INCLUDE_DIR%"^
-DOGRE_LIBRARIES="%OGRE_LIBS%"^
-DPROTOBUF_SRC_ROOT_FOLDER="%PROTOBUF_PATH%"^
-DBOOST_ROOT="%BOOST_PATH%"^
-DBOOST_LIBRARYDIR="%BOOST_LIBRARY_DIR%"^
..

View File

@@ -1,243 +0,0 @@
// These add the nilibraries shared library to the linker args
def niLibraryPath = file('ni-libraries/lib').path
def niLibrary = niLibraryPath + "/libnilibraries.so"
configurations.create('armDeps')
dependencies {
armDeps ntcoreDep('cpp', 'arm', 'zip')
armDeps wpiUtilDep('arm')
armDeps cscoreDep('cpp', 'athena-uberzip', 'zip')
}
def depLocation = "$buildDir/dependencies"
configurations.armDeps.files.each { file ->
def depName = file.name.substring(0, file.name.indexOf('-'))
def t = tasks.create("downloadArm${depName.capitalize()}", Copy) {
description = "Downloads and unzips the $depName dependency."
group = 'Dependencies'
from zipTree(file)
into "$depLocation/${depName.toLowerCase()}"
}
}
task downloadNetworkTables {
description = 'Downloads all needed versions of networktables.'
group = 'Dependencies'
dependsOn downloadArmNetworkTables
}
task downloadWpiutil {
description = 'Downloads all needed versions of WPIUtil.'
group = 'Dependencies'
dependsOn downloadArmWpiutil
}
task downloadCscore {
description = 'Downloads all needed versions of cscore.'
group = 'Dependencies'
dependsOn downloadArmCscore
}
if (enableSimulation) {
configurations.create('nativeDeps')
dependencies {
nativeDeps ntcoreDep('cpp', 'desktop', 'zip')
nativeDeps wpiUtilDep('desktop')
}
configurations.nativeDeps.files.each { file ->
def depName = file.name.substring(0, file.name.indexOf('-'))
def t = tasks.create("downloadNative${depName.capitalize()}", Copy) {
description = "Downloads and unzips the $depName dependency."
group = 'Dependencies'
from zipTree(file)
into "$depLocation/${depName.toLowerCase()}"
}
}
downloadNetworkTables.dependsOn downloadNativeNetworkTables
downloadWpiutil.dependsOn downloadNativeWpiutil
}
def netTablesUnzipLocation = "$depLocation/networktables"
def wpiUtilUnzipLocation = "$depLocation/wpiutil"
def csCoreUnzipLocation = "$depLocation/cscore"
task clean(type: Delete) {
description = "Deletes the build directory"
group = "Build"
delete buildDir
}
if (!hasProperty("toolChainPath")) {
ext.toolChainPath = null
}
subprojects {
ext.defineWpiUtilProperties = {
ext.wpiUtil = wpiUtilUnzipLocation
ext.wpiUtilInclude = "$wpiUtilUnzipLocation/include"
ext.wpiUtilLibArmLocation = "$wpiUtilUnzipLocation/Linux/arm"
if (enableSimulation) {
ext.wpiUtilLibDesktopLocation = "$wpiUtilUnzipLocation/Linux/amd64"
}
ext.wpiUtilSharedLib = "$wpiUtilLibArmLocation/libwpiutil.so"
ext.wpiUtilSharedLibDebug = "$wpiUtilLibArmLocation/libwpiutil.so.debug"
ext.wpiUtilStaticLib = "$wpiUtilLibArmLocation/libwpiutil.a"
ext.addWpiUtilLibraryLinks = { compileTask, linker, targetPlatform ->
compileTask.dependsOn project(':').downloadWpiutil
String architecture = targetPlatform.architecture
if (architecture.contains('arm')) {
linker.args wpiUtilSharedLib
}
}
ext.addStaticWpiUtilLibraryLinks = { compileTask, linker, targetPlatform ->
compileTask.dependsOn project(':').downloadWpiutil
String architecture = targetPlatform.architecture
if (architecture.contains('arm')) {
linker.args wpiUtilStaticLib
}
}
}
// This defines a project property that projects depending on network tables can use to setup that dependency.
ext.defineNetworkTablesProperties = {
ext.netTables = netTablesUnzipLocation
ext.netTablesInclude = "$netTablesUnzipLocation/include"
ext.netLibArmLocation = "$netTablesUnzipLocation/Linux/arm"
if (enableSimulation) {
ext.netLibDesktopLocation = "$netTablesUnzipLocation/Linux/amd64"
}
ext.netSharedLib = "$netLibArmLocation/libntcore.so"
ext.netSharedLibDebug = "$netLibArmLocation/libntcore.so.debug"
ext.netStaticLib = "$netLibArmLocation/libntcore.a"
ext.addNetworkTablesLibraryLinks = { compileTask, linker, targetPlatform ->
compileTask.dependsOn project(':').downloadNetworkTables
String architecture = targetPlatform.architecture
if (architecture.contains('arm')) {
linker.args netSharedLib
}
addWpiUtilLibraryLinks(compileTask, linker, targetPlatform)
}
ext.addStaticNetworkTablesLibraryLinks = { compileTask, linker, targetPlatform ->
compileTask.dependsOn project(':').downloadNetworkTables
String architecture = targetPlatform.architecture
if (architecture.contains('arm')) {
linker.args netStaticLib
}
addStaticWpiUtilLibraryLinks(compileTask, linker, targetPlatform)
}
}
// This defines a project property that projects depending on cscore can use to setup that dependency.
ext.defineCsCoreProperties = {
ext.csCore = csCoreUnzipLocation
ext.csCoreInclude = "$csCoreUnzipLocation/include"
ext.csLibArmLocation = "$csCoreUnzipLocation/lib"
ext.csSharedLib = "$csLibArmLocation/libcscore.so"
ext.cvSharedLib = "$csLibArmLocation/libopencv.so"
ext.addCsCoreLibraryLinks = { compileTask, linker, targetPlatform ->
compileTask.dependsOn project(':').downloadCscore
String architecture = targetPlatform.architecture
if (architecture.contains('arm')) {
linker.args << '-L' + csLibArmLocation
linker.args csSharedLib
linker.args cvSharedLib
}
}
}
ext.defineCrossCompilerProperties = {
// We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi-<util name>
// If this ever changes, the prefix will need to be changed here
ext.compilerPrefix = 'arm-frc-linux-gnueabi-'
}
plugins.withType(CppPlugin).whenPluginAdded {
defineCrossCompilerProperties()
model {
buildTypes {
debug
}
// Adds a custom toolchain for our compiler prefix and options
toolChains {
roborioGcc(Gcc) {
if (toolChainPath != null)
path toolChainPath
target('roborio-arm') {
cCompiler.executable = compilerPrefix + cCompiler.executable
cppCompiler.executable = compilerPrefix + cppCompiler.executable
linker.executable = compilerPrefix + linker.executable
assembler.executable = compilerPrefix + assembler.executable
// Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports
// arm, and doesn't understand this flag, so it is removed from both
cppCompiler.withArguments { args ->
args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic'
args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-Og' << '-g3' << '-rdynamic'
//TODO: When the compiler allows us to actually call deprecated functions from within
// deprecated function, remove this line (this will cause calling deprecated functions
// to be treated as a warning rather than an error).
args << '-Wno-error=deprecated-declarations'
args.remove('-m32')
}
linker.withArguments { args ->
args << '-rdynamic'
args.remove('-m32')
}
staticLibArchiver.executable = compilerPrefix + staticLibArchiver.executable
}
}
}
platforms {
'roborio-arm' {
architecture 'arm'
operatingSystem 'linux'
}
}
}
ext.niLibraryHeadersRoot = "${rootDir}/ni-libraries/include"
ext.niLibraryHeadersChipObject = "${rootDir}/ni-libraries/include/FRC_FPGA_ChipObject"
ext.binTool = { tool ->
if (toolChainPath != null) return "${toolChainPath}/${compilerPrefix}${tool}"
return "${compilerPrefix}${tool}"
}
// This task adds the appropriate linker flags for the NI libraries
ext.addNiLibraryLinks = { linker, targetPlatform ->
String architecture = targetPlatform.architecture
if (architecture.contains('arm')){
linker.args << '-L' + niLibraryPath
linker.args niLibrary
}
}
// This task sets up the shared libraries to be stripped
ext.debugStripSetup = { project->
if (!project.hasProperty('debug')) {
project.tasks.whenObjectAdded { task ->
def name = task.name.toLowerCase()
if (name.contains('link') && name.contains('sharedlibrary')) {
def library = task.outputFile.absolutePath
def debugLibrary = task.outputFile.absolutePath + ".debug"
task.doLast {
exec { commandLine binTool('objcopy'), '--only-keep-debug', library, debugLibrary }
exec { commandLine binTool('strip'), '-g', library }
exec { commandLine binTool('objcopy'), "--add-gnu-debuglink=$debugLibrary", library }
}
}
}
}
}
}
}

44
driver-station/pom.xml Normal file
View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.wpi.first</groupId>
<artifactId>driver-station</artifactId>
<packaging>jar</packaging>
<version>0.1.0-SNAPSHOT</version>
<profiles>
<profile>
<id>docline-java8-disable</id>
<activation>
<jdk>[1.8,</jdk>
</activation>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>edu.wpi.first.driverstation.DriverStation</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,248 @@
package edu.wpi.first.driverstation;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import edu.wpi.first.driverstation.fms.FMSController;
import edu.wpi.first.driverstation.fms.FMSInterface;
import edu.wpi.first.driverstation.robotcoms.ControlMode;
import edu.wpi.first.driverstation.robotcoms.RobotComm;
/**
* Driver station implementation for the test stand. This is based heavily on
* code done by Brendan McLeod, modified for command line argument and local
* socket input.
*
* @author Fredric Silberberg
*/
public class DriverStation {
protected static final Logger log = Logger.getLogger(DriverStation.class
.getName());
protected static DriverStation station;
public static void main(String[] args) {
int team = 190, port = 6190;
List<String> commandQueue = new LinkedList<>();
// If there are command line arguments, then input them
if (args.length > 0) {
for (int i = 0; i < args.length; i++) {
String command = args[i];
switch (command) {
case "-t":
// Get the team number if there is still an argument
if (i + 1 < args.length) {
try {
team = Integer.parseInt(args[++i]);
} catch (NumberFormatException ex) {
log.log(Level.WARNING,
"Error, non-integer team number " + args[i]);
displayUsage();
System.exit(-1);
}
} else {
log.log(Level.WARNING,
"Error, no team number provided.");
displayUsage();
System.exit(-1);
}
log.log(Level.INFO, "Team number is set to " + team);
break;
case "-h":
// Display help
displayUsage();
return;
// TODO: Support networked commands
// case "-p":
// // Get the port number
// // Get the team number if there is still an argument
// if (i + 1 < args.length) {
// try {
// port = Integer.parseInt(args[++i]);
// } catch (NumberFormatException ex) {
// log.log(Level.WARNING,
// "Error, non-integer port number " + args[i]);
// displayUsage();
// System.exit(-1);
// }
// } else {
// log.log(Level.WARNING,
// "Error, no port number provided.");
// displayUsage();
// System.exit(-1);
// }
// log.log(Level.INFO, "Port number is set to " + port);
// break;
case "enable":
case "disable":
case "teleop":
case "auto":
case "estop":
case "reboot":
case "test":
// Add the command to the queue of commands
commandQueue.add(command);
break;
default:
log.log(Level.SEVERE, "Unknown input " + command);
displayUsage();
System.exit(-1);
}
}
}
station = new DriverStation(team, port);
for (String command : commandQueue) {
station.addCommand(command);
}
station.run();
}
public static void displayUsage() {
System.out.println("The Java FRC Driverstation");
System.out.println("To Use: java -jar <driverstation jar> [commands]");
System.out.println("-h: Print this display and exit");
System.out.println("-t [team]: Specify the team number (default 190)");
System.out
.println("enable, disable, teleop, auto, test, estop, reboot");
System.out.println("Run the given commands on startup");
}
RobotComm robot;
FMSInterface fms;
LinkedBlockingQueue<String> queue;
Thread netThread, sysThread;
public DriverStation(final int team, final int port) {
queue = new LinkedBlockingQueue<>();
robot = new RobotComm(team);
fms = new FMSController(team);
robot.setFMSController(fms);
robot.setDaemon(true);
sysThread = new Thread(new Runnable() {
public void run() {
BufferedReader sysIn = new BufferedReader(
new InputStreamReader(System.in));
while (!Thread.interrupted()) {
try {
String com = sysIn.readLine();
log.log(Level.FINE, "Recieved stdin command " + com);
station.addCommand(com);
} catch (IOException ex) {
log.log(Level.WARNING, "Error in system read thread",
ex);
}
}
}
});
sysThread.setDaemon(true);
// TODO: Test the networking protocol
// netThread = new Thread(new Runnable() {
// public void run() {
// ServerSocket servSock = null;
// List<Thread> connections = new LinkedList<>();
// try {
// servSock = new ServerSocket(port);
// while (!Thread.interrupted()) {
// Socket sock = servSock.accept();
// Thread newCon = new Thread(new ReadThread(sock, station));
// newCon.run();
// connections.add(newCon);
// log.log(Level.INFO, "Accepted new network connection");
// }
// } catch (IOException ex) {
// log.log(Level.WARNING, "Error with the network thread", ex);
// } finally {
// try {
// for (Thread t : connections) {
// t.interrupt();
// }
// servSock.close();
// } catch (IOException | NullPointerException e) {
// log.log(Level.SEVERE,
// "Error when closing the server socket", e);
// }
// }
// }
// });
// netThread.setDaemon(true);
}
public void run() {
System.out.println("Activating driver station");
robot.start();
System.out
.println("The driverstation supports the following commands:");
System.out
.println("enable, disable, teleop, auto, test, reboot, estop, quit");
sysThread.start();
// netThread.start();
while (true) {
try {
String command = queue.take();
log.log(Level.FINE, "Received command " + command);
switch (command) {
case "enable":
log.log(Level.INFO, "Enabling robot");
robot.setEnabled(true);
break;
case "disable":
log.log(Level.INFO, "Disabling robot");
robot.setEnabled(false);
break;
case "teleop":
log.log(Level.INFO, "Setting robot to teleop mode");
robot.setControlMode(ControlMode.TELEOP);
break;
case "auto":
log.log(Level.INFO, "Setting robot to auto mode");
robot.setControlMode(ControlMode.AUTO);
break;
case "test":
log.log(Level.INFO, "Setting robot to test mode");
robot.setControlMode(ControlMode.TEST_MODE);
break;
case "estop":
log.log(Level.INFO, "Estoping robot");
robot.eStopRobot();
break;
case "reboot":
log.log(Level.INFO, "Rebooting robot");
robot.rebootRobot();
break;
case "quit":
log.log(Level.INFO, "Shutting down");
sysThread.interrupt();
// netThread.interrupt();
return;
default:
log.log(Level.WARNING, "Unknown input " + command);
break;
}
} catch (InterruptedException e) {
log.log(Level.WARNING, "Error when taking command", e);
}
}
}
public void addCommand(String command) {
try {
queue.put(command);
} catch (InterruptedException e) {
log.log(Level.WARNING, "Error when added an element to the queue",
e);
}
}
}

View File

@@ -0,0 +1,42 @@
package edu.wpi.first.driverstation;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ReadThread implements Runnable {
private final Logger log = Logger.getLogger(DriverStation.class.getName());
Socket sock;
DriverStation ds;
public ReadThread(Socket sock, DriverStation ds) {
this.sock = sock;
this.ds = ds;
}
@Override
public void run() {
try {
BufferedReader netIn = new BufferedReader(new InputStreamReader(
sock.getInputStream()));
while (!Thread.interrupted()) {
String com = netIn.readLine();
log.log(Level.FINE, "Received command " + com);
ds.addCommand(com);
}
} catch (IOException e) {
log.log(Level.WARNING, "IO Exception in net thread", e);
} finally {
try {
sock.close();
} catch (IOException | NullPointerException ex) {
log.log(Level.SEVERE, "Error when closing the socket", ex);
}
}
}
}

View File

@@ -0,0 +1,249 @@
package edu.wpi.first.driverstation.fms;
import edu.wpi.first.driverstation.DriverStation;
import edu.wpi.first.driverstation.fms.FMSInterface;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.CRC32;
import edu.wpi.first.driverstation.robotcoms.ControlMode;
/**
*
* @author Brendan
*/
public class FMSController extends Thread implements FMSInterface {
private static final Logger log = Logger.getLogger(DriverStation.class
.getName());
private class FMSDataIn extends Thread {
private FMSController fmsController;
private int FMSreceivePort = 1120;
private DatagramSocket FMSreceiveSocket;
public FMSDataIn(FMSController fmsController) {
this.fmsController = fmsController;
try {
FMSreceiveSocket = new DatagramSocket(FMSreceivePort);
} catch (SocketException ex) {
log.log(Level.WARNING, "Error creating Robot Sockets", ex);
}
}
@Override
public void run() {
while (true) {
try {
byte[] receiveData = new byte[74];// the size of the data
DatagramPacket receivePacket = new DatagramPacket(
receiveData, receiveData.length);
FMSreceiveSocket.receive(receivePacket);
fmsController
.setIP(receivePacket.getAddress().getAddress());
fmsController.receiveFMSpacket(receiveData);
} catch (Exception ex) {
log.log(Level.INFO, "Receive error", ex);
}
}
}
}
private FMSDataIn dataInput;
private DatagramSocket FMSsendingSocket;
private int teamNumber;
private int FMSsendPort = 1160;
private byte[] ipFMS = new byte[4];
private boolean[] controlState = new boolean[8];
// {auto, test, mode, enabled, not-estopped}
private boolean[] fromRobot = new boolean[] { false, false, false, true };
private char[] batteryData = new char[] { 13, 13 };
private long lastFMS = 0;
private long lastFMSSent = 0;
char[] stationID = new char[2];
private boolean isRobotConnected;
/*
* controlState[0] //null controlState[1] //WAP link controlState[2] //check
* version #s controlState[3] //request DS info? controlState[4]
* //auto-teleop controlState[5] //enabled-disabled controlState[6] //not
* estop controlState[7] //null
*/
public FMSController(int team) {
teamNumber = team;
try {
FMSsendingSocket = new DatagramSocket(FMSsendPort);
} catch (SocketException ex) {
log.log(Level.WARNING, "Error creating FMS Sockets", ex);
}
for (int i = 0; i < 4; i++) {
ipFMS[i] = (byte) 0xFF;
}
dataInput = new FMSDataIn(this);
dataInput.setDaemon(true);
setDaemon(true);
start();
}
@Override
public void start() {
dataInput.start();
super.start();
}
@Override
public void run() {
while (true) {
if ((System.currentTimeMillis() > (lastFMSSent + 100))) {
lastFMSSent = System.currentTimeMillis();
sendFMSData();
}
}
}
private void setIP(byte[] ipIn) {
ipFMS = ipIn;
}
@Override
public boolean isFMSConnected() {
return ((lastFMS + 1000) > System.currentTimeMillis());
}
private void receiveFMSpacket(byte[] receiveData) {
lastFMS = System.currentTimeMillis();
// reveive data 0, 1 are useless
// 2 contains control data
for (int i = 0; i < 8; i++) {
controlState[i] = (receiveData[2] & (1 << (i))) > 0;
}
stationID[0] = (char) receiveData[3];
stationID[1] = (char) receiveData[4];
}
private void sendFMSData() {
CRC32 crctest = new CRC32();
byte[] sendData = new byte[50];
for (int i = 0; i < 50; i++) {
sendData[i] = 0x00;
}
if (isRobotConnected)// {auto, test mode, enabled, not-estopped}
{
sendData[2] += 0x02;
}
if (fromRobot[0])// 0 holds the mode (1=auto 0=teleop)
{
sendData[2] += 0x10;
}
if (fromRobot[2])// 1 holds enabled (1=enabled)
{
sendData[2] += 0x20;
}
if (fromRobot[3])// 2 holds not e-stoped (1=good, 0=bad)
{
sendData[2] += 0x40;
}
byte teamHigh = (byte) ((teamNumber - (teamNumber % 100)) / 100);
byte teamLow = (byte) (teamNumber % 100);
sendData[6] = 10;// IP address
sendData[7] = teamHigh;
sendData[8] = teamLow;
sendData[9] = 5;// make this variable!!!!
sendData[10] = (byte) stationID[0];// the alliance color
sendData[11] = (byte) stationID[1]; // the station number
sendData[26] = 0x00;// amount of dropped packets
sendData[27] = 0x00;// amount of dropped packets
sendData[28] = 0x00;// number of packets received
sendData[29] = 0x00;// number of packets received
sendData[30] = 0x00;// trip time
sendData[31] = 0x00;// trip time
sendData[32] = 0x00;// trip time
sendData[33] = 0x00;// trip time
// need to capture actual voltage
sendData[40] = (byte) batteryData[0];
sendData[41] = (byte) batteryData[1];
/*
* get CRC
*/
crctest.reset();
crctest.update(sendData);
/*
* convert CRC to byte format
*/
long crccheck = crctest.getValue();
sendData[46] = (byte) ((crccheck >> 24) & 0xff);
sendData[47] = (byte) ((crccheck >> 16) & 0xff);
sendData[48] = (byte) ((crccheck >> 8) & 0xff);
sendData[49] = (byte) ((crccheck) & 0xff);
log.log(Level.FINE, "Sending FMS Data");
/*
* send packet
*/
try {
DatagramPacket sendPacket = new DatagramPacket(sendData,
sendData.length, InetAddress.getByAddress(ipFMS),
FMSsendPort);
FMSsendingSocket.send(sendPacket);
} catch (Exception e) {
}
}
@Override
public char getAllianceColor() {
return stationID[0];
}
@Override
public char getDSNumber() {
return stationID[1];
}
@Override
public boolean isEnabled() {
return controlState[5];
}
@Override
public ControlMode getControlMode() {
if (!controlState[4]) {
return ControlMode.TELEOP;
}
return ControlMode.AUTO;
}
@Override
public void updateBattery(char[] batteryData) {
this.batteryData = batteryData;
}
@Override
public void updateRobotFeedback(boolean[] fromRobot) {
this.fromRobot = fromRobot;
}
@Override
public void setRobotConnected(boolean connected) {
isRobotConnected = connected;
}
}

View File

@@ -0,0 +1,25 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package edu.wpi.first.driverstation.fms;
import edu.wpi.first.driverstation.robotcoms.ControlMode;
/**
*
* @author Brendan
*/
public interface FMSInterface {
public char getAllianceColor();
public char getDSNumber();
public boolean isFMSConnected();
public boolean isEnabled();
public ControlMode getControlMode();
public void updateBattery(char[] batteryData);
public void updateRobotFeedback(boolean[] fromRobot);
public void setRobotConnected(boolean connected);
}

View File

@@ -0,0 +1,54 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package edu.wpi.first.driverstation.fms;
import edu.wpi.first.driverstation.robotcoms.ControlMode;
/**
*
* @author Brendan
*/
public class NoFMSController implements FMSInterface {
@Override
public char getAllianceColor() {
return 'B';
}
@Override
public char getDSNumber() {
return '1';
}
@Override
public boolean isFMSConnected() {
return false;
}
@Override
public boolean isEnabled() {
return false;
}
@Override
public ControlMode getControlMode() {
return ControlMode.TELEOP;
}
@Override
public void updateBattery(char[] batteryData) {
return;
}
@Override
public void updateRobotFeedback(boolean[] fromRobot) {
return;
}
@Override
public void setRobotConnected(boolean connected) {
return;
}
}

View File

@@ -0,0 +1,24 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package edu.wpi.first.driverstation.robotcoms;
/**
*
* @author Brendan
*/
public enum ControlMode {
AUTO("AUTO"), TELEOP("TELEOP"), TEST_MODE("TEST");
private String name;
private ControlMode(String name) {
this.name = name;
}
@Override
public String toString() {
return name; //To change body of generated methods, choose Tools | Templates.
}
}

View File

@@ -0,0 +1,319 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package edu.wpi.first.driverstation.robotcoms;
import edu.wpi.first.driverstation.DriverStation;
import edu.wpi.first.driverstation.fms.FMSInterface;
import edu.wpi.first.driverstation.fms.NoFMSController;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.CRC32;
/**
*
* @author Brendan
*/
public class RobotComm extends Thread {
private static final Logger log = Logger.getLogger(DriverStation.class
.getName());
private class RobotDataIn extends Thread {
RobotComm theRobotComm;
private DatagramSocket robotReceiveSocket;
private int robotReceivePort = 1150;
public RobotDataIn(RobotComm robotComm) {
theRobotComm = robotComm;
try {
robotReceiveSocket = new DatagramSocket(robotReceivePort);
} catch (SocketException ex) {
log.log(Level.WARNING, "Error creating Robot Sockets", ex);
}
}
public void run() {
while (true) {
try {
byte[] receiveData = new byte[1024];// the size of the data
DatagramPacket receivePacket = new DatagramPacket(
receiveData, receiveData.length);
robotReceiveSocket.receive(receivePacket);
theRobotComm.receiveRobotpacket(receiveData);
Thread.yield();
} catch (Exception ex) {
}
}
}
}
private DatagramSocket robotSendingSocket;
private RobotDataIn inputSocket;
private final int robotSendPortNormal = 1110;
// private final int robotSendPortNormal = 1115;//actually for sending on
// the field (used for robot sim)
private final int robotSendPortFMS = 1115;
private int sentPackets;// the current packet ID that is being sent to the
// robot
private int lastRobotPacket;// the last packet ID to have been recieved by
// the robot
private long lastRobotTime;// the time stamp when the robot was seen
private boolean[] controlDataToSend;// {auto, test mode, enabled,
// not-estopped, reboot}
private boolean[] controlFromRobot;// {auto, test mode, enabled,
// not-estopped}
private byte[] stationID = new byte[2];
private char[] batteryData = new char[2];
private int robotTeam = 0;
private long lastSentTime = 0;
private int packetOffset = 0;
private FMSInterface fmsController;
public RobotComm(int team) {
robotTeam = team;
try {
robotSendingSocket = new DatagramSocket();// robotSendPortNormal);
} catch (SocketException ex) {
log.log(Level.WARNING, "Error creating Robot Sockets", ex);
}
sentPackets = 0;
controlFromRobot = new boolean[] { false, false, false, true };// {auto,
// test
// mode,
// enabled,
// not-estopped}
controlDataToSend = new boolean[] { false, false, false, true, false };// {auto,
// test
// mode,
// enabled,
// not-estopped,
// reboot}
fmsController = new NoFMSController();
inputSocket = new RobotDataIn(this);
inputSocket.setDaemon(true);
}
@Override
public void start() {
inputSocket.start();
super.start();
}
@Override
public void run() {
while (true) {
if ((lastSentTime + 20) < System.currentTimeMillis()) {
lastSentTime = System.currentTimeMillis();
sendRobotData();
}
}
}
public void rebootRobot() {
setEnabled(false);
controlDataToSend[4] = true;
}
public void setControlMode(ControlMode theMode) {
if (theMode == ControlMode.AUTO) {// {auto, test mode, enabled,
// not-estopped}
controlDataToSend[0] = true;
controlDataToSend[1] = false;
} else if (theMode == ControlMode.TELEOP) {// {auto, test mode, enabled,
// not-estopped}
controlDataToSend[0] = false;
controlDataToSend[1] = false;
} else if (theMode == ControlMode.TEST_MODE) {// {auto, test mode,
// enabled,
// not-estopped}
controlDataToSend[0] = false;
controlDataToSend[1] = true;
}
}
public void setEnabled(boolean enabled) {// {auto, test mode, enabled,
// not-estopped, reboot}
controlDataToSend[2] = enabled;
}
public void eStopRobot() {
controlDataToSend[3] = false;
}
public void setAllianceInfo(byte allianceColor, byte allianceStation) {
stationID = new byte[] { allianceColor, allianceStation };
}
public void setTeamNumber(int newTeam) {
robotTeam = newTeam;
}
public void setFMSController(FMSInterface newFMS) {
fmsController = newFMS;
}
/**
* Packs up all the data and sends the packet to the robot
*/
private void sendRobotData() {
sentPackets++;
sentPackets = sentPackets % 0xFFFF;// makes it overflow properly
packetOffset = sentPackets - lastRobotPacket;
CRC32 crctest = new CRC32();
byte[] sendData = new byte[1024];
for (int i = 0; i < 1024; i++) {
sendData[i] = 0x00;
}
// Construct the pacet counts
sendData[0] = (byte) ((sentPackets >> 8) & 0xFF);
sendData[1] = (byte) (sentPackets & 0xFF);
// {auto, test mode, enabled, not-estopped, reboot}
if (controlDataToSend[4]) {// reboot bit
sendData[2] += 0x80;
controlDataToSend[4] = false;
}
if (controlDataToSend[3]) {// not e-stop bit
sendData[2] += 0x40;
} else {
controlDataToSend[3] = true;
}
if (controlDataToSend[2])// if enabled
{
sendData[2] += 0x20;
}
if (controlDataToSend[0])// 1 holds the mode (1=auto 0=teleop)
{
sendData[2] += 0x10;
}
if (fmsController.isFMSConnected()) {
sendData[2] += 0x08;
}
if (!isConnected()) {
sendData[2] += 0x04;
}
sendData[3] = (byte) 0xFF;// make all digial inputs high
sendData[4] = (byte) ((robotTeam >> 8) & 0xFF);// packs up and sends
// team number
sendData[5] = (byte) ((robotTeam) & 0xFF);
sendData[6] = stationID[0];// the alliance color
sendData[7] = stationID[1]; // the station number
sendData[72] = (byte) 0x31;
sendData[73] = (byte) 0x31;
sendData[74] = (byte) 0x33;
sendData[75] = (byte) 0x30;
sendData[76] = (byte) 0x21;
sendData[77] = (byte) 0x21;
sendData[78] = (byte) 0x30;
sendData[79] = (byte) 0x30;
crctest.reset();
crctest.update(sendData);
long crccheck = crctest.getValue();
sendData[1020] = (byte) ((crccheck >> 24) & 0xff);
sendData[1021] = (byte) ((crccheck >> 16) & 0xff);
sendData[1022] = (byte) ((crccheck >> 8) & 0xff);
sendData[1023] = (byte) ((crccheck >> 0) & 0xff);
byte teamHigh = (byte) ((robotTeam - robotTeam % 100) / 100);
byte teamLow = (byte) (robotTeam % 100);
/*
* send packet
*/
try {
DatagramPacket sendPacket;
if (!fmsController.isFMSConnected()) {
sendPacket = new DatagramPacket(sendData, sendData.length,
InetAddress.getByAddress(new byte[] { 10, teamHigh,
teamLow, 2 }), robotSendPortNormal);
} else {
sendPacket = new DatagramPacket(sendData, sendData.length,
InetAddress.getByAddress(new byte[] { 10, teamHigh,
teamLow, 2 }), robotSendPortFMS);
}
robotSendingSocket.send(sendPacket);
} catch (Exception e) {
log.log(Level.WARNING, "Failed to send", e);
}
fmsController.setRobotConnected(isConnected());
}
public boolean isConnected() {
if (!(lastRobotTime + 100 > System.currentTimeMillis())) {
return (false);
}
if (packetOffset > 25) {
return (false);
}
return (true);
}
public char[] getBatteryData() {
return batteryData;
}
/**
* Return the control data that it has gathered from the robot in the
* format: {auto, test mode, enabled, not-estopped}
*
* @return The data from the robot
*/
public boolean[] getControlDataFromRobot() {
return controlFromRobot;
}
public double getBatteryVoltage() {
return Double.parseDouble(getBatteryString());
}
public String getBatteryString() {
return (String.format("%x", getBatteryData()[0]) + "." + String.format(
"%x", getBatteryData()[1]));
}
protected void receiveRobotpacket(byte[] dataIn) {// this gets called
// whenever a new robot
// packet is recieved
int teamNumber = 0;
teamNumber += dataIn[8] & 0xFF;
teamNumber = ((teamNumber << 8) + (dataIn[9] & 0xFF)) & 0xFFFF;
if (robotTeam == teamNumber) {
lastRobotTime = System.currentTimeMillis();
batteryData[0] = (char) dataIn[1];
batteryData[1] = (char) dataIn[2];
lastRobotPacket = 0;
lastRobotPacket += dataIn[30] & 0xFF;
lastRobotPacket = ((lastRobotPacket << 8) + (dataIn[31] & 0xFF)) & 0xFFFF;
controlFromRobot[0] = ((0x10 & dataIn[0]) > 0);// auto
controlFromRobot[2] = ((0x20 & dataIn[0]) > 0);// enabled
controlFromRobot[3] = true;// robot isn't estopped yet
} else {
log.log(Level.INFO, "Data from different team...");
}
fmsController.updateRobotFeedback(controlFromRobot);
fmsController.updateBattery(batteryData);
}
}

4
eclipse-plugins/.gitattributes vendored Normal file
View File

@@ -0,0 +1,4 @@
*runcppprogram text eol=lf
*runjavaprogram text eol=lf
*robotCommand text eol=lf
*robotDebugCommand text eol=lf

4
eclipse-plugins/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*~
target/
bin/
.settings/

View File

@@ -0,0 +1 @@
bin.includes = feature.xml

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="edu.wpi.first.wpilib.plugins.core.feature"
label="WPILib Robot Development Core"
version="0.1.0.qualifier"
provider-name="Worcester Polytechnic Institute">
<copyright>
* Copyright (c) 2013 FIRST and WPI
* All rights reserved.
</copyright>
<license>
* Copyright (c) 2013 FIRST and WPI
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer. Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution. Neither the name of the FIRST nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS&apos;&apos;
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</license>
<url>
<discovery label="Juno" url="http://download.eclipse.org/releases/juno/"/>
</url>
<plugin
id="edu.wpi.first.wpilib.plugins.core"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>edu.wpi.first.wpilib.plugins.core.feature</artifactId>
<packaging>eclipse-feature</packaging>
<parent>
<groupId>edu.wpi.first.wpilib.plugins</groupId>
<artifactId>edu.wpi.first.wpilib.plugins</artifactId>
<version>0.1.0.qualifier</version>
<relativePath>..</relativePath>
</parent>
</project>

View File

@@ -0,0 +1,34 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: edu.wpi.first.wpilib.plugins.core
Bundle-SymbolicName: edu.wpi.first.wpilib.plugins.core;singleton:=true
Bundle-Version: 0.1.0.qualifier
Bundle-Activator: edu.wpi.first.wpilib.plugins.core.WPILibCore
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.jface.text,
org.eclipse.core.resources,
org.eclipse.ui.editors,
org.eclipse.ui.ide,
org.eclipse.ant.core;bundle-version="3.2.400",
org.eclipse.ant.launching;bundle-version="1.0.200",
org.eclipse.debug.core;bundle-version="3.7.100",
org.eclipse.core.externaltools;bundle-version="1.0.100",
org.eclipse.debug.ui;bundle-version="3.8.1",
org.eclipse.ui.externaltools;bundle-version="3.2.100",
org.eclipse.ant.ui;bundle-version="3.5.300",
org.eclipse.ui.console;bundle-version="3.5.100",
org.eclipse.ui.navigator;bundle-version="3.5.200",
org.eclipse.ui.navigator.resources;bundle-version="3.4.400",
org.eclipse.ui.intro,
org.eclipse.ui.intro.universal,
org.eclipse.core.expressions;bundle-version="3.4.400"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Export-Package: edu.wpi.first.wpilib.plugins.core,
edu.wpi.first.wpilib.plugins.core.ant,
edu.wpi.first.wpilib.plugins.core.installer,
edu.wpi.first.wpilib.plugins.core.launching,
edu.wpi.first.wpilib.plugins.core.nature,
edu.wpi.first.wpilib.plugins.core.preferences,
edu.wpi.first.wpilib.plugins.core.wizards

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,3 @@
a#WPILibRobotDevelopment-introLink img { background-image : url(graphics/sample.gif); }
a#WPILibRobotDevelopment-introLink:hover img { background-image : url(graphics/sample_hov.gif); }

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?>
<introContent>
<extensionContent id="WPILibRobotDevelopment-introExtension" style="css/sample.css" name="Sample Extension" path="overview/@">
<group style-id="content-group" id="WPILibRobotDevelopment-introLink-group">
<link label="WPILib Documentation" url="http://wpilib.screenstepslive.com/s/3120" id="WPILibRobotDevelopment-introLink" style-id="content-link">
<text>Documentation of how WPILib and it's associated tools work. (Internet Connection Needed)</text>
</link>
</group>
</extensionContent>
</introContent>

View File

@@ -0,0 +1,10 @@
source.. = src/main/java/
output.. = bin/
bin.includes = plugin.xml,\
META-INF/,\
.,\
icons/,\
resources/
buildDirectory = build/
plugin.destination = ${basedir}/repository
eclipse.home = /usr/lib/eclipse

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 894 B

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
id="edu.wpi.first.wpilib.plugins.core.nature.FRCProjectNature"
name="FRCProjectNature"
point="org.eclipse.core.resources.natures">
<runtime>
<run
class="edu.wpi.first.wpilib.plugins.core.nature.FRCProjectNature">
</run>
</runtime>
</extension>
<extension
point="org.eclipse.ui.actionSets">
<actionSet
id="edu.wpi.first.wpilib.plugins.core.actionSet"
label="WPILib Action Set"
visible="true">
<menu
id="edu.wpi.first.wpilib.plugins.core.menu"
label="WPI&amp;Lib">
<separator
name="edu.wpi.first.wpilib.plugins.core.actions">
</separator>
</menu>
<action
class="edu.wpi.first.wpilib.plugins.core.actions.RunSmartDashboardAction"
icon="icons/smartdashboard16x16.png"
id="edu.wpi.first.wpilib.plugins.core.actions.RunSmartDashboardAction"
label="Run &amp;SmartDashboard"
menubarPath="edu.wpi.first.wpilib.plugins.core.menu/edu.wpi.first.wpilib.plugins.core.actions"
toolbarPath="WPILib"
tooltip="Launch the SmartDashboard to get feedback from the robot.">
</action>
<action
class="edu.wpi.first.wpilib.plugins.core.actions.RunRobotBuilderAction"
icon="icons/robotbuilder16x16.png"
id="edu.wpi.first.wpilib.plugins.core.actions.RunRobotBuilderAction"
label="Run &amp;RobotBuilder"
menubarPath="edu.wpi.first.wpilib.plugins.core.menu/edu.wpi.first.wpilib.plugins.core.actions"
toolbarPath="WPILib"
tooltip="Launch the RobotBuilder to help develop command-based programs.">
</action>
<action
class="edu.wpi.first.wpilib.plugins.core.actions.RunSFXDashboardAction"
icon="icons/sfxdashboard16x16.png"
id="edu.wpi.first.wpilib.plugins.core.actions.RunSFXDashboardAction"
label="Run &amp;SFX Dashboard"
menubarPath="edu.wpi.first.wpilib.plugins.core.menu/edu.wpi.first.wpilib.plugins.core.actions"
toolbarPath="WPILib"
tooltip="Launch the SFX Dashboard to get feedback from the robot.">
</action>
<action
class="edu.wpi.first.wpilib.plugins.core.actions.RunOutlineViewerAction"
icon="icons/outlineviewer16x16.png"
id="edu.wpi.first.wpilib.plugins.core.actions.RunOutlineViewerAction"
label="Run &amp;Outline Viewer"
menubarPath="edu.wpi.first.wpilib.plugins.core.menu/edu.wpi.first.wpilib.plugins.core.actions"
toolbarPath="WPILib"
tooltip="Launch the Outline Viewer to see the raw feedback from the robot.">
</action>
</actionSet>
</extension>
<extension
point="org.eclipse.ui.preferencePages">
<page
class="edu.wpi.first.wpilib.plugins.core.preferences.WPILibPreferencePage"
id="edu.wpi.first.wpilib.plugins.core.preferences.WPILibPreferencePage"
name="WPILib Preferences">
</page>
</extension>
<extension
point="org.eclipse.core.runtime.preferences">
<initializer
class="edu.wpi.first.wpilib.plugins.core.preferences.PreferenceInitializer">
</initializer>
</extension>
<extension
point="org.eclipse.ui.intro.configExtension">
<configExtension
configId="org.eclipse.ui.intro.universalConfig"
content="WPILib Intro/sample.xml">
</configExtension>
</extension>
</plugin>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>edu.wpi.first.wpilib.plugins.core</artifactId>
<packaging>eclipse-plugin</packaging>
<parent>
<groupId>edu.wpi.first.wpilib.plugins</groupId>
<artifactId>edu.wpi.first.wpilib.plugins</artifactId>
<version>0.1.0.qualifier</version>
<relativePath>..</relativePath>
</parent>
</project>

View File

@@ -0,0 +1,151 @@
package edu.wpi.first.wpilib.plugins.core;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import edu.wpi.first.wpilib.plugins.core.ant.AntPropertiesParser;
import edu.wpi.first.wpilib.plugins.core.installer.ToolsInstaller;
import edu.wpi.first.wpilib.plugins.core.preferences.PreferenceConstants;
/**
* The activator class controls the plug-in life cycle
*/
public class WPILibCore extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "edu.wpi.first.wpilib.plugins.core"; //$NON-NLS-1$
// The shared instance
private static WPILibCore plugin;
/**
* The constructor
*/
public WPILibCore() {
}
/*
* (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;
new ToolsInstaller(getDefaultVersion()).installIfNecessary();
}
/*
* (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 WPILibCore getDefault() {
return plugin;
}
/**
* Returns an image descriptor for the image file at the given plug-in
* relative path
*
* @param path
* the path
* @return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(String path) {
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}
public Properties getProjectProperties(IProject project) {
List<InputStream> streams = new ArrayList<InputStream>();
try {
if (project != null) {
try {
streams.add(project.getFile("build.properties")
.getContents());
} catch (CoreException e) {
} // No properties file
}
File file = new File(getWPILibBaseDir() + "/wpilib.properties");
streams.add(new FileInputStream(file));
return new AntPropertiesParser(streams).getProperties();
} catch (Exception e) {
WPILibCore.logError("Error loading project properties.", e);
return new Properties();
}
}
public void saveGlobalProperties(Properties props) {
try {
props.store(new FileOutputStream(new File(WPILibCore.getDefault()
.getWPILibBaseDir() + "/wpilib.properties")),
"Don't add new properties, they will be deleted by the eclipse plugin.");
} catch (IOException e) {
WPILibCore.logError("Error saving global properties.", e);
}
}
public int getTeamNumber(IProject project) {
return Integer.parseInt(getProjectProperties(project).getProperty(
"team-number", "0"));
}
public String getTargetIP(IProject project) {
String target = getProjectProperties(project).getProperty("target");
if (target != null)
return target;
else {
int teamNumber = getTeamNumber(project);
return "roborio-" + teamNumber + ".local";
}
}
public String getWPILibBaseDir() {
return System.getProperty("user.home") + "/wpilib";
}
public String getDefaultVersion() {
return "2013-test-0.4";
}
public String getCurrentVersion() {
return getPreferenceStore()
.getString(PreferenceConstants.TOOLS_VERSION);
}
public static void logInfo(String msg) {
getDefault().getLog().log(new Status(Status.INFO, PLUGIN_ID, Status.OK, msg, null));
}
public static void logError(String msg, Exception e) {
getDefault().getLog().log(new Status(Status.ERROR, PLUGIN_ID, Status.OK, msg, e));
}
}

View File

@@ -0,0 +1,71 @@
package edu.wpi.first.wpilib.plugins.core.actions;
import java.io.File;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
/**
* Our sample action implements workbench action delegate.
* The action proxy will be created by the workbench and
* shown in the UI. When the user tries to use the action,
* this delegate will be created and execution will be
* delegated to it.
* @see IWorkbenchWindowActionDelegate
*/
public class RunOutlineViewerAction implements IWorkbenchWindowActionDelegate {
/**
* The constructor.
*/
public RunOutlineViewerAction() {
}
/**
* The action has been activated. The argument of the
* method represents the 'real' action sitting
* in the workbench UI.
* @see IWorkbenchWindowActionDelegate#run
*/
public void run(IAction action) {
String jarFile = WPILibCore.getDefault().getWPILibBaseDir()+File.separator+"tools"+File.separator
+WPILibCore.getDefault().getCurrentVersion()+File.separator+"OutlineViewer-with-dependencies.jar";
String[] cmd = {"java", "-jar", jarFile};
try {
DebugPlugin.exec(cmd, new File(System.getProperty("user.home")));
} catch (CoreException e) {
WPILibCore.logError("Error running outline viewer.", e);
}
}
/**
* Selection in the workbench has been changed. We
* can change the state of the 'real' action here
* if we want, but this can only happen after
* the delegate has been created.
* @see IWorkbenchWindowActionDelegate#selectionChanged
*/
public void selectionChanged(IAction action, ISelection selection) {
}
/**
* We can use this method to dispose of any system
* resources we previously allocated.
* @see IWorkbenchWindowActionDelegate#dispose
*/
public void dispose() {
}
/**
* We will cache window object in order to
* be able to provide parent shell for the message dialog.
* @see IWorkbenchWindowActionDelegate#init
*/
public void init(IWorkbenchWindow window) {
}
}

View File

@@ -0,0 +1,78 @@
package edu.wpi.first.wpilib.plugins.core.actions;
import java.io.File;
import java.io.FilenameFilter;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
/**
* Our sample action implements workbench action delegate.
* The action proxy will be created by the workbench and
* shown in the UI. When the user tries to use the action,
* this delegate will be created and execution will be
* delegated to it.
* @see IWorkbenchWindowActionDelegate
*/
public class RunRobotBuilderAction implements IWorkbenchWindowActionDelegate {
/**
* The constructor.
*/
public RunRobotBuilderAction() {
}
/**
* The action has been activated. The argument of the
* method represents the 'real' action sitting
* in the workbench UI.
* @see IWorkbenchWindowActionDelegate#run
*/
public void run(IAction action) {
File dir = new File(WPILibCore.getDefault().getWPILibBaseDir()+File.separator+"tools"+File.separator
+WPILibCore.getDefault().getCurrentVersion());
File[] files = dir.listFiles(new FilenameFilter() {
@Override public boolean accept(File dir, String name) {
return name.startsWith("RobotBuilder") && name.endsWith(".jar");
}
});
if (files.length < 1) return;
String[] cmd = {"java", "-jar", files[0].getAbsolutePath()};
try {
DebugPlugin.exec(cmd, new File(System.getProperty("user.home")));
} catch (CoreException e) {
WPILibCore.logError("Error running RobotBuilder.", e);
}
}
/**
* Selection in the workbench has been changed. We
* can change the state of the 'real' action here
* if we want, but this can only happen after
* the delegate has been created.
* @see IWorkbenchWindowActionDelegate#selectionChanged
*/
public void selectionChanged(IAction action, ISelection selection) {
}
/**
* We can use this method to dispose of any system
* resources we previously allocated.
* @see IWorkbenchWindowActionDelegate#dispose
*/
public void dispose() {
}
/**
* We will cache window object in order to
* be able to provide parent shell for the message dialog.
* @see IWorkbenchWindowActionDelegate#init
*/
public void init(IWorkbenchWindow window) {
}
}

View File

@@ -0,0 +1,71 @@
package edu.wpi.first.wpilib.plugins.core.actions;
import java.io.File;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
/**
* Our sample action implements workbench action delegate.
* The action proxy will be created by the workbench and
* shown in the UI. When the user tries to use the action,
* this delegate will be created and execution will be
* delegated to it.
* @see IWorkbenchWindowActionDelegate
*/
public class RunSFXDashboardAction implements IWorkbenchWindowActionDelegate {
/**
* The constructor.
*/
public RunSFXDashboardAction() {
}
/**
* The action has been activated. The argument of the
* method represents the 'real' action sitting
* in the workbench UI.
* @see IWorkbenchWindowActionDelegate#run
*/
public void run(IAction action) {
String jarFile = WPILibCore.getDefault().getWPILibBaseDir()+File.separator+"tools"+File.separator
+WPILibCore.getDefault().getCurrentVersion()+File.separator+"sfx.jar";
String[] cmd = {"java", "-jar", jarFile};
try {
DebugPlugin.exec(cmd, new File(System.getProperty("user.home")));
} catch (CoreException e) {
WPILibCore.logError("Error running SFXDashboard.", e);
}
}
/**
* Selection in the workbench has been changed. We
* can change the state of the 'real' action here
* if we want, but this can only happen after
* the delegate has been created.
* @see IWorkbenchWindowActionDelegate#selectionChanged
*/
public void selectionChanged(IAction action, ISelection selection) {
}
/**
* We can use this method to dispose of any system
* resources we previously allocated.
* @see IWorkbenchWindowActionDelegate#dispose
*/
public void dispose() {
}
/**
* We will cache window object in order to
* be able to provide parent shell for the message dialog.
* @see IWorkbenchWindowActionDelegate#init
*/
public void init(IWorkbenchWindow window) {
}
}

View File

@@ -0,0 +1,71 @@
package edu.wpi.first.wpilib.plugins.core.actions;
import java.io.File;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
/**
* Our sample action implements workbench action delegate.
* The action proxy will be created by the workbench and
* shown in the UI. When the user tries to use the action,
* this delegate will be created and execution will be
* delegated to it.
* @see IWorkbenchWindowActionDelegate
*/
public class RunSmartDashboardAction implements IWorkbenchWindowActionDelegate {
/**
* The constructor.
*/
public RunSmartDashboardAction() {
}
/**
* The action has been activated. The argument of the
* method represents the 'real' action sitting
* in the workbench UI.
* @see IWorkbenchWindowActionDelegate#run
*/
public void run(IAction action) {
String jarFile = WPILibCore.getDefault().getWPILibBaseDir()+File.separator+"tools"+File.separator
+WPILibCore.getDefault().getCurrentVersion()+File.separator+"SmartDashboard.jar";
String[] cmd = {"java", "-jar", jarFile};
try {
DebugPlugin.exec(cmd, new File(System.getProperty("user.home")));
} catch (CoreException e) {
WPILibCore.logError("Error running SmartDashboard.", e);
}
}
/**
* Selection in the workbench has been changed. We
* can change the state of the 'real' action here
* if we want, but this can only happen after
* the delegate has been created.
* @see IWorkbenchWindowActionDelegate#selectionChanged
*/
public void selectionChanged(IAction action, ISelection selection) {
}
/**
* We can use this method to dispose of any system
* resources we previously allocated.
* @see IWorkbenchWindowActionDelegate#dispose
*/
public void dispose() {
}
/**
* We will cache window object in order to
* be able to provide parent shell for the message dialog.
* @see IWorkbenchWindowActionDelegate#init
*/
public void init(IWorkbenchWindow window) {
}
}

View File

@@ -0,0 +1,83 @@
package edu.wpi.first.wpilib.plugins.core.ant;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Status;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
public class AntPropertiesParser {
List<InputStream> files;
public AntPropertiesParser(List<InputStream> files) {
this.files = files;
}
@SuppressWarnings("serial")
public AntPropertiesParser(final InputStream file) {
this(new ArrayList<InputStream>() {{add(file);}});
}
public Properties getProperties() throws CoreException {
return getProperties(null);
}
public Properties getProperties(Properties defaults) throws CoreException {
Properties props = defaults;
for (int i = files.size()-1; i >= 0; i--) {
props = getPropertyFile(files.get(i), props);
}
return props;
}
public Properties getPropertyFile(InputStream resource, Properties defaults) throws CoreException {
Properties props;
if (defaults == null) props = new Properties();
else props = new Properties(defaults);
try {
props.load(resource);
} catch (IOException e) {
WPILibCore.logError("Error loading property file: "+resource, e);
return null;
}
// TODO: Improve parsing of ant properties
boolean overflow = false;
for (Object key : props.keySet().toArray()) {
int count = 0;
while (props.getProperty((String) key).toString().contains("$") && count < 10) {
Pattern pattern = Pattern.compile( "\\$\\{(.*?)\\}" );
Matcher matcher = pattern.matcher( props.getProperty((String) key).toString() );
StringBuffer sb = new StringBuffer();
while ( matcher.find() ) {
String prop = matcher.group().substring(2, matcher.group().length()-1);
if (props.getProperty(prop) != null) {
matcher.appendReplacement(sb, Matcher.quoteReplacement(props.getProperty(prop)));
} else if (prop.equals("user.home")) {
matcher.appendReplacement(sb, Matcher.quoteReplacement(System.getProperty("user.home")));
} else {
matcher.appendReplacement(sb, Matcher.quoteReplacement(matcher.group()));
}
}
matcher.appendTail( sb );
props.setProperty((String) key, sb.toString());
count++;
}
if (count >= 50) overflow = true;
}
if (overflow) throw new CoreException(new Status(0, "WPI", "Could not parse build.properties file"));
return props;
}
}

View File

@@ -0,0 +1,243 @@
package edu.wpi.first.wpilib.plugins.core.installer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.swing.JOptionPane;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
public abstract class AbstractInstaller {
protected File installLocation;
protected String version;
public AbstractInstaller(String version) {
this.installLocation = new File(WPILibCore.getDefault().getWPILibBaseDir()
+ File.separator + getFeatureName() + File.separator + version);
this.version = version;
}
/**
* @return The name of the feature being installed.
*/
protected abstract String getFeatureName();
/**
* Update the installed version to the latest version.
* @param version The latest version installed.
*/
protected abstract void updateInstalledVersion(String version);
/**
* @return The input stream to the zip file being installed.
*/
protected abstract InputStream getInstallResourceStream();
public void installIfNecessary() {
final Job installJob = new Job("Install " + getFeatureName()) {
@Override
protected IStatus run(IProgressMonitor monitor) {
monitor.beginTask(getTaskMessage(), IProgressMonitor.UNKNOWN);
WPILibCore.logInfo("Installing "+getFeatureName()+" if necessary");
if (!isInstalled()) {
WPILibCore.logInfo("Install necessary");
try {
install();
} catch (InstallException e) {
WPILibCore.logError("Error installing "+getFeatureName(), e);
return new Status(IStatus.ERROR, WPILibCore.PLUGIN_ID,
getErrorMessage(e));
}
}
updateInstalledVersion(version);
WPILibCore.logInfo("Installed");
return Status.OK_STATUS;
}
private String getErrorMessage(InstallException ex) {
String message = "Unable to install " + getFeatureName();
if (ex.getCause() != null) {
message += ": " + ex.getCause().getMessage();
} else if (ex.getMessage() != null) {
message += ": " + ex.getMessage();
}
message += ". See console for details.";
return message;
}
private String getTaskMessage() {
try {
return "Extracting to " + installLocation.getCanonicalPath();
} catch (IOException ex) {
WPILibCore.logError("installIfNecessary().getTaskMessage()", ex);
return "Extracting";
}
}
};
installJob.setUser(true);
installJob.setRule(ResourcesPlugin.getWorkspace().getRuleFactory().buildRule());
installJob.schedule();
}
/**
* This function has been updated to guarantee that the wpilib folder date
* is older than the jar file being run, which ensures up to date tools.
*
* @return True for is there and newer, false otherwise.
*/
protected boolean isInstalled() {
return installLocation.exists();
}
/**
* This function will delete an old wpilib subfolder if necessary and then copy
* the resource stream to the intended directory.
*
* @throws InstallException if bad things happen ...
*/
protected void install() throws InstallException {
if(installLocation.exists()) {
if(!removeFileHandler(installLocation, true)) {
JOptionPane.showMessageDialog(null,
String.format("Could not update the old wpilib folder.%n"
+ "Please close any WPILib tools and restart Eclipse."));
}
else
removeFileHandler(installLocation, false);
}
installLocation.mkdirs();
final String osName = System.getProperty("os.name");
try {
if (osName.startsWith("Mac OS X") || osName.startsWith("Linux")) { // Unix-like OSes must preserve the executable bit; call unzip
final File tmpFile = File.createTempFile(getFeatureName()+"-", ".zip");
try {
// Copy to temporary file
try (final InputStream zip = getInstallResourceStream();
final FileOutputStream fout = new FileOutputStream(tmpFile)) {
copyStreams(zip, fout);
}
// Call 'unzip'
final String[] cmd = {"unzip", tmpFile.getAbsolutePath(), "-d", installLocation.getAbsolutePath()};
WPILibCore.logInfo("unzip "+tmpFile.getAbsolutePath()+" -d "+installLocation.getAbsolutePath());
final Process unzipProcess = DebugPlugin.exec(cmd, installLocation);
try (final InputStream is = unzipProcess.getInputStream()) {
copyStreams(is, System.out); // Copy output to console
}
// Check result
final int exitCode = unzipProcess.waitFor();
if (exitCode > 1 || exitCode < 0) { // Exit code 1 indicates success with warnings
throw new InstallException("Unzip process failed with code " + exitCode);
}
} finally {
tmpFile.delete();
}
} else {
ZipInputStream zip = new ZipInputStream(getInstallResourceStream());
ZipEntry entry = zip.getNextEntry();
while (entry != null) {
WPILibCore.logInfo("\tZipEntry " + entry + ": " + entry.getSize());
File f = new File(installLocation, entry.getName());
if (entry.isDirectory()) {
f.mkdirs();
} else {
FileOutputStream fo = new FileOutputStream(f);
copyStreams(zip, fo);
fo.close();
}
zip.closeEntry();
entry = zip.getNextEntry();
}
zip.close();
}
} catch (IOException | CoreException | InterruptedException ex) {
throw new InstallException("Install encountered a problem", ex);
}
}
private static void copyStreams(InputStream source, OutputStream destination) throws IOException {
byte[] buffer = new byte[1024];
int len;
while((len = source.read(buffer)) >= 0){
destination.write(buffer,0,len);
}
}
/**
* Recursively remove all of the files and folders described by this file handler.
*
* @param file The file to remove
* @param testRun True to just test if the files can be deleted
* @return True if this and all subFiles were removed, false otherwise.
*/
private static boolean removeFileHandler(File file, boolean testRun) {
// if normal files (data files and the like)
if(file.isFile()) {
if(testRun) return file.getParentFile().canWrite();
else return file.delete();
}
// if folders
else if(file.isDirectory()) {
for(File f : file.listFiles()) {
if(!removeFileHandler(f, testRun))
return false;
}
if(testRun) return file.getParentFile().canWrite();
else return file.delete();
}
// I'm not sure what to do if the file is not normal or a directory ...
else return false;
}
/**
* Indicates that an attempt to install a resource failed.
*/
private static class InstallException extends Exception {
private static final long serialVersionUID = 4883122446098399588L;
/**
* @see Exception#Exception()
*/
@SuppressWarnings("unused")
public InstallException() {
super();
}
/**
* @see Exception#Exception(String)
*/
public InstallException(String message) {
super(message);
}
/**
* @see Exception#Exception(String, Throwable)
*/
public InstallException(String message, Throwable cause) {
super(message, cause);
}
}
}

View File

@@ -0,0 +1,38 @@
package edu.wpi.first.wpilib.plugins.core.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.preferences.PreferenceConstants;
public class ToolsInstaller extends AbstractInstaller {
public ToolsInstaller(String version) {
super(version);
}
@Override
protected String getFeatureName() {
return "tools";
}
@Override
protected void updateInstalledVersion(String version) {
IPreferenceStore prefs = WPILibCore.getDefault().getPreferenceStore();
if (prefs.getBoolean(PreferenceConstants.UPDATE_TOOLS_VERSION)) {
WPILibCore.logInfo("Forcing library version to "+version);
Properties props = WPILibCore.getDefault().getProjectProperties(null);
props.setProperty("version", version);
WPILibCore.getDefault().saveGlobalProperties(props);
prefs.setValue(PreferenceConstants.TOOLS_VERSION, version);
}
}
@Override
protected InputStream getInstallResourceStream() {
return ToolsInstaller.class.getResourceAsStream("/resources/tools.zip");
}
}

View File

@@ -0,0 +1,148 @@
package edu.wpi.first.wpilib.plugins.core.launching;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.ant.internal.ui.launchConfigurations.AntLaunchShortcut;
import org.eclipse.ant.launching.IAntLaunchConstants;
import org.eclipse.core.externaltools.internal.IExternalToolConstants;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.IConsoleConstants;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
/**
* Contains functions to launch ant scripts while having the output sent to the
* console. Allows for the use of arguments, the specification of targets, and
* the choice of launch modes
*
* @author Ryan O'Meara
*/
@SuppressWarnings("restriction")
public class AntLauncher {
private static boolean installing = false;
/**
* Runs an ant script's target's with the given arguments, in the given launch mode
* @param antScript A java.io.File representation of the ant file to execute
* @param targets A String of the ant targets to run. For multiple targets,
* format if "target1,target2". For no targets, this argument can be null. This
* method will assume output should be sent to the console, same as calling
* runAntFile(antScript, targets, arguments, mode, true)
* @param arguments A String of arguments to run the file with. Format is
* "-argument1 -argument2". For no arguments, this argument can be null
* @param mode String, either "run" or "debug". If an invalid input is given,
* defaults to "run"
* @return The ILaunch started, or null if it failed to start
*/
public static ILaunch runAntFile(File antScript, String targets, String arguments, String mode){
return runAntFile(antScript, targets, arguments, mode, true);
}
/**
* Runs an ant script's target's with the given arguments, in the given launch mode
* @param antScript A java.io.File representation of the ant file to execute
* @param targets A String of the ant targets to run. For multiple targets,
* format if "target1,target2". For no targets, this argument can be null. Allows
* choice of outputting to the console
* @param arguments A String of arguments to run the file with. Format is
* "-argument1 -argument2". For no arguments, this argument can be null
* @param mode String, either "run" or "debug". If an invalid input is given,
* defaults to "run"
* @param outputToConsole If true, output will be sent to console, if false it will not
* @return The ILaunch started, or null if it failed to start
*/
public static ILaunch runAntFile(File antScript, String targets, String arguments, String mode, boolean outputToConsole){
//Input error checking
if((mode == null)||(!mode.equalsIgnoreCase(ILaunchManager.DEBUG_MODE))){mode = ILaunchManager.RUN_MODE;} //Launcher only accepts run or debug
if((targets != null)&&(targets.equalsIgnoreCase(""))){targets = null;} //Standardize representation of "none"
if((arguments != null)&&(arguments.equalsIgnoreCase(""))){arguments = null;}
if(antScript.getAbsolutePath().indexOf("install.xml") != -1){
installing = true;
}else{
installing = false;
}
ILaunch ret = null;
try{
//Show the console
if(outputToConsole){
try{
final IWorkbenchPage activePage = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow()
.getActivePage();
activePage.showView(IConsoleConstants.ID_CONSOLE_VIEW);
}catch(Exception e){}
}
//Get an ant launch config setup to use eclipse VM - which users will setup to be the jdk,
//allowing the use of javac. Also sets the location of the file to execute
ILaunchConfiguration launcher = AntLaunchShortcut.createDefaultLaunchConfiguration(new Path(antScript.getAbsolutePath()), null);
//Get copy that can be edited
ILaunchConfigurationWorkingCopy workingCopy = launcher.getWorkingCopy();
//Prevent this configuration from appearing in history or dialogs
workingCopy.setAttribute(ILaunchManager.ATTR_PRIVATE, false);
//Setup to show output on console
if(outputToConsole){
workingCopy.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, true);
workingCopy.setAttribute(IExternalToolConstants.ATTR_SHOW_CONSOLE, true);
}else{
workingCopy.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, false);
workingCopy.setAttribute(IExternalToolConstants.ATTR_SHOW_CONSOLE, false);
}
workingCopy.setAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, true);
if(targets != null){
workingCopy.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, targets);
}
if(arguments != null){
workingCopy.setAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, arguments);
}
if(mode.equals(ILaunchManager.DEBUG_MODE)){
Set<String> modes = new HashSet<String>();
modes.add(ILaunchManager.DEBUG_MODE);
workingCopy.addModes(modes);
}
//Save/assert all changes
launcher = workingCopy.doSave();
//Launch the modified configuration in the specified mode
try {
ret = launcher.launch(mode, null, true, true);
} catch(Exception e) {
//Does not need Output, handled and resolved internally
WPILibCore.logError("Error running launch.", e);
return null;
}
} catch(Exception e) {
WPILibCore.logError("Error running ant file", e);
return null;
}
return ret;
}
public static boolean isInstalling(){
return installing;
}
}

View File

@@ -0,0 +1,97 @@
package edu.wpi.first.wpilib.plugins.core.nature;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
/**
* Project nature which configures any project which is given it to be an
* FRC Project, and designates it so FRC options will be enabled to act on
* it
*
*/
public class FRCProjectNature implements IProjectNature {
public static final String FRC_PROJECT_NATURE =
"edu.wpi.first.wpilib.plugins.core.nature.FRCProjectNature";
private IProject internalProject;
/**
* IStatus representing a failed configuration attempt
*
* @author Ryan O'Meara
*/
private class FRCProjectFailedStatus implements IStatus{
String message;
public FRCProjectFailedStatus(String message){
this.message = message;
}
@Override
public IStatus[] getChildren() {return null;}
@Override
public int getCode() {return 0;}
@Override
public Throwable getException() {return null;}
@Override
public String getMessage() {return message;}
@Override
public String getPlugin() {return WPILibCore.PLUGIN_ID;}
@Override
public int getSeverity() {return ERROR;}
@Override
public boolean isMultiStatus() {return false;}
@Override
public boolean isOK() {return false;}
@Override
public boolean matches(int severityMask) {
if((severityMask & ERROR) == ERROR){return true;}
return false;
}
}
public FRCProjectNature(){
internalProject = null;
}
@Override
public void configure() throws CoreException {
if(internalProject == null){
throw new CoreException(
new FRCProjectFailedStatus("No project set"));
}
}
@Override
public void deconfigure() throws CoreException {
if(internalProject == null){
throw new CoreException(
new FRCProjectFailedStatus("No project set"));
}
}
@Override
public IProject getProject() {
return internalProject;
}
@Override
public void setProject(IProject project) {
internalProject = project;
}
}

View File

@@ -0,0 +1,69 @@
package edu.wpi.first.wpilib.plugins.core.preferences;
import java.util.List;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
public class ComboFieldEditor extends FieldEditor {
private List<String> choices;
private Composite parent;
Combo comboDropDown;
public ComboFieldEditor(String preference, String label, Composite parent, List<String> choices) {
super(preference, label, parent);
this.choices = choices;
for (String choice : choices) {
comboDropDown.add(choice);
}
}
public void setChoice(String item) {
comboDropDown.select(choices.indexOf(item));
}
public String getChoice() {
return choices.get(comboDropDown.getSelectionIndex());
}
@Override protected void adjustForNumColumns(int numColumns) {
((GridData) parent.getLayoutData()).horizontalSpan = numColumns;
}
@Override protected void doFillIntoGrid(Composite parent, int numColumns) {
this.parent = parent;
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = numColumns;
parent.setLayoutData(gd);
Label label = getLabelControl(parent);
label.setText(getLabelText());
comboDropDown = new Combo(parent, SWT.DROP_DOWN | SWT.BORDER);
gd = new GridData(GridData.FILL_HORIZONTAL);
comboDropDown.setLayoutData(gd);
}
@Override protected void doLoad() {
String item = getPreferenceStore().getString(getPreferenceName());
setChoice(item);
}
@Override protected void doLoadDefault() {
String item = getPreferenceStore().getDefaultString(getPreferenceName());
setChoice(item);
}
@Override protected void doStore() {
getPreferenceStore().setValue(getPreferenceName(), getChoice());
}
@Override public int getNumberOfControls() {
return 2;
}
}

View File

@@ -0,0 +1,10 @@
package edu.wpi.first.wpilib.plugins.core.preferences;
/**
* Constant definitions for plug-in preferences
*/
public class PreferenceConstants {
public static final String TEAM_NUMBER = "teamNumberPreference";
public static final String TOOLS_VERSION = "toolsVersionPreference";
public static final String UPDATE_TOOLS_VERSION = "udpateToolsVersionPreference";
}

View File

@@ -0,0 +1,25 @@
package edu.wpi.first.wpilib.plugins.core.preferences;
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
import org.eclipse.jface.preference.IPreferenceStore;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
/**
* 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 = WPILibCore.getDefault().getPreferenceStore();
store.setDefault(PreferenceConstants.TEAM_NUMBER,
WPILibCore.getDefault().getProjectProperties(null).getProperty("team-number", "0"));
store.setDefault(PreferenceConstants.TOOLS_VERSION, WPILibCore.getDefault().getDefaultVersion());
store.setDefault(PreferenceConstants.UPDATE_TOOLS_VERSION, true);
}
}

View File

@@ -0,0 +1,98 @@
package edu.wpi.first.wpilib.plugins.core.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.jface.preference.IntegerFieldEditor;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
/**
* 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 WPILibPreferencePage
extends FieldEditorPreferencePage
implements IWorkbenchPreferencePage {
IntegerFieldEditor teamNumberEditor;
private ComboFieldEditor toolsVersionEditor;
private BooleanFieldEditor autoUpdateEditor;
public WPILibPreferencePage() {
super(GRID);
setPreferenceStore(WPILibCore.getDefault().getPreferenceStore());
setDescription("A preference page for changing all workspace level settings.");
}
/**
* 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() {
teamNumberEditor = new IntegerFieldEditor(PreferenceConstants.TEAM_NUMBER,
"&Team Number:", getFieldEditorParent());
addField(teamNumberEditor);
toolsVersionEditor = new ComboFieldEditor(PreferenceConstants.TOOLS_VERSION,
"&Tools Version:", getFieldEditorParent(), getInstalledVersions());
addField(toolsVersionEditor);
autoUpdateEditor = new BooleanFieldEditor(PreferenceConstants.UPDATE_TOOLS_VERSION,
"&Auto Update Tools Version", getFieldEditorParent());
addField(autoUpdateEditor);
}
private List<String> getInstalledVersions() {
File[] dirs = new File(WPILibCore.getDefault().getWPILibBaseDir()+File.separator+"tools")
.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) {
WPILibCore.logInfo("Preferences initialized.");
Properties props = WPILibCore.getDefault().getProjectProperties(null);
getPreferenceStore().setValue(PreferenceConstants.TEAM_NUMBER,
Integer.parseInt(props.getProperty("team-number", "0")));
}
@Override public void performApply() {
performOk();
}
@Override public boolean performOk() {
Properties props = WPILibCore.getDefault().getProjectProperties(null);
props.setProperty("team-number", teamNumberEditor.getStringValue());
WPILibCore.getDefault().saveGlobalProperties(props);
return super.performOk();
}
}

View File

@@ -0,0 +1,90 @@
package edu.wpi.first.wpilib.plugins.core.wizards;
import java.net.URL;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizardPage;
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;
public abstract class ExampleWizard extends Wizard implements INewWizard {
private ExampleWizardChoicePage page1;
private IWizardPage page2;
protected ISelection selection;
private TeamNumberPage teamNumberPage;
/**
* Constructor for SampleNewWizard.
*/
public ExampleWizard() {
super();
setNeedsProgressMonitor(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.
*/
protected abstract void doFinish(IExampleProject ex, String teamNumber) throws CoreException;
protected abstract IWizardPage getDetailsPage();
public abstract IExampleProject makeExampleProject(String name, String description,
List<String> tags, List<String> folders, List<IExampleProject.ExportFile> files);
public abstract URL getResourceURL();
public abstract String getXMLFile();
protected TeamNumberPage getTeamNumberPage() {
return teamNumberPage;
}
/**
* Adding the page to the wizard.
*/
public void addPages() {
if (TeamNumberPage.needsTeamNumberPage()) {
teamNumberPage = new TeamNumberPage(selection);
addPage(teamNumberPage);
}
page1 = new ExampleWizardChoicePage(this, selection);
addPage(page1);
page2 = getDetailsPage();
addPage(page2);
}
/**
* 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() {
try {
doFinish(page1.getExampleProject(), TeamNumberPage.getTeamNumberFromPage(teamNumberPage));
} catch (CoreException e) {
WPILibCore.logError("Error finishing example.", e);
MessageDialog.openError(getShell(), "Error", e.getMessage());
return false;
}
return true;
}
/**
* 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,240 @@
package edu.wpi.first.wpilib.plugins.core.wizards;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
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.browser.Browser;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
/**
* 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 ExampleWizardChoicePage extends WizardPage {
private Tree exampleTree;
private Browser descriptionText;
private IExampleProject selectedExample;
private ExampleWizard parent;
/**
* Constructor for SampleNewWizardPage.
*
* @param pageName
*/
public ExampleWizardChoicePage(ExampleWizard parent, ISelection selection) {
super("wizardPage");
this.parent = parent;
setTitle("Select Example Project to Create");
setDescription("This wizard creates a new example project based on your selection.");
}
/**
* @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;
exampleTree = new Tree(container, SWT.BORDER);
GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
gd.heightHint = 400;
exampleTree.setLayoutData(gd);
exampleTree.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent arg0) {
dialogChanged();
}
@Override
public void widgetDefaultSelected(SelectionEvent arg0) {
dialogChanged();
}
});
descriptionText = new Browser(container, SWT.BORDER);
gd = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
gd.heightHint = 400;
gd.widthHint = 300;
descriptionText.setLayoutData(gd);
initialize();
dialogChanged();
setControl(container);
}
/**
* Tests if the current workbench selection is a suitable container to use.
*/
private void initialize() {
Document doc = loadXMLResource(parent.getXMLFile());
// Generate all of the tags
List<Tag> tags = new ArrayList<Tag>();
NodeList nList = doc.getElementsByTagName("tagDescription");
for (int i = 0; i < nList.getLength(); i++) {
if (nList.item(i).getNodeType() == Node.ELEMENT_NODE) {
tags.add(generateTagFromElement((Element) nList.item(i)));
}
}
// Generate all of the example projects
List<IExampleProject> examples = new ArrayList<IExampleProject>();
nList = doc.getElementsByTagName("example");
for (int i = 0; i < nList.getLength(); i++) {
if (nList.item(i).getNodeType() == Node.ELEMENT_NODE) {
examples.add(generateExampleFromElement((Element) nList.item(i)));
}
}
WPILibCore.logInfo(examples.toString());
WPILibCore.logInfo(tags.toString());
// Generate the tags tree
for (Tag tag : tags) {
TreeItem tagItem = new TreeItem(exampleTree, SWT.NONE);
tagItem.setData(tag);
tagItem.setText(tag.getName());
for (IExampleProject ex : examples) {
if (ex.getTags().contains(tag.getName())) {
TreeItem exItem = new TreeItem(tagItem, SWT.NONE);
exItem.setData(ex);
exItem.setText(ex.getName());
}
}
tagItem.setExpanded(true);
}
}
/**
* Ensures that both text fields are set.
*/
private void dialogChanged() {
if (exampleTree.getSelection().length > 0) {
Object selectedData = exampleTree.getSelection()[0].getData();
if (selectedData instanceof IExampleProject) {
IExampleProject example = (IExampleProject) selectedData;
descriptionText.setText(example.getContent());
selectedExample = example;
} else if (selectedData instanceof Tag) {
Tag tag = (Tag) selectedData;
descriptionText.setText(tag.getContent());
selectedExample = null;
} else selectedExample = null;
}
if (selectedExample == null) {
updateStatus("Must select a valid example before continuing.");
return;
}
updateStatus(null);
}
private void updateStatus(String message) {
setErrorMessage(message);
setPageComplete(message == null);
}
private Document loadXMLResource(String filename) {
final URL installURL = parent.getResourceURL();
URL url = null;
try {
url = new URL(installURL, filename);
} catch (final MalformedURLException e) {
WPILibCore.logError("loadXMLResource()", e);
return null;
}
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
Document doc;
try {
dBuilder = dbFactory.newDocumentBuilder();
doc = dBuilder.parse(url.openStream());
} catch (ParserConfigurationException e) {
WPILibCore.logError("Error parsing "+filename, e);
return null;
} catch (SAXException e) {
WPILibCore.logError("SAX issue with "+filename, e);
return null;
} catch (IOException e) {
WPILibCore.logError("Error reading "+filename, e);
return null;
}
doc.getDocumentElement().normalize();
return doc;
}
private Tag generateTagFromElement(Element element) {
String name = element.getElementsByTagName("name").item(0).getTextContent();
String description = element.getElementsByTagName("description").item(0).getTextContent();
return new Tag(name, description);
}
private IExampleProject generateExampleFromElement(Element element) {
String name = element.getElementsByTagName("name").item(0).getTextContent();
String description = element.getElementsByTagName("description").item(0).getTextContent();
List<String> tags = new ArrayList<String>();
Node tagsElement = element.getElementsByTagName("tags").item(0);
if (tagsElement.getNodeType() == Node.ELEMENT_NODE) {
NodeList tagElementList = ((Element) tagsElement).getElementsByTagName("tag");
for (int i = 0; i < tagElementList.getLength(); i++) {
tags.add(tagElementList.item(i).getTextContent());
}
}
List<String> packages = new ArrayList<String>();
tagsElement = element.getElementsByTagName("packages").item(0);
if (tagsElement.getNodeType() == Node.ELEMENT_NODE) {
NodeList elementList = ((Element) tagsElement).getElementsByTagName("package");
for (int i = 0; i < elementList.getLength(); i++) {
packages.add(elementList.item(i).getTextContent());
}
}
List<IExampleProject.ExportFile> files = new ArrayList<IExampleProject.ExportFile>();
tagsElement = element.getElementsByTagName("files").item(0);
if (tagsElement.getNodeType() == Node.ELEMENT_NODE) {
NodeList elementList = ((Element) tagsElement).getElementsByTagName("file");
for (int i = 0; i < elementList.getLength(); i++) {
if (elementList.item(i).getNodeType() == Node.ELEMENT_NODE) {
element = (Element) elementList.item(i);
files.add(new IExampleProject.ExportFile(element.getAttribute("source"),
element.getAttribute("destination")));
}
}
}
return parent.makeExampleProject(name, description, tags, packages, files);
}
public IExampleProject getExampleProject() {
return selectedExample;
}
}

View File

@@ -0,0 +1,17 @@
package edu.wpi.first.wpilib.plugins.core.wizards;
import java.util.List;
public interface IExampleProject extends ProjectType {
public String getName();
public String getContent();
public List<String> getTags();
static class ExportFile {
public String source, destination;
public ExportFile(String source, String destination) {
this.source = source;
this.destination = destination;
}
}
}

View File

@@ -0,0 +1,60 @@
package edu.wpi.first.wpilib.plugins.core.wizards;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
/**
* An interface for providing hooks into the project creation
* process. It provides necessary information and can perform
* both initialization and finalization of the project
* creation process.
*
* @author Alex Henning
*/
public interface IProjectCreator {
/**
* @return The name of the project to create.
*/
String getName();
/**
* @return The main package to be created. Should be an
* empty string if irrelevant.
*/
String getPackageName();
/**
* @return Map of keys to be substituted with values
* during the creation process.
*/
Map<String, String> getValues();
/**
* @return The natures that this project should have.
*/
List<String> getNatures();
/**
* @return A project type object that provides files
* and directories to create.
*/
ProjectType getProjectType();
/**
* Run extra initialization code on the project.
* @param project The project being created
* @throws CoreException
*/
void initialize(IProject project) throws CoreException;
/**
* Run extra finalization code on the project.
* @param project The project being created
* @throws CoreException
*/
void finalize(IProject project) throws CoreException;
}

View File

@@ -0,0 +1,17 @@
package edu.wpi.first.wpilib.plugins.core.wizards;
import org.eclipse.core.resources.IProject;
/**
* A filter that can be used to select projects.
*
* @author alex
*
*/
public interface IProjectFilter {
/**
* @param project The project to check.
* @return Whether or to accept the project.
*/
boolean accept(IProject project);
}

View File

@@ -0,0 +1,236 @@
package edu.wpi.first.wpilib.plugins.core.wizards;
import java.util.Map;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
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.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
/**
* 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 NewProjectMainPage extends WizardPage {
private Text projectNameText;
private Text packageText;
Map<String, ProjectType> types;
private Text worldText;
private Button worldButton;
Button iterativeRobot, commandRobot;
private boolean showPackage;
private boolean showProjectTypes;
private TeamNumberPage teamNumberPage;
/**
* Constructor for SampleNewWizardPage.
* @param teamNumberPage
*
* @param pageName
*/
public NewProjectMainPage(ISelection selection, TeamNumberPage teamNumberPage) {
super("wizardPage");
this.teamNumberPage = teamNumberPage;
showPackage = true;
showProjectTypes = false;
}
/**
* @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("Project &Name:");
projectNameText = new Text(container, SWT.BORDER | SWT.SINGLE);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
projectNameText.setLayoutData(gd);
projectNameText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
dialogChanged();
}
});
if (showPackage) {
label = new Label(container, SWT.NULL);
label.setText("&Package:");
packageText = new Text(container, SWT.BORDER | SWT.SINGLE);
gd = new GridData(GridData.FILL_HORIZONTAL);
packageText.setLayoutData(gd);
packageText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
dialogChanged();
}
});
}
if (showProjectTypes) {
Group projectTypeGroup = new Group(container, SWT.BORDER);
projectTypeGroup.setText("Project Type");
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
projectTypeGroup.setLayoutData(gd);
GridLayout groupLayout = new GridLayout();
groupLayout.numColumns = 1;
projectTypeGroup.setLayout(groupLayout);
iterativeRobot = new Button(projectTypeGroup, SWT.RADIO | SWT.WRAP);
iterativeRobot.setText("Iterative Robot: A robot project that allows robots to be implemented in an iterative manner.");
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.widthHint = 300;
iterativeRobot.setLayoutData(gd);
commandRobot = new Button(projectTypeGroup, SWT.RADIO | SWT.WRAP);
commandRobot.setText("Command-Based Robot: A robot project that allows robots to be implemented using the command based model to allow complex functionality to be developed from simpler functionality.");
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.widthHint = 300;
commandRobot.setLayoutData(gd);
}
label = new Label(container, SWT.NULL);
label.setText("Simulation &World:");
Composite comp = new Composite(container, SWT.NULL);
gd = new GridData(GridData.FILL_HORIZONTAL);
comp.setLayoutData(gd);
GridLayout groupLayout = new GridLayout();
groupLayout.numColumns = 2;
comp.setLayout(groupLayout);
worldText = new Text(comp, SWT.BORDER | SWT.SINGLE);
worldText.setLayoutData(gd);
worldText.setText("/usr/share/frcsim/worlds/GearsBotDemo.world");
worldText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
dialogChanged();
}
});
worldButton = new Button(comp, SWT.NULL);
worldButton.setText("Browse");
worldButton.addSelectionListener(new SelectionAdapter() {
@Override public void widgetSelected(SelectionEvent e) {
browse();
}
});
initialize();
dialogChanged();
setControl(container);
}
/**
* Tests if the current workbench selection is a suitable container to use.
*/
private void initialize() {
String teamNumber = TeamNumberPage.getTeamNumberFromPage(teamNumberPage);
if (showPackage) {
packageText.setText("org.usfirst.frc.team"+teamNumber+".robot");
if (teamNumberPage != null) {
teamNumberPage.registerChangeListener(new ChangeListener() {
@Override public void stateChanged(ChangeEvent e) {
String teamNumber = TeamNumberPage.getTeamNumberFromPage(teamNumberPage);
packageText.setText("org.usfirst.frc.team"+teamNumber+".robot");
}
});
}
}
}
/**
* Ensures that both text fields are set.
*/
private void dialogChanged() {
String projectName = getProjectName();
String packageString = "";
if (showPackage) packageString = getPackage();
if (projectName.length() == 0) {
updateStatus("Project name must be specified");
return;
}
if (showPackage && packageString.length() == 0) {
updateStatus("Package must be specified");
return;
}
if (showPackage && !packageString.matches("^([a-zA-Z_]{1}[a-zA-Z0-9_]*(\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*)*)$")) {
updateStatus("Must be valid java package");
return;
}
updateStatus(null);
}
private void browse() {
FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
dialog.setText("Pick a World to Simulate");
dialog.setFileName(worldText.getText());
dialog.setFilterNames(new String[] { "World Files", "All Files (*.*)" });
dialog.setFilterExtensions(new String[] { "*.world", "*.*" });
String result = dialog.open();
if (result != null) {
worldText.setText(result);
}
}
private void updateStatus(String message) {
setErrorMessage(message);
setPageComplete(message == null);
}
public String getProjectName() {
return projectNameText.getText();
}
public String getPackage() {
return packageText.getText();
}
public ProjectType getProjectType() {
if (!showProjectTypes) return null;
else if (iterativeRobot.getSelection()) return types.get(ProjectType.ITERATIVE);
else return types.get(ProjectType.COMMAND_BASED);
}
public String getWorld() {
return worldText.getText().replace(System.getProperty("user.home"), "${user.home}");
}
public void setShowPackage(boolean bool) {
showPackage = bool;
}
public void setShowProjectTypes(boolean bool) {
showProjectTypes = bool;
}
public void setProjectTypes(Map<String, ProjectType> types) {
showProjectTypes = true;
this.types = types;
}
}

View File

@@ -0,0 +1,51 @@
package edu.wpi.first.wpilib.plugins.core.wizards;
import java.util.Arrays;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
public class ProjectComboField {
public static String NO_PROJECT = "No Project";
private Combo combo;
public ProjectComboField(Composite composite, int config, IProjectFilter filter) {
combo = new Combo(composite, config);
combo.add(NO_PROJECT);
combo.select(0);
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
for (IProject project : projects) {
if (filter == null || filter.accept(project))
combo.add(project.getName());
}
}
public void setProject(IProject project) {
if (project != null)
combo.select(Arrays.binarySearch(combo.getItems(), project.getName()));
else combo.select(0);
}
public IProject getProject() {
return ResourcesPlugin.getWorkspace().getRoot().getProject(combo.getItem(combo.getSelectionIndex()));
}
public boolean isValid() {
return combo.getSelectionIndex() != 0;
}
public void setLayoutData(GridData gd) {
combo.setLayoutData(gd);
}
public void addModifyListener(ModifyListener modifyListener) {
combo.addModifyListener(modifyListener);
}
}

View File

@@ -0,0 +1,195 @@
package edu.wpi.first.wpilib.plugins.core.wizards;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
/**
* Utilities for creating a new project and files from templates. Uses
* IProjectCreator to provide hooks for generating the directory
* structure, initial files, initializing and finalizing the creation
* of the new project.
*
* @author Alex Henning
**/
public class ProjectCreationUtils {
/**
* Create a project using the given IProjectCreator.
*
* @param creator The creator that provides the necessary information
* to create the project.
* @return The newly created project.
*/
public static IProject createProject(IProjectCreator creator) {
IProject project = createBaseProject(creator.getName(), null);
try {
creator.initialize(project);
for (String nature : creator.getNatures()) {
addNature(project, nature);
}
addToProjectStructure(project, creator);
addFilesToProject(project, creator);
creator.finalize(project);
} catch (CoreException e) {
WPILibCore.logError("Error creating project "+creator.getName(), e);
project = null;
}
return project;
}
private static IProject createBaseProject(String projectName, IPath location) {
IProject newProject = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
if (!newProject.exists()) {
IPath projectLocation = location;
IProjectDescription desc = newProject.getWorkspace().newProjectDescription(newProject.getName());
if (location != null &&
ResourcesPlugin.getWorkspace().getRoot().getLocation().equals(location)) {
projectLocation = null;
}
desc.setLocation(projectLocation);
try {
newProject.create(desc, null);
if (!newProject.isOpen()) {
newProject.open(null);
}
} catch (CoreException e) {
WPILibCore.logError("Can't create new project.", e);
}
}
return newProject;
}
private static void addNature(IProject project, String nature_id) throws CoreException {
if (!project.hasNature(nature_id)) {
IProjectDescription desc = project.getDescription();
String[] prevNatures = desc.getNatureIds();
String[] newNatures = new String[prevNatures.length + 1];
System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
newNatures[prevNatures.length] = nature_id;
desc.setNatureIds(newNatures);
project.setDescription(desc, null);
}
}
private static void addToProjectStructure(IProject project, IProjectCreator creator) throws CoreException {
String[] paths = creator.getProjectType().getFolders(creator.getPackageName());
for (String path : paths) {
IFolder etcFolders = project.getFolder(path);
createFolder(etcFolders);
}
}
private static void createFolder(IFolder folder) throws CoreException {
IContainer parent = folder.getParent();
if (parent instanceof IFolder) {
createFolder((IFolder) parent);
}
if (!folder.exists()) {
folder.create(false, true, null);
}
folder.refreshLocal(IResource.DEPTH_INFINITE, null);
}
private static void addFilesToProject(IProject project, IProjectCreator creator) throws CoreException {
Map<String, String> files = creator.getProjectType().getFiles(creator.getPackageName());
for (Entry<String, String> e : files.entrySet()) {
try {
URL url = new URL(creator.getProjectType().getBaseURL(), e.getValue());
createTemplateFile(project, e.getKey(), url, creator.getValues());
} catch (MalformedURLException e1) {
WPILibCore.logError("Error adding file "+e.toString()+" to project.", e1);
}
}
}
/**
* Create a file in the project from a template. Substituting as required.
*
* @param project The project to use create the file in.
* @param filepath The path of the created file.
* @param filesource The source of the template to use.
* @param vals The map of values to use for substitution.
* @throws CoreException
*/
public static void createTemplateFile(IProject project, String filepath, URL url, Map<String, String> vals) throws CoreException {
IFile template = project.getFile(new Path(filepath));
if (!template.exists()) {
InputStream in = openTemplateContentStream(project, url, vals);
template.create(in, true, null);
}
}
private static InputStream openTemplateContentStream(IProject project, URL url, Map<String, String> vals) {
//http://eclipse-javacc.cvs.sourceforge.net/viewvc/eclipse-javacc/sf.eclipse.javacc/src-plugin/sf/eclipse/javacc/wizards/JJNewWizard.java?view=markup
//eclipse plugin distributing template files
try {
return makeTemplateInputStream(url.openStream(), vals);
} catch (final MalformedURLException e) {
WPILibCore.logError("Malformed URL "+url, e);
} catch (final IOException e) {
WPILibCore.logError("Issue opening input stream.", e);
}
return null;
}
private static InputStream makeTemplateInputStream(InputStream stream, Map<String, String> vals) {
String str;
try {
str = readInput(stream);
stream.close();
} catch (final IOException e) {
WPILibCore.logError("Error reading template.", e);
return null;
}
// Instantiate template
for (Entry<String, String> e : vals.entrySet())
str = str.replace(e.getKey(), e.getValue());
return new ByteArrayInputStream(str.getBytes());
}
private static String readInput(InputStream stream) {
StringBuffer buffer = new StringBuffer();
try {
InputStreamReader isr = new InputStreamReader(stream);
Reader in = new BufferedReader(isr);
int ch;
while ((ch = in.read()) > -1) {
buffer.append((char)ch);
}
in.close();
return buffer.toString();
} catch (IOException e) {
WPILibCore.logError("Error reading input.", e);
return null;
}
}
}

View File

@@ -0,0 +1,14 @@
package edu.wpi.first.wpilib.plugins.core.wizards;
import java.net.URL;
import java.util.Map;
public interface ProjectType {
String SIMPLE = "SIMPLE";
String ITERATIVE = "ITERATIVE";
String COMMAND_BASED = "COMMAND_BASED";
String[] getFolders(String packageName);
Map<String, String> getFiles(String packageName);
URL getBaseURL();
}

View File

@@ -0,0 +1,19 @@
package edu.wpi.first.wpilib.plugins.core.wizards;
public class Tag {
private String name, description;
public Tag(String name, String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public String getContent() {
return "<h1>"+name+"</h1><p>"+description+"</p>";
}
}

View File

@@ -0,0 +1,111 @@
package edu.wpi.first.wpilib.plugins.core.wizards;
import javax.swing.event.ChangeListener;
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.WPILibCore;
public class TeamNumberPage extends WizardPage {
private Text teamNumberText;
private ChangeListener listener;
/**
* Constructor for SampleNewWizardPage.
*
* @param pageName
*/
public TeamNumberPage(ISelection selection) {
super("wizardPage");
setTitle("Set Team Number");
setDescription("This page lets you set your team number so that code can be loaded onto the right robot.");
}
/**
* @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("Team &Number:");
teamNumberText = new Text(container, SWT.BORDER | SWT.SINGLE);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
teamNumberText.setLayoutData(gd);
teamNumberText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
dialogChanged();
}
});
label = new Label(container, SWT.NULL);
label.setText("Team number is a global setting that can be changed in Window > Preferences > WPILib Preferences > Team Number");
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
label.setLayoutData(gd);
initialize();
dialogChanged();
setControl(container);
}
/**
* Tests if the current workbench selection is a suitable container to use.
*/
private void initialize() {
String teamNumber = Integer.toString(WPILibCore.getDefault().getTeamNumber(null));
teamNumberText.setText(teamNumber);
}
/**
* Ensures that both text fields are set.
*/
private void dialogChanged() {
String teamNumber = getTeamNumber();
if (listener != null) listener.stateChanged(null);
if (!teamNumber.matches("^([0-9]+)$")) {
updateStatus("Team number must be a valid integer.");
return;
}
updateStatus(null);
}
private void updateStatus(String message) {
setErrorMessage(message);
setPageComplete(message == null);
}
public String getTeamNumber() {
return teamNumberText.getText();
}
public static boolean needsTeamNumberPage() {
return WPILibCore.getDefault().getTeamNumber(null) == 0;
}
public static String getTeamNumberFromPage(TeamNumberPage teamNumberPage) {
if (teamNumberPage != null) {
return teamNumberPage.getTeamNumber();
} else {
return Integer.toString(WPILibCore.getDefault().getTeamNumber(null));
}
}
public void registerChangeListener(ChangeListener changeListener) {
listener = changeListener;
}
}

View File

@@ -0,0 +1 @@
bin.includes = feature.xml

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="edu.wpi.first.wpilib.plugins.cpp.feature"
label="Robot C++ Development"
version="0.1.0.qualifier"
provider-name="Worcester Polytechnic Institute">
<description>
FRC Robot C++ Program Development Environment.
</description>
<copyright>
* Copyright (c) 2013 FIRST and WPI
* All rights reserved.
</copyright>
<license>
* Copyright (c) 2013 FIRST and WPI
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer. Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution. Neither the name of the FIRST nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS&apos;&apos;
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</license>
<url>
<discovery label="CDT" url="http://download.eclipse.org/tools/cdt/releases/juno/"/>
<discovery label="RSE" url="http://download.eclipse.org/tm/updates/2.0/"/>
</url>
<includes
id="edu.wpi.first.wpilib.plugins.core.feature"
version="0.0.0"/>
<plugin
id="edu.wpi.first.wpilib.plugins.cpp"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>edu.wpi.first.wpilib.plugins.cpp.feature</artifactId>
<packaging>eclipse-feature</packaging>
<parent>
<groupId>edu.wpi.first.wpilib.plugins</groupId>
<artifactId>edu.wpi.first.wpilib.plugins</artifactId>
<version>0.1.0.qualifier</version>
<relativePath>..</relativePath>
</parent>
</project>

View File

@@ -0,0 +1 @@
bin.includes = feature.xml

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="edu.wpi.first.wpilib.plugins.cpp.toolchains.linux.feature"
label="Linux Toolchain for Robot C++ Development"
version="0.2.0"
provider-name="Worcester Polytechnic Institute"
os="linux">
<description>
The C++ toolchain to build Athena programs on Linux.
</description>
<copyright>
* Copyright (c) 2013 FIRST and WPI
* All rights reserved.
</copyright>
<license>
* Copyright (c) 2013 FIRST and WPI
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer. Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution. Neither the name of the FIRST nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS&apos;&apos;
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</license>
<requires>
<import feature="edu.wpi.first.wpilib.plugins.cpp.feature" version="0.1.0.qualifier"/>
</requires>
<plugin
id="edu.wpi.first.wpilib.plugins.cpp.toolchains.linux"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>edu.wpi.first.wpilib.plugins.cpp.toolchains.linux.feature</artifactId>
<version>0.2.0</version>
<packaging>eclipse-feature</packaging>
<parent>
<groupId>edu.wpi.first.wpilib.plugins</groupId>
<artifactId>edu.wpi.first.wpilib.plugins</artifactId>
<version>0.1.0.qualifier</version>
<relativePath>..</relativePath>
</parent>
</project>

View File

@@ -0,0 +1,12 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Linux
Bundle-SymbolicName: edu.wpi.first.wpilib.plugins.cpp.toolchains.linux;singleton:=true
Bundle-Version: 0.2.0
Bundle-Activator: edu.wpi.first.wpilib.plugins.cpp.toolchains.linux.Activator
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
edu.wpi.first.wpilib.plugins.core;bundle-version="0.1.0",
edu.wpi.first.wpilib.plugins.cpp;bundle-version="0.1.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.7

View File

@@ -0,0 +1,8 @@
Making This Plugin Work
=======================
This plugin needs a very big zip that contains the toolchain. This is
currently hosted by Jenkins in the "Windows Toolchain Provider"
project. This can also be created from the download from mentor
embedded. The file should be resources/toolchain.zip and contains the
5 main directories.

View File

@@ -0,0 +1,7 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
resources/,\
plugin.xml
src.includes = resources/

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
point="org.eclipse.ui.startup">
<startup
class="edu.wpi.first.wpilib.plugins.cpp.toolchains.linux.Activator">
</startup>
</extension>
</plugin>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>edu.wpi.first.wpilib.plugins.cpp.toolchains.linux</artifactId>
<version>0.2.0</version>
<packaging>eclipse-plugin</packaging>
<parent>
<groupId>edu.wpi.first.wpilib.plugins</groupId>
<artifactId>edu.wpi.first.wpilib.plugins</artifactId>
<version>0.1.0.qualifier</version>
<relativePath>..</relativePath>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy</id>
<phase>prepare-package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>edu.wpi.first.wpilib.plugins.cpp.toolchains</groupId>
<artifactId>linux</artifactId>
<version>1.0.0</version>
<type>zip</type>
<destFileName>toolchain.zip</destFileName>
</artifactItem>
</artifactItems>
<overWriteIfNewer>true</overWriteIfNewer>
<outputDirectory>${project.build.outputDirectory}/resources</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,62 @@
package edu.wpi.first.wpilib.plugins.cpp.toolchains.linux;
import org.eclipse.ui.IStartup;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import edu.wpi.first.wpilib.plugins.cpp.WPILibCPPPlugin;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin implements IStartup {
// The plug-in ID
public static final String PLUGIN_ID = "edu.wpi.first.wpilib.plugins.cpp.toolchains.windows"; //$NON-NLS-1$
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
}
/*
* (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;
}
private String getCurrentVersion() {
return WPILibCPPPlugin.getDefault().getDefaultToolchainVersion();
}
/*
* (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 Activator getDefault() {
return plugin;
}
@Override
public void earlyStartup() {
new ToolchainInstaller(getCurrentVersion()).installIfNecessary();
}
}

View File

@@ -0,0 +1,36 @@
package edu.wpi.first.wpilib.plugins.cpp.toolchains.linux;
import java.io.InputStream;
import org.eclipse.jface.preference.IPreferenceStore;
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;
public class ToolchainInstaller extends AbstractInstaller {
public ToolchainInstaller(String version) {
super(version);
}
@Override
protected String getFeatureName() {
return "toolchains";
}
@Override
protected void updateInstalledVersion(String version) {
IPreferenceStore prefs = WPILibCPPPlugin.getDefault().getPreferenceStore();
if (prefs.getBoolean(PreferenceConstants.UPDATE_TOOLCHAIN_VERSION)) {
System.out.println("Forcing library version to "+version);
prefs.setValue(PreferenceConstants.TOOLCHAIN_VERSION, version);
}
}
@Override
protected InputStream getInstallResourceStream() {
return ToolchainInstaller.class.getResourceAsStream("/resources/toolchain.zip");
}
}

View File

@@ -0,0 +1 @@
bin.includes = feature.xml

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="edu.wpi.first.wpilib.plugins.cpp.toolchains.mac.feature"
label="Mac Toolchain for Robot C++ Development"
version="0.2.0"
provider-name="Worcester Polytechnic Institute"
os="macosx">
<description>
The C++ toolchain to build Athena programs on a Mac.
</description>
<copyright>
* Copyright (c) 2013 FIRST and WPI
* All rights reserved.
</copyright>
<license>
* Copyright (c) 2013 FIRST and WPI
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer. Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution. Neither the name of the FIRST nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS&apos;&apos;
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</license>
<requires>
<import feature="edu.wpi.first.wpilib.plugins.cpp.feature" version="0.1.0.qualifier"/>
</requires>
<plugin
id="edu.wpi.first.wpilib.plugins.cpp.toolchains.mac"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>edu.wpi.first.wpilib.plugins.cpp.toolchains.mac.feature</artifactId>
<version>0.2.0</version>
<packaging>eclipse-feature</packaging>
<parent>
<groupId>edu.wpi.first.wpilib.plugins</groupId>
<artifactId>edu.wpi.first.wpilib.plugins</artifactId>
<version>0.1.0.qualifier</version>
<relativePath>..</relativePath>
</parent>
</project>

View File

@@ -0,0 +1,12 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Windows
Bundle-SymbolicName: edu.wpi.first.wpilib.plugins.cpp.toolchains.mac;singleton:=true
Bundle-Version: 0.2.0
Bundle-Activator: edu.wpi.first.wpilib.plugins.cpp.toolchains.mac.Activator
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
edu.wpi.first.wpilib.plugins.core;bundle-version="0.1.0",
edu.wpi.first.wpilib.plugins.cpp;bundle-version="0.1.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.7

View File

@@ -0,0 +1,8 @@
Making This Plugin Work
=======================
This plugin needs a very big zip that contains the toolchain. This is
currently hosted by Jenkins in the "Windows Toolchain Provider"
project. This can also be created from the download from mentor
embedded. The file should be resources/toolchain.zip and contains the
5 main directories.

View File

@@ -0,0 +1,7 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
resources/,\
plugin.xml
src.includes = resources/

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
point="org.eclipse.ui.startup">
<startup
class="edu.wpi.first.wpilib.plugins.cpp.toolchains.mac.Activator">
</startup>
</extension>
</plugin>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>edu.wpi.first.wpilib.plugins.cpp.toolchains.mac</artifactId>
<version>0.2.0</version>
<packaging>eclipse-plugin</packaging>
<parent>
<groupId>edu.wpi.first.wpilib.plugins</groupId>
<artifactId>edu.wpi.first.wpilib.plugins</artifactId>
<version>0.1.0.qualifier</version>
<relativePath>..</relativePath>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy</id>
<phase>prepare-package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>edu.wpi.first.wpilib.plugins.cpp.toolchains</groupId>
<artifactId>mac</artifactId>
<version>1.0.0</version>
<type>zip</type>
<destFileName>toolchain.zip</destFileName>
</artifactItem>
</artifactItems>
<overWriteIfNewer>true</overWriteIfNewer>
<outputDirectory>${project.build.outputDirectory}/resources</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,62 @@
package edu.wpi.first.wpilib.plugins.cpp.toolchains.mac;
import org.eclipse.ui.IStartup;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import edu.wpi.first.wpilib.plugins.cpp.WPILibCPPPlugin;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin implements IStartup {
// The plug-in ID
public static final String PLUGIN_ID = "edu.wpi.first.wpilib.plugins.cpp.toolchains.windows"; //$NON-NLS-1$
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
}
/*
* (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;
}
private String getCurrentVersion() {
return WPILibCPPPlugin.getDefault().getDefaultToolchainVersion();
}
/*
* (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 Activator getDefault() {
return plugin;
}
@Override
public void earlyStartup() {
new ToolchainInstaller(getCurrentVersion()).installIfNecessary();
}
}

View File

@@ -0,0 +1,36 @@
package edu.wpi.first.wpilib.plugins.cpp.toolchains.mac;
import java.io.InputStream;
import org.eclipse.jface.preference.IPreferenceStore;
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;
public class ToolchainInstaller extends AbstractInstaller {
public ToolchainInstaller(String version) {
super(version);
}
@Override
protected String getFeatureName() {
return "toolchains";
}
@Override
protected void updateInstalledVersion(String version) {
IPreferenceStore prefs = WPILibCPPPlugin.getDefault().getPreferenceStore();
if (prefs.getBoolean(PreferenceConstants.UPDATE_TOOLCHAIN_VERSION)) {
System.out.println("Forcing library version to "+version);
prefs.setValue(PreferenceConstants.TOOLCHAIN_VERSION, version);
}
}
@Override
protected InputStream getInstallResourceStream() {
return ToolchainInstaller.class.getResourceAsStream("/resources/toolchain.zip");
}
}

View File

@@ -0,0 +1 @@
bin.includes = feature.xml

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="edu.wpi.first.wpilib.plugins.cpp.toolchains.windows.feature"
label="Windows Toolchain for Robot C++ Development"
version="0.2.0"
provider-name="Worcester Polytechnic Institute"
os="win32">
<description>
The C++ toolchain to build Athena programs on Windows.
</description>
<copyright>
* Copyright (c) 2013 FIRST and WPI
* All rights reserved.
</copyright>
<license>
* Copyright (c) 2013 FIRST and WPI
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer. Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution. Neither the name of the FIRST nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS&apos;&apos;
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</license>
<requires>
<import feature="edu.wpi.first.wpilib.plugins.cpp.feature" version="0.1.0.qualifier"/>
</requires>
<plugin
id="edu.wpi.first.wpilib.plugins.cpp.toolchains.windows"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>edu.wpi.first.wpilib.plugins.cpp.toolchains.windows.feature</artifactId>
<version>0.2.0</version>
<packaging>eclipse-feature</packaging>
<parent>
<groupId>edu.wpi.first.wpilib.plugins</groupId>
<artifactId>edu.wpi.first.wpilib.plugins</artifactId>
<version>0.1.0.qualifier</version>
<relativePath>..</relativePath>
</parent>
</project>

View File

@@ -0,0 +1,12 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Windows
Bundle-SymbolicName: edu.wpi.first.wpilib.plugins.cpp.toolchains.windows;singleton:=true
Bundle-Version: 0.2.0
Bundle-Activator: edu.wpi.first.wpilib.plugins.cpp.toolchains.windows.Activator
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
edu.wpi.first.wpilib.plugins.core;bundle-version="0.1.0",
edu.wpi.first.wpilib.plugins.cpp;bundle-version="0.1.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.7

Some files were not shown because too many files have changed in this diff Show More