Is it safe to change the timeline from the main function of a python tag?
-
Hi, I'm trying to code according to the treading manual..
But it's not clear to me if changing the timeline can be safely done from the main function of a python tag, or that that kind of functionality needs to be done from the "main tread".
Hope to hear from you, tia, Jochem
# some simplified script.. def set_timeline(): # at the moment this runs (without crashes) from the main function on a python tag.. startFrame = 0 endFrame = 123 # just some numbers.. doc = op.GetDocument() fps = doc.GetFps() minTime = c4d.BaseTime(startFrame,fps) doc.SetMinTime(minTime) doc.SetLoopMinTime(minTime) maxTime = c4d.BaseTime(endFrame, fps) doc.SetMaxTime(maxTime) doc.SetLoopMaxTime(maxTime) def message(msg_type, data): # simplified message function.. # .. if not c4d.threading.GeIsMainThread(): return # safer to call set_timeline() from here?..
-
Hello @jochemdk,
modifying a document from outside of the main thread (testable via c4d.threading.GeIsMainThreadAndNoDrawThread) is never safe. The
main
function of a Python Programming tag is just an alias forTagData.Execute
and therefore never runs on the main thread. Expressions (tags) have the exception that it is here okay to set parameters of scene elements in off-main-thread functions; for anything else it is also forbidden to modify parameter values off-main-thread.But doing something fundamental like adding or removing scene elements, changing the current time value of the document is bound to cause problems when done in
TagData.Execute
. You should do this inmessage
. But you must also there check if you are on the MT, there is no guarantee thatmessage
will run on the MT all the time. See also: Threading Manual.In general something like this should not be implemented without a button click, i.e., there should be a button in your tag UI, and only when the user clicks it, you should modify the document time. You can also technically have a tag which piggy-backs on some other commonly on the main thread emitted message but that is also not the best idea.
And regrading things 'working fine': These restrictions exist because the backend auf Cinema 4D is written in C++. And while the scene execution pipeline runs, a document is considered immutable as everything is running in parallel and operating on pointers to some data in memory. When you now write a plugin which deletes data (adding data can also cause problems, as adding data can lead to other data being reallcoated), this will result in a crash when something else relies on that data and blindly accesses it under the assumption that it still exists. Simple example would be your plugin deleting points from a point object, and another plugin holding a pointer to these points to which was established earlier. Now it tries to access N points, but there are only N - 1 points now because you deleted one, and the fireworks begin.
Cheers,
Ferdinand -
OK, clear, thx!