Skip to content

Commit 182363c

Browse files
authored
Add source for video files (#698)
1 parent c530c62 commit 182363c

File tree

18 files changed

+772
-6
lines changed

18 files changed

+772
-6
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ project(":core") {
230230
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.0.0-1.1', classifier: os
231231
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv-3.0.0-1.1', classifier: 'linux-frc'
232232
compile group: 'org.bytedeco.javacpp-presets', name: 'videoinput', version: '0.200-1.1', classifier: os
233+
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '0.200-1.1', classifier: os
233234
compile group: 'org.python', name: 'jython', version: '2.7.0'
234235
compile group: 'com.thoughtworks.xstream', name: 'xstream', version: '1.4.9'
235236
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'

core/src/main/java/edu/wpi/grip/core/GripCoreModule.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import edu.wpi.grip.core.sources.ImageFileSource;
1717
import edu.wpi.grip.core.sources.MultiImageFileSource;
1818
import edu.wpi.grip.core.sources.NetworkTableEntrySource;
19+
import edu.wpi.grip.core.sources.VideoFileSource;
1920
import edu.wpi.grip.core.util.ExceptionWitness;
2021
import edu.wpi.grip.core.util.GripMode;
2122

@@ -157,6 +158,9 @@ public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
157158
install(new FactoryModuleBuilder()
158159
.implement(ClassifierSource.class, ClassifierSource.class)
159160
.build(ClassifierSource.Factory.class));
161+
install(new FactoryModuleBuilder()
162+
.implement(VideoFileSource.class, VideoFileSource.class)
163+
.build(VideoFileSource.Factory.class));
160164

161165
install(new FactoryModuleBuilder().build(ExceptionWitness.Factory.class));
162166
install(new FactoryModuleBuilder().build(Timer.Factory.class));

core/src/main/java/edu/wpi/grip/core/Source.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import edu.wpi.grip.core.sources.ImageFileSource;
88
import edu.wpi.grip.core.sources.MultiImageFileSource;
99
import edu.wpi.grip.core.sources.NetworkTableEntrySource;
10+
import edu.wpi.grip.core.sources.VideoFileSource;
1011
import edu.wpi.grip.core.util.ExceptionWitness;
1112

1213
import com.google.common.base.MoreObjects;
@@ -125,6 +126,8 @@ public static class SourceFactoryImpl implements SourceFactory {
125126
NetworkTableEntrySource.Factory networkTableEntryFactory;
126127
@Inject
127128
ClassifierSource.Factory fileSourceFactory;
129+
@Inject
130+
VideoFileSource.Factory videoFileSourceFactory;
128131

129132
@Override
130133
public Source create(Class<?> type, Properties properties) throws IOException {
@@ -140,6 +143,8 @@ public Source create(Class<?> type, Properties properties) throws IOException {
140143
return networkTableEntryFactory.create(properties);
141144
} else if (type.isAssignableFrom(ClassifierSource.class)) {
142145
return fileSourceFactory.create(properties);
146+
} else if (type.isAssignableFrom(VideoFileSource.class)) {
147+
return videoFileSourceFactory.create(properties);
143148
} else {
144149
throw new IllegalArgumentException(type + " was not a valid type");
145150
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package edu.wpi.grip.core.observables;
2+
3+
/**
4+
* An observable wraps a value that, when changed, will notify listeners of the change.
5+
*
6+
* @param <T> the type of value to observe
7+
*/
8+
public interface Observable<T> {
9+
10+
/**
11+
* Add an observer to this observable. It will be notified of any future changes to the value
12+
* of this observable. Listeners will be fired in the order in which they were added, and on the
13+
* thread that updates the observed value. Because of this, listeners should take as little time
14+
* as possible to run (unless submitting a long-running task to a worker thread).
15+
*/
16+
void addObserver(Observer<? super T> observer);
17+
18+
/**
19+
* Removes an observer from this observable. The observer will not be updated with future changes
20+
* to the value of this observable.
21+
*/
22+
void removeObserver(Observer<? super T> observer);
23+
24+
/**
25+
* Gets the current value of this observable.
26+
*/
27+
T get();
28+
29+
/**
30+
* Sets the value of this observable. If it's not {@link Object#equals(Object) equal} to the
31+
* current value, all observers will be notified of the change.
32+
*/
33+
void set(T value);
34+
35+
/**
36+
* Creates an observable initialized to the given value. This observable is <i>not</i>
37+
* thread-safe; for a thread-safe observable, use {@link #synchronizedOf(Object) synchronizedOf}.
38+
*
39+
* @param value the initial value of the observable
40+
* @param <T> the type of value in the observable
41+
*/
42+
static <T> Observable<T> of(T value) {
43+
return new SimpleObservable<>(value);
44+
}
45+
46+
/**
47+
* Creates a thread-safe observable initialized to the given value.
48+
*
49+
* @param value the initial value of the observable
50+
* @param <T> the type of value in the observable
51+
*/
52+
static <T> Observable<T> synchronizedOf(T value) {
53+
return new SynchronizedObservable<>(value);
54+
}
55+
56+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package edu.wpi.grip.core.observables;
2+
3+
/**
4+
* Observes changes to the value of an {@link Observable}.
5+
*
6+
* @param <T> the type of the value to observe
7+
*/
8+
@FunctionalInterface
9+
public interface Observer<T> {
10+
11+
/**
12+
* Called when the value of the observable changes.
13+
*
14+
* @param previous the previous value of the observable
15+
* @param current the current value of the observable
16+
*/
17+
void onChange(T previous, T current);
18+
19+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package edu.wpi.grip.core.observables;
2+
3+
import java.util.LinkedHashSet;
4+
import java.util.Objects;
5+
import java.util.Set;
6+
7+
/**
8+
* Default thread-unsafe implementation of {@link Observable}. For a thread-safe solution, see
9+
* {@link SynchronizedObservable}.
10+
*
11+
* @param <T> the type of the values to observe
12+
*/
13+
public class SimpleObservable<T> implements Observable<T> {
14+
15+
private final Set<Observer<? super T>> observers = new LinkedHashSet<>();
16+
private T value;
17+
18+
/**
19+
* Creates an observable value with no initial value.
20+
*/
21+
SimpleObservable() {
22+
this(null);
23+
}
24+
25+
/**
26+
* Creates an observable value with the given initial value.
27+
*
28+
* @param initialValue the initial value
29+
*/
30+
SimpleObservable(T initialValue) {
31+
this.value = initialValue;
32+
}
33+
34+
@Override
35+
public void addObserver(Observer<? super T> observer) {
36+
Objects.requireNonNull(observer, "Listener cannot be null");
37+
observers.add(observer);
38+
}
39+
40+
@Override
41+
public void removeObserver(Observer<? super T> observer) {
42+
observers.remove(observer);
43+
}
44+
45+
@Override
46+
public T get() {
47+
return value;
48+
}
49+
50+
@Override
51+
public void set(T value) {
52+
T previous = this.value;
53+
if (!Objects.equals(previous, value)) {
54+
this.value = value;
55+
observers.forEach(l -> l.onChange(previous, value));
56+
}
57+
}
58+
59+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package edu.wpi.grip.core.observables;
2+
3+
/**
4+
* A thread-safe implementation of {@link Observable}. This should only be used in situations where
5+
* observers are <i>very likely</i> to run in multiple threads. Otherwise, {@link SimpleObservable}
6+
* should be used to avoid the penalties of {@code synchronized} and lock contention.
7+
*
8+
* @param <T> the type of the values to observe
9+
*/
10+
public class SynchronizedObservable<T> extends SimpleObservable<T> {
11+
12+
private final Object observersLock = new Object();
13+
private final Object valueLock = new Object();
14+
15+
SynchronizedObservable() {
16+
super();
17+
}
18+
19+
SynchronizedObservable(T initialValue) {
20+
super(initialValue);
21+
}
22+
23+
@Override
24+
public void addObserver(Observer<? super T> observer) {
25+
synchronized (observersLock) {
26+
super.addObserver(observer);
27+
}
28+
}
29+
30+
@Override
31+
public void removeObserver(Observer<? super T> observer) {
32+
synchronized (observersLock) {
33+
super.addObserver(observer);
34+
}
35+
}
36+
37+
@Override
38+
public T get() {
39+
synchronized (valueLock) {
40+
return super.get();
41+
}
42+
}
43+
44+
@Override
45+
public void set(T value) {
46+
synchronized (valueLock) {
47+
synchronized (observersLock) {
48+
super.set(value);
49+
}
50+
}
51+
}
52+
53+
}

0 commit comments

Comments
 (0)