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

CreateObject component to include default constructor for each BHoM object type #147

Merged
merged 8 commits into from
Nov 1, 2019

Conversation

adecler
Copy link
Member

@adecler adecler commented Oct 23, 2019

NOTE: Depends on

BHoM/BHoM_Engine#1276

Issues addressed by this PR

Closes #124

Test files

Just pop the new component on the canvas and play with it.

Additional comments

  • This is just a first version of the component for testing. There are still quite a few things to sort out properly (such as the speed issue of not relying on existing methods). But should be good enough for you to try.
  • To make it easier to compare behaviours, I have created a completely new component instead of replacing the existing one. This is obviously temporary and will be fixed before merging.
  • This component will replace both the CreateObject and the CreateCustom components so bear that in mind when testing.
  • I have only done the Grassopper UI PR for testing purposes. Will do the other UIs once we settle on the code and are ready to merge this.

@adecler adecler added the type:feature New capability or enhancement label Oct 23, 2019
@adecler adecler added this to the BHoM 3.0 β MVP milestone Oct 23, 2019
@adecler adecler self-assigned this Oct 23, 2019
@adecler adecler added the status:do-not-merge For instance, test PR, for discussion, or dependant PRs not ready for merge label Oct 23, 2019
@epignatelli
Copy link
Member

epignatelli commented Oct 23, 2019

Hi @adecler ! I added the status:WIP label to the pr as it is a draft. I was not sure which one the two was the truth (no label or draft state). Let me know if I can review it, in case, I can remove the label!

@epignatelli epignatelli added the status:WIP PR in progress and still in draft, not ready for formal review label Oct 23, 2019
@adecler
Copy link
Member Author

adecler commented Oct 23, 2019

Thanks @epignatelli , we are starting to have a bit too many labels for it not to be at least a bit confusing :-P. This PR can already be reviewed within the context of what it already promises (i.e. a new component that merges CreateObject and CreateCustom).

@adecler adecler marked this pull request as ready for review October 29, 2019 06:38
@adecler adecler removed the status:do-not-merge For instance, test PR, for discussion, or dependant PRs not ready for merge label Oct 29, 2019
@adecler
Copy link
Member Author

adecler commented Oct 29, 2019

This is now ready for review and merging

Copy link
Member

@epignatelli epignatelli left a comment

Choose a reason for hiding this comment

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

Left some comments in the code. Generally I love it!

@@ -35,15 +35,23 @@ public static partial class Convert

[Input("property", "The system property to convert to bhom")]
[Output("parameter", "The bhom parameter used in the bhom abstract syntax")]
public static oM.UI.ParamInfo ToBHoM(this PropertyInfo property)
public static oM.UI.ParamInfo ToBHoM(this PropertyInfo property, object instance = 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 have had this problem as well some times.
A Convert method should accept only one argument, correct?

Not saying that we need to change this, just trying to understand for the future.

Copy link
Member Author

Choose a reason for hiding this comment

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

It is for sure a rare case. I couldn't really find a better way of doing this (if we actually end up needing it as it is currently placeholder code for further development). I guess there could be an argument for having an additional 'config' parameter required in some conversion although I am not super keen on the idea. This one is purely for performance reason though. I am not a big fan of it so happy for any suggestion to go around it in a different way.

/**** Private Methods ****/
/*************************************/

protected Func<object[], object> CreateConstructor(Type type, List<ParamInfo> parameters)
Copy link
Member

Choose a reason for hiding this comment

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

In the light of the migration of all the methods to construct delegates (https://github.com/BHoM/BHoM_Engine/blob/master/Reflection_Engine/Convert/ToFunc.cs) maybe BH.Engine.Reflection.Create is a better place for this?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point

Description = type.Description();

//object instance = Activator.CreateInstance(type); // Potentially for later
string[] excluded = new string[] { "BHoM_Guid" };
Copy link
Member

@epignatelli epignatelli Oct 31, 2019

Choose a reason for hiding this comment

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

If we are going to use this component to avoid continuously coding Create methods, I think it is scary for people to have the properties of the base BHoMObject as inputs.

LeakyRelu is an example but I am sure there are a lot of others.
It just wants you to set NegativeSlope, the rest is useless (but the user doesn't know that).
image

Although, I would still like to have a way to include them.
My suggesting is an Additional Inputs entry in the context menu, with a checklist where you can check/uncheck the additional properties you need (might extend it to all properties).
You can test it on speckle:
image

To be clear, the additional properties I am referring to are Name, Fragments, Tags and CustomData.

Copy link
Member Author

Choose a reason for hiding this comment

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

I like that.

@epignatelli
Copy link
Member

As a final comment, I think that we can address the comments in a separate pr, especially to unblock the adapter refactoring. Thus, I am approving, but not merging to have a coordination chat before that @adecler

@epignatelli epignatelli self-requested a review October 31, 2019 12:13
Copy link
Member

@epignatelli epignatelli left a comment

Choose a reason for hiding this comment

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

Approving as per comment above.

Do not merge this, please.

@epignatelli epignatelli added the status:do-not-merge For instance, test PR, for discussion, or dependant PRs not ready for merge label Oct 31, 2019
@al-fisher
Copy link
Member

This is looking good - massively going to improve both user and coding experience I think.

One specific comment I have which I think will be good to include in this PR if possible is the way in which the default constructor is represented in the menu.

Is currently showing up as BH.oM.Structure.Elements.Bar(...) as an example.
I think this is likely confusing for new users - as you do not necessarly know what the defining properties of an object are in advance.

Suggest we try and explicitly list out the defining properties as possible inputs. (Knowing that they can actually be removed or left as default).

BH.oM.Structure.Elements.Bar(Node startNode, Node endNode, ISectionProperty sectionProperty, double orientationAngle, BarRelease release, BarFEAType fEAType, Constraint4DOF support, Offset offset)

For bar example will look not too dissimilar to current Engine.Create exposing and mapping directly across many of the object initialiser syntax. a method which we will remove. See screen shot below.

Also as these can get long - I do really like the and "x" more inputs added to the end where needed.

image

@al-fisher
Copy link
Member

@adecler @epignatelli @alelom - what do you think of the above?

@alelom
Copy link
Member

alelom commented Oct 31, 2019

I generally agree we should find a better representation for the (...) constructor.

Suggest we try and explicitly list out the defining properties as possible inputs. (Knowing that they can actually be removed or left as default).

Also as these can get long - I do really like the and "x" more inputs added to the end where needed.

Problem with this is if you end up having a Create constructor and the (...) constructor cut to the same string, I think. So you won't know which one refers to which.

In this cases, I would simply go for the clearest, most explicit description, like using a sentence:
Create BH.oM.Structure.Elements.Bar() with all public properties
which has the advantage of appearing less scary than the other options, or if we want to remain closer to the other options:
BH.oM.Structure.Elements.Bar() - all public properties

@epignatelli
Copy link
Member

epignatelli commented Oct 31, 2019

In agree with all the above as well.
I guess the problem is that the menu is created when Grasshopper loads. At that time we do not yet mine the properties of each object?

I also agree with @alelom about potentially confusing the custom constructor with the Create methods.

Maybe we can exploit curly braces?
BH.oM.Structure.Elements.Bar() { Node StartNode, Node EndNode, ISectionProperty SectionProperty, double OrientationAngle, BarRelease Release, BarFEAType FEAType, Constraint4DOF Support, Offset Offset }

@al-fisher
Copy link
Member

Problem with this is if you end up having a Create constructor and the (...) constructor cut to the same string, I think.

Don't forget we will be removing any and all Create methods that are simply exposing defining properties only - so there will be, by definition, no conflicts or generating the same string.

@al-fisher
Copy link
Member

I guess the problem is that the menu is created when Grasshopper loads. At that time we do not yet mine the properties of each object?

hmmm ... right. Thanks @epignatelli.
@adecler will this be too much of an overhead at load time? Keen to expose the public properties as parameters here if at all possible.

So there are alternate options above - but personally I do like the idea of not labouring the distinction between creating an object through selecting a Create method or reflected public properties through syntax. Is not important to user here - and may confuse. Interested in thoughts though?

@adecler
Copy link
Member Author

adecler commented Nov 1, 2019

Eduardo is right that gathering the properties would be an overhead. But more importantly to me the distinction between the two type of constructors is actually quite important as they behave differently. One can have some of its input removed, the other cannot. Something you will only see when zooming on the component. Having a clear visual indicator of this difference in the menu is therefore important to avoid guessing work in my opinion. Alessio's point of the final method string looking the same due to the cutting of long parameter chain is also very relevant.

@epignatelli , I like you suggestion on using the context menu to allow adding the base properties instead of providing them by default. Agreed that it would be better to do this on a separate PR though so we can merge this and unblock the PR from @alelom .

Let's catch up in your morning before merging this.

@epignatelli epignatelli removed the status:do-not-merge For instance, test PR, for discussion, or dependant PRs not ready for merge label Nov 1, 2019
@epignatelli epignatelli merged commit 3e0e890 into master Nov 1, 2019
@epignatelli epignatelli deleted the BHoM_UI-#124-NewCreateObjectComponent branch November 1, 2019 09:38
@epignatelli
Copy link
Member

I think that #147 (comment) is a bigger obstacle, because it can scary people - they don't know what to do when they are overwhelmed by all the properties.

For this other issue, I agree that the initialiser provides a different experience compared to the other methods. Despite that, the user does not yet know that when he/she's choosing the entry from the list for the first time.
I do not agree with conforming the initialiser string to the others in all its aspects, because the second time the user gets there, he/she cannot distinguish it from the rest.
I do agree that it should provide the same level of info though, like the available properties. But not at the cost of doubling the loading time.

@al-fisher
Copy link
Member

Agreed @epignatelli - good summary above.

on this:

I do agree that it should provide the same level of info though, like the available properties. But not at the cost of doubling the loading time.

Thinking your idea of curly braces could be a subtle but distinct way of clarifying

@adecler
Copy link
Member Author

adecler commented Nov 2, 2019

To be honest I don't really see the point of listing all the properties explicitly while the idea is always the same: all properties are used as input.

@al-fisher
Copy link
Member

When you are creating an object through the UI you do not necessarily know what the defining properties are.
As a new user, or even as a returning user, I think is important to see side by side the different input options when you are creating your object.
To use our favourite Bar as an example! 😄
Seeing the options of BarbyStartAndEndNode and BarbyLine next to each other is important as can inform design of the workflow and any other objects you might need to create on the canvas.
The menus are actually a really helpful way of exploring what is possible.
Dos that make sense?

@adecler
Copy link
Member Author

adecler commented Nov 2, 2019

It does. So you're saying this helps when people don't know what properties an object is made of and there are multiple ways of building an object.

My concern was that it would not be as obvious that we are dealing with a variable input component anymore (hence the ...) but this is a one time learning aspect versus a full time practical issue so I am with you now.

@al-fisher
Copy link
Member

I like your identification of “one time learning aspect versus a full time practical issue“.
Imagining there are a few ideas like that that we could highlight across the UI as we continue to refine. And therefore design best/most appropriate way to support both.

One idea I just had - is around icons. We obviously only want one component!! (that was this whole task!!) but the wee icons in the search list could subtly reference the difference between variable input component or not. Maybe? An option in addition to the written syntax anyway.

@adecler
Copy link
Member Author

adecler commented Nov 4, 2019

Hmmm, the issue I have with that idea is that the icons in the search are an indicator of the component from the task bar used in each case. This might be confusing if the search shows an icon that is not actually in the task bar. I guess we could make a small change but 1) it might be missed by some people 2) others will consider as a different icon altogether.

@al-fisher
Copy link
Member

Yep fair point - if subtle, then may well defeat the point. Icon are small in the menu here too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:feature New capability or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BHoM_UI : Reflect Defining Property Create Methods into CreateObject menu
4 participants