tt-acm / DynamoForRebar

A Dynamo package for authoring geometrically complex rebar models in Revit 2016.
Other
39 stars 18 forks source link

Generic Enum Drop Down #40

Closed ksobon closed 8 years ago

ksobon commented 8 years ago

My guess is that your method doesn't produce a node that returns a Type object. It seems to be returning a Name (string) of the selected value. Is that intended use of this method?

capture

moethu commented 8 years ago

Hi, i itended to return a string, but I can also change it to return the actual Enum.

ksobon commented 8 years ago

I was kind of expecting an Enum, so I was a little surprised when I realized this. If you don't mind just sharing in the comments how you would return an actual Enum then I will implement it appropriately in my package. I don't want you to change your implementation if that's how you intended it to work. I have no problem with that. Thanks!

moethu commented 8 years ago

Hi Konrad, sadly the PrimitiveNode Methode doesn't handle any Enums (https://github.com/DynamoDS/Dynamo/blob/e60fc6e1d7ddc7557faf5db3849cfb68794c2bc3/src/Engine/ProtoCore/Parser/AssociativeAST.cs#L2564-L2597) but even it would, it would be nothing else than a string value in a generic node (https://github.com/DynamoDS/Dynamo/blob/9de002f8743d57e1d35698483b2c26830b5f6cd6/src/Legacy/ProtoCore/Parser/Imperative/AST.cs#L94-L97) if you want to use the actual Enumerator you'd have to implement this:

        public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
        {
            // If there the dropdown is still empty try to populate it again
            if (Items.Count == 0 || Items.Count == -1)
            {
                PopulateItems();
            }

            // get the selected items name
            var node = AstFactory.BuildFunctionCall(string.Format("Revit.Elements.{0}",this.EnumerationType.Name), "ByName",
                    new List<AssociativeNode> { AstFactory.BuildStringNode(Items[SelectedIndex].Name) });

            // assign the selected name to an actual enumeration value
            var assign = AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), node);

            // return the enumeration value
            return new List<AssociativeNode> { assign };
        }

But this means you'd have to make sure that corresponding classes are implemented for each Type of Enum. This is not very generic and therefore not suitable for a generic class. This implementation is checking for a method using the AST Function call: AstFactory.BuildFunctionCall(string.Format("Revit.Elements.{0}",this.EnumerationType.Name), "ByName") which means it is looking for a ByName Method in a Revit.Elements.(Enumname) class. If you don't want to hardcode the Revit.Elements Namespace use Reflection to walk though your implementation to search for a matching Enum implementation. I will stick with string since this way it is way more generic and I prefer it this way.

ksobon commented 8 years ago

Got ya! Thanks for the insight.