0
$\begingroup$

I'm trying to understand the many features AN has developed over normal node api and by reading the code I realize that if you need to be notified of a property change with the classical update hooked to a function call it needs to be declared as normal blender property and there is no way to get update notification with sockets data? For example:

import bpy
from bpy.props import *
from ... base_types.node import AnimationNode

class TestNode(bpy.types.Node, AnimationNode):
    bl_idname = "an_TestNode"
    bl_label = "Test node"

    def runUpdate(self, context): #this never get's called by run2 update
        print("update ", self.run1)
        #print("update ", self.run2 ) #<---- this error not sure how to get it

    def draw(self, layout):
        layout.prop(self, "run1")

    run1 = BoolProperty(name = "run1", default = False, update = runUpdate)

    def create(self):
        self.newInput("Boolean", "run2", "run2", update=self.runUpdate, value = False)

    def execute(self,run2):  
        if run2:
            print("RUN 1 ", self.run1)
            print("RUN 2 ", run2)

In this example the only way (I know) to get run2 value is with the main execute function and update=self.runUpdate never get called.

Also I noticed all the time blender props get hooked to events.propertyChanged / executionCodeChanged etc and/or the function calls createSockets() with @keepNodeState decorator and inside this function the sockets get declared. can someone tell me if I got it right and how is supposed to work to get notified if a value in the socket change and in general what is the correct way to take advantage of these events?

$\endgroup$
1
$\begingroup$

A node should not react to changes of the value of a socket. What you are trying to do is not possible. You cannot create an event handler yourself that is executed when the eg the boolean input socket changes.

Also run2 is not a property of the node. This is why self.run2 raises an error. The final value of run2 is passed into the execute function. It my differ from the value of the socket (when the value comes from another node via a link).

The propertyChanged and executionCodeChanged event handlers are mostly used by the Auto Execution system. When propertyChanged is called the tree will execute (only if Property Changed is activated in the Auto Execution panel).

The executionCodeChanged event on the other side triggers a new generation of the execution code. Furthermore the new execution code will be executed if Tree Changed is activated in the Auto Execution panel.

The keepNodeState decorator stores the current values and links to a node in the beginning of the function execution and sets them back on the newly created sockets when the real function ends. This makes it much easier to update sockets without having to care about all the details every time.

When you create/move/remove sockets the treeChanged event is called automatically. It does pretty much the same as executionCodeChanged. This is why I don't have to call executionCodeChanged again after I changed the sockets.

$\endgroup$
1
  • $\begingroup$ Very complete answer and architecture, this make more sense now, even if I find strange not being able to register my own functions to the change of some value exactly in the case of propertyChanged. I guess is because I'm used to thing to programs "isolated" not that every time it has to run the whole tree $\endgroup$ – diramazioni Sep 22 '16 at 1:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.