• S sverchok
  • Информация о проекте
    • Информация о проекте
    • Активность
    • Метки
    • Участники
  • Репозиторий
    • Репозиторий
    • Файлы
    • Коммиты
    • Ветки
    • Теги
    • Участники
    • Диаграмма
    • Сравнение
  • Задачи 148
    • Задачи 148
    • Список
    • Доски
    • Спринты
  • Запросы на слияние 21
    • Запросы на слияние 21
  • CI/CD
    • CI/CD
    • Конвейеры
    • Задания
    • Расписания
  • Развертывания
    • Развертывания
    • Окружения
    • Релизы
  • Пакеты и реестры
    • Пакеты и реестры
    • Реестр пакетов
    • Реестр контейнеров
  • Мониторинг
    • Мониторинг
    • Инциденты
  • Аналитика
    • Аналитика
    • Поток ценности
    • CI/CD
    • Репозиторий
  • Wiki
    • Wiki
  • Сниппеты
    • Сниппеты
  • Активность
  • Диаграмма
  • Создать новую задачу
  • Задания
  • Коммиты
  • Доски с задачами
Свернуть панель
  • nikitronn
  • sverchok
  • Задачи
  • #1959
Закр.
Открыто
Задача созд. Дек 20, 2017 пользователемnikitronn@nikitronnВладелец

Nodes upgrade approaches: discussion

Created by: portnov

Problem statement

Sometimes we have to change some node in incompatible way. Examples of such changes are:

  • Changing type of property
  • Changing type of socket
  • Removing a property
  • Adding input or output not to the end of list
  • etc (it would be nice to have full list of such changes written somewhere, for example right here)

We cant "just change" node code in such situations, because in existing blend files nodes are already set up in the old way, so the new code will not know how to deal with old node.

Current solution

  • Create new node with new bl_idname
  • Move old node to old_nodes

Drawbacks of current approach

  • Users have to manually remove old nodes from their setups and create new ones, if they do not want to see ugly red "Deprecated" frames
  • We have to maintain several versions of the same code
  • In some situations, we have several MkN non-deprecated versions of the same node at the same time.

Suggested approach

  • Introduce a new IntProperty in base node class, node_version, with default value of 0. This property is not displayed anywhere in UI, but it will be stored in blend files as all properties are. This property will mean the version of node code, which was used when this node was created; so this is the version of stored node settings.
  • Introduce a new method in base node class, get_current_version(self). Return value of this method will mean current version of node code. Default implementation just always returns 0.
  • In base implementation of node.init() (not even sv_init, because this one is overriden everywhere) do self.node_version = get_self.get_current_version().
  • Introduce a new method in base node class, upgrade_version(self, old_version, new_version). This method should re-setup node properties and sockets, considering that node was created with old_version of code, and current version of code is new_version.
  • At event of scene loading, loop through all nodes that have node_version != get_current_version(), and mark them as "needing upgrade" somehow (by using node.color or a frame).
  • For actually upgrading node settings, I see two possible approaches:
    • Call node.upgrade_version() automatically at scene loading; This has obvious advantage, which is that user does not have to do anything to upgrade the whole setup.
    • Or have a special bpy.types.Operator, that calls upgrade_version for selected node, and a button for it somewhere, so that user would upgrade nodes manually. This has another advantage: Operator can interact with user somehow, for example ask for initial value of newly introduced property. But, in this approach, we must have in mind, that there can exist non-upgraded nodes, so in process() we will have to add checks like if self.node_version == 0: don't try to use new properties.
  • Similar logic should be triggered after importing nodetree from json.
  • Anyway, after node.upgrade_version() is called, we should do node.node_version = node.get_current_version().
  • When we want to introduce an incompatible change, we will have to:
    • override get_current_version() or increase version number in already existing override (just write return 7 instead of return 6 there).
    • override upgrade_version() or write a new branch in existing one (if old_version == 6 and new_version == 7: self.outputs.new(), self.new_property = default_value and so on)

Obviously, the new approach is to be used only for new situations when we would change nodes in incompatible way; already existing old_nodes will live as they are.

@zeffii @nortikin @DolphinDream any thoughts?

Ответственный
Назначить
Оценка трудозатрат