mirror of
https://github.com/servo/servo.git
synced 2025-06-14 03:14:29 +00:00
Use internal mutability for Window::{active_timers, next_timer_handle}.
This commit is contained in:
parent
07c67a1d5a
commit
e9b64dc361
2 changed files with 35 additions and 38 deletions
|
@ -73,8 +73,8 @@ pub struct Window {
|
||||||
pub location: Cell<Option<JS<Location>>>,
|
pub location: Cell<Option<JS<Location>>>,
|
||||||
pub navigator: Cell<Option<JS<Navigator>>>,
|
pub navigator: Cell<Option<JS<Navigator>>>,
|
||||||
pub image_cache_task: ImageCacheTask,
|
pub image_cache_task: ImageCacheTask,
|
||||||
pub active_timers: Box<HashMap<TimerId, TimerHandle>>,
|
pub active_timers: Traceable<RefCell<HashMap<TimerId, TimerHandle>>>,
|
||||||
pub next_timer_handle: i32,
|
pub next_timer_handle: Untraceable<Cell<i32>>,
|
||||||
pub compositor: Untraceable<Box<ScriptListener>>,
|
pub compositor: Untraceable<Box<ScriptListener>>,
|
||||||
pub browser_context: Traceable<RefCell<Option<BrowserContext>>>,
|
pub browser_context: Traceable<RefCell<Option<BrowserContext>>>,
|
||||||
pub page: Rc<Page>,
|
pub page: Rc<Page>,
|
||||||
|
@ -100,7 +100,7 @@ impl Window {
|
||||||
#[unsafe_destructor]
|
#[unsafe_destructor]
|
||||||
impl Drop for Window {
|
impl Drop for Window {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
for (_, timer_handle) in self.active_timers.mut_iter() {
|
for (_, timer_handle) in self.active_timers.borrow_mut().mut_iter() {
|
||||||
timer_handle.cancel();
|
timer_handle.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,10 +122,10 @@ pub trait WindowMethods {
|
||||||
fn Location(&self) -> Temporary<Location>;
|
fn Location(&self) -> Temporary<Location>;
|
||||||
fn Console(&self) -> Temporary<Console>;
|
fn Console(&self) -> Temporary<Console>;
|
||||||
fn Navigator(&self) -> Temporary<Navigator>;
|
fn Navigator(&self) -> Temporary<Navigator>;
|
||||||
fn SetTimeout(&mut self, _cx: *mut JSContext, callback: JSVal, timeout: i32) -> i32;
|
fn SetTimeout(&self, _cx: *mut JSContext, callback: JSVal, timeout: i32) -> i32;
|
||||||
fn ClearTimeout(&mut self, handle: i32);
|
fn ClearTimeout(&self, handle: i32);
|
||||||
fn SetInterval(&mut self, _cx: *mut JSContext, callback: JSVal, timeout: i32) -> i32;
|
fn SetInterval(&self, _cx: *mut JSContext, callback: JSVal, timeout: i32) -> i32;
|
||||||
fn ClearInterval(&mut self, handle: i32);
|
fn ClearInterval(&self, handle: i32);
|
||||||
fn Window(&self) -> Temporary<Window>;
|
fn Window(&self) -> Temporary<Window>;
|
||||||
fn Self(&self) -> Temporary<Window>;
|
fn Self(&self) -> Temporary<Window>;
|
||||||
fn Performance(&self) -> Temporary<Performance>;
|
fn Performance(&self) -> Temporary<Performance>;
|
||||||
|
@ -182,24 +182,25 @@ impl<'a> WindowMethods for JSRef<'a, Window> {
|
||||||
Temporary::new(self.navigator.get().get_ref().clone())
|
Temporary::new(self.navigator.get().get_ref().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SetTimeout(&mut self, _cx: *mut JSContext, callback: JSVal, timeout: i32) -> i32 {
|
fn SetTimeout(&self, _cx: *mut JSContext, callback: JSVal, timeout: i32) -> i32 {
|
||||||
self.set_timeout_or_interval(callback, timeout, false)
|
self.set_timeout_or_interval(callback, timeout, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ClearTimeout(&mut self, handle: i32) {
|
fn ClearTimeout(&self, handle: i32) {
|
||||||
let mut timer_handle = self.active_timers.pop(&TimerId(handle));
|
let mut timers = self.active_timers.deref().borrow_mut();
|
||||||
|
let mut timer_handle = timers.pop(&TimerId(handle));
|
||||||
match timer_handle {
|
match timer_handle {
|
||||||
Some(ref mut handle) => handle.cancel(),
|
Some(ref mut handle) => handle.cancel(),
|
||||||
None => { }
|
None => { }
|
||||||
}
|
}
|
||||||
self.active_timers.remove(&TimerId(handle));
|
timers.remove(&TimerId(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SetInterval(&mut self, _cx: *mut JSContext, callback: JSVal, timeout: i32) -> i32 {
|
fn SetInterval(&self, _cx: *mut JSContext, callback: JSVal, timeout: i32) -> i32 {
|
||||||
self.set_timeout_or_interval(callback, timeout, true)
|
self.set_timeout_or_interval(callback, timeout, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ClearInterval(&mut self, handle: i32) {
|
fn ClearInterval(&self, handle: i32) {
|
||||||
self.ClearTimeout(handle);
|
self.ClearTimeout(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +289,7 @@ pub trait WindowHelpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PrivateWindowHelpers {
|
trait PrivateWindowHelpers {
|
||||||
fn set_timeout_or_interval(&mut self, callback: JSVal, timeout: i32, is_interval: bool) -> i32;
|
fn set_timeout_or_interval(&self, callback: JSVal, timeout: i32, is_interval: bool) -> i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> WindowHelpers for JSRef<'a, Window> {
|
impl<'a> WindowHelpers for JSRef<'a, Window> {
|
||||||
|
@ -325,10 +326,10 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PrivateWindowHelpers for JSRef<'a, Window> {
|
impl<'a> PrivateWindowHelpers for JSRef<'a, Window> {
|
||||||
fn set_timeout_or_interval(&mut self, callback: JSVal, timeout: i32, is_interval: bool) -> i32 {
|
fn set_timeout_or_interval(&self, callback: JSVal, timeout: i32, is_interval: bool) -> i32 {
|
||||||
let timeout = cmp::max(0, timeout) as u64;
|
let timeout = cmp::max(0, timeout) as u64;
|
||||||
let handle = self.next_timer_handle;
|
let handle = self.next_timer_handle.deref().get();
|
||||||
self.next_timer_handle += 1;
|
self.next_timer_handle.deref().set(handle + 1);
|
||||||
|
|
||||||
// Post a delayed message to the per-window timer task; it will dispatch it
|
// Post a delayed message to the per-window timer task; it will dispatch it
|
||||||
// to the relevant script handler that will deal with it.
|
// to the relevant script handler that will deal with it.
|
||||||
|
@ -379,7 +380,7 @@ impl<'a> PrivateWindowHelpers for JSRef<'a, Window> {
|
||||||
funval: Traceable::new(callback),
|
funval: Traceable::new(callback),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.active_timers.insert(timer_id, timer);
|
self.active_timers.deref().borrow_mut().insert(timer_id, timer);
|
||||||
handle
|
handle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,8 +401,8 @@ impl Window {
|
||||||
location: Cell::new(None),
|
location: Cell::new(None),
|
||||||
navigator: Cell::new(None),
|
navigator: Cell::new(None),
|
||||||
image_cache_task: image_cache_task,
|
image_cache_task: image_cache_task,
|
||||||
active_timers: box HashMap::new(),
|
active_timers: Traceable::new(RefCell::new(HashMap::new())),
|
||||||
next_timer_handle: 0,
|
next_timer_handle: Untraceable::new(Cell::new(0)),
|
||||||
browser_context: Traceable::new(RefCell::new(None)),
|
browser_context: Traceable::new(RefCell::new(None)),
|
||||||
performance: Cell::new(None),
|
performance: Cell::new(None),
|
||||||
navigationStart: time::get_time().sec as u64,
|
navigationStart: time::get_time().sec as u64,
|
||||||
|
|
|
@ -817,31 +817,27 @@ impl ScriptTask {
|
||||||
let page = page.find(id).expect("ScriptTask: received fire timer msg for a
|
let page = page.find(id).expect("ScriptTask: received fire timer msg for a
|
||||||
pipeline ID not associated with this script task. This is a bug.");
|
pipeline ID not associated with this script task. This is a bug.");
|
||||||
let frame = page.frame();
|
let frame = page.frame();
|
||||||
let mut window = frame.get_ref().window.root();
|
let window = frame.get_ref().window.root();
|
||||||
|
|
||||||
let this_value = window.deref().reflector().get_jsobject();
|
let this_value = window.deref().reflector().get_jsobject();
|
||||||
|
|
||||||
let is_interval;
|
let data = match window.deref().active_timers.deref().borrow().find(&timer_id) {
|
||||||
match window.deref().active_timers.find(&timer_id) {
|
|
||||||
None => return,
|
None => return,
|
||||||
Some(timer_handle) => {
|
Some(timer_handle) => timer_handle.data,
|
||||||
// TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`.
|
};
|
||||||
let cx = self.get_cx();
|
|
||||||
with_compartment(cx, this_value, || {
|
|
||||||
let mut rval = NullValue();
|
|
||||||
unsafe {
|
|
||||||
JS_CallFunctionValue(cx, this_value,
|
|
||||||
*timer_handle.data.funval,
|
|
||||||
0, ptr::mut_null(), &mut rval);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
is_interval = timer_handle.data.is_interval;
|
// TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`.
|
||||||
|
let cx = self.get_cx();
|
||||||
|
with_compartment(cx, this_value, || {
|
||||||
|
let mut rval = NullValue();
|
||||||
|
unsafe {
|
||||||
|
JS_CallFunctionValue(cx, this_value, *data.funval,
|
||||||
|
0, ptr::mut_null(), &mut rval);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if !is_interval {
|
if !data.is_interval {
|
||||||
window.deref_mut().active_timers.remove(&timer_id);
|
window.deref().active_timers.deref().borrow_mut().remove(&timer_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue