Allow for bigger indices in VisitChildrenResult

The indexes stored in `VisitChildrenResult` are unsigned. We have 64
bits to store two values and we need to have one special value as a flag.

So accept any index `< u32::MAX` instead of `< i32::MAX`, which should
allow for more data to be visited;-)
This commit is contained in:
Tobias Hunger 2022-01-05 15:37:34 +01:00 committed by Tobias Hunger
parent d13067db04
commit 79e2456ead
3 changed files with 15 additions and 15 deletions

View file

@ -695,16 +695,16 @@ public:
viewport_height->set(h); viewport_height->set(h);
} }
intptr_t visit(TraversalOrder order, private_api::ItemVisitorRefMut visitor) const uintptr_t visit(TraversalOrder order, private_api::ItemVisitorRefMut visitor) const
{ {
for (std::size_t i = 0; i < inner->data.size(); ++i) { for (std::size_t i = 0; i < inner->data.size(); ++i) {
int index = order == TraversalOrder::BackToFront ? i : inner->data.size() - 1 - i; int index = order == TraversalOrder::BackToFront ? i : inner->data.size() - 1 - i;
auto ref = item_at(index); auto ref = item_at(index);
if (ref.vtable->visit_children_item(ref, -1, order, visitor) != -1) { if (ref.vtable->visit_children_item(ref, -1, order, visitor) != std::numeric_limits<uint64_t>::max()) {
return index; return index;
} }
} }
return -1; return std::numeric_limits<uint64_t>::max();
} }
vtable::VRef<private_api::ComponentVTable> item_at(int i) const vtable::VRef<private_api::ComponentVTable> item_at(int i) const

View file

@ -1488,7 +1488,7 @@ fn generate_component(
Access::Public, Access::Public,
Declaration::Function(Function { Declaration::Function(Function {
name: "visit_dynamic_children".into(), name: "visit_dynamic_children".into(),
signature: "(intptr_t dyn_index, [[maybe_unused]] sixtyfps::private_api::TraversalOrder order, [[maybe_unused]] sixtyfps::private_api::ItemVisitorRefMut visitor) const -> int64_t".into(), signature: "(intptr_t dyn_index, [[maybe_unused]] sixtyfps::private_api::TraversalOrder order, [[maybe_unused]] sixtyfps::private_api::ItemVisitorRefMut visitor) const -> uint64_t".into(),
statements: Some(vec![ statements: Some(vec![
" auto self = this;".to_owned(), " auto self = this;".to_owned(),
format!(" switch(dyn_index) {{ {} }};", children_visitor_cases.join("")), format!(" switch(dyn_index) {{ {} }};", children_visitor_cases.join("")),
@ -1616,10 +1616,10 @@ fn generate_component_vtable(
Access::Private, Access::Private,
Declaration::Function(Function { Declaration::Function(Function {
name: "visit_children".into(), name: "visit_children".into(),
signature: "(sixtyfps::private_api::ComponentRef component, intptr_t index, sixtyfps::private_api::TraversalOrder order, sixtyfps::private_api::ItemVisitorRefMut visitor) -> int64_t".into(), signature: "(sixtyfps::private_api::ComponentRef component, intptr_t index, sixtyfps::private_api::TraversalOrder order, sixtyfps::private_api::ItemVisitorRefMut visitor) -> uint64_t".into(),
is_static: true, is_static: true,
statements: Some(vec![ statements: Some(vec![
"static const auto dyn_visit = [] (const uint8_t *base, [[maybe_unused]] sixtyfps::private_api::TraversalOrder order, [[maybe_unused]] sixtyfps::private_api::ItemVisitorRefMut visitor, uintptr_t dyn_index) -> int64_t {".to_owned(), "static const auto dyn_visit = [] (const uint8_t *base, [[maybe_unused]] sixtyfps::private_api::TraversalOrder order, [[maybe_unused]] sixtyfps::private_api::ItemVisitorRefMut visitor, uintptr_t dyn_index) -> uint64_t {".to_owned(),
format!(" [[maybe_unused]] auto self = reinterpret_cast<const {}*>(base);", component_id), format!(" [[maybe_unused]] auto self = reinterpret_cast<const {}*>(base);", component_id),
format!(" switch(dyn_index) {{ {} }};", children_visitor_cases.join("")), format!(" switch(dyn_index) {{ {} }};", children_visitor_cases.join("")),
" std::abort();\n};".to_owned(), " std::abort();\n};".to_owned(),

View file

@ -23,30 +23,30 @@ pub enum TraversalOrder {
/// otherwise this is the index of the item that aborted the visit. /// otherwise this is the index of the item that aborted the visit.
#[repr(transparent)] #[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq)] #[derive(Copy, Clone, Eq, PartialEq)]
pub struct VisitChildrenResult(i64); pub struct VisitChildrenResult(u64);
impl VisitChildrenResult { impl VisitChildrenResult {
/// The result used for a visitor that want to continue the visit /// The result used for a visitor that want to continue the visit
pub const CONTINUE: Self = Self(-1); pub const CONTINUE: Self = Self(u64::MAX);
/// Returns a result that means that the visitor must stop, and convey the item that caused the abort /// Returns a result that means that the visitor must stop, and convey the item that caused the abort
pub fn abort(item_index: usize, index_within_repeater: usize) -> Self { pub fn abort(item_index: usize, index_within_repeater: usize) -> Self {
assert!(item_index < i32::MAX as usize); assert!(item_index < u32::MAX as usize);
assert!(index_within_repeater < i32::MAX as usize); assert!(index_within_repeater < u32::MAX as usize);
Self(item_index as i64 | (index_within_repeater as i64) << 32) Self(item_index as u64 | (index_within_repeater as u64) << 32)
} }
/// True if the visitor wants to abort the visit /// True if the visitor wants to abort the visit
pub fn has_aborted(&self) -> bool { pub fn has_aborted(&self) -> bool {
self.0 != -1 self.0 != Self::CONTINUE.0
} }
pub fn aborted_index(&self) -> Option<usize> { pub fn aborted_index(&self) -> Option<usize> {
if self.0 != -1 { if self.0 != Self::CONTINUE.0 {
Some((self.0 & 0xffff_ffff) as usize) Some((self.0 & 0xffff_ffff) as usize)
} else { } else {
None None
} }
} }
pub fn aborted_indexes(&self) -> Option<(usize, usize)> { pub fn aborted_indexes(&self) -> Option<(usize, usize)> {
if self.0 != -1 { if self.0 != Self::CONTINUE.0 {
Some(((self.0 & 0xffff_ffff) as usize, (self.0 >> 32) as usize)) Some(((self.0 & 0xffff_ffff) as usize, (self.0 >> 32) as usize))
} else { } else {
None None
@ -55,7 +55,7 @@ impl VisitChildrenResult {
} }
impl core::fmt::Debug for VisitChildrenResult { impl core::fmt::Debug for VisitChildrenResult {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if self.0 == -1 { if self.0 == Self::CONTINUE.0 {
write!(f, "CONTINUE") write!(f, "CONTINUE")
} else { } else {
write!(f, "({},{})", (self.0 & 0xffff_ffff) as usize, (self.0 >> 32) as usize) write!(f, "({},{})", (self.0 & 0xffff_ffff) as usize, (self.0 >> 32) as usize)