public void CannotConnectScalarBufferElement_ToComponentNodeWithMatchingBuffer_ThroughWeakAPI()
        {
            Assert.Zero(NodeWithParametricPortType <SimpleBuffer> .IL2CPP_ClassInitializer);

            using (var f = new Fixture <UpdateSystem>())
            {
                var entity = f.EM.CreateEntity(typeof(SimpleBuffer));

                var entityNode = f.Set.CreateComponentNode(entity);
                var node       = f.Set.Create <NodeWithParametricPortType <SimpleBuffer> >();

                Assert.Throws <InvalidOperationException>(
                    () =>
                {
                    f.Set.Connect(
                        entityNode,
                        (OutputPortID)ComponentNode.Output <SimpleBuffer>(),
                        node,
                        (InputPortID)NodeWithParametricPortType <SimpleBuffer> .KernelPorts.Input
                        );
                }
                    );

                Assert.Throws <InvalidOperationException>(
                    () =>
                {
                    f.Set.Connect(
                        node,
                        (OutputPortID)NodeWithParametricPortType <SimpleBuffer> .KernelPorts.Output,
                        entityNode,
                        (InputPortID)ComponentNode.Input <SimpleBuffer>()
                        );
                }
                    );

                f.Set.Destroy(node, entityNode);
            }
        }
        public void CanConnectBuffer_OfBufferElement_ToComponentNode_WithMatchingBuffer_ThroughWeakAPI([Values(true, false)] bool forward)
        {
            using (var f = new Fixture <UpdateSystem>())
            {
                var entity = f.EM.CreateEntity(typeof(SimpleBuffer));

                var componentNode = f.Set.CreateComponentNode(entity);
                var node          = f.Set.Create <BufferNode>();

                Assert.DoesNotThrow(
                    () =>
                {
                    if (forward)
                    {
                        f.Set.Connect(
                            componentNode,
                            (OutputPortID)ComponentNode.Output <SimpleBuffer>(),
                            node,
                            (InputPortID)BufferNode.KernelPorts.Input
                            );
                    }
                    else
                    {
                        f.Set.Connect(
                            node,
                            (OutputPortID)BufferNode.KernelPorts.Output,
                            componentNode,
                            (InputPortID)ComponentNode.Input <SimpleBuffer>()
                            );
                    }
                }
                    );

                f.Set.Destroy(node, componentNode);
            }
        }
 public static void Connect <TType, TBuffer>(this NodeSet set, NodeHandle <TType> from, DataOutput <TType, Buffer <TBuffer> > port, NodeHandle <ComponentNode> to, NodeSet.ConnectionType type = NodeSet.ConnectionType.Normal)
     where TType : NodeDefinition
     where TBuffer : struct, IBufferElementData
 {
     set.Connect(from, port, to, ComponentNode.Input <TBuffer>(), type);
 }
        public void CanReadAndWrite_ToSameECSBuffer_FromInsideDFG(
            [Values] NodeSet.RenderExecutionModel model,
            [Values(1, 3, 13, 50)] int bufferSize,
            [Values] bool feedbackAfterProcessing)
        {
            const int k_Loops  = 10;
            var       k_Offset = new float3(1.0f, 1.5f, 2.0f);

            using (var f = new Fixture <UpdateSystem>())
            {
                f.Set.RendererModel = model;
                var entity = f.EM.CreateEntity(typeof(SimpleBuffer), typeof(SimpleData));

                var entityNode = f.Set.CreateComponentNode(entity);

                var dfgNode = f.Set.Create <BufferNode>();
                f.Set.SetData(dfgNode, BufferNode.KernelPorts.Offset, k_Offset);

                f.Set.Connect(
                    entityNode,
                    ComponentNode.Output <SimpleBuffer>(),
                    dfgNode,
                    BufferNode.KernelPorts.Input,
                    !feedbackAfterProcessing ? NodeSet.ConnectionType.Feedback : NodeSet.ConnectionType.Normal
                    );

                f.Set.Connect(
                    dfgNode,
                    BufferNode.KernelPorts.Output,
                    entityNode,
                    ComponentNode.Input <SimpleBuffer>(),
                    feedbackAfterProcessing ? NodeSet.ConnectionType.Feedback : NodeSet.ConnectionType.Normal
                    );

                var ecsBuffer = f.EM.GetBuffer <SimpleBuffer>(entity);

                // match all buffer sizes
                ecsBuffer.ResizeUninitialized(bufferSize);
                f.Set.SetBufferSize(dfgNode, BufferNode.KernelPorts.Output, Buffer <SimpleBuffer> .SizeRequest(bufferSize));

                var expected = new List <SimpleBuffer>();

                var rng = new Mathematics.Random(0x8f);
                for (int n = 0; n < bufferSize; ++n)
                {
                    ecsBuffer[n] = new SimpleBuffer {
                        Values = feedbackAfterProcessing ? -k_Offset : rng.NextFloat3()
                    };
                    expected.Add(ecsBuffer[n]);
                }

                for (int i = 0; i < k_Loops; ++i)
                {
                    f.System.Update();

                    // This should fence on all dependencies
                    ecsBuffer = f.EM.GetBuffer <SimpleBuffer>(entity);

                    for (int n = 0; n < bufferSize; ++n)
                    {
                        expected[n] = new SimpleBuffer {
                            Values = expected[n].Values + k_Offset
                        }
                    }
                    ;

                    for (int n = 0; n < bufferSize; ++n)
                    {
                        Assert.AreEqual(expected[n], ecsBuffer[n]);
                    }
                }

                f.Set.Destroy(entityNode, dfgNode);
            }
        }
    }
        public void CanConnect_ECSBuffer_ToECSBuffer_UsingOnlyComponentNodes_AndTransferData(
            [Values] NodeSet.RenderExecutionModel model,
            [Values(1, 3, 13, 50)] int bufferSize,
            [Values] ConnectionMode strongNess)
        {
            const int k_Loops = 10;

            using (var f = new Fixture <UpdateSystem>())
            {
                f.Set.RendererModel = model;
                var entitySource      = f.EM.CreateEntity(typeof(SimpleBuffer));
                var entityDestination = f.EM.CreateEntity(typeof(SimpleBuffer));

                var entityNodeSource = f.Set.CreateComponentNode(entitySource);
                var entityNodeDest   = f.Set.CreateComponentNode(entityDestination);

                if (strongNess == ConnectionMode.Strong)
                {
                    f.Set.Connect(
                        entityNodeSource,
                        ComponentNode.Output <SimpleBuffer>(),
                        entityNodeDest,
                        ComponentNode.Input <SimpleBuffer>()
                        );
                }
                else
                {
                    f.Set.Connect(
                        entityNodeSource,
                        (OutputPortID)ComponentNode.Output <SimpleBuffer>(),
                        entityNodeDest,
                        (InputPortID)ComponentNode.Input <SimpleBuffer>()
                        );
                }

                var rng = new Mathematics.Random(0x8f);

                var ecsSourceBuffer = f.EM.GetBuffer <SimpleBuffer>(entitySource);
                var ecsDestBuffer   = f.EM.GetBuffer <SimpleBuffer>(entityDestination);

                // match all buffer sizes
                ecsSourceBuffer.ResizeUninitialized(bufferSize);
                ecsDestBuffer.ResizeUninitialized(bufferSize);

                for (int i = 0; i < k_Loops; ++i)
                {
                    ecsSourceBuffer = f.EM.GetBuffer <SimpleBuffer>(entitySource);

                    for (int n = 0; n < bufferSize; ++n)
                    {
                        ecsSourceBuffer[n] = new SimpleBuffer {
                            Values = rng.NextFloat3()
                        };
                    }

                    f.System.Update();

                    // This should fence on all dependencies
                    ecsDestBuffer = f.EM.GetBuffer <SimpleBuffer>(entityDestination);
                    //f.Set.DataGraph.SyncAnyRendering();
                    // TODO: can compare alias here
                    for (int n = 0; n < bufferSize; ++n)
                    {
                        Assert.AreEqual(ecsSourceBuffer[n], ecsDestBuffer[n]);
                    }
                }

                f.Set.Destroy(entityNodeSource, entityNodeDest);
            }
        }
        public void CanWrite_ToECSBuffer_InsideFromDFG_FromOriginalECS_Source(
            [Values] NodeSet.RenderExecutionModel model,
            [Values(1, 3, 13, 50)] int bufferSize,
            [Values] ConnectionMode strongNess)
        {
            const int k_Loops = 10;

            using (var f = new Fixture <UpdateSystem>())
            {
                f.Set.RendererModel = model;
                var entitySource      = f.EM.CreateEntity(typeof(SimpleBuffer));
                var entityDestination = f.EM.CreateEntity(typeof(SimpleBuffer));

                var entityNodeSource = f.Set.CreateComponentNode(entitySource);
                var entityNodeDest   = f.Set.CreateComponentNode(entityDestination);

                var dfgNode = f.Set.Create <BufferNode>();
                var gv      = f.Set.CreateGraphValue(dfgNode, BufferNode.KernelPorts.Output);

                if (strongNess == ConnectionMode.Strong)
                {
                    f.Set.Connect(entityNodeSource, ComponentNode.Output <SimpleBuffer>(), dfgNode, BufferNode.KernelPorts.Input);
                    f.Set.Connect(dfgNode, BufferNode.KernelPorts.Output, entityNodeDest, ComponentNode.Input <SimpleBuffer>());
                }
                else
                {
                    f.Set.Connect(
                        entityNodeSource,
                        (OutputPortID)ComponentNode.Output <SimpleBuffer>(),
                        dfgNode,
                        (InputPortID)BufferNode.KernelPorts.Input
                        );

                    f.Set.Connect(
                        dfgNode,
                        (OutputPortID)BufferNode.KernelPorts.Output,
                        entityNodeDest,
                        (InputPortID)ComponentNode.Input <SimpleBuffer>()
                        );
                }

                var rng = new Mathematics.Random(0x8f);

                var ecsSourceBuffer = f.EM.GetBuffer <SimpleBuffer>(entitySource);
                var ecsDestBuffer   = f.EM.GetBuffer <SimpleBuffer>(entityDestination);

                // match all buffer sizes
                ecsSourceBuffer.ResizeUninitialized(bufferSize);
                ecsDestBuffer.ResizeUninitialized(bufferSize);
                f.Set.SetBufferSize(dfgNode, BufferNode.KernelPorts.Output, Buffer <SimpleBuffer> .SizeRequest(bufferSize));

                for (int i = 0; i < k_Loops; ++i)
                {
                    ecsSourceBuffer = f.EM.GetBuffer <SimpleBuffer>(entitySource);

                    for (int n = 0; n < bufferSize; ++n)
                    {
                        ecsSourceBuffer[n] = new SimpleBuffer {
                            Values = rng.NextFloat3()
                        };
                    }

                    f.System.Update();

                    // This should fence on all dependencies
                    ecsDestBuffer = f.EM.GetBuffer <SimpleBuffer>(entityDestination);

                    // TODO: can compare alias here
                    for (int n = 0; n < bufferSize; ++n)
                    {
                        Assert.AreEqual(ecsSourceBuffer[n], ecsDestBuffer[n]);
                    }
                }

                f.Set.ReleaseGraphValue(gv);
                f.Set.Destroy(entityNodeSource, entityNodeDest, dfgNode);
            }
        }
        public void DFGBuffer_ToECSBuffer_WithMismatchedSize_OnlyBlitsSharedPortion([Values(1, 3, 13, 50)] int bufferSize, [Values(true, false)] bool sourceIsBigger)
        {
            const int k_SizeDifference = 11;

            using (var f = new Fixture <UpdateSystem>())
            {
                var entitySource      = f.EM.CreateEntity(typeof(SimpleBuffer), typeof(SimpleData));
                var entityDestination = f.EM.CreateEntity(typeof(SimpleBuffer));

                var entityNodeSource = f.Set.CreateComponentNode(entitySource);
                var entityNodeDest   = f.Set.CreateComponentNode(entityDestination);

                var dfgNode = f.Set.Create <BufferNode>();
                var gv      = f.Set.CreateGraphValue(dfgNode, BufferNode.KernelPorts.Output);

                f.Set.Connect(entityNodeSource, ComponentNode.Output <SimpleBuffer>(), dfgNode, BufferNode.KernelPorts.Input);
                f.Set.Connect(dfgNode, BufferNode.KernelPorts.Output, entityNodeDest, ComponentNode.Input <SimpleBuffer>());

                var rng = new Mathematics.Random(0x8f);

                var ecsSourceBuffer = f.EM.GetBuffer <SimpleBuffer>(entitySource);
                var ecsDestBuffer   = f.EM.GetBuffer <SimpleBuffer>(entityDestination);

                var sourceSize = sourceIsBigger ? bufferSize * k_SizeDifference : bufferSize;
                var destSize   = sourceIsBigger ? bufferSize : bufferSize * k_SizeDifference;

                // Make sources much larger than destination
                ecsSourceBuffer.ResizeUninitialized(sourceSize);
                ecsDestBuffer.ResizeUninitialized(destSize);
                f.Set.SetBufferSize(dfgNode, BufferNode.KernelPorts.Output, Buffer <SimpleBuffer> .SizeRequest(sourceSize));

                ecsSourceBuffer = f.EM.GetBuffer <SimpleBuffer>(entitySource);
                for (int n = 0; n < sourceSize; ++n)
                {
                    ecsSourceBuffer[n] = new SimpleBuffer {
                        Values = rng.NextFloat3()
                    };
                }

                f.System.Update();
                ecsDestBuffer = f.EM.GetBuffer <SimpleBuffer>(entityDestination);

                // TODO: can compare alias here
                for (int n = 0; n < bufferSize; ++n)
                {
                    Assert.AreEqual(ecsSourceBuffer[n], ecsDestBuffer[n]);
                }

                f.Set.ReleaseGraphValue(gv);
                f.Set.Destroy(entityNodeSource, entityNodeDest, dfgNode);
            }
        }