Skip to main content
reubenlara
Known Participant
December 24, 2024
Question

How can I avoid a recursive Action loop?

  • December 24, 2024
  • 3 replies
  • 486 views

I'm creating a script called "Export Assets to Cavalry". It uses custom Actions in functions to work around the lack of native Illustrator scripting API. In my case, I'm using a make_action() function to get an array of highlighted layers in the Layers palette. Everything works great when launched from the File menu. Now I want to attach a Function Key keyboard shortcut to it, but since Illustrator once again lacks the ability to attach shortcuts to user Scripts (like PS can), the workaround is to attach a Menu Item to an action in the Actions palette. But now this creates a recursive loop, wherein, when executed from the Action palette, when I fire off specific parts of my script , my script creates a temp folder called 'Scripted_Actions' and causes Illustrator to hang. I have to Force Quit and I get a crash report from Illustrator. 

 

The attached image shows what's on screen when it hangs. The "Selection only" functionality is calling the internal script actions, which create the temporary actions folder, which causes the loop.

 

Is there a way to avoid this Action battle?

 

This topic has been closed for replies.

3 replies

Sergey Osokin
Inspiring
December 25, 2024

In Illustrator, you can't run a script from an action that itself calls another action. Illustrator cannot handle such processes and will freeze.

 

It may be possible in ExtendScript to write an export of assets without using an action? All I see in your action is a Hide Others command for layers. And no other specific commands. But this can be done in a loop through the layer[idx].visible property.

 

If you really need to hotkey a script, use third-party utilities AutoHotkey (Win), KeyboardMaestro (Mac), and these are not all possible utilities

reubenlara
Known Participant
December 25, 2024

Thank you @m1b and @Sergey Osokin for your comments. There is an action in the code above "function make_action()" that actually detects wich layers are highlighted by the user in the layers pallete and keeps those visible, and then I can get the names of those visible layers. The end goal is just to return user select layers. Does anyone know a way to accomplish this without running a coded action? I couldn't find any other solutions on my end.

reubenlara
Known Participant
December 25, 2024

If anyone wants to try on their end, paste this into a .jsx file and run it from the File > Scripts menu. It should work fine (alerts selected layers' names):

function get_selected_layers(mode) {
  var doc = app.activeDocument;
  var lays = doc.layers;
  var originalLayers = [];

  for (var i = 0; i < lays.length; i++) {
    originalLayers.push(lays[i].visible);
    if (!lays[i].visible) {
      lays[i].visible = true;
    }
  }
  make_action();

  var SelectedLayers = [];

  for (var i = 0; i < lays.length; i++) {
    if (lays[i].visible) {
      if (mode == "name") {
        SelectedLayers.push(lays[i].name);
      } else {
        SelectedLayers.push(lays[i]);
      }
    }
  }

  for (var i = 0; i < lays.length; i++) {
    lays[i].visible = originalLayers[i];
  }

  return SelectedLayers;

  function make_action() {
    // Set you action name and the set name that it belongs to here

    var myAction = "Select_Layers";
    var mySet = "Scripted_Actions";
    //---------------------------------------------------------------------------------

    var currentInteractionLevel = app.userInteractionLevel;

    app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS;

    var actionStr = [
      "/version 3",
      "/name [ 16",
      "53637269707465645f416374696f6e73",
      "]",
      "/isOpen 0",
      "/actionCount 1",
      "/action-1 {",
      "/name [ 13",
      "53656c6563745f4c6179657273",
      "]",
      "/keyIndex 0",
      "/colorIndex 0",
      "/isOpen 0",
      "/eventCount 1",
      "/event-1 {",
      "/useRulersIn1stQuadrant 0",
      "/internalName (ai_plugin_Layer)",
      "/localizedName [ 5",
      "4c61796572",
      "]",
      "/isOpen 0",
      "/isOn 1",
      "/hasDialog 0",
      "/parameterCount 3",
      "/parameter-1 {",
      "/key 1836411236",
      "/showInPalette -1",
      "/type (integer)",
      "/value 7",
      "}",
      "/parameter-2 {",
      "/key 1937008996",
      "/showInPalette -1",
      "/type (integer)",
      "/value 23",
      "}",
      "/parameter-3 {",
      "/key 1851878757",
      "/showInPalette -1",
      "/type (ustring)",
      "/value [ 11",
      "48696465204f7468657273",
      "]",
      "}",
      "}",
      "}",
    ].join("\n");

    createAction(actionStr);

    app.doScript(myAction, mySet, false);
    actionStr = null;
    app.unloadAction(mySet, "");
    app.userInteractionLevel = currentInteractionLevel;
  }

  function createAction(str) {
    var f = new File("~/ScriptAction.aia");
    f.open("w");
    f.write(str);
    f.close();
    app.loadAction(f);
    f.remove();
  }
}

var selectedLayers = get_selected_layers();

for (var index = 0; index < selectedLayers.length; index++) {
  alert(selectedLayers[index].name);
}

Now, in Illustrator's Actions pallete, create a new Action, record an "Insert Menu Item" and choose the custom script as the only action item. Play the script from the Actions pallete, and it hangs/crashes Illustrator. How can this "actions conflict" be resolved? ( @c.pfaffenbichler any ideas?)

 

m1b
Community Expert
Community Expert
December 25, 2024

I haven't done this, but I have a vague memory it might be a known bug (maybe this one? and/or this one?). @CarlosCanto do you know if this is true? @Kurt Gold?

_scott__
Legend
December 24, 2024

I do not know if this is specficially your issue...

 

What I've found is that function keys can conflict with the operating system causing Illustrator to see the F-key as being hit twice. There is no warning, no error, no indication that this is the issue. If you watch the action as it plays "step by step" you can often see the action recycle steps after you've hit the Fkey shortcut.

 

To test this... play the action using the Play button on the panel.. does that work correctly? If yes, then the issue is the Fkey and a conflict. Tracking down the conflict (across the operating system) may take some invistigation.

reubenlara
Known Participant
December 24, 2024

Thanks for the good suggestion. I removed the F key shortcut and just played it from the palette, and it's the same issue. What would you suggest as a next step toward troubleshooting?