diff --git a/.clinerules/AGENTS.md b/.clinerules/AGENTS.md index c28ed67f..a9b707e9 100644 --- a/.clinerules/AGENTS.md +++ b/.clinerules/AGENTS.md @@ -81,6 +81,7 @@ Directory: `lib/[category]/[name]/` (e.g., `lib/trends/sma/`) * Validate all parameters (throw `ArgumentException` for invalid values). * Initialize `Name` property (e.g., `$"Sma({period})"`); * Support chaining: `public [Name](ITValuePublisher source, ...)` +* **Event Subscription:** Subscribe to events directly (`source.Pub += ...`) when the source is passed as a non-nullable parameter. Do not use defensive null checks (`if (_source != null)`). ### The `Update` Method Contract diff --git a/lib/core/simd/SimdExtensions.cs b/lib/core/simd/SimdExtensions.cs index 4cf22bff..9804128a 100644 --- a/lib/core/simd/SimdExtensions.cs +++ b/lib/core/simd/SimdExtensions.cs @@ -551,7 +551,7 @@ public static class SimdExtensions vSum3 = Avx512F.Add(vSum3, vSum4); vSum = Avx512F.Add(vSum, vSum3); - Vector256 v256 = Avx512F.Add(vSum.GetLower(), vSum.GetUpper()); + Vector256 v256 = Avx.Add(vSum.GetLower(), vSum.GetUpper()); Vector128 lower = v256.GetLower(); Vector128 upper = v256.GetUpper(); Vector128 combined = Sse2.Add(lower, upper); diff --git a/lib/trends/bessel/Bessel.cs b/lib/trends/bessel/Bessel.cs index 16bf6109..cae93835 100644 --- a/lib/trends/bessel/Bessel.cs +++ b/lib/trends/bessel/Bessel.cs @@ -69,7 +69,7 @@ public sealed class Bessel : AbstractBase, IDisposable { _publisher = source; _handler = item => Update(item); - _publisher.Pub += _handler; + source.Pub += _handler; } /// @@ -85,7 +85,7 @@ public sealed class Bessel : AbstractBase, IDisposable _publisher = source; _handler = item => Update(item); - _publisher.Pub += _handler; + source.Pub += _handler; } public override bool IsHot => _state.IsHot; diff --git a/lib/trends/blma/Blma.Tests.cs b/lib/trends/blma/Blma.Tests.cs index ea3c7bf1..bec22be4 100644 --- a/lib/trends/blma/Blma.Tests.cs +++ b/lib/trends/blma/Blma.Tests.cs @@ -25,8 +25,7 @@ public class BlmaTests [Fact] public void Constructor_ValidatesSource() { - Assert.Throws(() => new Blma(null!, 10)); - Assert.Throws(() => new Blma(new object(), 10)); + Assert.Throws(() => new Blma(null!, 10)); } [Fact] diff --git a/lib/trends/blma/Blma.cs b/lib/trends/blma/Blma.cs index 5be5d827..db9db564 100644 --- a/lib/trends/blma/Blma.cs +++ b/lib/trends/blma/Blma.cs @@ -33,19 +33,10 @@ public sealed class Blma : AbstractBase, IDisposable _weightSum = CalculateWeights(period, _weights); } - public Blma(object source, int period) : this(period) + public Blma(ITValuePublisher source, int period) : this(period) { - ArgumentNullException.ThrowIfNull(source); - - if (source is ITValuePublisher pub) - { - _publisher = pub; - _publisher.Pub += Handle; - } - else - { - throw new ArgumentException("Source must implement ITValuePublisher", nameof(source)); - } + _publisher = source; + source.Pub += Handle; } public void Dispose() diff --git a/lib/trends/dema/Dema.cs b/lib/trends/dema/Dema.cs index b18fa5dd..02bab1bc 100644 --- a/lib/trends/dema/Dema.cs +++ b/lib/trends/dema/Dema.cs @@ -58,7 +58,7 @@ public sealed class Dema : AbstractBase, IDisposable { _publisher = source; _listener = (item) => Update(item); - _publisher.Pub += _listener; + source.Pub += _listener; } public Dema(double alpha) diff --git a/lib/trends/pwma/Pwma.Tests.cs b/lib/trends/pwma/Pwma.Tests.cs index 4c4e4396..cdab964d 100644 --- a/lib/trends/pwma/Pwma.Tests.cs +++ b/lib/trends/pwma/Pwma.Tests.cs @@ -8,7 +8,7 @@ public class PwmaTests { Assert.Throws(() => new Pwma(0)); Assert.Throws(() => new Pwma(-1)); - Assert.Throws(() => new Pwma(null!, 10)); + Assert.Throws(() => new Pwma(null!, 10)); var pwma = new Pwma(10); Assert.NotNull(pwma); diff --git a/lib/trends/pwma/Pwma.cs b/lib/trends/pwma/Pwma.cs index 61e83be6..a510f10d 100644 --- a/lib/trends/pwma/Pwma.cs +++ b/lib/trends/pwma/Pwma.cs @@ -56,7 +56,6 @@ public sealed class Pwma : AbstractBase public Pwma(ITValuePublisher source, int period) : this(period) { - if (source == null) throw new ArgumentNullException(nameof(source)); source.Pub += (item) => Update(item); } diff --git a/lib/trends/t3/T3.cs b/lib/trends/t3/T3.cs index 0cc96db8..bdd9c254 100644 --- a/lib/trends/t3/T3.cs +++ b/lib/trends/t3/T3.cs @@ -81,7 +81,7 @@ public sealed class T3 : AbstractBase, IDisposable { _publisher = source; _handler = (item) => Update(item); - _publisher.Pub += _handler; + source.Pub += _handler; } /// diff --git a/lib/trends/trima/Trima.cs b/lib/trends/trima/Trima.cs index 0327f6bc..fb9a60f4 100644 --- a/lib/trends/trima/Trima.cs +++ b/lib/trends/trima/Trima.cs @@ -52,7 +52,7 @@ public sealed class Trima : AbstractBase, IDisposable public Trima(ITValuePublisher source, int period) : this(period) { _publisher = source; - _publisher.Pub += _updateHandler; + source.Pub += _updateHandler; } public void Dispose() diff --git a/lib/trends/vidya/Vidya.cs b/lib/trends/vidya/Vidya.cs index 62fc477e..417985f7 100644 --- a/lib/trends/vidya/Vidya.cs +++ b/lib/trends/vidya/Vidya.cs @@ -60,7 +60,7 @@ public sealed class Vidya : AbstractBase, IDisposable { _source = source; _pubHandler = (item) => Update(item); - _source.Pub += _pubHandler; + source.Pub += _pubHandler; } public void Dispose() diff --git a/lib/trends/wma/Wma.cs b/lib/trends/wma/Wma.cs index 6214b541..f5ab692d 100644 --- a/lib/trends/wma/Wma.cs +++ b/lib/trends/wma/Wma.cs @@ -69,7 +69,7 @@ public sealed class Wma : AbstractBase, IDisposable { _source = source; _handler = (item) => Update(item); - _source.Pub += _handler; + source.Pub += _handler; } public void Dispose()