Synchronize the change handlers
I'm pretty confident that this isn't actually required by the JavaFX threading model, but it makes the code more obviously correct and uncontended synchronization has a negligible cost when we're talking about UI-level changes.
This commit is contained in:
parent
3f30eb32c2
commit
13e841d613
@ -8,6 +8,13 @@ import scalafx.beans.property._
|
||||
import scalafx.beans.value._
|
||||
|
||||
trait ObservableImplicits {
|
||||
/* NOTE: (Sarah) I believe that the synchronization in these helpers is not
|
||||
* _really_ required in the JavaFX threading model. However, the overhead of
|
||||
* uncontended synchronization is relatively low, and typical UIs won't have
|
||||
* enough change events for it to be a serious issue. (If you're updating
|
||||
* a property in a tight loop, I expect you'll have bigger performance
|
||||
* issues.)
|
||||
*/
|
||||
implicit val observableInstances = new Applicative[Observable] with Functor[Observable] with Monad[Observable] {
|
||||
/* Map can be derived from `ap`, but this adds less overhead. */
|
||||
override def map[A, B](a: Observable[A])(f: A => B): ObservableValue[B, B] = {
|
||||
@ -18,7 +25,7 @@ trait ObservableImplicits {
|
||||
val prop = ObjectProperty[B](originalValue)
|
||||
|
||||
var prevValue = originalValue
|
||||
def changeHandler = {
|
||||
def changeHandler = prop.synchronized {
|
||||
val newVal = recalculate()
|
||||
if (prevValue != newVal) {
|
||||
prop.value = recalculate()
|
||||
@ -44,7 +51,7 @@ trait ObservableImplicits {
|
||||
|
||||
var prevValue = originalValue
|
||||
|
||||
def changeHandler = {
|
||||
def changeHandler = prop.synchronized {
|
||||
val newVal = recalculate()
|
||||
if (prevValue != newVal) {
|
||||
prop.value = newVal
|
||||
@ -74,7 +81,7 @@ trait ObservableImplicits {
|
||||
|
||||
var prevValue = originalValue
|
||||
|
||||
def innerHandle() = {
|
||||
def innerHandle() = prop.synchronized {
|
||||
val newVal = calc()
|
||||
if (prevValue != newVal) {
|
||||
prop.value = newVal
|
||||
@ -84,7 +91,7 @@ trait ObservableImplicits {
|
||||
var innerSub = oa() onChange innerHandle
|
||||
|
||||
var prevOuter = oa()
|
||||
def outerHandle() = {
|
||||
def outerHandle() = prop.synchronized {
|
||||
val newOuter = oa()
|
||||
/* We need reference equality here: we're subscribing to a specific object. */
|
||||
if (prevOuter ne newOuter) {
|
||||
|
Loading…
Reference in New Issue
Block a user