Closed s0600204 closed 5 years ago
Thanks for the very accurate report :smile: I can't reproduce the problem :confounded: which is odd, but I think I know what is happening.
So your theory is very likely correct, as the direct cause of the problem, but, even if you don't disconnect the signals (those from core/signal.py
not the Qt ones) this shouldn't happen.
Those connections will die with the old layout (and it's model), this should happen during Application._new_session
where the old session is "deleted", if this doesn't happen it means that probably something is keeping one of the object in the chain session->layout->layout-model-adapter
alive.
:rocket: To debug this you can use objgraph
specifically objgraph.show_backrefs
, something like objgraph.show_backref(objgraph.by_type("<ClassName or fully.qualified.ClassName>"))
Those connections will die with the old layout
To be more clear on this point, the Slot
class used by Signal
to wrap the connected callable (functions/methods/...) keeps only a weak-reference
of the the callable, this way a connection signal->slot
will never keep alive another object.
There is a second (less likely) possibility, as said by the python weakref documentation:
However, until the object is actually destroyed the weak reference may return the object even if there are no strong references to it.
:rocket: You can try to test the above using gc.collect
, and force a garbage-collection in Application._new_session
:man_facepalming: seems I've committed a rookie error - I didn't check whether this was the base code, or caused by some of the various changes I've made locally. This error is, in fact, self-inflicted.
@s0600204 no problem :smile:
(Tested on the
develop
branch, haven't tried inv0.5.1
release.)Expected Behaviour
When loading a showfile, cues in the "Cart" layout are placed in the positions they were in when the showfile was last saved,
Actual Behaviour
Under certain conditions, cues in the "Cart" layout are not in the positions they were in when the showfile was last saved.
Instead they appear in the order they are recorded in the showfile's JSON, with the first cue at 0,0,0 (page,row,column), the second at 0,0,1, the third at 0,0,2, and so on.
To replicate:
What works:
What doesn't work:
Diagnosing:
core/signal.py
Signal::connect
(about line 172).logging.warn(slot_callable)
before the linewith self.__lock:
.And here appears to be the problem. We've opened a showfile using the "Cart" layout. But because we've previously had the "List" layout active (and not restarted the application), the "List" layout methods/slots are still connected.
Theory
In the "Cart" layout, cue indexes can be non-contiguous. In the "List" layout, they must be contiguous. Thus, the "List" layout has code in the method that runs when a cue is added to ensure that the cue added has a cue index that conforms, and "corrects" it if not.
And that method is still being called...
To test this theory:
plugins/list_layout/models.py
,CueListModel::_item_added
(about line 61),item.index = len(self.__cues)
withpass
,Solution
Ideally, slots belonging to the "List" layout (and its models) should be disconnected when switching to the "Cart" layout. (There are some slots that should or could remain connected, such as those added by the
Triggers
,Controller
andTimecode
plugins.)This could be achieved by altering the
finalize
method of the two layouts to disconnect any and all Slots the layout (and their specific sub-classes and models) have connected.Thoughts?