Skip to content

Commit f0dee39

Browse files
authored
fix: prevent allocation and component ID ranges from overlapping (#230)
* fix: bug where ID ranges were overlapping for components and allocations * correct release plz * add rhai changes to changelogs
1 parent 70bad5a commit f0dee39

File tree

2 files changed

+63
-22
lines changed

2 files changed

+63
-22
lines changed

crates/bevy_mod_scripting_core/src/bindings/access_map.rs

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -96,31 +96,35 @@ pub struct ReflectAccessId {
9696

9797
impl AccessMapKey for ReflectAccessId {
9898
fn as_index(&self) -> u64 {
99-
// project two linear non-negative ranges to a single linear non-negative range, offset by 1 to avoid 0
100-
// y1 = 2x - 0 + 1
101-
// y2 = 2x - 1 + 1
99+
// project two linear non-negative ranges [0,inf] to a single linear non-negative range, offset by 1 to avoid 0
100+
// y1 = 2x - 0 + 2 = 2x + 2
101+
// y2 = 2x - 1 + 2 = 2x + 1
102102
match self.kind {
103-
ReflectAccessKind::ComponentOrResource => (self.id * 2) + 1,
103+
ReflectAccessKind::ComponentOrResource => (self.id * 2) + 2,
104104
ReflectAccessKind::Allocation => (self.id * 2) + 1,
105105
ReflectAccessKind::Global => 0,
106106
}
107107
}
108108

109109
fn from_index(value: u64) -> Self {
110-
// retrieve the kind of range based on if the value is odd or even
111-
// y1 if even, y2 if odd
112-
// to retrieve value of x:
113-
// x1 = (y / 2) - 1
114-
// x2 = ((y - 1) / 2) - 1
115-
116-
let (kind, id) = if value == 0 {
117-
(ReflectAccessKind::Global, 0)
118-
} else if value % 2 == 0 {
119-
(ReflectAccessKind::ComponentOrResource, (value / 2) - 1)
120-
} else {
121-
(ReflectAccessKind::Allocation, ((value - 1) / 2) - 1)
122-
};
123-
Self { kind, id }
110+
// reverse the projection
111+
// x1 = (y1 - 2) / 2
112+
// x2 = (y2 - 1) / 2
113+
114+
match value {
115+
0 => ReflectAccessId {
116+
kind: ReflectAccessKind::Global,
117+
id: 0,
118+
},
119+
v if v % 2 == 0 => ReflectAccessId {
120+
kind: ReflectAccessKind::ComponentOrResource,
121+
id: (v - 2) / 2,
122+
},
123+
v => ReflectAccessId {
124+
kind: ReflectAccessKind::Allocation,
125+
id: (v - 1) / 2,
126+
},
127+
}
124128
}
125129
}
126130

@@ -521,4 +525,41 @@ mod test {
521525
.join()
522526
.unwrap();
523527
}
528+
529+
#[test]
530+
fn test_as_and_from_index_for_access_id_non_overlapping() {
531+
let global = ReflectAccessId::for_global();
532+
533+
let first_component = ReflectAccessId {
534+
kind: ReflectAccessKind::ComponentOrResource,
535+
id: 0,
536+
};
537+
538+
let first_allocation = ReflectAccessId {
539+
kind: ReflectAccessKind::Allocation,
540+
id: 0,
541+
};
542+
543+
let second_component = ReflectAccessId {
544+
kind: ReflectAccessKind::ComponentOrResource,
545+
id: 1,
546+
};
547+
548+
let second_allocation = ReflectAccessId {
549+
kind: ReflectAccessKind::Allocation,
550+
id: 1,
551+
};
552+
553+
assert_eq!(global.as_index(), 0);
554+
assert_eq!(first_allocation.as_index(), 1);
555+
assert_eq!(first_component.as_index(), 2);
556+
assert_eq!(second_allocation.as_index(), 3);
557+
assert_eq!(second_component.as_index(), 4);
558+
559+
assert_eq!(ReflectAccessId::from_index(0), global);
560+
assert_eq!(ReflectAccessId::from_index(1), first_allocation);
561+
assert_eq!(ReflectAccessId::from_index(2), first_component);
562+
assert_eq!(ReflectAccessId::from_index(3), second_allocation);
563+
assert_eq!(ReflectAccessId::from_index(4), second_component);
564+
}
524565
}

release-plz.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ git_release_body = """
3939
changelog_include = [
4040
"bevy_mod_scripting_lua",
4141
"bevy_mod_scripting_core",
42-
# "bevy_mod_scripting_rhai",
42+
"bevy_mod_scripting_rhai",
4343
# "bevy_mod_scripting_rune",
4444
"bevy_mod_scripting_functions",
4545
]
@@ -53,9 +53,9 @@ version_group = "main"
5353
name = "bevy_mod_scripting_core"
5454
version_group = "main"
5555

56-
# [[package]]
57-
# name = "bevy_mod_scripting_rhai"
58-
# version_group = "main"
56+
[[package]]
57+
name = "bevy_mod_scripting_rhai"
58+
version_group = "main"
5959

6060
# [[package]]
6161
# name = "bevy_mod_scripting_rune"

0 commit comments

Comments
 (0)