[librsvg] The C-side representation of Nodes is a Box<Rc<Node>>



commit a7ae2be3ee40a9560f1ad571a65a7c608a3f9726
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Feb 9 15:42:46 2017 -0600

    The C-side representation of Nodes is a Box<Rc<Node>>
    
    A refcounted node, in the heap.  Just like a GObject.
    
    The rest of the code doesn't compile yet; this just fixes cnode.rs and
    node.rs to hopefully their semi-final versions.

 rust/src/cnode.rs   |   38 +++++++++++++++-----------------
 rust/src/node.rs    |   58 +++++++++++++++++++++++---------------------------
 rust/src/pattern.rs |    2 +-
 rust/src/shapes.rs  |    4 +-
 4 files changed, 48 insertions(+), 54 deletions(-)
---
diff --git a/rust/src/cnode.rs b/rust/src/cnode.rs
index c998f66..7dd6bfd 100644
--- a/rust/src/cnode.rs
+++ b/rust/src/cnode.rs
@@ -3,17 +3,16 @@ use handle::*;
 use node::*;
 use property_bag::RsvgPropertyBag;
 use state::RsvgState;
-use std::rc::Rc;
-use std::rc::Weak;
-use std::cell::RefCell;
+
+use std::rc::*;
 
 /* A *const RsvgCNodeImpl is just an opaque pointer to the C code's
  * struct for a particular node type.
  */
 pub enum RsvgCNodeImpl {}
 
-type CNodeSetAtts = unsafe extern "C" fn (node: *const RsvgRcNode, node_impl: *const RsvgCNodeImpl, handle: 
*const RsvgHandle, pbag: *const RsvgPropertyBag);
-type CNodeDraw = unsafe extern "C" fn (node: *const RsvgRcNode, node_impl: *const RsvgCNodeImpl, draw_ctx: 
*const RsvgDrawingCtx, dominate: i32);
+type CNodeSetAtts = unsafe extern "C" fn (node: *const RsvgNode, node_impl: *const RsvgCNodeImpl, handle: 
*const RsvgHandle, pbag: *const RsvgPropertyBag);
+type CNodeDraw = unsafe extern "C" fn (node: *const RsvgNode, node_impl: *const RsvgCNodeImpl, draw_ctx: 
*const RsvgDrawingCtx, dominate: i32);
 type CNodeFree = unsafe extern "C" fn (node_impl: *const RsvgCNodeImpl);
 
 struct CNode {
@@ -25,12 +24,12 @@ struct CNode {
 }
 
 impl NodeTrait for CNode {
-    fn set_atts (&self, node: &RsvgRcNode, handle: *const RsvgHandle, pbag: *const RsvgPropertyBag) {
-        unsafe { (self.set_atts_fn) (node as *const RsvgRcNode, self.c_node_impl, handle, pbag); }
+    fn set_atts (&self, node: &RsvgNode, handle: *const RsvgHandle, pbag: *const RsvgPropertyBag) {
+        unsafe { (self.set_atts_fn) (node as *const RsvgNode, self.c_node_impl, handle, pbag); }
     }
 
-    fn draw (&self, node: &RsvgRcNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
-        unsafe { (self.draw_fn) (node as *const RsvgRcNode, self.c_node_impl, draw_ctx, dominate); }
+    fn draw (&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+        unsafe { (self.draw_fn) (node as *const RsvgNode, self.c_node_impl, draw_ctx, dominate); }
     }
 }
 
@@ -42,22 +41,22 @@ impl Drop for CNode {
 
 #[no_mangle]
 pub extern fn rsvg_rust_cnode_new (node_type:   NodeType,
-                                   raw_parent:  *const RsvgRcNode,
+                                   raw_parent:  *const RsvgNode,
                                    state:       *mut RsvgState,
                                    c_node_impl: *const RsvgCNodeImpl,
                                    set_atts_fn: CNodeSetAtts,
                                    draw_fn:     CNodeDraw,
-                                   free_fn:     CNodeFree) -> *const RsvgRcNode {
+                                   free_fn:     CNodeFree) -> *const RsvgNode {
     assert! (!state.is_null ());
     assert! (!c_node_impl.is_null ());
 
-    let parent: Option<Weak<RefCell<Node>>> = unsafe {
+    let parent: Option<Weak<Node>> =
         if raw_parent.is_null () {
             None
         } else {
-            Some (Rc::downgrade (&*(raw_parent as *const RsvgRcNode)))
-        }
-    };
+            let p: &RsvgNode = unsafe { & *raw_parent };
+            Some (Rc::downgrade (&p.clone ()))
+        };
 
     let cnode = CNode {
         c_node_impl: c_node_impl,
@@ -66,9 +65,8 @@ pub extern fn rsvg_rust_cnode_new (node_type:   NodeType,
         free_fn:     free_fn
     };
 
-    &Rc::new (RefCell::new (Node::new (node_type,
-                                        parent,
-                                        state,
-                                       Box::new (cnode))))
-        as *const RsvgRcNode
+    Box::into_raw (Box::new (Rc::new (Node::new (node_type,
+                                                 parent,
+                                                 state,
+                                                 Box::new (cnode)))))
 }
diff --git a/rust/src/node.rs b/rust/src/node.rs
index 2591d5e..664cfee 100644
--- a/rust/src/node.rs
+++ b/rust/src/node.rs
@@ -13,24 +13,21 @@ use property_bag::RsvgPropertyBag;
 
 use state::RsvgState;
 
-/* A const *RsvgNode is just a pointer for the C code's benefit: it
- * points to a RsvgRcNode, which is our refcounted Rust representation
+/* A *const RsvgNode is just a pointer for the C code's benefit: it
+ * points to an  Rc<Node>, which is our refcounted Rust representation
  * of nodes.
  */
-pub enum RsvgNode {}
-
-/* This is just to take a pointer to an Rc<RefCell<Node>> */
-pub type RsvgRcNode = Rc<RefCell<Node>>;
+pub type RsvgNode = Rc<Node>;
 
 pub trait NodeTrait {
-    fn set_atts (&self, node: &RsvgRcNode, handle: *const RsvgHandle, pbag: *const RsvgPropertyBag);
-    fn draw (&self, node: &RsvgRcNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32);
+    fn set_atts (&self, node: &RsvgNode, handle: *const RsvgHandle, pbag: *const RsvgPropertyBag);
+    fn draw (&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32);
 }
 
 pub struct Node {
     node_type: NodeType,
-    parent:    Option<Weak<RefCell<Node>>>, // optional; weak ref to parent-made-mutable
-    children:  Vec<Rc<RefCell<Node>>>,   // strong references to children-made-mutable through RefCell
+    parent:    Option<Weak<Node>>,      // optional; weak ref to parent
+    children:  RefCell<Vec<Rc<Node>>>,   // strong references to children
     state:     *mut RsvgState,
     node_impl: Box<NodeTrait>
 }
@@ -94,13 +91,13 @@ pub enum NodeType {
 
 impl Node {
     pub fn new (node_type: NodeType,
-                parent:    Option<Weak<RefCell<Node>>>,
+                parent:    Option<Weak<Node>>,
                 state:     *mut RsvgState,
                 node_impl: Box<NodeTrait>) -> Node {
         Node {
             node_type: node_type,
             parent:    parent,
-            children:  Vec::new (),
+            children:  RefCell::new (Vec::new ()),
             state:     state,
             node_impl: node_impl
         }
@@ -114,56 +111,55 @@ impl Node {
         self.state
     }
 
-    pub fn add_child (&mut self, child: &Rc<RefCell<Node>>) {
-        self.children.push (child.clone ());
+    pub fn add_child (&self, child: &Rc<Node>) {
+        self.children.borrow_mut ().push (child.clone ());
     }
 }
 
 #[no_mangle]
-pub extern fn rsvg_node_get_type (raw_node: *const RsvgRcNode) -> NodeType {
+pub extern fn rsvg_node_get_type (raw_node: *const RsvgNode) -> NodeType {
     assert! (!raw_node.is_null ());
-    let node: &RsvgRcNode = unsafe { & *raw_node };
+    let node: &RsvgNode = unsafe { & *raw_node };
 
-    node.borrow ().get_type ()
+    node.get_type ()
 }
 
 #[no_mangle]
-pub extern fn rsvg_node_get_parent (raw_node: *const RsvgRcNode) -> *const RsvgRcNode {
+pub extern fn rsvg_node_get_parent (raw_node: *const RsvgNode) -> *const RsvgNode {
     assert! (!raw_node.is_null ());
-    let rc_node: &RsvgRcNode = unsafe { & *raw_node };
+    let node: &RsvgNode = unsafe { & *raw_node };
 
-    match rc_node.borrow ().parent {
+    match node.parent {
         None => { ptr::null () }
 
         Some (ref weak_node) => {
             let strong_node = weak_node.upgrade ().unwrap ();
-            &strong_node as *const RsvgRcNode
+            Box::into_raw (Box::new (strong_node))
         }
     }
 }
 
 #[no_mangle]
-pub extern fn rsvg_node_unref (raw_node: *const RsvgRcNode) {
+pub unsafe extern fn rsvg_node_unref (raw_node: *mut RsvgNode) {
     assert! (!raw_node.is_null ());
-    let rc_node: &RsvgRcNode = unsafe { & *raw_node };
 
-    drop (rc_node);
+    let _ = Box::from_raw (raw_node);
 }
 
 #[no_mangle]
-pub extern fn rsvg_node_get_state (raw_node: *const RsvgRcNode) -> *mut RsvgState {
+pub extern fn rsvg_node_get_state (raw_node: *const RsvgNode) -> *mut RsvgState {
     assert! (!raw_node.is_null ());
-    let rc_node: &RsvgRcNode = unsafe { & *raw_node };
+    let node: &RsvgNode = unsafe { & *raw_node };
 
-    rc_node.borrow ().get_state ()
+    node.get_state ()
 }
 
 #[no_mangle]
-pub extern fn rsvg_node_add_child (raw_node: *mut RsvgRcNode, raw_child: *const RsvgRcNode) {
+pub extern fn rsvg_node_add_child (raw_node: *mut RsvgNode, raw_child: *const RsvgNode) {
     assert! (!raw_node.is_null ());
     assert! (!raw_child.is_null ());
-    let rc_node: &mut RsvgRcNode = unsafe { &mut *raw_node };
-    let rc_child: &RsvgRcNode = unsafe { & *raw_child };
+    let node: &mut RsvgNode = unsafe { &mut *raw_node };
+    let child: &RsvgNode = unsafe { & *raw_node };
 
-    rc_node.borrow_mut ().add_child (rc_child);
+    node.add_child (child);
 }
diff --git a/rust/src/pattern.rs b/rust/src/pattern.rs
index 3e1b6ed..d0595f9 100644
--- a/rust/src/pattern.rs
+++ b/rust/src/pattern.rs
@@ -14,7 +14,7 @@ use length::*;
 
 use drawing_ctx;
 use drawing_ctx::RsvgDrawingCtx;
-use drawing_ctx::RsvgNode;
+use node::RsvgNode;
 
 use bbox::*;
 use util::*;
diff --git a/rust/src/shapes.rs b/rust/src/shapes.rs
index 5b61ba9..e3f0028 100644
--- a/rust/src/shapes.rs
+++ b/rust/src/shapes.rs
@@ -25,7 +25,7 @@ impl NodePath {
 }
 
 impl NodeTrait for NodePath {
-    fn set_atts (&self, node: &RsvgRcNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) {
+    fn set_atts (&self, _: &RsvgNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) {
         if let Some (value) = property_bag::lookup (pbag, "d") {
             let mut builder = self.builder.borrow_mut ();
 
@@ -36,7 +36,7 @@ impl NodeTrait for NodePath {
         }
     }
 
-    fn draw (&self, node: &RsvgRcNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    fn draw (&self, _: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
         drawing_ctx::state_reinherit_top (draw_ctx, self.state, dominate);
         drawing_ctx::render_path_builder (draw_ctx, & *self.builder.borrow ());
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]