Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating the colors of the ports according to the Function State #12826

Merged
merged 5 commits into from
May 3, 2022

Conversation

filipeotero
Copy link
Contributor

@filipeotero filipeotero commented Apr 25, 2022

Purpose

This PR contains the code improvement that changes the colors of the input/output of the nodes by checking the class and library of the object to define if the node is a 'Function'.

colorInputOutputFunction

Declarations

Check these if you believe they are true

  • The codebase is in a better state after this PR
  • Is documented according to the standards
  • The level of testing this PR includes is appropriate
  • User facing strings, if any, are extracted into *.resx files
  • All tests pass using the self-service CI.
  • Snapshot of UI changes, if any.
  • Changes to the API follow Semantic Versioning and are documented in the API Changes document.
  • This PR modifies some build requirements and the readme is updated

Reviewers

@mjkkirschner @QilongTang @Amoursol

FYIs

@RobertGlobant20 @jesusalvino

@QilongTang QilongTang requested a review from mjkkirschner April 25, 2022 20:24
@QilongTang QilongTang added this to the 2.15.0 milestone Apr 25, 2022
@mjkkirschner
Copy link
Member

As I mentioned in the thread, this is not unique to python nodes, but any class that inherits from NodeModel.

@filipeotero
Copy link
Contributor Author

As I mentioned in the thread, this is not unique to python nodes, but any class that inherits from NodeModel.

Sorry, I've understood that this is an issue that happens for Python Nodes because it has default values when created.
Could you be more specific? Do we need to check the output result of the node then? If yes, is there any specific property that returns the type of the return?

@Amoursol
Copy link
Contributor

As I mentioned in the thread, this is not unique to python nodes, but any class that inherits from NodeModel.

Sorry, I've understood that this is an issue that happens for Python Nodes because it has default values when created. Could you be more specific? Do we need to check the output result of the node then? If yes, is there any specific property that returns the type of the return?

@filipeotero as Mike suggested, this same problem will exist on other nodes. Take the following example of the "Color Range" node:

image

This has an issue with the "Function" grey-bar output also. It also has an issue with the input vertical bars too which we didn't catch for Global Launch :( Essentially, the input ports are also satisfied, but show as unsatisfied.

FYI @QilongTang

@filipeotero
Copy link
Contributor Author

Updated the code to check the Result of the node by getting the CachedValue of the model.
Some examples of the nodes after this implementation:

image

@Amoursol Are there more examples to be covered for this issue? Thanks!
FYI: @QilongTang @mjkkirschner

//Is in function state
if (node.NodeModel.IsPartiallyApplied)
//Boolean that defines if the node has a default value from the cache value
isReturningDefaultValue = !string.IsNullOrEmpty(node.NodeModel.CachedValue?.StringData);
Copy link
Member

@mjkkirschner mjkkirschner Apr 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this logic, many nodes return strings which are not default values, and many default values are not strings?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this either. How can you say if a node has default value(s) assigned to one or more input ports if you examine its output (cachedValue)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of getting the info of a Function State from isPartiallyApplied, I'm getting the info from the CachedValue because It's what is appearing in the little console below the node. The idea was to identify if the node has a result, even though It's a null result.
Another thing is that I had to differentiate between the output 'Function' (in which the inputs have to change the color between red/blue and the output grey) and other ones (inputs always blue and output disabled).
I would love to hear any other suggestions from you guys!
Thanks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this flag isReturningDefaultValue.

isReturningDefaultValue = !string.IsNullOrEmpty(node.NodeModel.CachedValue?.StringData);

//This variable checks if the node is a function class
bool isFunctionNode = node.NodeModel.CachedValue != null &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think - there are better options - this is too fragile and could break. Let me look.

src/DynamoCoreWpf/ViewModels/Core/OutPortViewModel.cs Outdated Show resolved Hide resolved
@@ -321,7 +342,7 @@ private void SetupDefaultPortColorValues()
PortBorderBrushColor = PortBorderBrushColorKeepListStructure;
}
// Port has a default value, shows blue marker
else if (UsingDefaultValue && DefaultValueEnabled)
else if (UsingDefaultValue && DefaultValueEnabled || (isReturningDefaultValue && !isFunctionNode))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this will show the port with a blue marker only after the node has executed? Is that the only requirement or is the requirement to also include showing the blue marker for default value ports on NodeModel nodes before they execute because the latter could be quite hard to determine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, after the node has been executed.
Both requirements are valid, right @Amoursol?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how we can achieve the second requirement for nodemodel nodes. @mjkkirschner do you know if we identify a default argument for a ZT node (before it executes) by looking at its signature?

Copy link
Member

@mjkkirschner mjkkirschner Apr 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand how you can prove anything about the default value from the return value of the output ports -

I think it's important to point out that the python node executes because it doesn't NEED its inputs to be satisfied to execute, not because it has default values, it doesn't have default values for its ports, nor do many other explicit NodeModel nodes, like ColorRange etc. (some do of course, but these are two separate things)

NodeModel nodes are compiled to some arbitrary designscript code, and that code runs, unless argument checking is part of that code, it's going to execute.

I'm not yet getting how default values factor into the requirements.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just saw your comment above @filipeotero regarding getting rid of isReturningDefaultValue - sounds good to me.

Copy link
Contributor

@aparajit-pratap aparajit-pratap Apr 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, more strictly speaking, @filipeotero is trying to determine if a node's input ports are "satisfied" (not necessarily default) by inspecting the node output after it has run, and if it returns a non-Function value, he's assuming all ports to be satisfied, whereas if it returns a Function, he's marking them as unsatisfied (if not connected). @filipeotero can you confirm if I'm understanding this correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes @aparajit-pratap, you are right.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct @filipeotero @aparajit-pratap - it's about port satisfaction. This simply means the node will run as intended. On non NodeModel Nodes, this happens when you wire in or unwire a connector. Doesn't have to wait for node execution.

//Is in function state
if (node.NodeModel.IsPartiallyApplied)
//Boolean that defines if the node has a default value from the cache value
isReturningDefaultValue = !string.IsNullOrEmpty(node.NodeModel.CachedValue?.StringData);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this either. How can you say if a node has default value(s) assigned to one or more input ports if you examine its output (cachedValue)?

{
get
{
return svData.IsPointer && Class.Name.Equals("Function") && Class.LibraryMirror.Name.Equals("FunctionObject.ds");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have constants already defined for "Function" and "FunctionObject.ds"? Can you search for these in the codebase? If not, I think we should create them in a common utility class and make them accessible in the ProtoCore project at least.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't find any constants defined for that. Do you have a class in mind for that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ProtoCore.Utils.CoreUtils maybe

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, done. Thanks!

if (node.NodeModel.IsPartiallyApplied)
//This variable checks if the node is a function class
isFunctionNode = node.NodeModel.CachedValue != null &&
node.NodeModel.CachedValue.IsFunction;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be:

isFunctionNode = node.NodeModel.IsPartiallyApplied || (node.NodeModel.CachedValue != null &&
                node.NodeModel.CachedValue.IsFunction);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node.NodeModel.IsPartiallyApplied will not make sense for now because there are cases where the node doesn't return a function ever, like the python node.

Copy link
Member

@mjkkirschner mjkkirschner Apr 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, I actually think it should be

isFunctionNode = node.NodeModel.IsPartiallyApplied && (node.NodeModel.CachedValue != null &&
                node.NodeModel.CachedValue.IsFunction);

We could probably write a node which returns another function from all valid inputs - and it would now turn ports blue, even if it was not partially unsatisfied.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, updating the code...

Copy link
Contributor

@aparajit-pratap aparajit-pratap Apr 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@filipeotero the check if (node.NodeModel.IsPartiallyApplied) was there earlier, so by removing this check, won't you break behavior? I think this check is necessary for those nodes for which you can determine their "unsatisfied" state even before execution.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean a case like this that was working earlier in manual mode will fail won't it:
default_value

@filipeotero filipeotero changed the title Checking if it's a python node for input/output colors Updating the colors of the ports according to the Function State Apr 29, 2022
@QilongTang
Copy link
Contributor

@QilongTang
Copy link
Contributor

No new regressions were introduced in this PR. Merging.

@QilongTang QilongTang merged commit c64c66b into DynamoDS:master May 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants