This Toolkit is for script writers. It is not intended to be used by end users.
The toolkit is finally in stable state and the packaging/deployment issues have apparently been worked.
The point of this Beta1 release is to get some early feedback on the installation process and verify that the installation works ok.
There are not enough docs around to call this a finished product. Nor have I done enough testing.
This Beta works under CS2. Almost all of it will work under CS. And a large part of it will work under PS7.
The next Beta release will address any issues brought up by anybody testing this beast as well as address and document PS7/CS/CS2 compatibility.
Usability within the Bridge framework has not been addressed at all.
Enjoy.
XToolkit Beta1
XToolkit Beta1
The xtools folder was under Common Files/Adobe/
I tried a second time with the folder just at /c/xtools but same result.
Andrew
XToolkit Beta1
Ooops. I left some debugging code in the Install.js script in the method Install.modifyActionFiles.
On lines 115 and 121 in Install.js there are calls to Stdlib.writeToFile.
You can either remove/comment out those two lines or point them to a real directory on your harddisk (like c:\temp) if your curious to see what's going.
More specifically, the two writeToFile calls save the XML representation of the XToolkit.atn file before and after a rather gnarly regexp substitution. It took several attempts to get that one right.
The xtools folder was under Common Files/Adobe/
Do you mean you unzipped the package to Common Files/Adobe?
I tried a second time with the folder just at /c/xtools but same result.
Andrew
The install script should install fine from anywhere.
I've attached a copy of Install.js with the two lines commented.
Thanks much for the find.
ciao,
-X
On lines 115 and 121 in Install.js there are calls to Stdlib.writeToFile.
You can either remove/comment out those two lines or point them to a real directory on your harddisk (like c:\temp) if your curious to see what's going.
More specifically, the two writeToFile calls save the XML representation of the XToolkit.atn file before and after a rather gnarly regexp substitution. It took several attempts to get that one right.
The xtools folder was under Common Files/Adobe/
Do you mean you unzipped the package to Common Files/Adobe?
I tried a second time with the folder just at /c/xtools but same result.
Andrew
The install script should install fine from anywhere.
I've attached a copy of Install.js with the two lines commented.
Thanks much for the find.
ciao,
-X
XToolkit Beta1
Hi X, that attachement is giving me a 404 - does not exist any more?
Andrew
Andrew
XToolkit Beta1
I did those changes and it installed OK and the test with the jsr action worked. Looks very interesting indeed X, thanks - not the least interesting is the loading of all those actions directly into photoshop without even a restart. I will have to think of how I can use that myself.
Tell us more about what we can do with it when you have time.
Andrew
Tell us more about what we can do with it when you have time.
Andrew
XToolkit Beta1
I re-attached the file. It should be fine now.
It's more than just loading Actions on the fly. It's the possiblity of defining or modifying Actions at runtime that's the really big deal here.
I'm starting in on the docs later today or tomorrow. I'll post interesting bits here along the way.
It's more than just loading Actions on the fly. It's the possiblity of defining or modifying Actions at runtime that's the really big deal here.
I'm starting in on the docs later today or tomorrow. I'll post interesting bits here along the way.
XToolkit Beta1
One thing that I think will be pretty cool is a script that will read an Action file into script-space (not load into the palette) and execute an action. After you run the Action and the calling script completes, no more Action in Photoshop. As it currently stands, if you load an Action File dynamically from a script, the Actions are not available for execution until after the script completes.
Why would you want to do something uber-geeky like this?
Photoshop has this interesting 'feature' where a script can call an Action but if the Action contains a call to a script, it comes to a screeching halt. It looks like some kind of reentrancy problem.
This technique will get around that little issue because you never leave the script to run the action. This script will step through each step in the Action and execute in the current interpreter. This should not cause a problem. I can see that the Action Manager may have code to prevent this, but I can always finesse the issue by doing a 'eval("//@include \"" + scriptName + "\";")' instead of letting the Action Manager execute that step.
I'll see if I can get this working for the next release of XToolkit.
Why would you want to do something uber-geeky like this?
Photoshop has this interesting 'feature' where a script can call an Action but if the Action contains a call to a script, it comes to a screeching halt. It looks like some kind of reentrancy problem.
This technique will get around that little issue because you never leave the script to run the action. This script will step through each step in the Action and execute in the current interpreter. This should not cause a problem. I can see that the Action Manager may have code to prevent this, but I can always finesse the issue by doing a 'eval("//@include \"" + scriptName + "\";")' instead of letting the Action Manager execute that step.
I'll see if I can get this working for the next release of XToolkit.
XToolkit Beta1
LOL I was thinking of exactly that yesterday and was going to ask you about whether it could be done. It would be VERY neat to find a way to run scripts within actions from scripts.
"After you run the Action and the calling script completes, no more Action in Photoshop. "
Not sure about that part, or at least have other options. This is something that would be useful to package so script-writers can encorporate it in thier own scripts without making end-users install xtools. Sometimes I would like to be able to leave the action in the pallette so that in certain cases the user can modify the target script.
Then a way to do a Stop that passes control back to PS with a Resume after... but that one I suspect is a step too far.
Andrew
"After you run the Action and the calling script completes, no more Action in Photoshop. "
Not sure about that part, or at least have other options. This is something that would be useful to package so script-writers can encorporate it in thier own scripts without making end-users install xtools. Sometimes I would like to be able to leave the action in the pallette so that in certain cases the user can modify the target script.
Then a way to do a Stop that passes control back to PS with a Resume after... but that one I suspect is a step too far.
Andrew
XToolkit Beta1
Andrew wrote:"After you run the Action and the calling script completes, no more Action in Photoshop. "
Not sure about that part, or at least have other options.
When I say "read the script file" I mean read it with JS into JS datastructures but don't put it in the Action Palette. "loading a script" is loading an Action File into the Action Palette. The problem with this is ,like I said before, you can't load and run an Action from the same script. BTW, the code to load and delete actions is in stdlib.js
This is something that would be useful to package so script-writers can encorporate it in thier own scripts without making end-users install xtools.
I've packaged couple of stand-alone scripts already in xtools. I can do others upon request. The problem is do you want one file or can you deal with multiple files (and have to do //@include's).
Sometimes I would like to be able to leave the action in the pallette so that in certain cases the user can modify the target script.
I think I covered that one above.
Then a way to do a Stop that passes control back to PS with a Resume after... but that one I suspect is a step too far.
If all you are doing is running the Action, it's not that difficult. You just need to save enough state information (ActionFile name, Action name, current step number) to pickup where you left off. If you have complex application state that need to be preserved, that is a more difficult problem.
I'll add in the Stop/Resume stuff to the Action execution code and I'll think a bit more on the application state problem.
One more tidbit: I can do all this with Actions in the Action Palette or Actions in Action Files. It's just simpler and faster to do it with Action files because to do one directly from the Action Palette I have to read in the palette's .psp file which means loading in all of the action. This kinda suX0Rs if you have 1000+ actions, like I do in my CS config.
Ooo! I just thought of another handy utility. How about having a script that will read through the palette .psp file and save off the all of the individual Action Sets (as Action Files). I imagen that this would be more help to someone with a large number of actions.
Not sure about that part, or at least have other options.
When I say "read the script file" I mean read it with JS into JS datastructures but don't put it in the Action Palette. "loading a script" is loading an Action File into the Action Palette. The problem with this is ,like I said before, you can't load and run an Action from the same script. BTW, the code to load and delete actions is in stdlib.js
This is something that would be useful to package so script-writers can encorporate it in thier own scripts without making end-users install xtools.
I've packaged couple of stand-alone scripts already in xtools. I can do others upon request. The problem is do you want one file or can you deal with multiple files (and have to do //@include's).
Sometimes I would like to be able to leave the action in the pallette so that in certain cases the user can modify the target script.
I think I covered that one above.
Then a way to do a Stop that passes control back to PS with a Resume after... but that one I suspect is a step too far.
If all you are doing is running the Action, it's not that difficult. You just need to save enough state information (ActionFile name, Action name, current step number) to pickup where you left off. If you have complex application state that need to be preserved, that is a more difficult problem.
I'll add in the Stop/Resume stuff to the Action execution code and I'll think a bit more on the application state problem.
One more tidbit: I can do all this with Actions in the Action Palette or Actions in Action Files. It's just simpler and faster to do it with Action files because to do one directly from the Action Palette I have to read in the palette's .psp file which means loading in all of the action. This kinda suX0Rs if you have 1000+ actions, like I do in my CS config.
Ooo! I just thought of another handy utility. How about having a script that will read through the palette .psp file and save off the all of the individual Action Sets (as Action Files). I imagen that this would be more help to someone with a large number of actions.
XToolkit Beta1
I didn't take all that much code to be able to read an ActionFile and execute it step by step. This is just a basic runner, more of a proof of concept than anything else.
There are a whole lot of interesting things that can be done with something like this. But, as is, it does illustrate the power of xtools.
Code: Select all//
// ActionRunner
//
// $Id: ActionRunner.js,v 1.1 2005/10/18 15:10:33 anonymous Exp $
// Copyright: (c)2005, xbytor
// License: http://creativecommons.org/licenses/LGPL/2.1
// Contact: xbytor@gmail.com
//
//@show include
//
//@includepath "/c/Program Files/Adobe/Adobe Photoshop CS2/xtools"
//
//@include "xlib/Action.js"
//@include "xlib/xml/atn2bin.jsx"
//
ActionRunner = function(action) {
var self = this;
self.action = action;
self.playbackOptions = undefined;
self.enabled = undefined;
self.dialogMode = undefined; // DilaogModes.ALL ERROR NO
self.ip = 0; // instruction pointer
};
ActionRunner.prototype.typename = "ActionRunner";
ActionRunner.prototype.exec = function() {
var self = this;
while (self.step()) {
; // empty
}
};
ActionRunner.prototype.step = function() {
var self = this;
var action = self.action;
if (self.ip >= action.getCount()) {
return false;
}
var ai = action.byIndex(self.ip);
if (ai.enabled) {
$.level = 1; debugger;
if (ai.identifier == ActionItem.TEXT_ID && ai.name == "Scripts") {
self.runScript(ai.descriptor);
} else {
var execId;
if (ai.identifier == ActionItem.TEXT_ID) {
execId = PSConstants.lookup(ai.name);
} else {
execId = ai.itemID;
}
var desc = ai.hasDescriptor ? ai.descriptor : undefined;
var dmode = ai.withDialog ? DialogModes.ALL : DialogModes.ERROR;
executeAction(execId, desc, dmode);
}
}
self.ip++;
return true;
};
ActionRunner.prototype.runScript = function(desc) {
var file = desc.getPath(cTID("jsCt"));
var str = '//@include "' + file.absoluteURI + '";\r\n';
eval(str);
};
function main() {
var infile = new File("/c/work/XActions.atn");
var actFile = new ActionFile();
actFile.read(infile);
var act = actFile.actionSet.getByName("Test");
var runner = new ActionRunner(act);
runner.exec();
};
main();
"ActionRunner.js";
// EOF
There are a whole lot of interesting things that can be done with something like this. But, as is, it does illustrate the power of xtools.
Code: Select all//
// ActionRunner
//
// $Id: ActionRunner.js,v 1.1 2005/10/18 15:10:33 anonymous Exp $
// Copyright: (c)2005, xbytor
// License: http://creativecommons.org/licenses/LGPL/2.1
// Contact: xbytor@gmail.com
//
//@show include
//
//@includepath "/c/Program Files/Adobe/Adobe Photoshop CS2/xtools"
//
//@include "xlib/Action.js"
//@include "xlib/xml/atn2bin.jsx"
//
ActionRunner = function(action) {
var self = this;
self.action = action;
self.playbackOptions = undefined;
self.enabled = undefined;
self.dialogMode = undefined; // DilaogModes.ALL ERROR NO
self.ip = 0; // instruction pointer
};
ActionRunner.prototype.typename = "ActionRunner";
ActionRunner.prototype.exec = function() {
var self = this;
while (self.step()) {
; // empty
}
};
ActionRunner.prototype.step = function() {
var self = this;
var action = self.action;
if (self.ip >= action.getCount()) {
return false;
}
var ai = action.byIndex(self.ip);
if (ai.enabled) {
$.level = 1; debugger;
if (ai.identifier == ActionItem.TEXT_ID && ai.name == "Scripts") {
self.runScript(ai.descriptor);
} else {
var execId;
if (ai.identifier == ActionItem.TEXT_ID) {
execId = PSConstants.lookup(ai.name);
} else {
execId = ai.itemID;
}
var desc = ai.hasDescriptor ? ai.descriptor : undefined;
var dmode = ai.withDialog ? DialogModes.ALL : DialogModes.ERROR;
executeAction(execId, desc, dmode);
}
}
self.ip++;
return true;
};
ActionRunner.prototype.runScript = function(desc) {
var file = desc.getPath(cTID("jsCt"));
var str = '//@include "' + file.absoluteURI + '";\r\n';
eval(str);
};
function main() {
var infile = new File("/c/work/XActions.atn");
var actFile = new ActionFile();
actFile.read(infile);
var act = actFile.actionSet.getByName("Test");
var runner = new ActionRunner(act);
runner.exec();
};
main();
"ActionRunner.js";
// EOF