[Closed] When object deleted, delete children. Huh?
So… noticed something odd.
delete objects
deleteAllChangeHandlers id:#del
tPot = teapot()
when tPot deleted id:#del obj do
(
format "obj: %
" obj
format "children: %
" obj.children
)
obj.children returns empty.
Since the when construct is still able to recognize the node that it is working with, I’m guessing there is an intermediate step prior to actual deletion in which the node is removed from any hierarchies it’s part of?
I’m trying to clean up a script I’ve been working on, and was hoping there was a way to use a when construct for this sort of thing, since using the #selectedNodesPreDelete callback feels like killing a mosquito with a bazooka. But I guess not?
EDIT:
As an interesting corollary, when I tried it with scene objects added as a node tab, it worked fine.
when o deleted id:#del obj do
(
nodes = obj.nodes
for i = nodes.count to 1 by -1 where nodes[i] != undefined do
delete nodes[i]
)
it will not help… if you check events for delete process the first will be Unlink (unlink all children of a deleting node), and only after PreDelete
So okay, working with linked hierarchies like that won’t work. But using custom parameters will.
ca = attributes ca
(
parameters ca rollout:ca
(
nodes type:#nodeTab tabSize:0 tabSizeVariable:on
)
rollout ca "ca" ( )
) – end ca
delete objects
theSphere = sphere()
custAttributes.add theSphere ca #unique
theSphere.nodes = #()
for i = 1 to 5 do
(
b = box pos:[i*10,i*10,i*10]
append theSphere.nodes b
)
when theSphere deleted id:#del obj do
(
nodes = obj.nodes
for i = nodes.count to 1 by -1 where nodes[i] != undefined do delete nodes[i]
)
Now, to make things a little trickier. I’d like to make it so that if ANY of the associated nodes are deleted, all of them will be. So I tried the following, and it works. But if used several times in succession (I think about 6 or 7), it crashes Max. Any ideas about that?
delete objects
deleteAllChangeHandlers id:#del
ca = attributes ca
(
parameters ca rollout:ca
(
nodes type:#nodeTab tabSize:0 tabSizeVariable:on
on nodes tabChanged do
(
local owner = (refs.dependents (custAttributes.getOwner this))[1]
d = false
for i = this.nodes.count to 1 by -1 where this.nodes[i] == undefined do
d = true
if d == true do
(
for i = this.nodes.count to 1 by -1 where this.nodes[i] != undefined do
delete this.nodes[i]
if owner != undefined do
delete owner
)
)
) -- end parameters
rollout ca "ca"
(
)
) -- end ca
delete objects
theSphere = sphere()
custAttributes.add theSphere ca #unique
theSphere.nodes = #()
for i = 1 to 5 do
(
b = box pos:[i*10,i*10,i*10]
append theSphere.nodes b
)
when theSphere deleted id:#del obj do
(
nodes = obj.nodes
for i = nodes.count to 1 by -1 where nodes[i] != undefined do delete nodes[i]
)
I had a friend try it out and he claims to have run it over 40 times in a row without incident. At least now I know it’s not just me. And I don’t even know how begin figuring out the cause
global ContainerAttrib = attributes ContainerAttrib
(
local handler
fn getNode = (refs.dependentnodes (custattributes.getowner this) firstonly:on)
fn constructNode node: =
(
if node == unsupplied do node = getNode()
if isvalidnode node do
(
if handler != undefined do deleteChangeHandler handler
handler = when node deleted do
(
delete (for n in this.nodes where isvalidnode n collect n)
this.nodes = #()
)
)
)
parameters params
(
nodes type:#nodeTab tabsizevariable:on
on nodes set val do constructNode()
)
on update do constructNode()
on load do constructNode()
)
(
delete objects
b = dummy name:"master"
custattributes.add b ContainerAttrib
b.ContainerAttrib.constructNode()
b.nodes = for k = 1 to 5 collect (point pos:[k*20,0,0] wirecolor:orange)
)
most important it’s undoable/redoable, and you can also add and delete dependent nodes as well
Definitely an improvement, and probably stable enough for my needs, but at least for me it still crashes after running it (for some reason always exactly) 22 consecutive times. (And I don’t just mean if I spam the script. Even if I wait a while before executing it each time it still happens.)
For my current project, I probably won’t ever run into a situation where I would need to run this repeatedly like that, but I’d still like to know WHY it’s happening
your code might crash by any reason. but … do you say that my code crashes being run isolated?
I’m saying that code you gave me, copied and pasted exactly as is, is crashing after being run repeatedly a whole bunch of times. At least on my machine, running Max 2012 64-bit. I can try it on my laptop later on I guess and see if I get the same results, but you’re saying it isn’t causing any problems on your side, so it may run fine. I guess I will find out.
well… get a new max scene… means load the max. how do you crash the max using my code and only my code?