Skip to content

Commit

Permalink
Add source for video files (#698)
Browse files Browse the repository at this point in the history
  • Loading branch information
SamCarlberg authored May 9, 2017
1 parent c530c62 commit 182363c
Show file tree
Hide file tree
Showing 18 changed files with 772 additions and 6 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ project(":core") {
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.0.0-1.1', classifier: os
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv-3.0.0-1.1', classifier: 'linux-frc'
compile group: 'org.bytedeco.javacpp-presets', name: 'videoinput', version: '0.200-1.1', classifier: os
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '0.200-1.1', classifier: os
compile group: 'org.python', name: 'jython', version: '2.7.0'
compile group: 'com.thoughtworks.xstream', name: 'xstream', version: '1.4.9'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'
Expand Down
4 changes: 4 additions & 0 deletions core/src/main/java/edu/wpi/grip/core/GripCoreModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import edu.wpi.grip.core.sources.ImageFileSource;
import edu.wpi.grip.core.sources.MultiImageFileSource;
import edu.wpi.grip.core.sources.NetworkTableEntrySource;
import edu.wpi.grip.core.sources.VideoFileSource;
import edu.wpi.grip.core.util.ExceptionWitness;
import edu.wpi.grip.core.util.GripMode;

Expand Down Expand Up @@ -157,6 +158,9 @@ public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
install(new FactoryModuleBuilder()
.implement(ClassifierSource.class, ClassifierSource.class)
.build(ClassifierSource.Factory.class));
install(new FactoryModuleBuilder()
.implement(VideoFileSource.class, VideoFileSource.class)
.build(VideoFileSource.Factory.class));

install(new FactoryModuleBuilder().build(ExceptionWitness.Factory.class));
install(new FactoryModuleBuilder().build(Timer.Factory.class));
Expand Down
5 changes: 5 additions & 0 deletions core/src/main/java/edu/wpi/grip/core/Source.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import edu.wpi.grip.core.sources.ImageFileSource;
import edu.wpi.grip.core.sources.MultiImageFileSource;
import edu.wpi.grip.core.sources.NetworkTableEntrySource;
import edu.wpi.grip.core.sources.VideoFileSource;
import edu.wpi.grip.core.util.ExceptionWitness;

import com.google.common.base.MoreObjects;
Expand Down Expand Up @@ -125,6 +126,8 @@ public static class SourceFactoryImpl implements SourceFactory {
NetworkTableEntrySource.Factory networkTableEntryFactory;
@Inject
ClassifierSource.Factory fileSourceFactory;
@Inject
VideoFileSource.Factory videoFileSourceFactory;

@Override
public Source create(Class<?> type, Properties properties) throws IOException {
Expand All @@ -140,6 +143,8 @@ public Source create(Class<?> type, Properties properties) throws IOException {
return networkTableEntryFactory.create(properties);
} else if (type.isAssignableFrom(ClassifierSource.class)) {
return fileSourceFactory.create(properties);
} else if (type.isAssignableFrom(VideoFileSource.class)) {
return videoFileSourceFactory.create(properties);
} else {
throw new IllegalArgumentException(type + " was not a valid type");
}
Expand Down
56 changes: 56 additions & 0 deletions core/src/main/java/edu/wpi/grip/core/observables/Observable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package edu.wpi.grip.core.observables;

/**
* An observable wraps a value that, when changed, will notify listeners of the change.
*
* @param <T> the type of value to observe
*/
public interface Observable<T> {

/**
* Add an observer to this observable. It will be notified of any future changes to the value
* of this observable. Listeners will be fired in the order in which they were added, and on the
* thread that updates the observed value. Because of this, listeners should take as little time
* as possible to run (unless submitting a long-running task to a worker thread).
*/
void addObserver(Observer<? super T> observer);

/**
* Removes an observer from this observable. The observer will not be updated with future changes
* to the value of this observable.
*/
void removeObserver(Observer<? super T> observer);

/**
* Gets the current value of this observable.
*/
T get();

/**
* Sets the value of this observable. If it's not {@link Object#equals(Object) equal} to the
* current value, all observers will be notified of the change.
*/
void set(T value);

/**
* Creates an observable initialized to the given value. This observable is <i>not</i>
* thread-safe; for a thread-safe observable, use {@link #synchronizedOf(Object) synchronizedOf}.
*
* @param value the initial value of the observable
* @param <T> the type of value in the observable
*/
static <T> Observable<T> of(T value) {
return new SimpleObservable<>(value);
}

/**
* Creates a thread-safe observable initialized to the given value.
*
* @param value the initial value of the observable
* @param <T> the type of value in the observable
*/
static <T> Observable<T> synchronizedOf(T value) {
return new SynchronizedObservable<>(value);
}

}
19 changes: 19 additions & 0 deletions core/src/main/java/edu/wpi/grip/core/observables/Observer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package edu.wpi.grip.core.observables;

/**
* Observes changes to the value of an {@link Observable}.
*
* @param <T> the type of the value to observe
*/
@FunctionalInterface
public interface Observer<T> {

/**
* Called when the value of the observable changes.
*
* @param previous the previous value of the observable
* @param current the current value of the observable
*/
void onChange(T previous, T current);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package edu.wpi.grip.core.observables;

import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;

/**
* Default thread-unsafe implementation of {@link Observable}. For a thread-safe solution, see
* {@link SynchronizedObservable}.
*
* @param <T> the type of the values to observe
*/
public class SimpleObservable<T> implements Observable<T> {

private final Set<Observer<? super T>> observers = new LinkedHashSet<>();
private T value;

/**
* Creates an observable value with no initial value.
*/
SimpleObservable() {
this(null);
}

/**
* Creates an observable value with the given initial value.
*
* @param initialValue the initial value
*/
SimpleObservable(T initialValue) {
this.value = initialValue;
}

@Override
public void addObserver(Observer<? super T> observer) {
Objects.requireNonNull(observer, "Listener cannot be null");
observers.add(observer);
}

@Override
public void removeObserver(Observer<? super T> observer) {
observers.remove(observer);
}

@Override
public T get() {
return value;
}

@Override
public void set(T value) {
T previous = this.value;
if (!Objects.equals(previous, value)) {
this.value = value;
observers.forEach(l -> l.onChange(previous, value));
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package edu.wpi.grip.core.observables;

/**
* A thread-safe implementation of {@link Observable}. This should only be used in situations where
* observers are <i>very likely</i> to run in multiple threads. Otherwise, {@link SimpleObservable}
* should be used to avoid the penalties of {@code synchronized} and lock contention.
*
* @param <T> the type of the values to observe
*/
public class SynchronizedObservable<T> extends SimpleObservable<T> {

private final Object observersLock = new Object();
private final Object valueLock = new Object();

SynchronizedObservable() {
super();
}

SynchronizedObservable(T initialValue) {
super(initialValue);
}

@Override
public void addObserver(Observer<? super T> observer) {
synchronized (observersLock) {
super.addObserver(observer);
}
}

@Override
public void removeObserver(Observer<? super T> observer) {
synchronized (observersLock) {
super.addObserver(observer);
}
}

@Override
public T get() {
synchronized (valueLock) {
return super.get();
}
}

@Override
public void set(T value) {
synchronized (valueLock) {
synchronized (observersLock) {
super.set(value);
}
}
}

}
Loading

0 comments on commit 182363c

Please # to comment.