This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fun getScreenCaptureSource( | |
screenRectangle: Rectangle, | |
numThreads: Int = 6, | |
fpsPerThread: Int = 8, | |
robot: Robot = Robot() | |
): Observable<BufferedImage> { | |
val periodPerThreadMs: Long = 1000 / fpsPerThread.toLong() | |
val perThreadOffsetMs: Long = periodPerThreadMs / numThreads | |
val sources = (0 until numThreads).map { i -> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Removes duplicate consecutive elements in a list, up to maxN duplicate consecutive elements | |
* per group. | |
* Ex. where maxN = 2: | |
* [0, 0, 1, 2, 2, 4, 4, 4, 4] => [0, 1, 2, 4, 4] | |
*/ | |
fun <T> List<T>.normalize(maxN: Int): List<T> { | |
var nextIndexToConsider = 0 | |
return windowed(size = maxN, step = 1, partialWindows = true) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Uses OpenCV to decode an image that is an android test resource i.e. | |
* a file from `src/androidTest/resources`. | |
* Note that the resulting Mat will be empty if there was a problem loading the file. | |
*/ | |
private fun loadOpenCvImage(testResourceFilename: String): Mat { | |
val bytes: ByteArray = javaClass.classLoader!!.getResource(testResourceFilename).readBytes() | |
val matOfByte = MatOfByte().apply { fromList(bytes.toList()) } | |
return Imgcodecs.imdecode(matOfByte, CV_LOAD_IMAGE_COLOR) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Converts a list of bits (booleans) with big-endian ordering to its corresponding | |
* integer. | |
*/ | |
fun List<Boolean>.bigEndianBitsToInt(): Int { | |
return reversed().foldIndexed(initial = 0) { bitNo: Int, output: Int, bit: Boolean -> | |
output or (bit.toInt() shl bitNo) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* E.g. | |
* cartesianProduct(listOf(1, 2, 3), listOf(true, false)) returns | |
* [(1, true), (1, false), (2, true), (2, false), (3, true), (3, false)] | |
*/ | |
fun <T, U> cartesianProduct(c1: Collection<T>, c2: Collection<U>): List<Pair<T, U>> { | |
return c1.flatMap { lhsElem -> c2.map { rhsElem -> lhsElem to rhsElem } } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Find all instances of given substring in this string. | |
* Results are in the form of a list of index pairs (start and end index of that particular match). | |
*/ | |
fun String.findAllInstancesOf( | |
subString: String, | |
startIndex: Int = 0 | |
): List<Pair<Int, Int>> { | |
val index = this.indexOf(subString, startIndex) | |
if (index == -1) return emptyList() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Filters items emitted by an observable by only emitting those that satisfy the specified | |
* predicate based on the latest and previous items emitted. | |
* Note that this will always filter out the first item of the stream since in this case there | |
* is as of yet no previous item to compare it to. | |
* | |
* @param bipredicate | |
* a function that evaluates the current and previous item emitted by the source ObservableSource, returning {@code true} | |
* if it passes the filter | |
* @return an Observable that emits only those items emitted by the source ObservableSource that the filter |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fun <T> Observable<T>.throttleMatchingItems( | |
windowDuration: Long, | |
unit: TimeUnit, | |
predicate: (T) -> Boolean | |
): Observable<T> { | |
return this.compose { stream -> | |
val throttledItems = stream | |
.filter(predicate) | |
.throttleFirst(windowDuration, unit) | |
val allOtherItems = stream.filter { !predicate(it) } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import io.reactivex.Observable | |
import okhttp3.* | |
import okio.ByteString | |
fun OkHttpClient.newWebSocketObservable(serverUrl: String): Observable<WebSocketEvent> { | |
val request = Request.Builder().url(serverUrl).build() | |
return newWebSocketObservable(request) | |
} | |
fun OkHttpClient.newWebSocketObservable(request: Request): Observable<WebSocketEvent> { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fun <T1, T2, R> asyncZip(source1: Single<T1>, | |
source2: Single<T2>, | |
zipper: (T1, T2) -> Single<R>): Single<R> = | |
Single.zip( | |
source1, source2, | |
io.reactivex.functions.BiFunction<T1, T2, Single<R>> { t1, t2 -> zipper(t1, t2) } | |
).flatMap { it } |
NewerOlder