Can something cancel observer events?
-
I'm trying to debug a strange behaviour in a script I'm writing.
I have
EntityObserver
s attached to some instances. When I move them one by one, theonChangeEntity
event triggers for each of them. But when I move more than one at once, only one triggers.If I however, create a separate test case where I add an observer to two instances and move them, everything works.
But if I try to add the same test observers to the same instances my script has attached to, they don't trigger.
So there seems like something prevents all the events to trigger. But the console returns no errors or warnings. I'm wondering if there's something in my code that silently cancels the events. Are any of you aware of methods to do so, or have any idea of what I might be doing wrong?
-
hmm... I think I might have found something. When the
onChangeEntity
triggers, I perform a transformation to another instance within the event, it cancels the rest of the events. When I comment out the transformation code, everything else works as expected.Has anyone experienced similar?
Know why this occurs?
Any workarounds? -
The way I understand it, applying a change will trigger another check within SU to see if anything in the model has changed. This will supersede any previous checks (and thus any previous observer calls). You should store any planned changes (i.e. transforms) and the entities to be changed, and call them after everything else you want to check is done.
You're lucky you haven't gotten a BugSplat - that was what happened when I did some early Observer experiments in this vein and figured out what was happening.
-
@rickw said:
The way I understand it, applying a change will trigger another check within SU to see if anything in the model has changed. This will supersede any previous checks (and thus any previous observer calls). You should store any planned changes (i.e. transforms) and the entities to be changed, and call them after everything else you want to check is done.
You're lucky you haven't gotten a BugSplat - that was what happened when I did some early Observer experiments in this vein and figured out what was happening.
I'm not getting a BugSplat at that point. But I do get one after I do File->New two times; http://www.sketchucation.com/forums/scf/viewtopic.php?f=180&t=18967
-
The event system inside SketchUp is not designed to allow changes to geometry inside an event handler. You have to be very careful about any changes to the model that you make here. Bugsplats are common.
In some cases, the problem is that changes that you make can fire another event, which can lead to infinite loops or cancelled event chains.
When I was working on DCs, I quickly learned that the onToolStateChange event is the one spot that you can safely alter the model without crashes. For example, instead of watching the entities to see if they're moved, watch the move tool and the selection to figure out what the user is moving, and react accordingly.
Of course, the tool state doesn't always change exactly where and how you might like it to, but by keeping track of states in some local variables, you can figure out what's going on.
As you work through all of this, please keep in mind that the new API docs need help for not only what is wrong or missing, but for additional notes about how and now not to use the observers. Keep on adding to the documentation to-do thread and over time we'll at least make it easier on future developers.
Cheers,
-
Bugsplats - check
Infinite loops - check
Headache - checkBack to the drawing board. I think I need to make some sort of queuing system for actions to perform. Though, I'm not sure 'when' I can apply them safely.
And the thing about the Tools observer, that monitor user actions. But what if other plugins do modification to the geometry I'm watching?
-
@thomthom said:
Back to the drawing board. I think I need to make some sort of queuing system for actions to perform. Though, I'm not sure 'when' I can apply them safely.
I haven't done too much experimentation with it, but I suspect that the timer approach would work safely.
Another idea: have you played with onTransactionCommit? In theory, you could queue up your "stuff to do", and then do it all inside this handler. I haven't tried that ever, but in theory that event shouldn't be called until everything else is done.
@thomthom said:
And the thing about the Tools observer, that monitor user actions. But what if other plugins do modification to the geometry I'm watching?
You might create an API that allows other developers to manually call your "handleChange" code. You wouldn't catch every plugin out there, but for the popular ones you might be able to coordinate with the authors to do that for you.
-
I was going to look into the Transaction events. I've been avoiding them so far due to the warming in the docs. And you answered a question I had actually; "can you do stuff in onTransactionCommit?"
Another thing I tried was to wrap the transformation change into a transparent
start_operation
. Triedstart_operation 'TTDC - Change', true, false, true
andstart_operation 'TTDC - Change', true, true, fals
e andstart_operation 'TTDC - Change', true, true, true
in hopes that would prevent the cancellation of events. But no luck there.
Advertisement