From 5d505d9c7dbbe365f373b60a095f162ab86a4d27 Mon Sep 17 00:00:00 2001 From: Marcus Tomlinson Date: Fri, 11 Aug 2023 17:52:47 +0100 Subject: [PATCH 01/17] Test std::any performance --- include/dspatch/SignalBus.h | 30 +++++++++++++++--------------- src/internal/CircuitThread.cpp | 1 - subprojects/fast_any | 2 +- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/include/dspatch/SignalBus.h b/include/dspatch/SignalBus.h index dfd08629..cb86d7c4 100644 --- a/include/dspatch/SignalBus.h +++ b/include/dspatch/SignalBus.h @@ -30,7 +30,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include +#include #include @@ -57,7 +57,7 @@ class DLLEXPORT SignalBus final inline void SetSignalCount( int signalCount ); inline int GetSignalCount() const; - inline fast_any::fast_any* GetSignal( int signalIndex ); + inline std::any* GetSignal( int signalIndex ); inline bool HasValue( int signalIndex ) const; @@ -70,15 +70,15 @@ class DLLEXPORT SignalBus final template inline void MoveValue( int signalIndex, ValueType&& newValue ); - inline void SetSignal( int toSignalIndex, const fast_any::fast_any& fromSignal ); - inline void MoveSignal( int toSignalIndex, fast_any::fast_any& fromSignal ); + inline void SetSignal( int toSignalIndex, const std::any& fromSignal ); + inline void MoveSignal( int toSignalIndex, std::any& fromSignal ); inline void ClearAllValues(); - inline fast_any::fast_any_type GetType( int signalIndex ) const; + inline const std::type_info& GetType( int signalIndex ) const; private: - std::vector _signals; + std::vector _signals; }; inline SignalBus::SignalBus() = default; @@ -99,7 +99,7 @@ inline int SignalBus::GetSignalCount() const return (int)_signals.size(); } -inline fast_any::fast_any* SignalBus::GetSignal( int signalIndex ) +inline std::any* SignalBus::GetSignal( int signalIndex ) { if ( (size_t)signalIndex < _signals.size() ) { @@ -128,7 +128,7 @@ inline ValueType* SignalBus::GetValue( int signalIndex ) const { if ( (size_t)signalIndex < _signals.size() ) { - return _signals[signalIndex].as(); + return const_cast( &std::any_cast( _signals[signalIndex] ) ); } else { @@ -141,7 +141,7 @@ inline void SignalBus::SetValue( int signalIndex, const ValueType& newValue ) { if ( (size_t)signalIndex < _signals.size() ) { - _signals[signalIndex].emplace( newValue ); + _signals[signalIndex].emplace( newValue ); } } @@ -150,19 +150,19 @@ inline void SignalBus::MoveValue( int signalIndex, ValueType&& newValue ) { if ( (size_t)signalIndex < _signals.size() ) { - _signals[signalIndex].emplace( std::move( newValue ) ); + _signals[signalIndex].emplace( std::move( newValue ) ); } } -inline void SignalBus::SetSignal( int toSignalIndex, const fast_any::fast_any& fromSignal ) +inline void SignalBus::SetSignal( int toSignalIndex, const std::any& fromSignal ) { if ( (size_t)toSignalIndex < _signals.size() ) { - _signals[toSignalIndex].emplace( fromSignal ); + _signals[toSignalIndex] = fromSignal; } } -inline void SignalBus::MoveSignal( int toSignalIndex, fast_any::fast_any& fromSignal ) +inline void SignalBus::MoveSignal( int toSignalIndex, std::any& fromSignal ) { if ( (size_t)toSignalIndex < _signals.size() ) { @@ -178,7 +178,7 @@ inline void SignalBus::ClearAllValues() } } -inline fast_any::fast_any_type SignalBus::GetType( int signalIndex ) const +inline const std::type_info& SignalBus::GetType( int signalIndex ) const { if ( (size_t)signalIndex < _signals.size() ) { @@ -186,7 +186,7 @@ inline fast_any::fast_any_type SignalBus::GetType( int signalIndex ) const } else { - return fast_any::type_id; + return typeid( void ); } } diff --git a/src/internal/CircuitThread.cpp b/src/internal/CircuitThread.cpp index 93291549..c1f4d475 100644 --- a/src/internal/CircuitThread.cpp +++ b/src/internal/CircuitThread.cpp @@ -117,7 +117,6 @@ void CircuitThread::SyncAndResume( DSPatch::Component::TickMode mode ) std::unique_lock lock( _resumeMutex ); - // cppcheck-suppress knownConditionTrueFalse if ( !_gotSync ) // if haven't already got sync { _syncCondt.wait( lock ); // wait for sync diff --git a/subprojects/fast_any b/subprojects/fast_any index 5fa78cb4..33bad8b0 160000 --- a/subprojects/fast_any +++ b/subprojects/fast_any @@ -1 +1 @@ -Subproject commit 5fa78cb43d2a66338f543bc806ed450242da96d9 +Subproject commit 33bad8b01e19e410452a8b9b16a054c1d0af0165 From 7dfde3d2d46d525e3b3232c46a65d28d8f87de51 Mon Sep 17 00:00:00 2001 From: Marcus Tomlinson Date: Fri, 11 Aug 2023 21:35:33 +0100 Subject: [PATCH 02/17] Update fast_any --- include/dspatch/SignalBus.h | 10 +++++----- subprojects/fast_any | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/dspatch/SignalBus.h b/include/dspatch/SignalBus.h index dfd08629..8150a023 100644 --- a/include/dspatch/SignalBus.h +++ b/include/dspatch/SignalBus.h @@ -75,7 +75,7 @@ class DLLEXPORT SignalBus final inline void ClearAllValues(); - inline fast_any::fast_any_type GetType( int signalIndex ) const; + inline const fast_any::type_info& GetType( int signalIndex ) const; private: std::vector _signals; @@ -141,7 +141,7 @@ inline void SignalBus::SetValue( int signalIndex, const ValueType& newValue ) { if ( (size_t)signalIndex < _signals.size() ) { - _signals[signalIndex].emplace( newValue ); + _signals[signalIndex].emplace( newValue ); } } @@ -150,7 +150,7 @@ inline void SignalBus::MoveValue( int signalIndex, ValueType&& newValue ) { if ( (size_t)signalIndex < _signals.size() ) { - _signals[signalIndex].emplace( std::move( newValue ) ); + _signals[signalIndex].emplace( std::move( newValue ) ); } } @@ -158,7 +158,7 @@ inline void SignalBus::SetSignal( int toSignalIndex, const fast_any::fast_any& f { if ( (size_t)toSignalIndex < _signals.size() ) { - _signals[toSignalIndex].emplace( fromSignal ); + _signals[toSignalIndex] = fromSignal; } } @@ -178,7 +178,7 @@ inline void SignalBus::ClearAllValues() } } -inline fast_any::fast_any_type SignalBus::GetType( int signalIndex ) const +inline const fast_any::type_info& SignalBus::GetType( int signalIndex ) const { if ( (size_t)signalIndex < _signals.size() ) { diff --git a/subprojects/fast_any b/subprojects/fast_any index 5fa78cb4..22616a26 160000 --- a/subprojects/fast_any +++ b/subprojects/fast_any @@ -1 +1 @@ -Subproject commit 5fa78cb43d2a66338f543bc806ed450242da96d9 +Subproject commit 22616a26a132ffd48de8437d27fb8cbd6cf7a670 From 7f32447506f97c88c5ac78eed9461a0f2d9b4ab3 Mon Sep 17 00:00:00 2001 From: Marcus Tomlinson Date: Fri, 11 Aug 2023 21:39:35 +0100 Subject: [PATCH 03/17] Update fast_any --- include/dspatch/SignalBus.h | 24 ++++++++++++------------ subprojects/fast_any | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/dspatch/SignalBus.h b/include/dspatch/SignalBus.h index dfd08629..6da5d97e 100644 --- a/include/dspatch/SignalBus.h +++ b/include/dspatch/SignalBus.h @@ -57,7 +57,7 @@ class DLLEXPORT SignalBus final inline void SetSignalCount( int signalCount ); inline int GetSignalCount() const; - inline fast_any::fast_any* GetSignal( int signalIndex ); + inline fast_any::any* GetSignal( int signalIndex ); inline bool HasValue( int signalIndex ) const; @@ -70,15 +70,15 @@ class DLLEXPORT SignalBus final template inline void MoveValue( int signalIndex, ValueType&& newValue ); - inline void SetSignal( int toSignalIndex, const fast_any::fast_any& fromSignal ); - inline void MoveSignal( int toSignalIndex, fast_any::fast_any& fromSignal ); + inline void SetSignal( int toSignalIndex, const fast_any::any& fromSignal ); + inline void MoveSignal( int toSignalIndex, fast_any::any& fromSignal ); inline void ClearAllValues(); - inline fast_any::fast_any_type GetType( int signalIndex ) const; + inline const fast_any::type_info& GetType( int signalIndex ) const; private: - std::vector _signals; + std::vector _signals; }; inline SignalBus::SignalBus() = default; @@ -99,7 +99,7 @@ inline int SignalBus::GetSignalCount() const return (int)_signals.size(); } -inline fast_any::fast_any* SignalBus::GetSignal( int signalIndex ) +inline fast_any::any* SignalBus::GetSignal( int signalIndex ) { if ( (size_t)signalIndex < _signals.size() ) { @@ -141,7 +141,7 @@ inline void SignalBus::SetValue( int signalIndex, const ValueType& newValue ) { if ( (size_t)signalIndex < _signals.size() ) { - _signals[signalIndex].emplace( newValue ); + _signals[signalIndex].emplace( newValue ); } } @@ -150,19 +150,19 @@ inline void SignalBus::MoveValue( int signalIndex, ValueType&& newValue ) { if ( (size_t)signalIndex < _signals.size() ) { - _signals[signalIndex].emplace( std::move( newValue ) ); + _signals[signalIndex].emplace( std::move( newValue ) ); } } -inline void SignalBus::SetSignal( int toSignalIndex, const fast_any::fast_any& fromSignal ) +inline void SignalBus::SetSignal( int toSignalIndex, const fast_any::any& fromSignal ) { if ( (size_t)toSignalIndex < _signals.size() ) { - _signals[toSignalIndex].emplace( fromSignal ); + _signals[toSignalIndex] = fromSignal; } } -inline void SignalBus::MoveSignal( int toSignalIndex, fast_any::fast_any& fromSignal ) +inline void SignalBus::MoveSignal( int toSignalIndex, fast_any::any& fromSignal ) { if ( (size_t)toSignalIndex < _signals.size() ) { @@ -178,7 +178,7 @@ inline void SignalBus::ClearAllValues() } } -inline fast_any::fast_any_type SignalBus::GetType( int signalIndex ) const +inline const fast_any::type_info& SignalBus::GetType( int signalIndex ) const { if ( (size_t)signalIndex < _signals.size() ) { diff --git a/subprojects/fast_any b/subprojects/fast_any index 5fa78cb4..f9abdd09 160000 --- a/subprojects/fast_any +++ b/subprojects/fast_any @@ -1 +1 @@ -Subproject commit 5fa78cb43d2a66338f543bc806ed450242da96d9 +Subproject commit f9abdd09a6c3c60f2670b5e39a365b4111880f20 From b71ddb621d4b9b10df859b5656239aa18d31c7cb Mon Sep 17 00:00:00 2001 From: Marcus Tomlinson Date: Fri, 11 Aug 2023 21:43:29 +0100 Subject: [PATCH 04/17] Update fast_any --- include/dspatch/SignalBus.h | 26 +++++++++++++------------- subprojects/fast_any | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/dspatch/SignalBus.h b/include/dspatch/SignalBus.h index dfd08629..0a35962f 100644 --- a/include/dspatch/SignalBus.h +++ b/include/dspatch/SignalBus.h @@ -30,7 +30,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include +#include #include @@ -57,7 +57,7 @@ class DLLEXPORT SignalBus final inline void SetSignalCount( int signalCount ); inline int GetSignalCount() const; - inline fast_any::fast_any* GetSignal( int signalIndex ); + inline fast_any::any* GetSignal( int signalIndex ); inline bool HasValue( int signalIndex ) const; @@ -70,15 +70,15 @@ class DLLEXPORT SignalBus final template inline void MoveValue( int signalIndex, ValueType&& newValue ); - inline void SetSignal( int toSignalIndex, const fast_any::fast_any& fromSignal ); - inline void MoveSignal( int toSignalIndex, fast_any::fast_any& fromSignal ); + inline void SetSignal( int toSignalIndex, const fast_any::any& fromSignal ); + inline void MoveSignal( int toSignalIndex, fast_any::any& fromSignal ); inline void ClearAllValues(); - inline fast_any::fast_any_type GetType( int signalIndex ) const; + inline const fast_any::type_info& GetType( int signalIndex ) const; private: - std::vector _signals; + std::vector _signals; }; inline SignalBus::SignalBus() = default; @@ -99,7 +99,7 @@ inline int SignalBus::GetSignalCount() const return (int)_signals.size(); } -inline fast_any::fast_any* SignalBus::GetSignal( int signalIndex ) +inline fast_any::any* SignalBus::GetSignal( int signalIndex ) { if ( (size_t)signalIndex < _signals.size() ) { @@ -141,7 +141,7 @@ inline void SignalBus::SetValue( int signalIndex, const ValueType& newValue ) { if ( (size_t)signalIndex < _signals.size() ) { - _signals[signalIndex].emplace( newValue ); + _signals[signalIndex].emplace( newValue ); } } @@ -150,19 +150,19 @@ inline void SignalBus::MoveValue( int signalIndex, ValueType&& newValue ) { if ( (size_t)signalIndex < _signals.size() ) { - _signals[signalIndex].emplace( std::move( newValue ) ); + _signals[signalIndex].emplace( std::move( newValue ) ); } } -inline void SignalBus::SetSignal( int toSignalIndex, const fast_any::fast_any& fromSignal ) +inline void SignalBus::SetSignal( int toSignalIndex, const fast_any::any& fromSignal ) { if ( (size_t)toSignalIndex < _signals.size() ) { - _signals[toSignalIndex].emplace( fromSignal ); + _signals[toSignalIndex] = fromSignal; } } -inline void SignalBus::MoveSignal( int toSignalIndex, fast_any::fast_any& fromSignal ) +inline void SignalBus::MoveSignal( int toSignalIndex, fast_any::any& fromSignal ) { if ( (size_t)toSignalIndex < _signals.size() ) { @@ -178,7 +178,7 @@ inline void SignalBus::ClearAllValues() } } -inline fast_any::fast_any_type SignalBus::GetType( int signalIndex ) const +inline const fast_any::type_info& SignalBus::GetType( int signalIndex ) const { if ( (size_t)signalIndex < _signals.size() ) { diff --git a/subprojects/fast_any b/subprojects/fast_any index 5fa78cb4..fa38c0f2 160000 --- a/subprojects/fast_any +++ b/subprojects/fast_any @@ -1 +1 @@ -Subproject commit 5fa78cb43d2a66338f543bc806ed450242da96d9 +Subproject commit fa38c0f29386be61739f83f3fe6e222b22b016c0 From 54ac24fdbdeb871943df313aacd424ad02fcd8d0 Mon Sep 17 00:00:00 2001 From: Marcus Tomlinson Date: Fri, 11 Aug 2023 22:03:08 +0100 Subject: [PATCH 05/17] Update fast_any --- include/dspatch/SignalBus.h | 26 +++++++++++++------------- subprojects/fast_any | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/dspatch/SignalBus.h b/include/dspatch/SignalBus.h index dfd08629..51860965 100644 --- a/include/dspatch/SignalBus.h +++ b/include/dspatch/SignalBus.h @@ -30,7 +30,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include +#include #include @@ -57,7 +57,7 @@ class DLLEXPORT SignalBus final inline void SetSignalCount( int signalCount ); inline int GetSignalCount() const; - inline fast_any::fast_any* GetSignal( int signalIndex ); + inline fast_any::any* GetSignal( int signalIndex ); inline bool HasValue( int signalIndex ) const; @@ -70,15 +70,15 @@ class DLLEXPORT SignalBus final template inline void MoveValue( int signalIndex, ValueType&& newValue ); - inline void SetSignal( int toSignalIndex, const fast_any::fast_any& fromSignal ); - inline void MoveSignal( int toSignalIndex, fast_any::fast_any& fromSignal ); + inline void SetSignal( int toSignalIndex, const fast_any::any& fromSignal ); + inline void MoveSignal( int toSignalIndex, fast_any::any& fromSignal ); inline void ClearAllValues(); - inline fast_any::fast_any_type GetType( int signalIndex ) const; + inline const fast_any::type_info& GetType( int signalIndex ) const; private: - std::vector _signals; + std::vector _signals; }; inline SignalBus::SignalBus() = default; @@ -99,7 +99,7 @@ inline int SignalBus::GetSignalCount() const return (int)_signals.size(); } -inline fast_any::fast_any* SignalBus::GetSignal( int signalIndex ) +inline fast_any::any* SignalBus::GetSignal( int signalIndex ) { if ( (size_t)signalIndex < _signals.size() ) { @@ -141,7 +141,7 @@ inline void SignalBus::SetValue( int signalIndex, const ValueType& newValue ) { if ( (size_t)signalIndex < _signals.size() ) { - _signals[signalIndex].emplace( newValue ); + _signals[signalIndex].emplace( newValue ); } } @@ -150,19 +150,19 @@ inline void SignalBus::MoveValue( int signalIndex, ValueType&& newValue ) { if ( (size_t)signalIndex < _signals.size() ) { - _signals[signalIndex].emplace( std::move( newValue ) ); + _signals[signalIndex].emplace( std::move( newValue ) ); } } -inline void SignalBus::SetSignal( int toSignalIndex, const fast_any::fast_any& fromSignal ) +inline void SignalBus::SetSignal( int toSignalIndex, const fast_any::any& fromSignal ) { if ( (size_t)toSignalIndex < _signals.size() ) { - _signals[toSignalIndex].emplace( fromSignal ); + _signals[toSignalIndex] = fromSignal; } } -inline void SignalBus::MoveSignal( int toSignalIndex, fast_any::fast_any& fromSignal ) +inline void SignalBus::MoveSignal( int toSignalIndex, fast_any::any& fromSignal ) { if ( (size_t)toSignalIndex < _signals.size() ) { @@ -178,7 +178,7 @@ inline void SignalBus::ClearAllValues() } } -inline fast_any::fast_any_type SignalBus::GetType( int signalIndex ) const +inline const fast_any::type_info& SignalBus::GetType( int signalIndex ) const { if ( (size_t)signalIndex < _signals.size() ) { diff --git a/subprojects/fast_any b/subprojects/fast_any index 5fa78cb4..25c7951c 160000 --- a/subprojects/fast_any +++ b/subprojects/fast_any @@ -1 +1 @@ -Subproject commit 5fa78cb43d2a66338f543bc806ed450242da96d9 +Subproject commit 25c7951c6f296cc111a203771c59e6fd73d80e2f From 852ef0613115d6aac68704d3cc604df73e449c8a Mon Sep 17 00:00:00 2001 From: Marcus Tomlinson Date: Fri, 11 Aug 2023 22:26:02 +0100 Subject: [PATCH 06/17] Fix crash in tests --- include/dspatch/SignalBus.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/dspatch/SignalBus.h b/include/dspatch/SignalBus.h index cb86d7c4..c7753c95 100644 --- a/include/dspatch/SignalBus.h +++ b/include/dspatch/SignalBus.h @@ -128,7 +128,14 @@ inline ValueType* SignalBus::GetValue( int signalIndex ) const { if ( (size_t)signalIndex < _signals.size() ) { - return const_cast( &std::any_cast( _signals[signalIndex] ) ); + try + { + return const_cast( &std::any_cast( _signals[signalIndex] ) ); + } + catch ( const std::exception& ) + { + return nullptr; + } } else { From f8b82983a21f06633483b3492e3799a1fb205f31 Mon Sep 17 00:00:00 2001 From: Marcus Tomlinson Date: Sat, 12 Aug 2023 15:17:27 +0100 Subject: [PATCH 07/17] Clean up SignalBus docs --- include/dspatch/SignalBus.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/include/dspatch/SignalBus.h b/include/dspatch/SignalBus.h index fa58dff3..70c16029 100644 --- a/include/dspatch/SignalBus.h +++ b/include/dspatch/SignalBus.h @@ -110,12 +110,13 @@ inline fast_any::any* SignalBus::GetSignal( int signalIndex ) { // You might be thinking: Why the raw pointer return here? - // This is for usability, performance, and readably. Usability, because a pointer allows the - // user to manipulate the contained value externally. Performance, because returning a smart - // pointer here means having to store the value as a smart pointer too. This adds yet another - // level of indirection to the value, as well as some reference counting overhead. These Get() - // and Set() methods are VERY frequently called, so doing as little as possible with the data - // here is best, which ultimately aids in the readably of the code too. + // This is for usability, design, and performance reasons. Usability, because a pointer allows + // the user to manipulate the contained value externally. Design, because DSPatch doesn't use + // exceptions - a nullptr return here is the equivalent of "signal does not exist". + // Performance, because returning a smart pointer means having to store the value as a smart + // pointer too - this adds yet another level of indirection to the value, as well as some + // reference counting overhead. These Get() and Set() methods are VERY frequently called, so + // doing as little as possible with the data here is best. if ( (size_t)signalIndex < _signals.size() ) { @@ -142,6 +143,10 @@ inline bool SignalBus::HasValue( int signalIndex ) const template inline ValueType* SignalBus::GetValue( int signalIndex ) const { + // You might be thinking: Why the raw pointer return here? + + // See: GetSignal(). + if ( (size_t)signalIndex < _signals.size() ) { return _signals[signalIndex].as(); From c2994fe76913ec73edfc9e6b7bc3c9b889680afc Mon Sep 17 00:00:00 2001 From: Marcus Tomlinson Date: Sun, 13 Aug 2023 14:16:42 +0100 Subject: [PATCH 08/17] Update fast_any --- include/fast_any | 2 +- meson.build | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/fast_any b/include/fast_any index 93bf2667..c91ef7f2 160000 --- a/include/fast_any +++ b/include/fast_any @@ -1 +1 @@ -Subproject commit 93bf266731e1a16176ee57f7fa9107c895ffb0e3 +Subproject commit c91ef7f2912189f085a85701187276e0eb971683 diff --git a/meson.build b/meson.build index 1b717c89..c6c503a0 100644 --- a/meson.build +++ b/meson.build @@ -65,6 +65,7 @@ if find_program('cppcheck', required: false).found() '--force', '--quiet', '--suppress=missingIncludeSystem', + '--suppress=*:' + meson.current_source_dir() + '/include/fast_any/any.h', '-i', meson.current_source_dir() + '/build', '-i', meson.current_source_dir() + '/builddir', From 53884e6974028af3f15d645bb31779e850343417 Mon Sep 17 00:00:00 2001 From: Marcus Tomlinson Date: Sat, 19 Aug 2023 14:47:04 +0100 Subject: [PATCH 09/17] Run just the TenThousandComponents test --- src/Circuit.cpp | 3 + src/Component.cpp | 1 + tests/main.cpp | 2334 ++++++++++++++++++++++----------------------- 3 files changed, 1171 insertions(+), 1167 deletions(-) diff --git a/src/Circuit.cpp b/src/Circuit.cpp index dabb1b6c..a97ce131 100644 --- a/src/Circuit.cpp +++ b/src/Circuit.cpp @@ -91,6 +91,7 @@ bool Circuit::AddComponent( const Component::SPtr& component ) return true; } +// cppcheck-suppress unusedFunction bool Circuit::RemoveComponent( const Component::SPtr& component ) { if ( p->componentsSet.find( component ) == p->componentsSet.end() ) @@ -131,6 +132,7 @@ void Circuit::RemoveAllComponents() p->componentsSet.clear(); } +// cppcheck-suppress unusedFunction int Circuit::GetComponentCount() const { return (int)p->components.size(); @@ -219,6 +221,7 @@ void Circuit::SetBufferCount( int bufferCount ) } } +// cppcheck-suppress unusedFunction int Circuit::GetBufferCount() const { return (int)p->circuitThreads.size(); diff --git a/src/Component.cpp b/src/Component.cpp index 842fefca..7a482650 100644 --- a/src/Component.cpp +++ b/src/Component.cpp @@ -188,6 +188,7 @@ void Component::DisconnectAllInputs() p->inputWires.clear(); } +// cppcheck-suppress unusedFunction int Component::GetInputCount() const { return p->inputBuses[0].GetSignalCount(); diff --git a/tests/main.cpp b/tests/main.cpp index c7ef428f..0b23e871 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -27,1205 +27,1205 @@ using namespace DSPatch; -static double refEff; +// static double refEff; + +// TEST_CASE( "SignalBusTest" ) +// { +// SignalBus signalBus; + +// signalBus.SetSignalCount( 4 ); + +// signalBus.SetValue( 0, 1.0 ); +// REQUIRE( signalBus.HasValue( 0 ) ); +// REQUIRE( *signalBus.GetValue( 0 ) == 1.0 ); + +// signalBus.SetValue( 1, 1.0f ); +// REQUIRE( signalBus.HasValue( 1 ) ); +// REQUIRE( *signalBus.GetValue( 1 ) == 1.0f ); + +// signalBus.SetValue( 2, 1u ); +// REQUIRE( signalBus.HasValue( 2 ) ); +// REQUIRE( *signalBus.GetValue( 2 ) == 1u ); + +// signalBus.SetValue( 3, 1 ); +// REQUIRE( signalBus.HasValue( 3 ) ); +// REQUIRE( *signalBus.GetValue( 3 ) == 1 ); + +// // no 5th input so should return false and nullptr +// REQUIRE( !signalBus.HasValue( 4 ) ); +// REQUIRE( signalBus.GetValue( 4 ) == nullptr ); + +// REQUIRE( signalBus.GetType( 0 ) != signalBus.GetType( 1 ) ); +// REQUIRE( signalBus.GetType( 1 ) != signalBus.GetType( 2 ) ); +// REQUIRE( signalBus.GetType( 2 ) != signalBus.GetType( 3 ) ); +// // no 5th input so should return void type_info +// REQUIRE( signalBus.GetType( 3 ) != signalBus.GetType( 4 ) ); +// } + +// TEST_CASE( "SerialTest" ) +// { +// // Configure a circuit made up of a counter and 5 incrementers in series +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto inc_s1 = std::make_shared( 1 ); +// auto inc_s2 = std::make_shared( 2 ); +// auto inc_s3 = std::make_shared( 3 ); +// auto inc_s4 = std::make_shared( 4 ); +// auto inc_s5 = std::make_shared( 5 ); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter ); +// circuit->AddComponent( inc_s1 ); +// circuit->AddComponent( inc_s2 ); +// circuit->AddComponent( inc_s3 ); +// circuit->AddComponent( inc_s4 ); +// circuit->AddComponent( inc_s5 ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter, 0, inc_s1, 0 ); +// circuit->ConnectOutToIn( inc_s1, 0, inc_s2, 0 ); +// circuit->ConnectOutToIn( inc_s2, 0, inc_s3, 0 ); +// circuit->ConnectOutToIn( inc_s3, 0, inc_s4, 0 ); +// circuit->ConnectOutToIn( inc_s4, 0, inc_s5, 0 ); +// circuit->ConnectOutToIn( inc_s5, 0, probe, 0 ); + +// // Tick the circuit 100 times +// for ( int i = 0; i < 100; ++i ) +// { +// circuit->Tick( Component::TickMode::Series ); +// } +// } + +// TEST_CASE( "ParallelTest" ) +// { +// // Configure a circuit made up of a counter and 5 incrementers in parallel +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto inc_p1 = std::make_shared( 1 ); +// auto inc_p2 = std::make_shared( 2 ); +// auto inc_p3 = std::make_shared( 3 ); +// auto inc_p4 = std::make_shared( 4 ); +// auto inc_p5 = std::make_shared( 5 ); +// auto probe = std::make_shared(); + +// REQUIRE( counter->GetInputCount() == 0 ); +// REQUIRE( inc_p1->GetInputCount() == 1 ); +// REQUIRE( probe->GetInputCount() == 5 ); + +// circuit->AddComponent( counter ); +// circuit->AddComponent( inc_p1 ); +// circuit->AddComponent( inc_p2 ); +// circuit->AddComponent( inc_p3 ); +// circuit->AddComponent( inc_p4 ); +// circuit->AddComponent( inc_p5 ); +// circuit->AddComponent( probe ); + +// REQUIRE( circuit->GetComponentCount() == 7 ); + +// REQUIRE( !circuit->AddComponent( counter ) ); +// REQUIRE( !circuit->AddComponent( inc_p1 ) ); +// REQUIRE( !circuit->AddComponent( probe ) ); + +// circuit->ConnectOutToIn( counter, 0, inc_p1, 0 ); +// circuit->ConnectOutToIn( counter, 0, inc_p2, 0 ); +// circuit->ConnectOutToIn( counter, 0, inc_p3, 0 ); +// circuit->ConnectOutToIn( counter, 0, inc_p4, 0 ); +// circuit->ConnectOutToIn( counter, 0, inc_p5, 0 ); +// circuit->ConnectOutToIn( inc_p1, 0, probe, 0 ); +// circuit->ConnectOutToIn( inc_p2, 0, probe, 1 ); +// circuit->ConnectOutToIn( inc_p3, 0, probe, 2 ); +// circuit->ConnectOutToIn( inc_p4, 0, probe, 3 ); +// circuit->ConnectOutToIn( inc_p5, 0, probe, 4 ); + +// // Tick the circuit for 100ms with 3 threads +// circuit->SetBufferCount( 3 ); + +// REQUIRE( counter->GetBufferCount() == 3 ); +// REQUIRE( inc_p1->GetBufferCount() == 3 ); +// REQUIRE( probe->GetBufferCount() == 3 ); + +// circuit->StartAutoTick( Component::TickMode::Series ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); +// circuit->StopAutoTick(); +// } + +// TEST_CASE( "BranchSyncTest" ) +// { +// // Configure a circuit made up of 3 parallel branches of 4, 2, and 1 component(s) respectively +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto inc_p1_s1 = std::make_shared(); +// auto inc_p1_s2 = std::make_shared(); +// auto inc_p1_s3 = std::make_shared(); +// auto inc_p1_s4 = std::make_shared(); +// auto inc_p2_s1 = std::make_shared(); +// auto inc_p2_s2 = std::make_shared(); +// auto inc_p3_s1 = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter ); + +// circuit->AddComponent( inc_p1_s1 ); +// circuit->AddComponent( inc_p1_s2 ); +// circuit->AddComponent( inc_p1_s3 ); +// circuit->AddComponent( inc_p1_s4 ); + +// circuit->AddComponent( inc_p2_s1 ); +// circuit->AddComponent( inc_p2_s2 ); + +// circuit->AddComponent( inc_p3_s1 ); + +// circuit->AddComponent( probe ); + +// // Wire branch 1 +// circuit->ConnectOutToIn( counter, 0, inc_p1_s1, 0 ); +// circuit->ConnectOutToIn( inc_p1_s1, 0, inc_p1_s2, 0 ); +// circuit->ConnectOutToIn( inc_p1_s2, 0, inc_p1_s3, 0 ); +// circuit->ConnectOutToIn( inc_p1_s3, 0, inc_p1_s4, 0 ); +// circuit->ConnectOutToIn( inc_p1_s4, 0, probe, 0 ); + +// // Wire branch 2 +// circuit->ConnectOutToIn( counter, 0, inc_p2_s1, 0 ); +// circuit->ConnectOutToIn( inc_p2_s1, 0, inc_p2_s2, 0 ); +// circuit->ConnectOutToIn( inc_p2_s2, 0, probe, 1 ); + +// // Wire branch 3 +// circuit->ConnectOutToIn( counter, 0, inc_p3_s1, 0 ); +// circuit->ConnectOutToIn( inc_p3_s1, 0, probe, 2 ); + +// // Tick the circuit 100 times +// for ( int i = 0; i < 100; ++i ) +// { +// circuit->Tick( Component::TickMode::Series ); +// } +// } + +// TEST_CASE( "FeedbackTest" ) +// { +// // Configure a circuit made up of an adder that adds a counter to its own previous output +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto adder = std::make_shared(); +// auto passthrough = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter ); +// circuit->AddComponent( adder ); +// circuit->AddComponent( passthrough ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter, 0, adder, 0 ); +// circuit->ConnectOutToIn( adder, 0, passthrough, 0 ); + +// circuit->ConnectOutToIn( passthrough, 0, adder, 1 ); + +// circuit->ConnectOutToIn( adder, 0, probe, 0 ); + +// // Tick the circuit 100 times +// for ( int i = 0; i < 100; ++i ) +// { +// circuit->Tick( Component::TickMode::Series ); +// } +// } + +// TEST_CASE( "FeedbackTestNoCircuit" ) +// { +// auto counter = std::make_shared(); +// auto adder = std::make_shared(); +// auto passthrough = std::make_shared(); +// auto probe = std::make_shared(); + +// adder->ConnectInput( counter, 0, 0 ); +// passthrough->ConnectInput( adder, 0, 0 ); + +// adder->ConnectInput( passthrough, 0, 1 ); + +// probe->ConnectInput( adder, 0, 0 ); + +// // Tick the circuit 100 times +// for ( int i = 0; i < 100; ++i ) +// { +// counter->Tick( Component::TickMode::Series ); +// adder->Tick( Component::TickMode::Series ); +// passthrough->Tick( Component::TickMode::Series ); +// probe->Tick( Component::TickMode::Series ); + +// counter->Reset( Component::TickMode::Series ); +// adder->Reset( Component::TickMode::Series ); +// passthrough->Reset( Component::TickMode::Series ); +// probe->Reset( Component::TickMode::Series ); +// } +// } + +// TEST_CASE( "RefCountResetRegressionTest" ) +// { +// auto circuit = std::make_shared(); +// auto feedback = std::make_shared( 2 ); + +// circuit->AddComponent( feedback ); +// circuit->SetBufferCount( 2 ); + +// feedback->ConnectInput( feedback, 0, 0 ); +// feedback->SetValidInputs( 1 ); + +// circuit->StartAutoTick( Component::TickMode::Series ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); +// circuit->PauseAutoTick(); + +// feedback->ConnectInput( feedback, 0, 1 ); +// feedback->ConnectInput( feedback, 0, 2 ); +// feedback->ConnectInput( feedback, 0, 3 ); +// feedback->SetValidInputs( 4 ); + +// circuit->StartAutoTick( Component::TickMode::Series ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); +// circuit->PauseAutoTick(); + +// feedback->ConnectInput( feedback, 0, 4 ); +// feedback->ConnectInput( feedback, 0, 5 ); +// feedback->ConnectInput( feedback, 0, 6 ); +// feedback->ConnectInput( feedback, 0, 7 ); +// feedback->ConnectInput( feedback, 0, 8 ); +// feedback->ConnectInput( feedback, 0, 9 ); +// feedback->SetValidInputs( 10 ); + +// circuit->StartAutoTick( Component::TickMode::Series ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); +// circuit->StopAutoTick(); +// } + +// TEST_CASE( "NoOutputTest" ) +// { +// // Configure a circuit where the counter responds sporadically +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter, 0, probe, 0 ); + +// // Tick the circuit 100 times +// for ( int i = 0; i < 100; ++i ) +// { +// circuit->Tick( Component::TickMode::Series ); +// } +// } + +// TEST_CASE( "ChangingOutputTest" ) +// { +// // Configure a circuit whereby a component outputs varying types (int, float, string, vector) +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter, 0, probe, 0 ); + +// // Tick the circuit 100 times +// for ( int i = 0; i < 100; ++i ) +// { +// circuit->Tick( Component::TickMode::Series ); +// } +// } + +// TEST_CASE( "ThreadPerformanceTest" ) +// { +// // Configure a circuit made up of 4 parallel counters, then adjust the thread count +// auto circuit = std::make_shared(); + +// auto counter1 = std::make_shared(); +// auto counter2 = std::make_shared(); +// auto counter3 = std::make_shared(); +// auto counter4 = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter1 ); +// circuit->AddComponent( counter2 ); +// circuit->AddComponent( counter3 ); +// circuit->AddComponent( counter4 ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter1, 0, probe, 0 ); +// circuit->ConnectOutToIn( counter2, 0, probe, 1 ); +// circuit->ConnectOutToIn( counter3, 0, probe, 2 ); +// circuit->ConnectOutToIn( counter4, 0, probe, 3 ); + +// // Calculate reference efficiency + +// SignalBus testBus; +// auto measureRef = [&testBus]( std::shared_ptr& counter ) +// { +// for ( int i = 0; i < 1000; ++i ) +// { +// counter->Process_( testBus, testBus ); +// } +// }; + +// auto begin = std::chrono::high_resolution_clock::now(); +// auto t1 = std::thread( [&measureRef, &counter1]() { measureRef( counter1 ); } ); +// auto t2 = std::thread( [&measureRef, &counter2]() { measureRef( counter2 ); } ); +// auto t3 = std::thread( [&measureRef, &counter3]() { measureRef( counter3 ); } ); +// auto t4 = std::thread( [&measureRef, &counter4]() { measureRef( counter4 ); } ); +// t1.join(); +// t2.join(); +// t3.join(); +// t4.join(); +// auto end = std::chrono::high_resolution_clock::now(); +// refEff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); + +// counter1->ResetCount(); +// counter2->ResetCount(); +// counter3->ResetCount(); +// counter4->ResetCount(); + +// std::cout << "Reference Efficiency: " << refEff << "%" << std::endl; + +// // Tick the circuit with no threads +// begin = std::chrono::high_resolution_clock::now(); +// for ( int i = 0; i < 1000; ++i ) +// { +// circuit->Tick( Component::TickMode::Series ); +// } +// end = std::chrono::high_resolution_clock::now(); +// auto eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); + +// auto overhead = 100 - ( 100 * ( eff / refEff ) ); +// std::cout << "0x Buffer Efficiency (Series Mode): " << eff << "% (-" << overhead << "%)" << std::endl; +// REQUIRE( eff >= refEff * 0.25 * 0.90 ); + +// // Tick the circuit with 1 thread, and check that no more ticks occurred +// if ( std::thread::hardware_concurrency() < 1 ) +// { +// return; +// } +// circuit->SetBufferCount( 1 ); + +// begin = std::chrono::high_resolution_clock::now(); +// for ( int i = 0; i < 1000; ++i ) +// { +// circuit->Tick( Component::TickMode::Series ); +// } +// end = std::chrono::high_resolution_clock::now(); +// eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); + +// overhead = 100 - ( 100 * ( eff / refEff ) ); +// std::cout << "1x Buffer Efficiency (Series Mode): " << eff << "% (-" << overhead << "%)" << std::endl; +// REQUIRE( eff >= refEff * 0.25 * 0.90 ); + +// // Tick the circuit with 2 threads, and check that more ticks occurred +// if ( std::thread::hardware_concurrency() < 2 ) +// { +// return; +// } +// circuit->SetBufferCount( 2 ); + +// begin = std::chrono::high_resolution_clock::now(); +// for ( int i = 0; i < 1000; ++i ) +// { +// circuit->Tick( Component::TickMode::Series ); +// } +// end = std::chrono::high_resolution_clock::now(); +// eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); + +// overhead = 100 - ( 100 * ( eff / refEff ) ); +// std::cout << "2x Buffer Efficiency (Series Mode): " << eff << "% (-" << overhead << "%)" << std::endl; +// REQUIRE( eff >= refEff * 0.5 * 0.90 ); + +// // Tick the circuit with 3 threads, and check that more ticks occurred +// if ( std::thread::hardware_concurrency() < 4 ) +// { +// return; +// } +// circuit->SetBufferCount( 3 ); + +// begin = std::chrono::high_resolution_clock::now(); +// for ( int i = 0; i < 1000; ++i ) +// { +// circuit->Tick( Component::TickMode::Series ); +// } +// end = std::chrono::high_resolution_clock::now(); +// eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); + +// overhead = 100 - ( 100 * ( eff / refEff ) ); +// std::cout << "3x Buffer Efficiency (Series Mode): " << eff << "% (-" << overhead << "%)" << std::endl; +// REQUIRE( eff >= refEff * 0.75 * 0.90 ); + +// // Tick the circuit with 4 threads, and check that more ticks occurred +// if ( std::thread::hardware_concurrency() < 4 ) +// { +// return; +// } +// circuit->SetBufferCount( 4 ); + +// begin = std::chrono::high_resolution_clock::now(); +// for ( int i = 0; i < 1000; ++i ) +// { +// circuit->Tick( Component::TickMode::Series ); +// } +// end = std::chrono::high_resolution_clock::now(); +// eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); + +// overhead = 100 - ( 100 * ( eff / refEff ) ); +// std::cout << "4x Buffer Efficiency (Series Mode): " << eff << "% (-" << overhead << "%)" << std::endl; +// REQUIRE( eff >= refEff * 0.90 ); +// } + +// TEST_CASE( "StopAutoTickRegressionTest" ) +// { +// auto circuit = std::make_shared(); + +// auto counter1 = std::make_shared(); +// auto counter2 = std::make_shared(); +// auto counter3 = std::make_shared(); +// auto counter4 = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter1 ); +// circuit->AddComponent( counter2 ); +// circuit->AddComponent( counter3 ); +// circuit->AddComponent( counter4 ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter1, 0, probe, 0 ); +// circuit->ConnectOutToIn( counter2, 0, probe, 1 ); +// circuit->ConnectOutToIn( counter3, 0, probe, 2 ); +// circuit->ConnectOutToIn( counter4, 0, probe, 3 ); + +// circuit->SetBufferCount( std::thread::hardware_concurrency() ); + +// circuit->StartAutoTick( Component::TickMode::Series ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); +// circuit->StopAutoTick(); +// circuit->RemoveComponent( counter1 ); +// circuit->RemoveComponent( counter2 ); +// circuit->RemoveComponent( counter3 ); +// circuit->RemoveComponent( counter4 ); +// circuit->RemoveComponent( probe ); + +// REQUIRE( !circuit->RemoveComponent( counter1 ) ); +// } + +// TEST_CASE( "ThreadAdjustmentTest" ) +// { +// // Configure a counter circuit, then adjust the thread count while it's running +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter, 0, probe, 0 ); +// circuit->ConnectOutToIn( counter, 0, probe, 1 ); +// circuit->ConnectOutToIn( counter, 0, probe, 2 ); +// circuit->ConnectOutToIn( counter, 0, probe, 3 ); + +// // Tick the circuit for 100ms with 1 thread +// circuit->StartAutoTick( Component::TickMode::Series ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// // Adjust the thread count while the circuit is running +// circuit->SetBufferCount( 2 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// circuit->SetBufferCount( 0 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// circuit->SetBufferCount( 4 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// circuit->SetBufferCount( 2 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// circuit->SetBufferCount( 3 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// circuit->StopAutoTick(); + +// REQUIRE( circuit->GetBufferCount() == 3 ); +// } + +// TEST_CASE( "WiringTest" ) +// { +// // Configure a counter circuit, then re-wire it while it's running +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->ConnectOutToIn( counter, 0, probe, 0 ); +// circuit->ConnectOutToIn( probe, 0, counter, 0 ); + +// // Tick the circuit for 100ms with 1 thread +// circuit->StartAutoTick( Component::TickMode::Series ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// // Re-wire + +// auto pass_s1 = std::make_shared(); +// circuit->AddComponent( pass_s1 ); + +// circuit->ConnectOutToIn( pass_s1, 0, probe, 0 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// circuit->ConnectOutToIn( counter, 0, pass_s1, 0 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// // Disconnect a component + +// circuit->PauseAutoTick(); +// probe->DisconnectInput( 0 ); +// circuit->ResumeAutoTick(); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); +// circuit->DisconnectComponent( probe ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// // Wire in a new component + +// auto pass_s2 = std::make_shared(); +// circuit->AddComponent( pass_s2 ); + +// circuit->ConnectOutToIn( probe, 0, counter, 0 ); +// circuit->ConnectOutToIn( pass_s2, 0, probe, 0 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// circuit->ConnectOutToIn( pass_s1, 0, pass_s2, 0 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// circuit->StopAutoTick(); +// } + +// //================================================================================================= + +// TEST_CASE( "SerialTest2" ) +// { +// // Configure a circuit made up of a counter and 5 incrementers in series +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto inc_s1 = std::make_shared( 1 ); +// auto inc_s2 = std::make_shared( 2 ); +// auto inc_s3 = std::make_shared( 3 ); +// auto inc_s4 = std::make_shared( 4 ); +// auto inc_s5 = std::make_shared( 5 ); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter ); +// circuit->AddComponent( inc_s1 ); +// circuit->AddComponent( inc_s2 ); +// circuit->AddComponent( inc_s3 ); +// circuit->AddComponent( inc_s4 ); +// circuit->AddComponent( inc_s5 ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter, 0, inc_s1, 0 ); +// circuit->ConnectOutToIn( inc_s1, 0, inc_s2, 0 ); +// circuit->ConnectOutToIn( inc_s2, 0, inc_s3, 0 ); +// circuit->ConnectOutToIn( inc_s3, 0, inc_s4, 0 ); +// circuit->ConnectOutToIn( inc_s4, 0, inc_s5, 0 ); +// circuit->ConnectOutToIn( inc_s5, 0, probe, 0 ); + +// // Tick the circuit 100 times +// for ( int i = 0; i < 100; ++i ) +// { +// circuit->Tick( Component::TickMode::Parallel ); +// } +// } + +// TEST_CASE( "ParallelTest2" ) +// { +// // Configure a circuit made up of a counter and 5 incrementers in parallel +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto inc_p1 = std::make_shared( 1 ); +// auto inc_p2 = std::make_shared( 2 ); +// auto inc_p3 = std::make_shared( 3 ); +// auto inc_p4 = std::make_shared( 4 ); +// auto inc_p5 = std::make_shared( 5 ); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter ); +// circuit->AddComponent( inc_p1 ); +// circuit->AddComponent( inc_p2 ); +// circuit->AddComponent( inc_p3 ); +// circuit->AddComponent( inc_p4 ); +// circuit->AddComponent( inc_p5 ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter, 0, inc_p1, 0 ); +// circuit->ConnectOutToIn( counter, 0, inc_p2, 0 ); +// circuit->ConnectOutToIn( counter, 0, inc_p3, 0 ); +// circuit->ConnectOutToIn( counter, 0, inc_p4, 0 ); +// circuit->ConnectOutToIn( counter, 0, inc_p5, 0 ); +// circuit->ConnectOutToIn( inc_p1, 0, probe, 0 ); +// circuit->ConnectOutToIn( inc_p2, 0, probe, 1 ); +// circuit->ConnectOutToIn( inc_p3, 0, probe, 2 ); +// circuit->ConnectOutToIn( inc_p4, 0, probe, 3 ); +// circuit->ConnectOutToIn( inc_p5, 0, probe, 4 ); + +// // Tick the circuit for 100ms with 3 threads +// circuit->SetBufferCount( 3 ); +// circuit->StartAutoTick( Component::TickMode::Parallel ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); +// circuit->StopAutoTick(); +// } + +// TEST_CASE( "BranchSyncTest2" ) +// { +// // Configure a circuit made up of 3 parallel branches of 4, 2, and 1 component(s) respectively +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto inc_p1_s1 = std::make_shared(); +// auto inc_p1_s2 = std::make_shared(); +// auto inc_p1_s3 = std::make_shared(); +// auto inc_p1_s4 = std::make_shared(); +// auto inc_p2_s1 = std::make_shared(); +// auto inc_p2_s2 = std::make_shared(); +// auto inc_p3_s1 = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter ); + +// circuit->AddComponent( inc_p1_s1 ); +// circuit->AddComponent( inc_p1_s2 ); +// circuit->AddComponent( inc_p1_s3 ); +// circuit->AddComponent( inc_p1_s4 ); + +// circuit->AddComponent( inc_p2_s1 ); +// circuit->AddComponent( inc_p2_s2 ); + +// circuit->AddComponent( inc_p3_s1 ); + +// circuit->AddComponent( probe ); + +// // Wire branch 1 +// circuit->ConnectOutToIn( counter, 0, inc_p1_s1, 0 ); +// circuit->ConnectOutToIn( inc_p1_s1, 0, inc_p1_s2, 0 ); +// circuit->ConnectOutToIn( inc_p1_s2, 0, inc_p1_s3, 0 ); +// circuit->ConnectOutToIn( inc_p1_s3, 0, inc_p1_s4, 0 ); +// circuit->ConnectOutToIn( inc_p1_s4, 0, probe, 0 ); + +// // Wire branch 2 +// circuit->ConnectOutToIn( counter, 0, inc_p2_s1, 0 ); +// circuit->ConnectOutToIn( inc_p2_s1, 0, inc_p2_s2, 0 ); +// circuit->ConnectOutToIn( inc_p2_s2, 0, probe, 1 ); + +// // Wire branch 3 +// circuit->ConnectOutToIn( counter, 0, inc_p3_s1, 0 ); +// circuit->ConnectOutToIn( inc_p3_s1, 0, probe, 2 ); + +// // Tick the circuit 100 times +// for ( int i = 0; i < 100; ++i ) +// { +// circuit->Tick( Component::TickMode::Parallel ); +// } +// } + +// TEST_CASE( "FeedbackTest2" ) +// { +// // Configure a circuit made up of an adder that adds a counter to its own previous output +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto adder = std::make_shared(); +// auto passthrough = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter ); +// circuit->AddComponent( adder ); +// circuit->AddComponent( passthrough ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter, 0, adder, 0 ); +// circuit->ConnectOutToIn( adder, 0, passthrough, 0 ); + +// circuit->ConnectOutToIn( passthrough, 0, adder, 1 ); + +// circuit->ConnectOutToIn( adder, 0, probe, 0 ); + +// // Tick the circuit 100 times +// for ( int i = 0; i < 100; ++i ) +// { +// circuit->Tick( Component::TickMode::Parallel ); +// } +// } + +// TEST_CASE( "FeedbackTestNoCircuit2" ) +// { +// auto counter = std::make_shared(); +// auto adder = std::make_shared(); +// auto passthrough = std::make_shared(); +// auto probe = std::make_shared(); + +// adder->ConnectInput( counter, 0, 0 ); +// passthrough->ConnectInput( adder, 0, 0 ); + +// adder->ConnectInput( passthrough, 0, 1 ); + +// probe->ConnectInput( adder, 0, 0 ); + +// // Tick the circuit 100 times +// for ( int i = 0; i < 100; ++i ) +// { +// counter->Tick( Component::TickMode::Parallel ); +// adder->Tick( Component::TickMode::Parallel ); +// passthrough->Tick( Component::TickMode::Parallel ); +// probe->Tick( Component::TickMode::Parallel ); + +// counter->Reset( Component::TickMode::Parallel ); +// adder->Reset( Component::TickMode::Parallel ); +// passthrough->Reset( Component::TickMode::Parallel ); +// probe->Reset( Component::TickMode::Parallel ); +// } +// } + +// TEST_CASE( "RefCountResetRegressionTest2" ) +// { +// auto circuit = std::make_shared(); +// auto feedback = std::make_shared( 2 ); + +// circuit->AddComponent( feedback ); +// circuit->SetBufferCount( 2 ); + +// feedback->ConnectInput( feedback, 0, 0 ); +// feedback->SetValidInputs( 1 ); + +// circuit->StartAutoTick( Component::TickMode::Parallel ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); +// circuit->PauseAutoTick(); + +// feedback->ConnectInput( feedback, 0, 1 ); +// feedback->ConnectInput( feedback, 0, 2 ); +// feedback->ConnectInput( feedback, 0, 3 ); +// feedback->SetValidInputs( 4 ); + +// circuit->StartAutoTick( Component::TickMode::Parallel ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); +// circuit->PauseAutoTick(); + +// feedback->ConnectInput( feedback, 0, 4 ); +// feedback->ConnectInput( feedback, 0, 5 ); +// feedback->ConnectInput( feedback, 0, 6 ); +// feedback->ConnectInput( feedback, 0, 7 ); +// feedback->ConnectInput( feedback, 0, 8 ); +// feedback->ConnectInput( feedback, 0, 9 ); +// feedback->SetValidInputs( 10 ); + +// circuit->StartAutoTick( Component::TickMode::Parallel ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); +// circuit->StopAutoTick(); +// } + +// TEST_CASE( "NoOutputTest2" ) +// { +// // Configure a circuit where the counter responds sporadically +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter, 0, probe, 0 ); + +// // Tick the circuit 100 times +// for ( int i = 0; i < 100; ++i ) +// { +// circuit->Tick( Component::TickMode::Parallel ); +// } +// } + +// TEST_CASE( "ChangingOutputTest2" ) +// { +// // Configure a circuit whereby a component outputs varying types (int, float, string, vector) +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter, 0, probe, 0 ); + +// // Tick the circuit 100 times +// for ( int i = 0; i < 100; ++i ) +// { +// circuit->Tick( Component::TickMode::Parallel ); +// } +// } + +// TEST_CASE( "ThreadPerformanceTest2" ) +// { +// double cores = std::thread::hardware_concurrency(); +// cores = cores == 3.0 ? 2.0 : cores; +// cores = cores > 4.0 ? 4.0 : cores; +// auto effFrac = cores / 4.0; + +// // Configure a circuit made up of 4 parallel counters, then adjust the thread count +// auto circuit = std::make_shared(); + +// auto counter1 = std::make_shared(); +// auto counter2 = std::make_shared(); +// auto counter3 = std::make_shared(); +// auto counter4 = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter1 ); +// circuit->AddComponent( counter2 ); +// circuit->AddComponent( counter3 ); +// circuit->AddComponent( counter4 ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter1, 0, probe, 0 ); +// circuit->ConnectOutToIn( counter2, 0, probe, 1 ); +// circuit->ConnectOutToIn( counter3, 0, probe, 2 ); +// circuit->ConnectOutToIn( counter4, 0, probe, 3 ); + +// // Tick the circuit with no threads +// auto begin = std::chrono::high_resolution_clock::now(); +// for ( int i = 0; i < 1000; ++i ) +// { +// circuit->Tick( Component::TickMode::Parallel ); +// } +// auto end = std::chrono::high_resolution_clock::now(); +// auto eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); + +// auto overhead = 100 - ( 100 * ( eff / refEff ) ); +// std::cout << "0x Buffer Efficiency (Parallel Mode): " << eff << "% (-" << overhead << "%)" << std::endl; +// REQUIRE( eff >= refEff * effFrac * 0.85 ); + +// // Tick the circuit with 1 thread, and check that no more ticks occurred +// if ( std::thread::hardware_concurrency() < 1 ) +// { +// return; +// } +// circuit->SetBufferCount( 1 ); + +// begin = std::chrono::high_resolution_clock::now(); +// for ( int i = 0; i < 1000; ++i ) +// { +// circuit->Tick( Component::TickMode::Parallel ); +// } +// end = std::chrono::high_resolution_clock::now(); +// eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); + +// overhead = 100 - ( 100 * ( eff / refEff ) ); +// std::cout << "1x Buffer Efficiency (Parallel Mode): " << eff << "% (-" << overhead << "%)" << std::endl; +// REQUIRE( eff >= refEff * effFrac * 0.85 ); + +// // Tick the circuit with 2 threads, and check that more ticks occurred +// if ( std::thread::hardware_concurrency() < 2 ) +// { +// return; +// } +// circuit->SetBufferCount( 2 ); + +// begin = std::chrono::high_resolution_clock::now(); +// for ( int i = 0; i < 1000; ++i ) +// { +// circuit->Tick( Component::TickMode::Parallel ); +// } +// end = std::chrono::high_resolution_clock::now(); +// eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); + +// overhead = 100 - ( 100 * ( eff / refEff ) ); +// std::cout << "2x Buffer Efficiency (Parallel Mode): " << eff << "% (-" << overhead << "%)" << std::endl; +// REQUIRE( eff >= refEff * effFrac * 0.90 ); + +// // Tick the circuit with 3 threads, and check that more ticks occurred +// if ( std::thread::hardware_concurrency() < 4 ) +// { +// return; +// } +// circuit->SetBufferCount( 3 ); + +// begin = std::chrono::high_resolution_clock::now(); +// for ( int i = 0; i < 1000; ++i ) +// { +// circuit->Tick( Component::TickMode::Parallel ); +// } +// end = std::chrono::high_resolution_clock::now(); +// eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); + +// overhead = 100 - ( 100 * ( eff / refEff ) ); +// std::cout << "3x Buffer Efficiency (Parallel Mode): " << eff << "% (-" << overhead << "%)" << std::endl; +// REQUIRE( eff >= refEff * effFrac * 0.90 ); + +// // Tick the circuit with 4 threads, and check that more ticks occurred +// if ( std::thread::hardware_concurrency() < 4 ) +// { +// return; +// } +// circuit->SetBufferCount( 4 ); + +// begin = std::chrono::high_resolution_clock::now(); +// for ( int i = 0; i < 1000; ++i ) +// { +// circuit->Tick( Component::TickMode::Parallel ); +// } +// end = std::chrono::high_resolution_clock::now(); +// eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); + +// overhead = 100 - ( 100 * ( eff / refEff ) ); +// std::cout << "4x Buffer Efficiency (Parallel Mode): " << eff << "% (-" << overhead << "%)" << std::endl; +// REQUIRE( eff >= refEff * effFrac * 0.90 ); +// } + +// TEST_CASE( "StopAutoTickRegressionTest2" ) +// { +// auto circuit = std::make_shared(); + +// auto counter1 = std::make_shared(); +// auto counter2 = std::make_shared(); +// auto counter3 = std::make_shared(); +// auto counter4 = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter1 ); +// circuit->AddComponent( counter2 ); +// circuit->AddComponent( counter3 ); +// circuit->AddComponent( counter4 ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter1, 0, probe, 0 ); +// circuit->ConnectOutToIn( counter2, 0, probe, 1 ); +// circuit->ConnectOutToIn( counter3, 0, probe, 2 ); +// circuit->ConnectOutToIn( counter4, 0, probe, 3 ); + +// circuit->SetBufferCount( std::thread::hardware_concurrency() ); + +// circuit->StartAutoTick( Component::TickMode::Parallel ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); +// circuit->StopAutoTick(); +// circuit->RemoveComponent( counter1 ); +// circuit->RemoveComponent( counter2 ); +// circuit->RemoveComponent( counter3 ); +// circuit->RemoveComponent( counter4 ); +// circuit->RemoveComponent( probe ); +// } + +// TEST_CASE( "ThreadAdjustmentTest2" ) +// { +// // Configure a counter circuit, then adjust the thread count while it's running +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->AddComponent( counter ); +// circuit->AddComponent( probe ); + +// circuit->ConnectOutToIn( counter, 0, probe, 0 ); +// circuit->ConnectOutToIn( counter, 0, probe, 1 ); +// circuit->ConnectOutToIn( counter, 0, probe, 2 ); +// circuit->ConnectOutToIn( counter, 0, probe, 3 ); + +// // Tick the circuit for 100ms with 1 thread +// circuit->StartAutoTick( Component::TickMode::Parallel ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// // Adjust the thread count while the circuit is running +// circuit->SetBufferCount( 2 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// circuit->SetBufferCount( 0 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// circuit->SetBufferCount( 4 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// circuit->SetBufferCount( 2 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// circuit->SetBufferCount( 3 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// circuit->StopAutoTick(); + +// REQUIRE( circuit->GetBufferCount() == 3 ); +// } + +// TEST_CASE( "WiringTest2" ) +// { +// // Configure a counter circuit, then re-wire it while it's running +// auto circuit = std::make_shared(); + +// auto counter = std::make_shared(); +// auto probe = std::make_shared(); + +// circuit->ConnectOutToIn( counter, 0, probe, 0 ); +// circuit->ConnectOutToIn( probe, 0, counter, 0 ); + +// // Tick the circuit for 100ms with 1 thread +// circuit->StartAutoTick( Component::TickMode::Parallel ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + +// // Re-wire -TEST_CASE( "SignalBusTest" ) -{ - SignalBus signalBus; - - signalBus.SetSignalCount( 4 ); - - signalBus.SetValue( 0, 1.0 ); - REQUIRE( signalBus.HasValue( 0 ) ); - REQUIRE( *signalBus.GetValue( 0 ) == 1.0 ); - - signalBus.SetValue( 1, 1.0f ); - REQUIRE( signalBus.HasValue( 1 ) ); - REQUIRE( *signalBus.GetValue( 1 ) == 1.0f ); - - signalBus.SetValue( 2, 1u ); - REQUIRE( signalBus.HasValue( 2 ) ); - REQUIRE( *signalBus.GetValue( 2 ) == 1u ); - - signalBus.SetValue( 3, 1 ); - REQUIRE( signalBus.HasValue( 3 ) ); - REQUIRE( *signalBus.GetValue( 3 ) == 1 ); - - // no 5th input so should return false and nullptr - REQUIRE( !signalBus.HasValue( 4 ) ); - REQUIRE( signalBus.GetValue( 4 ) == nullptr ); - - REQUIRE( signalBus.GetType( 0 ) != signalBus.GetType( 1 ) ); - REQUIRE( signalBus.GetType( 1 ) != signalBus.GetType( 2 ) ); - REQUIRE( signalBus.GetType( 2 ) != signalBus.GetType( 3 ) ); - // no 5th input so should return void type_info - REQUIRE( signalBus.GetType( 3 ) != signalBus.GetType( 4 ) ); -} - -TEST_CASE( "SerialTest" ) -{ - // Configure a circuit made up of a counter and 5 incrementers in series - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto inc_s1 = std::make_shared( 1 ); - auto inc_s2 = std::make_shared( 2 ); - auto inc_s3 = std::make_shared( 3 ); - auto inc_s4 = std::make_shared( 4 ); - auto inc_s5 = std::make_shared( 5 ); - auto probe = std::make_shared(); - - circuit->AddComponent( counter ); - circuit->AddComponent( inc_s1 ); - circuit->AddComponent( inc_s2 ); - circuit->AddComponent( inc_s3 ); - circuit->AddComponent( inc_s4 ); - circuit->AddComponent( inc_s5 ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter, 0, inc_s1, 0 ); - circuit->ConnectOutToIn( inc_s1, 0, inc_s2, 0 ); - circuit->ConnectOutToIn( inc_s2, 0, inc_s3, 0 ); - circuit->ConnectOutToIn( inc_s3, 0, inc_s4, 0 ); - circuit->ConnectOutToIn( inc_s4, 0, inc_s5, 0 ); - circuit->ConnectOutToIn( inc_s5, 0, probe, 0 ); - - // Tick the circuit 100 times - for ( int i = 0; i < 100; ++i ) - { - circuit->Tick( Component::TickMode::Series ); - } -} - -TEST_CASE( "ParallelTest" ) -{ - // Configure a circuit made up of a counter and 5 incrementers in parallel - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto inc_p1 = std::make_shared( 1 ); - auto inc_p2 = std::make_shared( 2 ); - auto inc_p3 = std::make_shared( 3 ); - auto inc_p4 = std::make_shared( 4 ); - auto inc_p5 = std::make_shared( 5 ); - auto probe = std::make_shared(); - - REQUIRE( counter->GetInputCount() == 0 ); - REQUIRE( inc_p1->GetInputCount() == 1 ); - REQUIRE( probe->GetInputCount() == 5 ); - - circuit->AddComponent( counter ); - circuit->AddComponent( inc_p1 ); - circuit->AddComponent( inc_p2 ); - circuit->AddComponent( inc_p3 ); - circuit->AddComponent( inc_p4 ); - circuit->AddComponent( inc_p5 ); - circuit->AddComponent( probe ); - - REQUIRE( circuit->GetComponentCount() == 7 ); - - REQUIRE( !circuit->AddComponent( counter ) ); - REQUIRE( !circuit->AddComponent( inc_p1 ) ); - REQUIRE( !circuit->AddComponent( probe ) ); - - circuit->ConnectOutToIn( counter, 0, inc_p1, 0 ); - circuit->ConnectOutToIn( counter, 0, inc_p2, 0 ); - circuit->ConnectOutToIn( counter, 0, inc_p3, 0 ); - circuit->ConnectOutToIn( counter, 0, inc_p4, 0 ); - circuit->ConnectOutToIn( counter, 0, inc_p5, 0 ); - circuit->ConnectOutToIn( inc_p1, 0, probe, 0 ); - circuit->ConnectOutToIn( inc_p2, 0, probe, 1 ); - circuit->ConnectOutToIn( inc_p3, 0, probe, 2 ); - circuit->ConnectOutToIn( inc_p4, 0, probe, 3 ); - circuit->ConnectOutToIn( inc_p5, 0, probe, 4 ); - - // Tick the circuit for 100ms with 3 threads - circuit->SetBufferCount( 3 ); - - REQUIRE( counter->GetBufferCount() == 3 ); - REQUIRE( inc_p1->GetBufferCount() == 3 ); - REQUIRE( probe->GetBufferCount() == 3 ); - - circuit->StartAutoTick( Component::TickMode::Series ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - circuit->StopAutoTick(); -} - -TEST_CASE( "BranchSyncTest" ) -{ - // Configure a circuit made up of 3 parallel branches of 4, 2, and 1 component(s) respectively - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto inc_p1_s1 = std::make_shared(); - auto inc_p1_s2 = std::make_shared(); - auto inc_p1_s3 = std::make_shared(); - auto inc_p1_s4 = std::make_shared(); - auto inc_p2_s1 = std::make_shared(); - auto inc_p2_s2 = std::make_shared(); - auto inc_p3_s1 = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter ); - - circuit->AddComponent( inc_p1_s1 ); - circuit->AddComponent( inc_p1_s2 ); - circuit->AddComponent( inc_p1_s3 ); - circuit->AddComponent( inc_p1_s4 ); - - circuit->AddComponent( inc_p2_s1 ); - circuit->AddComponent( inc_p2_s2 ); - - circuit->AddComponent( inc_p3_s1 ); - - circuit->AddComponent( probe ); - - // Wire branch 1 - circuit->ConnectOutToIn( counter, 0, inc_p1_s1, 0 ); - circuit->ConnectOutToIn( inc_p1_s1, 0, inc_p1_s2, 0 ); - circuit->ConnectOutToIn( inc_p1_s2, 0, inc_p1_s3, 0 ); - circuit->ConnectOutToIn( inc_p1_s3, 0, inc_p1_s4, 0 ); - circuit->ConnectOutToIn( inc_p1_s4, 0, probe, 0 ); - - // Wire branch 2 - circuit->ConnectOutToIn( counter, 0, inc_p2_s1, 0 ); - circuit->ConnectOutToIn( inc_p2_s1, 0, inc_p2_s2, 0 ); - circuit->ConnectOutToIn( inc_p2_s2, 0, probe, 1 ); - - // Wire branch 3 - circuit->ConnectOutToIn( counter, 0, inc_p3_s1, 0 ); - circuit->ConnectOutToIn( inc_p3_s1, 0, probe, 2 ); - - // Tick the circuit 100 times - for ( int i = 0; i < 100; ++i ) - { - circuit->Tick( Component::TickMode::Series ); - } -} - -TEST_CASE( "FeedbackTest" ) -{ - // Configure a circuit made up of an adder that adds a counter to its own previous output - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto adder = std::make_shared(); - auto passthrough = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter ); - circuit->AddComponent( adder ); - circuit->AddComponent( passthrough ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter, 0, adder, 0 ); - circuit->ConnectOutToIn( adder, 0, passthrough, 0 ); - - circuit->ConnectOutToIn( passthrough, 0, adder, 1 ); - - circuit->ConnectOutToIn( adder, 0, probe, 0 ); - - // Tick the circuit 100 times - for ( int i = 0; i < 100; ++i ) - { - circuit->Tick( Component::TickMode::Series ); - } -} - -TEST_CASE( "FeedbackTestNoCircuit" ) -{ - auto counter = std::make_shared(); - auto adder = std::make_shared(); - auto passthrough = std::make_shared(); - auto probe = std::make_shared(); - - adder->ConnectInput( counter, 0, 0 ); - passthrough->ConnectInput( adder, 0, 0 ); - - adder->ConnectInput( passthrough, 0, 1 ); - - probe->ConnectInput( adder, 0, 0 ); - - // Tick the circuit 100 times - for ( int i = 0; i < 100; ++i ) - { - counter->Tick( Component::TickMode::Series ); - adder->Tick( Component::TickMode::Series ); - passthrough->Tick( Component::TickMode::Series ); - probe->Tick( Component::TickMode::Series ); - - counter->Reset( Component::TickMode::Series ); - adder->Reset( Component::TickMode::Series ); - passthrough->Reset( Component::TickMode::Series ); - probe->Reset( Component::TickMode::Series ); - } -} - -TEST_CASE( "RefCountResetRegressionTest" ) -{ - auto circuit = std::make_shared(); - auto feedback = std::make_shared( 2 ); - - circuit->AddComponent( feedback ); - circuit->SetBufferCount( 2 ); - - feedback->ConnectInput( feedback, 0, 0 ); - feedback->SetValidInputs( 1 ); - - circuit->StartAutoTick( Component::TickMode::Series ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - circuit->PauseAutoTick(); - - feedback->ConnectInput( feedback, 0, 1 ); - feedback->ConnectInput( feedback, 0, 2 ); - feedback->ConnectInput( feedback, 0, 3 ); - feedback->SetValidInputs( 4 ); - - circuit->StartAutoTick( Component::TickMode::Series ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - circuit->PauseAutoTick(); - - feedback->ConnectInput( feedback, 0, 4 ); - feedback->ConnectInput( feedback, 0, 5 ); - feedback->ConnectInput( feedback, 0, 6 ); - feedback->ConnectInput( feedback, 0, 7 ); - feedback->ConnectInput( feedback, 0, 8 ); - feedback->ConnectInput( feedback, 0, 9 ); - feedback->SetValidInputs( 10 ); - - circuit->StartAutoTick( Component::TickMode::Series ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - circuit->StopAutoTick(); -} - -TEST_CASE( "NoOutputTest" ) -{ - // Configure a circuit where the counter responds sporadically - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter, 0, probe, 0 ); - - // Tick the circuit 100 times - for ( int i = 0; i < 100; ++i ) - { - circuit->Tick( Component::TickMode::Series ); - } -} - -TEST_CASE( "ChangingOutputTest" ) -{ - // Configure a circuit whereby a component outputs varying types (int, float, string, vector) - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter, 0, probe, 0 ); - - // Tick the circuit 100 times - for ( int i = 0; i < 100; ++i ) - { - circuit->Tick( Component::TickMode::Series ); - } -} - -TEST_CASE( "ThreadPerformanceTest" ) -{ - // Configure a circuit made up of 4 parallel counters, then adjust the thread count - auto circuit = std::make_shared(); - - auto counter1 = std::make_shared(); - auto counter2 = std::make_shared(); - auto counter3 = std::make_shared(); - auto counter4 = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter1 ); - circuit->AddComponent( counter2 ); - circuit->AddComponent( counter3 ); - circuit->AddComponent( counter4 ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter1, 0, probe, 0 ); - circuit->ConnectOutToIn( counter2, 0, probe, 1 ); - circuit->ConnectOutToIn( counter3, 0, probe, 2 ); - circuit->ConnectOutToIn( counter4, 0, probe, 3 ); - - // Calculate reference efficiency - - SignalBus testBus; - auto measureRef = [&testBus]( std::shared_ptr& counter ) - { - for ( int i = 0; i < 1000; ++i ) - { - counter->Process_( testBus, testBus ); - } - }; - - auto begin = std::chrono::high_resolution_clock::now(); - auto t1 = std::thread( [&measureRef, &counter1]() { measureRef( counter1 ); } ); - auto t2 = std::thread( [&measureRef, &counter2]() { measureRef( counter2 ); } ); - auto t3 = std::thread( [&measureRef, &counter3]() { measureRef( counter3 ); } ); - auto t4 = std::thread( [&measureRef, &counter4]() { measureRef( counter4 ); } ); - t1.join(); - t2.join(); - t3.join(); - t4.join(); - auto end = std::chrono::high_resolution_clock::now(); - refEff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); - - counter1->ResetCount(); - counter2->ResetCount(); - counter3->ResetCount(); - counter4->ResetCount(); - - std::cout << "Reference Efficiency: " << refEff << "%" << std::endl; - - // Tick the circuit with no threads - begin = std::chrono::high_resolution_clock::now(); - for ( int i = 0; i < 1000; ++i ) - { - circuit->Tick( Component::TickMode::Series ); - } - end = std::chrono::high_resolution_clock::now(); - auto eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); - - auto overhead = 100 - ( 100 * ( eff / refEff ) ); - std::cout << "0x Buffer Efficiency (Series Mode): " << eff << "% (-" << overhead << "%)" << std::endl; - REQUIRE( eff >= refEff * 0.25 * 0.90 ); - - // Tick the circuit with 1 thread, and check that no more ticks occurred - if ( std::thread::hardware_concurrency() < 1 ) - { - return; - } - circuit->SetBufferCount( 1 ); - - begin = std::chrono::high_resolution_clock::now(); - for ( int i = 0; i < 1000; ++i ) - { - circuit->Tick( Component::TickMode::Series ); - } - end = std::chrono::high_resolution_clock::now(); - eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); - - overhead = 100 - ( 100 * ( eff / refEff ) ); - std::cout << "1x Buffer Efficiency (Series Mode): " << eff << "% (-" << overhead << "%)" << std::endl; - REQUIRE( eff >= refEff * 0.25 * 0.90 ); - - // Tick the circuit with 2 threads, and check that more ticks occurred - if ( std::thread::hardware_concurrency() < 2 ) - { - return; - } - circuit->SetBufferCount( 2 ); - - begin = std::chrono::high_resolution_clock::now(); - for ( int i = 0; i < 1000; ++i ) - { - circuit->Tick( Component::TickMode::Series ); - } - end = std::chrono::high_resolution_clock::now(); - eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); - - overhead = 100 - ( 100 * ( eff / refEff ) ); - std::cout << "2x Buffer Efficiency (Series Mode): " << eff << "% (-" << overhead << "%)" << std::endl; - REQUIRE( eff >= refEff * 0.5 * 0.90 ); - - // Tick the circuit with 3 threads, and check that more ticks occurred - if ( std::thread::hardware_concurrency() < 4 ) - { - return; - } - circuit->SetBufferCount( 3 ); - - begin = std::chrono::high_resolution_clock::now(); - for ( int i = 0; i < 1000; ++i ) - { - circuit->Tick( Component::TickMode::Series ); - } - end = std::chrono::high_resolution_clock::now(); - eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); - - overhead = 100 - ( 100 * ( eff / refEff ) ); - std::cout << "3x Buffer Efficiency (Series Mode): " << eff << "% (-" << overhead << "%)" << std::endl; - REQUIRE( eff >= refEff * 0.75 * 0.90 ); - - // Tick the circuit with 4 threads, and check that more ticks occurred - if ( std::thread::hardware_concurrency() < 4 ) - { - return; - } - circuit->SetBufferCount( 4 ); - - begin = std::chrono::high_resolution_clock::now(); - for ( int i = 0; i < 1000; ++i ) - { - circuit->Tick( Component::TickMode::Series ); - } - end = std::chrono::high_resolution_clock::now(); - eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); - - overhead = 100 - ( 100 * ( eff / refEff ) ); - std::cout << "4x Buffer Efficiency (Series Mode): " << eff << "% (-" << overhead << "%)" << std::endl; - REQUIRE( eff >= refEff * 0.90 ); -} - -TEST_CASE( "StopAutoTickRegressionTest" ) -{ - auto circuit = std::make_shared(); - - auto counter1 = std::make_shared(); - auto counter2 = std::make_shared(); - auto counter3 = std::make_shared(); - auto counter4 = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter1 ); - circuit->AddComponent( counter2 ); - circuit->AddComponent( counter3 ); - circuit->AddComponent( counter4 ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter1, 0, probe, 0 ); - circuit->ConnectOutToIn( counter2, 0, probe, 1 ); - circuit->ConnectOutToIn( counter3, 0, probe, 2 ); - circuit->ConnectOutToIn( counter4, 0, probe, 3 ); - - circuit->SetBufferCount( std::thread::hardware_concurrency() ); - - circuit->StartAutoTick( Component::TickMode::Series ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - circuit->StopAutoTick(); - circuit->RemoveComponent( counter1 ); - circuit->RemoveComponent( counter2 ); - circuit->RemoveComponent( counter3 ); - circuit->RemoveComponent( counter4 ); - circuit->RemoveComponent( probe ); - - REQUIRE( !circuit->RemoveComponent( counter1 ) ); -} - -TEST_CASE( "ThreadAdjustmentTest" ) -{ - // Configure a counter circuit, then adjust the thread count while it's running - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter, 0, probe, 0 ); - circuit->ConnectOutToIn( counter, 0, probe, 1 ); - circuit->ConnectOutToIn( counter, 0, probe, 2 ); - circuit->ConnectOutToIn( counter, 0, probe, 3 ); - - // Tick the circuit for 100ms with 1 thread - circuit->StartAutoTick( Component::TickMode::Series ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - // Adjust the thread count while the circuit is running - circuit->SetBufferCount( 2 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->SetBufferCount( 0 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->SetBufferCount( 4 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->SetBufferCount( 2 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->SetBufferCount( 3 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->StopAutoTick(); - - REQUIRE( circuit->GetBufferCount() == 3 ); -} - -TEST_CASE( "WiringTest" ) -{ - // Configure a counter circuit, then re-wire it while it's running - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto probe = std::make_shared(); - - circuit->ConnectOutToIn( counter, 0, probe, 0 ); - circuit->ConnectOutToIn( probe, 0, counter, 0 ); - - // Tick the circuit for 100ms with 1 thread - circuit->StartAutoTick( Component::TickMode::Series ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - // Re-wire - - auto pass_s1 = std::make_shared(); - circuit->AddComponent( pass_s1 ); - - circuit->ConnectOutToIn( pass_s1, 0, probe, 0 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->ConnectOutToIn( counter, 0, pass_s1, 0 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - // Disconnect a component - - circuit->PauseAutoTick(); - probe->DisconnectInput( 0 ); - circuit->ResumeAutoTick(); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - circuit->DisconnectComponent( probe ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - // Wire in a new component - - auto pass_s2 = std::make_shared(); - circuit->AddComponent( pass_s2 ); - - circuit->ConnectOutToIn( probe, 0, counter, 0 ); - circuit->ConnectOutToIn( pass_s2, 0, probe, 0 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->ConnectOutToIn( pass_s1, 0, pass_s2, 0 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); +// auto pass_s1 = std::make_shared(); +// circuit->AddComponent( pass_s1 ); - circuit->StopAutoTick(); -} +// circuit->ConnectOutToIn( pass_s1, 0, probe, 0 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); -//================================================================================================= +// circuit->ConnectOutToIn( counter, 0, pass_s1, 0 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); -TEST_CASE( "SerialTest2" ) -{ - // Configure a circuit made up of a counter and 5 incrementers in series - auto circuit = std::make_shared(); +// // Disconnect a component - auto counter = std::make_shared(); - auto inc_s1 = std::make_shared( 1 ); - auto inc_s2 = std::make_shared( 2 ); - auto inc_s3 = std::make_shared( 3 ); - auto inc_s4 = std::make_shared( 4 ); - auto inc_s5 = std::make_shared( 5 ); - auto probe = std::make_shared(); - - circuit->AddComponent( counter ); - circuit->AddComponent( inc_s1 ); - circuit->AddComponent( inc_s2 ); - circuit->AddComponent( inc_s3 ); - circuit->AddComponent( inc_s4 ); - circuit->AddComponent( inc_s5 ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter, 0, inc_s1, 0 ); - circuit->ConnectOutToIn( inc_s1, 0, inc_s2, 0 ); - circuit->ConnectOutToIn( inc_s2, 0, inc_s3, 0 ); - circuit->ConnectOutToIn( inc_s3, 0, inc_s4, 0 ); - circuit->ConnectOutToIn( inc_s4, 0, inc_s5, 0 ); - circuit->ConnectOutToIn( inc_s5, 0, probe, 0 ); - - // Tick the circuit 100 times - for ( int i = 0; i < 100; ++i ) - { - circuit->Tick( Component::TickMode::Parallel ); - } -} +// circuit->PauseAutoTick(); +// probe->DisconnectInput( 0 ); +// circuit->ResumeAutoTick(); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); +// circuit->DisconnectComponent( probe ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); -TEST_CASE( "ParallelTest2" ) -{ - // Configure a circuit made up of a counter and 5 incrementers in parallel - auto circuit = std::make_shared(); +// // Wire in a new component - auto counter = std::make_shared(); - auto inc_p1 = std::make_shared( 1 ); - auto inc_p2 = std::make_shared( 2 ); - auto inc_p3 = std::make_shared( 3 ); - auto inc_p4 = std::make_shared( 4 ); - auto inc_p5 = std::make_shared( 5 ); - auto probe = std::make_shared(); - - circuit->AddComponent( counter ); - circuit->AddComponent( inc_p1 ); - circuit->AddComponent( inc_p2 ); - circuit->AddComponent( inc_p3 ); - circuit->AddComponent( inc_p4 ); - circuit->AddComponent( inc_p5 ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter, 0, inc_p1, 0 ); - circuit->ConnectOutToIn( counter, 0, inc_p2, 0 ); - circuit->ConnectOutToIn( counter, 0, inc_p3, 0 ); - circuit->ConnectOutToIn( counter, 0, inc_p4, 0 ); - circuit->ConnectOutToIn( counter, 0, inc_p5, 0 ); - circuit->ConnectOutToIn( inc_p1, 0, probe, 0 ); - circuit->ConnectOutToIn( inc_p2, 0, probe, 1 ); - circuit->ConnectOutToIn( inc_p3, 0, probe, 2 ); - circuit->ConnectOutToIn( inc_p4, 0, probe, 3 ); - circuit->ConnectOutToIn( inc_p5, 0, probe, 4 ); - - // Tick the circuit for 100ms with 3 threads - circuit->SetBufferCount( 3 ); - circuit->StartAutoTick( Component::TickMode::Parallel ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - circuit->StopAutoTick(); -} +// auto pass_s2 = std::make_shared(); +// circuit->AddComponent( pass_s2 ); -TEST_CASE( "BranchSyncTest2" ) -{ - // Configure a circuit made up of 3 parallel branches of 4, 2, and 1 component(s) respectively - auto circuit = std::make_shared(); +// circuit->ConnectOutToIn( probe, 0, counter, 0 ); +// circuit->ConnectOutToIn( pass_s2, 0, probe, 0 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - auto counter = std::make_shared(); - auto inc_p1_s1 = std::make_shared(); - auto inc_p1_s2 = std::make_shared(); - auto inc_p1_s3 = std::make_shared(); - auto inc_p1_s4 = std::make_shared(); - auto inc_p2_s1 = std::make_shared(); - auto inc_p2_s2 = std::make_shared(); - auto inc_p3_s1 = std::make_shared(); - auto probe = std::make_shared(); +// circuit->ConnectOutToIn( pass_s1, 0, pass_s2, 0 ); +// std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - circuit->AddComponent( counter ); +// circuit->StopAutoTick(); +// } - circuit->AddComponent( inc_p1_s1 ); - circuit->AddComponent( inc_p1_s2 ); - circuit->AddComponent( inc_p1_s3 ); - circuit->AddComponent( inc_p1_s4 ); +// //================================================================================================= - circuit->AddComponent( inc_p2_s1 ); - circuit->AddComponent( inc_p2_s2 ); +// TEST_CASE( "ThreadStopRegressionTest" ) +// { +// // Configure a circuit made up of 3 parallel branches of 4, 2, and 1 component(s) respectively +// auto circuit = std::make_shared(); - circuit->AddComponent( inc_p3_s1 ); +// auto counter = std::make_shared(); +// auto inc_p1_s1 = std::make_shared(); +// auto inc_p1_s2 = std::make_shared(); +// auto inc_p1_s3 = std::make_shared(); +// auto inc_p1_s4 = std::make_shared(); +// auto inc_p2_s1 = std::make_shared(); +// auto inc_p2_s2 = std::make_shared(); +// auto inc_p3_s1 = std::make_shared(); +// auto probe = std::make_shared(); - circuit->AddComponent( probe ); +// circuit->AddComponent( counter ); - // Wire branch 1 - circuit->ConnectOutToIn( counter, 0, inc_p1_s1, 0 ); - circuit->ConnectOutToIn( inc_p1_s1, 0, inc_p1_s2, 0 ); - circuit->ConnectOutToIn( inc_p1_s2, 0, inc_p1_s3, 0 ); - circuit->ConnectOutToIn( inc_p1_s3, 0, inc_p1_s4, 0 ); - circuit->ConnectOutToIn( inc_p1_s4, 0, probe, 0 ); +// circuit->AddComponent( inc_p1_s1 ); +// circuit->AddComponent( inc_p1_s2 ); +// circuit->AddComponent( inc_p1_s3 ); +// circuit->AddComponent( inc_p1_s4 ); - // Wire branch 2 - circuit->ConnectOutToIn( counter, 0, inc_p2_s1, 0 ); - circuit->ConnectOutToIn( inc_p2_s1, 0, inc_p2_s2, 0 ); - circuit->ConnectOutToIn( inc_p2_s2, 0, probe, 1 ); +// circuit->AddComponent( inc_p2_s1 ); +// circuit->AddComponent( inc_p2_s2 ); - // Wire branch 3 - circuit->ConnectOutToIn( counter, 0, inc_p3_s1, 0 ); - circuit->ConnectOutToIn( inc_p3_s1, 0, probe, 2 ); +// circuit->AddComponent( inc_p3_s1 ); - // Tick the circuit 100 times - for ( int i = 0; i < 100; ++i ) - { - circuit->Tick( Component::TickMode::Parallel ); - } -} +// circuit->AddComponent( probe ); -TEST_CASE( "FeedbackTest2" ) -{ - // Configure a circuit made up of an adder that adds a counter to its own previous output - auto circuit = std::make_shared(); +// // Wire branch 1 +// circuit->ConnectOutToIn( counter, 0, inc_p1_s1, 0 ); +// circuit->ConnectOutToIn( inc_p1_s1, 0, inc_p1_s2, 0 ); +// circuit->ConnectOutToIn( inc_p1_s2, 0, inc_p1_s3, 0 ); +// circuit->ConnectOutToIn( inc_p1_s3, 0, inc_p1_s4, 0 ); +// circuit->ConnectOutToIn( inc_p1_s4, 0, probe, 0 ); - auto counter = std::make_shared(); - auto adder = std::make_shared(); - auto passthrough = std::make_shared(); - auto probe = std::make_shared(); +// // Wire branch 2 +// circuit->ConnectOutToIn( counter, 0, inc_p2_s1, 0 ); +// circuit->ConnectOutToIn( inc_p2_s1, 0, inc_p2_s2, 0 ); +// circuit->ConnectOutToIn( inc_p2_s2, 0, probe, 1 ); - circuit->AddComponent( counter ); - circuit->AddComponent( adder ); - circuit->AddComponent( passthrough ); - circuit->AddComponent( probe ); +// // Wire branch 3 +// circuit->ConnectOutToIn( counter, 0, inc_p3_s1, 0 ); +// circuit->ConnectOutToIn( inc_p3_s1, 0, probe, 2 ); - circuit->ConnectOutToIn( counter, 0, adder, 0 ); - circuit->ConnectOutToIn( adder, 0, passthrough, 0 ); +// // Tick the circuit 100 times +// for ( int i = 0; i < 100; ++i ) +// { +// circuit->Tick( Component::TickMode::Series ); +// circuit->Tick( Component::TickMode::Parallel ); +// } - circuit->ConnectOutToIn( passthrough, 0, adder, 1 ); +// circuit->SetBufferCount( 30 ); - circuit->ConnectOutToIn( adder, 0, probe, 0 ); +// for ( int i = 0; i < 100; ++i ) +// { +// circuit->Tick( Component::TickMode::Series ); +// circuit->Tick( Component::TickMode::Parallel ); +// } +// } - // Tick the circuit 100 times - for ( int i = 0; i < 100; ++i ) - { - circuit->Tick( Component::TickMode::Parallel ); - } -} +// TEST_CASE( "DisconnectComponentRegressionTest" ) +// { +// auto circuit = std::make_shared(); -TEST_CASE( "FeedbackTestNoCircuit2" ) -{ - auto counter = std::make_shared(); - auto adder = std::make_shared(); - auto passthrough = std::make_shared(); - auto probe = std::make_shared(); +// auto counter = std::make_shared(); +// auto probe = std::make_shared(); - adder->ConnectInput( counter, 0, 0 ); - passthrough->ConnectInput( adder, 0, 0 ); +// circuit->AddComponent( counter ); +// circuit->AddComponent( probe ); - adder->ConnectInput( passthrough, 0, 1 ); +// circuit->ConnectOutToIn( counter, 0, probe, 0 ); +// circuit->ConnectOutToIn( counter, 0, probe, 1 ); - probe->ConnectInput( adder, 0, 0 ); +// circuit->DisconnectComponent( counter ); - // Tick the circuit 100 times - for ( int i = 0; i < 100; ++i ) - { - counter->Tick( Component::TickMode::Parallel ); - adder->Tick( Component::TickMode::Parallel ); - passthrough->Tick( Component::TickMode::Parallel ); - probe->Tick( Component::TickMode::Parallel ); - - counter->Reset( Component::TickMode::Parallel ); - adder->Reset( Component::TickMode::Parallel ); - passthrough->Reset( Component::TickMode::Parallel ); - probe->Reset( Component::TickMode::Parallel ); - } -} +// circuit->Tick( Component::TickMode::Series ); +// } + +// TEST_CASE( "AutoTickOnCircuitDestructRegressionTest" ) +// { +// auto circuit = std::make_shared(); +// auto counter = std::make_shared(); +// circuit->AddComponent( counter ); +// circuit->SetBufferCount( 3 ); + +// REQUIRE( counter->Count() == 0 ); +// circuit->Tick( Component::TickMode::Series ); +// circuit->Tick( Component::TickMode::Series ); +// circuit->Tick( Component::TickMode::Series ); +// circuit->Tick( Component::TickMode::Series ); -TEST_CASE( "RefCountResetRegressionTest2" ) -{ - auto circuit = std::make_shared(); - auto feedback = std::make_shared( 2 ); - - circuit->AddComponent( feedback ); - circuit->SetBufferCount( 2 ); - - feedback->ConnectInput( feedback, 0, 0 ); - feedback->SetValidInputs( 1 ); - - circuit->StartAutoTick( Component::TickMode::Parallel ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - circuit->PauseAutoTick(); - - feedback->ConnectInput( feedback, 0, 1 ); - feedback->ConnectInput( feedback, 0, 2 ); - feedback->ConnectInput( feedback, 0, 3 ); - feedback->SetValidInputs( 4 ); - - circuit->StartAutoTick( Component::TickMode::Parallel ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - circuit->PauseAutoTick(); - - feedback->ConnectInput( feedback, 0, 4 ); - feedback->ConnectInput( feedback, 0, 5 ); - feedback->ConnectInput( feedback, 0, 6 ); - feedback->ConnectInput( feedback, 0, 7 ); - feedback->ConnectInput( feedback, 0, 8 ); - feedback->ConnectInput( feedback, 0, 9 ); - feedback->SetValidInputs( 10 ); - - circuit->StartAutoTick( Component::TickMode::Parallel ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - circuit->StopAutoTick(); -} - -TEST_CASE( "NoOutputTest2" ) -{ - // Configure a circuit where the counter responds sporadically - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter, 0, probe, 0 ); - - // Tick the circuit 100 times - for ( int i = 0; i < 100; ++i ) - { - circuit->Tick( Component::TickMode::Parallel ); - } -} - -TEST_CASE( "ChangingOutputTest2" ) -{ - // Configure a circuit whereby a component outputs varying types (int, float, string, vector) - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter, 0, probe, 0 ); - - // Tick the circuit 100 times - for ( int i = 0; i < 100; ++i ) - { - circuit->Tick( Component::TickMode::Parallel ); - } -} - -TEST_CASE( "ThreadPerformanceTest2" ) -{ - double cores = std::thread::hardware_concurrency(); - cores = cores == 3.0 ? 2.0 : cores; - cores = cores > 4.0 ? 4.0 : cores; - auto effFrac = cores / 4.0; - - // Configure a circuit made up of 4 parallel counters, then adjust the thread count - auto circuit = std::make_shared(); - - auto counter1 = std::make_shared(); - auto counter2 = std::make_shared(); - auto counter3 = std::make_shared(); - auto counter4 = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter1 ); - circuit->AddComponent( counter2 ); - circuit->AddComponent( counter3 ); - circuit->AddComponent( counter4 ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter1, 0, probe, 0 ); - circuit->ConnectOutToIn( counter2, 0, probe, 1 ); - circuit->ConnectOutToIn( counter3, 0, probe, 2 ); - circuit->ConnectOutToIn( counter4, 0, probe, 3 ); - - // Tick the circuit with no threads - auto begin = std::chrono::high_resolution_clock::now(); - for ( int i = 0; i < 1000; ++i ) - { - circuit->Tick( Component::TickMode::Parallel ); - } - auto end = std::chrono::high_resolution_clock::now(); - auto eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); - - auto overhead = 100 - ( 100 * ( eff / refEff ) ); - std::cout << "0x Buffer Efficiency (Parallel Mode): " << eff << "% (-" << overhead << "%)" << std::endl; - REQUIRE( eff >= refEff * effFrac * 0.85 ); - - // Tick the circuit with 1 thread, and check that no more ticks occurred - if ( std::thread::hardware_concurrency() < 1 ) - { - return; - } - circuit->SetBufferCount( 1 ); - - begin = std::chrono::high_resolution_clock::now(); - for ( int i = 0; i < 1000; ++i ) - { - circuit->Tick( Component::TickMode::Parallel ); - } - end = std::chrono::high_resolution_clock::now(); - eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); - - overhead = 100 - ( 100 * ( eff / refEff ) ); - std::cout << "1x Buffer Efficiency (Parallel Mode): " << eff << "% (-" << overhead << "%)" << std::endl; - REQUIRE( eff >= refEff * effFrac * 0.85 ); - - // Tick the circuit with 2 threads, and check that more ticks occurred - if ( std::thread::hardware_concurrency() < 2 ) - { - return; - } - circuit->SetBufferCount( 2 ); - - begin = std::chrono::high_resolution_clock::now(); - for ( int i = 0; i < 1000; ++i ) - { - circuit->Tick( Component::TickMode::Parallel ); - } - end = std::chrono::high_resolution_clock::now(); - eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); - - overhead = 100 - ( 100 * ( eff / refEff ) ); - std::cout << "2x Buffer Efficiency (Parallel Mode): " << eff << "% (-" << overhead << "%)" << std::endl; - REQUIRE( eff >= refEff * effFrac * 0.90 ); - - // Tick the circuit with 3 threads, and check that more ticks occurred - if ( std::thread::hardware_concurrency() < 4 ) - { - return; - } - circuit->SetBufferCount( 3 ); - - begin = std::chrono::high_resolution_clock::now(); - for ( int i = 0; i < 1000; ++i ) - { - circuit->Tick( Component::TickMode::Parallel ); - } - end = std::chrono::high_resolution_clock::now(); - eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); - - overhead = 100 - ( 100 * ( eff / refEff ) ); - std::cout << "3x Buffer Efficiency (Parallel Mode): " << eff << "% (-" << overhead << "%)" << std::endl; - REQUIRE( eff >= refEff * effFrac * 0.90 ); - - // Tick the circuit with 4 threads, and check that more ticks occurred - if ( std::thread::hardware_concurrency() < 4 ) - { - return; - } - circuit->SetBufferCount( 4 ); +// circuit = nullptr; + +// REQUIRE( counter->Count() == 4 ); +// } + +// TEST_CASE( "AutoTickOnBuffersUpdateRegressionTest" ) +// { +// auto circuit = std::make_shared(); +// auto counter = std::make_shared(); +// circuit->AddComponent( counter ); +// circuit->SetBufferCount( 3 ); + +// REQUIRE( counter->Count() == 0 ); +// circuit->Tick( Component::TickMode::Series ); +// circuit->Tick( Component::TickMode::Series ); +// circuit->Tick( Component::TickMode::Series ); +// circuit->Tick( Component::TickMode::Series ); + +// circuit->SetBufferCount( 2 ); - begin = std::chrono::high_resolution_clock::now(); - for ( int i = 0; i < 1000; ++i ) - { - circuit->Tick( Component::TickMode::Parallel ); - } - end = std::chrono::high_resolution_clock::now(); - eff = 100000.0 / std::chrono::duration_cast( end - begin ).count(); - - overhead = 100 - ( 100 * ( eff / refEff ) ); - std::cout << "4x Buffer Efficiency (Parallel Mode): " << eff << "% (-" << overhead << "%)" << std::endl; - REQUIRE( eff >= refEff * effFrac * 0.90 ); -} - -TEST_CASE( "StopAutoTickRegressionTest2" ) -{ - auto circuit = std::make_shared(); - - auto counter1 = std::make_shared(); - auto counter2 = std::make_shared(); - auto counter3 = std::make_shared(); - auto counter4 = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter1 ); - circuit->AddComponent( counter2 ); - circuit->AddComponent( counter3 ); - circuit->AddComponent( counter4 ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter1, 0, probe, 0 ); - circuit->ConnectOutToIn( counter2, 0, probe, 1 ); - circuit->ConnectOutToIn( counter3, 0, probe, 2 ); - circuit->ConnectOutToIn( counter4, 0, probe, 3 ); - - circuit->SetBufferCount( std::thread::hardware_concurrency() ); - - circuit->StartAutoTick( Component::TickMode::Parallel ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - circuit->StopAutoTick(); - circuit->RemoveComponent( counter1 ); - circuit->RemoveComponent( counter2 ); - circuit->RemoveComponent( counter3 ); - circuit->RemoveComponent( counter4 ); - circuit->RemoveComponent( probe ); -} - -TEST_CASE( "ThreadAdjustmentTest2" ) -{ - // Configure a counter circuit, then adjust the thread count while it's running - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter, 0, probe, 0 ); - circuit->ConnectOutToIn( counter, 0, probe, 1 ); - circuit->ConnectOutToIn( counter, 0, probe, 2 ); - circuit->ConnectOutToIn( counter, 0, probe, 3 ); - - // Tick the circuit for 100ms with 1 thread - circuit->StartAutoTick( Component::TickMode::Parallel ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - // Adjust the thread count while the circuit is running - circuit->SetBufferCount( 2 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->SetBufferCount( 0 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->SetBufferCount( 4 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->SetBufferCount( 2 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->SetBufferCount( 3 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->StopAutoTick(); - - REQUIRE( circuit->GetBufferCount() == 3 ); -} - -TEST_CASE( "WiringTest2" ) -{ - // Configure a counter circuit, then re-wire it while it's running - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto probe = std::make_shared(); - - circuit->ConnectOutToIn( counter, 0, probe, 0 ); - circuit->ConnectOutToIn( probe, 0, counter, 0 ); - - // Tick the circuit for 100ms with 1 thread - circuit->StartAutoTick( Component::TickMode::Parallel ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - // Re-wire - - auto pass_s1 = std::make_shared(); - circuit->AddComponent( pass_s1 ); - - circuit->ConnectOutToIn( pass_s1, 0, probe, 0 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->ConnectOutToIn( counter, 0, pass_s1, 0 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - // Disconnect a component - - circuit->PauseAutoTick(); - probe->DisconnectInput( 0 ); - circuit->ResumeAutoTick(); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - circuit->DisconnectComponent( probe ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - // Wire in a new component - - auto pass_s2 = std::make_shared(); - circuit->AddComponent( pass_s2 ); - - circuit->ConnectOutToIn( probe, 0, counter, 0 ); - circuit->ConnectOutToIn( pass_s2, 0, probe, 0 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->ConnectOutToIn( pass_s1, 0, pass_s2, 0 ); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - - circuit->StopAutoTick(); -} - -//================================================================================================= - -TEST_CASE( "ThreadStopRegressionTest" ) -{ - // Configure a circuit made up of 3 parallel branches of 4, 2, and 1 component(s) respectively - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto inc_p1_s1 = std::make_shared(); - auto inc_p1_s2 = std::make_shared(); - auto inc_p1_s3 = std::make_shared(); - auto inc_p1_s4 = std::make_shared(); - auto inc_p2_s1 = std::make_shared(); - auto inc_p2_s2 = std::make_shared(); - auto inc_p3_s1 = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter ); - - circuit->AddComponent( inc_p1_s1 ); - circuit->AddComponent( inc_p1_s2 ); - circuit->AddComponent( inc_p1_s3 ); - circuit->AddComponent( inc_p1_s4 ); - - circuit->AddComponent( inc_p2_s1 ); - circuit->AddComponent( inc_p2_s2 ); - - circuit->AddComponent( inc_p3_s1 ); - - circuit->AddComponent( probe ); - - // Wire branch 1 - circuit->ConnectOutToIn( counter, 0, inc_p1_s1, 0 ); - circuit->ConnectOutToIn( inc_p1_s1, 0, inc_p1_s2, 0 ); - circuit->ConnectOutToIn( inc_p1_s2, 0, inc_p1_s3, 0 ); - circuit->ConnectOutToIn( inc_p1_s3, 0, inc_p1_s4, 0 ); - circuit->ConnectOutToIn( inc_p1_s4, 0, probe, 0 ); - - // Wire branch 2 - circuit->ConnectOutToIn( counter, 0, inc_p2_s1, 0 ); - circuit->ConnectOutToIn( inc_p2_s1, 0, inc_p2_s2, 0 ); - circuit->ConnectOutToIn( inc_p2_s2, 0, probe, 1 ); - - // Wire branch 3 - circuit->ConnectOutToIn( counter, 0, inc_p3_s1, 0 ); - circuit->ConnectOutToIn( inc_p3_s1, 0, probe, 2 ); - - // Tick the circuit 100 times - for ( int i = 0; i < 100; ++i ) - { - circuit->Tick( Component::TickMode::Series ); - circuit->Tick( Component::TickMode::Parallel ); - } - - circuit->SetBufferCount( 30 ); - - for ( int i = 0; i < 100; ++i ) - { - circuit->Tick( Component::TickMode::Series ); - circuit->Tick( Component::TickMode::Parallel ); - } -} - -TEST_CASE( "DisconnectComponentRegressionTest" ) -{ - auto circuit = std::make_shared(); - - auto counter = std::make_shared(); - auto probe = std::make_shared(); - - circuit->AddComponent( counter ); - circuit->AddComponent( probe ); - - circuit->ConnectOutToIn( counter, 0, probe, 0 ); - circuit->ConnectOutToIn( counter, 0, probe, 1 ); - - circuit->DisconnectComponent( counter ); - - circuit->Tick( Component::TickMode::Series ); -} - -TEST_CASE( "AutoTickOnCircuitDestructRegressionTest" ) -{ - auto circuit = std::make_shared(); - auto counter = std::make_shared(); - circuit->AddComponent( counter ); - circuit->SetBufferCount( 3 ); - - REQUIRE( counter->Count() == 0 ); - circuit->Tick( Component::TickMode::Series ); - circuit->Tick( Component::TickMode::Series ); - circuit->Tick( Component::TickMode::Series ); - circuit->Tick( Component::TickMode::Series ); - - circuit = nullptr; - - REQUIRE( counter->Count() == 4 ); -} - -TEST_CASE( "AutoTickOnBuffersUpdateRegressionTest" ) -{ - auto circuit = std::make_shared(); - auto counter = std::make_shared(); - circuit->AddComponent( counter ); - circuit->SetBufferCount( 3 ); - - REQUIRE( counter->Count() == 0 ); - circuit->Tick( Component::TickMode::Series ); - circuit->Tick( Component::TickMode::Series ); - circuit->Tick( Component::TickMode::Series ); - circuit->Tick( Component::TickMode::Series ); - - circuit->SetBufferCount( 2 ); - - REQUIRE( counter->Count() == 4 ); -} +// REQUIRE( counter->Count() == 4 ); +// } TEST_CASE( "TenThousandComponents" ) { From 071c14f158036d3dab4bbca10b75e1080b08cebd Mon Sep 17 00:00:00 2001 From: Marcus Tomlinson Date: Sun, 27 Aug 2023 20:28:44 +0100 Subject: [PATCH 10/17] Clean up Component.cpp --- src/Component.cpp | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/src/Component.cpp b/src/Component.cpp index b120167d..e645a7fc 100644 --- a/src/Component.cpp +++ b/src/Component.cpp @@ -47,22 +47,9 @@ class Component enum class TickStatus { NotTicked, - TickStarted, Ticking }; - struct MovableMutex - { - MovableMutex() = default; - - // cppcheck-suppress missingMemberCopy - MovableMutex( MovableMutex&& ) - { - } - - std::mutex mutex; - }; - struct MovableAtomicFlag { MovableAtomicFlag() = default; @@ -95,7 +82,6 @@ class Component std::vector outputBuses; std::vector>> refs; // ref_total:ref_counter per output, per buffer - std::vector> refMutexes; std::vector inputWires; @@ -229,7 +215,6 @@ void Component::SetBufferCount( int bufferCount ) p->releaseFlags.resize( bufferCount ); p->refs.resize( bufferCount ); - p->refMutexes.resize( bufferCount ); // init vector values for ( int i = 0; i < bufferCount; ++i ) @@ -247,8 +232,6 @@ void Component::SetBufferCount( int bufferCount ) // sync output reference counts p->refs[i][j] = p->refs[0][j]; } - - p->refMutexes[i].resize( p->refMutexes[0].size() ); } p->releaseFlags[0].flag.clear(); @@ -345,10 +328,6 @@ void Component::SetOutputCount_( int outputCount, const std::vector { ref.resize( outputCount ); } - for ( auto& refMutexes : p->refMutexes ) - { - refMutexes.resize( outputCount ); - } } void internal::Component::WaitForRelease( int threadNo ) @@ -391,15 +370,13 @@ void internal::Component::GetOutput( int bufferNo, int fromOutput, int toInput, } else if ( ++ref.second != ref.first ) { + // this is not the final reference, copy the signal toBus.SetSignal( toInput, signal ); return; } - else - { - // this is the final reference, reset the counter, move the signal - ref.second = 0; - } + // this is the final reference, reset the counter, move the signal + ref.second = 0; toBus.MoveSignal( toInput, signal ); } From 6a5cc3e8b3fc571291372ec4a43afa66c2be5401 Mon Sep 17 00:00:00 2001 From: Marcus Tomlinson Date: Sun, 27 Aug 2023 20:47:08 +0100 Subject: [PATCH 11/17] Merge branch 'master' into std_any-test --- CHANGES | 5 + CMakeLists.txt | 4 +- docs/Doxyfile | 2 +- docs/html/_auto_tick_thread_8h_source.html | 53 +- docs/html/_circuit_8h_source.html | 72 +-- docs/html/_circuit_thread_8h_source.html | 29 +- docs/html/_common_8h_source.html | 48 +- docs/html/_component_8h_source.html | 107 ++- docs/html/_d_s_patch_8h_source.html | 2 +- docs/html/_plugin_8h_source.html | 2 +- docs/html/_signal_bus_8h_source.html | 2 +- docs/html/_wire_8h_source.html | 2 +- docs/html/annotated.html | 13 +- .../class_d_s_patch_1_1_circuit-members.html | 6 +- docs/html/class_d_s_patch_1_1_circuit.html | 19 +- ...class_d_s_patch_1_1_component-members.html | 9 +- docs/html/class_d_s_patch_1_1_component.html | 48 +- .../class_d_s_patch_1_1_plugin-members.html | 2 +- docs/html/class_d_s_patch_1_1_plugin.html | 2 +- ...lass_d_s_patch_1_1_signal_bus-members.html | 2 +- docs/html/class_d_s_patch_1_1_signal_bus.html | 2 +- ...internal_1_1_auto_tick_thread-members.html | 15 +- ...atch_1_1internal_1_1_auto_tick_thread.html | 11 +- ..._1internal_1_1_circuit_thread-members.html | 4 +- ..._patch_1_1internal_1_1_circuit_thread.html | 8 +- docs/html/classes.html | 4 +- .../dir_3756d50f4003bc63fa3fe49460f9c79d.html | 4 +- .../dir_68267d1309a1af8e8297ef4c3efbcdba.html | 2 +- .../dir_96ae4afe4ae1b3c2e5b248f6fc6b60cd.html | 2 +- .../dir_d44c64559bbebec7f509842c48db8b23.html | 2 +- docs/html/files.html | 5 +- docs/html/index.html | 5 +- docs/html/search/all_1.js | 3 +- docs/html/search/classes_1.js | 3 +- ..._s_patch_1_1internal_1_1_wire-members.html | 2 +- ...struct_d_s_patch_1_1internal_1_1_wire.html | 2 +- include/DSPatch.h | 6 +- include/dspatch/Circuit.h | 10 +- include/dspatch/Component.h | 14 +- meson.build | 1 - src/Circuit.cpp | 16 +- src/Component.cpp | 202 ++---- src/internal/AutoTickThread.cpp | 10 +- src/internal/AutoTickThread.h | 5 +- src/internal/CircuitThread.cpp | 10 +- src/internal/CircuitThread.h | 3 +- src/internal/ComponentThread.cpp | 138 ---- src/internal/ComponentThread.h | 85 --- tests/main.cpp | 610 ++---------------- 49 files changed, 331 insertions(+), 1282 deletions(-) delete mode 100644 src/internal/ComponentThread.cpp delete mode 100644 src/internal/ComponentThread.h diff --git a/CHANGES b/CHANGES index 54417eb6..f583f5b7 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +v.9.7.0 (27 August 2023) + - Improved tick performance by removing non-scalable "Parallel" mode. + - Replaced custom YieldThread() method with std::this_thread::yield(). + - Updated fast_any submodule (incl. inline initialization of value type). + v.9.6.1 (24 August 2023) - Reverted some "optimizations" that actually made things slower. diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a8d958b..c7fcc2ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,8 +8,8 @@ set(CMAKE_CXX_EXTENSIONS OFF) # Set version information. set(DSPATCH_MAJOR 9) -set(DSPATCH_MINOR 6) -set(DSPATCH_MICRO 1) +set(DSPATCH_MINOR 7) +set(DSPATCH_MICRO 0) if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W4") diff --git a/docs/Doxyfile b/docs/Doxyfile index 6d72b4e6..c4e91b0f 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -32,7 +32,7 @@ PROJECT_NAME = DSPatch # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = v.9.6.1 +PROJECT_NUMBER = v.9.7.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer diff --git a/docs/html/_auto_tick_thread_8h_source.html b/docs/html/_auto_tick_thread_8h_source.html index f9aa4238..c89c63a0 100644 --- a/docs/html/_auto_tick_thread_8h_source.html +++ b/docs/html/_auto_tick_thread_8h_source.html @@ -22,7 +22,7 @@ Logo -
DSPatch v.9.6.1 +
DSPatch v.9.7.0
@@ -127,33 +127,30 @@
58
-
59 DSPatch::Component::TickMode Mode() const;
-
60
-
61 bool IsStopped() const;
-
62 bool IsPaused() const;
-
63
-
64 void Start( DSPatch::Circuit* circuit, DSPatch::Component::TickMode mode );
-
65 void Stop();
-
66 void Pause();
-
67 void Resume();
-
68
-
69private:
-
70 void _Run();
-
71
-
72private:
-
73 DSPatch::Component::TickMode _mode = DSPatch::Component::TickMode::Series;
-
74 std::thread _thread;
-
75 DSPatch::Circuit* _circuit = nullptr;
-
76 bool _stop = false;
-
77 bool _pause = false;
-
78 bool _stopped = true;
-
79 std::mutex _resumeMutex;
-
80 std::condition_variable _resumeCondt, _pauseCondt;
-
81};
-
82
-
83} // namespace internal
-
84} // namespace DSPatch
-
Workspace for adding and routing components.
Definition Circuit.h:67
+
59 bool IsStopped() const;
+
60 bool IsPaused() const;
+
61
+
62 void Start( DSPatch::Circuit* circuit );
+
63 void Stop();
+
64 void Pause();
+
65 void Resume();
+
66
+
67private:
+
68 void _Run();
+
69
+
70private:
+
71 std::thread _thread;
+
72 DSPatch::Circuit* _circuit = nullptr;
+
73 bool _stop = false;
+
74 bool _pause = false;
+
75 bool _stopped = true;
+
76 std::mutex _resumeMutex;
+
77 std::condition_variable _resumeCondt, _pauseCondt;
+
78};
+
79
+
80} // namespace internal
+
81} // namespace DSPatch
+
Workspace for adding and routing components.
Definition Circuit.h:61
Thread class for auto-ticking a circuit.
diff --git a/docs/html/_circuit_8h_source.html b/docs/html/_circuit_8h_source.html index fe32d8be..c1f0e686 100644 --- a/docs/html/_circuit_8h_source.html +++ b/docs/html/_circuit_8h_source.html @@ -22,7 +22,7 @@ Logo -
DSPatch v.9.6.1 +
DSPatch v.9.7.0
@@ -118,42 +118,42 @@
39}
40
42
-
66class DLLEXPORT Circuit final
-
67{
-
68public:
-
69 NONCOPYABLE( Circuit );
-
70
-
71 Circuit();
-
72 ~Circuit();
-
73
-
74 bool AddComponent( const Component::SPtr& component );
-
75
-
76 bool RemoveComponent( const Component::SPtr& component );
-
77 void RemoveAllComponents();
-
78
-
79 int GetComponentCount() const;
-
80
-
81 bool ConnectOutToIn( const Component::SPtr& fromComponent, int fromOutput, const Component::SPtr& toComponent, int toInput );
+
60class DLLEXPORT Circuit final
+
61{
+
62public:
+
63 NONCOPYABLE( Circuit );
+
64
+
65 Circuit();
+
66 ~Circuit();
+
67
+
68 bool AddComponent( const Component::SPtr& component );
+
69
+
70 bool RemoveComponent( const Component::SPtr& component );
+
71 void RemoveAllComponents();
+
72
+
73 int GetComponentCount() const;
+
74
+
75 bool ConnectOutToIn( const Component::SPtr& fromComponent, int fromOutput, const Component::SPtr& toComponent, int toInput );
+
76
+
77 bool DisconnectComponent( const Component::SPtr& component );
+
78 void DisconnectAllComponents();
+
79
+
80 void SetBufferCount( int bufferCount );
+
81 int GetBufferCount() const;
82
-
83 bool DisconnectComponent( const Component::SPtr& component );
-
84 void DisconnectAllComponents();
-
85
-
86 void SetBufferCount( int bufferCount );
-
87 int GetBufferCount() const;
-
88
-
89 void Tick( Component::TickMode mode = Component::TickMode::Series );
-
90
-
91 void StartAutoTick( Component::TickMode mode = Component::TickMode::Series );
-
92 void StopAutoTick();
-
93 void PauseAutoTick();
-
94 void ResumeAutoTick();
-
95
-
96private:
-
97 internal::Circuit* p;
-
98};
-
99
-
100} // namespace DSPatch
-
Workspace for adding and routing components.
Definition Circuit.h:67
+
83 void Tick();
+
84
+
85 void StartAutoTick();
+
86 void StopAutoTick();
+
87 void PauseAutoTick();
+
88 void ResumeAutoTick();
+
89
+
90private:
+
91 internal::Circuit* p;
+
92};
+
93
+
94} // namespace DSPatch
+
Workspace for adding and routing components.
Definition Circuit.h:61