예제 #1
0
파일: Node.cs 프로젝트: l2obin/Dynamo
        //Function used to construct our expression. This is used to properly create a curried function call, which will be
        //able to support partial function application.
        protected Expression ToExpression(
            Expression function,
            IEnumerable <string> parameters,
            int expectedArgs,
            Dictionary <INode, string> symbols,
            Dictionary <INode, List <INode> > letEntries,
            HashSet <string> initializedIds,
            HashSet <string> conditionalIds)
        {
            //If no arguments have been supplied and if we are expecting arguments, simply return the function.
            if (arguments.Keys.Count == 0 && expectedArgs > 0)
            {
                return(function);
            }

            //If the number of expected arguments is greater than how many arguments have been supplied, we perform a partial
            //application, returning a function which takes the remaining arguments.
            if (arguments.Keys.Count < expectedArgs)
            {
                //Get all of the missing arguments.
                IEnumerable <string> missingArgs = parameters.Where(
                    input => !arguments.ContainsKey(input)
                    );
                //Return a function that...
                return(Utils.MakeAnon(
                           //...takes all of the missing arguments...
                           missingArgs.ToList(),
                           Expression.NewList_E(
                               FSharpList <Expression> .Cons(
                                   //...and calls this function...
                                   function,
                                   Utils.SequenceToFSharpList(
                                       //...with the arguments which were supplied.
                                       parameters.Select(
                                           input =>
                                           missingArgs.Contains(input)
                                    ? Expression.NewId(input)
                                    : arguments[input].compile(
                                               symbols, letEntries, initializedIds, conditionalIds)))))));
            }

            //If all the arguments were supplied, just return a standard function call expression.
            else
            {
                return(Expression.NewList_E(
                           FSharpList <Expression> .Cons(
                               function,
                               Utils.SequenceToFSharpList(
                                   parameters.Select(
                                       input => arguments[input].compile(
                                           symbols, letEntries, initializedIds, conditionalIds))
                                   )
                               )
                           ));
            }
        }
예제 #2
0
            protected override Expression compileBody(
                Dictionary <INode, string> symbols,
                Dictionary <INode, List <INode> > letEntries,
                HashSet <string> initializedIds,
                HashSet <string> conditionalIds)
            {
                var arg = arguments.First().Value.compile(
                    symbols, letEntries, initializedIds, conditionalIds);

                //idle :: (() -> A) -> A
                //Evaluates the given function in the Revit Idle thread.
                var idle = Expression.NewFunction_E(
                    FSharpFunc <FSharpList <Value>, Value> .FromConverter(
                        args =>
                {
                    var f = (args[0] as Value.Function).Item;

                    if (dynSettings.Controller.DynamoViewModel.RunInDebug)
                    {
                        return(f.Invoke(FSharpList <Value> .Empty));
                    }

                    return(IdlePromise <Value> .ExecuteOnIdle(
                               () => f.Invoke(FSharpList <Value> .Empty)));
                }));

                //startTransaction :: () -> ()
                //Starts a Dynamo Transaction.
                var startTransaction = Expression.NewFunction_E(
                    FSharpFunc <FSharpList <Value>, Value> .FromConverter(
                        _ =>
                {
                    if (_node.Controller.RunCancelled)
                    {
                        throw new CancelEvaluationException(false);
                    }

                    if (!dynSettings.Controller.DynamoViewModel.RunInDebug)
                    {
                        dynRevitSettings.Controller.InIdleThread = true;
                        dynRevitSettings.Controller.InitTransaction();
                    }

                    return(Value.NewDummy("started transaction"));
                }));

                //endTransaction :: () -> ()
                //Ends a Dynamo Transaction.
                var endTransaction = Expression.NewFunction_E(
                    FSharpFunc <FSharpList <Value>, Value> .FromConverter(
                        _ =>
                {
                    if (!dynRevitSettings.Controller.DynamoViewModel.RunInDebug)
                    {
                        dynRevitSettings.Controller.EndTransaction();
                        dynRevitSettings.Controller.InIdleThread = false;

                        dynSettings.Controller.DynamoViewModel.OnRequestLayoutUpdate(this, EventArgs.Empty);

                        _node.ValidateConnections();
                    }
                    else
                    {
                        _node.setDirty(false);
                    }

                    return(Value.NewDummy("ended transaction"));
                }));

                /*  (define (idleArg)
                 *    (startTransaction)
                 *    (let ((a <arg>))
                 *      (endTransaction)
                 *      a))
                 */
                var idleArg = Expression.NewFun(
                    FSharpList <FScheme.Parameter> .Empty,
                    Expression.NewBegin(
                        Utils.SequenceToFSharpList(new List <Expression>
                {
                    Expression.NewList_E(
                        Utils.SequenceToFSharpList(
                            new List <Expression> {
                        startTransaction
                    })),
                    Expression.NewLet(
                        Utils.SequenceToFSharpList(
                            new List <string> {
                        "__result"
                    }),
                        Utils.SequenceToFSharpList(
                            new List <Expression> {
                        arg
                    }),
                        Expression.NewBegin(
                            Utils.SequenceToFSharpList(
                                new List <Expression>
                    {
                        Expression.NewList_E(
                            Utils.SequenceToFSharpList(
                                new List <Expression> {
                            endTransaction
                        })),
                        Expression.NewId("__result")
                    })))
                })));

                // (idle idleArg)
                return(Expression.NewList_E(
                           Utils.SequenceToFSharpList(new List <Expression>
                {
                    idle,
                    idleArg
                })));
            }