コード例 #1
0
        /// <summary>
        ///     Selects a <see cref="DoubleArray"/> to another <see cref="DoubleArray"/>. The result is stored in a <see cref="Identity"/>.
        /// </summary>
        /// <param name="input">The indicator that sends data via <see cref="IUpdatable.Updated"/></param>
        /// <param name="selector">A selector to choose what <see cref="DoubleArray"/>.</param>
        /// <param name="waitForFirstToReady">Input must be ready in order to push the updates forward.</param>
        /// <param name="name">Name of the new returned <see cref="Identity"/>.</param>
        public static Identity Select(this IUpdatable input, ArraySelectorFunctionHandler selector, int outputCount = 1, int properties = 1, bool waitForFirstToReady = true, string name = null)
        {
            if (selector == null)
            {
                throw new ArgumentNullException(nameof(selector));
            }
            outputCount = outputCount > 0 ? outputCount : input.OutputCount;
            var idn = new Identity(ResolveName(input, name), outputCount, properties);

            if (outputCount > 1)
            {
                unsafe {
                    if (waitForFirstToReady)
                    {
                        input.Updated += (time, updated) => {
                            if (input.IsReady)
                            {
                                var ret = new DoubleArray2DManaged(outputCount, properties);
                                fixed(double *dst = ret, selectSrc = updated)
                                for (int i = 0; i < updated.Count; i++)
                                {
                                    var result = selector(selectSrc[i * updated.Properties]);

                                    Guard.AssertTrue(result.Count == outputCount, "Passed outputCount must be matching to the updated array.");
                                    Guard.AssertTrue(properties == result.Properties, "Properties must match the properties argument passed.");

                                    fixed(double *src = result)
                                    Unsafe.CopyBlock(dst + i, src, (uint)(result.LinearLength * sizeof(double)));
                                }

                                idn.Update(time, ret);
                            }
                        };
                    }
                    else
                    {
                        input.Updated += (time, updated) => {
                            var ret = new DoubleArray2DManaged(updated.Count, properties);
                            fixed(double *dst = ret, selectSrc = updated)
                            for (int i = 0; i < outputCount; i++)
                            {
                                var result = selector(selectSrc[i * updated.Properties]);

                                Guard.AssertTrue(result.Count == outputCount, "Passed outputCount must be matching to the updated array.");
                                Guard.AssertTrue(properties == result.Properties, "Properties must match the properties argument passed.");

                                fixed(double *src = result)
                                Unsafe.CopyBlock(dst, src, (uint)(result.LinearLength * sizeof(double)));
                            }

                            idn.Update(time, ret);
                        };
                    }

                    input.Resetted += sender => idn.Reset();
                }
            }

            if (waitForFirstToReady)
            {
                input.Updated += (time, updated) => {
                    if (input.IsReady)
                    {
                        idn.Update(time, selector(updated));
                    }
                };
            }
            else
            {
                input.Updated += (time, updated) => idn.Update(time, selector(updated));
            }

            input.Resetted += sender => idn.Reset();

            return(idn);
        }
コード例 #2
0
        /// <summary>
        ///     Performs a math <paramref name="op"/> over <see cref="DoubleArray"/> or the value from <paramref name="selector"/>. The result is stored in a <see cref="Identity"/>.
        /// </summary>
        /// <param name="first">The indicator that sends data via <see cref="IUpdatable.Updated"/> even to the math <paramref name="op"/></param>
        /// <param name="op">The operation to perform on the <see cref="DoubleArray"/> passed from <paramref name="first"/>.</param>
        /// <param name="selector">A selector to choose what <see cref="DoubleArray"/> to pass to math <paramref name="op"/>. By default, the unchanged <see cref="DoubleArray"/> is used.</param>
        /// <param name="waitForFirstToReady">First must be ready in order to push the updates forward.</param>
        /// <param name="name">Name of the new returned <see cref="Identity"/> representing the <paramref name="op"/>.</param>
        public static Identity Function(this IUpdatable first, UnaryArrayFunctionHandler op, ArraySelectorFunctionHandler selector = null, bool waitForFirstToReady = true, string name = null)
        {
            if (op == null)
            {
                throw new ArgumentNullException(nameof(op));
            }

            var idn = new Identity(ResolveName(first, name));

            if (selector == null)
            {
                if (waitForFirstToReady)
                {
                    first.Updated += (time, updated) => {
                        if (first.IsReady)
                        {
                            idn.Update(time, op(updated));
                        }
                    };
                }
                else
                {
                    first.Updated += (time, updated) => idn.Update(time, op(updated));
                }
            }
            else
            {
                if (waitForFirstToReady)
                {
                    first.Updated += (time, updated) => {
                        if (first.IsReady)
                        {
                            idn.Update(time, op(selector(updated)));
                        }
                    };
                }
                else
                {
                    first.Updated += (time, updated) => idn.Update(time, op(selector(updated)));
                }
            }

            first.Resetted += sender => idn.Reset();

            return(idn);
        }