diff options
-rw-r--r-- | components/compositing/Cargo.toml | 3 | ||||
-rw-r--r-- | components/devtools/actor.rs | 67 | ||||
-rw-r--r-- | components/servo/Cargo.lock | 1 |
3 files changed, 59 insertions, 12 deletions
diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index 194e07ba7aa..39c00d31445 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -25,9 +25,6 @@ path = "../net" [dependencies.util] path = "../util" -[dependencies.devtools] -path = "../devtools" - [dependencies.devtools_traits] path = "../devtools_traits" diff --git a/components/devtools/actor.rs b/components/devtools/actor.rs index 2b4f408cd45..8fc9eecd055 100644 --- a/components/devtools/actor.rs +++ b/components/devtools/actor.rs @@ -7,14 +7,16 @@ use std::any::Any; use std::collections::HashMap; use std::cell::{Cell, RefCell}; +use std::intrinsics::TypeId; use std::io::TcpStream; -use std::mem::replace; +use std::mem::{replace, transmute}; +use std::raw::TraitObject; use serialize::json; /// A common trait for all devtools actors that encompasses an immutable name /// and the ability to process messages that are directed to particular actors. /// TODO: ensure the name is immutable -pub trait Actor : Any { +pub trait Actor: Any { fn handle_message(&self, registry: &ActorRegistry, msg_type: &String, @@ -23,10 +25,59 @@ pub trait Actor : Any { fn name(&self) -> String; } +impl Actor { + /// Returns true if the boxed type is the same as `T` + #[inline] + pub fn is<T: 'static>(&self) -> bool { + // Get TypeId of the type this function is instantiated with + let t = TypeId::of::<T>(); + + // Get TypeId of the type in the trait object + let boxed = self.get_type_id(); + + // Compare both TypeIds on equality + t == boxed + } + + /// Returns some reference to the boxed value if it is of type `T`, or + /// `None` if it isn't. + #[inline] + pub fn downcast_ref<T: 'static>(&self) -> Option<&T> { + if self.is::<T>() { + unsafe { + // Get the raw representation of the trait object + let to: TraitObject = transmute(self); + + // Extract the data pointer + Some(transmute(to.data)) + } + } else { + None + } + } + + /// Returns some mutable reference to the boxed value if it is of type `T`, or + /// `None` if it isn't. + #[inline] + pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> { + if self.is::<T>() { + unsafe { + // Get the raw representation of the trait object + let to: TraitObject = transmute(self); + + // Extract the data pointer + Some(transmute(to.data)) + } + } else { + None + } + } +} + /// A list of known, owned actors. pub struct ActorRegistry { - actors: HashMap<String, Box<Actor+Send+Sized>>, - new_actors: RefCell<Vec<Box<Actor+Send+Sized>>>, + actors: HashMap<String, Box<Actor+Send>>, + new_actors: RefCell<Vec<Box<Actor+Send>>>, script_actors: RefCell<HashMap<String, String>>, next: Cell<u32>, } @@ -77,24 +128,24 @@ impl ActorRegistry { } /// Add an actor to the registry of known actors that can receive messages. - pub fn register(&mut self, actor: Box<Actor+Send+Sized>) { + pub fn register(&mut self, actor: Box<Actor+Send>) { self.actors.insert(actor.name().to_string(), actor); } - pub fn register_later(&self, actor: Box<Actor+Send+Sized>) { + pub fn register_later(&self, actor: Box<Actor+Send>) { let mut actors = self.new_actors.borrow_mut(); actors.push(actor); } /// Find an actor by registered name pub fn find<'a, T: 'static>(&'a self, name: &str) -> &'a T { - let actor: &Any = self.actors.get(&name.to_string()).unwrap(); + let actor = self.actors.get(&name.to_string()).unwrap(); actor.downcast_ref::<T>().unwrap() } /// Find an actor by registered name pub fn find_mut<'a, T: 'static>(&'a mut self, name: &str) -> &'a mut T { - let actor: &mut Any = self.actors.get_mut(&name.to_string()).unwrap(); + let actor = self.actors.get_mut(&name.to_string()).unwrap(); actor.downcast_mut::<T>().unwrap() } diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index f799f63a952..2e21d3c82ce 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -81,7 +81,6 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)", "core_text 0.1.0 (git+https://github.com/servo/rust-core-text)", - "devtools 0.0.1", "devtools_traits 0.0.1", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", |