0 Replies Latest reply on Jun 27, 2006 5:06 AM by sneskid

    mapping objects

    sneskid Level 1
      Here are recursive and non-recursive methods to cycle through an objects data.
      I wrote it out of frustration from MovieClips needing 1 frame to fully populate with custom properties.
      I wanted a better way to see what's going on, and I've never come accross a function that can trace objects fully (the way you can in PHP for example).

      This can be used to debug, I've made it trace out a deacent looking object tree.
      But with slight modifications it can be used to custom serialize data for web transfers, or whatever.

      map recursively
      quote:

      var tabb:String = "";
      function map_recursive(obj, nam:String) {
      tname(tabb + ">", nam, obj);
      tabb += "\t"; // add a tab
      for(nam in obj) {
      if( isContainer(obj) ) map_recursive(obj[nam], nam);
      else tname((tabb + ">"), nam, obj[nam]);
      }
      tabb = tabb.substr(1, tabb.length-1); // remove a tab
      }



      non-recursive
      quote:

      function map(obj, nam:String) {
      var tab:String = "|---"; // a string to format the map nicely with
      var arr:Array = new Array(); // this will make non-recursive possible (basically a custom call stack)
      var dep:Number = 0; // keeps track of what object we are mapping
      // usage:
      // arr[dep][0] = reference to an object
      // arr[dep][1] = name of the object
      // arr[dep][2] = array with all object elements
      // arr[dep][3] = position in arr[dep][2] array to continue from (makes using 1 for loop in many short burts possible)

      tname(">", nam, obj);
      arr[dep] = new Array();
      arr[dep][0] = obj;
      arr[dep][1] = nam;
      arr[dep][2] = new Array();
      arr[dep][3] = 0;
      map_in_array(arr[dep][0], arr[dep][2]);
      while(true) {
      for(arr[dep][3]; arr[dep][3] < arr[dep][2].length; arr[dep][3]++) {
      nam = arr[dep][2][arr[dep][3]];
      obj = arr[dep][0][nam];
      tname((tab + ">"), nam, obj);
      if( isContainer(obj) ) {
      arr[dep][3]++; // manually increase counter, for loop won't because of the break
      tab = "\t" + tab; // add a tab
      // dive into the next object
      dep++;
      arr[dep] = new Array();
      arr[dep][0] = obj;
      arr[dep][1] = nam;
      arr[dep][2] = new Array();
      arr[dep][3] = 0;
      map_in_array(arr[dep][0], arr[dep][2]);
      break;
      }
      }
      if( arr[dep][3] == (arr[dep][2].length) ) {
      if(dep == 0) break; // finished

      tab = tab.substr(1, tab.length-1); // remove a tab
      // surface to previous object
      arr.pop();
      dep--;
      }
      }
      }



      helper functions
      quote:

      // Helpers for mapping
      function map_in_array(obj, arr:Array) {
      for(var n in obj) arr.push(n);
      }
      function tname(pre, nam, obj) {
      trace(pre + "[" + nam + " ; " + obj + " ; " + typeof(obj) + " ]");
      }
      function isContainer(obj) {
      return ( typeof(obj) == "object" || typeof(obj) == "movieclip");
      }



      I'm trying to simplify the non-recursive structure, I feel there is a better way to do it. But it does work 100% right now.
      Although it's longer, it has 1 benefit over the recursive version; it will not hang up after 256 loops. It can go indefinately, untill the trace window crashes (which happened to me).

      Hope this could be usefull to someone.
      It helped me learn how flash instantiates MovieClips in great depth (no pun intended).

      PS
      Thank you kglad. You've helped me out alot. Now I'm finally starting to contribute.
      chears



      EDIT:
      Please note that this should not be used on objects that reference eachother, this would cause an eternal loop.