View Full Version : scriptJob -nodeNameChanged usefulness?
11 November 2010, 03:37 PM
I'm currently writing my first more or less useful piece of code attached to a custom GUI.
This project is presenting me with challenges at every second line of code, which keeps the process fun but makes for a rather tedious experience.
Anyhow, here's just one of the many problems I've encountered for which I haven't really found a workaround, so I'm asking the Pros :)
How do I keep track of a node's name, even after that node has been renamed?
There's a wonderful pre-defined scriptJob event that I can attach to my node, triggering whenever said node changes its name.
string $myNode = "pSphere1";
scriptJob -nnc $myNode "print(\"Node name changed!\")";
So far, so good. I know when the node get's renamed. The problem is, there is no way for me to tell what the node's name currently is.
I'd have to query that node, but since the name isn't the same as before, I can't point to it.
Interestingly, the scriptJob command seems to be able to keep track of the node, no matter what its current name is, since it obviously triggers after arbitrary rename operations.
Here's the more specific problem:
I have a GUI, which lets the user create a set of objects. These objects are grouped under a groupnode (transform), let's say it's called "ObjectGroup_1".
The GUI lets the user run a script which manipulates the created objects. The script only knows which objects to operate on by querying the children of the group "ObjectGroup_1" (and some other conditions, but they aren't relevant).
The problem is: node names are not bound to any kind of attribute, all the way up to the depency node. So there is no way of locking the (fictional) name attribute to prevent the user from renaming the group node.
So if the users goes ahead and for some reason changes the group's name, then the script will fail at subsequent calls to the old group name. Thing is, I don't want to prevent the user from renaming the group, which could be done easily by simply attaching a rename command to the scriptJob which would revert to the 'old' name. The user should not be restricted from chosing what name he deems appropriate for his DAG objects.
So what I thought I could do is: create a scriptJob together with the group node, attached to the GUI, that triggers whenever the group node's name changes. Then report the new name back to the GUI to pass along to the script.
The problem: I can't think of a way to find out what the group's name has been changed to.
How does the scriptJob itself do it?
I'd be really grateful if someone came up with some hint at a solution.
It's little problems like these that seem to be consuming an uproportional amount of development time, which isn't really acceptable (the main, complex script function was a matter of a few hours; the GUI and waterproofing/crosschecking is taking up days).
11 November 2010, 04:35 PM
without seeing and disassembling your entire code so far Nyro it's hard for me to say you're going about whatever you're doing with these groups correctly. However, I'll assume you are so here's two different ways you could keep track of them:
1) add an attribute to your group, this way, rather than your UI code looking for a specific node by NAME you simply look for the node that has your attribute (`ls "*.myCustomAttr"`).
2) put the group into a SET. then, whenever your code needs to do anything with the group node, just query the SET contents. Sets keep full track of nodes when renamed or reparented.
I know you said you don't want to restrict users fiddling with node properties, but you can also lockNode nodes which makes them unable to be renamed or reparented, which may be a solution for this or for future use...
11 November 2010, 05:22 PM
Thanks for your quick response, Nathan!
Funny thing. I had thought about the 'query by attribute' solution already, but there was some reason why I didn't want to go that way. Problem was, by the time I got to formulating my issue here I had (and still have :/) forgotten that reason :) But there was one, I'm sure of it!
The Set solution seems like a good compromise though. This would also solve my problem of 'where to store custom attributes'. At the moment, I'm storing script-specific parameters in custom attributes of the group node, simply because they're initially derived from GUI controls, but the user could change these control's values and I don't want those changes to be propagated to the currently running script. Also, the values shouldn't vanish if the GUI is deleted (closed).
Because I wanted to hide these parameters (and the node storing them) from the Users eyes (which would prevent him from changing them inside the node, since even locked, hidden attributes can be unlocked and changed), I was searching through the whole Nodes reference to find one that would suit my needs (preferably a non-DAG node, rather a Dependency-type node, which by default are not listed in the outliner or Hypergraph). But none of them seemed appropriate. And I don't know how to create my own nodes (maybe that's a plugin thing, no idea).
The set node is a DAG node, but it looks unobstrusive and, to be completely honest, it does present exactly the functionality that I'm looking for (storing object information).
There is one problem though: the Set node represents the same problem as a transform node acting as a group: The user could want to rename it. I can lock it, but that's just not really what I was after. I figure I have to enter some form of compromise, still I wonder if there isn't a way to make the scriptJob -nnc return the name BEFORE it gets executed.
Or do you know a way to track which commands get executed? Because catching a rename command would provide exactly what I need: the rename command returns the OLD name of the renamed node.
Anyhow, thanks for your suggestion, I'll go with that lacking some form of epiphany on my part :) :beer:
11 November 2010, 12:30 AM
Wow, I'm the biggest dork.
The scriptJob lists "-nameChanged" as an event to listen for. This flag explicitly checks for name changes.
I know I have tons of other questions I'd like to ask here, but after this faux pas, I don't think I'll dare...
11 November 2010, 10:22 AM
oh. I thought that's what you already had and explained about in your first post..! :D
does "NameChanged" solve your problem then?
11 November 2010, 11:40 AM
No. :p I thought it did, but it really is just a variant of the nodeNameChanged flag.
It poses the same problem. But the Set solution works and I'm using that now.
Different question, if you please:
Is there a way to register when a custom window is closed, other than running a scriptjob that checks for the window's existence every other cycle?
11 November 2010, 12:09 PM
yep: scriptJob -uid
however, this does not pre-alert you to closing the UI, so if your UI contains user-data that the user may want to "save" before closing there's no mechanism (afaik) that will allow you to do a sanity check "Are you sure you want to close this UI" kind of thing.
11 November 2010, 12:42 PM
Thanks Nathan. I think I'm starting to spend too much time in the command reference. I'm constantly missing obvious details in in the command descriptions.
The sanity-check part isn't that problematic. Parameters are initialized and then stored outside the UI, in the SET.
But I'd like to give the User the opportunity to say "I've closed the window. I want to cancel all running operations and delete all that I created so far" or "I just want to get the window out of the way but I'll need it later".
So my Sets, whcih are locked and complicated to manually delete, and various scriptJobs don't get left behind (I obviously can't parent them to my GUI, because closing the UI doesn't mean the sJob should be killed).
11 November 2010, 12:42 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.