public void TestThatFactoryMethodForIStickyNoteModelIsFromEM1ForGraphView()
        {
            var method = ExtensionMethodCache <ElementBuilder> .GetExtensionMethod(typeof(GraphView),
                                                                                   typeof(IStickyNoteModel), GraphElementFactory.FilterMethods, GraphElementFactory.KeySelector);

            Assert.AreEqual(typeof(ExtensionMethods1).GetMethod(nameof(ExtensionMethods1.CreateForStickyNote)), method);
        }
        public void TestThatFactoryMethodForINodeModelIsFromDefault(Type domainType)
        {
            var method = ExtensionMethodCache <ElementBuilder> .GetExtensionMethod(domainType,
                                                                                   typeof(INodeModel), GraphElementFactory.FilterMethods, GraphElementFactory.KeySelector);

            Assert.AreEqual(typeof(GraphViewFactoryExtensions).GetMethod(nameof(GraphViewFactoryExtensions.CreateNode)), method);
        }
        public void TestThatFactoryMethodForIPlacematModelIsFromEM1(Type domainType)
        {
            var method = ExtensionMethodCache <ElementBuilder> .GetExtensionMethod(domainType,
                                                                                   typeof(IPlacematModel), GraphElementFactory.FilterMethods, GraphElementFactory.KeySelector);

            Assert.AreEqual(typeof(ExtensionMethods1).GetMethod(nameof(ExtensionMethods1.CreateForPlacemat)), method);
        }
        public void TestThatFactoryMethodForModel3IsFromEM2()
        {
            var method = ExtensionMethodCache <ElementBuilder> .GetExtensionMethod(typeof(ExtensionTestGraphView),
                                                                                   typeof(TestModel3), GraphElementFactory.FilterMethods, GraphElementFactory.KeySelector);

            Assert.AreEqual(typeof(ExtensionMethods2).GetMethod(nameof(ExtensionMethods2.CreateForTestModel3)), method);
        }
        public void TestThatFactoryMethodForModel3IsNullForGraphView()
        {
            var method = ExtensionMethodCache <ElementBuilder> .GetExtensionMethod(typeof(GraphView),
                                                                                   typeof(TestModel3), GraphElementFactory.FilterMethods, GraphElementFactory.KeySelector);

            Assert.IsNull(method);
        }
        public static VisualElement CreateEditorForNodeModel(this VisualElement element, IConstantNodeModel model, Action <IChangeEvent> onValueChanged)
        {
            VisualElement editorElement;

            var ext = ExtensionMethodCache <IConstantEditorBuilder> .GetExtensionMethod(model.GetType(), ConstantEditorBuilder.FilterMethods, ConstantEditorBuilder.KeySelector);

            var graphAsset = model.AssetModel;

            if (ext != null)
            {
                Action <IChangeEvent> myValueChanged = evt =>
                {
                    if (evt != null) // Enum editor sends null
                    {
                        var p        = evt.GetType().GetProperty("newValue");
                        var newValue = p.GetValue(evt);
                        ((ConstantNodeModel)model).ObjectValue = newValue;
                        onValueChanged(evt);
                    }

                    // TODO ugly but required to actually get the graph to be saved. Note that for some reason, the
                    // first edit works because the graph is already dirty
                    EditorUtility.SetDirty(graphAsset as Object);
                };
                var constantBuilder = new ConstantEditorBuilder(myValueChanged);
                editorElement = (VisualElement)ext.Invoke(null, new object[] { constantBuilder, model });
            }
            else
            {
                Debug.Log($"Could not draw Editor GUI for node of type {model.GetType()}");
                editorElement = new Label("<Unknown>");
            }

            return(editorElement);
        }
        //        static StatementSyntax StatementFromExitStrategy(StackExitStrategy stackExitStrategy, ExpressionSyntax returnValue)
        //        {
        //            StatementSyntax lastStatementSyntax;
        //            switch (stackExitStrategy)
        //            {
        //                case StackExitStrategy.Return:
        //                    lastStatementSyntax = ReturnStatement(returnValue);
        //                    break;
        //                case StackExitStrategy.Break:
        //                    lastStatementSyntax = BreakStatement();
        //                    break;
        //                case StackExitStrategy.None:
        //                    lastStatementSyntax = null;
        //                    break;
        //                default:
        //                    lastStatementSyntax = ContinueStatement();
        //                    break;
        //            }
        //
        //            return lastStatementSyntax;
        //        }

        protected virtual IEnumerable <SyntaxNode> BuildNode(INodeModel statement, IPortModel portModel)
        {
            if (statement == null)
            {
                return(Enumerable.Empty <SyntaxNode>());
            }
            Assert.IsTrue(portModel == null || portModel.NodeModel == statement, "If a Port is provided, it must be owned by the provided node");
            var ext = ExtensionMethodCache <RoslynTranslator> .GetExtensionMethod(
                statement.GetType(),
                FilterMethods,
                KeySelector);

            if (ext != null)
            {
                var syntaxNode     = (IEnumerable <SyntaxNode>)ext.Invoke(null, new object[] { this, statement, portModel }) ?? Enumerable.Empty <SyntaxNode>();
                var annotatedNodes = new List <SyntaxNode>();
                foreach (var node in syntaxNode)
                {
                    var annotatedNode = node?.WithAdditionalAnnotations(new SyntaxAnnotation(Annotations.VSNodeMetadata, statement.Guid.ToString()));
                    annotatedNodes.Add(annotatedNode);
                }

                return(annotatedNodes);
            }
            else
            {
                Debug.LogError("Roslyn Translator doesn't know how to create a node of type: " + statement.GetType());
            }

            return(Enumerable.Empty <SyntaxNode>());
        }
        // PF TODO: This API and ConstantEditorBuilder is badly designed.

        /// <summary>
        /// Creates an editor for a constant.
        /// </summary>
        /// <param name="uiContext">The view in which the editor constant will be displayed.</param>
        /// <param name="portModel">The port that owns the constant, if any.</param>
        /// <param name="constant">The constant.</param>
        /// <param name="onValueChanged">An action to call when the user has finished editing the value.</param>
        /// <param name="modelIsLocked">Whether the node owning the constant, if any, is locked.</param>
        /// <returns>A VisualElement that contains an editor for the constant.</returns>
        public static VisualElement CreateEditorForConstant(
            IModelView uiContext, IPortModel portModel, IConstant constant,
            Action <IChangeEvent, object> onValueChanged, bool modelIsLocked)
        {
            Action <IChangeEvent> myValueChanged = evt =>
            {
                if (evt != null) // Enum editor sends null
                {
                    var p        = evt.GetType().GetProperty("newValue");
                    var newValue = p.GetValue(evt);
                    if (constant is IStringWrapperConstantModel stringWrapperConstantModel)
                    {
                        stringWrapperConstantModel.StringValue = (string)newValue;
                    }
                    else
                    {
                        onValueChanged(evt, newValue);
                    }
                }
            };

            var ext = ExtensionMethodCache <IConstantEditorBuilder> .GetExtensionMethod(
                uiContext.GetType(), constant.GetType(),
                ConstantEditorBuilder.FilterMethods, ConstantEditorBuilder.KeySelector);

            if (ext != null)
            {
                var constantBuilder = new ConstantEditorBuilder(myValueChanged, uiContext.CommandDispatcher, modelIsLocked, portModel);
                return((VisualElement)ext.Invoke(null, new object[] { constantBuilder, constant }));
            }

            Debug.Log($"Could not draw Editor GUI for node of type {constant.Type}");
            return(new Label("<Unknown>"));
        }
        public void TestConstantEditorExtensionMethodsExistForBasicTypes()
        {
            var expectedTypes = new[]
            {
                typeof(StringConstant), typeof(BooleanConstant), typeof(IntConstant),
                typeof(DoubleConstant), typeof(FloatConstant),
                typeof(Vector2Constant), typeof(Vector3Constant), typeof(Vector4Constant), typeof(QuaternionConstant),
                typeof(EnumConstant), typeof(ColorConstant),
                typeof(AnimationClipConstant), typeof(MeshConstant), typeof(Texture2DConstant), typeof(Texture3DConstant),
                typeof(EnumValueReference)
            };

            for (var i = 0; i < expectedTypes.Length; i++)
            {
                var type = expectedTypes[i];

                var constantExtMethod = ExtensionMethodCache <IConstantEditorBuilder> .GetExtensionMethod(typeof(GraphView), type, ConstantEditorBuilder.FilterMethods, ConstantEditorBuilder.KeySelector);

                Assert.IsNotNull(constantExtMethod, $"No constant editor for {type.Name}");
            }
        }
Beispiel #10
0
        /// <summary>
        /// Creates an instance of a class implementing <see cref="IModelUI"/> to display <paramref name="model"/>.
        /// </summary>
        /// <param name="view">The view in which to put the UI.</param>
        /// <param name="commandDispatcher">The command dispatcher.</param>
        /// <param name="model">The model.</param>
        /// <param name="context">A context creation string. When a model needs different UI in
        /// different contexts, use this parameter to differentiate between contexts.</param>
        /// <typeparam name="T">The type of the returned object.</typeparam>
        /// <returns>An instance of <see cref="IModelUI"/> that display <paramref name="model"/>.</returns>
        public static T CreateUI <T>(IModelView view, CommandDispatcher commandDispatcher, IGraphElementModel model, string context) where T : class, IModelUI
        {
            if (view == null)
            {
                Debug.LogError("GraphElementFactory could not create element because view is null.");
                return(null);
            }

            if (model == null)
            {
                Debug.LogError("GraphElementFactory could not create element because model is null.");
                return(null);
            }

            var ext = ExtensionMethodCache <ElementBuilder> .GetExtensionMethod(
                view.GetType(),
                model.GetType(),
                FilterMethods,
                KeySelector
                );

            T newElem = null;

            if (ext != null)
            {
                var nodeBuilder = new ElementBuilder {
                    View = view, Context = context
                };
                newElem = ext.Invoke(null, new object[] { nodeBuilder, commandDispatcher, model }) as T;
            }

            if (newElem == null)
            {
                Debug.LogError($"GraphElementFactory doesn't know how to create a UI of type {typeof(T)} for model of type: {model.GetType()}");
                return(null);
            }

            return(newElem);
        }
Beispiel #11
0
 public void TestUINodeBuilderExtensionMethods()
 {
     TestExtensionMethodsAreSameFastAndSlow(mode =>
                                            ExtensionMethodCache <ElementBuilder> .BuildFactoryMethodCache(GraphElementFactory.FilterMethods, GraphElementFactory.KeySelector, mode));
 }
Beispiel #12
0
 public void TestConstantEditorExtensionMethods()
 {
     TestExtensionMethodsAreSameFastAndSlow(mode =>
                                            ExtensionMethodCache <IConstantEditorBuilder> .BuildFactoryMethodCache(ConstantEditorBuilder.FilterMethods, ConstantEditorBuilder.KeySelector, mode));
 }