Merge pull request #2210 from MoritzBrueckner/merge-node

Merge node: add execution mode and output for input index
This commit is contained in:
Lubos Lenco 2021-05-23 16:32:27 +02:00 committed by GitHub
commit 88f522c27b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 4 deletions

View file

@ -2,11 +2,31 @@ package armory.logicnode;
class MergeNode extends LogicNode {
/** Execution mode. **/
public var property0: String;
var lastInputIndex = -1;
public function new(tree: LogicTree) {
super(tree);
tree.notifyOnLateUpdate(lateUpdate);
}
override function run(from: Int) {
// Check if there already were executions on the same frame
if (lastInputIndex != -1 && property0 == "once_per_frame") {
return;
}
lastInputIndex = from;
runOutput(0);
}
override function get(from: Int): Dynamic {
return lastInputIndex;
}
function lateUpdate() {
lastInputIndex = -1;
}
}

View file

@ -1,14 +1,45 @@
from arm.logicnode.arm_nodes import *
class MergeNode(ArmLogicTreeNode):
"""Activates the output when any connected input is activated.
"""Activates the output when at least one connected input is activated.
If multiple inputs are active, the behaviour is specified by the
`Execution Mode` option.
@output Active Input Index: [*Available if Execution Mode is set to
Once Per Input*] The index of the last input that activated the output,
-1 if there was no execution yet on the current frame.
@option Execution Mode: The node's behaviour if multiple inputs are
active on the same frame.
- `Once Per Input`: If multiple inputs are active on one frame, activate
the output for each active input individually (simple forwarding).
- `Once Per Frame`: If multiple inputs are active on one frame,
trigger the output only once.
@option New: Add a new input socket.
@option X Button: Remove the lowermost input socket."""
bl_idname = 'LNMergeNode'
bl_label = 'Merge'
arm_section = 'flow'
arm_version = 1
arm_version = 2
def update_exec_mode(self, context):
self.outputs['Active Input Index'].hide = self.property0 == 'once_per_frame'
property0: EnumProperty(
name='Execution Mode',
description='The node\'s behaviour if multiple inputs are active on the same frame',
items=[('once_per_input', 'Once Per Input',
'If multiple inputs are active on one frame, activate the'
' output for each active input individually (simple forwarding)'),
('once_per_frame', 'Once Per Frame',
'If multiple inputs are active on one frame, trigger the output only once')],
default='once_per_input',
update=update_exec_mode,
)
def __init__(self):
super(MergeNode, self).__init__()
@ -17,10 +48,12 @@ class MergeNode(ArmLogicTreeNode):
def init(self, context):
super(MergeNode, self).init(context)
self.add_output('ArmNodeSocketAction', 'Out')
self.add_output('NodeSocketInt', 'Active Input Index')
def draw_buttons(self, context, layout):
row = layout.row(align=True)
layout.prop(self, 'property0', text='')
row = layout.row(align=True)
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
op.node_index = str(id(self))
op.socket_type = 'ArmNodeSocketAction'
@ -32,3 +65,24 @@ class MergeNode(ArmLogicTreeNode):
return self.bl_label
return f'{self.bl_label}: [{len(self.inputs)}]'
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
if self.arm_version not in (0, 1):
raise LookupError()
newnode = node_tree.nodes.new('LNMergeNode')
newnode.property0 = self.property0
# Recreate all original inputs
array_nodes[str(id(newnode))] = newnode
for idx, input in enumerate(self.inputs):
bpy.ops.arm.node_add_input('EXEC_DEFAULT', node_index=str(id(newnode)), socket_type='ArmNodeSocketAction')
for link in input.links:
node_tree.links.new(link.from_socket, newnode.inputs[idx])
# Recreate outputs
for link in self.outputs[0].links:
node_tree.links.new(newnode.outputs[0], link.to_socket)
return newnode

View file

@ -254,7 +254,8 @@ def replace_all():
print(f"A node whose class doesn't exist was found in node tree \"{tree_name}\"", file=reportf)
elif error_type == 'update failed':
print(f"A node of type {node_class} in tree \"{tree_name}\" failed to be updated, "
f"because there is no (longer?) an update routine for this version of the node.", file=reportf)
f"because there is no (longer?) an update routine for this version of the node. Original exception:"
"\n" + tb + "\n", file=reportf)
elif error_type == 'future version':
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)