示例#1
0
 public BuildResult(NodePlugin plugin, CilCompilation compilation, IOperationDefinitionSymbol operation, IMethodDefinition methodToCall,
                    MethodInfo clrMethodToCall, EvalAction evaluateAction, string error)
 {
     Plugin          = plugin;
     Compilation     = compilation;
     Operation       = operation;
     MethodToCall    = methodToCall;
     ClrMethodToCall = clrMethodToCall;
     EvaluateAction  = evaluateAction;
     Error           = error;
 }
示例#2
0
        // Called on main thread
        public void Initialize(Host vlHost, IHDEHost hdeHost, ILogger logger)
        {
            FVlHost   = vlHost;
            FPlatform = (Platform)FVlHost.Session.TargetPlatform;

            FHDEHost = hdeHost;
            FLogger  = logger;
            FHDEHost.MainLoop.OnResetCache += HandleMainLoopOnResetCache;
            FCompilation                   = FPlatform.LatestCompilation;
            Clocks.FRealTimeClock          = new HDERealTimeClock(FHDEHost);
            FHDEHost.MainLoop.OnInitFrame += MainLoop_OnInitFrame;
        }
示例#3
0
        public async Task UpdateAsync(CilCompilation compilation, CancellationToken token)
        {
            try
            {
                var results = new List <NodePlugin.BuildResult>(FInstances.Length);
                foreach (var instance in FInstances)
                {
                    var buildResult = await Task.Run(() => instance.Update(compilation), token);

                    results.Add(buildResult);
                }

                token.ThrowIfCancellationRequested();

                using (var swapper = new HotSwapper(Compilation, compilation, token))
                {
                    foreach (var result in results)
                    {
                        var instance = result.Plugin;
                        if (!instance.IsDisposed) // It could be that the node has already been deleted
                        {
                            instance.SyncPinsAndRestoreState(result, swapper);
                        }
                    }
                    ImplicitEntryPointInstanceManager.Update(swapper);
                    Compilation = compilation;
                }
            }
            catch (OperationCanceledException)
            {
                // Fine
            }
            catch (Exception e)
            {
                LogAndStop(e);
            }
        }
示例#4
0
 public BuildResult WithCompilation(CilCompilation compilation) => compilation != Compilation ? new BuildResult(Plugin, compilation, Operation, MethodToCall, ClrMethodToCall, EvaluateAction, Error) : this;
示例#5
0
        // Gets called on background thread. Does not write to any fields. All results get returned on stack.
        public BuildResult Update(CilCompilation compilation)
        {
            if (compilation == FBuildResult.Compilation)
            {
                return(FBuildResult); // Same compilation, nothing to do
            }
            if (compilation.Age < FBuildResult.Compilation?.Age)
            {
                return(FBuildResult); // Dismiss outdated compilations
            }
            var definitionSymbol = compilation.EntryPoints.FirstOrDefault(e => e.Node.Identity == NodeId) as INodeDefinitionSymbol;

            if (definitionSymbol == null)
            {
                return(FBuildResult.WithError($"Couldn't find entry point with id {NodeId} in compilation."));
            }
            var closedDefinitionSymbol = definitionSymbol.GetClosedOrDefault(definitionSymbol.DocSymbols);

            if (closedDefinitionSymbol == null)
            {
                return(FBuildResult.WithError($"Couldn't close the generic node {definitionSymbol}."));
            }
            // Look for the desired operation and build our evaluate method around it
            IMethodDefinition methodToCall;
            var processDefinitionSymbol = closedDefinitionSymbol as IProcessDefinitionSymbol;

            if (processDefinitionSymbol != null)
            {
                // TODO: Rewrite me to support process nodes fully (calling all its operations!)
                var updateOperation = processDefinitionSymbol.Operations.FirstOrDefault(p => p.Name == NameAndVersion.Update);
                if (updateOperation == null)
                {
                    return(FBuildResult.WithError($"Couldn't find 'Update' operation in {processDefinitionSymbol}."));
                }
                methodToCall = compilation.GetCciMethod(updateOperation);
            }
            else
            {
                methodToCall = compilation.GetCciMethod((IOperationDefinitionSymbol)closedDefinitionSymbol);
            }

            if (methodToCall == null)
            {
                return(FBuildResult.WithError($"Couldn't find suitable method to call in evaluate for node {closedDefinitionSymbol}."));
            }
            if (methodToCall.IsGeneric)
            {
                return(FBuildResult.WithError($"The method {methodToCall} must not be generic. Use the closed flag or annotate in- and output pins to avoid generic nodes."));
            }
            var containingType = methodToCall.ContainingTypeDefinition;

            if (containingType.IsGeneric)
            {
                return(FBuildResult.WithError($"The containing type {containingType} must not be generic. Use the closed flag or annotate in- and output pins to avoid generic nodes."));
            }

            // Only if the method changed our pins need to be synced and our state restored
            if (methodToCall != FBuildResult.MethodToCall)
            {
                var scope              = closedDefinitionSymbol.DocSymbols;
                var operation          = compilation.GetVlOperation(methodToCall, scope);
                var stateOutput        = operation.GetStateOutput();
                var returnValueIsState = !methodToCall.IsStatic;
                var builder            = new EvaluateMethodBuilder(FVlHost, compilation, scope, returnValueIsState);
                var evaluateAction     = builder.Build(methodToCall);
                return(new BuildResult(
                           plugin: this,
                           compilation: compilation,
                           operation: operation,
                           methodToCall: methodToCall,
                           clrMethodToCall: (MethodInfo)compilation.GetClrMethod(methodToCall),
                           evaluateAction: evaluateAction,
                           error: null));
            }

            // Remember the new compilation so we can exit early in subsequent calls
            return(FBuildResult.WithCompilation(compilation));
        }