2
$\begingroup$

I have made an addon that has custom objects with custom data and interfacing. This is an internal tool for the time being.

Now my addon is being used, but I come across a problem when updating it. If I want to add data to my custom objects, I may break previously created objects using an older version of the addon.

I can fix this by a version check of the objects, and then running an upgrade script that adds relevant data fields to the objects.

The best time to check for objects of older version would be on blend file loading time. Can I have such a feature with the python api?

$\endgroup$
4
  • 2
    $\begingroup$ Hello ! This and This should solve your problem $\endgroup$
    – Gorgious
    Aug 19, 2022 at 9:39
  • $\begingroup$ @Gorgious, looks perfect! Will give it a go and report back here. $\endgroup$ Aug 19, 2022 at 10:08
  • $\begingroup$ @Gorgious, it works thanks. Will put an answer up with some details for others learning $\endgroup$ Aug 19, 2022 at 20:32
  • $\begingroup$ Thanks for the comprehensive answer, +1 ;) $\endgroup$
    – Gorgious
    Aug 20, 2022 at 9:44

1 Answer 1

2
$\begingroup$

As answered by @Gorgious in comments.

The answer lies in application handlers, that are particularly designed for this type of feature. They exist for all kinds of events in Blender, including pre and post blend-file loading.

For addons, one need to consider at least 2 important details:

  1. use the bpy.app.handlers.persistent decorator for your callback function (as is shown in the example in the doc link)

  2. Make certain that you remove your handler in the unregister part of your addon (not documented anywhere I could find). For example, add the following lines in your unregister function for the addon:

bpy.app.handlers.load_post.remove(handlerFunction)

The second point is needed because the bpy.app.handlers.load_post list will have the handlerFunction removed as your addon gets unregistered (while still leaving it active in the background none-the-less).

It is particulary important to add add the lines in the unregister function, if you use Jaques Lucke's vscode interface for development. It will break the the vscode extension otherwise, by adding succesive copies of the handler for every time you issue an addon reload.

$\endgroup$
8
  • $\begingroup$ There is not need to create an infinite loop and try/catch for a value error. Calling bpy.app.handlers.load_post.remove(handlerFunction) once is the correct solution. $\endgroup$
    – Robert Gützkow
    Aug 20, 2022 at 10:12
  • $\begingroup$ @RobertGützkow, I disagree. The bpy.app.handlers.load_post.remove(handlerFunction), without looping, is less robust. It only removes the first instance of the handler. The solution I put ensures that the handler truly will be removed by investigating the whole list. The run-time is neglible, and since the risk is that Blender might break (forcing restart, depending on the addon), I believe my suggestion is the better one. Thanks as always for your valuable input. $\endgroup$ Aug 21, 2022 at 8:25
  • $\begingroup$ In that case the actual issue is that the add-on registers the handler more than once. Why would that be the case? $\endgroup$
    – Robert Gützkow
    Aug 21, 2022 at 8:46
  • $\begingroup$ the actual issue is not connected to the number of instances in the list, whether there are one instance of the function handler in the list, or several the problem is the same. And you are right that for well written addons, there should never be more than one instance of the handler added. I was trying to give a robust solution that really makes certain that all instances (due whatever mistake may happen) are removed.... this since it will be the very last chance ever to remove them $\endgroup$ Aug 21, 2022 at 8:48
  • $\begingroup$ .... although I agree, the loop solution is not pretty. Perhaps you could suggest a better line(s), that would yield the same outcome? $\endgroup$ Aug 21, 2022 at 9:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .