Fix Logical union not merging value observers correctly

A recursive call to union() would interfere and prevent value observers
to be propagated to the new root. This causes, among other things, a failure
to reactivate certain constraints.
This commit is contained in:
Fedor Isakov 2023-05-02 15:16:21 +02:00
parent 8401363109
commit 0e417646c2
1 changed files with 23 additions and 26 deletions

View File

@ -131,11 +131,7 @@ internal class LogicalImpl<T> : MutableLogical<T> {
otherRepr.setValue(thisVal);
}
// then set parent
otherRepr.setParent(thisRepr)
thisRepr.mergeParentObservers(otherRepr)
// last, reconcile the values/merge observers
// reconcile the values/merge value observers
if (thisVal == null && otherVal == null) {
// var var
thisRepr.mergeValueObservers(otherRepr);
@ -147,10 +143,20 @@ internal class LogicalImpl<T> : MutableLogical<T> {
// copy usages
thisRepr.usagesCount += otherRepr.usagesCount
// save other observers
val otherObservers = ArrayList(otherRepr.parentObservers)
mergeParentObservers(thisRepr, otherRepr)
// finally set parent and notify observers
otherRepr._parent = thisRepr
for (p in otherObservers) {
p.second.parentUpdated(p.first)
}
}
override fun union(other: MutableLogical<T>) {
union(other, { a, b -> if (a != b) throw IllegalStateException("$a does not equal to $b")})
union(other, { a, b -> if (a != b) throw IllegalStateException("$a does not equal to $b") })
}
override fun addObserver(observer: LogicalObserver) {
@ -183,13 +189,17 @@ internal class LogicalImpl<T> : MutableLogical<T> {
private fun rank(): Int = rank
private fun incRank() { rank++ }
private fun incRank() {
rank++
}
private fun incUsages() { usagesCount++ }
private fun incUsages() {
usagesCount++
}
private fun setParent(parent: LogicalImpl<T>) {
this._parent = parent
notifyParentUpdated()
private fun mergeParentObservers(thisRepr: LogicalImpl<T>, otherRepr: LogicalImpl<T>) {
thisRepr.parentObservers.addAll(otherRepr.parentObservers)
otherRepr.parentObservers.clear()
}
private fun mergeValueObservers(mergeFrom: MutableLogical<T>) {
@ -198,12 +208,6 @@ internal class LogicalImpl<T> : MutableLogical<T> {
other.valueObservers.clear()
}
private fun mergeParentObservers(mergeFrom: MutableLogical<T>) {
val other = mergeFrom as LogicalImpl<T>
this.find().parentObservers.addAll(other.parentObservers)
other.parentObservers.clear()
}
private fun notifyValueUpdated() {
val obs = ArrayList(valueObservers)
this.valueObservers.clear()
@ -212,16 +216,9 @@ internal class LogicalImpl<T> : MutableLogical<T> {
}
}
private fun notifyParentUpdated() {
val obs = ArrayList(parentObservers)
for (p in obs) {
p.second.parentUpdated(p.first)
}
}
override fun toString(): String =
if (_parent != null) "${name}(^${_parent.toString()})"
else name
if (_parent != null) "${name}(^${_parent.toString()})"
else name
}