Merge pull request #1891 from niacdoial/master

Further handling of node depreciation
This commit is contained in:
Lubos Lenco 2020-09-28 10:14:34 +02:00 committed by GitHub
commit dc515c97d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 251 additions and 107 deletions

View file

@ -139,6 +139,7 @@ def on_load_post(context):
# Show trait users as collections
arm.utils.update_trait_collections()
props.update_armory_world()
def reload_blend_data():
armory_pbr = bpy.data.node_groups.get('Armory PBR')

View file

@ -0,0 +1,27 @@
import bpy
from bpy.props import *
from bpy.types import Node, NodeSocket
from arm.logicnode.arm_nodes import *
class GetMouseLockNode(ArmLogicTreeNode):
"""Deprecated. It is recommended to use the 'Get Cursor State' node instead."""
bl_idname = 'LNGetMouseLockNode'
bl_label = 'Get Mouse Lock (Deprecated)'
bl_description = "Please use the \"Get Cursor State\" node instead"
bl_icon = 'ERROR'
arm_version = 2
def init(self, context):
super(GetMouseLockNode, self).init(context)
self.outputs.new('NodeSocketBool', 'Is Locked')
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.arm_version not in (0, 1):
raise LookupError()
return NodeReplacement(
'LNGetMouseLockNode', self.arm_version, 'LNGetCursorStateNode', 1,
in_socket_mapping = {}, out_socket_mapping={0:2}
)
add_node(GetMouseLockNode, category='input', section='mouse', is_obsolete=True)

View file

@ -0,0 +1,30 @@
import bpy
from bpy.props import *
from bpy.types import Node, NodeSocket
from arm.logicnode.arm_nodes import *
class GetMouseVisibleNode(ArmLogicTreeNode):
"""Deprecated. It is recommended to use the 'Get Cursor State' node instead."""
bl_idname = 'LNGetMouseVisibleNode'
bl_label = 'Get Mouse Visible (Deprecated)'
bl_description = "Please use the \"Get Cursor State\" node instead"
bl_icon='ERROR'
arm_version = 2
def init(self, context):
super(GetMouseVisibleNode, self).init(context)
self.outputs.new('NodeSocketBool', 'Is Visible')
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.arm_version not in (0, 1):
raise LookupError()
mainnode = node_tree.nodes.new('LNGetCursorStateNode')
secondnode = node_tree.nodes.new('LNNotNode')
node_tree.links.new(mainnode.outputs[2], secondnode.inputs[0])
for link in self.outputs[0].links:
node_tree.links.new(secondnode.outputs[0], link.to_socket)
return [mainnode, secondnode]
add_node(GetMouseVisibleNode, category='input', section='mouse', is_obsolete=True)

View file

@ -0,0 +1,50 @@
from arm.logicnode.arm_nodes import *
class MouseCoordsNode(ArmLogicTreeNode):
"""Deprecated. It is recommended to use 'Get Cursor Location' node and the 'Get Mouse Movement' node instead."""
bl_idname = 'LNMouseCoordsNode'
bl_label = 'Mouse Coords (Deprecated)'
bl_description = "Please use the \"Get Cursor Location\" and \"Get Mouse Movement\" nodes instead"
bl_icon = 'ERROR'
arm_version = 2
def init(self, context):
super(MouseCoordsNode, self).init(context)
self.add_output('NodeSocketVector', 'Coords')
self.add_output('NodeSocketVector', 'Movement')
self.add_output('NodeSocketInt', 'Wheel')
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.arm_version not in (0, 1):
raise LookupError()
all_new_nodes = []
if len(self.outputs[0].links) > 0:
# "coords": use the cursor coordinates
newmain = node_tree.nodes.new('LNGetCursorLocationNode')
new_secondary = node_tree.nodes.new('LNVectorNode')
node_tree.links.new(newmain.outputs[0], new_secondary.inputs[0])
node_tree.links.new(newmain.outputs[1], new_secondary.inputs[1])
for link in self.outputs[0].links:
node_tree.links.new(new_secondary.outputs[0], link.to_socket)
all_new_nodes += [newmain, new_secondary]
if len(self.outputs[1].links) > 0 or len(self.outputs[2].links) > 0:
# "movement": use the mouse movement
# "wheel": use data from mouse movement as well
newmain = node_tree.nodes.new('LNGetMouseMovementNode')
all_new_nodes.append(newmain)
if len(self.outputs[1].links) > 0:
new_secondary = node_tree.nodes.new('LNVectorNode')
all_new_nodes.append(new_secondary)
node_tree.links.new(newmain.outputs[0], new_secondary.inputs[0])
node_tree.links.new(newmain.outputs[1], new_secondary.inputs[1])
for link in self.outputs[1].links:
node_tree.links.new(new_secondary.outputs[0], link.to_socket)
for link in self.outputs[2].links:
node_tree.links.new(newmain.outputs[2], link.to_socket)
return all_new_nodes
add_node(MouseCoordsNode, category='input', section='mouse', is_obsolete=True)

View file

@ -1,10 +1,12 @@
from arm.logicnode.arm_nodes import *
class OnGamepadNode(ArmLogicTreeNode):
"""Deprecated. Is recommended to use 'Gamepad' node instead."""
"""Deprecated. It is recommended to use the 'Gamepad' node instead."""
bl_idname = 'LNOnGamepadNode'
bl_label = 'On Gamepad'
arm_version = 1
bl_label = "On Gamepad (Deprecated)"
bl_description = "Please use the \"Gamepad\" node instead"
bl_icon = 'ERROR'
arm_version = 2
property0: EnumProperty(
items = [('Down', 'Down', 'Down'),
@ -44,4 +46,15 @@ class OnGamepadNode(ArmLogicTreeNode):
layout.prop(self, 'property0')
layout.prop(self, 'property1')
add_node(OnGamepadNode, category=PKG_AS_CATEGORY, section='gamepad')
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.arm_version not in (0, 1):
raise LookupError()
return NodeReplacement(
"LNOnGamepadNode", self.arm_version,
"LNMergedGamepadNode", 1,
in_socket_mapping={0: 0}, out_socket_mapping={0: 0},
property_mapping={"property0": "property0", "property1": "property1"}
)
add_node(OnGamepadNode, category='input', section='gamepad', is_obsolete=True)

View file

@ -1,10 +1,12 @@
from arm.logicnode.arm_nodes import *
class OnKeyboardNode(ArmLogicTreeNode):
"""Deprecated. Is recommended to use 'Keyboard' node instead."""
"""Deprecated. It is recommended to use the 'Keyboard' node instead."""
bl_idname = 'LNOnKeyboardNode'
bl_label = 'On Keyboard'
arm_version = 1
bl_label = "On Keyboard (Deprecated)"
bl_descrition = "Please use the \"Keyboard\" node instead"
bl_icon = 'ERROR'
arm_version = 2
property0: EnumProperty(
items = [('Down', 'Down', 'Down'),
@ -75,4 +77,15 @@ class OnKeyboardNode(ArmLogicTreeNode):
layout.prop(self, 'property0')
layout.prop(self, 'property1')
add_node(OnKeyboardNode, category=PKG_AS_CATEGORY, section='keyboard')
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.arm_version not in (0, 1):
raise LookupError()
return NodeReplacement(
"LNOnKeyboardNode", self.arm_version,
"LNMergedKeyboardNode", 1,
in_socket_mapping={}, out_socket_mapping={0: 0},
property_mapping={"property0": "property0", "property1": "property1"}
)
add_node(OnKeyboardNode, category='input', section='keyboard', is_obsolete=True)

View file

@ -1,10 +1,13 @@
from arm.logicnode.arm_nodes import *
class OnMouseNode(ArmLogicTreeNode):
"""Deprecated. Is recommended to use 'Mouse' node instead."""
"""Deprecated. It is recommended to use the 'Mouse' node instead."""
bl_idname = 'LNOnMouseNode'
bl_label = 'On Mouse'
arm_version = 1
bl_label = "On Mouse (Deprecated)"
bl_description = "Please use the \"Mouse\" node instead"
bl_icon = 'ERROR'
arm_version = 2
property0: EnumProperty(
items = [('Down', 'Down', 'Down'),
('Started', 'Started', 'Started'),
@ -25,4 +28,15 @@ class OnMouseNode(ArmLogicTreeNode):
layout.prop(self, 'property0')
layout.prop(self, 'property1')
add_node(OnMouseNode, category=PKG_AS_CATEGORY, section='mouse')
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.arm_version not in (0, 1):
raise LookupError()
return NodeReplacement(
"LNOnMouseNode", self.arm_version,
"LNMergedMouseNode", 1,
in_socket_mapping={}, out_socket_mapping={0: 0},
property_mapping={"property0": "property0", "property1": "property1"}
)
add_node(OnMouseNode, category='input', section='mouse', is_obsolete=True)

View file

@ -1,10 +1,10 @@
from arm.logicnode.arm_nodes import *
class RotateObjectAroundAxisNode(ArmLogicTreeNode):
"""Use to rotate an object around an axis. Deprecated."""
"""Deprecated. It is recommended to use the 'Rotate Object' node instead."""
bl_idname = 'LNRotateObjectAroundAxisNode'
bl_label = 'Rotate Object Around Axis'
bl_description = 'Rotate Object Around Axis (Depreciated: use "Rotate Object")'
bl_label = 'Rotate Object Around Axis (Deprecated)'
bl_description = "Please use the \"Rotate Object\" node instead"
bl_icon = 'ERROR'
arm_version=2
@ -26,9 +26,5 @@ class RotateObjectAroundAxisNode(ArmLogicTreeNode):
property_defaults={'property0': "Angle Axies (Radians)"}
)
def draw_buttons(self, context, layout):
row = layout.row(align=True)
row.label(text='Depreciated. Consider using "Rotate Object"')
add_node(RotateObjectAroundAxisNode, category=PKG_AS_CATEGORY, section='rotation', is_obsolete=True)
add_node(RotateObjectAroundAxisNode, category='transform', section='rotation', is_obsolete=True)

View file

@ -0,0 +1,27 @@
from arm.logicnode.arm_nodes import *
class SetMouseLockNode(ArmLogicTreeNode):
"""Deprecated. It is recommended to use the 'Set Cursor State' node instead."""
bl_idname = 'LNSetMouseLockNode'
bl_label = 'Set Mouse Lock (Deprecated)'
bl_description = "Please use the \"Set Cursor State\" node instead"
bl_icon = 'ERROR'
arm_version = 2
def init(self, context):
super(SetMouseLockNode, self).init(context)
self.add_input('ArmNodeSocketAction', 'In')
self.add_input('NodeSocketBool', 'Lock')
self.add_output('ArmNodeSocketAction', 'Out')
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.arm_version not in (0, 1):
raise LookupError()
return NodeReplacement(
'LNSetMouseLockNode', self.arm_version, 'LNSetCursorStateNode', 1,
in_socket_mapping = {0:0, 1:1}, out_socket_mapping={0:0},
property_defaults={'property0': "Lock"}
)
add_node(SetMouseLockNode, category='input', section='mouse', is_obsolete=True)

View file

@ -0,0 +1,43 @@
from arm.logicnode.arm_nodes import *
class ShowMouseNode(ArmLogicTreeNode):
"""Deprecated. It is recommended to use the 'Set Cursor State' node instead."""
bl_idname = 'LNShowMouseNode'
bl_label = "Set Mouse Visible (Deprecated)"
bl_description = "Please use the \"Set Cursor State\" node instead"
bl_icon = 'ERROR'
arm_version = 2
def init(self, context):
super(ShowMouseNode, self).init(context)
self.add_input('ArmNodeSocketAction', 'In')
self.add_input('NodeSocketBool', 'Show')
self.add_output('ArmNodeSocketAction', 'Out')
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.arm_version not in (0, 1):
raise LookupError()
if len(self.inputs[1].links) == 0:
# if the value is 'hard-coded', then use a simple replacement. Otherwise, use a Not node.
return NodeReplacement(
'LNShowMouseNode', self.arm_version, 'LNSetCursorStateNode', 1,
in_socket_mapping={0:0}, out_socket_mapping={0:0}, # deliberately forgetting input 1 here: it is taken care of in the next line
input_defaults={1: not self.inputs[1].default_value},
property_defaults={'property0': 'Hide'}
)
new_main = node_tree.nodes.new('LNSetCursorStateNode')
new_secondary = node_tree.nodes.new('LNNotNode')
new_main.property0 = 'Hide'
node_tree.links.new(self.inputs[0].links[0].from_socket, new_main.inputs[0]) # Action in
node_tree.links.new(self.inputs[1].links[0].from_socket, new_secondary.inputs[0]) # Value in
node_tree.links.new(new_secondary.outputs[0], new_main.inputs[1]) # Value in, part 2
for link in self.outputs[0].links:
node_tree.links.new(new_main.outputs[0], link.to_socket) # Action out
return [new_main, new_secondary]
add_node(ShowMouseNode, category='input', section='mouse', is_obsolete=True)

View file

@ -0,0 +1 @@
"""dummy file to include the code fro the deprecated nodes"""

View file

@ -1,16 +0,0 @@
import bpy
from bpy.props import *
from bpy.types import Node, NodeSocket
from arm.logicnode.arm_nodes import *
class GetMouseLockNode(ArmLogicTreeNode):
"""Deprecated. Is recommended to use 'Get Cursor State' node instead."""
bl_idname = 'LNGetMouseLockNode'
bl_label = 'Get Mouse Lock'
arm_version = 1
def init(self, context):
super(GetMouseLockNode, self).init(context)
self.outputs.new('NodeSocketBool', 'Is Locked')
add_node(GetMouseLockNode, category=PKG_AS_CATEGORY, section='mouse')

View file

@ -1,16 +0,0 @@
import bpy
from bpy.props import *
from bpy.types import Node, NodeSocket
from arm.logicnode.arm_nodes import *
class GetMouseVisibleNode(ArmLogicTreeNode):
"""Deprecated. Is recommended to use 'Get Cursor State' node instead."""
bl_idname = 'LNGetMouseVisibleNode'
bl_label = 'Get Mouse Visible'
arm_version = 1
def init(self, context):
super(GetMouseVisibleNode, self).init(context)
self.outputs.new('NodeSocketBool', 'Is Visible')
add_node(GetMouseVisibleNode, category=PKG_AS_CATEGORY, section='mouse')

View file

@ -1,15 +0,0 @@
from arm.logicnode.arm_nodes import *
class MouseCoordsNode(ArmLogicTreeNode):
"""Deprecated. Is recommended to use 'Get Cursor Location' and 'Get Mouse Movement' nodes instead."""
bl_idname = 'LNMouseCoordsNode'
bl_label = 'Mouse Coords'
arm_version = 1
def init(self, context):
super(MouseCoordsNode, self).init(context)
self.add_output('NodeSocketVector', 'Coords')
self.add_output('NodeSocketVector', 'Movement')
self.add_output('NodeSocketInt', 'Wheel')
add_node(MouseCoordsNode, category=PKG_AS_CATEGORY, section='mouse')

View file

@ -1,15 +0,0 @@
from arm.logicnode.arm_nodes import *
class SetMouseLockNode(ArmLogicTreeNode):
"""Deprecated. Is recommended to use 'Set Cursor State' node instead."""
bl_idname = 'LNSetMouseLockNode'
bl_label = 'Set Mouse Lock'
arm_version = 1
def init(self, context):
super(SetMouseLockNode, self).init(context)
self.add_input('ArmNodeSocketAction', 'In')
self.add_input('NodeSocketBool', 'Lock')
self.add_output('ArmNodeSocketAction', 'Out')
add_node(SetMouseLockNode, category=PKG_AS_CATEGORY, section='mouse')

View file

@ -1,15 +0,0 @@
from arm.logicnode.arm_nodes import *
class ShowMouseNode(ArmLogicTreeNode):
"""Deprecated. Is recommended to use 'Set Cursor State' node instead."""
bl_idname = 'LNShowMouseNode'
bl_label = 'Set Mouse Visible'
arm_version = 1
def init(self, context):
super(ShowMouseNode, self).init(context)
self.add_input('ArmNodeSocketAction', 'In')
self.add_input('NodeSocketBool', 'Show')
self.add_output('ArmNodeSocketAction', 'Out')
add_node(ShowMouseNode, category=PKG_AS_CATEGORY, section='mouse')

View file

@ -300,7 +300,7 @@ def replace(tree: bpy.types.NodeTree, node: bpy.types.Node):
newnode.location = node.location
newnode.select = node.select
elif isinstance(response, list): # a list of nodes:
for node in response:
for newnode in response:
newnode.parent = node.parent
newnode.location = node.location
newnode.select = node.select
@ -327,7 +327,8 @@ def replace(tree: bpy.types.NodeTree, node: bpy.types.Node):
if isinstance(input_socket, arm_sockets.ArmCustomSocket):
if input_socket.arm_socket_type != 'NONE':
input_socket.default_value_raw = input_value
else:
elif input_socket.type != 'SHADER':
# note: shader-type sockets don't have a default value...
input_socket.default_value = input_value
# map properties
@ -346,7 +347,8 @@ def replace(tree: bpy.types.NodeTree, node: bpy.types.Node):
if isinstance(dest_socket, arm_sockets.ArmCustomSocket):
if dest_socket.arm_socket_type != 'NONE':
dest_socket.default_value_raw = src_socket.default_value_raw
else:
elif dest_socket.type != 'SHADER':
# note: shader-type sockets don't have a default value...
dest_socket.default_value = src_socket.default_value
# map outputs
@ -364,9 +366,13 @@ def replaceAll():
list_of_errors = set()
for tree in bpy.data.node_groups:
if tree.bl_idname == "ArmLogicTreeType":
for node in tree.nodes:
for node in list(tree.nodes):
# add the list() to make a "static" copy
# (note: one can iterate it, because and nodes which get removed from the tree leave python objects in the list)
if isinstance(node, (bpy.types.NodeFrame, bpy.types.NodeReroute) ):
pass
elif node.type=='':
pass # that node has been removed from the tree without replace() being called on it somehow.
elif not node.is_registered_node_type():
# node type deleted. That's unusual. Or it has been replaced for a looong time.
list_of_errors.add( ('unregistered', None, tree.name) )
@ -403,8 +409,9 @@ def replaceAll():
print(f"A node of type {node_class} in tree \"{tree_name}\" seemingly comes from a future version of armory. "
f"Please check whether your version of armory is up to date", file=reportf)
elif error_type == 'bad version':
print(f"A node of type {node_class} in tree \"{tree_name}\" Doesn't have version information attached to it."
f"if might come from an armory addon. If so, please check that the version of said addon is compatible with armory", file=reportf)
print(f"A node of type {node_class} in tree \"{tree_name}\" Doesn't have version information attached to it. "
f"If so, please check that the nodes in the file are compatible with the in-code node classes. "
f"If this nodes comes from an add-on, please check that it is compatible with this version of armory.", file=reportf)
elif error_type == 'misc.':
print(f"A node of type {node_class} in tree \"{tree_name}\" failed to be updated, "
f"because the node's update procedure itself failed.", file=reportf)
@ -433,9 +440,6 @@ class ReplaceNodesOperator(bpy.types.Operator):
return context.space_data is not None and context.space_data.type == 'NODE_EDITOR'
# Node Replacement Rules (TODO port them)
#add_replacement(NodeReplacement("LNOnGamepadNode", "LNMergedGamepadNode", {0: 0}, {0: 0}, {"property0": "property0", "property1": "property1"}))
#add_replacement(NodeReplacement("LNOnKeyboardNode", "LNMergedKeyboardNode", {}, {0: 0}, {"property0": "property0", "property1": "property1"}))
def register():
arm_sockets.register()

View file

@ -301,10 +301,12 @@ def create_wrd():
wrd.arm_commit = arm_commit
def init_properties_on_load():
global arm_version
if not 'Arm' in bpy.data.worlds:
init_properties()
arm.utils.fetch_script_names()
def update_armory_world():
global arm_version
wrd = bpy.data.worlds['Arm']
# Outdated project
if bpy.data.filepath != '' and (wrd.arm_version != arm_version or wrd.arm_commit != arm_commit): # Call on project load only