Просмотр исходного кода

wallet: add scan_dangling() method used for garbage collection of nodes

rsx 2 лет назад
Родитель
Сommit
266ecc2ed1

+ 26 - 4
bin/darkwallet/client.py

@@ -97,11 +97,19 @@ def remove_node_recursive(node_id):
 
 def clear_layer(layer_path):
     layer_id = api.lookup_node_id("/window/layer2")
+    if layer_id is None:
+        return
+
+    win_id = api.lookup_node_id("/window")
+    api.unlink_node(layer_id, win_id)
+
     for (_, child_id, child_type) in api.get_children(layer_id):
         api.unlink_node(child_id, layer_id)
         if child_type == SceneNodeType.RENDER_OBJECT:
             remove_node_recursive(child_id)
 
+    api.remove_node(layer_id)
+
 def remove_all_slots(node_path, sig):
     node_id = api.lookup_node_id(node_path)
     for slot_id, slot in api.get_slots(node_id, sig):
@@ -126,17 +134,23 @@ def set_property(node_path, prop, val):
             api.set_property_u32(node_id, prop, val)
 
 def recalc_areas():
+    print("recalc areas")
     w = get_property("/window", "width")
     h = get_property("/window", "height")
-    set_property("/window/layer1", "rect_w", int(w))
-    set_property("/window/layer1", "rect_h", int(h))
     set_property("/window/layer2", "rect_w", int(w))
     set_property("/window/layer2", "rect_h", int(h))
 
+    print_tree()
+
+def garbage_collect():
+    for node_id in api.scan_dangling():
+        remove_node_recursive(node_id)
+
 api = Api()
 host = HostApi(api)
 print(api.hello())
 
+garbage_collect()
 clear_layer("/window/layer2")
 
 print("Generating scene...")
@@ -147,6 +161,16 @@ register_slot("/window/input/mouse",    "button_down",   b"click")
 register_slot("/window/input/mouse",    "wheel",         b"wheel")
 #register_slot("/window/input/mouse",    "move",          b"mouse")
 
+layer_id = api.add_node("layer2", SceneNodeType.RENDER_LAYER)
+api.add_property(layer_id, "rect_x", PropertyType.UINT32)
+api.add_property(layer_id, "rect_y", PropertyType.UINT32)
+api.add_property(layer_id, "rect_w", PropertyType.UINT32)
+api.add_property(layer_id, "rect_h", PropertyType.UINT32)
+api.add_property(layer_id, "is_visible", PropertyType.BOOL)
+api.set_property_bool(layer_id, "is_visible", True)
+win_id = api.lookup_node_id("/window")
+api.link_node(layer_id, win_id)
+
 if True:
     layer_id = api.lookup_node_id("/window/layer2")
 
@@ -186,8 +210,6 @@ if True:
     api.link_node(obj_id, layer_id)
 
 if True:
-    set_property("/window/layer1", "is_visible", False)
-
     layer_id = api.lookup_node_id("/window/layer2")
     obj_id = api.add_node("obj", SceneNodeType.RENDER_OBJECT)
     api.add_property(obj_id, "x", PropertyType.FLOAT32)

+ 11 - 1
bin/darkwallet/pydrk/api.py

@@ -6,7 +6,8 @@ class Command:
     HELLO = 0
     ADD_NODE = 1
     REMOVE_NODE = 9
-    RENAME_NODE = 23,
+    RENAME_NODE = 23
+    SCAN_DANGLING = 24
     LOOKUP_NODE_ID = 12
     ADD_PROPERTY = 11
     LINK_NODE = 2
@@ -299,6 +300,15 @@ class Api:
         serial.encode_str(req, node_name)
         self._make_request(Command.RENAME_NODE, req)
 
+    def scan_dangling(self):
+        cur = self._make_request(Command.SCAN_DANGLING, bytearray())
+        dangling_len = serial.decode_varint(cur)
+        dangling = []
+        for _ in range(dangling_len):
+            node_id = serial.read_u32(cur)
+            dangling.append(node_id)
+        return dangling
+
     def lookup_node_id(self, node_path):
         req = bytearray()
         serial.encode_str(req, node_path)

+ 7 - 52
bin/darkwallet/src/gfx.rs

@@ -219,51 +219,6 @@ impl Stage {
         mouse.add_signal("move").unwrap();
         let mouse_id = mouse.id;
         scene_graph.link(mouse_id, input_id).unwrap();
-
-        let layer1 = scene_graph.add_node("layer1", SceneNodeType::RenderLayer);
-        layer1.add_property_bool("is_visible", true).unwrap();
-        layer1.add_property_u32("rect_x", 0).unwrap();
-        layer1.add_property_u32("rect_y", 0).unwrap();
-        layer1.add_property_u32("rect_w", 0).unwrap();
-        layer1.add_property_u32("rect_h", 0).unwrap();
-        let layer1_id = layer1.id;
-        scene_graph.link(layer1_id, window_id).unwrap();
-
-        let layer2 = scene_graph.add_node("layer2", SceneNodeType::RenderLayer);
-        layer2.add_property_bool("is_visible", true).unwrap();
-        layer2.add_property_u32("rect_x", 0).unwrap();
-        layer2.add_property_u32("rect_y", 0).unwrap();
-        layer2.add_property_u32("rect_w", 0).unwrap();
-        layer2.add_property_u32("rect_h", 0).unwrap();
-        let layer2_id = layer2.id;
-        scene_graph.link(layer2_id, window_id).unwrap();
-
-        let funky_square = scene_graph.add_node("funky_square", SceneNodeType::RenderObject);
-        funky_square.add_property_f32("x", 0.).unwrap();
-        funky_square.add_property_f32("y", 0.).unwrap();
-        funky_square.add_property_f32("scale", 0.).unwrap();
-        let funky_square_id = funky_square.id;
-        scene_graph.link(funky_square_id, layer1_id).unwrap();
-
-        let funky_mesh = scene_graph.add_node("mesh", SceneNodeType::RenderMesh);
-        let mut buf = vec![];
-        // top left
-        Vertex { pos: [0., 0.], color: [1., 0., 1., 1.], uv: [0., 0.] }.encode(&mut buf).unwrap();
-        // top right
-        Vertex { pos: [0.5, 0.], color: [1., 1., 0., 1.], uv: [1., 0.] }.encode(&mut buf).unwrap();
-        // bottom left
-        Vertex { pos: [0., 0.5], color: [0., 0., 0.8, 1.], uv: [0., 1.] }.encode(&mut buf).unwrap();
-        // bottom right
-        Vertex { pos: [0.5, 0.5], color: [1., 1., 0., 1.], uv: [1., 1.] }.encode(&mut buf).unwrap();
-        funky_mesh.add_property_buf("verts", buf).unwrap();
-
-        let mut buf = vec![];
-        Face { idxs: [0, 2, 1] }.encode(&mut buf).unwrap();
-        Face { idxs: [1, 2, 3] }.encode(&mut buf).unwrap();
-        funky_mesh.add_property_buf("faces", buf).unwrap();
-
-        let funky_mesh_id = funky_mesh.id;
-        scene_graph.link(funky_mesh_id, funky_square_id).unwrap();
     }
 
     fn draw_glyph(
@@ -332,19 +287,19 @@ impl Stage {
             BufferSource::slice(&indices),
         );
 
-        let texture =
-            //self.king_texture;
-            ctx.new_texture_from_rgba8(
-                font_metrics.width as u16,
-                font_metrics.height as u16,
-                &text_bitmap,
-            );
+        let texture = ctx.new_texture_from_rgba8(
+            font_metrics.width as u16,
+            font_metrics.height as u16,
+            &text_bitmap,
+        );
 
         let bindings =
             Bindings { vertex_buffers: vec![vertex_buffer], index_buffer, images: vec![texture] };
 
         ctx.apply_bindings(&bindings);
         ctx.draw(0, 6, 1);
+
+        ctx.delete_texture(texture);
     }
 
     fn create_text_node(

+ 5 - 0
bin/darkwallet/src/net.rs

@@ -17,6 +17,7 @@ enum Command {
     AddNode = 1,
     RemoveNode = 9,
     RenameNode = 23,
+    ScanDangling = 24,
     LookupNodeId = 12,
     AddProperty = 11,
     LinkNode = 2,
@@ -221,6 +222,10 @@ impl ZeroMQAdapter {
                 debug!(target: "req", "{:?}({})", cmd, node_id);
                 scene_graph.rename_node(node_id, node_name)?;
             }
+            Command::ScanDangling => {
+                let dangling = scene_graph.scan_dangling();
+                dangling.encode(&mut reply).unwrap();
+            }
             Command::LookupNodeId => {
                 let node_path: String = deserialize(&payload).unwrap();
                 debug!(target: "req", "{:?}({})", cmd, node_path);

+ 16 - 0
bin/darkwallet/src/scene.rs

@@ -268,6 +268,22 @@ impl SceneGraph {
         }
         Ok(siblings)
     }
+
+    pub fn scan_dangling(&self) -> Vec<SceneNodeId> {
+        let mut dangling = vec![];
+        for node in &self.nodes {
+            if node.id == Self::ROOT_ID {
+                continue
+            }
+            if self.freed.contains(&node.id) {
+                continue
+            }
+            if node.parents.is_empty() {
+                dangling.push(node.id);
+            }
+        }
+        dangling
+    }
 }
 
 pub type SceneNodeId = u32;