[Closed] NodeEventCallback issues
I’m looking at the Node Event system as an alternative to the general event callback, to improve performance in a script. But I’ve run into some odd behavior:
#1 selectionChanged doesn’t work with maxscript select/deselect/selectMore commands?
fn selChanged evt nodes =
(
format "% %
" evt nodes;
)
--Destruct previous object in case you run the script more than once.
callbackItem = undefined;
gc()
callbackItem = NodeEventCallback selectionChanged:selChanged;
Try it in the viewport, works fine. Now run this code, and nothing happens:
(
local s = sphere();
select s;
)
#2 Using the ‘all’ event disables calling any other events.
The code from the help doesn’t work as it should:
--Define a callback function to handle linking and layer changes:
fn CallbackFn1 ev nd = (
messageBox ("Event Detected: Event "+(ev as string)+ ", Nodes " + (nd as string))
)
--Define a callback function to handle ALL messages:
fn CallbackFn2 ev nd = (
format "Event Detected: Event %, Nodes %
" ev nd
)
--Register callbacks for link changes, layer changes using the
--first function and for all changes using the second function.
--Act only when mouse is up and there have been no other events
--within one second (1000 milliseconds):
callbackItem = NodeEventCallback mouseUp:true delay:1000 linkChanged:CallbackFn1 layerChanged:CallbackFn1 all:CallbackFn2
Using 3dsmax 2010, the messagebox never pops up when linking or changing layer…
Hmm I don’t know what was going on when I first tried #1, but now that I tried it again today, it just works fine… strange.
#1 doesn’t work… you were right:
if there is an object in the scene already selected, then it works,
but,
if no object is selected, then using maxscript or the 3dsmax interface to create a new object, the callback won’t work.
tecnically, deleting objects changes the selection to ‘none’, but it wont work either
It might sounds odd but both #1 and #2 work right for me (max 2009-32, 2009-64, 2010-32, 2010-64). I’m using Node Event System since max 2009 with no problem.
Hmm that’s crazy…
Also, another thing I’ve been struggling with today, is some weird system exceptions I’m getting in some cases. I have a NodeEventCallback setup for my tool, and want to disable it while merging. So I use a #filePreMerge general event callback to set the NodeEventCallback object to undefined, do a gc() and then at #filePostMerge rebuild it again. Now the crazy thing is, with just one callback type (e.g. selectionChanged), there’s no problem. But as soon as there’s more than one (e.g. selectionChanged and hideChanged), I get a system exception when either of them should be triggered…
I haven’t been able to replicate the issue in a simpler situation either, it’s really strange…
I had no idea that was a property on NodeEventCallback! It’s not in the documentation (2010).
I’ll give that a try!
Hihi, no maxscript agrees with you, there is a .enabled property!
However, I just noticed that this problem does not seem to be caused by the destructing and reconstructing of the NodeEventCallback. I got the same unknown system exception if I did not have any filePreMerge or filePostMerge callbacks and basically left the NodeEventCallback untouched… And now I got it with just the one callback type too…
So something fishy is going on there, I’ll have to look into it more…
Alright, some further oddness. First of all, callback functions in a struct don’t seem to have access to other struct members unless the instance is specifically declared as such:
struct a
(
cbItem,
fifteen = 15,
fn selChanged evt nodes =
(
format "% %
" evt nodes;
format "fifteen: %
" fifteen;
),
fn createCallback =
(
cbItem = NodeEventCallback selectionChanged:selChanged;
)
)
b = a();
b.createCallback()
This will throw an error when changing the selection:
MAXScript NodeEventCallback Exception: – Runtime error: Struct member access requires instance: fifteen <<
Whereas this works:
global b;
struct a
(
cbItem,
fifteen = 15,
fn selChanged evt nodes =
(
format "% %
" evt nodes;
format "fifteen: %
" fifteen;
),
fn createCallback =
(
cbItem = NodeEventCallback selectionChanged:b.selChanged;
)
)
b = a();
b.createCallback()
It is only useful for singleton-like structs of course, since you have to refer to the instance inside the struct itself, but at least it works.
That is to say, it works until you perform a merge… I don’t know if this is caused by the merge itself, or by something else, but this is what I get after merging in a file and changing the selection:
MAXScript NodeEventCallback Exception: – Unknown system exception <<
edit: same issue when opening a new file.
Wrapping the callback function in an anonymous function seems to work around this issue, but it’s not exactly pretty…
global b;
struct a
(
cbItem,
fifteen = 15,
fn selChanged evt nodes =
(
format "% %
" evt nodes;
format "fifteen: %
" fifteen;
),
fn createCallback =
(
cbItem = NodeEventCallback();
cbItem.selectionChanged = fn anonymFn evt nodes = ( b.selChanged evt nodes; )
)
)
b = a();
b.createCallback()
Any thoughts?