Commit_operation bug
-
hmm... if you don't modify the model from within the events you usually should be fine. ..but there might be deviating causes. observers has always been a can of worms.
I've tried to make an overview: http://forums.sketchucation.com/viewtopic.php?f=180&t=30793
So - they could be the cause.
Maybe we could get the attention of a Googler to look at this thread...
-
Ok, they ARE the problem.
I have just checked what happens if I don't attach an observer to Sketchup.active_model.entities, and everything is fine with *_operation.
But I still have bug splats when closing SU. I bet this problem has to do with the other EntitiesObservers...
By the moment I need this observers, so I will have to resign myself until the observers run smoothly...
By the way, your overview was so useful to me some weeks ago (I was struggling with another bug). It is a great job
Thank you
-
Which observers and which events did you use?
Can you also briefly describe what you do with the events?
(It'd be nice ot have this info in order to attempts to correlate the issues.)Btw - I just tried abort_operation to write out texture without adding to the undo stack or messing with the outliner:
tw = Sketchup.create_texture_writer model = Sketchup.active_model model.start_operation('Write Textures', true) tmp = model.definitions.add('Temp_TextureWriter') g = tmp.entities.add_group model.materials.to_a.each_with_index { |m,i| next if m.texture.nil? g.material = m tw.load( g ) p tw.write( g, "c;/temp/mat_#{i}.png" ) } model.abort_operation
Notice that I make a temp component definition - and therefore do not add anything to the model's entities collection. In worst case you just end up with a temp definition with an empty group. which I think SU will purge automatically at some point.
The code can be improved with error catching - but the concept works.Think I'll make a wrapper for doing things like this - calling a method with a block where everything inside the block is aborted and therefore not included in the undo stack.
-
Ok, I have three types of observers:
Type 1 < AppObserver
Attached to Sketchup. It defines:
-onQuit, that asks the user to save certain structure of my plugin
-onNewModel, that does the same as onQuit plus hiding the plugin toolbar
-onOpenModel, that does the same as onNewModel
Type 2 < EntitiesObserver
This one is attached to Sketchup.active_model.entities at the beginning of the code. It defines:
-onElementModified, that checks if the modified entity is included in an internal list. In that case, shows a messagebox.
Type 3 < EntitiesObserver
This is attached to some special entities in my application. I have to save the transformations that the user performs on them. It defines:
-onElementModified, that saves the transformation and material of the modified entity
-onEraseEntities, that shows a messagebox
-onElementRemoved, that shows a messagebox
-
@adabyron said:
This one is attached to Sketchup.active_model.entities at the beginning of the code. It defines:
What if something is contained in a group/component?
@adabyron said:
-onElementModified, that saves the transformation and material of the modified entity
"Save" - saving a reference to the material object?
And all of these message boxes - all they do is display a message? Nothing that is done depending on how the user interacts with the messagebox?
-
@thomthom said:
What if something is contained in a group/component?
I don't understand what you mean. I have an internal list of entity IDs (they are groups), and if the modified entity ID is inside this list, I show a message box.
@thomthom said:
"Save" - saving a reference to the material object?
Yes, and the transformation one.
@thomthom said:
And all of these message boxes - all they do is display a message? Nothing that is done depending on how the user interacts with the messagebox?
Nothing. Just messages.
-
@adabyron said:
I don't understand what you mean. I have an internal list of entity IDs (they are groups), and if the modified entity ID is inside this list, I show a message box.
You monitor
model.entities
- but are you sure the entities you want to monitor is always in model.entities and not wrapped in some other group / component?
You don't have to monitor when the active context changes and hook your observer to model.active_entities? -
Yes, I'm sure. The entities I want to monitor are always added to Sketchup.active_model.entities.
-
@adabyron said:
Yes, I'm sure. The entities I want to monitor are always added to Sketchup.active_model.entities.
But if you attach your observer to the active context when a model is created/opened then you are attacking it to model.entities. But if the user creates a group or component where your entities are created - then your observer is not monitoring the correct entities collection.
For that you need to monitor when the active context changes and then add/remove your entities observer when it changes. -
I only want to monitor model.entities. If the user adds a group or component where new entities are created, then I don't care about them. It is the normal behavior of the plugin. It may sound absurd but makes sense in the context of the plugin functionality.
-
Manuela,
Add into your onQuit method, statements that detach your plugin's observers, then dispose of the observer instances by setting them to nil, and then call GC.start (Garbage Collection.)
See if that prevents the BugSplat!s when SU closes.
Advertisement