Skip to content

Instantly share code, notes, and snippets.

View mikehearn's full-sized avatar

Mike Hearn mikehearn

View GitHub Profile
/**
* Maps elements of type F to E with change listeners working as expected.
*/
public class MappedList<E, F> extends TransformationList<E, F> {
private final Function<F, E> mapper;
private final ArrayList<E> mapped;
/**
* Creates a new MappedList list wrapped around the source list.
* Each element will have the given function applied to it, such that the list is cast through the mapper.
/**
* This list is created by dynamically concatenating all the source lists together.
*/
public class ConcatenatingList<T> extends ObservableListBase<T> implements ObservableList<T> {
private List<ObservableList<T>> sources = new ArrayList<>();
private ListChangeListener<T> listener = this::sourceChanged;
@SafeVarargs
public ConcatenatingList(ObservableList<T>... source) {
super();
@mikehearn
mikehearn / AffinityExecutor.java
Last active November 18, 2020 09:26
Some code for JavaFX observable collections (maps and sets) which replicate changes between threads. From the open source, Apache licensed Lighthouse project. Check there for the latest code.
// Contact: hearn@vinumeris.com
package lighthouse.threading;
import com.google.common.util.concurrent.Uninterruptibles;
import javafx.application.Platform;
import lighthouse.protocol.LHUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public static class AnimatedBindInfo {
@Nullable public Timeline timeline;
public NumberBinding bindFrom;
public Runnable onAnimFinish;
}
public static AnimatedBindInfo animatedBind(Node node, WritableDoubleValue bindTo, NumberBinding bindFrom) {
bindTo.set(bindFrom.doubleValue()); // Initialise.
bindFrom.addListener((o, prev, cur) -> {
AnimatedBindInfo info = (AnimatedBindInfo) node.getUserData();
@mikehearn
mikehearn / gist:7274375de2950e10f56f
Last active August 29, 2015 14:24
ThreadBox/UIThreadBox
class ThreadBox<T>(private val data: T) {
synchronized fun use<R>(block: (T) -> R): R = block(data)
synchronized fun useWith<R>(block: T.() -> R): R = data.block()
}
class UIThreadBox<T>(private val data: T) {
fun use(block: (T) -> Unit): Unit = if (Platform.isFxApplicationThread()) block(data) else Platform.runLater { block(data) }
fun useWith(block: T.() -> Unit): Unit = if (Platform.isFxApplicationThread()) data.block() else Platform.runLater { data.block() }
/** Does a blocking get from the UI thread - danger of deadlock if not used properly! */
@mikehearn
mikehearn / threadbox.kt
Created August 15, 2015 12:15
More advanced ThreadBox with affinity guards
// This is a class that attempts to stop you accessing variables outside a lock.
//
// It does not do a perfect job, but can catch some common kinds of mistake, in
// particular when you accidentally try to work with objects inside closures that
// end up running later, outside the locked region (or in a different thread).
// EXAMPLE
val bank = ThreadBox(object {
val accounts by arrayListOf(10, 0, 0, 0).guard()
@mikehearn
mikehearn / linear.kt
Created December 14, 2015 21:11
Rough sketch of possible linear types in kotlin (doesn't work with today's compiler)
open class LinearVal<T>(private val _v: T) {
open operator fun invoke(): T {
return _v
}
inline fun move(): LinearVal<T> {
if (this !is UnavailableLinearVal)
throw AssertionError()
@Suppress("DEPRECATION")
return __dupe()
@mikehearn
mikehearn / Kryo Kotlin class serialiser.kt
Created December 17, 2015 10:53
A Kryo serialiser that lets you serialise immutable classes like "class Foo(val a: Int, val b: Bar)" without bypassing the c'tor.
interface SerializeableWithKryo
class ImmutableClassSerializer<T : SerializeableWithKryo>(val klass: KClass<T>) : Serializer<T>() {
val props = klass.memberProperties.sortedBy { it.name }
val propsByName = props.toMapBy { it.name }
val constructor = klass.primaryConstructor!!
init {
// Verify that this class is immutable (all properties are final)
assert(props.none { it is KMutableProperty<*> })
@mikehearn
mikehearn / KotlinDuckTyping.kt
Created December 18, 2015 13:46
Kotlin duck typing / type classing fiddle
class A {
fun shout() = println("go team A!")
}
class B {
fun shout() = println("go team B!")
}
interface Shoutable {
fun shout()
@mikehearn
mikehearn / puzzle.kt
Created February 9, 2016 20:32
Kotlin version of the NYT Puzzles program
import java.io.File
import kotlin.system.measureTimeMillis
fun main(args: Array<String>) {
val name = if (args.size > 1) args[0] else "/usr/share/dict/words"
val time = measureTimeMillis {
repeat(200) {
go(name)
}