Skip to content

Commit 1437ea7

Browse files
committed
history: Use OnceCell instead of RefCell<Option<_>> for thread locals
1 parent ff19d20 commit 1437ea7

File tree

2 files changed

+49
-62
lines changed

2 files changed

+49
-62
lines changed

crates/history/src/browser.rs

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::any::Any;
22
use std::borrow::Cow;
3-
use std::cell::RefCell;
3+
use std::cell::{OnceCell, RefCell};
44
use std::fmt;
55
use std::rc::Rc;
66

@@ -250,46 +250,40 @@ impl Default for BrowserHistory {
250250
fn default() -> Self {
251251
// We create browser history only once.
252252
thread_local! {
253-
static BROWSER_HISTORY: RefCell<Option<BrowserHistory>> = RefCell::default();
254-
static LISTENER: RefCell<Option<EventListener>> = RefCell::default();
253+
static BROWSER_HISTORY: OnceCell<BrowserHistory> = OnceCell::default();
254+
static LISTENER: OnceCell<EventListener> = OnceCell::default();
255255
}
256256

257-
BROWSER_HISTORY.with(|m| {
258-
let mut m = m.borrow_mut();
259-
260-
match *m {
261-
Some(ref m) => m.clone(),
262-
None => {
263-
let window = window();
264-
265-
let inner = window
266-
.history()
267-
.expect_throw("Failed to create browser history. Are you using a browser?");
268-
let callbacks = Rc::default();
269-
270-
let history = Self {
271-
inner,
272-
callbacks,
273-
states: Rc::default(),
274-
};
275-
276-
{
277-
let history = history.clone();
278-
279-
// Listens to popstate.
280-
LISTENER.with(move |m| {
281-
let mut listener = m.borrow_mut();
282-
283-
*listener = Some(EventListener::new(&window, "popstate", move |_| {
284-
history.notify_callbacks();
285-
}));
286-
});
287-
}
288-
289-
*m = Some(history.clone());
290-
history
257+
BROWSER_HISTORY.with(|b| {
258+
b.get_or_init(|| {
259+
let window = window();
260+
261+
let inner = window
262+
.history()
263+
.expect_throw("Failed to create browser history. Are you using a browser?");
264+
let callbacks = Rc::default();
265+
266+
let history = Self {
267+
inner,
268+
callbacks,
269+
states: Rc::default(),
270+
};
271+
272+
{
273+
let history = history.clone();
274+
275+
// Listens to popstate.
276+
LISTENER.with(move |l| {
277+
l.set(EventListener::new(&window, "popstate", move |_| {
278+
history.notify_callbacks();
279+
}))
280+
.expect("this function is only called once");
281+
});
291282
}
292-
}
283+
284+
history
285+
})
286+
.clone()
293287
})
294288
}
295289
}

crates/history/src/hash.rs

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::borrow::Cow;
2-
use std::cell::RefCell;
2+
use std::cell::OnceCell;
33
use std::fmt;
44

55
use gloo_utils::window;
@@ -238,36 +238,29 @@ impl HashHistory {
238238
impl Default for HashHistory {
239239
fn default() -> Self {
240240
thread_local! {
241-
static HASH_HISTORY: RefCell<Option<HashHistory>> = RefCell::default();
241+
static HASH_HISTORY: OnceCell<HashHistory> = OnceCell::default();
242242
}
243243

244-
HASH_HISTORY.with(|m| {
245-
let mut m = m.borrow_mut();
244+
HASH_HISTORY.with(|h| {
245+
h.get_or_init(|| {
246+
let browser_history = BrowserHistory::new();
247+
let browser_location = browser_history.location();
246248

247-
match *m {
248-
Some(ref m) => m.clone(),
249-
None => {
250-
let browser_history = BrowserHistory::new();
251-
let browser_location = browser_history.location();
249+
let current_hash = browser_location.hash();
252250

253-
let current_hash = browser_location.hash();
251+
// Hash needs to start with #/.
252+
if current_hash.is_empty() || !current_hash.starts_with("#/") {
253+
let url = Self::get_url();
254+
url.set_hash("#/");
254255

255-
// Hash needs to start with #/.
256-
if current_hash.is_empty() || !current_hash.starts_with("#/") {
257-
let url = Self::get_url();
258-
url.set_hash("#/");
259-
260-
browser_history.replace(url.href());
261-
}
262-
263-
let history = Self {
264-
inner: browser_history,
265-
};
256+
browser_history.replace(url.href());
257+
}
266258

267-
*m = Some(history.clone());
268-
history
259+
Self {
260+
inner: browser_history,
269261
}
270-
}
262+
})
263+
.clone()
271264
})
272265
}
273266
}

0 commit comments

Comments
 (0)