Skip to content

Commit 9932a86

Browse files
committed
finally
1 parent 4347d50 commit 9932a86

File tree

7 files changed

+128
-178
lines changed

7 files changed

+128
-178
lines changed

assets/scripts/game_of_life.lua

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,61 @@
1-
-- print("The game_of_life.lua script just got loaded")
2-
-- print("Hello from Lua! I am initiating the game of life simulation state to a random state now")
1+
print("The game_of_life.lua script just got loaded")
2+
print("Hello from Lua! I am initiating the game of life simulation state to a random state now")
33

4-
-- math.randomseed(os.time())
5-
-- _LifeState = world.get_type_by_name("LifeState")
6-
_Settings = world.get_type_by_name("Settings")
4+
math.randomseed(os.time())
5+
LifeState = world.get_type_by_name("LifeState")
6+
Settings = world.get_type_by_name("Settings")
77

8-
-- function fetch_life_state()
9-
-- -- find the entity with life state
10-
-- local life_state = nil
11-
-- for i,result in pairs(world.query({_LifeState}):build()) do
12-
-- life_state = result:components()[1]
13-
-- break
14-
-- end
15-
-- return life_state
16-
-- end
8+
function fetch_life_state()
9+
-- find the entity with life state
10+
local life_state = nil
11+
for i,result in pairs(world.query({LifeState}):build()) do
12+
life_state = result:components()[1]
13+
break
14+
end
15+
return life_state
16+
end
1717

18-
function on_init()
19-
-- print("On init was called")
20-
-- local life_state = fetch_life_state()
21-
-- local cells = life_state.cells
18+
local life_state = fetch_life_state()
19+
local cells = life_state.cells
2220

23-
-- -- set some cells alive
24-
-- for _=1,10000 do
25-
-- local index = math.random(#cells)
26-
-- cells[index] = 255
27-
-- end
21+
-- set some cells alive
22+
for _=1,10000 do
23+
local index = math.random(#cells)
24+
cells[index] = 255
2825
end
2926

3027
function on_update()
31-
-- local cells = fetch_life_state().cells
32-
local settings = world.get_resource(_Settings)
33-
-- local dimensions = settings.physical_grid_dimensions
34-
-- local dimension_x = dimensions._1
35-
-- local dimension_y = dimensions._2
28+
local cells = fetch_life_state().cells
29+
world.log_all_allocations()
30+
local settings = world.get_resource(Settings)
31+
local dimensions = settings.physical_grid_dimensions
32+
local dimension_x = dimensions._1
33+
local dimension_y = dimensions._2
3634

37-
-- -- primitives are passed by value to lua, keep a hold of old state but turn 255's into 1's
38-
-- local prev_state = {}
39-
-- for k,v in pairs(cells) do
40-
-- prev_state[k] = (not(v == 0)) and 1 or 0
41-
-- end
42-
-- for i=1,(dimension_x * dimension_y) do
43-
-- local north = prev_state[i - dimension_x] or 1
44-
-- local south = prev_state[i + dimension_x] or 1
45-
-- local east = prev_state[i + 1] or 1
46-
-- local west = prev_state[i - 1] or 1
47-
-- local northeast = prev_state[i - dimension_x + 1] or 1
48-
-- local southeast = prev_state[i + dimension_x + 1] or 1
49-
-- local northwest = prev_state[i - dimension_x - 1] or 1
50-
-- local southwest = prev_state[i + dimension_x - 1] or 1
35+
-- primitives are passed by value to lua, keep a hold of old state but turn 255's into 1's
36+
local prev_state = {}
37+
for v in pairs(cells) do
38+
prev_state[#prev_state+1] = (not(v == 0)) and 1 or 0
39+
end
40+
for i=1,(dimension_x * dimension_y) do
41+
local north = prev_state[i - dimension_x] or 1
42+
local south = prev_state[i + dimension_x] or 1
43+
local east = prev_state[i + 1] or 1
44+
local west = prev_state[i - 1] or 1
45+
local northeast = prev_state[i - dimension_x + 1] or 1
46+
local southeast = prev_state[i + dimension_x + 1] or 1
47+
local northwest = prev_state[i - dimension_x - 1] or 1
48+
local southwest = prev_state[i + dimension_x - 1] or 1
5149

52-
-- local neighbours = north + south + east + west
53-
-- + northeast + southeast + northwest + southwest
50+
local neighbours = north + south + east + west
51+
+ northeast + southeast + northwest + southwest
5452

55-
-- -- was dead and got 3 neighbours now
56-
-- if prev_state[i] == 0 and neighbours == 3 then
57-
-- cells[i] = 255
58-
-- -- was alive and should die now
59-
-- elseif prev_state[i] == 1 and ((neighbours < 2) or (neighbours > 3)) then
60-
-- cells[i] = 0
61-
-- end
62-
-- end
53+
-- was dead and got 3 neighbours now
54+
if prev_state[i] == 0 and neighbours == 3 then
55+
cells[i] = 255
56+
-- was alive and should die now
57+
elseif prev_state[i] == 1 and ((neighbours < 2) or (neighbours > 3)) then
58+
cells[i] = 0
59+
end
60+
end
6361
end

crates/bevy_mod_scripting_core/src/bindings/access_map.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,16 @@ impl AccessCount {
5858
}
5959

6060
pub trait AccessMapKey {
61-
fn as_usize(&self) -> usize;
62-
fn from_usize(value: usize) -> Self;
61+
fn as_index(&self) -> u64;
62+
fn from_index(value: u64) -> Self;
6363
}
6464

65-
impl AccessMapKey for usize {
66-
fn as_usize(&self) -> usize {
65+
impl AccessMapKey for u64 {
66+
fn as_index(&self) -> u64 {
6767
*self
6868
}
6969

70-
fn from_usize(value: usize) -> Self {
70+
fn from_index(value: u64) -> Self {
7171
value
7272
}
7373
}
@@ -84,11 +84,11 @@ pub enum ReflectAccessKind {
8484
#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
8585
pub struct ReflectAccessId {
8686
kind: ReflectAccessKind,
87-
id: usize,
87+
id: u64,
8888
}
8989

9090
impl AccessMapKey for ReflectAccessId {
91-
fn as_usize(&self) -> usize {
91+
fn as_index(&self) -> u64 {
9292
// project two linear non-negative ranges to a single linear non-negative range
9393
// y1 = 2x - 0
9494
// y2 = 2x - 1
@@ -98,7 +98,7 @@ impl AccessMapKey for ReflectAccessId {
9898
}
9999
}
100100

101-
fn from_usize(value: usize) -> Self {
101+
fn from_index(value: u64) -> Self {
102102
// retrieve the kind of range based on if the value is odd or even
103103
// y1 if even, y2 if odd
104104
// to retrieve value of x:
@@ -117,7 +117,7 @@ impl ReflectAccessId {
117117
pub fn for_resource<R: Resource>(cell: &UnsafeWorldCell) -> Option<Self> {
118118
Some(Self {
119119
kind: ReflectAccessKind::ComponentOrResource,
120-
id: cell.components().resource_id::<R>()?.index(),
120+
id: cell.components().resource_id::<R>()?.index() as u64,
121121
})
122122
}
123123

@@ -139,7 +139,7 @@ impl ReflectAccessId {
139139
pub fn for_component_id(id: ComponentId) -> Self {
140140
Self {
141141
kind: ReflectAccessKind::ComponentOrResource,
142-
id: id.index(),
142+
id: id.index() as u64,
143143
}
144144
}
145145

@@ -156,7 +156,7 @@ impl From<ComponentId> for ReflectAccessId {
156156
fn from(value: ComponentId) -> Self {
157157
Self {
158158
kind: ReflectAccessKind::ComponentOrResource,
159-
id: value.index(),
159+
id: value.index() as u64,
160160
}
161161
}
162162
}
@@ -172,13 +172,13 @@ impl From<ReflectAllocationId> for ReflectAccessId {
172172

173173
impl From<ReflectAccessId> for ComponentId {
174174
fn from(val: ReflectAccessId) -> Self {
175-
ComponentId::new(val.id)
175+
ComponentId::new(val.id as usize)
176176
}
177177
}
178178

179179
#[derive(Debug, Default)]
180180
pub struct AccessMap {
181-
individual_accesses: DashMap<usize, AccessCount>,
181+
individual_accesses: DashMap<u64, AccessCount>,
182182
global_lock: AtomicBool,
183183
}
184184

@@ -189,7 +189,7 @@ impl AccessMap {
189189
if self.global_lock.load(std::sync::atomic::Ordering::Relaxed) {
190190
return false;
191191
}
192-
let key = key.as_usize();
192+
let key = key.as_index();
193193
let access = self.individual_accesses.try_entry(key);
194194
match access.map(Entry::or_default) {
195195
Some(mut entry) if entry.can_read() => {
@@ -209,7 +209,7 @@ impl AccessMap {
209209
if self.global_lock.load(std::sync::atomic::Ordering::Relaxed) {
210210
return false;
211211
}
212-
let key = key.as_usize();
212+
let key = key.as_index();
213213
let access = self.individual_accesses.try_entry(key);
214214
match access.map(Entry::or_default) {
215215
Some(mut entry) if entry.can_write() => {
@@ -244,7 +244,7 @@ impl AccessMap {
244244
/// # Panics
245245
/// if the access is released from a different thread than it was claimed from
246246
pub fn release_access<K: AccessMapKey>(&self, key: K) {
247-
let key = key.as_usize();
247+
let key = key.as_index();
248248
let access = self.individual_accesses.entry(key);
249249
match access {
250250
dashmap::mapref::entry::Entry::Occupied(mut entry) => {
@@ -274,7 +274,7 @@ impl AccessMap {
274274
pub fn list_accesses<K: AccessMapKey>(&self) -> Vec<(K, AccessCount)> {
275275
self.individual_accesses
276276
.iter()
277-
.map(|e| (K::from_usize(*e.key()), e.value().clone()))
277+
.map(|e| (K::from_index(*e.key()), e.value().clone()))
278278
.collect()
279279
}
280280

@@ -293,7 +293,7 @@ impl AccessMap {
293293
key: K,
294294
) -> Option<std::panic::Location<'static>> {
295295
self.individual_accesses
296-
.try_get(&key.as_usize())
296+
.try_get(&key.as_index())
297297
.try_unwrap()
298298
.and_then(|access| access.as_location())
299299
}
@@ -389,7 +389,7 @@ mod test {
389389
access_map.claim_read_access(0);
390390
access_map.claim_write_access(1);
391391

392-
let accesses = access_map.list_accesses::<usize>();
392+
let accesses = access_map.list_accesses::<u64>();
393393

394394
assert_eq!(accesses.len(), 2);
395395
let access_0 = accesses.iter().find(|(k, _)| *k == 0).unwrap();

crates/bevy_mod_scripting_core/src/bindings/allocator.rs

Lines changed: 34 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@ use std::collections::HashMap;
88
use std::fmt::{Display, Formatter};
99
use std::hash::Hasher;
1010
use std::io::Read;
11+
use std::sync::atomic::{AtomicU64, AtomicUsize};
1112
use std::sync::Arc;
1213

1314
#[derive(Clone, Debug)]
14-
pub struct ReflectAllocationId(pub(crate) Arc<usize>);
15+
pub struct ReflectAllocationId(pub(crate) Arc<u64>);
1516
impl ReflectAllocationId {
16-
pub fn id(&self) -> usize {
17+
pub fn id(&self) -> u64 {
1718
*self.0
1819
}
1920

2021
/// Creates a new [`ReflectAllocationId`] from its id
21-
pub(crate) fn new(id: usize) -> Self {
22+
pub(crate) fn new(id: u64) -> Self {
2223
Self(Arc::new(id))
2324
}
2425

@@ -139,7 +140,7 @@ impl AppReflectAllocator {
139140
pub struct ReflectAllocator {
140141
// TODO: experiment with object pools, sparse set etc.
141142
allocations: HashMap<ReflectAllocationId, ReflectAllocation>,
142-
types: HashMap<usize, TypeId>,
143+
types: HashMap<u64, TypeId>,
143144
}
144145

145146
impl ReflectAllocator {
@@ -150,9 +151,11 @@ impl ReflectAllocator {
150151
}
151152

152153
pub fn allocate_boxed(&mut self, value: Box<dyn PartialReflect>) -> ReflectAllocationId {
153-
let type_id = value.get_represented_type_info().map(|i| i.type_id());
154+
static COUNTER: AtomicU64 = AtomicU64::new(0);
154155

155-
let id = ReflectAllocationId::new(self.allocations.len());
156+
let type_id = value.get_represented_type_info().map(|i| i.type_id());
157+
let id =
158+
ReflectAllocationId::new(COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed));
156159
let index = id.id();
157160
let value = ReflectAllocation::new(value);
158161
self.allocations.insert(id.clone(), value);
@@ -161,34 +164,6 @@ impl ReflectAllocator {
161164
}
162165
id
163166
}
164-
165-
// /// Moves the given boxed [`PartialReflect`] value into the allocator, returning an [`AllocationId`] which can be used to access it later
166-
// pub fn allocate_boxed(
167-
// &mut self,
168-
// existing: Box<dyn PartialReflect>,
169-
// ) -> (ReflectAllocationId, ReflectAllocation) {
170-
// let type_id = existing.get_represented_type_info().map(|i| i.type_id());
171-
// let id = ReflectAllocationId(self.allocations.len());
172-
173-
// let raw_ptr = Box::into_raw(existing);
174-
// // Safety:
175-
// // - we are the only ones to have access to this value since we have the Box
176-
// // - UnsafeCell is repr(transparent), meaning we can safely transmute between it and the trait object
177-
// // TODO: I don't think we can use this, because from_raw has a pre-condition that requires the pointer to have been an arc before
178-
// let arc: Arc<UnsafeCell<dyn PartialReflect>> =
179-
// unsafe { Arc::from_raw(raw_ptr as *const _) };
180-
// let allocation = ReflectAllocation::new(arc);
181-
// self.allocations.insert(id, allocation.clone());
182-
// if let Some(type_id) = type_id {
183-
// self.types.insert(id, type_id);
184-
// }
185-
// (id, allocation)
186-
// }
187-
188-
// pub fn get(&self, id: &ReflectAllocationId) -> Option<ReflectAllocation> {
189-
// self.allocations.get(id).cloned()
190-
// }
191-
192167
pub fn insert(
193168
&mut self,
194169
id: ReflectAllocationId,
@@ -221,15 +196,14 @@ impl ReflectAllocator {
221196
/// Runs a garbage collection pass on the allocations, removing any allocations which have no more strong references
222197
/// Needs to be run periodically to prevent memory leaks
223198
pub fn clean_garbage_allocations(&mut self) {
224-
bevy::log::debug!("Cleaning garbage allocations");
225-
226-
self.allocations.retain(|k, _| {
227-
let retain = Arc::strong_count(&k.0) > 1;
228-
if !retain {
229-
bevy::log::debug!("Deallocating allocation {:?}", k);
230-
}
231-
retain
232-
});
199+
bevy::log::trace!("Cleaning garbage allocations");
200+
self.allocations.retain(|k, _| Arc::strong_count(&k.0) > 1);
201+
}
202+
203+
pub fn iter_allocations(
204+
&self,
205+
) -> impl Iterator<Item = (&ReflectAllocationId, &ReflectAllocation)> {
206+
self.allocations.iter()
233207
}
234208
}
235209

@@ -247,6 +221,23 @@ mod test {
247221
assert_eq!(allocator.allocations.len(), 0);
248222
}
249223

224+
#[test]
225+
fn test_reflect_allocator_allocate_clean_and_access_does_not_overwrite_id() {
226+
let mut allocator = ReflectAllocator::default();
227+
let id = allocator.allocate(0);
228+
let id2 = allocator.allocate("string");
229+
assert_eq!(allocator.allocations.len(), 2);
230+
drop(id);
231+
allocator.clean_garbage_allocations();
232+
assert_eq!(allocator.allocations.len(), 1);
233+
allocator.allocate(3);
234+
assert_eq!(allocator.allocations.len(), 2);
235+
236+
// Safety: only one reference to the allocation exists
237+
let ref_ = unsafe { &*allocator.get(&id2).unwrap().get_ptr() };
238+
assert!(ref_.reflect_partial_eq(&"string").unwrap());
239+
}
240+
250241
#[test]
251242
fn test_reflect_allocator_garbage_clean_no_garbage() {
252243
let mut allocator = ReflectAllocator::default();

0 commit comments

Comments
 (0)