108 |
109 |
110 |
--------------------------------------------------------------------------------
/docs/html/folderclosed.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
12 |
--------------------------------------------------------------------------------
/docs/html/folderclosedd.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
12 |
--------------------------------------------------------------------------------
/docs/html/folderopen.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
18 |
--------------------------------------------------------------------------------
/docs/html/folderopend.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
13 |
--------------------------------------------------------------------------------
/docs/html/heartbeat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cross-platform/dspatch/29022646fbae45196197a0f871d5c8d2d288e77a/docs/html/heartbeat.png
--------------------------------------------------------------------------------
/docs/html/menu.js:
--------------------------------------------------------------------------------
1 | /*
2 | @licstart The following is the entire license notice for the JavaScript code in this file.
3 |
4 | The MIT License (MIT)
5 |
6 | Copyright (C) 1997-2020 by Dimitri van Heesch
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software
9 | and associated documentation files (the "Software"), to deal in the Software without restriction,
10 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
11 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all copies or
15 | substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
18 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 |
23 | @licend The above is the entire license notice for the JavaScript code in this file
24 | */
25 | function initMenu(relPath,searchEnabled,serverSide,searchPage,search,treeview) {
26 | function makeTree(data,relPath) {
27 | let result='';
28 | if ('children' in data) {
29 | result+='
';
30 | for (let i in data.children) {
31 | let url;
32 | const link = data.children[i].url;
33 | if (link.substring(0,1)=='^') {
34 | url = link.substring(1);
35 | } else {
36 | url = relPath+link;
37 | }
38 | result+='
87 |
88 |
89 | Generated by 1.9.7
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/docs/html/sync_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cross-platform/dspatch/29022646fbae45196197a0f871d5c8d2d288e77a/docs/html/sync_off.png
--------------------------------------------------------------------------------
/docs/html/sync_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cross-platform/dspatch/29022646fbae45196197a0f871d5c8d2d288e77a/docs/html/sync_on.png
--------------------------------------------------------------------------------
/docs/html/tab_a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cross-platform/dspatch/29022646fbae45196197a0f871d5c8d2d288e77a/docs/html/tab_a.png
--------------------------------------------------------------------------------
/docs/html/tab_ad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cross-platform/dspatch/29022646fbae45196197a0f871d5c8d2d288e77a/docs/html/tab_ad.png
--------------------------------------------------------------------------------
/docs/html/tab_b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cross-platform/dspatch/29022646fbae45196197a0f871d5c8d2d288e77a/docs/html/tab_b.png
--------------------------------------------------------------------------------
/docs/html/tab_bd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cross-platform/dspatch/29022646fbae45196197a0f871d5c8d2d288e77a/docs/html/tab_bd.png
--------------------------------------------------------------------------------
/docs/html/tab_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cross-platform/dspatch/29022646fbae45196197a0f871d5c8d2d288e77a/docs/html/tab_h.png
--------------------------------------------------------------------------------
/docs/html/tab_hd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cross-platform/dspatch/29022646fbae45196197a0f871d5c8d2d288e77a/docs/html/tab_hd.png
--------------------------------------------------------------------------------
/docs/html/tab_s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cross-platform/dspatch/29022646fbae45196197a0f871d5c8d2d288e77a/docs/html/tab_s.png
--------------------------------------------------------------------------------
/docs/html/tab_sd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cross-platform/dspatch/29022646fbae45196197a0f871d5c8d2d288e77a/docs/html/tab_sd.png
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/docs/latex/Makefile:
--------------------------------------------------------------------------------
1 | LATEX_CMD?=pdflatex
2 | MKIDX_CMD?=makeindex
3 | BIBTEX_CMD?=bibtex
4 | LATEX_COUNT?=8
5 | MANUAL_FILE?=refman
6 |
7 | all: $(MANUAL_FILE).pdf
8 |
9 | pdf: $(MANUAL_FILE).pdf
10 |
11 | $(MANUAL_FILE).pdf: clean $(MANUAL_FILE).tex
12 | $(LATEX_CMD) $(MANUAL_FILE) || \
13 | if [ $$? != 0 ] ; then \
14 | \echo "Please consult $(MANUAL_FILE).log to see the error messages" ; \
15 | false; \
16 | fi
17 | $(MKIDX_CMD) $(MANUAL_FILE).idx
18 | $(LATEX_CMD) $(MANUAL_FILE) || \
19 | if [ $$? != 0 ] ; then \
20 | \echo "Please consult $(MANUAL_FILE).log to see the error messages" ; \
21 | false; \
22 | fi
23 | latex_count=$(LATEX_COUNT) ; \
24 | while grep -E -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\
25 | do \
26 | echo "Rerunning latex...." ;\
27 | $(LATEX_CMD) $(MANUAL_FILE) || \
28 | if [ $$? != 0 ] ; then \
29 | \echo "Please consult $(MANUAL_FILE).log to see the error messages" ; \
30 | false; \
31 | fi; \
32 | latex_count=`expr $$latex_count - 1` ;\
33 | done
34 | $(MKIDX_CMD) $(MANUAL_FILE).idx
35 | $(LATEX_CMD) $(MANUAL_FILE) || \
36 | if [ $$? != 0 ] ; then \
37 | \echo "Please consult $(MANUAL_FILE).log to see the error messages" ; \
38 | false; \
39 | fi
40 |
41 | clean:
42 | rm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl $(MANUAL_FILE).pdf
43 |
--------------------------------------------------------------------------------
/include/dspatch/Plugin.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | #include "Component.h"
32 |
33 | #ifdef _WIN32
34 | #define WIN32_LEAN_AND_MEAN
35 | #include
36 | #undef WIN32_LEAN_AND_MEAN
37 | #define DLLEXPORT __declspec( dllexport )
38 | #else
39 | #include
40 | #define DLLEXPORT
41 | #endif
42 |
43 | #include
44 |
45 | #define EXPORT_PLUGIN( classname, ... ) \
46 | extern "C" \
47 | { \
48 | DLLEXPORT DSPatch::Component* Create() \
49 | { \
50 | return new classname( __VA_ARGS__ ); \
51 | } \
52 | }
53 |
54 | namespace DSPatch
55 | {
56 |
57 | /// Component plugin loader
58 |
59 | /**
60 | A component, packaged into a shared library (.so / .dylib / .dll) and exported via the EXPORT_PLUGIN macro, can be dynamically
61 | loaded into a host application using the Plugin class. Each Plugin object represents one Component class. (Example component plugins)
63 |
64 | A Plugin should be constructed with the absolute path of the plugin (shared library) to be loaded. Once instantiated you should
65 | check that the plugin was successfully loaded by calling IsLoaded(). Thereafter, the contained component type can be instantiated
66 | (mutiple times) via the Create() method.
67 | */
68 |
69 | class Plugin final
70 | {
71 | public:
72 | Plugin( const Plugin& ) = delete;
73 | Plugin& operator=( const Plugin& ) = delete;
74 |
75 | explicit Plugin( const std::string& pluginPath );
76 | ~Plugin();
77 |
78 | bool IsLoaded() const;
79 |
80 | Component::SPtr Create() const;
81 |
82 | private:
83 | typedef DSPatch::Component* ( *Create_t )();
84 |
85 | void* _handle = nullptr;
86 | Create_t _create = nullptr;
87 | };
88 |
89 | inline Plugin::Plugin( const std::string& pluginPath )
90 | {
91 | // open library
92 | #ifdef _WIN32
93 | _handle = LoadLibrary( pluginPath.c_str() );
94 | #else
95 | _handle = dlopen( pluginPath.c_str(), RTLD_NOW );
96 | #endif
97 |
98 | if ( _handle )
99 | {
100 | // load symbols
101 | #ifdef _WIN32
102 | _create = (Create_t)GetProcAddress( (HMODULE)_handle, "Create" );
103 | #else
104 | _create = (Create_t)dlsym( _handle, "Create" );
105 | #endif
106 |
107 | if ( !_create )
108 | {
109 | #ifdef _WIN32
110 | FreeLibrary( (HMODULE)_handle );
111 | #else
112 | dlclose( _handle );
113 | #endif
114 |
115 | _handle = nullptr;
116 | }
117 | }
118 | }
119 |
120 | inline Plugin::~Plugin()
121 | {
122 | // close library
123 | if ( _handle )
124 | {
125 | #ifdef _WIN32
126 | FreeLibrary( (HMODULE)_handle );
127 | #else
128 | dlclose( _handle );
129 | #endif
130 | }
131 | }
132 |
133 | // cppcheck-suppress unusedFunction
134 | inline bool Plugin::IsLoaded() const
135 | {
136 | return _handle;
137 | }
138 |
139 | // cppcheck-suppress unusedFunction
140 | inline Component::SPtr Plugin::Create() const
141 | {
142 | if ( _handle )
143 | {
144 | return Component::SPtr( _create() );
145 | }
146 | return nullptr;
147 | }
148 |
149 | } // namespace DSPatch
150 |
--------------------------------------------------------------------------------
/include/dspatch/SignalBus.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | #include "../fast_any/any.h"
32 |
33 | #include
34 |
35 | namespace DSPatch
36 | {
37 |
38 | /// Signal container
39 |
40 | /**
41 | Components process and transfer data between each other in the form of "signals" via interconnected wires. SignalBuses are signal
42 | containers. Via the Process_() method, a Component receives signals into its "inputs" SignalBus and provides signals to its
43 | "outputs" SignalBus. The SignalBus class provides public getters and setters for manipulating its internal signal values,
44 | abstracting the need to retrieve and interface with them directly.
45 |
46 | Signals can be dynamically typed at runtime, this means a signal has the ability to change its data type at any point during
47 | program execution. This is designed such that a SignalBus can hold any number of different typed variables, as well as to allow
48 | for a variable to dynamically change its type when needed - this can be useful for inputs that accept a number of different data
49 | types (E.g. Varying sample size in an audio buffer: array of byte / int / float).
50 | */
51 |
52 | class SignalBus final
53 | {
54 | public:
55 | SignalBus( const SignalBus& ) = delete;
56 | SignalBus& operator=( const SignalBus& ) = delete;
57 |
58 | SignalBus();
59 | SignalBus( SignalBus&& );
60 | ~SignalBus();
61 |
62 | void SetSignalCount( int signalCount );
63 | int GetSignalCount() const;
64 |
65 | fast_any::any* GetSignal( int signalIndex );
66 |
67 | bool HasValue( int signalIndex ) const;
68 |
69 | template
70 | ValueType* GetValue( int signalIndex ) const;
71 |
72 | template
73 | void SetValue( int signalIndex, const ValueType& newValue );
74 |
75 | template
76 | void MoveValue( int signalIndex, ValueType&& newValue );
77 |
78 | void SetSignal( int toSignalIndex, const fast_any::any& fromSignal );
79 | void MoveSignal( int toSignalIndex, fast_any::any& fromSignal );
80 |
81 | void ClearValue( int signalIndex );
82 | void ClearAllValues();
83 |
84 | fast_any::type_info GetType( int signalIndex ) const;
85 |
86 | private:
87 | std::vector _signals;
88 | };
89 |
90 | inline SignalBus::SignalBus() = default;
91 |
92 | inline SignalBus::SignalBus( SignalBus&& rhs )
93 | : _signals( std::move( rhs._signals ) )
94 | {
95 | }
96 |
97 | inline SignalBus::~SignalBus() = default;
98 |
99 | inline void SignalBus::SetSignalCount( int signalCount )
100 | {
101 | _signals.resize( signalCount );
102 | }
103 |
104 | inline int SignalBus::GetSignalCount() const
105 | {
106 | return (int)_signals.size();
107 | }
108 |
109 | inline fast_any::any* SignalBus::GetSignal( int signalIndex )
110 | {
111 | // You might be thinking: Why the raw pointer return here?
112 |
113 | // This is for usability and performance reasons. Usability, because a pointer allows the user
114 | // to manipulate the contained value externally. Performance, because returning a smart pointer
115 | // means having to store the value as a smart pointer too - this adds yet another level of
116 | // indirection to the value, as well as some reference counting overhead. These Get() and Set()
117 | // methods are VERY frequently called, so doing as little as possible with the data here is best.
118 |
119 | return &_signals[signalIndex];
120 | }
121 |
122 | inline bool SignalBus::HasValue( int signalIndex ) const
123 | {
124 | return _signals[signalIndex].has_value();
125 | }
126 |
127 | template
128 | inline ValueType* SignalBus::GetValue( int signalIndex ) const
129 | {
130 | // You might be thinking: Why the raw pointer return here?
131 |
132 | // See: GetSignal().
133 |
134 | return _signals[signalIndex].as();
135 | }
136 |
137 | template
138 | inline void SignalBus::SetValue( int signalIndex, const ValueType& newValue )
139 | {
140 | _signals[signalIndex].emplace( newValue );
141 | }
142 |
143 | template
144 | inline void SignalBus::MoveValue( int signalIndex, ValueType&& newValue )
145 | {
146 | _signals[signalIndex].emplace( std::forward( newValue ) );
147 | }
148 |
149 | inline void SignalBus::SetSignal( int toSignalIndex, const fast_any::any& fromSignal )
150 | {
151 | _signals[toSignalIndex].emplace( fromSignal );
152 | }
153 |
154 | inline void SignalBus::MoveSignal( int toSignalIndex, fast_any::any& fromSignal )
155 | {
156 | // You might be thinking: Why swap and not move here?
157 |
158 | // This is a really nifty little optimisation actually. When we move a signal value from an
159 | // output to an input (or vice-versa within a component) we move its type_info along with it.
160 | // If you look at any::emplace(), you'll see that type_info is really useful in determining
161 | // whether we need to delete and copy (re)construct our contained value, or can simply copy
162 | // assign. To avoid the former as much as possible, a swap is done between source and target
163 | // signals such that, between these two points, just two value holders need to be constructed,
164 | // and shared back and forth from then on.
165 |
166 | _signals[toSignalIndex].swap( fromSignal );
167 | }
168 |
169 | inline void SignalBus::ClearValue( int signalIndex )
170 | {
171 | _signals[signalIndex].reset();
172 | }
173 |
174 | inline void SignalBus::ClearAllValues()
175 | {
176 | for ( auto& signal : _signals )
177 | {
178 | signal.reset();
179 | }
180 | }
181 |
182 | inline fast_any::type_info SignalBus::GetType( int signalIndex ) const
183 | {
184 | return _signals[signalIndex].type();
185 | }
186 |
187 | } // namespace DSPatch
188 |
--------------------------------------------------------------------------------
/meson.build:
--------------------------------------------------------------------------------
1 | project('DSPatch', 'cpp',
2 | default_options: [
3 | 'cpp_std=c++17',
4 | 'warning_level=3',
5 | 'werror=true'
6 | ]
7 | )
8 |
9 | if host_machine.system() == 'darwin'
10 | env = environment()
11 | env.set('MACOSX_DEPLOYMENT_TARGET', '10.13')
12 |
13 | add_project_arguments(['-mmacosx-version-min=10.13', '-arch', 'arm64', '-arch', 'x86_64'], language: 'cpp')
14 | add_project_link_arguments(['-mmacosx-version-min=10.13', '-arch', 'arm64', '-arch', 'x86_64'], language: 'cpp')
15 | endif
16 |
17 | # Add code coverage
18 |
19 | opencppcoverage = find_program('opencppcoverage', required: false)
20 |
21 | opencppcoverage_args = [
22 | '--sources', meson.project_name(),
23 | '--excluded_sources', 'tests',
24 | '--excluded_sources', 'tutorial'
25 | ]
26 |
27 | if opencppcoverage.found()
28 | run_target('codecoverage',
29 | command: [
30 | opencppcoverage,
31 | '--input_coverage', 'Tests.cov',
32 | '--export_type', 'html:coverage'
33 | ]
34 | )
35 | endif
36 |
37 | # Add formatting
38 |
39 | format_first = []
40 | if find_program('clang-format', required: false).found()
41 | if host_machine.system() == 'windows'
42 | format_command = meson.current_source_dir() + '/scripts/clang-format.bat'
43 | else
44 | format_command = ['bash', meson.current_source_dir() + '/scripts/clang-format.sh']
45 | endif
46 |
47 | format_first = custom_target(
48 | output: 'formatting',
49 | command: format_command,
50 | build_always: true
51 | )
52 | endif
53 |
54 | # Add static code analysis
55 |
56 | if find_program('cppcheck', required: false).found()
57 | if host_machine.system() == 'windows'
58 | extra_cppcheck_args = ['-D_WIN32']
59 | else
60 | extra_cppcheck_args = []
61 | endif
62 |
63 | custom_target(
64 | input: format_first,
65 | output: 'static code analysis',
66 | command: [
67 | 'cppcheck',
68 |
69 | '--error-exitcode=1',
70 | '--enable=all',
71 | '--check-level=exhaustive',
72 | '--inconclusive',
73 | '--inline-suppr',
74 | '--force',
75 | '--quiet',
76 | '--suppress=missingIncludeSystem',
77 | '--suppress=*:' + meson.current_source_dir() + '/include/fast_any/any.h',
78 |
79 | '-i', meson.current_source_dir() + '/build',
80 | '-I', meson.current_source_dir() + '/include',
81 |
82 | extra_cppcheck_args,
83 |
84 | meson.current_source_dir()
85 | ],
86 | build_always: true
87 | )
88 | endif
89 |
90 | # Configure DSPatch
91 |
92 | dspatch_dep = declare_dependency(
93 | include_directories: include_directories('include'),
94 | dependencies: dependency('threads')
95 | )
96 |
97 | # Add subdirectories
98 |
99 | subdir('tests')
100 | subdir('tutorial')
101 |
--------------------------------------------------------------------------------
/scripts/clang-format.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | cd %~dp0..
4 |
5 | call :processDir
6 | goto :finish
7 |
8 | :processDir
9 | for %%f in ("*.cpp", "*.h") do (
10 | clang-format --style=file --verbose -i %%f
11 | )
12 |
13 | for /D %%d in (*) do (
14 | cd %%d
15 | if not %%d==build if not %%d==builddir call :processDir
16 | cd ..
17 | )
18 |
19 | exit /b
20 |
21 | :finish
22 |
--------------------------------------------------------------------------------
/scripts/clang-format.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
4 | cd "$DIR/.."
5 |
6 | find . -iname *.h -o -iname *.cpp | grep -v build | grep -v builddir | xargs clang-format --style=file --verbose -i
7 |
--------------------------------------------------------------------------------
/tests/components/Adder.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class Adder final : public Component
35 | {
36 | public:
37 | Adder()
38 | : Component( ProcessOrder::OutOfOrder )
39 | {
40 | SetInputCount_( 2 );
41 | SetOutputCount_( 1 );
42 | }
43 |
44 | protected:
45 | void Process_( SignalBus& inputs, SignalBus& outputs ) override
46 | {
47 | auto in0 = inputs.GetValue( 0 );
48 | auto in1 = inputs.GetValue( 1 );
49 |
50 | outputs.SetValue( 0, ( in0 ? *in0 : 0 ) + ( in1 ? *in1 : 0 ) );
51 | }
52 | };
53 |
54 | } // namespace DSPatch
55 |
--------------------------------------------------------------------------------
/tests/components/BranchSyncProbe.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class BranchSyncProbe final : public Component
35 | {
36 | public:
37 | BranchSyncProbe( int p1, int p2, int p3 )
38 | : _p1( p1 )
39 | , _p2( p2 )
40 | , _p3( p3 )
41 | , _count( 0 )
42 | {
43 | SetInputCount_( 3 );
44 | }
45 |
46 | protected:
47 | void Process_( SignalBus& inputs, SignalBus& ) override
48 | {
49 | auto in0 = inputs.GetValue( 0 );
50 | REQUIRE( in0 );
51 |
52 | auto in1 = inputs.GetValue( 1 );
53 | REQUIRE( in1 );
54 |
55 | auto in2 = inputs.GetValue( 2 );
56 | REQUIRE( in2 );
57 |
58 | REQUIRE( *in0 == _p1 + _count );
59 | REQUIRE( *in1 == _p2 + _count );
60 | REQUIRE( *in2 == _p3 + _count++ );
61 | }
62 |
63 | private:
64 | int _p1;
65 | int _p2;
66 | int _p3;
67 | int _count;
68 | };
69 |
70 | } // namespace DSPatch
71 |
--------------------------------------------------------------------------------
/tests/components/ChangingCounter.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class ChangingCounter final : public Component
35 | {
36 | public:
37 | ChangingCounter()
38 | : _count( 0 )
39 | {
40 | srand( (unsigned int)time( nullptr ) );
41 |
42 | SetOutputCount_( 1 );
43 | }
44 |
45 | protected:
46 | void Process_( SignalBus&, SignalBus& outputs ) override
47 | {
48 | if ( rand() % 2 == 1 )
49 | {
50 | int choice = rand() % 4;
51 |
52 | switch ( choice )
53 | {
54 | case 0:
55 | outputs.SetValue( 0, _count++ );
56 | break;
57 | case 1:
58 | outputs.SetValue( 0, (float)_count++ );
59 | break;
60 | case 2:
61 | outputs.SetValue( 0, std::to_string( _count++ ) );
62 | break;
63 | case 3:
64 | outputs.SetValue( 0, std::vector{ _count, _count + 1, _count + 2 } );
65 | _count += 3;
66 | break;
67 | }
68 | }
69 | else
70 | {
71 | outputs.ClearValue( 0 );
72 | }
73 | }
74 |
75 | private:
76 | int _count;
77 | };
78 |
79 | } // namespace DSPatch
80 |
--------------------------------------------------------------------------------
/tests/components/ChangingProbe.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class ChangingProbe final : public Component
35 | {
36 | public:
37 | ChangingProbe()
38 | : _count( 0 )
39 | {
40 | SetInputCount_( 1 );
41 | }
42 |
43 | protected:
44 | void Process_( SignalBus& inputs, SignalBus& ) override
45 | {
46 | if ( const auto* integer = inputs.GetValue( 0 ) )
47 | {
48 | REQUIRE( *integer == _count++ );
49 | }
50 | else if ( const auto* floating = inputs.GetValue( 0 ) )
51 | {
52 | REQUIRE( *floating == (float)_count++ );
53 | }
54 | else if ( const auto* string = inputs.GetValue( 0 ) )
55 | {
56 | REQUIRE( *string == std::to_string( _count++ ) );
57 | }
58 | else if ( const auto* vector = inputs.GetValue>( 0 ) )
59 | {
60 | REQUIRE( ( *vector )[0] == _count++ );
61 | REQUIRE( ( *vector )[1] == _count++ );
62 | REQUIRE( ( *vector )[2] == _count++ );
63 | }
64 | }
65 |
66 | private:
67 | int _count;
68 | };
69 |
70 | } // namespace DSPatch
71 |
--------------------------------------------------------------------------------
/tests/components/CircuitCounter.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class CircuitCounter final : public Component
35 | {
36 | public:
37 | CircuitCounter()
38 | : _count( 0 )
39 | {
40 | SetInputCount_( 1 );
41 | SetOutputCount_( 1 );
42 | }
43 |
44 | protected:
45 | void Process_( SignalBus& inputs, SignalBus& outputs ) override
46 | {
47 | auto in = inputs.GetValue( 0 );
48 | if ( in )
49 | {
50 | // Count only when the circuit is closed
51 | ++_count;
52 | }
53 |
54 | outputs.SetValue( 0, _count );
55 | }
56 |
57 | private:
58 | int _count;
59 | };
60 |
61 | } // namespace DSPatch
62 |
--------------------------------------------------------------------------------
/tests/components/CircuitProbe.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class CircuitProbe final : public Component
35 | {
36 | public:
37 | CircuitProbe()
38 | : _count( 0 )
39 | {
40 | SetInputCount_( 1 );
41 | SetOutputCount_( 1 );
42 | }
43 |
44 | protected:
45 | void Process_( SignalBus& inputs, SignalBus& outputs ) override
46 | {
47 | const auto* in = inputs.GetValue( 0 );
48 | if ( in )
49 | {
50 | REQUIRE( *in == _count++ );
51 |
52 | // inform the counter that the circuit is closed
53 | outputs.SetValue( 0, true );
54 | }
55 | else
56 | {
57 | outputs.ClearValue( 0 );
58 | }
59 | }
60 |
61 | private:
62 | int _count;
63 | };
64 |
65 | } // namespace DSPatch
66 |
--------------------------------------------------------------------------------
/tests/components/Counter.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class Counter final : public Component
35 | {
36 | public:
37 | explicit Counter( int increment = 1 )
38 | : _count( 0 )
39 | , _increment( increment )
40 | {
41 | SetOutputCount_( 1 );
42 | }
43 |
44 | int Count() const
45 | {
46 | return _count;
47 | }
48 |
49 | protected:
50 | void Process_( SignalBus&, SignalBus& outputs ) override
51 | {
52 | outputs.SetValue( 0, _count );
53 | _count += _increment;
54 | }
55 |
56 | private:
57 | int _count;
58 | const int _increment;
59 | };
60 |
61 | } // namespace DSPatch
62 |
--------------------------------------------------------------------------------
/tests/components/FeedbackProbe.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class FeedbackProbe final : public Component
35 | {
36 | public:
37 | FeedbackProbe()
38 | : _adder_in( 0 )
39 | , _adder_out( 0 )
40 | {
41 | SetInputCount_( 1 );
42 | }
43 |
44 | protected:
45 | void Process_( SignalBus& inputs, SignalBus& ) override
46 | {
47 | auto in = inputs.GetValue( 0 );
48 | REQUIRE( in );
49 |
50 | // The Adder component adds a counter input to its previous output
51 | _adder_out = _adder_in + _adder_out;
52 |
53 | REQUIRE( *in == _adder_out );
54 |
55 | ++_adder_in;
56 | }
57 |
58 | private:
59 | int _adder_in;
60 | int _adder_out;
61 | };
62 |
63 | } // namespace DSPatch
64 |
--------------------------------------------------------------------------------
/tests/components/FeedbackTester.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class FeedbackTester final : public Component
35 | {
36 | public:
37 | explicit FeedbackTester( int bufferCount )
38 | : _bufferCount( bufferCount )
39 | {
40 | SetInputCount_( 10 );
41 | SetOutputCount_( 1 );
42 | }
43 |
44 | void SetValidInputs( int count )
45 | {
46 | _inputs = count;
47 | }
48 |
49 | protected:
50 | void Process_( SignalBus& inputs, SignalBus& outputs ) override
51 | {
52 | for ( int i = 0; i < _inputs; ++i )
53 | {
54 | auto in = inputs.GetValue( i );
55 | if ( _counter >= _bufferCount )
56 | {
57 | REQUIRE( in );
58 | REQUIRE( *in == _counter - ( _bufferCount - 1 ) );
59 | }
60 | }
61 |
62 | outputs.SetValue( 0, ++_counter );
63 | }
64 |
65 | private:
66 | const int _bufferCount = 0;
67 | int _inputs = 0;
68 | int _counter = 0;
69 | };
70 |
71 | } // namespace DSPatch
72 |
--------------------------------------------------------------------------------
/tests/components/Incrementer.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | #include
32 |
33 | namespace DSPatch
34 | {
35 |
36 | class Incrementer final : public Component
37 | {
38 | public:
39 | explicit Incrementer( int increment = 1 )
40 | : Component( ProcessOrder::OutOfOrder )
41 | , _increment( increment )
42 | {
43 | SetInputCount_( 1 );
44 | SetOutputCount_( 1 );
45 | }
46 |
47 | protected:
48 | void Process_( SignalBus& inputs, SignalBus& outputs ) override
49 | {
50 | auto in = inputs.GetValue( 0 );
51 | if ( in )
52 | {
53 | *in += _increment;
54 | outputs.MoveValue( 0, std::move( *in ) ); // pass the adjusted signal through (no copy)
55 | }
56 | // else set no output
57 | }
58 |
59 | private:
60 | const int _increment;
61 | };
62 |
63 | } // namespace DSPatch
64 |
--------------------------------------------------------------------------------
/tests/components/NoOutputProbe.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class NoOutputProbe final : public Component
35 | {
36 | public:
37 | NoOutputProbe()
38 | : _count( 0 )
39 | {
40 | SetInputCount_( 1 );
41 | }
42 |
43 | protected:
44 | void Process_( SignalBus& inputs, SignalBus& ) override
45 | {
46 | const auto* in = inputs.GetValue( 0 );
47 |
48 | if ( in )
49 | {
50 | REQUIRE( *in == _count++ );
51 | }
52 | }
53 |
54 | private:
55 | int _count;
56 | };
57 |
58 | } // namespace DSPatch
59 |
--------------------------------------------------------------------------------
/tests/components/NullInputProbe.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class NullInputProbe final : public Component
35 | {
36 | public:
37 | NullInputProbe()
38 | : Component( ProcessOrder::OutOfOrder )
39 | {
40 | SetInputCount_( 2 );
41 | }
42 |
43 | protected:
44 | void Process_( SignalBus& inputs, SignalBus& ) override
45 | {
46 | const auto* in0 = inputs.GetValue( 0 );
47 | REQUIRE( !in0 );
48 |
49 | const auto* in1 = inputs.GetValue( 1 );
50 | REQUIRE( !in1 );
51 | }
52 | };
53 |
54 | } // namespace DSPatch
55 |
--------------------------------------------------------------------------------
/tests/components/ParallelProbe.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class ParallelProbe final : public Component
35 | {
36 | public:
37 | ParallelProbe()
38 | : _count( 0 )
39 | {
40 | SetInputCount_( 5 );
41 | }
42 |
43 | protected:
44 | void Process_( SignalBus& inputs, SignalBus& ) override
45 | {
46 | auto in0 = inputs.GetValue( 0 );
47 | REQUIRE( in0 );
48 | auto in1 = inputs.GetValue( 1 );
49 | REQUIRE( in1 );
50 | auto in2 = inputs.GetValue( 2 );
51 | REQUIRE( in2 );
52 | auto in3 = inputs.GetValue( 3 );
53 | REQUIRE( in3 );
54 | auto in4 = inputs.GetValue( 4 );
55 | REQUIRE( in4 );
56 |
57 | REQUIRE( *in0 == _count + 1 );
58 | REQUIRE( *in1 == _count + 2 );
59 | REQUIRE( *in2 == _count + 3 );
60 | REQUIRE( *in3 == _count + 4 );
61 | REQUIRE( *in4 == _count + 5 );
62 |
63 | ++_count;
64 | }
65 |
66 | private:
67 | int _count;
68 | };
69 |
70 | } // namespace DSPatch
71 |
--------------------------------------------------------------------------------
/tests/components/PassThrough.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class PassThrough final : public Component
35 | {
36 | public:
37 | PassThrough()
38 | : Component( ProcessOrder::OutOfOrder )
39 | {
40 | SetInputCount_( 1 );
41 | SetOutputCount_( 1 );
42 | }
43 |
44 | protected:
45 | void Process_( SignalBus& inputs, SignalBus& outputs ) override
46 | {
47 | outputs.MoveSignal( 0, *inputs.GetSignal( 0 ) ); // pass the signal through (no copy)
48 | }
49 | };
50 |
51 | } // namespace DSPatch
52 |
--------------------------------------------------------------------------------
/tests/components/SerialProbe.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class SerialProbe final : public Component
35 | {
36 | public:
37 | SerialProbe()
38 | : _count( 0 )
39 | {
40 | SetInputCount_( 1 );
41 | }
42 |
43 | protected:
44 | void Process_( SignalBus& inputs, SignalBus& ) override
45 | {
46 | auto in = inputs.GetValue( 0 );
47 | REQUIRE( in );
48 |
49 | REQUIRE( *in == _count + 1 + 2 + 3 + 4 + 5 );
50 |
51 | ++_count;
52 | }
53 |
54 | private:
55 | int _count;
56 | };
57 |
58 | } // namespace DSPatch
59 |
--------------------------------------------------------------------------------
/tests/components/SlowCounter.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | #include
32 |
33 | namespace DSPatch
34 | {
35 |
36 | class SlowCounter final : public Component
37 | {
38 | public:
39 | SlowCounter()
40 | : _count( 0 )
41 | {
42 | SetOutputCount_( 1 );
43 | }
44 |
45 | void ResetCount()
46 | {
47 | _count = 0;
48 | }
49 |
50 | void Process_( SignalBus&, SignalBus& outputs ) override
51 | {
52 | _start = std::chrono::high_resolution_clock::now();
53 |
54 | outputs.SetValue( 0, _count++ );
55 |
56 | if ( _waitMs <= 0 )
57 | {
58 | _waitMs += 1000.0;
59 | }
60 | else
61 | {
62 | do
63 | {
64 | std::this_thread::yield();
65 | _elapsedMs = std::chrono::high_resolution_clock::now() - _start;
66 | } while ( _elapsedMs.count() < _waitMs );
67 |
68 | _waitMs = 1000.0 - ( _elapsedMs.count() - _waitMs );
69 | }
70 | }
71 |
72 | private:
73 | std::chrono::high_resolution_clock::time_point _start;
74 | std::chrono::duration _elapsedMs;
75 | int _count;
76 | double _waitMs = 1000.0;
77 | };
78 |
79 | } // namespace DSPatch
80 |
--------------------------------------------------------------------------------
/tests/components/SporadicCounter.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class SporadicCounter final : public Component
35 | {
36 | public:
37 | explicit SporadicCounter( int increment = 1 )
38 | : _count( 0 )
39 | , _increment( increment )
40 | {
41 | srand( (unsigned int)time( nullptr ) );
42 |
43 | SetOutputCount_( 1 );
44 | }
45 |
46 | protected:
47 | void Process_( SignalBus&, SignalBus& outputs ) override
48 | {
49 | if ( rand() % 2 == 1 )
50 | {
51 | outputs.SetValue( 0, _count );
52 | _count += _increment;
53 | }
54 | else
55 | {
56 | outputs.ClearValue( 0 );
57 | }
58 | }
59 |
60 | private:
61 | int _count;
62 | const int _increment;
63 | };
64 |
65 | } // namespace DSPatch
66 |
--------------------------------------------------------------------------------
/tests/components/ThreadingProbe.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | namespace DSPatch
32 | {
33 |
34 | class ThreadingProbe final : public Component
35 | {
36 | public:
37 | explicit ThreadingProbe( int inputCount = 4 )
38 | : _inputCount( inputCount )
39 | , _count( 0 )
40 | {
41 | SetInputCount_( _inputCount );
42 | }
43 |
44 | protected:
45 | void Process_( SignalBus& inputs, SignalBus& ) override
46 | {
47 | for ( int i = 0; i < _inputCount; ++i )
48 | {
49 | REQUIRE( *inputs.GetValue( i ) == _count );
50 | }
51 |
52 | ++_count;
53 | }
54 |
55 | private:
56 | const int _inputCount;
57 | int _count;
58 | };
59 |
60 | } // namespace DSPatch
--------------------------------------------------------------------------------
/tests/meson.build:
--------------------------------------------------------------------------------
1 | # Configure tests
2 |
3 | dspatch_tests_src = [
4 | 'main.cpp'
5 | ]
6 |
7 | dspatch_tests_inc = include_directories('.')
8 |
9 | dspatch_tests = executable(
10 | 'Tests',
11 | format_first,
12 | dspatch_tests_src,
13 | include_directories: dspatch_tests_inc,
14 | dependencies: dspatch_dep
15 | )
16 |
17 | # Add code coverage
18 |
19 | if opencppcoverage.found()
20 | test('Tests', opencppcoverage,
21 | args: [
22 | opencppcoverage_args,
23 | '--export_type', 'binary:Tests.cov',
24 | dspatch_tests
25 | ], timeout: 120
26 | )
27 | else
28 | test('Tests', dspatch_tests, timeout: 120)
29 | endif
30 |
--------------------------------------------------------------------------------
/tutorial/components.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #pragma once
30 |
31 | #include
32 |
33 | #include
34 | #include
35 | #include
36 |
37 | // AndBool:
38 | // AndBool has 2 inputs and 1 output.
39 | // This component performs a logic AND on 2 boolean input values and outputs the result.
40 |
41 | // 1. Derive AndBool class from Component
42 | // ======================================
43 | class AndBool final : public DSPatch::Component
44 | {
45 | public:
46 | // 2. Configure component IO buses
47 | // ===============================
48 | AndBool()
49 | // the order in which buffers are Process_()'ed is not important
50 | : Component( ProcessOrder::OutOfOrder )
51 | {
52 | // add 2 inputs
53 | SetInputCount_( 2 );
54 |
55 | // add 1 output
56 | SetOutputCount_( 1 );
57 | }
58 |
59 | protected:
60 | // 3. Implement virtual Process_() method
61 | // ======================================
62 | void Process_( DSPatch::SignalBus& inputs, DSPatch::SignalBus& outputs ) override
63 | {
64 | // create some local pointers to hold our input values
65 | auto bool1 = inputs.GetValue( 0 );
66 | auto bool2 = inputs.GetValue( 1 );
67 |
68 | // check first that our component has received valid inputs
69 | if ( bool1 && bool2 )
70 | {
71 | // set the output as the result of bool1 AND bool2
72 | outputs.SetValue( 0, *bool1 && *bool2 );
73 | }
74 | }
75 | };
76 |
77 | // GenBool:
78 | // GenBool has 1 output.
79 | // This component generates a random boolean value then outputs the result.
80 |
81 | class GenBool final : public DSPatch::Component
82 | {
83 | public:
84 | GenBool()
85 | // the order in which buffers are Process_()'ed is not important
86 | : Component( ProcessOrder::OutOfOrder )
87 | {
88 | // add 1 output
89 | SetOutputCount_( 1 );
90 |
91 | // seed randomizer
92 | srand( static_cast( time( nullptr ) ) );
93 | }
94 |
95 | protected:
96 | void Process_( DSPatch::SignalBus&, DSPatch::SignalBus& outputs ) override
97 | {
98 | // set output as randomized true / false
99 | outputs.SetValue( 0, rand() % 2 == 0 );
100 | }
101 | };
102 |
103 | // PrintBool:
104 | // PrintBool has 1 input.
105 | // This component receives a boolean value and outputs it to the console.
106 |
107 | class PrintBool final : public DSPatch::Component
108 | {
109 | public:
110 | PrintBool()
111 | // here, the order in which buffers are Process_()'ed is important
112 | : Component( ProcessOrder::InOrder )
113 | {
114 | // add 1 input
115 | SetInputCount_( 1 );
116 | }
117 |
118 | protected:
119 | void Process_( DSPatch::SignalBus& inputs, DSPatch::SignalBus& ) override
120 | {
121 | // create a local stack variable to hold input value
122 | auto inputBool = inputs.GetValue( 0 );
123 |
124 | // get boolean value from inputs bus
125 | if ( inputBool )
126 | {
127 | // print "true" / "false" depending on boolean value received
128 | if ( *inputBool )
129 | {
130 | std::cout << "true" << '\n';
131 | }
132 | else
133 | {
134 | std::cout << "false" << '\n';
135 | }
136 | }
137 | }
138 | };
139 |
--------------------------------------------------------------------------------
/tutorial/main.cpp:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | DSPatch - The Refreshingly Simple C++ Dataflow Framework
3 | Copyright (c) 2025, Marcus Tomlinson
4 |
5 | BSD 2-Clause License
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | ******************************************************************************/
28 |
29 | #include "components.h"
30 |
31 | #include
32 |
33 | // The code below results in the following wiring configuration:
34 | // __________ _________
35 | // | | | |
36 | // | genBool1 |-0 ===> 0-| | ___________
37 | // |__________| | | | |
38 | // __________ | andBool |-0 ===> 0-| printBool |
39 | // | | | | |___________|
40 | // | genBool2 |-0 ===> 1-| |
41 | // |__________| |_________|
42 |
43 | int main()
44 | {
45 | // 1. Create a circuit where we can route our components
46 | // =====================================================
47 | auto circuit = std::make_shared();
48 |
49 | // 2. Create instances of the components needed for our circuit
50 | // ============================================================
51 | auto genBool1 = std::make_shared();
52 | auto genBool2 = std::make_shared();
53 | auto andBool = std::make_shared();
54 | auto printBool = std::make_shared();
55 |
56 | // 3. Add component instances to circuit
57 | // =====================================
58 | circuit->AddComponent( genBool1 );
59 | circuit->AddComponent( genBool2 );
60 | circuit->AddComponent( andBool );
61 | circuit->AddComponent( printBool );
62 |
63 | // 4. Wire up the components inside the circuit
64 | // ============================================
65 | circuit->ConnectOutToIn( genBool1, 0, andBool, 0 );
66 | circuit->ConnectOutToIn( genBool2, 0, andBool, 1 );
67 | circuit->ConnectOutToIn( andBool, 0, printBool, 0 );
68 |
69 | // 5. Tick the circuit
70 | // ===================
71 |
72 | // Circuit tick method 1: Manual
73 | for ( int i = 0; i < 10; ++i )
74 | {
75 | circuit->Tick();
76 | }
77 |
78 | // Circuit tick method 2: Automatic
79 | std::cout << "Press any key to begin circuit auto-tick.";
80 | getchar();
81 | circuit->StartAutoTick();
82 |
83 | // Increase circuit buffer count for higher performance
84 | getchar();
85 | circuit->SetBufferCount( 4 );
86 |
87 | // Press any key to quit
88 | getchar();
89 | return 0;
90 | }
91 |
--------------------------------------------------------------------------------
/tutorial/meson.build:
--------------------------------------------------------------------------------
1 | dspatch_tutorial_src = [
2 | 'main.cpp'
3 | ]
4 |
5 | dspatch_tutorial_inc = include_directories('.')
6 |
7 | dspatch_tutorial = executable(
8 | 'Tutorial',
9 | format_first,
10 | dspatch_tutorial_src,
11 | include_directories: dspatch_tutorial_inc,
12 | dependencies: dspatch_dep
13 | )
14 |
--------------------------------------------------------------------------------