Stdlib.getLayersList very slow with lots of layers

Discussion of the xtools Toolkit

Moderators: Tom, Kukurykus

ronronmx

Stdlib.getLayersList very slow with lots of layers

Post by ronronmx »

Hi guys,
I'm using xtools to return all the layers in my document using Stdlib.getLayersList(), which works great if there are between 20-50 layers, but when I run the same script on a much bigger file with hundreds of layers, it either takes forever for my UI window to popup, or locks up and I have to kill it manually.

I'm wondering if I'm doing something wrong, like maybe using Stdlib.getLayersList() in the wrong place...? Here my code below for refence:

Code: Select all// enable double clicking from the Macintosh Finder or the Windows Explorer
#target photoshop

// bring application forward for double-click events
app.bringToFront();

// debug level: 0-2 (0:disable, 1:break on error, 2:break at beginning)
// $.level = 2;
// debugger; // launch debugger on next line

// on localized builds we pull the $$$/Strings from a .dat file, see documentation for more details
//$.localize = true;

//@includepath "/c/Program Files/Adobe/xtools"
//@include "xlib/stdlib.js"


//////////////////////////////////////////////////////////////////////////
// Define global variables...
//////////////////////////////////////////////////////////////////////////

// Store reference to the active document and it's layerSets (groups)...
var sourceDoc;
var layers;
var includeGroups = false;

//////////////////////////////////////////////////////////////////////////
// Execute Main Function
//////////////////////////////////////////////////////////////////////////

// test initial conditions prior to running main function
if ( isOpenDocs() && hasLayers() )
{
   try {
      // suspend history for CS3 (v10) or higher
      if (parseInt(version, 10) >= 10)
         activeDocument.suspendHistory('Find Layer', 'main()');

      // just run main for CS2 (v9)
      else
         main();
   }
   catch(e) {
      // don't report error on user cancel
      if (e.number != 8007)
         showError(e);
   }
}


//////////////////////////////////////////////////////////////////////////
// Main Function
//////////////////////////////////////////////////////////////////////////
function main () {

   sourceDoc = app.activeDocument;
   layers = Stdlib.getLayersList( sourceDoc, false, false );
   
   // Create and initialize the UI window
   var window = createWindow ();
   initWindow ( window );
   
}



// ===================================== Custom Functions ===================================== //

///////////////////////////////////////////////////////////////////////////////
// createWindow - Creates the main UI window
///////////////////////////////////////////////////////////////////////////////
function createWindow () {
   
   var win = new Window("dialog", "Find Layers", undefined, {resizeable : true});
   win.alignChildren = 'left';
   
   // First panel
   win.panel1 = win.add( "panel{ text:'Layer Properties', orientation:'column', alignChildren:'left', margins:15, \
                      grp1: Group{ orienation:'row', \
                        label: StaticText{ text:'Search For: ' }, \
                        et: EditText{ text:'<Layer Name>', characters:35 }}, \
                      grp2: Group{ orientation:'row', \
                        chkbx: Checkbox{ text:'Include Groups?' }}}" );
   
   // Search button group
   win.group1 = win.add( "group", undefined );
   win.group1.orientation = 'row';
   win.group1.searchBtn = win.group1.add( "button", {x:0, y:0, width:150, height:40}, "Search Now!", {name : "ok"} );
   win.group1.staticText = win.group1.add( "statictext", undefined, "Number Of Layers: " + layers.length );
   
   with( win )
   {
      //Focus edit text box to enter layer name
      panel1.grp1.et.active = true;
   }
   

   return win;
}

///////////////////////////////////////////////////////////////////////////////
// initWindow - Initialize the main UI window and control states
///////////////////////////////////////////////////////////////////////////////
function initWindow ( w ) {
   
   var searchBtn = w.group1.searchBtn;
   var grpCheckbox = w.panel1.grp2.chkbx;
   
   // onClick actions for the search button
   searchBtn.onClick = function( )
   {
      // Start the search
      FindLayer( w.panel1.grp1.et.text );
   }

   // Update layer count when checking the include groups checkbox
   grpCheckbox.onClick = function( )
   {
      includeGroups = !includeGroups;
      layers = Stdlib.getLayersList( sourceDoc, false, includeGroups );
      w.group1.staticText.text = "Number Of Layers: " + layers.length;
   }
   
   return w.show();
   w.center();
   
}

///////////////////////////////////////////////////////////////////////////////
// FindLayer - Loop through all layers in document and find given name
///////////////////////////////////////////////////////////////////////////////
function FindLayer ( layerName ) {
   
   var isMatch = false;
   
   // Throw an alert if nothing was entered in the text box
   if( !layerName )
   {
      alert( "No name specified! Please enter the layer name you wish to search for." );
      return;
   }
   else
   {
      // Loop through all layers and search for layerName
      for( var i = 0; i < layers.length; i++ )
      {
         if( layers.name.toLowerCase() == layerName.toLowerCase() )
         {
            alert( "Found Layer: " + layerName );
            activeDocument.activeLayer = layers;
            isMatch = true;
            break;
         }
      }
   }
   
   // Alert user if the layer wasn't found
   if( !isMatch && layerName )
   {
      alert( "<" + layerName + ">" + " layer doesn't exist!" );
   }

   return isMatch;
}

///////////////////////////////////////////////////////////////////////////////
// isOpenDocs - ensure at least one document is open
///////////////////////////////////////////////////////////////////////////////
function isOpenDocs() {
   
   if (documents.length)
   {
      return true;
   }
   else
   {
      alert('There are no documents open.', 'No Documents Open', false);
      return false;
   }
};


///////////////////////////////////////////////////////////////////////////////
// hasLayers - ensure that the active document contains at least one layer
///////////////////////////////////////////////////////////////////////////////
function hasLayers() {
   
   var doc = activeDocument;
   if( doc.layers.length == 1 && doc.activeLayer.isBackgroundLayer )
   {
      alert('The active document has no layers.', 'No Layers', false);
      return false;
   }
   else
   {
      return true;
   }
};


///////////////////////////////////////////////////////////////////////////////
// showError - display error message if something goes wrong
///////////////////////////////////////////////////////////////////////////////
function showError(err) {
   
   if (confirm('An unknown error has occurred.\n' + 'Would you like to see more information?', true, 'Unknown Error'))
   {
      alert(err + ': on line ' + err.line, 'Script Error', true);
   }
};

If anyone can help out I would greatly appreciate it
Thanks for your time, and for the xtools library!!!

Stephane
xbytor

Stdlib.getLayersList very slow with lots of layers

Post by xbytor »

The problem you are seeing is that when working with a large number of layers, the PS DOM can be very inefficient.
In these cases, you need to use ActionManager-level code working with layer indexes instead of Layer objects.
There is some support for this style of programming in stdlib.js, but others (Mike Hale and Trevor Morris, in particular)
have done more complete work in this area.
ronronmx

Stdlib.getLayersList very slow with lots of layers

Post by ronronmx »

xbytor wrote:The problem you are seeing is that when working with a large number of layers, the PS DOM can be very inefficient.
In these cases, you need to use ActionManager-level code working with layer indexes instead of Layer objects.
There is some support for this style of programming in stdlib.js, but others (Mike Hale and Trevor Morris, in particular)
have done more complete work in this area.

Ah yes thanks for the quick reply, I was really wondering if I was doing something wrong haha

You mentioned Mike Hale and Trevor Morris, could you point me in the right direction so that I can look into their work? The ActionManager-level code is like a martian language to me, it doesn't make any sense at all! This is gonna get interesting lol

Thanks again for the help!
Stephane
AaronPowers

Stdlib.getLayersList very slow with lots of layers

Post by AaronPowers »

Ronronmx,

Here's a thread that has some information on your question:
http://ps-scripts.com/bb/viewtopic.php? ... 28&p=20849