• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

.jsx script extremely slow

Explorer ,
Aug 12, 2021 Aug 12, 2021

Copy link to clipboard

Copied

Hi,

I've tried to work a little with photoshop scripting, and I tried to make a thing that removes groups if it fits some criteria.

The problem I am facing is - it's VERY VERY slow. Let's say we have a file that contains 10 groups, each group contains 10 sub-groups, and each of these groups contains 10 layers.

 

I made a recursion that checks if the first child layer is a group, if it is a group, it moves in (recursion), if it's not, then skip. At the end, remove group. (This is simplified, but it is basically the thing).

 

From my previous programming experience, I'd say this should run under a second without any issues. But what I've found out is, that it takes several seconds to remove one group.

 

This is just straight up unacceptable. Can anyone point me in the right direction on how to solve this? Or explain to me, why is such a popular app so so so badly made? (In this specific case)

 
To continue, I'll provide with the actual real stuff, time, code ...
 

These results show, that any photoshop call takes quite a long time. Any suggestions on how to improve this? I'd need it to improve dramatically in speed (at least 10x).

 

Second issue:

I've now noticed a second problem - the first group is marked visible immediatelly, so it doens't get removed. Any idea why this happens?

 

Intel core i7-7700, 32 GB RAM, Adobe Photoshop 2021

 

 

Recreate demo:

Photoshop file:

 

create new, printing, A4, remove layer, add empty layer, dulicate so you have 10 empty layers. Now group these 10 layers into one group, and duplicate 9 more times. Group these groups together and duplicate 9 more times.

So there are 10 top groups, each contains 10 sub groups, each sub group contains 10 empty groups.

 

My code:

 

var start_time = new Date().getTime();

var doc = activeDocument;
var objectString;


var textFile = File(doc.path + '/time.txt');
textFile.encoding = 'UTF-8';
textFile.open('a');

textFile.write("Initialization: ", new Date().getTime() - start_time, "\n");

loopTopGroups();

textFile.write("Total time: ", new Date().getTime() - start_time, "\n");


function loopTopGroups() {

    var time_before = new Date().getTime();

    var len = doc.layers.length;
    var layers = doc.layers;

    textFile.write("Get layers: ", new Date().getTime() - time_before, "\n");
    
    for (var i = len - 1; i >= 0; i--) {
        var currentLayer = layers[i];
        
        if (!currentLayer.visible) {
            loopGroups(currentLayer);
        }

        if (currentLayer.layers.length == 0) {
            var time_before = new Date().getTime();

            currentLayer.remove();

            textFile.write("Out remove: ", new Date().getTime() - time_before, "\n");
        }
    }
}


function loopGroups(parentLayer) {
    
    var time_before = new Date().getTime();

    var len = parentLayer.layers.length;
    var layers = parentLayer.layers;

    textFile.write("Get inner layers: ", new Date().getTime() - time_before, "\n");

    for (var i = len - 1; i >= 0; i--) {
        var currentLayer = layers[i];
        
        if (currentLayer.typename == 'LayerSet') {
            if (currentLayer.layers[0].typename == 'LayerSet') {
                loopGroups(currentLayer);
            } else {
                var time_before = new Date().getTime();

                currentLayer.remove();

                textFile.write("Remove: ", new Date().getTime() - time_before, "\n");
            }
        }
    }
}

 

 

Output:

Initialization: 1
Get layers: 257
Get inner layers: 256
Remove: 249
Remove: 227
Remove: 224
Remove: 225
Remove: 223
Remove: 227
Remove: 370
Remove: 222
Remove: 324
Remove: 180
Out remove: 183
Get inner layers: 240
Remove: 222
Remove: 240
Remove: 226
Remove: 304
Remove: 234
Remove: 219
Remove: 218
Remove: 215
Remove: 291
Remove: 201
Out remove: 179
Get inner layers: 249
Remove: 218
Remove: 236
Remove: 226
Remove: 253
Remove: 279
Remove: 302
Remove: 290
Remove: 215
Remove: 465
Remove: 199
Out remove: 247
Get inner layers: 233
Remove: 239
Remove: 301
Remove: 254
Remove: 291
Remove: 255
Remove: 230
Remove: 211
Remove: 213
Remove: 220
Remove: 214
Out remove: 185
Get inner layers: 192
Remove: 208
Remove: 211
Remove: 209
Remove: 219
Remove: 217
Remove: 244
Remove: 222
Remove: 216
Remove: 203
Remove: 163
Out remove: 160
Get inner layers: 135
Remove: 234
Remove: 212
Remove: 222
Remove: 205
Remove: 305
Remove: 211
Remove: 224
Remove: 195
Remove: 227
Remove: 157
Out remove: 144
Get inner layers: 108
Remove: 197
Remove: 195
Remove: 196
Remove: 196
Remove: 224
Remove: 217
Remove: 217
Remove: 209
Remove: 217
Remove: 134
Out remove: 132
Get inner layers: 79
Remove: 194
Remove: 192
Remove: 190
Remove: 201
Remove: 196
Remove: 192
Remove: 196
Remove: 215
Remove: 191
Remove: 196
Out remove: 127
Get inner layers: 55
Remove: 218
Remove: 195
Remove: 218
Remove: 194
Remove: 224
Remove: 185
Remove: 186
Remove: 169
Remove: 166
Remove: 124
Out remove: 164
Total time: 85440
TOPICS
Actions and scripting

Views

2.6K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 3 Correct answers

Guide , Aug 12, 2021 Aug 12, 2021
quote

my final target was to have a script that removes not needed groups and ignores entire group if it's visible on top level (no recursion dive into these groups).

how to determine if the group is not needed - if it's first sub-layer is a layer and not a group, and the name of this group is not in a .txt file, remove.

 

By @Samuel_PFD

 

UPD 1*

 

#target photoshop

$.hiresTimer

var lr = new AM(),
    namesOfGroupsFromTxtFile = ['test name 1', 'test name 2']

var lrs = getLayersCollection(),
    exceptionN
...

Votes

Translate

Translate
Explorer , Aug 13, 2021 Aug 13, 2021

After hours of pain and suffering, I made my own solution.

 

@jazz-y  I really appreciate you helping (and your older posts where you explained some basics and how to start), without you, I wouldn't have been able to do anything.

 

I would have straight up used your solution, but it had some errors, and at that time, I had no knowledge of this magic API, so I wasn't capable of fixing it -> so I learned the basics and adapted them in my solution.

 

Again, huge thanks to you.

 

loopGroups(loadObjectsFile(
...

Votes

Translate

Translate
Explorer , Aug 17, 2021 Aug 17, 2021

After some talk with my team, the target changed a little, to make it easier to work with.

 

Right now what the script is supposed to do - ignore groups that are visible on top level.

For the rest of the groups, find those that are in the objects.txt file. Remove everything else (except parent groups of groups to keep). It also deletes the top groups first to make it faster.

 

Huge thanks to this community, I wouldn't have been able to make it at all without you.

 

removeGroups(loadObjectsFile());


//
...

Votes

Translate

Translate
Adobe
Explorer ,
Aug 16, 2021 Aug 16, 2021

Copy link to clipboard

Copied

Regarding the delete all at once

 

I tried to do it in a for loop, but it didn't really work - said delete is not available at the moment.

 

function removeLayerByIDs(IDs) {

    ref = new ActionReference();

    for (ID in IDs) {
        ref.putIdentifier(s2t('layer'), ID);
    }

    var d = new ActionDescriptor();
    d.putReference(s2t('null'), ref);

    executeAction(s2t('delete'), d);
}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Aug 16, 2021 Aug 16, 2021

Copy link to clipboard

Copied

I have not checked, but it seems the order is important here. if the parent group identifier is the first in the list, then it will be removed first. If the next on the list is the child group ID (which has already been deleted), then there is likely to be an error. That is why I decided not to bother in my script and first selected all the necessary layers, and then deleted them in one operation.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 16, 2021 Aug 16, 2021

Copy link to clipboard

Copied

that could be possibly the issue here, I'll check right away.

I've added a check - if parent is not to be removed, only then add the ID.

 

This did not resolve the issue, and it still ended with the same error. (yes, I've tested if the exclude works properly, it does.)

 

if (!isParentInList(ID, toRemove)) {
    toRemove.push(ID);
}

 

function isParentInList(ID, list) {
    
    var parentID = getLayerPropertyByID(ID, 'parentLayerID');

    if (arrayContains(list, parentID)) {
        return true;
    }

    while (parentID != -1) {

        ID = getLayerPropertyByID(ID, 'parentLayerID');
        parentID = getLayerPropertyByID(ID, 'parentLayerID');

        if (arrayContains(list, parentID)) {
            return true;
        }
    }

    return false;
}

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 16, 2021 Aug 16, 2021

Copy link to clipboard

Copied

You're going to have fast script if jazz-y will be willing to implement it to his code for you.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 16, 2021 Aug 16, 2021

Copy link to clipboard

Copied

it could also be a lot faster if the one delete is faster than loads of smaller ones (which it should be), but for some reason it doesn't really want to work.

 

It should also be a lot similar to what you wrote @Kukurykus in your reply (the delete).

 

I'll copy it here for your convenience. Even after making sure, that the IDs array doesn't contain both child and parent objects, it still doesn't work.

 

if (!isParentInList(ID, toRemove)) {
    toRemove.push(ID);
}

 

function removeLayerByIDs(IDs) {

    ref = new ActionReference();

    for (ID in IDs) {
        ref.putIdentifier(s2t('layer'), ID);
    }

    var d = new ActionDescriptor();
    d.putReference(s2t('null'), ref);

    executeAction(s2t('delete'), d);
}

 

function isParentInList(ID, list) {
    
    var parentID = getLayerPropertyByID(ID, 'parentLayerID');

    if (arrayContains(list, parentID)) {
        return true;
    }

    while (parentID != -1) {

        ID = getLayerPropertyByID(ID, 'parentLayerID');
        parentID = getLayerPropertyByID(ID, 'parentLayerID');

        if (arrayContains(list, parentID)) {
            return true;
        }
    }

    return false;
}

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Aug 16, 2021 Aug 16, 2021

Copy link to clipboard

Copied

Post the complete code again.
Have you removed the removal of layers from the loop? Is it possible that your script in each iteration tries to delete layers according to the same list of IDs?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Aug 16, 2021 Aug 16, 2021

Copy link to clipboard

Copied

@Kukurykus i still do not fully understand the task 🙂 Yes, in my script it is easy to replace selection + deletion with simple deletion, but my script does not produce the result that @Samuel_PFD needs 


UPD: yes, my code becomes almost a third faster if I remove the layer selection operation and pass the list of IDs to the delete function (fortunately, it was written with this in mind).

function selectAndDelete(lr, list) {
    if (list.length) {
      //  lr.deselect()
    //    lr.selectLayers(list)
        lr.removeLayer(list)
    }
}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 16, 2021 Aug 16, 2021

Copy link to clipboard

Copied

Here is the latest version (it's the same as the small segments, but full).

 

So it adds all the IDs if their parent isn't there already, and their parent will get sorted first, and only tries to remove them once at the end.

 

removeGroups(loadObjectsFile());


// Load objects.txt file
function loadObjectsFile() {

    var title = getProperty('document', 'title');
    var full_path = String(getProperty('document', 'fileReference')).split('%20').join(' ');

    var textFile = File(full_path.replace(title, 'objects.txt'));
    textFile.encoding = 'UTF-8';
    textFile.open('r');

    return textFile.read().toLowerCase();
}


// Return if top group is visible
function isTopVisible(index) {

    var parentID = getLayerPropertyByIndex(index, 'parentLayerID');
    var ID = getLayerPropertyByIndex(index, 'layerID');

    while (parentID != -1) {

        ID = getLayerPropertyByID(ID, 'parentLayerID');
        parentID = getLayerPropertyByID(ID, 'parentLayerID');
    }

    return getLayerPropertyByID(ID, 'visible');
}


// Return if any parent is in a list
function isParentInList(ID, list) {
    
    var parentID = getLayerPropertyByID(ID, 'parentLayerID');

    if (arrayContains(list, parentID)) {
        return true;
    }

    while (parentID != -1) {

        ID = getLayerPropertyByID(ID, 'parentLayerID');
        parentID = getLayerPropertyByID(ID, 'parentLayerID');

        if (arrayContains(list, parentID)) {
            return true;
        }
    }

    return false;
}


function arrayContains(array, element) {

    for (var i = 0; i < array.length; i++) {
        if (array[i] == element) {
            return true;
        }
    }

    return false;
}


function removeGroups(objectString) {

    var start = getProperty('document', 'hasBackgroundLayer') ? 0 : 1;
    var end = getProperty('document', 'numberOfLayers');
    var toRemove = [];

    // Loop through all layers
    for (var i = end - 1; i >= start; i--) {
        var ID = getLayerPropertyByIndex(i, 'layerID');

        var section = getLayerPropertyByIndex(i, 'layerSection').value;
        
        // It's a group
        if (section == 'layerSectionStart') {
            if (!isTopVisible(i)) {
                var name = getLayerPropertyByIndex(i, 'name');

                if (objectString.indexOf(String(name).toLowerCase()) == -1) {
                    if (!isParentInList(ID, toRemove)) {
                        toRemove.push(ID);
                        alert(ID);
                    }
                    else {
                        alert("Ignore");
                    }
                }
            }
        }
    }

    removeLayerByIDs(toRemove);
}


function s2t(s) { return stringIDToTypeID(s); }
function t2s(t) { return typeIDToStringID(t); }


function getProperty(obj, property) {

    var ref = new ActionReference();
    ref.putProperty(s2t('property'), s2t(property));
    ref.putEnumerated(s2t(obj), s2t('ordinal'), s2t('targetEnum'));
    return getDescValue(executeActionGet(ref), s2t(property));
}


function getLayerPropertyByIndex(index, property) {

    ref = new ActionReference();
    ref.putProperty(s2t('property'), s2t(property))
    ref.putIndex(s2t('layer'), index);
    var desc = executeActionGet(ref);
    return getDescValue(desc, s2t(property));
}


function getLayerPropertyByID(ID, property) {

    ref = new ActionReference();
    ref.putProperty(s2t('property'), s2t(property))
    ref.putIdentifier(s2t('layer'), ID);
    var desc = executeActionGet(ref);
    return getDescValue(desc, s2t(property));
}


function removeLayerByIDs(IDs) {

    ref = new ActionReference();

    for (ID in IDs) {
        ref.putIdentifier(s2t('layer'), ID);
    }

    var d = new ActionDescriptor();
    d.putReference(s2t('null'), ref);

    executeAction(s2t('delete'), d);
}


function getDescValue(descriptor, property) {
    switch (descriptor.getType(property)) {
        case DescValueType.OBJECTTYPE: return { type: t2s(descriptor.getObjectType(property)), value: descriptor.getObjectValue(property) };
        case DescValueType.LISTTYPE: return descriptor.getList(property);
        case DescValueType.REFERENCETYPE: return descriptor.getReference(property);
        case DescValueType.BOOLEANTYPE: return descriptor.getBoolean(property);
        case DescValueType.STRINGTYPE: return descriptor.getString(property);
        case DescValueType.INTEGERTYPE: return descriptor.getInteger(property);
        case DescValueType.LARGEINTEGERTYPE: return descriptor.getLargeInteger(property);
        case DescValueType.DOUBLETYPE: return descriptor.getDouble(property);
        case DescValueType.ALIASTYPE: return descriptor.getPath(property);
        case DescValueType.CLASSTYPE: return descriptor.getClass(property);
        case DescValueType.UNITDOUBLE: return (descriptor.getUnitDoubleValue(property));
        case DescValueType.ENUMERATEDTYPE: return { type: t2s(descriptor.getEnumerationType(property)), value: t2s(descriptor.getEnumerationValue(property)) };
        default: return 0;
    };
}

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Aug 16, 2021 Aug 16, 2021

Copy link to clipboard

Copied

You are using the "for...in" loop incorrectly (generally not the best choice for arrays). As an argument to the function, you pass not the value of an element of the IDs array, but its index.

 

function removeLayerByIDs(IDs) {

    ref = new ActionReference();

    for (ID in IDs) {
        ref.putIdentifier(s2t('layer'), IDs[ID]);
    }

    var d = new ActionDescriptor();
    d.putReference(s2t('null'), ref);

    executeAction(s2t('delete'), d);
}

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 16, 2021 Aug 16, 2021

Copy link to clipboard

Copied

oh wow ...

 

that's a really stupid mistake. well, first time working with .js though.

 

Implemented it properly now, and it works about 3x faster, which is amazing.

Thanks for the help. I'll get back to the script tomorrow, I'll clean it up, add some comments and stuff, and post it as a new answer with a description what it's supposed to do.

 

Good day to you all

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 17, 2021 Aug 17, 2021

Copy link to clipboard

Copied

So that was the culprID 😉

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 17, 2021 Aug 17, 2021

Copy link to clipboard

Copied

After some talk with my team, the target changed a little, to make it easier to work with.

 

Right now what the script is supposed to do - ignore groups that are visible on top level.

For the rest of the groups, find those that are in the objects.txt file. Remove everything else (except parent groups of groups to keep). It also deletes the top groups first to make it faster.

 

Huge thanks to this community, I wouldn't have been able to make it at all without you.

 

removeGroups(loadObjectsFile());


// Load objects.txt file, to lowercase and some clean-up
function loadObjectsFile() {

    var title = getObjectProperty('document', 'title');
    var full_path = String(getObjectProperty('document', 'fileReference')).split('%20').join(' ');

    var textFile = File(full_path.replace(title, 'objects.txt'));
    textFile.encoding = 'UTF-8';
    textFile.open('r');

    return textFile.read().toLowerCase();
}


// Hide all groups the script will work with
function hideAll(start, end) {

    var toDo = [];

    for (var i = end - 1; i >= start; i--) {
        var section = getLayerPropertyByIndex(i, 'layerSection').value;
        
        // It's a group
        if (section == 'layerSectionStart') {
            var ID = getLayerPropertyByIndex(i, 'layerID');

            // Ignore groups that are visible on top level
            if (!isTopVisible(ID)) {
                toDo.push(ID);
            }
        }
    }

    // Hide all at once
    if (toDo.length != 0) {
        executeActionOnLayers('hide', toDo);
    }
}


// Show all groups that should be kept (but not top level), return top level groups to keep
function showTarget(start, end, objectString) {

    var toDo = [];
    var topGroups = [];

    for (var i = end - 1; i >= start; i--) {
        var section = getLayerPropertyByIndex(i, 'layerSection').value;
        
        // It's a group
        if (section == 'layerSectionStart') {
            var ID = getLayerPropertyByIndex(i, 'layerID');

            if (!isTopVisible(ID)) {
                var name = getLayerPropertyByIndex(i, 'name');

                if (objectString.indexOf(String(name).toLowerCase()) != -1) {
                    if (!arrayContains(toDo, ID)) {
                        toDo.push(ID);
                    }
                    
                    var parents = getParentGroups(ID);
                    topGroups.push(parents[parents.length - 1]);

                    for (j in parents) {
                        if (!arrayContains(toDo, parents[j])) {
                            toDo.push(parents[j]);
                        }
                    }
                }
            }
        }
    }

    // Show all at once
    if (toDo.length != 0) {
        executeActionOnLayers('show', toDo);
    }

    return topGroups;
}


// Delete all groups that are not visible, keep top level array groups
function deleteRest(start, end, topGroups) {

    var toDo = [];

    // Loop through all layers
    for (var i = end - 1; i >= start; i--) {
        var section = getLayerPropertyByIndex(i, 'layerSection').value;
        
        // It's a group
        if (section == 'layerSectionStart') {
            var ID = getLayerPropertyByIndex(i, 'layerID');
            var visible = getLayerPropertyByID(ID, 'visible');

            // Only push if a parent group is not in list, and group is hidden
            if ((!isTopVisible(ID) || isParentInList(ID, topGroups)) && !visible) {
                toDo.push(ID);
            }
        }
    }

    // Delete all at once
    if (toDo.length != 0) {
        executeActionOnLayers('delete', toDo);
    }
}


// Remove all groups that are not in the objectString
function removeGroups(objectString) {

    var start = getObjectProperty('document', 'hasBackgroundLayer') ? 0 : 1;
    var end = getObjectProperty('document', 'numberOfLayers');

    hideAll(start, end);
    var topGroups = showTarget(start, end, objectString);
    deleteRest(start, end, topGroups);
}




// Return if top group is visible
function isTopVisible(ID) {

    var parentID = getLayerPropertyByID(ID, 'parentLayerID');

    while (parentID != -1) {

        ID = getLayerPropertyByID(ID, 'parentLayerID');
        parentID = getLayerPropertyByID(ID, 'parentLayerID');
    }

    return getLayerPropertyByID(ID, 'visible');
}


// Return if any parent is in a list
function isParentInList(ID, list) {

    if (list.length == 0) {
        return false;
    }
    
    var parentID = getLayerPropertyByID(ID, 'parentLayerID');

    if (arrayContains(list, parentID)) {
        return true;
    }

    while (parentID != -1) {
        ID = getLayerPropertyByID(ID, 'parentLayerID');
        parentID = getLayerPropertyByID(ID, 'parentLayerID');

        if (arrayContains(list, parentID)) {
            return true;
        }
    }

    return false;
}


// Return IDs of all parent groups
function getParentGroups(ID) {

    var parentID = getLayerPropertyByID(ID, 'parentLayerID');
    var parents = [];

    while (parentID != -1) {

        parents.push(parentID);
        ID = getLayerPropertyByID(ID, 'parentLayerID');
        parentID = getLayerPropertyByID(ID, 'parentLayerID');
    }

    return parents;
}


// Return if array contains an element
function arrayContains(array, element) {

    for (var i = 0; i < array.length; i++) {
        if (array[i] == element) {
            return true;
        }
    }

    return false;
}


function s2t(s) { return stringIDToTypeID(s); }
function t2s(t) { return typeIDToStringID(t); }


function getObjectProperty(obj, property) {

    var ref = new ActionReference();
    ref.putProperty(s2t('property'), s2t(property));
    ref.putEnumerated(s2t(obj), s2t('ordinal'), s2t('targetEnum'));
    return getDescValue(executeActionGet(ref), s2t(property));
}


function getLayerPropertyByIndex(index, property) {

    ref = new ActionReference();
    ref.putProperty(s2t('property'), s2t(property))
    ref.putIndex(s2t('layer'), index);
    var desc = executeActionGet(ref);
    return getDescValue(desc, s2t(property));
}


function getLayerPropertyByID(ID, property) {

    ref = new ActionReference();
    ref.putProperty(s2t('property'), s2t(property))
    ref.putIdentifier(s2t('layer'), ID);
    var desc = executeActionGet(ref);
    return getDescValue(desc, s2t(property));
}


function executeActionOnLayers(action, IDs) {

    ref = new ActionReference();

    for (i in IDs) {
        ref.putIdentifier(s2t('layer'), IDs[i]);
    }

    var d = new ActionDescriptor();
    d.putReference(s2t('null'), ref);

    executeAction(s2t(action), d);
}


function getDescValue(descriptor, property) {
    switch (descriptor.getType(property)) {
        case DescValueType.OBJECTTYPE: return { type: t2s(descriptor.getObjectType(property)), value: descriptor.getObjectValue(property) };
        case DescValueType.LISTTYPE: return descriptor.getList(property);
        case DescValueType.REFERENCETYPE: return descriptor.getReference(property);
        case DescValueType.BOOLEANTYPE: return descriptor.getBoolean(property);
        case DescValueType.STRINGTYPE: return descriptor.getString(property);
        case DescValueType.INTEGERTYPE: return descriptor.getInteger(property);
        case DescValueType.LARGEINTEGERTYPE: return descriptor.getLargeInteger(property);
        case DescValueType.DOUBLETYPE: return descriptor.getDouble(property);
        case DescValueType.ALIASTYPE: return descriptor.getPath(property);
        case DescValueType.CLASSTYPE: return descriptor.getClass(property);
        case DescValueType.UNITDOUBLE: return (descriptor.getUnitDoubleValue(property));
        case DescValueType.ENUMERATEDTYPE: return { type: t2s(descriptor.getEnumerationType(property)), value: t2s(descriptor.getEnumerationValue(property)) };
        default: return 0;
    };
}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 17, 2021 Aug 17, 2021

Copy link to clipboard

Copied

It's appropriate to mark correct answer of user (jazz-y) that helped you due to your original request, than the solution to somehow changed problem, but still with code based on originally provided.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 17, 2021 Aug 17, 2021

Copy link to clipboard

Copied

That's a good point, however that code wasn't working for me due to something.

 

If it's fixed, I will mark that instead.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 17, 2021 Aug 17, 2021

Copy link to clipboard

Copied

If you mean the code from Aug 12, 2021 there's no your comment to where you say what that 'something' is, to let correct it.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 17, 2021 Aug 17, 2021

Copy link to clipboard

Copied

testing it now, it didn't show the initial error I got, I think that was due to me making it into a .jsx instead of .js (which I did the first time).

 

Now it removes everything, I tried to check if it's case sensitive, but it removed everything in both cases, so I'm not sure what the mistake/error is now.

 

It also producec the couldn't execute delete at the end (after removing pretty much everything), again not sure what the issue is there.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 17, 2021 Aug 17, 2021

Copy link to clipboard

Copied

You asked why the script you use is slow and how to accelearate its work. Later you additionally mentioned of names of groups in text file, but did not posted its structure.

 

jazz-y explained why it's slow, said how to speed it up and made correct code due to your description (10 groups conatining 10 subgroups with 10 layers each). As a bonus he created array of names that imitiated .txt file. The script process skipped visible groups and removed all invisible ones unless the name of their subfolders were part of array (then it deleted only other subgroups within their top groups).

 

I tested it originally and now again and it works as should, so that's sure only his answer should be marked as correct solution.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Aug 17, 2021 Aug 17, 2021

Copy link to clipboard

Copied

It really makes no difference to me which answer will be marked as correct - the most important thing is that the @Samuel_PFD  understood why his code was slow and figured out with our help how to make it faster. 

My code works well for a test case. Its code copes with the task in a real environment. Both answers are correct.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 17, 2021 Aug 17, 2021

Copy link to clipboard

Copied

Personally no matter indeed, but not for the forum order 😉

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 30, 2021 Oct 30, 2021

Copy link to clipboard

Copied

Why is java script files are slow, I think may be some issue. 

I found the answar but not understand :- .jsx script extremely slow

 

There, DOM is slower than AM. I can't indentify which code is DOM or AM

Could you give the example of DOM or AM For Understand. I have searched on google ,but didnot get the answar.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Oct 30, 2021 Oct 30, 2021

Copy link to clipboard

Copied

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 31, 2021 Oct 31, 2021

Copy link to clipboard

Copied

There, I can't determine which code is AM Code, Could you give example of AM Code For Understanding

I can't identify to AM Code or DOM Code

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Oct 31, 2021 Oct 31, 2021

Copy link to clipboard

Copied

Photoshop CS6 scripting guide  pages 73 - 81

 

get active layer id in with DOM:

var id = activeDocument.activeLayer.id

 

 get active layer id in with AM:

(r = new ActionReference()).putProperty(stringIDToTypeID('property'), stringIDToTypeID('layerID'));
r.putEnumerated(stringIDToTypeID('layer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
var id = executeActionGet(r).getInteger(stringIDToTypeID('layerID'));

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 31, 2021 Oct 31, 2021

Copy link to clipboard

Copied

Thanku so much I am happy for your answar

My Doubt is clear now. why is DOM slow in PS Script

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Oct 31, 2021 Oct 31, 2021

Copy link to clipboard

Copied

In the Contents look for ActionDescriptor, ActionList, ActionReference and the Application methods: charIdToTypeId, executeAction, ExecuteActionGet, stringIdToTypeId, typeIdToCharId, typeIdToStringId. They are used in Action Manager.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines