Jean-Marc Le Roux Web, RIAs and chocolate spaghettis…

11Apr/121

Minko 2 New Feature: XPath Selectors

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[0].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;
Comments (1) Trackbacks (0)
  1. Brilliant as usual :)


Leave a comment

No trackbacks yet.