Manipulating a scene graph is sometime quite a challenge. If you take the classic Flash display list for example: fetching tree nodes and modifying them as batches is not possible. You have to write a lot of code to simply fetch all the nodes you need reqgarding a set of creteria. Then you have to loop on this set to call the proper functions and set the right properties.
Working with trees as a representation model is something XML is very good at. XPath is a part of the XML specification and it defines a specific syntax to select a subset of XML nodes in an XML document. I think the syntax is quite obvious and very intuitive as it inherits most of its design from the UNIX/URI paths.
That's why we chose to add a simple XPath implementation in Minko 2. You can now write this kind of things:
var visibleMeshes : SceneIterator = group.get("/group/mesh[visible=true]");
The Group.get() method takes the XPath you wan to match and returns a SceneIterator object. This object acts as a wrapper for the fetched collection of nodes that matched your XPath request:
var visibleMeshes : SceneIterator = group.get("/group/mesh[visible=true]"); var numMeshes : uint = visibleMeshes.length; for (var i : uint = 0; i < numMeshes; ++i) visibleMeshes.visible = false;
The "" operator can be used to get the nth item of the fetched collection. To override this operator, we simply extend the Proxy class and override the flash_proxy getProperty() method. Extending the Proxy makes it possible to add two new features:
- iterator: our SceneIterator object can be used in "for each" loops if we override the proper Proxy methods
- property setters/getters overriding: set/get properties on all the selected nodes at once
// fetch all the visible meshes and hide them group.get("//mesh[visible=true]").visible = false; // fetch all the white meshes and make them white group.get("//mesh[@diffuseColor=0xffffffff]").bindings.setProperty( "diffuseColor", 0xff0000ff ); // fetch all the visible white meshes and remove them from their parent group.get("/group/group/mesh[@diffuseColor=0xffffffff][visible=true]").parent = null;