Created
August 12, 2010 19:03
-
-
Save nkallen/521505 to your computer and use it in GitHub Desktop.
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
class NotifyingFuture[A] extends Future[A] { | |
import NotifyingFuture._ | |
private var result: Option[A] = None | |
private val computations = new ArrayBuffer[A => Unit] | |
def setResult(result: A) { | |
setResultIfEmpty(result) || { | |
throw new ImmutableResult("Result set multiple times: " + result) | |
} | |
} | |
private def isSet(onSet: A => B)(onEmpty: => B)(onWasSet: A => B)(onWasEmpty: => B) { | |
result map(onSet) orElse { | |
val wasSet = synchronized { | |
result map(onSet) getOrElse(onEmpty) | |
} | |
if (wasSet) onWasSet else onWasEmpty | |
} | |
} | |
def setResultIfEmpty(result: A) = { | |
isSet {} { | |
this.result = Some(result) | |
} { | |
false | |
} { | |
computations foreach(_(result)) | |
true | |
} | |
} | |
def respond(k: A => Unit) { | |
isSet {} {} { | |
k(result) | |
} { | |
computations += k | |
} | |
} | |
} |
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
class NotifyingFuture[A] extends Future[A] { | |
import NotifyingFuture._ | |
private var result: Option[A] = None | |
private val computations = new ArrayBuffer[A => Unit] | |
def setResult(result: A) { | |
setResultIfEmpty(result) || { | |
throw new ImmutableResult("Result set multiple times: " + result) | |
} | |
} | |
def setResultIfEmpty(result: A) = { | |
val didSetResult = synchronized { | |
result map(false) getOrElse { | |
this.result = Some(result) | |
true | |
} | |
} | |
if (didSetResult) computations foreach(_(result)) | |
didSetResult | |
} | |
def respond(k: A => Unit) { | |
result map(k) orElse { | |
val isDefined = synchronized { | |
result.isDefined || { computations += k; false } | |
} | |
if (isDefined) k(result.get) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment