Don't remove entities whose ref count has become positive again

This commit is contained in:
Nathan Sobo 2021-05-12 19:29:17 -06:00
parent e81a28e57e
commit 9dac491ed5

View File

@ -18,7 +18,7 @@ use smol::prelude::*;
use std::{ use std::{
any::{type_name, Any, TypeId}, any::{type_name, Any, TypeId},
cell::RefCell, cell::RefCell,
collections::{HashMap, HashSet, VecDeque}, collections::{hash_map::Entry, HashMap, HashSet, VecDeque},
fmt::{self, Debug}, fmt::{self, Debug},
hash::{Hash, Hasher}, hash::{Hash, Hasher},
marker::PhantomData, marker::PhantomData,
@ -1988,7 +1988,7 @@ pub struct ModelHandle<T> {
impl<T: Entity> ModelHandle<T> { impl<T: Entity> ModelHandle<T> {
fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self { fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
ref_counts.lock().inc_entity(model_id); ref_counts.lock().inc_model(model_id);
Self { Self {
model_id, model_id,
model_type: PhantomData, model_type: PhantomData,
@ -2089,7 +2089,7 @@ impl<T: Entity> ModelHandle<T> {
impl<T> Clone for ModelHandle<T> { impl<T> Clone for ModelHandle<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
self.ref_counts.lock().inc_entity(self.model_id); self.ref_counts.lock().inc_model(self.model_id);
Self { Self {
model_id: self.model_id, model_id: self.model_id,
model_type: PhantomData, model_type: PhantomData,
@ -2186,7 +2186,7 @@ pub struct ViewHandle<T> {
impl<T: View> ViewHandle<T> { impl<T: View> ViewHandle<T> {
fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self { fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
ref_counts.lock().inc_entity(view_id); ref_counts.lock().inc_view(window_id, view_id);
Self { Self {
window_id, window_id,
view_id, view_id,
@ -2298,7 +2298,9 @@ impl<T: View> ViewHandle<T> {
impl<T> Clone for ViewHandle<T> { impl<T> Clone for ViewHandle<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
self.ref_counts.lock().inc_entity(self.view_id); self.ref_counts
.lock()
.inc_view(self.window_id, self.view_id);
Self { Self {
window_id: self.window_id, window_id: self.window_id,
view_id: self.view_id, view_id: self.view_id,
@ -2380,7 +2382,9 @@ impl AnyViewHandle {
impl Clone for AnyViewHandle { impl Clone for AnyViewHandle {
fn clone(&self) -> Self { fn clone(&self) -> Self {
self.ref_counts.lock().inc_entity(self.view_id); self.ref_counts
.lock()
.inc_view(self.window_id, self.view_id);
Self { Self {
window_id: self.window_id, window_id: self.window_id,
view_id: self.view_id, view_id: self.view_id,
@ -2392,7 +2396,10 @@ impl Clone for AnyViewHandle {
impl<T: View> From<&ViewHandle<T>> for AnyViewHandle { impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
fn from(handle: &ViewHandle<T>) -> Self { fn from(handle: &ViewHandle<T>) -> Self {
handle.ref_counts.lock().inc_entity(handle.view_id); handle
.ref_counts
.lock()
.inc_view(handle.window_id, handle.view_id);
AnyViewHandle { AnyViewHandle {
window_id: handle.window_id, window_id: handle.window_id,
view_id: handle.view_id, view_id: handle.view_id,
@ -2433,7 +2440,7 @@ pub struct AnyModelHandle {
impl<T: Entity> From<ModelHandle<T>> for AnyModelHandle { impl<T: Entity> From<ModelHandle<T>> for AnyModelHandle {
fn from(handle: ModelHandle<T>) -> Self { fn from(handle: ModelHandle<T>) -> Self {
handle.ref_counts.lock().inc_entity(handle.model_id); handle.ref_counts.lock().inc_model(handle.model_id);
Self { Self {
model_id: handle.model_id, model_id: handle.model_id,
ref_counts: handle.ref_counts.clone(), ref_counts: handle.ref_counts.clone(),
@ -2542,8 +2549,24 @@ struct RefCounts {
} }
impl RefCounts { impl RefCounts {
fn inc_entity(&mut self, entity_id: usize) { fn inc_model(&mut self, model_id: usize) {
*self.entity_counts.entry(entity_id).or_insert(0) += 1; match self.entity_counts.entry(model_id) {
Entry::Occupied(mut entry) => *entry.get_mut() += 1,
Entry::Vacant(entry) => {
entry.insert(1);
self.dropped_models.remove(&model_id);
}
}
}
fn inc_view(&mut self, window_id: usize, view_id: usize) {
match self.entity_counts.entry(view_id) {
Entry::Occupied(mut entry) => *entry.get_mut() += 1,
Entry::Vacant(entry) => {
entry.insert(1);
self.dropped_views.remove(&(window_id, view_id));
}
}
} }
fn inc_value(&mut self, tag_type_id: TypeId, id: usize) { fn inc_value(&mut self, tag_type_id: TypeId, id: usize) {