Right, it's not done yet. This is a nicer workaround than the workaround we had before, essentially.
Patrick Bobby Holley <bobbyhol...@gmail.com> wrote: >To clarify, this stuff doesn't use the new inheritance stuff that's >going >into Rust, right? I assume that stuff isn't done yet? > > >On Thu, Dec 5, 2013 at 9:05 AM, Josh Matthews <j...@joshmatthews.net> >wrote: > >> For those who just want to see a before/after summary, here's an >example. >> >> BEFORE: we have to handwrite conversion routines for each downcast or >> upcast we want to use. Furthermore, we have the ugly >> AbstractDocument/AbstractNode/AbstractEvent/AbstractEventTarget >types, in >> addition to all of the concrete @mut SomeDOMType that are scattered >> everywhere. >> >> impl AbstractNode<ScriptView> { >> /// Allow consumers to upcast from derived classes. >> pub fn from_document(doc: AbstractDocument) -> >AbstractNode<View> { >> unsafe { >> cast::transmute(doc) >> } >> } >> >> pub fn from_eventtarget(target: AbstractEventTarget) -> >> tractNode<View> { >> assert!(target.is_node()); >> unsafe { >> cast::transmute(target) >> } >> } >> } >> >> 788 let doctarget = >AbstractEventTarget::from_document(document); >> 789 let wintarget = AbstractEventTarget::from_window(window); >> 790 window.eventtarget.dispatch_event_with_target(wintarget, >> Some(doctarget), event); >> >> 307 if child.is_element() { >> 308 do child.with_imm_element |elem| { >> 309 if callback(elem) { >> 310 elements.push(child); >> 311 } >> 312 } >> 313 } >> >> >> AFTER all casting methods are automatically generated; all that's >left is >> writing the is_foo method and ensuring that we can tell the concrete >type >> of a DOM object based on the root type in an inheritance chain: >> >> impl UIEventDerived for Event { >> fn is_uievent(&self) -> bool { >> self.type_id == UIEventTypeId >> } >> } >> >> let doctarget = EventTargetCast::from(document); >> let wintarget = EventTargetCast::from(window); >> window.eventtarget.dispatch_event_with_target(wintarget, >Some(doctarget), >> event); >> >> if child.is_element() { >> let elem = ElementCast::to(child); >> if callback(elem) { >> elements.push(elem); >> } >> } >> >> In my mind, the biggest improvement here is that we can actually have >> lists of JSManaged<Element>, whereas before we could only store >> ~[AbstractNode] with the handwave-y guarantee that all of the nodes >should >> also be elements. I also find the new checked casts much nicer to >read (and >> yes, the downcasts assert at runtime if the value passed is not an >instance >> of the desired type). >> >> Cheers, >> Josh >> >> >> On 12/03/2013 03:07 AM, Josh Matthews wrote: >> >>> Ms2ger and I have been working on this on and off, and the Event >>> hierarchy is looking very nice so far: >>> https://github.com/jdm/servo/commits/jsmanaged . It even builds and >>> passes tests, so we should be able to continue converting this >>> piece-by-piece. There is an absolute minimum amount of boilerplate >>> required now, which is lovely. >>> >>> Cheers, >>> Josh >>> >>> On 11/28/2013 10:54 AM, Josh Matthews wrote: >>> >>>> I've finally got a sketch of my plans to remove all of the @mut >>>> annotations from Servo's DOM. You can see it at >>>> https://gist.github.com/jdm/7693770, but here's the breakdown of >the >>>> improvements: >>>> >>>> * no more AbstractNode (\o/) - we can actually use >JSManaged<Element> >>>> when we want to refer to something derived from Element now. >>>> * actually fulfils the contract that the SpiderMonkey GC owns the >sole >>>> reference >>>> * no need to add as_foo methods for downcasting >>>> >>>> Breaking it down further, one of the biggest changes is in the >>>> implementation of downcasting and upcasting. Upcasting a >JSManaged<Foo> >>>> to a JSManaged<Bar> is a statically-checked operation that should >be >>>> free at runtime. This is enforced by a series of empty traits that >each >>>> derived class much implement (ie. see EventTargetBase), such that >any >>>> value passed to Bar::from() must be a type that implements BarBase. >In a >>>> similar fashion, downcasting is also statically-checked (does the >cast >>>> even make sense?), before performing a dynamic assertion (is this >base >>>> class actually an instance of the derived type?). Therefore, when >>>> calling Foo::to(), the value passed must implement the FooDerived >trait >>>> with an appropriate boolean is_foo method implemented. >>>> >>>> These casting changes may not look like a big improvement at first, >but >>>> the important consideration is the the upcasting traits can be >>>> automatically generated completely from WebIDL definitions, so that >>>> boilerplate should be essentially free. For downcasting, each type >that >>>> is on an inheritance chain will need to implement a single trait >with a >>>> single boolean method that performs the required dynamic check; all >>>> other boilerplate can also be generated from WebIDL definitions, >and is >>>> therefore essentially free. >>>> >>>> I welcome feedback about this sketch. For a quick look at how it >can be >>>> used by consumers, see main() in jsgc.rs. >>>> >>>> Cheers, >>>> Josh >>>> >>> >>> >> _______________________________________________ >> dev-servo mailing list >> dev-servo@lists.mozilla.org >> https://lists.mozilla.org/listinfo/dev-servo >> >_______________________________________________ >dev-servo mailing list >dev-servo@lists.mozilla.org >https://lists.mozilla.org/listinfo/dev-servo -- Sent from my Android phone with K-9 Mail. Please excuse my brevity. _______________________________________________ dev-servo mailing list dev-servo@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-servo