You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I've been having some trouble with signal_vec::Flatten when its outer SignalVec updates. Specifically it looks like UpdateAt, RemoveAt, Move and Pop aren't generating all the right updates. The current tests only seem to look at Replace and Clear.
For example, I think this test (if you add it to tests\signal_vec.rs) describes the expected behaviour of RemoveAt correctly, but it currently fails:
And this is a possible, but not particularly elegant, fix. A more elegant version would require more re-work (e.g., to FlattenState), which I think might be a bit beyond me.
fn poll_vec_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<VecDiff<Self::Item>>> {
let mut this = self.project();
if let Some(diff) = this.pending.pop_front() {
return Poll::Ready(Some(diff));
}
let mut pending: PendingBuilder<VecDiff<<A::Item as SignalVec>::Item>> = PendingBuilder::new();
let top_done = loop {
break match this.signal.as_mut().as_pin_mut().map(|signal| signal.poll_vec_change(cx)) {
Some(Poll::Ready(Some(diff))) => {
match diff {
VecDiff::Replace { values } => {
*this.inner = values.into_iter().map(FlattenState::new).collect();
let values = this.inner.iter_mut()
.flat_map(|state| state.poll_values(cx))
.collect();
return Poll::Ready(Some(VecDiff::Replace { values }));
},
VecDiff::InsertAt { index, value } => {
this.inner.insert(index, FlattenState::new(value));
},
VecDiff::UpdateAt { index, value } => {
let removed_len = this.inner[index].len;
this.inner[index] = FlattenState::new(value);
let start_ind: usize = this.inner[..index].iter().map(|state| state.len).sum();
for index in (0..removed_len).rev() {
pending.push(VecDiff::RemoveAt { index: start_ind + index });
}
},
VecDiff::RemoveAt { index } => {
let removed_len = this.inner.remove(index).len;
let start_ind: usize = this.inner[..index].iter().map(|state| state.len).sum();
for index in (0..removed_len).rev() {
pending.push(VecDiff::RemoveAt { index: start_ind + index });
}
},
VecDiff::Move { old_index, new_index } => {
if old_index != new_index {
let old_start_ind: usize = this.inner[..old_index].iter().map(|state| state.len).sum();
let value = this.inner.remove(old_index);
let new_start_ind: usize = this.inner[..new_index].iter().map(|state| state.len).sum();
let moved_len = value.len;
this.inner.insert(new_index, value);
if new_index < old_index {
(0..moved_len).for_each(|_| pending.push(VecDiff::Move {
old_index: old_start_ind + moved_len - 1,
new_index: new_start_ind,
}));
} else {
(0..moved_len).for_each(|_| pending.push(VecDiff::Move {
old_index: old_start_ind,
new_index: new_start_ind + moved_len - 1,
}));
}
}
},
VecDiff::Push { value } => {
this.inner.push(FlattenState::new(value));
},
VecDiff::Pop {} => {
let removed_len = this.inner.pop().unwrap().len;
(0..removed_len).for_each(|_| pending.push(VecDiff::Pop { }));
},
VecDiff::Clear {} => {
this.inner.clear();
return Poll::Ready(Some(VecDiff::Clear {}));
},
}
continue;
},
Some(Poll::Ready(None)) => {
this.signal.set(None);
true
},
Some(Poll::Pending) => {
false
},
None => {
true
},
};
};
let mut inner_done = true;
let mut prev_len = 0;
for state in this.inner.iter_mut() {
let done = state.poll_pending(cx, prev_len, &mut pending);
if !done {
inner_done = false;
}
prev_len += state.len;
}
if let Some(first) = pending.first {
*this.pending = pending.rest;
Poll::Ready(Some(first))
} else if inner_done && top_done {
Poll::Ready(None)
} else {
Poll::Pending
}
}
Sorry, I'm a total novice at using GitHub, so I thought I'd raise this as an issue first.
I've written a couple of other tests as well, if that's useful.
Thanks!
The text was updated successfully, but these errors were encountered:
Hi, I've been having some trouble with
signal_vec::Flatten
when its outerSignalVec
updates. Specifically it looks likeUpdateAt
,RemoveAt
,Move
andPop
aren't generating all the right updates. The current tests only seem to look atReplace
andClear
.For example, I think this test (if you add it to
tests\signal_vec.rs
) describes the expected behaviour ofRemoveAt
correctly, but it currently fails:And this is a possible, but not particularly elegant, fix. A more elegant version would require more re-work (e.g., to
FlattenState
), which I think might be a bit beyond me.Sorry, I'm a total novice at using GitHub, so I thought I'd raise this as an issue first.
I've written a couple of other tests as well, if that's useful.
Thanks!
The text was updated successfully, but these errors were encountered: