Browse Source

Fix #138

Due to memory management issues, it is likely impossible to remove a
node in its own init() callback without crashing Blender. Now, we will
deactivate any output node operators if an output node is already
present in the tree.
pull/152/head
Adam Johnson 6 years ago
parent
commit
e9ee49c8a6
Signed by: Hoikas
GPG Key ID: 0B6515D6FF6F271E
  1. 36
      korman/nodes/__init__.py
  2. 13
      korman/nodes/node_core.py

36
korman/nodes/__init__.py

@ -50,26 +50,48 @@ _kategory_names = {
"SV": "Soft Volume", "SV": "Soft Volume",
} }
class PlasmaNodeItem(NodeItem):
def __init__(self, **kwargs):
self._poll_add = kwargs.pop("poll_add", None)
super().__init__(**kwargs)
@staticmethod
def draw(self, layout, context):
# Blender's NodeItem completely unlists anything that polls False. We would rather
# display the item but disabled so the user has a hint that it exists but cannot be
# used at the present time.
if self._poll_add is not None and not self._poll_add(context):
row = layout.row()
row.enabled = False
NodeItem.draw(self, row, context)
else:
NodeItem.draw(self, layout, context)
# Now, generate the categories as best we can... # Now, generate the categories as best we can...
_kategories = {} _kategories = {}
for cls in dict(globals()).values(): for cls in dict(globals()).values():
if inspect.isclass(cls): if inspect.isclass(cls):
item = {}
if not issubclass(cls, PlasmaNodeBase): if not issubclass(cls, PlasmaNodeBase):
continue continue
if not issubclass(cls, bpy.types.Node): if not issubclass(cls, bpy.types.Node):
continue continue
if issubclass(cls, PlasmaDeprecatedNode): if issubclass(cls, PlasmaDeprecatedNode):
continue continue
else: if issubclass(cls, PlasmaTreeOutputNodeBase):
continue item["poll_add"] = PlasmaTreeOutputNodeBase.poll_add
try:
_kategories[cls.bl_category].append(cls) item["nodetype"] = cls.bl_idname
except LookupError: item["label"] = cls.bl_label
_kategories[cls.bl_category] = [cls,]
kat = _kategories.setdefault(cls.bl_category, [])
kat.append(item)
_actual_kategories = [] _actual_kategories = []
for i in sorted(_kategories.keys(), key=lambda x: _kategory_names[x]): for i in sorted(_kategories.keys(), key=lambda x: _kategory_names[x]):
# Note that even though we're sorting the category names, Blender appears to not care... # Note that even though we're sorting the category names, Blender appears to not care...
_kat_items = [NodeItem(j.bl_idname) for j in sorted(_kategories[i], key=lambda x: x.bl_label)] _kat_items = [PlasmaNodeItem(**j) for j in sorted(_kategories[i], key=lambda x: x["label"])]
_actual_kategories.append(PlasmaNodeCategory(i, _kategory_names[i], items=_kat_items)) _actual_kategories.append(PlasmaNodeCategory(i, _kategory_names[i], items=_kat_items))
def register(): def register():

13
korman/nodes/node_core.py

@ -313,14 +313,11 @@ class PlasmaNodeBase:
class PlasmaTreeOutputNodeBase(PlasmaNodeBase): class PlasmaTreeOutputNodeBase(PlasmaNodeBase):
"""Represents the final output of a node tree""" """Represents the final output of a node tree"""
def init(self, context): @classmethod
nodes = self.id_data.nodes def poll_add(cls, context):
# There can only be one of these nodes per tree, so we will only allow this to be
# There can only be one of these nodes per tree, so let's make sure I'm the only one. # added if no other output nodes are found.
for i in nodes: return not any((isinstance(node, cls) for node in context.space_data.node_tree.nodes))
if isinstance(i, self.__class__) and i != self:
nodes.remove(self)
return
class PlasmaNodeSocketBase: class PlasmaNodeSocketBase:

Loading…
Cancel
Save