public void CanRead_ECSBuffer_InsideFromDFG(
            [Values] NodeSet.RenderExecutionModel model,
            [Values(1, 3, 13, 50)] int bufferSize)
        {
            const int k_Loops = 10;

            using (var f = new Fixture <UpdateSystem>())
            {
                f.Set.RendererModel = model;
                var entity     = f.EM.CreateEntity(typeof(SimpleBuffer));
                var entityNode = f.Set.CreateComponentNode(entity);
                var dfgNode    = f.Set.Create <BufferNode>();
                var gv         = f.Set.CreateGraphValue(dfgNode, BufferNode.KernelPorts.Output);

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

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

                f.Set.SetBufferSize(dfgNode, BufferNode.KernelPorts.Output, Buffer <SimpleBuffer> .SizeRequest(bufferSize));

                for (int i = 0; i < k_Loops; ++i)
                {
                    var ecsBuffer = f.EM.GetBuffer <SimpleBuffer>(entity);
                    ecsBuffer.ResizeUninitialized(bufferSize);

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

                    f.System.Update();

                    var resolver = f.Set.GetGraphValueResolver(out var dependency);
                    dependency.Complete();

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

                    var dfgBuffer = resolver.Resolve(gv);

                    Assert.AreEqual(ecsBuffer.Length, dfgBuffer.Length);

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

                f.Set.ReleaseGraphValue(gv);
                f.Set.Destroy(entityNode, 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);
            }
        }
        public void OneTimeSetup()
        {
            var skeletonNodes = new[]
            {
                new SkeletonNode {
                    ParentIndex = -1, Id = string.Empty, AxisIndex = -1
                },
                new SkeletonNode {
                    ParentIndex = 0, Id = "Child1", AxisIndex = -1
                },
                new SkeletonNode {
                    ParentIndex = 0, Id = "Child2", AxisIndex = -1
                }
            };

            RigDefinition = RigBuilder.CreateRigDefinition(skeletonNodes);

            var r        = new Mathematics.Random(0x12345678);
            var range    = new float3(100);
            var fullClip = new UnityEngine.AnimationClip();

            // add some error into the clip, so it is not perfectly frame aligned
            float clipDuration = clipFrames / fullClip.frameRate + 0.123f / fullClip.frameRate;


            CreateLinearTranslate(fullClip, string.Empty, float3.zero, new float3(0, 1, 0), clipDuration);
            CreateLinearTranslate(fullClip, "Child1", r.NextFloat3(-range, range), r.NextFloat3(-range, range), clipDuration);
            CreateLinearTranslate(fullClip, "Child2", r.NextFloat3(-range, range), r.NextFloat3(-range, range), clipDuration);
            CreateRotation(fullClip, string.Empty, quaternion.identity, r.NextQuaternionRotation(), clipDuration);
            CreateRotation(fullClip, "Child1", r.NextQuaternionRotation(), r.NextQuaternionRotation(), clipDuration);
            CreateRotation(fullClip, "Child2", r.NextQuaternionRotation(), r.NextQuaternionRotation(), clipDuration);
            CreateScale(fullClip, string.Empty, new float3(1), new float3(1), clipDuration);
            CreateScale(fullClip, "Child1", new float3(1), new float3(2), clipDuration);
            CreateScale(fullClip, "Child2", new float3(2), new float3(3), clipDuration);
            FullAnimationClip = ClipBuilder.AnimationClipToDenseClip(fullClip);

            var partialClip = new UnityEngine.AnimationClip();

            CreateLinearTranslate(partialClip, "Child1", r.NextFloat3(-range, range), r.NextFloat3(-range, range), clipDuration);
            CreateRotation(partialClip, string.Empty, quaternion.identity, r.NextQuaternionRotation(), clipDuration);
            CreateRotation(partialClip, "Child2", quaternion.identity, r.NextQuaternionRotation(), clipDuration);
            CreateScale(partialClip, string.Empty, float3.zero, new float3(1), clipDuration);
            PartialAnimationClip = ClipBuilder.AnimationClipToDenseClip(partialClip);

            var alignedClip = new UnityEngine.AnimationClip();

            CreateLinearTranslate(alignedClip, string.Empty, float3.zero, new float3(0, 1, 0), 1.0f);
            CreateLinearTranslate(alignedClip, "Child1", r.NextFloat3(-range, range), r.NextFloat3(-range, range), 1.0f);
            CreateLinearTranslate(alignedClip, "Child2", r.NextFloat3(-range, range), r.NextFloat3(-range, range), 1.0f);
            CreateRotation(alignedClip, string.Empty, quaternion.identity, r.NextQuaternionRotation(), 1.0f);
            AlignedClip = ClipBuilder.AnimationClipToDenseClip(alignedClip);
        }
        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);
            }
        }