And of course I forgot to reply to the list at large... sorry :x -- Matthieu
On Wed, Mar 12, 2014 at 8:48 PM, Matthieu Monrocq < matthieu.monr...@gmail.com> wrote: > > > > On Tue, Mar 11, 2014 at 10:18 PM, Patrick Walton <pcwal...@mozilla.com>wrote: > >> On 3/11/14 2:15 PM, Maciej Piechotka wrote: >> >>> Could you elaborate on DOM? I saw it referred a few times but I haven't >>> seen any details. I wrote simple bindings to libxml2 dom >>> (https://github.com/uzytkownik/xml-rs - warning - I wrote it while I was >>> learning ruby) and I don't think there was a problem of OO - main >>> problem was mapping libxml memory management and rust's one [I gave up >>> with namespaces but with native rust dom implementation it would be >>> possible to solve in nicer way]. Of course - I might've been at too >>> early stage. >>> >> >> You need: >> >> 1. One-word pointers to each DOM node, not two. Every DOM node has 5 >> pointers inside (parent, first child, last child, next sibling, previous >> sibling). Using trait objects would 10 words, not 5 words, and would >> constitute a large memory regression over current browser engines. >> >> 2. Access to fields common to every instance of a trait without virtual >> dispatch. Otherwise the browser will be at a significant performance >> disadvantage relative to other engines. >> >> 3. Downcasting and upcasting. >> >> 4. Inheritance with the prefix property, to allow for (2). >> >> If anyone has alternative proposals that handle these constraints that >> are more orthogonal and are pleasant to use, then I'm happy to hear them. >> I'm just saying that dismissing the feature out of hand is not productive. >> >> >> Patrick >> >> > Please excuse me, I need some kind of visualization here, so I concocted a > simple tree: > > // So, in pseudo C++, let's imagine a DOM tree > struct Element { Element *parent, *prevSib, *nextSib, *firstChild, > *lastChild; uint leftPos, topPos, height, width; bool hidden; }; > struct Block: Element { BlockProperties blockP; }; struct Div: Block {}; > struct Inline: Element { InlineProperties inlineP; }; struct Span: Inline > {}; > > > Now, I'll be basically mimicking the way LLVM structures its AST, since > the LLVM AST achieves dynamic casting without RTTI. Note that this has a > very specific downside: the hierarchy is NOT extensible. > > // And now in Rust (excuse my poor syntax/errors) > enum ElementChild<'r> { ChildBlock(&'r Block), ChildInline(&'r Inline) } > > struct Element { > child: Option<&'self ElementChild<'self>>; > parent: &'self Element; > prevSib, nextSib, firstChild, lastChild: Option<&'self Element>; > leftPos, topPos, height, width: uint; > hidden: bool; > } > > > enum BlockChild<'r> { ChildDiv(&'r Div) } > > struct Block { > elementBase: Element; > child: Option<&'self BlockChild<'self>>; > blockP: BlockProperties; > } > > struct Div { blockBase: Block; } > > > enum InlineChild<'r> { ChildSpan(&'r Span) } > > struct Inline { > elementBase: Element; > child: Option<&'self InlineChild<'self>>; > inlineP: InlineProperties; > } > > struct Span { inlineBase: Inline; } > > > Let us review our objectives: > > (1) One word to each DOM element: check => Option<&'r Element> > > (2) Direct access to a field, without indirection: check => > span.inlineBase.elementBase.hidden > > (3) Downcast and upcasting: check => downcast is done by matching: > match(element.child) { ChildBlock(&'r block) => /* act on block */, > ChildInline(&'r inline) => /* act on inline */); upcast is just accessing > the "base" field. > > (4) Inheritance with the prefix property => not necessary, (2) is already > satisfied. > > > Note on (3): multiple bases are allowed easily, it's one field per base. > > > In order to reduce the foot-print; avoiding having a "child" field at each > level of the hierarchy might be beneficial. In this case, only the final > classes are considered in ElementChild > > enum ElementChild<'r> { ChildDiv(&'r Div), ChildSpan(&'r Span) } > > And then downcasting to &'r Block is achieved by: > > match(element.final) { ChildDiv(&'r div) => Some(&'r div.blockBase), _ => > None } > > > I would note that this does not make use of traits at all; the analysis is > only based on Patrick's list of objectives which I guess is incomplete and > I was lacking a realistic example so it might not address the full scope of > the problem... > > ... still, for CLOSED hierarchies, the use of traits should not be > necessary, although it might be very convenient. > > -- Matthieu. > > >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev@mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > >
_______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev