diff options
323 files changed, 7523 insertions, 10418 deletions
diff --git a/.clang-tidy b/.clang-tidy index 60a2b184..d4cd324f 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,73 +1,46 @@ Checks: > *, - -*-avoid-c-arrays, - -*-else-after-return, -*-magic-numbers, - -*-member-init, -*-named-parameter, - -*-narrowing-conversions, -*-non-private-member-variables-in-classes, -*-special-member-functions, - -*-uppercase-literal-suffix, - -abseil-string-find-str-contains, - -android-cloexec-*, - -bugprone-branch-clone, - -bugprone-exception-escape, - -bugprone-macro-parentheses, - -bugprone-parent-virtual-call, + -abseil-*, + -altera-*, + -bugprone-assignment-in-if-condition, -bugprone-reserved-identifier, - -bugprone-signed-char-misuse, - -bugprone-suspicious-string-compare, + -bugprone-switch-missing-default-case, -cert-dcl37-c, - -cert-dcl50-cpp, -cert-dcl51-cpp, - -cert-err34-c, - -cert-err58-cpp, - -cert-str34-c, - -clang-analyzer-alpha.*, - -clang-analyzer-core.CallAndMessage, - -clang-analyzer-optin.cplusplus.VirtualCall, - -clang-analyzer-valist.Uninitialized, - -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-avoid-const-or-ref-data-members, + -cppcoreguidelines-avoid-do-while, -cppcoreguidelines-macro-usage, - -cppcoreguidelines-no-malloc, - -cppcoreguidelines-owning-memory, - -cppcoreguidelines-pro-bounds-array-to-pointer-decay, - -cppcoreguidelines-pro-bounds-constant-array-index, - -cppcoreguidelines-pro-bounds-pointer-arithmetic, - -cppcoreguidelines-pro-type-const-cast, - -cppcoreguidelines-pro-type-cstyle-cast, - -cppcoreguidelines-pro-type-reinterpret-cast, - -cppcoreguidelines-pro-type-static-cast-downcast, - -cppcoreguidelines-pro-type-union-access, - -cppcoreguidelines-pro-type-vararg, - -cppcoreguidelines-slicing, - -fuchsia-*, + -fuchsia-default-arguments-calls, + -fuchsia-default-arguments-declarations, + -fuchsia-multiple-inheritance, + -fuchsia-overloaded-operator, -google-default-arguments, -google-explicit-constructor, - -google-readability-todo, - -google-runtime-int, - -google-runtime-references, -hicpp-explicit-conversions, - -hicpp-multiway-paths-covered, - -hicpp-no-array-decay, - -hicpp-no-malloc, -hicpp-signed-bitwise, - -hicpp-vararg, - -llvm-header-guard, -llvmlibc-*, - -misc-no-recursion, + -misc-include-cleaner, -misc-unused-parameters, + -misc-use-anonymous-namespace, + -modernize-use-nodiscard, -modernize-use-trailing-return-type, - -readability-convert-member-functions-to-static, + -performance-enum-size, + -readability-avoid-nested-conditional-operator, + -readability-identifier-length, -readability-implicit-bool-conversion, - -readability-use-anyofallof, -CheckOptions: - - key: modernize-use-override.AllowOverrideAndFinal - value: 'true' CheckOptions: - key: cppcoreguidelines-explicit-virtual-functions.AllowOverrideAndFinal value: 'true' + - key: hicpp-uppercase-literal-suffix.NewSuffixes + value: 'L;U;UL;ULL' + - key: modernize-use-override.AllowOverrideAndFinal + value: 'true' + - key: readability-uppercase-literal-suffix.NewSuffixes + value: 'L;U;UL;ULL' WarningsAsErrors: '*' -HeaderFilterRegex: 'include/ingen/.*|tests/.*|src/.*' +HeaderFilterRegex: '.*' FormatStyle: file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index b2babe71..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "waflib"] - path = waflib - url = ../autowaf.git diff --git a/.includes.imp b/.includes.imp index a1986d0f..247f2908 100644 --- a/.includes.imp +++ b/.includes.imp @@ -1,16 +1,17 @@ [ + { "symbol": [ "GdkEvent", "private", "<gdk/gdk.h>", "public" ] }, + { "symbol": [ "LilvWorld", "private", "<lilv/lilv.h>", "public" ] }, + { "symbol": [ "clockid_t", "private", "<sys/types.h>", "public" ] }, + { "symbol": [ "clockid_t", "private", "<time.h>", "public" ] }, { "symbol": [ "fmt::format", "private", "<fmt/core.h>", "public" ] }, + { "symbol": [ "posix_memalign", "private", "<stdlib.h>", "public" ] }, + { "symbol": [ "sched_param", "private", "<sched.h>", "public" ] }, { "symbol": [ "std::exception", "private", "<exception>", "public" ] }, { "symbol": [ "std::ifstream", "private", "<fstream>", "public" ] }, - { "symbol": [ "std::ostream", "private", "<ostream>", "public" ] }, + { "symbol": [ "std::mulliseconds", "private", "<chrono>", "public" ] }, { "symbol": [ "std::ostream", "private", "<iosfwd>", "public" ] }, - { "symbol": [ "posix_memalign", "private", "<stdlib.h>", "public" ] }, + { "symbol": [ "std::ostream", "private", "<ostream>", "public" ] }, { "symbol": [ "std::stringstream", "private", "<sstream>", "public" ] }, - { "symbol": [ "sched_param", "private", "<sched.h>", "public" ] }, - { "symbol": [ "clockid_t", "private", "<time.h>", "public" ] }, - { "symbol": [ "clockid_t", "private", "<sys/types.h>", "public" ] }, - { "symbol": [ "GdkEvent", "private", "<gdk/gdk.h>", "public" ] }, - { "symbol": [ "LilvWorld", "private", "\"lilv/lilv.h\"", "public" ] }, { "symbol": [ "boost::intrusive::constant_time_size", "private", "<boost/intrusive/options.hpp>", "public" ] }, @@ -18,8 +19,13 @@ { "symbol": [ "boost::intrusive::cache_last", "private", "<boost/intrusive/options.hpp>", "public" ] }, - { "include": [ "<ext/alloc_traits.h>", "private", "<string>", "public", ] }, - { "include": [ "<ext/alloc_traits.h>", "private", "<vector>", "public", ] }, - { "include": [ "<gdk/gdkevents.h>", "private", "<gdk/gdk.h>", "public", ] }, - { "include": [ "<gdk/gdktypes.h>", "private", "<gdk/gdk.h>", "public", ] } + { "include": [ "<bits/chrono.h>", "private", "<chrono>", "public" ] }, + { "include": [ "<bits/utility.h>", "private", "<utility>", "public" ] }, + { "include": [ "<ext/alloc_traits.h>", "private", "<string>", "public" ] }, + { "include": [ "<ext/alloc_traits.h>", "private", "<vector>", "public" ] }, + { "include": [ "<gdk/gdkevents.h>", "private", "<gdk/gdk.h>", "public" ] }, + { "include": [ "<gdk/gdktypes.h>", "private", "<gdk/gdk.h>", "public" ] }, + + { "include": [ "<sigc++/type_traits.h>", "public", "<sigc++/adaptors/bind.h>", "public" ] }, + { "include": [ "<sigc++/type_traits.h>", "public", "<sigc++/functors/mem_fun.h>", "public" ] } ] diff --git a/.suppress.cppcheck b/.suppress.cppcheck new file mode 100644 index 00000000..4ba574b1 --- /dev/null +++ b/.suppress.cppcheck @@ -0,0 +1,16 @@ +constParameterPointer +constParameterReference +constVariablePointer +constVariableReference +cstyleCast +duplInheritedMember +duplicateExpression +knownConditionTrueFalse +missingReturn +noExplicitConstructor +normalCheckLevelMaxBranches +shadowFunction +unsafeClassCanLeak +useStlAlgorithm +uselessOverride +virtualCallInConstructor diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 623cddde..00000000 --- a/INSTALL +++ /dev/null @@ -1,59 +0,0 @@ -Installation Instructions -========================= - -Basic Installation ------------------- - -Building this software requires only Python. To install with default options: - - ./waf configure - ./waf - ./waf install - -You may need to become root for the install stage, for example: - - sudo ./waf install - -Configuration Options ---------------------- - -All supported options can be viewed using the command: - - ./waf --help - -Most options only need to be passed during the configure stage, for example: - - ./waf configure --prefix=/usr - ./waf - ./waf install - -Compiler Configuration ----------------------- - -Several standard environment variables can be used to control how compilers are -invoked: - - * CC: Path to C compiler - * CFLAGS: C compiler options - * CXX: Path to C++ compiler - * CXXFLAGS: C++ compiler options - * CPPFLAGS: C preprocessor options - * LINKFLAGS: Linker options - -Installation Directories ------------------------- - -The --prefix option (or the PREFIX environment variable) can be used to change -the prefix which all files are installed under. There are also several options -allowing for more fine-tuned control, see the --help output for details. - -Packaging ---------- - -Everything can be installed to a specific root directory by passing a --destdir -option to the install stage (or setting the DESTDIR environment variable), -which adds a prefix to all install paths. For example: - - ./waf configure --prefix=/usr - ./waf - ./waf install --destdir=/tmp/package diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 00000000..96c4a60a --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,74 @@ +Installation Instructions +========================= + +Prerequisites +------------- + +To build from source, you will need: + + * A relatively modern C++ compiler (GCC, Clang, and MSVC are known to work). + + * [Meson](http://mesonbuild.com/), which depends on + [Python](http://python.org/). + +This is a brief overview of building this project with meson. See the meson +documentation for more detailed information. + +Configuration +------------- + +The build is configured with the `setup` command, which creates a new build +directory with the given name: + + meson setup build + +Some environment variables are read during `setup` and stored with the +configuration: + + * `CXX`: Path to C++ compiler. + * `CXXFLAGS`: C++ compiler options. + * `LDFLAGS`: Linker options. + +However, it is better to use meson options for configuration. All options can +be inspected with the `configure` command from within the build directory: + + cd build + meson configure + +Options can be set by passing C-style "define" options to `configure`: + + meson configure -Dcpp_args="-march=native" -Dprefix="/opt/mypackage/" + +Note that some options, such as `strict` and `werror` are for +developer/maintainer use only. Please don't file issues about anything that +happens when they are enabled. + +Building +-------- + +From within a configured build directory, everything can be built with the +`compile` command: + + meson compile + +Similarly, tests can be run with the `test` command: + + meson test + +Meson can also generate a project for several popular IDEs, see the `backend` +option for details. + +Installation +------------ + +A compiled project can be installed with the `install` command: + + meson install + +You may need to acquire root permissions to install to a system-wide prefix. +For packaging, the installation may be staged to a directory using the +`DESTDIR` environment variable or the `--destdir` option: + + DESTDIR=/tmp/mypackage/ meson install + + meson install --destdir=/tmp/mypackage/ diff --git a/bundles/MonoEffect.ingen/manifest.ttl b/bundles/MonoEffect.ingen/manifest.ttl deleted file mode 100644 index 4484811a..00000000 --- a/bundles/MonoEffect.ingen/manifest.ttl +++ /dev/null @@ -1,16 +0,0 @@ -@prefix atom: <http://lv2plug.in/ns/ext/atom#> . -@prefix patch: <http://lv2plug.in/ns/ext/patch#> . -@prefix doap: <http://usefulinc.com/ns/doap#> . -@prefix ingen: <http://drobilla.net/ns/ingen#> . -@prefix lv2: <http://lv2plug.in/ns/lv2core#> . -@prefix midi: <http://lv2plug.in/ns/ext/midi#> . -@prefix owl: <http://www.w3.org/2002/07/owl#> . -@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . -@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . -@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . - -<MonoEffect.ttl> - lv2:prototype ingen:GraphPrototype ; - a ingen:Graph , - lv2:Plugin ; - rdfs:seeAlso <MonoEffect.ttl> . diff --git a/bundles/MonoInstrument.ingen/manifest.ttl b/bundles/MonoInstrument.ingen/manifest.ttl deleted file mode 100644 index a65a5341..00000000 --- a/bundles/MonoInstrument.ingen/manifest.ttl +++ /dev/null @@ -1,16 +0,0 @@ -@prefix atom: <http://lv2plug.in/ns/ext/atom#> . -@prefix patch: <http://lv2plug.in/ns/ext/patch#> . -@prefix doap: <http://usefulinc.com/ns/doap#> . -@prefix ingen: <http://drobilla.net/ns/ingen#> . -@prefix lv2: <http://lv2plug.in/ns/lv2core#> . -@prefix midi: <http://lv2plug.in/ns/ext/midi#> . -@prefix owl: <http://www.w3.org/2002/07/owl#> . -@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . -@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . -@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . - -<MonoInstrument.ttl> - lv2:prototype ingen:GraphPrototype ; - a ingen:Graph , - lv2:Plugin ; - rdfs:seeAlso <MonoInstrument.ttl> . diff --git a/bundles/StereoEffect.ingen/manifest.ttl b/bundles/StereoEffect.ingen/manifest.ttl deleted file mode 100644 index 5c55ef41..00000000 --- a/bundles/StereoEffect.ingen/manifest.ttl +++ /dev/null @@ -1,16 +0,0 @@ -@prefix atom: <http://lv2plug.in/ns/ext/atom#> . -@prefix patch: <http://lv2plug.in/ns/ext/patch#> . -@prefix doap: <http://usefulinc.com/ns/doap#> . -@prefix ingen: <http://drobilla.net/ns/ingen#> . -@prefix lv2: <http://lv2plug.in/ns/lv2core#> . -@prefix midi: <http://lv2plug.in/ns/ext/midi#> . -@prefix owl: <http://www.w3.org/2002/07/owl#> . -@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . -@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . -@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . - -<StereoEffect.ttl> - lv2:prototype ingen:GraphPrototype ; - a ingen:Graph , - lv2:Plugin ; - rdfs:seeAlso <StereoEffect.ttl> . diff --git a/bundles/StereoInstrument.ingen/manifest.ttl b/bundles/StereoInstrument.ingen/manifest.ttl deleted file mode 100644 index d4cc271d..00000000 --- a/bundles/StereoInstrument.ingen/manifest.ttl +++ /dev/null @@ -1,16 +0,0 @@ -@prefix atom: <http://lv2plug.in/ns/ext/atom#> . -@prefix patch: <http://lv2plug.in/ns/ext/patch#> . -@prefix doap: <http://usefulinc.com/ns/doap#> . -@prefix ingen: <http://drobilla.net/ns/ingen#> . -@prefix lv2: <http://lv2plug.in/ns/lv2core#> . -@prefix midi: <http://lv2plug.in/ns/ext/midi#> . -@prefix owl: <http://www.w3.org/2002/07/owl#> . -@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . -@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . -@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . - -<StereoInstrument.ttl> - lv2:prototype ingen:GraphPrototype ; - a ingen:Graph , - lv2:Plugin ; - rdfs:seeAlso <StereoInstrument.ttl> . diff --git a/bundles/MonoEffect.ingen/MonoEffect.ttl b/bundles/ingen.lv2/MonoEffect.ttl index 45f55ad5..45f55ad5 100644 --- a/bundles/MonoEffect.ingen/MonoEffect.ttl +++ b/bundles/ingen.lv2/MonoEffect.ttl diff --git a/bundles/MonoInstrument.ingen/MonoInstrument.ttl b/bundles/ingen.lv2/MonoInstrument.ttl index f8a8595d..f8a8595d 100644 --- a/bundles/MonoInstrument.ingen/MonoInstrument.ttl +++ b/bundles/ingen.lv2/MonoInstrument.ttl diff --git a/bundles/StereoEffect.ingen/StereoEffect.ttl b/bundles/ingen.lv2/StereoEffect.ttl index fff6ffce..fff6ffce 100644 --- a/bundles/StereoEffect.ingen/StereoEffect.ttl +++ b/bundles/ingen.lv2/StereoEffect.ttl diff --git a/bundles/StereoInstrument.ingen/StereoInstrument.ttl b/bundles/ingen.lv2/StereoInstrument.ttl index 84c756c1..84c756c1 100644 --- a/bundles/StereoInstrument.ingen/StereoInstrument.ttl +++ b/bundles/ingen.lv2/StereoInstrument.ttl diff --git a/bundles/ingen.lv2/ingen.ttl b/bundles/ingen.lv2/ingen.ttl index 9cf5e8c2..4364a2f5 100644 --- a/bundles/ingen.lv2/ingen.ttl +++ b/bundles/ingen.lv2/ingen.ttl @@ -242,16 +242,11 @@ ingen:BundleEnd rdfs:label "Bundle End" ; rdfs:comment "The end of an undo transaction." . -ingen:Option - a rdfs:Class ; - rdfs:subClassOf rdf:Property ; - rdfs:label "Ingen Option" . - ingen:shortSwitch a rdf:Property , owl:DatatypeProperty , owl:FunctionalProperty ; - rdfs:domain ingen:Option ; + rdfs:domain rdf:Property ; rdfs:range xsd:string ; rdfs:label "short switch" ; rdfs:comment "Single character switch for short command line argument." . @@ -260,15 +255,14 @@ ingen:longSwitch a rdf:Property , owl:DatatypeProperty , owl:FunctionalProperty ; - rdfs:domain ingen:Option ; + rdfs:domain rdf:Property ; rdfs:range xsd:string ; rdfs:label "long switch" ; rdfs:comment "Lowercase, hyphenated switch for long command line argument." . ingen:numThreads a rdf:Property , - owl:ObjectProperty , - ingen:Option ; + owl:ObjectProperty ; rdfs:label "number of threads" ; ingen:shortSwitch "p" ; ingen:longSwitch "threads" . diff --git a/bundles/ingen.lv2/manifest.ttl b/bundles/ingen.lv2/manifest.ttl index 12d3621a..616933a5 100644 --- a/bundles/ingen.lv2/manifest.ttl +++ b/bundles/ingen.lv2/manifest.ttl @@ -41,3 +41,27 @@ internals:Note internals:Transport a ingen:Plugin ; rdfs:seeAlso <internals.ttl> . + +<MonoEffect.ttl> + a ingen:Graph , + lv2:Plugin ; + lv2:prototype ingen:GraphPrototype ; + rdfs:seeAlso <MonoEffect.ttl> . + +<MonoInstrument.ttl> + a ingen:Graph , + lv2:Plugin ; + lv2:prototype ingen:GraphPrototype ; + rdfs:seeAlso <MonoInstrument.ttl> . + +<StereoEffect.ttl> + a ingen:Graph , + lv2:Plugin ; + lv2:prototype ingen:GraphPrototype ; + rdfs:seeAlso <StereoEffect.ttl> . + +<StereoInstrument.ttl> + a ingen:Graph , + lv2:Plugin ; + lv2:prototype ingen:GraphPrototype ; + rdfs:seeAlso <StereoInstrument.ttl> . diff --git a/bundles/ingen.lv2/meson.build b/bundles/ingen.lv2/meson.build new file mode 100644 index 00000000..9e7dd5d0 --- /dev/null +++ b/bundles/ingen.lv2/meson.build @@ -0,0 +1,44 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +data_files = files( + 'MonoEffect.ttl', + 'MonoInstrument.ttl', + 'StereoEffect.ttl', + 'StereoInstrument.ttl', + 'errors.ttl', + 'ingen.ttl', + 'internals.ttl', + 'manifest.ttl', +) + +# Install bundle +install_data(data_files, install_dir: lv2dir / 'ingen.lv2') + +# Ontology documentation +lv2specgen_py = find_program('lv2specgen.py', required: get_option('docs')) +if lv2specgen_py.found() + ingen_html = custom_target( + 'ingen.html', + input: files('ingen.ttl'), + command: [ + lv2specgen_py, + '@INPUT@', + '@OUTPUT@', + '--copy-style', + '--instances', + '--list-email', 'ingen@drobilla.net', + '--list-page', 'http://lists.drobilla.net/listinfo.cgi/ingen-drobilla.net', + '--prefix', 'ingen', + ], + install: true, + install_dir: lv2dir / 'ingen.lv2', + output: 'ingen.html', + ) + + # TODO: Fix lv2specgen so third-party documentation is properly styled + install_data( + files('style.css'), + install_dir: lv2dir / 'ingen.lv2', + ) +endif diff --git a/bundles/ingen.lv2/style.css b/bundles/ingen.lv2/style.css new file mode 100644 index 00000000..174d889c --- /dev/null +++ b/bundles/ingen.lv2/style.css @@ -0,0 +1,804 @@ +@import url("./pygments.css"); + +/* Generic page style */ + +html { + background: #FFF; + color: #222; +} + +body { + font-family: "DejaVu Sans", "SF Pro Text", Verdana, sans-serif; + font-style: normal; + line-height: 1.6em; + margin-left: auto; + margin-right: auto; + max-width: 60em; + padding: 1em; +} + +h1 { + font-family: "DejaVu Sans Condensed", Helvetica, Arial, sans-serif; + font-size: 2.38em; + font-weight: 600; + line-height: 1.41em; + margin: 0 0 0.25em; +} + +h2 { + font-family: "DejaVu Sans Condensed", Helvetica, Arial, sans-serif; + font-size: 1.68em; + font-weight: 600; + line-height: 1.3em; + margin: 1.25em 0 0.5em; +} + +h3 { + font-family: "DejaVu Sans Condensed", Helvetica, Arial, sans-serif; + font-size: 1.41em; + font-weight: 600; + line-height: 1.19em; + margin: 1.25em 0 0.5em; +} + +h4 { + font-family: "DejaVu Sans Condensed", Helvetica, Arial, sans-serif; + font-size: 1.19em; + font-weight: 600; + line-height: 1.09em; + margin: 1.25em 0 0.5em; +} + +h5, h6 { + font-family: "DejaVu Sans Condensed", Helvetica, Arial, sans-serif; + font-size: 1em; + font-weight: 600; + line-height: 1em; + margin: 1.25em 0 0.5em; +} + +a { + color: #546E00; + text-decoration: none; +} + +h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + color: #222; +} + +a:link { + color: #546E00; + text-decoration: none; +} + +a:visited { + color: #546E00; +} + +a:hover { + text-decoration: underline; +} + +h1 a:link, h2 a:link, h3 a:link, h4 a:link, h5 a:link, h6 a:link { + color: #222; +} + +h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited { + color: #222; +} + +img { + border: 0; +} + +p { + margin: 0.5em 0; +} + +blockquote { + border-left: 1px solid #CCC; + margin-left: 1em; + padding-left: 1em; +} + +pre, code, kbd, samp { + color: #444; + font-family: "DejaVu Sans Mono", "SF Mono", Consolas, monospace; + margin: 1em 0; + white-space: pre; +} + +ul, ol { + margin: 0 0 0.5em; + padding-top: 0; +} + +dt { + font-weight: 600; + margin: 0.75em 0 0.125em; +} + +dt::after { + content: ": "; + margin-right: 0.5em; +} + +hr { + background-color: #EEE; + border: 0; + color: #666; + height: 1px; + margin-bottom: 1.5ex; + margin-top: 1.5ex; +} + +table { + border-collapse: collapse; + border-spacing: 1em 1em; + border-style: hidden; + margin: 0; +} + +th { + border: 1px solid #EEE; + padding: 0.25em 0.5em; + text-align: left; +} + +table tbody tr th { + text-align: left; +} + +td { + border: 1px solid #EEE; + padding: 0.25em 0.5em; + vertical-align: top; +} + +caption { + caption-side: bottom; + font-size: small; + font-style: italic; + margin: 0.75em 0; +} + +footer { + color: #444; + font-size: small; +} + +/* Specgen style */ + +#titlebox { + display: inline-block; + max-width: 60%; + left: 0; + top: 0; +} + +#metabox { + display: inline-block; + font-size: x-small; + font-family: "DejaVu Sans Condensed", Helvetica, Arial, sans-serif; + position: absolute; + right: 0; + bottom: 0.25em; + color: #666; + font-style: italic; +} + +#meta { + border-style: hidden; +} + +#meta tr, #meta th, #meta td { + border: 0; + font-weight: normal; + padding: 0 0 0.125em; + background-color: transparent; +} + +#meta th { + padding-right: 0.5em; + text-align: right; +} + +#meta th::after { + content: ": "; +} + +#subtitle { + font-size: small; +} + +#shortdesc { + padding: 0; + margin: 0 0 0.5em; + font-style: italic; + color: #666; + display: inline-block; +} + +#logo { + height: 63px; + margin-left: 1em; + margin-top: 10px; + width: 100px; +} + +#titlesep { + color: #EEE; +} + +#content-body { + border-bottom: 0; + display: block; + font-size: 75%; + left: 0; + margin-left: 2em; + min-width: 660px; + padding: 3px 10px 0 0; + position: absolute; + top: 63px; + width: 93.9%; + z-index: 0; +} + +#menu { + font-size: 75%; + margin-bottom: 5px; + padding: 0; + width: 16em; +} + +#menu ul { + border: 0; + list-style: none; + margin: 0; + padding: 0; +} + +#menu a { + text-decoration: none; +} + +#menu ul.level-one a { + background-color: #F5F5F5; + border: 1px solid #DADADA; + color: #4B5A6A; + display: block; + margin: 0 0 4px 1.4em; + padding: 2px 2px 2px 4px; + text-transform: uppercase; + width: 13.4em !important; +} + +#menu ul.level-two a { + background: none; + background-color: transparent; + border: 0; + border-top: 1px solid #DDD; + color: #3C4B7B; + display: block; + margin: 0 3em 0 1.5em; + padding: 0.1em; + text-transform: none; + width: 11em !important; +} + +#menu ul.level-three a { + border: 0; + color: #5E72A5; + display: block; + font-size: 95%; + margin: 0 3em 0 1.8em; + padding: 0.1em 0.1em 0.1em 1em; + width: 10em !important; +} + +#menu ul.level-one a:hover, +#menu ul.level-two a:hover, +#menu ul.level-three a:hover { + color: #000; + text-decoration: underline; +} + +#menu ul.level-one a.selected { + background-color: #FFF; + border-left: 3px solid #FFDB4C; + color: #000; +} + +#menu ul.level-two a:visited { + color: #4C3B5B; +} + +#menu ul.level-two li:first-child a { + border-top: 0; +} + +#menu ul.level-one ul.level-two a.selected { + background-color: #FFF; + border-left: 0; + color: #000; + font-weight: 700; +} + +#menu li ul { + margin-bottom: 7px; +} + +#menu ul.level-three li.selected a.selected { + color: #000; + font-weight: 400; +} + +#menu ul.level-three { + margin-top: 5px; +} + +#searchbox { + font-weight: 700; + position: absolute; + right: 0; + text-align: right; + top: 0; + vertical-align: middle; + white-space: nowrap; + width: 28.1em; +} + +#search { + color: #A38E60; + padding: 5px 5px 0 0; +} + +#search .input-text { + background-color: #FFF; + border: 1px solid #C4CCCC; + font-size: 116%; + font-weight: 400; + margin-top: 3px; + vertical-align: top; + width: 11em; +} + +#search .input-button { + background-color: #F8F7F7; + border-bottom: 1px solid #6F7777; + border-left: 1px solid #C4CCCC; + border-right: 1px solid #6F7777; + border-top: 1px solid #C4CCCC; + color: #234; + font-weight: 700; + margin: 3px 0.4em 0; + padding: 0 0.2em; + vertical-align: text-top; +} + +input.formbutton { + background-color: #F8F7F7; + border-bottom: 1px solid #6F7777; + border-left: 1px solid #C4CCCC; + border-right: 1px solid #6F7777; + border-top: 1px solid #C4CCCC; + color: #234; + font-weight: 700; + vertical-align: text-top; +} + +.formtextinput { + background-color: #FFF; + border: 1px solid #C4CCCC; + font-size: 116%; + font-weight: 400; + vertical-align: top; +} + +#content table { + clear: right; +} + +.content-section { + margin-top: 15px; +} + +.content-section h1 { + margin: 0 0 10px; +} + +.content-section p { + margin: 0 0 5px; + padding-left: 12px; +} + +.content-section .pubdate { + color: #696969; + margin: 0 0 8px; + padding: 0 0 0 12px; +} + +#footer { + bottom: 0; + clear: both; + font-size: x-small; + margin: 2em 0 0; + padding: 0; + color: #888; +} + +#searchbox a.reference, #searchbox span.reference { + color: #339; + font-size: 85%; + font-weight: 400; + position: absolute; + right: 8.3em; + text-decoration: none; + top: 2.9em; +} + +#topbar { + line-height: 1em; + border-bottom: 1px solid #EEE; +} + +@media print { + #topbar { + color: #000; + margin: 0.25em auto; + padding: 0.25em 0.5em 0.5em; + max-width: 60em; + position: relative; + } + + #contentsbox { + display: none; + } + + #topbar a, #title a, #topbar a:visited, #title a:visited { + color: #000; + } + + #contents { + display: none; + } +} + +@media screen { + #topbar { + margin: 0.25em auto; + padding: 0; + max-width: 60em; + position: relative; + } + + #contentsbox { + color: #546E00; + font-size: small; + margin: 0 0 1.5em; + } + + #contents { + display: inline; + padding: 0; + } + + #contents li { + display: inline; + list-style-type: none; + margin-left: 0; + margin-right: 0.5em; + padding: 0.25ex 0.25ex 0.25ex 0; + } +} + +#content { + clear: both; + padding: 0; + max-width: 60em; + margin-left: auto; + margin-right: auto; +} + +.section { + clear: right; + padding: 0 0 1.5em; +} + +.category { + font-size: small; + color: #AAA; + float: right; + vertical-align: bottom; + padding: 0; + margin: 0; + padding-right: 0.25em; +} + +.label { + font-style: italic; + margin-top: 0.25em; + color: #666; +} + +table.index { + border: 0; + line-height: 1.5em; + margin-top: 2em; +} + +.index ul { + padding-left: 1.25em; + margin-left: 0; + list-style-type: circle; +} + +.index ul li { + padding-left: 0; + color: #888; +} + +.prop { + margin: 0; + padding: 0; +} + +.description { + margin-top: 0; + margin-bottom: 0.75em; +} + +.blankdesc, .blankdef { + border-spacing: 0; + margin: 0; + padding-left: 0; + padding-right: 0; +} + +.blankdesc tbody tr td, .blankdef { + border: 0 !important; +} + +.blankdesc td { + padding-right: 0.5em; +} + +.blankdesc tbody tr td:first-child { + border-left: 1px solid #BBB; + text-align: right; +} + +.terminfo, .restriction { + border-collapse: collapse; + border-spacing: 0; + font-size: small; + color: #666; + border-radius: 0; + border-bottom-left-radius: 6px; +} + +table.terminfo { + border-top: 0; + border-collapse: collapse; + margin: -1px 0 2em 2em; + padding: 0.25em 0; + float: right; + border-bottom: 1px solid #EEE; + border-left: 1px solid #EEE; + border-bottom-left-radius: 6px; + max-width: 50%; + line-height: 1.4em; + min-width: 25%; +} + +table.terminfo td { + padding: 0 0.5em; +} + +.restriction { + border-style: hidden; + margin: 0 0 0.5ex; + padding: 0; + vertical-align: text-top; +} + +.restriction td { + vertical-align: text-top; +} + +.terminfo th { + padding: 0 0.5em; + text-align: right; + vertical-align: top; +} + +.specterm { + border: 0; + margin: 0; + padding: 1em 0; + clear: both; +} + +.specterm h3 { + display: inline-block; + margin-bottom: 0.25em; + width: 80%; +} + +.spectermtype { + color: #888; + display: inline-block; + font-size: small; + font-style: italic; + box-sizing: border-box; + margin: 0; + padding: 0 0.25em 0 0; + text-align: right; + vertical-align: bottom; + width: 20%; +} + +.spectermbody { + border-top: 1px solid #EEE; + padding: 0; +} + +.spectermbody .description .comment > p:first-child { + color: #444; + font-style: italic; + margin-bottom: 0.75em; +} + +dl { + margin: 0; + padding: 0; +} + +div.head { + margin-bottom: 1em; +} + +div.head h1 { + clear: both; + margin-top: 2em; +} + +div.head table { + margin-left: 2em; + margin-top: 2em; +} + +#menu li { + display: inline; +} + +.error { + color: #990A1B; +} + +.warning { + color: #7B6000; +} + +.success { + color: #546E00; +} + +.highlight, .codehilite { + margin-left: 2em; +} + +/* Dark mode */ +@media (prefers-color-scheme: dark) { + /* Dark generic page style */ + + html { + background: #222; + color: #DDD; + } + + a { + color: #B4C342; + } + + a:link { + color: #B4C342; + } + + a:visited { + color: #B4C342; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + color: #DDD; + } + + h1 a:link, h2 a:link, h3 a:link, h4 a:link, h5 a:link, h6 a:link { + color: #DDD; + } + + h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited { + color: #DDD; + } + + blockquote { + border-left: 1px solid #444; + } + + pre, code, kbd, samp { + color: #DDD; + } + + hr { + background-color: #333; + border: 0; + color: #666; + } + + th { + border: 1px solid #444; + } + + td { + border: 1px solid #444; + } + + footer { + color: #BBB; + } + + /* Dark specgen style */ + + #metabox { + color: #999; + } + + #shortdesc { + color: #999; + } + + #titlesep { + color: #444; + } + + .terminfo, .restriction { + color: #999; + } + + table.terminfo { + border-bottom: 1px solid #444; + border-left: 1px solid #444; + } + + .spectermbody { + border-top: 1px solid #444; + } + + .spectermbody .description .comment > p:first-child { + color: #BBB; + } + + .error { + color: #DC322F; + } + + .warning { + color: #B58900; + } + + .success { + color: #859900; + } + + #topbar { + border-bottom: 1px solid #444; + } +} + +/* Hard black for dark mode on mobile (since it's likely to be an OLED screen) */ +@media only screen and (hover: none) and (pointer: coarse) and (prefers-color-scheme: dark) { + html { + background: #000; + color: #CCC; + } +} diff --git a/bundles/meson.build b/bundles/meson.build new file mode 100644 index 00000000..851e3655 --- /dev/null +++ b/bundles/meson.build @@ -0,0 +1,4 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +subdir('ingen.lv2') diff --git a/doc/reference.doxygen.in b/doc/reference.doxygen.in deleted file mode 100644 index 3262d934..00000000 --- a/doc/reference.doxygen.in +++ /dev/null @@ -1,2394 +0,0 @@ -# Doxyfile 1.8.12 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all text -# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv -# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv -# for the list of possible encodings. -# The default value is: UTF-8. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = Ingen - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. This -# could be handy for archiving the generated documentation or if some version -# control system is used. - -PROJECT_NUMBER = @INGEN_VERSION@ - -# 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 a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify a logo or an icon that is included -# in the documentation. The maximum height of the logo should not exceed 55 -# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy -# the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = . - -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. -# The default value is: NO. - -CREATE_SUBDIRS = NO - -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII -# characters to appear in the names of generated files. If set to NO, non-ASCII -# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode -# U+3044. -# The default value is: NO. - -ALLOW_UNICODE_NAMES = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. -# The default value is: English. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member -# descriptions after the members that are listed in the file and class -# documentation (similar to Javadoc). Set to NO to disable this. -# The default value is: YES. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief -# description of a member or function before the detailed description -# -# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. -# The default value is: YES. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator that is -# used to form the text in various listings. Each string in this list, if found -# as the leading text of the brief description, will be stripped from the text -# and the result, after processing the whole list, is used as the annotated -# text. Otherwise, the brief description is used as-is. If left blank, the -# following values are used ($name is automatically replaced with the name of -# the entity):The $name class, The $name widget, The $name file, is, provides, -# specifies, contains, represents, a, an and the. - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief -# description. -# The default value is: NO. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. -# The default value is: NO. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path -# before files name in the file list and in the header files. If set to NO the -# shortest path that makes the file name unique will be used -# The default value is: YES. - -FULL_PATH_NAMES = NO - -# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. -# Stripping is only done if one of the specified strings matches the left-hand -# part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to -# strip. -# -# Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. -# This tag requires that the tag FULL_PATH_NAMES is set to YES. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the -# path mentioned in the documentation of a class, which tells the reader which -# header file to include in order to use a class. If left blank only the name of -# the header file containing the class definition is used. Otherwise one should -# specify the list of include paths that are normally passed to the compiler -# using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't -# support long names like on DOS, Mac, or CD-ROM. -# The default value is: NO. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) -# The default value is: NO. - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a -# multi-line C++ special comment block (i.e. a block of //! or /// comments) as -# a brief description. This used to be the default behavior. The new default is -# to treat a multi-line C++ comment block as a detailed description. Set this -# tag to YES if you prefer the old behavior instead. -# -# Note that setting this tag to YES also means that rational rose comments are -# not recognized any more. -# The default value is: NO. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new -# page for each member. If set to NO, the documentation of a member will be part -# of the file/class/namespace that contains it. -# The default value is: NO. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen -# uses this value to replace tabs by spaces in code fragments. -# Minimum value: 1, maximum value: 16, default value: 4. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that act as commands in -# the documentation. An alias has the form: -# name=value -# For example adding -# "sideeffect=@par Side Effects:\n" -# will allow you to put the command \sideeffect (or @sideeffect) in the -# documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. For -# instance, some of the names that are used will be different. The list of all -# members will be omitted, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or -# Python sources only. Doxygen will then generate output that is more tailored -# for that language. For instance, namespaces will be presented as packages, -# qualified scopes will look different, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources. Doxygen will then generate output that is tailored for Fortran. -# The default value is: NO. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for VHDL. -# The default value is: NO. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: -# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: -# Fortran. In the later case the parser tries to guess whether the code is fixed -# or free formatted code, this is the default for Fortran type files), VHDL. For -# instance to make doxygen treat .inc files as Fortran files (default is PHP), -# and .f files as C (default is Fortran), use: inc=Fortran f=C. -# -# Note: For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up -# to that level are automatically included in the table of contents, even if -# they do not have an id attribute. -# Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 0. -# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. - -TOC_INCLUDE_HEADINGS = 0 - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = YES - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. -# The default value is: NO. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. -# The default value is: NO. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. -# This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you -# should set this option to NO. -# The default value is: YES. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. -# The default value is: NO. - -DISTRIBUTE_GROUP_DOC = NO - -# If one adds a struct or class to a group and this option is enabled, then also -# any nested class or struct is added to the same group. By default this option -# is disabled and one has to add nested compounds explicitly via \ingroup. -# The default value is: NO. - -GROUP_NESTED_COMPOUNDS = NO - -# Set the SUBGROUPING tag to YES to allow class member groups of the same type -# (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent -# subgrouping. Alternatively, this can be done per class using the -# \nosubgrouping command. -# The default value is: YES. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions -# are shown inside the group in which they are included (e.g. using \ingroup) -# instead of on a separate page (for HTML and Man pages) or section (for LaTeX -# and RTF). -# -# Note that this feature does not work in combination with -# SEPARATE_MEMBER_PAGES. -# The default value is: NO. - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions -# with only public data fields or simple typedef fields will be shown inline in -# the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO, structs, classes, and unions are shown on a separate page (for HTML and -# Man pages) or section (for LaTeX and RTF). -# The default value is: NO. - -INLINE_SIMPLE_STRUCTS = YES - -# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or -# enum is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically be -# useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. -# The default value is: NO. - -TYPEDEF_HIDES_STRUCT = NO - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can be -# an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The -# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range -# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest -# the optimal cache size from a speed point of view. -# Minimum value: 0, maximum value: 9, default value: 0. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will -# be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal -# scope will be included in the documentation. -# The default value is: NO. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO, -# only classes defined in header files are included. Does not have any effect -# for Java sources. -# The default value is: YES. - -EXTRACT_LOCAL_CLASSES = NO - -# This flag is only useful for Objective-C code. If set to YES, local methods, -# which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO, only methods in the interface are -# included. -# The default value is: NO. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base name of -# the file that contains the anonymous namespace. By default anonymous namespace -# are hidden. -# The default value is: NO. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. -# The default value is: NO. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO, these -# blocks will be appended to the function's detailed documentation block. -# The default value is: NO. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation that is typed after a -# \internal command is included. If the tag is set to NO then the documentation -# will be excluded. Set it to YES to include the internal documentation. -# The default value is: NO. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES, the -# scope will be hidden. -# The default value is: NO. - -HIDE_SCOPE_NAMES = NO - -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will -# append additional text to a page's title, such as Class Reference. If set to -# YES the compound reference will be hidden. -# The default value is: NO. - -HIDE_COMPOUND_REFERENCE= NO - -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of -# the files that are included by a file in the documentation of that file. -# The default value is: YES. - -SHOW_INCLUDE_FILES = YES - -# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each -# grouped member an include statement to the documentation, telling the reader -# which file to include in order to use the member. -# The default value is: NO. - -SHOW_GROUPED_MEMB_INC = NO - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include -# files with double quotes in the documentation rather than with sharp brackets. -# The default value is: NO. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the -# documentation for inline members. -# The default value is: YES. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = NO - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief -# descriptions of file, namespace and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. Note that -# this will also influence the order of the classes in the class list. -# The default value is: NO. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the -# (brief and detailed) documentation of class members so that constructors and -# destructors are listed first. If set to NO the constructors will appear in the -# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. -# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief -# member documentation. -# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting -# detailed member documentation. -# The default value is: NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy -# of group names into alphabetical order. If set to NO the group names will -# appear in their defined order. -# The default value is: NO. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = YES - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between -# the prototype and the implementation of a member function even if there is -# only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still -# accept a match between prototype and implementation in such cases. -# The default value is: NO. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo -# list. This list is created by putting \todo commands in the documentation. -# The default value is: YES. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test -# list. This list is created by putting \test commands in the documentation. -# The default value is: YES. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug -# list. This list is created by putting \bug commands in the documentation. -# The default value is: YES. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) -# the deprecated list. This list is created by putting \deprecated commands in -# the documentation. -# The default value is: YES. - -GENERATE_DEPRECATEDLIST= NO - -# The ENABLED_SECTIONS tag can be used to enable conditional documentation -# sections, marked by \if <section_label> ... \endif and \cond <section_label> -# ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the -# initial value of a variable or macro / define can have for it to appear in the -# documentation. If the initializer consists of more lines than specified here -# it will be hidden. Use a value of 0 to hide initializers completely. The -# appearance of the value of individual variables and macros / defines can be -# controlled using \showinitializer or \hideinitializer command in the -# documentation regardless of this setting. -# Minimum value: 0, maximum value: 10000, default value: 30. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES, the -# list will mention the files that were used to generate the documentation. -# The default value is: YES. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = NO - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file -# version. For an example see the documentation. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can -# optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. -# -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE -# tag is left empty. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files containing -# the reference definitions. This must be a list of .bib files. The .bib -# extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. -# For LaTeX the style of the bibliography can be controlled using -# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. See also \cite for info how to create references. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = YES - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES -# this implies that the warnings are on. -# -# Tip: Turn warnings on while writing the documentation. -# The default value is: YES. - -WARNINGS = NO - -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = NO - -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. -# The default value is: YES. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that -# are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. -# The default value is: NO. - -WARN_NO_PARAMDOC = NO - -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. -# The default value is: NO. - -WARN_AS_ERROR = NO - -# The WARN_FORMAT tag determines the format of the warning messages that doxygen -# can produce. The string should contain the $file, $line, and $text tags, which -# will be replaced by the file and line number from which the warning originated -# and the warning text. Optionally the format may contain $version, which will -# be replaced by the version of the file (if it could be obtained via -# FILE_VERSION_FILTER) -# The default value is: $file:$line: $text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning and error -# messages should be written. If left blank the output is written to standard -# error (stderr). - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -INPUT = @INGEN_SRCDIR@/include - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: http://www.gnu.org/software/libiconv) for the list of -# possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, -# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command: -# -# <filter> <input-file> -# -# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the -# name of an input file. Doxygen will then use the output that the filter -# program writes to standard output. If FILTER_PATTERNS is specified, this tag -# will be ignored. -# -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: pattern=filter -# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how -# filters are used. If the FILTER_PATTERNS tag is empty or if none of the -# patterns match the file name, INPUT_FILTER is applied. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will also be used to filter the input files that are used for -# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). -# The default value is: NO. - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. -# The default value is: NO. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any -# special comment blocks from generated source code fragments. Normal C, C++ and -# Fortran comments will always remain visible. -# The default value is: YES. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. -# The default value is: NO. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES then for each documented function -# all documented entities called/used by that function will be listed. -# The default value is: NO. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES then the hyperlinks from functions in REFERENCES_RELATION and -# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will -# link to the documentation. -# The default value is: YES. - -REFERENCES_LINK_SOURCE = YES - -# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -# source code will show a tooltip with additional information such as prototype, -# brief description and links to the definition and documentation. Since this -# will make the HTML file larger and loading of large files a bit slower, you -# can opt to disable this feature. -# The default value is: YES. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -SOURCE_TOOLTIPS = YES - -# If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in -# source browser. The htags tool is part of GNU's global source tagging system -# (see http://www.gnu.org/software/global/global.html). You will need version -# 4.8.6 or higher. -# -# To use it do the following: -# - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file -# - Make sure the INPUT points to the root of the source tree -# - Run doxygen as normal -# -# Doxygen will invoke htags (and that will in turn invoke gtags), so these -# tools must be available from the command line (i.e. in the search path). -# -# The result: instead of the source browser generated by doxygen, the links to -# source code will now point to the output of htags. -# The default value is: NO. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a -# verbatim copy of the header file for each class for which an include is -# specified. Set to NO to disable this. -# See also: Section \class. -# The default value is: YES. - -VERBATIM_HEADERS = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all -# compounds will be generated. Enable this if the project contains a lot of -# classes, structs, unions or interfaces. -# The default value is: YES. - -ALPHABETICAL_INDEX = NO - -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 1 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each -# generated HTML page (for example: .htm, .php, .asp). -# The default value is: .html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a -# standard header. -# -# To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. -# the setting GENERATE_TREEVIEW). It is highly recommended to start with a -# default header using -# doxygen -w html new_header.html new_footer.html new_stylesheet.css -# YourConfigFile -# and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally -# uses. -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description -# of the possible markers and block names see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard -# footer. See HTML_HEADER for more information on how to generate a default -# footer and what special commands can be used inside the footer. See also -# section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style -# sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. -# See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. -# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as -# it is more robust and this tag (HTML_STYLESHEET) will in the future become -# obsolete. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_STYLESHEET = @INGEN_SRCDIR@/doc/style.css - -# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefore more robust against future updates. -# Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that the -# files will be copied as-is; there are no commands or markers available. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# http://en.wikipedia.org/wiki/Hue for more information. For instance the value -# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 -# purple, and 360 is red again. -# Minimum value: 0, maximum value: 359, default value: 220. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_HUE = 160 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A -# value of 255 will produce the most vivid colors. -# Minimum value: 0, maximum value: 255, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_SAT = 40 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the -# luminance component of the colors in the HTML output. Values below 100 -# gradually make the output lighter, whereas values above 100 make the output -# darker. The value divided by 100 is the actual gamma applied, so 80 represents -# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not -# change the gamma. -# Minimum value: 40, maximum value: 240, default value: 80. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = NO - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = YES - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries -# shown in the various tree structured indices initially; the user can expand -# and collapse entries dynamically later on. Doxygen will expand the tree to -# such a level that at most the specified number of entries are visible (unless -# a fully collapsed tree already exceeds this amount). So setting the number of -# entries 1 will produce a full collapsed tree by default. 0 is a special value -# representing an infinite number of entries and will result in a full expanded -# tree by default. -# Minimum value: 0, maximum value: 9999, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files will be -# generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: http://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_DOCSET = NO - -# This tag determines the name of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# The default value is: Doxygen generated docs. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# This tag specifies a string that should uniquely identify the documentation -# set bundle. This should be a reverse domain-name style string, e.g. -# com.mycompany.MyDocSet. Doxygen will append .docset to the name. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. -# The default value is: org.doxygen.Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. -# The default value is: Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three -# additional HTML index files: index.hhp, index.hhc, and index.hhk. The -# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. -# -# The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML -# files are now used as the Windows 98 help format, and will replace the old -# Windows help format (.hlp) on all Windows platforms in the future. Compressed -# HTML files also contain an index, a table of contents, and you can search for -# words in the documentation. The HTML workshop also contains a viewer for -# compressed HTML files. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_HTMLHELP = NO - -# The CHM_FILE tag can be used to specify the file name of the resulting .chm -# file. You can add a path in front of the file if the result should not be -# written to the html output directory. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_FILE = - -# The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. -# The file has to be specified with full path. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -HHC_LOCATION = - -# The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -GENERATE_CHI = NO - -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) -# and project file content. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_INDEX_ENCODING = - -# The BINARY_TOC flag controls whether a binary table of contents is generated -# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it -# enables the Previous and Next buttons. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members to -# the table of contents of the HTML help documentation and to the tree view. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -TOC_EXPAND = YES - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- -# folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be -# generated, together with the HTML files, they form an Eclipse help plugin. To -# install this plugin and make it available under the help contents menu in -# Eclipse, the contents of the directory containing the HTML and XML files needs -# to be copied into the plugins directory of eclipse. The name of the directory -# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. -# After copying Eclipse needs to be restarted before the help appears. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the Eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have this -# name. Each documentation set should have its own identifier. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# If you want full control over the layout of the generated HTML pages it might -# be necessary to disable the index and replace it with your own. The -# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top -# of each HTML page. A value of NO enables the index and the value YES disables -# it. Since the tabs in the index contain the same information as the navigation -# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. If the tag -# value is set to YES, a side panel will be generated containing a tree-like -# index structure (just like the one that is generated for HTML Help). For this -# to work a browser that supports JavaScript, DHTML, CSS and frames is required -# (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_TREEVIEW = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. -# -# Note that a value of 0 will completely suppress the enum values from appearing -# in the overview section. -# Minimum value: 0, maximum value: 20, default value: 4. -# This tag requires that the tag GENERATE_HTML is set to YES. - -ENUM_VALUES_PER_LINE = 1 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used -# to set the initial width (in pixels) of the frame in which the tree is shown. -# Minimum value: 0, maximum value: 1500, default value: 250. -# This tag requires that the tag GENERATE_HTML is set to YES. - -TREEVIEW_WIDTH = 250 - -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to -# external symbols imported via tag files in a separate window. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of LaTeX formulas included as images in -# the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML -# output directory to force them to be regenerated. -# Minimum value: 8, maximum value: 50, default value: 10. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering -# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX -# installed or if you want to formulas look prettier in the HTML output. When -# enabled you may also need to install MathJax separately and configure the path -# to it using the MATHJAX_RELPATH option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. -# Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. -# The default value is: HTML-CSS. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from http://www.mathjax.org before deployment. -# The default value is: http://cdn.mathjax.org/mathjax/latest. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax -# extension names that should be enabled during MathJax rendering. For example -# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an -# example see the documentation. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and -# should work on any modern browser. Note that when using HTML help -# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) -# there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then -# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to -# search using the keyboard; to jump to the search box use <access key> + S -# (what the <access key> is depends on the OS and browser, but it is typically -# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down -# key> to jump into the search results window, the results can be navigated -# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel -# the search. The filter options can be selected when the cursor is inside the -# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> -# to select a filter and <Enter> or <escape> to activate or cancel the filter -# option. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -SEARCHENGINE = NO - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. There -# are two flavors of web server based searching depending on the EXTERNAL_SEARCH -# setting. When disabled, doxygen will generate a PHP script for searching and -# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing -# and searching needs to be provided by external tools. See the section -# "External Indexing and Searching" for details. -# The default value is: NO. -# This tag requires that the tag SEARCHENGINE is set to YES. - -SERVER_BASED_SEARCH = NO - -# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP -# script for searching. Instead the search results are written to an XML file -# which needs to be processed by an external indexer. Doxygen will invoke an -# external search engine pointed to by the SEARCHENGINE_URL option to obtain the -# search results. -# -# Doxygen ships with an example indexer (doxyindexer) and search engine -# (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). -# -# See the section "External Indexing and Searching" for details. -# The default value is: NO. -# This tag requires that the tag SEARCHENGINE is set to YES. - -EXTERNAL_SEARCH = NO - -# The SEARCHENGINE_URL should point to a search engine hosted by a web server -# which will return the search results when EXTERNAL_SEARCH is enabled. -# -# Doxygen ships with an example indexer (doxyindexer) and search engine -# (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). See the section "External Indexing and -# Searching" for details. -# This tag requires that the tag SEARCHENGINE is set to YES. - -SEARCHENGINE_URL = - -# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed -# search data is written to a file for indexing by an external tool. With the -# SEARCHDATA_FILE tag the name of this file can be specified. -# The default file is: searchdata.xml. -# This tag requires that the tag SEARCHENGINE is set to YES. - -SEARCHDATA_FILE = searchdata.xml - -# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the -# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is -# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple -# projects and redirect the results back to the right project. -# This tag requires that the tag SEARCHENGINE is set to YES. - -EXTERNAL_SEARCH_ID = - -# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen -# projects other than the one defined by this configuration file, but that are -# all added to the same external search index. Each project needs to have a -# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of -# to a relative location where the documentation can be found. The format is: -# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... -# This tag requires that the tag SEARCHENGINE is set to YES. - -EXTRA_SEARCH_MAPPINGS = - -#--------------------------------------------------------------------------- -# Configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. -# The default value is: YES. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: latex. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. -# -# Note that when enabling USE_PDFLATEX this option is only used for generating -# bitmaps for formulas in the HTML output, but not in the Makefile that is -# written to the output directory. -# The default file is: latex. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate -# index for LaTeX. -# The default file is: makeindex. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX -# documents. This may be useful for small projects and may help to save some -# trees in general. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -COMPACT_LATEX = YES - -# The PAPER_TYPE tag can be used to set the paper type that is used by the -# printer. -# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x -# 14 inches) and executive (7.25 x 10.5 inches). -# The default value is: a4. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names -# that should be included in the LaTeX output. The package can be specified just -# by its name or with the correct syntax as to be used with the LaTeX -# \usepackage command. To get the times font for instance you can specify : -# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} -# To use the option intlimits with the amsmath package you can specify: -# EXTRA_PACKAGES=[intlimits]{amsmath} -# If left blank no extra packages will be included. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the -# generated LaTeX document. The header should contain everything until the first -# chapter. If it is left blank doxygen will generate a standard header. See -# section "Doxygen usage" for information on how to let doxygen write the -# default header to a separate file. -# -# Note: Only use a user-defined header if you know what you are doing! The -# following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber, -# $projectbrief, $projectlogo. Doxygen will replace $title with the empty -# string, for the replacement values of the other commands the user is referred -# to HTML_HEADER. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the -# generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. See -# LATEX_HEADER for more information on how to generate a default footer and what -# special commands can be used inside the footer. -# -# Note: Only use a user-defined footer if you know what you are doing! -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_FOOTER = - -# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# LaTeX style sheets that are included after the standard style sheets created -# by doxygen. Using this option one can overrule certain style aspects. Doxygen -# will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_EXTRA_STYLESHEET = - -# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the LATEX_OUTPUT output -# directory. Note that the files will be copied as-is; there are no commands or -# markers available. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_EXTRA_FILES = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is -# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will -# contain links (just like the HTML output) instead of page references. This -# makes the output suitable for online browsing using a PDF viewer. -# The default value is: YES. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES, to get a -# higher quality PDF documentation. -# The default value is: YES. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode -# command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. This option is also used -# when generating formulas in HTML. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_BATCHMODE = NO - -# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the -# index chapters (such as File Index, Compound Index, etc.) in the output. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_HIDE_INDICES = YES - -# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source -# code with syntax highlighting in the LaTeX output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_SOURCE_CODE = NO - -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. See -# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. -# The default value is: plain. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_BIB_STYLE = plain - -# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_TIMESTAMP = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The -# RTF output is optimized for Word 97 and may not look too pretty with other RTF -# readers/editors. -# The default value is: NO. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: rtf. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF -# documents. This may be useful for small projects and may help to save some -# trees in general. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will -# contain hyperlink fields. The RTF file will contain links (just like the HTML -# output) instead of page references. This makes the output suitable for online -# browsing using Word or some other Word compatible readers that support those -# fields. -# -# Note: WordPad (write) and others do not support links. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's config -# file, i.e. a series of assignments. You only have to provide replacements, -# missing definitions are set to their default value. -# -# See also section "Doxygen usage" for information on how to generate the -# default style sheet that doxygen normally uses. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's config file. A template extensions file can be generated -# using doxygen -e rtf extensionFile. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_EXTENSIONS_FILE = - -# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code -# with syntax highlighting in the RTF output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for -# classes and files. -# The default value is: NO. - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. A directory man3 will be created inside the directory specified by -# MAN_OUTPUT. -# The default directory is: man. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to the generated -# man pages. In case the manual section does not start with a number, the number -# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is -# optional. -# The default value is: .3. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_EXTENSION = .3 - -# The MAN_SUBDIR tag determines the name of the directory created within -# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by -# MAN_EXTENSION with the initial . removed. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_SUBDIR = - -# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it -# will generate one additional man file for each entity documented in the real -# man page(s). These additional files only source the real man page, but without -# them the man command would be unable to find the correct page. -# The default value is: NO. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that -# captures the structure of the code including all documentation. -# The default value is: NO. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: xml. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_OUTPUT = xml - -# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program -# listings (including syntax highlighting and cross-referencing information) to -# the XML output. Note that enabling this will significantly increase the size -# of the XML output. -# The default value is: YES. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the DOCBOOK output -#--------------------------------------------------------------------------- - -# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files -# that can be used to generate PDF. -# The default value is: NO. - -GENERATE_DOCBOOK = NO - -# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in -# front of it. -# The default directory is: docbook. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_OUTPUT = docbook - -# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the -# program listings (including syntax highlighting and cross-referencing -# information) to the DOCBOOK output. Note that enabling this will significantly -# increase the size of the DOCBOOK output. -# The default value is: NO. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_PROGRAMLISTING = NO - -#--------------------------------------------------------------------------- -# Configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sf.net) file that captures the -# structure of the code including all documentation. Note that this feature is -# still experimental and incomplete at the moment. -# The default value is: NO. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module -# file that captures the structure of the code including all documentation. -# -# Note that this feature is still experimental and incomplete at the moment. -# The default value is: NO. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary -# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI -# output from the Perl module output. -# The default value is: NO. -# This tag requires that the tag GENERATE_PERLMOD is set to YES. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely -# formatted so it can be parsed by a human reader. This is useful if you want to -# understand what is going on. On the other hand, if this tag is set to NO, the -# size of the Perl module output will be much smaller and Perl will parse it -# just the same. -# The default value is: YES. -# This tag requires that the tag GENERATE_PERLMOD is set to YES. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file are -# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful -# so different doxyrules.make files included by the same Makefile don't -# overwrite each other's variables. -# This tag requires that the tag GENERATE_PERLMOD is set to YES. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all -# C-preprocessor directives found in the sources and include files. -# The default value is: YES. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names -# in the source code. If set to NO, only conditional compilation will be -# performed. Macro expansion can be done in a controlled way by setting -# EXPAND_ONLY_PREDEF to YES. -# The default value is: NO. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then -# the macro expansion is limited to the macros specified with the PREDEFINED and -# EXPAND_AS_DEFINED tags. -# The default value is: NO. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES, the include files in the -# INCLUDE_PATH will be searched if a #include is found. -# The default value is: YES. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by the -# preprocessor. -# This tag requires that the tag SEARCH_INCLUDES is set to YES. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will be -# used. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that are -# defined before the preprocessor is started (similar to the -D option of e.g. -# gcc). The argument of the tag is a list of macros of the form: name or -# name=definition (no spaces). If the definition and the "=" are omitted, "=1" -# is assumed. To prevent a macro definition from being undefined via #undef or -# recursively expanded use the := operator instead of the = operator. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this -# tag can be used to specify a list of macro names that should be expanded. The -# macro definition that is found in the sources will be used. Use the PREDEFINED -# tag if you want to use a different macro definition that overrules the -# definition found in the source code. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all references to function-like macros that are alone on a line, have -# an all uppercase name, and do not end with a semicolon. Such function macros -# are typically used for boiler-plate code, and will confuse the parser if not -# removed. -# The default value is: YES. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration options related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES tag can be used to specify one or more tag files. For each tag -# file the location of the external documentation should be added. The format of -# a tag file without this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where loc1 and loc2 can be relative or absolute paths or URLs. See the -# section "Linking to external documentation" for more information about the use -# of tag files. -# Note: Each tag file must have a unique name (where the name does NOT include -# the path). If a tag file is not located in the directory in which doxygen is -# run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create a -# tag file that is based on the input files it reads. See section "Linking to -# external documentation" for more information about the usage of tag files. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES, all external class will be listed in -# the class index. If set to NO, only the inherited external classes will be -# listed. -# The default value is: NO. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will be -# listed. -# The default value is: YES. - -EXTERNAL_GROUPS = YES - -# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in -# the related pages index. If set to NO, only the current project's pages will -# be listed. -# The default value is: YES. - -EXTERNAL_PAGES = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram -# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to -# NO turns the diagrams off. Note that this option also works with HAVE_DOT -# disabled, but it is recommended to install and use dot, since it yields more -# powerful graphs. -# The default value is: YES. - -CLASS_DIAGRAMS = YES - -# You can include diagrams made with dia in doxygen documentation. Doxygen will -# then run dia to produce the diagram and insert it in the documentation. The -# DIA_PATH tag allows you to specify the directory where the dia binary resides. -# If left empty dia is assumed to be found in the default search path. - -DIA_PATH = - -# If set to YES the inheritance and collaboration graphs will hide inheritance -# and usage relations if the target is undocumented or is not a class. -# The default value is: YES. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz (see: -# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent -# Bell Labs. The other options in this section have no effect if this option is -# set to NO -# The default value is: NO. - -HAVE_DOT = YES - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed -# to run in parallel. When set to 0 doxygen will base this on the number of -# processors available in the system. You can set it explicitly to a value -# larger than 0 to get control over the balance between CPU load and processing -# speed. -# Minimum value: 0, maximum value: 32, default value: 0. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_NUM_THREADS = 0 - -# When you want a differently looking font in the dot files that doxygen -# generates you can specify the font name using DOT_FONTNAME. You need to make -# sure dot is able to find the font, which can be done by putting it in a -# standard location or by setting the DOTFONTPATH environment variable or by -# setting DOT_FONTPATH to the directory containing the font. -# The default value is: Helvetica. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_FONTNAME = - -# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of -# dot graphs. -# Minimum value: 4, maximum value: 24, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the default font as specified with -# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set -# the path where dot can find it using this tag. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_FONTPATH = - -# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for -# each documented class showing the direct and indirect inheritance relations. -# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a -# graph for each documented class showing the direct and indirect implementation -# dependencies (inheritance, containment, and class references variables) of the -# class with other documented classes. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -UML_LOOK = NO - -# If the UML_LOOK tag is enabled, the fields and methods are shown inside the -# class node. If there are many fields or methods and many nodes the graph may -# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the -# number of items for each type to make the size more manageable. Set this to 0 -# for no limit. Note that the threshold may be exceeded by 50% before the limit -# is enforced. So when you set the threshold to 10, up to 15 fields may appear, -# but if the number exceeds 15, the total amount of fields shown is limited to -# 10. -# Minimum value: 0, maximum value: 100, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. - -UML_LIMIT_NUM_FIELDS = 10 - -# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and -# collaboration graphs will show the relations between templates and their -# instances. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -TEMPLATE_RELATIONS = NO - -# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to -# YES then doxygen will generate a graph for each documented file showing the -# direct and indirect include dependencies of the file with other documented -# files. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -INCLUDE_GRAPH = YES - -# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are -# set to YES then doxygen will generate a graph for each documented file showing -# the direct and indirect include dependencies of the file with other documented -# files. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH tag is set to YES then doxygen will generate a call -# dependency graph for every global function or class method. -# -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. Disabling a call graph can be -# accomplished by means of the command \hidecallgraph. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller -# dependency graph for every global function or class method. -# -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. Disabling a caller graph can be -# accomplished by means of the command \hidecallergraph. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical -# hierarchy of all classes instead of a textual one. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the -# dependencies a directory has on other directories in a graphical way. The -# dependency relations are determined by the #include relations between the -# files in the directories. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. For an explanation of the image formats see the section -# output formats in the documentation of the dot tool (Graphviz (see: -# http://www.graphviz.org/)). -# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order -# to make the SVG files visible in IE 9+ (other browsers do not have this -# requirement). -# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, -# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and -# png:gdiplus:gdiplus. -# The default value is: png. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_IMAGE_FORMAT = png - -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. -# -# Note that this requires a modern browser other than Internet Explorer. Tested -# and working are Firefox, Chrome, Safari, and Opera. -# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make -# the SVG files visible. Older versions of IE do not have SVG support. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -INTERACTIVE_SVG = NO - -# The DOT_PATH tag can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the \dotfile -# command). -# This tag requires that the tag HAVE_DOT is set to YES. - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the \mscfile -# command). - -MSCFILE_DIRS = - -# The DIAFILE_DIRS tag can be used to specify one or more directories that -# contain dia files that are included in the documentation (see the \diafile -# command). - -DIAFILE_DIRS = - -# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the -# path where java can find the plantuml.jar file. If left blank, it is assumed -# PlantUML is not used or called during a preprocessing step. Doxygen will -# generate a warning when it encounters a \startuml command in this case and -# will not generate output for the diagram. - -PLANTUML_JAR_PATH = - -# When using plantuml, the specified paths are searched for files specified by -# the !include statement in a plantuml block. - -PLANTUML_INCLUDE_PATH = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes -# that will be shown in the graph. If the number of nodes in a graph becomes -# larger than this value, doxygen will truncate the graph, which is visualized -# by representing a node as a red box. Note that doxygen if the number of direct -# children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that -# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. -# Minimum value: 0, maximum value: 10000, default value: 50. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs -# generated by dot. A depth value of 3 means that only nodes reachable from the -# root by following a path via at most 3 edges will be shown. Nodes that lay -# further from the root node will be omitted. Note that setting this option to 1 -# or 2 may greatly reduce the computation time needed for large code bases. Also -# note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. -# Minimum value: 0, maximum value: 1000, default value: 0. -# This tag requires that the tag HAVE_DOT is set to YES. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not seem -# to support this out of the box. -# -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_TRANSPARENT = YES - -# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) support -# this, this feature is disabled by default. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page -# explaining the meaning of the various boxes and arrows in the dot generated -# graphs. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot -# files that are used to generate the various graphs. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_CLEANUP = YES diff --git a/doc/style.css b/doc/style.css deleted file mode 100644 index 172be516..00000000 --- a/doc/style.css +++ /dev/null @@ -1,1145 +0,0 @@ -body { - max-width: 80em; - margin: 0; - margin-left: auto; - margin-right: auto; - background: #FFF; - color: #000; -} - -#titlearea { - display: none; -} - -h1 { - font-size: 180%; - font-weight: 900; -} - -h2 { - font-size: 140%; - font-weight: 700; -} - -h3 { - font-size: 120%; - font-weight: 700; -} - -h4 { - font-size: 110%; - font-weight: 700; -} - -h5 { - font-size: 100%; - font-weight: 700; -} - -h6 { - font-size: 100%; - font-weight: 600; -} - -p { - margin: 0 0 1em 0; -} - -dt { - font-weight: 700; -} - -p.startli,p.startdd,p.starttd { - margin-top: 2px; -} - -p.endli { - margin-bottom: 0; -} - -p.enddd { - margin-bottom: 4px; -} - -p.endtd { - margin-bottom: 2px; -} - -caption { - font-weight: 700; -} - -span.legend { - font-size: 70%; - text-align: center; -} - -h3.version { - font-size: 90%; - text-align: center; -} - -div.qindex,div.navtab { - background-color: #EBEFF6; - border: 1px solid #A3B4D7; - text-align: center; - margin: 2px; - padding: 2px; -} - -div.navtab { - margin-right: 15px; -} - -/* @group Link Styling */ -a { - color: #546E00; - text-decoration: none; -} - -.contents a:visited { - color: #344E00; -} - -a:hover { - text-decoration: underline; -} - -a.qindexHL { - background-color: #9CAFD4; - color: #FFF; - border: 1px double #869DCA; -} - -code { - color: #444; -} - -a.code { - color: #4665A2; -} - -a.codeRef { - color: #4665A2; -} - -/* @end */ -dl.el { - margin-left: -1cm; -} - -.fragment { - font-family: monospace, fixed; - font-size: 105%; - padding-bottom: 1em; -} - -pre.fragment { - border: 1px solid #C4C4C4; - background-color: #F9F9F9; - padding: 4px 6px; - margin: 4px 8px 4px 2px; - overflow: auto; - font-size: 9pt; - line-height: 125%; -} - -div.ah { - background-color: #000; - font-weight: 700; - color: #FFF; - margin-bottom: 3px; - margin-top: 3px; - padding: .2em; - border: thin solid #333; -} - -div.groupHeader { - margin-left: 16px; - margin-top: 12px; - margin-bottom: 6px; - font-weight: 700; -} - -a + h2.groupheader { - display: none; -} - -div.groupText { - margin-left: 16px; - font-style: italic; -} - -div.contents { - margin-top: 10px; - margin-left: 10px; - margin-right: 10px; -} - -td.indexkey { - background-color: #EBEFF6; - font-weight: 700; - border: 1px solid #C4CFE5; - margin: 2px 0; - padding: 2px 10px; -} - -td.indexvalue { - background-color: #EBEFF6; - border: 1px solid #C4CFE5; - padding: 2px 10px; - margin: 2px 0; -} - -tr.memlist { - background-color: #EEF1F7; -} - -p.formulaDsp { - text-align: center; -} - -img.formulaInl { - vertical-align: middle; -} - -div.center { - text-align: center; - margin-top: 0; - margin-bottom: 0; - padding: 0; -} - -div.center img { - border: 0; -} - -address.footer { - text-align: right; - padding-right: 12px; -} - -img.footer { - border: 0; - vertical-align: middle; -} - -/* @group Code Colorization */ -span.keyword { - color: green; -} - -span.keywordtype { - color: #3E873E; -} - -span.keywordflow { - color: #e08000; -} - -span.comment { - color: maroon; -} - -span.preprocessor { - color: #806020; -} - -span.stringliteral { - color: #002080; -} - -span.charliteral { - color: teal; -} - -span.vhdldigit { - color: #F0F; -} - -span.vhdlkeyword { - color: #700070; -} - -span.vhdllogic { - color: red; -} - -/* @end */ -td.tiny { - font-size: 75%; -} - -.dirtab { - padding: 4px; - border-collapse: collapse; - border: 1px solid #A3B4D7; -} - -th.dirtab { - background: #EBEFF6; - font-weight: 700; -} - -hr { - height: 0; - border: none; - border-top: 1px solid #DDD; - margin: 2em 0 1em; -} - -hr.footer { - height: 1px; -} - -/* @group Member Descriptions */ -table.memberdecls { - border-spacing: 0.125em; -} - -h2.groupheader { - margin: 1em 0 0.5em 0; -} - -.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,.memTemplItemLeft,.memTemplItemRight,.memTemplParams { - margin: 0; - padding: 0; -} - -.mdescLeft,.mdescRight { - color: #555; -} - -.memItemLeft,.memItemRight,.memTemplParams { - border: 0; - font-family: monospace, fixed; - font-size: 90%; -} - -.memItemLeft,.memTemplItemLeft { - white-space: nowrap; - padding-left: 2em; - padding-right: 1em; -} - -.memItemLeft a.el { - font-weight: bold; -} - -.memTemplParams { - color: #464646; - white-space: nowrap; -} - -td.memSeparator { - display: none; -} - -td.mlabels-right { - vertical-align: top; - padding-top: 4px; - color: #AA6; -} - -.memtitle { - display: none; -} - -/* @end */ -/* @group Member Details */ -/* Styles for detailed member documentation */ -.memtemplate { - font-size: 80%; - color: #4665A2; - font-weight: bold; -} - -.memnav { - background-color: #EBEFF6; - border: 1px solid #A3B4D7; - text-align: center; - margin: 2px; - margin-right: 15px; - padding: 2px; -} - -.memitem { - padding: 0; - margin: 1em 0 1em 0; -} - -.memproto { - padding: 0; - font-size: 110%; - font-weight: bold; - color: #000; -} - -.memproto .paramname { - color: #444; - font-style: normal; -} - -.memdoc { - padding: 0 0 0.5em 2em; -} - -.paramkey { - text-align: right; -} - -.paramtype { - color: #3E873E; - white-space: nowrap; -} - -.paramname { - color: #444; - white-space: nowrap; - font-weight: bold; -} - -td.paramname { - vertical-align: top; -} - -.fieldname { - color: #000; -} - -td.fieldname { - padding-right: 1em; - vertical-align: top; -} - -td.fieldtype { - vertical-align: top; - color: #444; -} - -td.fielddoc p { - margin: 0; -} - -/* @end */ -/* @group Directory (tree) */ -/* for the tree view */ -.ftvtree { - font-family: sans-serif; - margin: 0; -} - -/* these are for tree view when used as main index */ -.directory { - font-size: small; - margin: 0.5em; -} - -.directory h3 { - margin: 0; - margin-top: 1em; - font-size: 11pt; -} - -.directory > h3 { - margin-top: 0; -} - -.directory p { - margin: 0; - white-space: nowrap; -} - -.directory div { - display: none; - margin: 0; -} - -.directory img { - vertical-align: -30%; -} - -/* these are for tree view when not used as main index */ -.directory-alt { - font-size: 100%; - font-weight: bold; -} - -.directory-alt h3 { - margin: 0; - margin-top: 1em; - font-size: 11pt; -} - -.directory-alt > h3 { - margin-top: 0; -} - -.directory-alt p { - margin: 0; - white-space: nowrap; -} - -.directory-alt div { - display: none; - margin: 0; -} - -.directory-alt img { - vertical-align: -30%; -} - -/* @end */ -div.dynheader { - margin-top: 8px; -} - -address { - font-style: normal; - color: #2A3D61; -} - -table.doxtable { - border-collapse: collapse; - margin: 0.5em; -} - -table.doxtable td,table.doxtable th { - border: 1px solid #DDD; - padding: 3px 7px 2px; -} - -table.doxtable th { - background-color: #F3F3F3; - color: #000; - padding-bottom: 4px; - padding-top: 5px; - text-align: left; - font-weight: bold; -} - -.tabsearch { - top: 0; - left: 10px; - height: 36px; - z-index: 101; - overflow: hidden; - font-size: 13px; -} - -div.navpath { - padding: 0.25em; -} - -.navpath ul { - font-size: x-small; - color: #8AA0CC; - overflow: hidden; - margin: 0; - padding: 0; -} - -.navpath li { - list-style-type: none; - float: left; - padding-left: 10px; - padding-right: 15px; - color: #364D7C; -} - -.navpath a { - display: block; - text-decoration: none; - outline: none; -} - -.navpath a:hover { - color: #6884BD; -} - -div.summary { - float: right; - font-size: x-small; - padding: 0.25em 0.5em 0 0; - width: 50%; - text-align: right; -} - -div.summary a { - white-space: nowrap; -} - -div.header { - background-color: #F3F3F3; - margin: 0; - border: 0; -} - -div.headertitle { - font-size: 180%; - font-weight: bold; - color: #FFF; - padding: 0.125em 0.25em 0.125em 0.25em; - background-color: #333; - background: linear-gradient(to bottom, #333 0%, #111 100%); - border: solid 1px #444; - border-top: 0; - border-radius: 0 0 6px 6px; -} - -div.line { - font-family: monospace, fixed; - font-size: 13px; - min-height: 13px; - line-height: 1.0; - text-wrap: avoid; - white-space: pre-wrap; - text-indent: -53px; - padding-left: 53px; - padding-bottom: 0; - margin: 0; -} - -.glow { - background-color: cyan; - box-shadow: 0 0 10px cyan; -} - -span.lineno { - padding-right: 4px; - text-align: right; - border-right: 2px solid #0F0; - background-color: #E8E8E8; - white-space: pre; -} -span.lineno a { - background-color: #D8D8D8; -} - -span.lineno a:hover { - background-color: #C8C8C8; -} - -.tabs, .tabs2, .navpath { - background-image: none; - background-color: #333; - background: linear-gradient(to bottom, #333 0%, #111 100%); - border: 0; - border-bottom: solid 2px #000; - padding: 0; - padding-top: 2px; - font-size: small; -} - -#navrow1 { - border: 0; -} - -th { - text-align: left; -} - -.mlabel { - padding: 0.125em; -} - -/* tabs*/ - -.tablist { - margin: 0; - padding: 0; - display: table; -} - -.tablist li { - display: table-cell; - line-height: 2em; - list-style: none; - background-color: #333; - background: linear-gradient(to bottom, #444 0%, #222 100%); - border: 1px solid #222; - border-bottom: 0; - border-radius: 6px 6px 0 0; - color: #DDD; -} - -.tablist a { - display: block; - padding: 0 20px; - font-weight: bold; - color: #859900; - text-decoration: none; - outline: none; -} - -.header a { - color: #859900; -} - -.tabs3 .tablist a { - padding: 0 10px; -} - -.tablist a:hover { - color: #fff; - text-decoration: none; -} - -.tablist li.current a { - color: #fff; -} - -span.icon { - display: none; -} - -/* nav bar */ - -.sm { - position: relative; - z-index: 9999; -} - -.sm,.sm ul,.sm li { - display: block; - list-style: none; - margin: 0; - padding: 0; - line-height: normal; - direction: ltr; - text-align: left; - -webkit-tap-highlight-color: rgba(0,0,0,0); -} - -.sm-rtl,.sm-rtl ul,.sm-rtl li { - direction: rtl; - text-align: right; -} - -.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6 { - margin: 0; - padding: 0; -} - -.sm ul { - display: none; -} - -.sm li,.sm a { - position: relative; -} - -.sm a { - display: block; -} - -.sm a.disabled { - cursor: not-allowed; -} - -.sm:after { - content: "\00a0"; - display: block; - height: 0; - font: 0/0 serif; - clear: both; - visibility: hidden; - overflow: hidden; -} - -.sm,.sm *,.sm :before,.sm :after { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} - -#doc-content { - overflow: auto; - display: block; - padding: 0; - margin: 0; - -webkit-overflow-scrolling: touch; -} - -.sm-dox { - background-image: none; - background-color: #333; - background: linear-gradient(to bottom, #333 0%, #111 100%); - color: #fff; -} - -.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active { - padding: 0 12px; - padding-right: 43px; - font-size: small; - font-weight: 600; - line-height: auto; - text-decoration: none; - text-shadow: none; - color: inherit; - outline: 0; -} - -.sm-dox a:hover { - background-image: none; - background-repeat: repeat-x; - color: inherit; - text-shadow: 0 1px 1px #000; -} - -.sm-dox a.current { - color: #d23600; -} - -.sm-dox a.disabled { - color: #bbb; -} - -.sm-dox a span.sub-arrow { - position: absolute; - top: 50%; - margin-top: -14px; - left: auto; - right: 3px; - width: 28px; - height: 28px; - overflow: hidden; - font: bold 12px/28px monospace !important; - text-align: center; - text-shadow: none; - background: rgba(255,255,255,0.5); - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - border-radius: 5px; -} - -.sm-dox a.highlighted span.sub-arrow:before { - display: block; - content: '-'; -} - -.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a { - -moz-border-radius: 5px 5px 0 0; - -webkit-border-radius: 5px; - border-radius: 5px 5px 0 0; -} - -.sm-dox>li:last-child>a,.sm-dox>li:last-child>:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul { - -moz-border-radius: 0 0 5px 5px; - -webkit-border-radius: 0; - border-radius: 0 0 5px 5px; -} - -.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>:not(ul) a.highlighted { - -moz-border-radius: 0; - -webkit-border-radius: 0; - border-radius: 0; -} - -.sm-dox ul { - background: rgba(162,162,162,0.1); -} - -.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active { - font-size: 12px; - border-left: 8px solid transparent; - line-height: auto; - text-shadow: none; - background-color: #fff; - background-image: none; -} - -.sm-dox ul a:hover { - background-image: none; - background-repeat: repeat-x; - color: inherit; - text-shadow: 0 1px 1px #000; -} - -.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active { - border-left: 16px solid transparent; -} - -.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active { - border-left: 24px solid transparent; -} - -.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active { - border-left: 32px solid transparent; -} - -.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active { - border-left: 40px solid transparent; -} - -@media(min-width:768px) { - .sm-dox ul { - position: absolute; - width: 12em; - } - - .sm-dox li { - float: left; - } - - .sm-dox.sm-rtl li { - float: right; - } - - .sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li { - float: none; - } - - .sm-dox a { - white-space: nowrap; - } - - .sm-dox ul a,.sm-dox.sm-vertical a { - white-space: normal; - } - - .sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a { - white-space: nowrap; - } - - .sm-dox { - padding: 0 10px; - background-image: none; - background-color: #000; - line-height: normal; - background-image: none; - background-color: #333; - background: linear-gradient(to bottom, #333 0%, #111 100%); - color: #ddd; - } - - .sm-dox a span.sub-arrow { - top: 50%; - margin-top: -2px; - right: 12px; - width: 0; - height: 0; - border-width: 4px; - border-style: solid dashed dashed; - border-color: #ddd transparent transparent; - background: transparent; - -moz-border-radius: 0; - -webkit-border-radius: 0; - border-radius: 0; - } - - .sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted { - padding: 0 1em 0 0; - background-image: none; - background-repeat: no-repeat; - background-position: right; - -moz-border-radius: 0 !important; - -webkit-border-radius: 0; - border-radius: 0 !important; - } - - .sm-dox a:hover { - background-image: none; - background-repeat: repeat-x; - color: #fff; - text-shadow: 0 1px 1px #000; - } - - .sm-dox a:hover span.sub-arrow { - border-color: #fff transparent transparent; - } - - .sm-dox a.has-submenu { - padding-right: 24px; - } - - .sm-dox li { - border-top: 0; - } - - .sm-dox>li>ul:before,.sm-dox>li>ul:after { - content: ''; - position: absolute; - top: -18px; - left: 30px; - width: 0; - height: 0; - overflow: hidden; - border-width: 9px; - border-style: dashed dashed solid; - border-color: transparent transparent #bbb; - } - - .sm-dox>li>ul:after { - top: -16px; - left: 31px; - border-width: 8px; - border-color: transparent transparent #fff; - } - - .sm-dox ul { - border: 1px solid #bbb; - padding: 5px 0; - background: initial; - -moz-border-radius: 5px !important; - -webkit-border-radius: 5px; - border-radius: 5px !important; - -moz-box-shadow: 0 5px 9px rgba(0,0,0,0.2); - -webkit-box-shadow: 0 5px 9px rgba(0,0,0,0.2); - box-shadow: 0 5px 9px rgba(0,0,0,0.2); - } - - .sm-dox ul a span.sub-arrow { - right: 8px; - top: 50%; - margin-top: -5px; - border-width: 5px; - border-color: transparent transparent transparent #555; - border-style: dashed dashed dashed solid; - } - - .sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted { - color: #555; - background-image: none; - border: 0 !important; - color: #555; - background-image: none; - } - - .sm-dox ul a:hover { - background-image: none; - background-repeat: repeat-x; - color: #fff; - text-shadow: 0 1px 1px #000; - } - - .sm-dox ul a:hover span.sub-arrow { - border-color: transparent transparent transparent #fff; - } - - .sm-dox span.scroll-up,.sm-dox span.scroll-down { - position: absolute; - display: none; - visibility: hidden; - overflow: hidden; - background: initial; - height: 36px; - } - - .sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover { - background: #eee; - } - - .sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow { - border-color: transparent transparent #d23600; - } - - .sm-dox span.scroll-down:hover span.scroll-down-arrow { - border-color: #d23600 transparent transparent; - } - - .sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow { - position: absolute; - top: 0; - left: 50%; - margin-left: -6px; - width: 0; - height: 0; - overflow: hidden; - border-width: 6px; - border-style: dashed dashed solid; - border-color: transparent transparent #555; - } - - .sm-dox span.scroll-down-arrow { - top: 8px; - border-style: solid dashed dashed; - border-color: #555 transparent transparent; - } - - .sm-dox.sm-rtl a.has-submenu { - padding-right: 12px; - padding-left: 24px; - } - - .sm-dox.sm-rtl a span.sub-arrow { - right: auto; - left: 12px; - } - - .sm-dox.sm-rtl.sm-vertical a.has-submenu { - padding: 10px 20px; - } - - .sm-dox.sm-rtl.sm-vertical a span.sub-arrow { - right: auto; - left: 8px; - border-style: dashed solid dashed dashed; - border-color: transparent #555 transparent transparent; - } - - .sm-dox.sm-rtl>li>ul:before { - left: auto; - right: 30px; - } - - .sm-dox.sm-rtl>li>ul:after { - left: auto; - right: 31px; - } - - .sm-dox.sm-rtl ul a.has-submenu { - padding: 10px 20px !important; - } - - .sm-dox.sm-rtl ul a span.sub-arrow { - right: auto; - left: 8px; - border-style: dashed solid dashed dashed; - border-color: transparent #555 transparent transparent; - } - - .sm-dox.sm-vertical { - padding: 10px 0; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - border-radius: 5px; - } - - .sm-dox.sm-vertical a { - padding: 10px 20px; - } - - .sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted { - background: initial; - } - - .sm-dox.sm-vertical a.disabled { - background-image: none; - } - - .sm-dox.sm-vertical a span.sub-arrow { - right: 8px; - top: 50%; - margin-top: -5px; - border-width: 5px; - border-style: dashed dashed dashed solid; - border-color: transparent transparent transparent #555; - } - - .sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after { - display: none; - } - - .sm-dox.sm-vertical ul a { - padding: 10px 20px; - } - - .sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted { - background: #eee; - } - - .sm-dox.sm-vertical ul a.disabled { - background: initial; - } -} diff --git a/icons/meson.build b/icons/meson.build new file mode 100644 index 00000000..74a2038f --- /dev/null +++ b/icons/meson.build @@ -0,0 +1,24 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +png_icon_sizes = [ + '16x16', + '22x22', + '24x24', + '32x32', + '48x48', + '64x64', + '128x128', + '256x256', +] + +icons_dir = get_option('prefix') / get_option('datadir') / 'icons' / 'hicolor' + +install_data('scalable/ingen.svg', install_dir: icons_dir / 'scalable' / 'apps') + +foreach size : png_icon_sizes + install_data( + files(size / 'ingen.png'), + install_dir: icons_dir / size / 'apps', + ) +endforeach diff --git a/include/ingen/Arc.hpp b/include/ingen/Arc.hpp index 1d21b65e..d456edfb 100644 --- a/include/ingen/Arc.hpp +++ b/include/ingen/Arc.hpp @@ -17,10 +17,12 @@ #ifndef INGEN_ARC_HPP #define INGEN_ARC_HPP -#include "ingen/ingen.h" -#include "raul/Deletable.hpp" +#include <ingen/ingen.h> +#include <raul/Deletable.hpp> -namespace raul { class Path; } +namespace raul { +class Path; +} // namespace raul namespace ingen { diff --git a/include/ingen/Atom.hpp b/include/ingen/Atom.hpp index 3fb8f091..8d9cbe7f 100644 --- a/include/ingen/Atom.hpp +++ b/include/ingen/Atom.hpp @@ -17,9 +17,9 @@ #ifndef INGEN_ATOM_HPP #define INGEN_ATOM_HPP -#include "ingen/ingen.h" -#include "lv2/atom/atom.h" -#include "lv2/urid/urid.h" +#include <ingen/ingen.h> +#include <lv2/atom/atom.h> +#include <lv2/urid/urid.h> #include <algorithm> #include <cassert> @@ -41,7 +41,8 @@ namespace ingen { In either case, the data is stored in a binary compatible format to LV2_Atom (i.e., if the value is dynamically allocated, the header is repeated there). */ -class INGEN_API Atom { +class INGEN_API Atom +{ public: Atom() noexcept = default; @@ -93,21 +94,22 @@ public: return *this; } - inline bool operator==(const Atom& other) const { + bool operator==(const Atom& other) const { if (_atom.type != other._atom.type || _atom.size != other._atom.size) { return false; } + return is_reference() ? !memcmp(_body.ptr, other._body.ptr, sizeof(LV2_Atom) + _atom.size) : _body.val == other._body.val; } - inline bool operator!=(const Atom& other) const { + bool operator!=(const Atom& other) const { return !operator==(other); } - inline bool operator<(const Atom& other) const { + bool operator<(const Atom& other) const { if (_atom.type == other._atom.type) { const uint32_t min_size = std::min(_atom.size, other._atom.size); const int cmp = is_reference() @@ -115,6 +117,7 @@ public: : memcmp(&_body.val, &other._body.val, min_size); return cmp < 0 || (cmp == 0 && _atom.size < other._atom.size); } + return type() < other.type(); } @@ -122,25 +125,25 @@ public: * Always real-time safe. * @return true iff set succeeded. */ - inline bool set_rt(const Atom& other) { + bool set_rt(const Atom& other) { if (is_reference()) { return false; - } else { - _atom = other._atom; - _body.val = other._body.val; - return true; } + + _atom = other._atom; + _body.val = other._body.val; + return true; } - inline uint32_t size() const { return _atom.size; } - inline LV2_URID type() const { return _atom.type; } - inline bool is_valid() const { return _atom.type; } + uint32_t size() const { return _atom.size; } + LV2_URID type() const { return _atom.type; } + bool is_valid() const { return _atom.type; } - inline const void* get_body() const { + const void* get_body() const { return is_reference() ? static_cast<void*>(_body.ptr + 1) : &_body.val; } - inline void* get_body() { + void* get_body() { return is_reference() ? static_cast<void*>(_body.ptr + 1) : &_body.val; } @@ -159,14 +162,14 @@ public: private: /** Free dynamically allocated value, if applicable. */ - inline void dealloc() { + void dealloc() { if (is_reference()) { free(_body.ptr); } } /** Return true iff this value is dynamically allocated. */ - inline bool is_reference() const { + bool is_reference() const { return _atom.size > sizeof(_body.val); } diff --git a/include/ingen/AtomForge.hpp b/include/ingen/AtomForge.hpp index bc44b698..5d696923 100644 --- a/include/ingen/AtomForge.hpp +++ b/include/ingen/AtomForge.hpp @@ -17,57 +17,41 @@ #ifndef INGEN_ATOMFORGE_HPP #define INGEN_ATOMFORGE_HPP -#include "ingen/memory.hpp" -#include "lv2/atom/atom.h" -#include "lv2/atom/forge.h" -#include "lv2/atom/util.h" -#include "lv2/urid/urid.h" -#include "sord/sord.h" -#include "sord/sordmm.hpp" -#include "sratom/sratom.h" - -#include <cassert> +#include <ingen/ingen.h> +#include <ingen/memory.hpp> +#include <lv2/atom/atom.h> +#include <lv2/atom/forge.h> +#include <lv2/urid/urid.h> +#include <sord/sord.h> +#include <sratom/sratom.h> + #include <cstdint> #include <cstdlib> -#include <cstring> #include <memory> +namespace Sord { +class World; +} // namespace Sord + namespace ingen { /// An atom forge that writes to an automatically-resized memory buffer -class AtomForge : public LV2_Atom_Forge +class INGEN_API AtomForge : public LV2_Atom_Forge { public: - explicit AtomForge(LV2_URID_Map& map) - : LV2_Atom_Forge{} - , _size{0} - , _capacity{8 * sizeof(LV2_Atom)} - , _sratom{sratom_new(&map)} - , _buf{static_cast<LV2_Atom*>(calloc(8, sizeof(LV2_Atom)))} - { - lv2_atom_forge_init(this, &map); - lv2_atom_forge_set_sink(this, c_append, c_deref, this); - } + explicit AtomForge(LV2_URID_Map& map); /// Forge an atom from `node` in `model` - void read(Sord::World& world, SordModel* model, const SordNode* node) - { - sratom_read(_sratom.get(), this, world.c_obj(), model, node); - } + void read(Sord::World& world, SordModel* model, const SordNode* node); /// Return the top-level atom that has been forged - const LV2_Atom* atom() const { return _buf.get(); } + const LV2_Atom* atom() const; /// Clear the atom buffer and reset the forge - void clear() - { - lv2_atom_forge_set_sink(this, c_append, c_deref, this); - _size = 0; - *_buf = {0U, 0U}; - } + void clear(); /// Return the internal atom serialiser - Sratom& sratom() { return *_sratom; } + Sratom& sratom(); private: struct SratomDeleter { void operator()(Sratom* s) { sratom_free(s); } }; @@ -76,53 +60,23 @@ private: using SratomPtr = std::unique_ptr<Sratom, SratomDeleter>; /// Append some data and return a reference to its start - intptr_t append(const void* data, uint32_t len) { - // Record offset of the start of this write (+1 to avoid null) - const intptr_t ref = _size + 1; - - // Update size and reallocate if necessary - if (lv2_atom_pad_size(_size + len) > _capacity) { - _capacity = lv2_atom_pad_size(_size + len); - - _buf = AtomPtr{static_cast<LV2_Atom*>( - realloc(_buf.release(), _capacity)), - FreeDeleter<LV2_Atom>{}}; - } - - // Append new data - memcpy(reinterpret_cast<uint8_t*>(_buf.get()) + _size, data, len); - _size += len; - return ref; - } + intptr_t append(const void* data, uint32_t len); /// Dereference a reference previously returned by append() - LV2_Atom* deref(intptr_t ref) { - /* Make some assumptions and do unnecessary math to appease - -Wcast-align. This is questionable at best, though the forge should - only dereference references to aligned atoms. */ - assert((ref - 1) % sizeof(LV2_Atom) == 0); - return static_cast<LV2_Atom*>(_buf.get() + (ref - 1) / sizeof(LV2_Atom)); - - // Alternatively: - // return (LV2_Atom*)((uint8_t*)_buf + ref - 1); - } + LV2_Atom* deref(intptr_t ref); static LV2_Atom_Forge_Ref - c_append(void* self, const void* data, uint32_t len) { - return static_cast<AtomForge*>(self)->append(data, len); - } + c_append(void* self, const void* data, uint32_t len); static LV2_Atom* - c_deref(void* self, LV2_Atom_Forge_Ref ref) { - return static_cast<AtomForge*>(self)->deref(ref); - } - - size_t _size; ///< Current atom size - size_t _capacity; ///< Allocated size of atom buffer - SratomPtr _sratom; ///< Atom serialiser - AtomPtr _buf; ///< Atom buffer + c_deref(void* self, LV2_Atom_Forge_Ref ref); + + size_t _size{0}; ///< Current atom size + size_t _capacity{8 * sizeof(LV2_Atom)}; ///< Allocated size of buffer + SratomPtr _sratom; ///< Atom serialiser + AtomPtr _buf; ///< Atom buffer }; -} // namespace ingen +} // namespace ingen -#endif // INGEN_ATOMFORGE_HPP +#endif // INGEN_ATOMFORGE_HPP diff --git a/include/ingen/AtomReader.hpp b/include/ingen/AtomReader.hpp index c83e7e4a..b0fe5906 100644 --- a/include/ingen/AtomReader.hpp +++ b/include/ingen/AtomReader.hpp @@ -17,14 +17,13 @@ #ifndef INGEN_ATOMREADER_HPP #define INGEN_ATOMREADER_HPP -#include "ingen/AtomSink.hpp" -#include "ingen/Resource.hpp" -#include "ingen/ingen.h" -#include "lv2/atom/atom.h" - -#include <boost/optional/optional.hpp> +#include <ingen/AtomSink.hpp> +#include <ingen/Resource.hpp> +#include <ingen/ingen.h> +#include <lv2/atom/atom.h> #include <cstdint> +#include <optional> namespace raul { class Path; @@ -58,9 +57,9 @@ public: private: void get_atom(const LV2_Atom* in, Atom& out); - boost::optional<URI> atom_to_uri(const LV2_Atom* atom); - boost::optional<raul::Path> atom_to_path(const LV2_Atom* atom); - Resource::Graph atom_to_context(const LV2_Atom* atom); + std::optional<URI> atom_to_uri(const LV2_Atom* atom); + std::optional<raul::Path> atom_to_path(const LV2_Atom* atom); + Resource::Graph atom_to_context(const LV2_Atom* atom); void get_props(const LV2_Atom_Object* obj, ingen::Properties& props); diff --git a/include/ingen/AtomSink.hpp b/include/ingen/AtomSink.hpp index 395eba54..4c759695 100644 --- a/include/ingen/AtomSink.hpp +++ b/include/ingen/AtomSink.hpp @@ -17,8 +17,8 @@ #ifndef INGEN_ATOMSINK_HPP #define INGEN_ATOMSINK_HPP -#include "ingen/ingen.h" -#include "lv2/atom/atom.h" +#include <ingen/ingen.h> +#include <lv2/atom/atom.h> #include <cstdint> @@ -27,7 +27,8 @@ namespace ingen { /** A sink for LV2 Atoms. * @ingroup IngenShared */ -class INGEN_API AtomSink { +class INGEN_API AtomSink +{ public: virtual ~AtomSink() = default; diff --git a/include/ingen/AtomWriter.hpp b/include/ingen/AtomWriter.hpp index 492e7ff6..e391870d 100644 --- a/include/ingen/AtomWriter.hpp +++ b/include/ingen/AtomWriter.hpp @@ -17,19 +17,21 @@ #ifndef INGEN_ATOMWRITER_HPP #define INGEN_ATOMWRITER_HPP -#include "ingen/AtomForge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Message.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URI.hpp" -#include "ingen/ingen.h" -#include "lv2/atom/forge.h" -#include "lv2/urid/urid.h" +#include <ingen/AtomForge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/ingen.h> +#include <lv2/atom/forge.h> +#include <lv2/urid/urid.h> #include <cstdint> -namespace raul { class Path; } +namespace raul { +class Path; +} // namespace raul namespace ingen { diff --git a/include/ingen/ClashAvoider.hpp b/include/ingen/ClashAvoider.hpp index c1d62754..bf6533ae 100644 --- a/include/ingen/ClashAvoider.hpp +++ b/include/ingen/ClashAvoider.hpp @@ -17,8 +17,8 @@ #ifndef INGEN_CLASHAVOIDER_HPP #define INGEN_CLASHAVOIDER_HPP -#include "ingen/ingen.h" -#include "raul/Path.hpp" +#include <ingen/ingen.h> +#include <raul/Path.hpp> #include <map> #include <string> @@ -48,9 +48,9 @@ public: * @param new_path The new path that `old_path` was mapped to * @param name The old name. */ - static std::string adjust_name(const raul::Path& old_path, - const raul::Path& new_path, - std::string name); + static std::string adjust_name(const raul::Path& old_path, + const raul::Path& new_path, + const std::string& name); private: using Offsets = std::map<raul::Path, unsigned>; diff --git a/include/ingen/Clock.hpp b/include/ingen/Clock.hpp index deea0495..9e20a031 100644 --- a/include/ingen/Clock.hpp +++ b/include/ingen/Clock.hpp @@ -28,15 +28,16 @@ namespace ingen { -class Clock { +class Clock +{ public: #ifdef __MACH__ Clock() { mach_timebase_info(&_timebase); } - inline uint64_t now_microseconds() const { + uint64_t now_microseconds() const { const uint64_t now = mach_absolute_time(); - return now * _timebase.numer / _timebase.denom / 1e3; + return now * _timebase.numer / _timebase.denom / 1000U; } private: @@ -44,11 +45,11 @@ private: #else - inline uint64_t now_microseconds() const { + uint64_t now_microseconds() const { struct timespec time{}; clock_gettime(_clock, &time); - return static_cast<uint64_t>(time.tv_sec) * 1e6 + - static_cast<uint64_t>(time.tv_nsec) / 1e3; + return (static_cast<uint64_t>(time.tv_sec) * 1000000U) + + (static_cast<uint64_t>(time.tv_nsec) / 1000U); } private: diff --git a/include/ingen/ColorContext.hpp b/include/ingen/ColorContext.hpp index aadb2980..666a044e 100644 --- a/include/ingen/ColorContext.hpp +++ b/include/ingen/ColorContext.hpp @@ -17,23 +17,29 @@ #ifndef INGEN_COLORCONTEXT_HPP #define INGEN_COLORCONTEXT_HPP -#include "ingen/ingen.h" +#include <ingen/ingen.h> #include <cstdio> namespace ingen { -class INGEN_API ColorContext { +class INGEN_API ColorContext +{ public: enum class Color { RED = 31, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE }; ColorContext(FILE* stream, Color color); ~ColorContext(); + ColorContext(const ColorContext&) = delete; + ColorContext& operator=(const ColorContext&) = delete; + ColorContext(ColorContext&&) = delete; + ColorContext& operator=(ColorContext&&) = delete; + private: FILE* _stream; }; -} // namespace ingen +} // namespace ingen -#endif // INGEN_COLORCONTEXT_HPP +#endif // INGEN_COLORCONTEXT_HPP diff --git a/include/ingen/Configuration.hpp b/include/ingen/Configuration.hpp index 16c20811..5c4d2841 100644 --- a/include/ingen/Configuration.hpp +++ b/include/ingen/Configuration.hpp @@ -17,11 +17,11 @@ #ifndef INGEN_CONFIGURATION_HPP #define INGEN_CONFIGURATION_HPP -#include "ingen/Atom.hpp" -#include "ingen/FilePath.hpp" -#include "ingen/ingen.h" -#include "lv2/urid/urid.h" -#include "raul/Exception.hpp" +#include <ingen/Atom.hpp> +#include <ingen/FilePath.hpp> +#include <ingen/ingen.h> +#include <lv2/urid/urid.h> +#include <raul/Exception.hpp> #include <cstdio> #include <list> @@ -37,7 +37,8 @@ class URIMap; /** Ingen configuration (command line options and/or configuration file). * @ingroup IngenShared */ -class INGEN_API Configuration { +class INGEN_API Configuration +{ public: explicit Configuration(Forge& forge); @@ -46,9 +47,9 @@ public: * This controls when and where an option will be saved or restored. */ enum Scope { - GLOBAL = 1, ///< Applies to any Ingen instance - SESSION = 1<<1, ///< Applies to this Ingen instance only - GUI = 1<<2 ///< Persistent GUI settings saved at exit + GLOBAL = 1, ///< Applies to any Ingen instance + SESSION = 1 << 1, ///< Applies to this Ingen instance only + GUI = 1 << 2 ///< Persistent GUI settings saved at exit }; /** Add a configuration option. @@ -81,7 +82,7 @@ public: /** Parse a command line. * - * @throw OptionError + * @throw OptionError An option is unknown or an option value is invalid. */ void parse(int argc, char **argv); @@ -132,7 +133,7 @@ private: }; struct OptionNameOrder { - inline bool operator()(const Option& a, const Option& b) { + bool operator()(const Option& a, const Option& b) { return a.name < b.name; } }; @@ -152,7 +153,7 @@ private: Options _options; Keys _keys; ShortNames _short_names; - size_t _max_name_length; + size_t _max_name_length{0}; }; } // namespace ingen diff --git a/include/ingen/DataAccess.hpp b/include/ingen/DataAccess.hpp index 3ea70eff..c18c74f3 100644 --- a/include/ingen/DataAccess.hpp +++ b/include/ingen/DataAccess.hpp @@ -17,21 +17,20 @@ #ifndef INGEN_DATAACCESS_HPP #define INGEN_DATAACCESS_HPP -#include "ingen/LV2Features.hpp" -#include "ingen/Node.hpp" -#include "ingen/Store.hpp" -#include "ingen/World.hpp" -#include "lilv/lilv.h" -#include "lv2/core/lv2.h" -#include "lv2/data-access/data-access.h" +#include <ingen/LV2Features.hpp> +#include <ingen/Node.hpp> +#include <ingen/Store.hpp> +#include <ingen/World.hpp> +#include <lilv/lilv.h> +#include <lv2/core/lv2.h> +#include <lv2/data-access/data-access.h> #include <cstdlib> #include <memory> namespace ingen { -struct DataAccess : public ingen::LV2Features::Feature -{ +struct DataAccess : public ingen::LV2Features::Feature { static void delete_feature(LV2_Feature* feature) { free(feature->data); delete feature; diff --git a/include/ingen/EngineBase.hpp b/include/ingen/EngineBase.hpp index 1b6b105a..35115ad4 100644 --- a/include/ingen/EngineBase.hpp +++ b/include/ingen/EngineBase.hpp @@ -17,7 +17,7 @@ #ifndef INGEN_ENGINEBASE_HPP #define INGEN_ENGINEBASE_HPP -#include "ingen/ingen.h" +#include <ingen/ingen.h> #include <chrono> #include <cstddef> @@ -46,7 +46,7 @@ public: */ virtual void init(double sample_rate, uint32_t block_length, - size_t seq_size) = 0; + uint32_t seq_size) = 0; /** Return true iff the engine and driver supports dynamic ports. diff --git a/include/ingen/FilePath.hpp b/include/ingen/FilePath.hpp index 3d077266..ce157d90 100644 --- a/include/ingen/FilePath.hpp +++ b/include/ingen/FilePath.hpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2018 David Robillard <http://drobilla.net/> + Copyright 2018-2020 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -17,108 +17,11 @@ #ifndef INGEN_FILEPATH_HPP #define INGEN_FILEPATH_HPP -#include "ingen/ingen.h" - -#include <boost/utility/string_view.hpp> // IWYU pragma: export - -#include <ostream> -#include <string> -#include <utility> - -#if defined(_WIN32) && !defined(__CYGWIN__) -#define USE_WINDOWS_FILE_PATHS 1 -#endif +#include <filesystem> namespace ingen { -/** A path to a file. - * - * This is a minimal subset of the std::filesystem::path interface in C++17. - * Support for Windows paths is only partial and there is no support for - * character encoding conversion at all. - */ -class INGEN_API FilePath -{ -public: -#ifdef USE_WINDOWS_FILE_PATHS - using value_type = wchar_t; - static constexpr value_type preferred_separator = L'\\'; -#else - using value_type = char; - static constexpr value_type preferred_separator = '/'; -#endif - - using string_type = std::basic_string<value_type>; - - FilePath() = default; - FilePath(const FilePath&) = default; - FilePath(FilePath&&) = default; - - FilePath(string_type str) : _str(std::move(str)) {} - FilePath(const value_type* str) : _str(str) {} - FilePath(const boost::basic_string_view<value_type>& sv) - : _str(sv.data(), sv.length()) - {} - - ~FilePath() = default; - - FilePath& operator=(const FilePath& path) = default; - FilePath& operator=(FilePath&& path) noexcept; - FilePath& operator=(string_type&& str); - - FilePath& operator/=(const FilePath& path); - - FilePath& operator+=(const FilePath& path); - FilePath& operator+=(const string_type& str); - FilePath& operator+=(const value_type* str); - FilePath& operator+=(value_type chr); - FilePath& operator+=(boost::basic_string_view<value_type> sv); - - void clear() noexcept { _str.clear(); } - - const string_type& native() const noexcept { return _str; } - const string_type& string() const noexcept { return _str; } - const value_type* c_str() const noexcept { return _str.c_str(); } - - operator string_type() const { return _str; } - - static FilePath root_name(); - - FilePath root_directory() const; - FilePath root_path() const; - FilePath relative_path() const; - FilePath parent_path() const; - FilePath filename() const; - FilePath stem() const; - FilePath extension() const; - - bool empty() const noexcept { return _str.empty(); } - - bool is_absolute() const; - bool is_relative() const { return !is_absolute(); } - -private: - std::size_t find_first_sep() const; - std::size_t find_last_sep() const; - - string_type _str; -}; - -INGEN_API bool operator==(const FilePath& lhs, const FilePath& rhs) noexcept; -INGEN_API bool operator!=(const FilePath& lhs, const FilePath& rhs) noexcept; -INGEN_API bool operator<(const FilePath& lhs, const FilePath& rhs) noexcept; -INGEN_API bool operator<=(const FilePath& lhs, const FilePath& rhs) noexcept; -INGEN_API bool operator>(const FilePath& lhs, const FilePath& rhs) noexcept; -INGEN_API bool operator>=(const FilePath& lhs, const FilePath& rhs) noexcept; - -INGEN_API FilePath operator/(const FilePath& lhs, const FilePath& rhs); - -template <typename Char, typename Traits> -std::basic_ostream<Char, Traits>& -operator<<(std::basic_ostream<Char, Traits>& os, const FilePath& path) -{ - return os << path.string(); -} +using FilePath = std::filesystem::path; } // namespace ingen diff --git a/include/ingen/Forge.hpp b/include/ingen/Forge.hpp index 54f5d3a9..dd7ec130 100644 --- a/include/ingen/Forge.hpp +++ b/include/ingen/Forge.hpp @@ -17,9 +17,9 @@ #ifndef INGEN_FORGE_HPP #define INGEN_FORGE_HPP -#include "ingen/Atom.hpp" -#include "ingen/ingen.h" -#include "lv2/atom/forge.h" +#include <ingen/Atom.hpp> +#include <ingen/ingen.h> +#include <lv2/atom/forge.h> #include <cstdint> #include <cstring> @@ -33,7 +33,8 @@ class URI; /** Forge for Atoms. * @ingroup IngenShared */ -class INGEN_API Forge : public LV2_Atom_Forge { +class INGEN_API Forge : public LV2_Atom_Forge +{ public: explicit Forge(URIMap& map); @@ -43,38 +44,38 @@ public: return atom.type() == URI || atom.type() == URID; } - static Atom make() { return Atom(); } - Atom make(int32_t v) { return Atom(sizeof(v), Int, &v); } - Atom make(float v) { return Atom(sizeof(v), Float, &v); } + static Atom make() { return {}; } + Atom make(int32_t v) { return {sizeof(v), Int, &v}; } + Atom make(float v) { return {sizeof(v), Float, &v}; } Atom make(bool v) { const int32_t iv = v ? 1 : 0; - return Atom(sizeof(int32_t), Bool, &iv); + return {sizeof(int32_t), Bool, &iv}; } - Atom make_urid(int32_t v) { return Atom(sizeof(int32_t), URID, &v); } + Atom make_urid(int32_t v) { return {sizeof(int32_t), URID, &v}; } Atom make_urid(const ingen::URI& u); static Atom alloc(uint32_t s, uint32_t t, const void* v) { - return Atom(s, t, v); + return {s, t, v}; } Atom alloc(const char* v) { - const size_t len = strlen(v); - return Atom(len + 1, String, v); + const auto len = static_cast<uint32_t>(strlen(v)); + return {len + 1U, String, v}; } Atom alloc(const std::string& v) { - return Atom(v.length() + 1, String, v.c_str()); + return {static_cast<uint32_t>(v.length()) + 1U, String, v.c_str()}; } Atom alloc_uri(const char* v) { - const size_t len = strlen(v); - return Atom(len + 1, URI, v); + const auto len = static_cast<uint32_t>(strlen(v)); + return {len + 1U, URI, v}; } Atom alloc_uri(const std::string& v) { - return Atom(v.length() + 1, URI, v.c_str()); + return {static_cast<uint32_t>(v.length()) + 1U, URI, v.c_str()}; } private: diff --git a/include/ingen/InstanceAccess.hpp b/include/ingen/InstanceAccess.hpp index e108d7d5..66a2b5c3 100644 --- a/include/ingen/InstanceAccess.hpp +++ b/include/ingen/InstanceAccess.hpp @@ -17,19 +17,18 @@ #ifndef INGEN_INSTANCEACCESS_HPP #define INGEN_INSTANCEACCESS_HPP -#include "ingen/LV2Features.hpp" -#include "ingen/Node.hpp" -#include "ingen/Store.hpp" -#include "ingen/World.hpp" -#include "lilv/lilv.h" -#include "lv2/core/lv2.h" +#include <ingen/LV2Features.hpp> +#include <ingen/Node.hpp> +#include <ingen/Store.hpp> +#include <ingen/World.hpp> +#include <lilv/lilv.h> +#include <lv2/core/lv2.h> #include <memory> namespace ingen { -struct InstanceAccess : public ingen::LV2Features::Feature -{ +struct InstanceAccess : public ingen::LV2Features::Feature { const char* uri() const override { return "http://lv2plug.in/ns/ext/instance-access"; } std::shared_ptr<LV2_Feature> feature(World& world, Node* node) override { diff --git a/include/ingen/Interface.hpp b/include/ingen/Interface.hpp index cb17039e..329dab2c 100644 --- a/include/ingen/Interface.hpp +++ b/include/ingen/Interface.hpp @@ -21,11 +21,11 @@ #ifndef INGEN_INTERFACE_HPP #define INGEN_INTERFACE_HPP -#include "ingen/Message.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/Status.hpp" -#include "ingen/ingen.h" +#include <ingen/Message.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/Status.hpp> +#include <ingen/ingen.h> #include <cstdint> #include <memory> @@ -65,75 +65,75 @@ public: * @{ */ - inline void operator()(const Message& msg) { message(msg); } + void operator()(const Message& msg) { message(msg); } - inline void set_response_id(int32_t id) { _seq = id; } + void set_response_id(int32_t id) { _seq = id; } - inline void bundle_begin() { message(BundleBegin{_seq++}); } - inline void bundle_end() { message(BundleEnd{_seq++}); } + void bundle_begin() { message(BundleBegin{_seq++}); } + void bundle_end() { message(BundleEnd{_seq++}); } - inline void put(const URI& uri, - const Properties& properties, - Resource::Graph ctx = Resource::Graph::DEFAULT) + void put(const URI& uri, + const Properties& properties, + Resource::Graph ctx = Resource::Graph::DEFAULT) { message(Put{_seq++, uri, properties, ctx}); } - inline void delta(const URI& uri, - const Properties& remove, - const Properties& add, - Resource::Graph ctx = Resource::Graph::DEFAULT) + void delta(const URI& uri, + const Properties& remove, + const Properties& add, + Resource::Graph ctx = Resource::Graph::DEFAULT) { message(Delta{_seq++, uri, remove, add, ctx}); } - inline void copy(const URI& old_uri, const URI& new_uri) + void copy(const URI& old_uri, const URI& new_uri) { message(Copy{_seq++, old_uri, new_uri}); } - inline void move(const raul::Path& old_path, const raul::Path& new_path) + void move(const raul::Path& old_path, const raul::Path& new_path) { message(Move{_seq++, old_path, new_path}); } - inline void del(const URI& uri) { message(Del{_seq++, uri}); } + void del(const URI& uri) { message(Del{_seq++, uri}); } - inline void connect(const raul::Path& tail, const raul::Path& head) + void connect(const raul::Path& tail, const raul::Path& head) { message(Connect{_seq++, tail, head}); } - inline void disconnect(const raul::Path& tail, const raul::Path& head) + void disconnect(const raul::Path& tail, const raul::Path& head) { message(Disconnect{_seq++, tail, head}); } - inline void disconnect_all(const raul::Path& graph, const raul::Path& path) + void disconnect_all(const raul::Path& graph, const raul::Path& path) { message(DisconnectAll{_seq++, graph, path}); } - inline void set_property(const URI& subject, - const URI& predicate, - const Atom& value, - Resource::Graph ctx = Resource::Graph::DEFAULT) + void set_property(const URI& subject, + const URI& predicate, + const Atom& value, + Resource::Graph ctx = Resource::Graph::DEFAULT) { message(SetProperty{_seq++, subject, predicate, value, ctx}); } - inline void undo() { message(Undo{_seq++}); } + void undo() { message(Undo{_seq++}); } - inline void redo() { message(Redo{_seq++}); } + void redo() { message(Redo{_seq++}); } - inline void get(const URI& uri) { message(Get{_seq++, uri}); } + void get(const URI& uri) { message(Get{_seq++, uri}); } - inline void response(int32_t id, Status status, const std::string& subject) + void response(int32_t id, Status status, const std::string& subject) { message(Response{id, status, subject}); } - inline void error(const std::string& error_message) + void error(const std::string& error_message) { message(Error{_seq++, error_message}); } diff --git a/include/ingen/LV2Features.hpp b/include/ingen/LV2Features.hpp index f61b9b85..41bdf848 100644 --- a/include/ingen/LV2Features.hpp +++ b/include/ingen/LV2Features.hpp @@ -17,9 +17,9 @@ #ifndef INGEN_LV2FEATURES_HPP #define INGEN_LV2FEATURES_HPP -#include "ingen/ingen.h" -#include "lv2/core/lv2.h" -#include "raul/Noncopyable.hpp" +#include <ingen/ingen.h> +#include <lv2/core/lv2.h> +#include <raul/Noncopyable.hpp> #include <memory> #include <string> @@ -33,11 +33,13 @@ class World; /** Features for use by LV2 plugins. * @ingroup IngenShared */ -class INGEN_API LV2Features { +class INGEN_API LV2Features +{ public: LV2Features() = default; - class Feature { + class Feature + { public: virtual ~Feature() = default; @@ -50,9 +52,10 @@ public: static void free_feature(LV2_Feature* feature); }; - class EmptyFeature : public Feature { + class EmptyFeature : public Feature + { public: - explicit EmptyFeature(const char* uri) : _uri(uri) {} + explicit EmptyFeature(const char* uri) noexcept : _uri(uri) {} const char* uri() const override { return _uri; } @@ -64,7 +67,8 @@ public: const char* _uri; }; - class FeatureArray : public raul::Noncopyable { + class FeatureArray : public raul::Noncopyable + { public: using FeatureVector = std::vector<std::shared_ptr<LV2_Feature>>; diff --git a/include/ingen/Library.hpp b/include/ingen/Library.hpp index fd4f4260..99dfff4c 100644 --- a/include/ingen/Library.hpp +++ b/include/ingen/Library.hpp @@ -17,19 +17,22 @@ #ifndef INGEN_LIBRARY_HPP #define INGEN_LIBRARY_HPP -#include "ingen/FilePath.hpp" -#include "ingen/ingen.h" +#include <ingen/FilePath.hpp> +#include <ingen/ingen.h> namespace ingen { /** A dynamically loaded library (module, plugin). */ -class INGEN_API Library { +class INGEN_API Library +{ public: - Library(const FilePath& path); + explicit Library(const FilePath& path); ~Library(); - Library(const Library&) = delete; + Library(const Library&) = delete; Library& operator=(const Library&) = delete; + Library(Library&&) = delete; + Library& operator=(Library&&) = delete; using VoidFuncPtr = void (*)(); @@ -37,7 +40,7 @@ public: static const char* get_last_error(); - operator bool() const { return _lib; } + explicit operator bool() const { return _lib; } private: void* _lib; diff --git a/include/ingen/Log.hpp b/include/ingen/Log.hpp index 5310c768..afde276a 100644 --- a/include/ingen/Log.hpp +++ b/include/ingen/Log.hpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2016 David Robillard <http://drobilla.net/> + Copyright 2007-2024 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -17,17 +17,15 @@ #ifndef INGEN_LOG_HPP #define INGEN_LOG_HPP -#include "ingen/LV2Features.hpp" -#include "ingen/fmt.hpp" // IWYU pragma: export -#include "ingen/ingen.h" -#include "lv2/core/lv2.h" -#include "lv2/log/log.h" -#include "lv2/urid/urid.h" +#include <ingen/LV2Features.hpp> +#include <ingen/fmt.hpp> +#include <ingen/ingen.h> +#include <lv2/core/lv2.h> +#include <lv2/log/log.h> +#include <lv2/urid/urid.h> #include <cstdarg> -#include <cstdio> #include <functional> -#include <memory> #include <string> #include <utility> @@ -35,9 +33,9 @@ namespace ingen { class Node; class URIs; -class World; -class INGEN_API Log { +class INGEN_API Log +{ public: using Sink = std::function<int(LV2_URID, const char*, va_list)>; @@ -88,21 +86,20 @@ public: } int vtprintf(LV2_URID type, const char* fmt, va_list args); + int tprintf(LV2_URID type, const char* fmt, ...); void set_flush(bool f) { _flush = f; } void set_trace(bool f) { _trace = f; } void set_sink(Sink s) { _sink = std::move(s); } private: - void print(FILE* stream, const std::string& msg) const; - LV2_Log_Log* _log; URIs& _uris; Sink _sink; - bool _flush; - bool _trace; + bool _flush{false}; + bool _trace{false}; }; } // namespace ingen -#endif // INGEN_LOG_HPP +#endif // INGEN_LOG_HPP diff --git a/include/ingen/Message.hpp b/include/ingen/Message.hpp index b7342eba..be0b5d00 100644 --- a/include/ingen/Message.hpp +++ b/include/ingen/Message.hpp @@ -17,52 +17,45 @@ #ifndef INGEN_MESSAGE_HPP #define INGEN_MESSAGE_HPP -#include "ingen/Atom.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/Status.hpp" -#include "ingen/URI.hpp" -#include "raul/Path.hpp" - -#include <boost/variant/variant.hpp> +#include <ingen/Atom.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/Status.hpp> +#include <ingen/URI.hpp> +#include <raul/Path.hpp> #include <cstdint> #include <string> +#include <variant> namespace ingen { -struct BundleBegin -{ +struct BundleBegin { int32_t seq; }; -struct BundleEnd -{ +struct BundleEnd { int32_t seq; }; -struct Connect -{ +struct Connect { int32_t seq; raul::Path tail; raul::Path head; }; -struct Copy -{ +struct Copy { int32_t seq; URI old_uri; URI new_uri; }; -struct Del -{ +struct Del { int32_t seq; URI uri; }; -struct Delta -{ +struct Delta { int32_t seq; URI uri; Properties remove; @@ -70,61 +63,52 @@ struct Delta Resource::Graph ctx; }; -struct Disconnect -{ +struct Disconnect { int32_t seq; raul::Path tail; raul::Path head; }; -struct DisconnectAll -{ +struct DisconnectAll { int32_t seq; raul::Path graph; raul::Path path; }; -struct Error -{ +struct Error { int32_t seq; std::string message; }; -struct Get -{ +struct Get { int32_t seq; URI subject; }; -struct Move -{ +struct Move { int32_t seq; raul::Path old_path; raul::Path new_path; }; -struct Put -{ +struct Put { int32_t seq; URI uri; Properties properties; Resource::Graph ctx; }; -struct Redo -{ +struct Redo { int32_t seq; }; -struct Response -{ +struct Response { int32_t id; Status status; std::string subject; }; -struct SetProperty -{ +struct SetProperty { int32_t seq; URI subject; URI predicate; @@ -132,28 +116,27 @@ struct SetProperty Resource::Graph ctx; }; -struct Undo -{ +struct Undo { int32_t seq; }; -using Message = boost::variant<BundleBegin, - BundleEnd, - Connect, - Copy, - Del, - Delta, - Disconnect, - DisconnectAll, - Error, - Get, - Move, - Put, - Redo, - Response, - SetProperty, - Undo>; - -} // namespace ingen - -#endif // INGEN_MESSAGE_HPP +using Message = std::variant<BundleBegin, + BundleEnd, + Connect, + Copy, + Del, + Delta, + Disconnect, + DisconnectAll, + Error, + Get, + Move, + Put, + Redo, + Response, + SetProperty, + Undo>; + +} // namespace ingen + +#endif // INGEN_MESSAGE_HPP diff --git a/include/ingen/Module.hpp b/include/ingen/Module.hpp index b540fe7d..1a12a036 100644 --- a/include/ingen/Module.hpp +++ b/include/ingen/Module.hpp @@ -17,8 +17,8 @@ #ifndef INGEN_MODULE_HPP #define INGEN_MODULE_HPP -#include "ingen/Library.hpp" -#include "ingen/ingen.h" +#include <ingen/Library.hpp> +#include <ingen/ingen.h> #include <memory> @@ -31,9 +31,11 @@ class World; * All components of Ingen reside in one of these. * @ingroup IngenShared */ -class INGEN_API Module { +class INGEN_API Module +{ public: - Module() : library(nullptr) {} + Module() noexcept : library(nullptr) {} + virtual ~Module() = default; Module(const Module&) = delete; @@ -44,8 +46,8 @@ public: /** Library implementing this module. * - * This is managed by the World and not this class, since closing the library - * in this destructor could possibly reference code from the library + * This is managed by the World and not this class, since closing the + * library in this destructor could possibly reference code from the library * afterwards and cause a segfault on exit. */ std::unique_ptr<Library> library; @@ -55,8 +57,14 @@ public: extern "C" { +#ifdef _WIN32 +# define INGEN_MODULE_EXPORT __declspec(dllexport) +#else +# define INGEN_MODULE_EXPORT __attribute__((visibility("default"))) +#endif + /** Prototype for the ingen_module_load() entry point in an ingen module. */ -INGEN_API ingen::Module* ingen_module_load(); +INGEN_MODULE_EXPORT ingen::Module* ingen_module_load(); } diff --git a/include/ingen/Node.hpp b/include/ingen/Node.hpp index 3733b51e..2370cfe7 100644 --- a/include/ingen/Node.hpp +++ b/include/ingen/Node.hpp @@ -17,13 +17,14 @@ #ifndef INGEN_NODE_HPP #define INGEN_NODE_HPP -#include "ingen/Resource.hpp" -#include "ingen/URI.hpp" -#include "ingen/ingen.h" -#include "ingen/paths.hpp" -#include "lilv/lilv.h" +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/ingen.h> +#include <ingen/paths.hpp> +#include <lilv/lilv.h> #include <cstdint> +#include <filesystem> #include <map> #include <memory> #include <string> @@ -37,7 +38,6 @@ class Symbol; namespace ingen { class Arc; -class FilePath; class URIs; /** A node in the audio graph. @@ -65,8 +65,8 @@ public: using Arcs = std::map<ArcsKey, std::shared_ptr<Arc>>; // Graphs only - Arcs& arcs() { return _arcs; } - const Arcs& arcs() const { return _arcs; } + Arcs& arcs() { return _graph_arcs; } + const Arcs& arcs() const { return _graph_arcs; } // Blocks and graphs only virtual uint32_t num_ports() const { return 0; } @@ -75,7 +75,11 @@ public: // Plugin blocks only virtual LilvInstance* instance() { return nullptr; } - virtual bool save_state(const FilePath& dir) const { return false; } + + virtual bool save_state(const std::filesystem::path& dir) const + { + return false; + } // All objects virtual GraphType graph_type() const = 0; @@ -98,7 +102,7 @@ protected: : Resource(uris, path_to_uri(path)) {} - Arcs _arcs; ///< Graphs only + Arcs _graph_arcs; ///< Graphs only }; } // namespace ingen diff --git a/include/ingen/Parser.hpp b/include/ingen/Parser.hpp index f2cd951f..8db64104 100644 --- a/include/ingen/Parser.hpp +++ b/include/ingen/Parser.hpp @@ -17,20 +17,21 @@ #ifndef INGEN_PARSER_HPP #define INGEN_PARSER_HPP -#include "ingen/FilePath.hpp" -#include "ingen/Properties.hpp" // IWYU pragma: keep -#include "ingen/URI.hpp" -#include "ingen/ingen.h" -#include "raul/Path.hpp" // IWYU pragma: keep -#include "raul/Symbol.hpp" // IWYU pragma: keep - -#include <boost/optional/optional.hpp> - +#include <ingen/FilePath.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/ingen.h> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> + +#include <optional> #include <set> #include <string> #include <utility> -namespace Sord { class World; } +namespace Sord { +class World; +} // namespace Sord namespace ingen { @@ -42,7 +43,8 @@ class World; @ingroup Ingen */ -class INGEN_API Parser { +class INGEN_API Parser +{ public: explicit Parser() = default; @@ -50,16 +52,16 @@ public: /** Record of a resource listed in a bundle manifest. */ struct ResourceRecord { - inline ResourceRecord(URI u, FilePath f) + ResourceRecord(URI u, FilePath f) : uri(std::move(u)), filename(std::move(f)) {} - inline bool operator<(const ResourceRecord& r) const { + bool operator<(const ResourceRecord& r) const { return uri < r.uri; } - URI uri; ///< URI of resource (e.g. a Graph) - FilePath filename; ///< Path of describing file (seeAlso) + URI uri; ///< URI of resource (e.g. a Graph) + FilePath filename; ///< Path of describing file (seeAlso) }; /** Find all resources of a given type listed in a manifest file. */ @@ -77,21 +79,21 @@ public: * @return whether or not load was successful. */ virtual bool parse_file( - World& world, - Interface& target, - const FilePath& path, - const boost::optional<raul::Path>& parent = boost::optional<raul::Path>(), - const boost::optional<raul::Symbol>& symbol = boost::optional<raul::Symbol>(), - const boost::optional<Properties>& data = boost::optional<Properties>()); - - virtual boost::optional<URI> parse_string( - World& world, - Interface& target, - const std::string& str, - const URI& base_uri, - const boost::optional<raul::Path>& parent = boost::optional<raul::Path>(), - const boost::optional<raul::Symbol>& symbol = boost::optional<raul::Symbol>(), - const boost::optional<Properties>& data = boost::optional<Properties>()); + World& world, + Interface& target, + const FilePath& path, + const std::optional<raul::Path>& parent = std::optional<raul::Path>(), + const std::optional<raul::Symbol>& symbol = std::optional<raul::Symbol>(), + const std::optional<Properties>& data = std::optional<Properties>()); + + virtual std::optional<URI> parse_string( + World& world, + Interface& target, + const std::string& str, + const URI& base_uri, + const std::optional<raul::Path>& parent = std::optional<raul::Path>(), + const std::optional<raul::Symbol>& symbol = std::optional<raul::Symbol>(), + const std::optional<Properties>& data = std::optional<Properties>()); }; } // namespace ingen diff --git a/include/ingen/Properties.hpp b/include/ingen/Properties.hpp index 1a80d0af..5f953902 100644 --- a/include/ingen/Properties.hpp +++ b/include/ingen/Properties.hpp @@ -17,9 +17,9 @@ #ifndef INGEN_PROPERTIES_HPP #define INGEN_PROPERTIES_HPP -#include "ingen/Atom.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" +#include <ingen/Atom.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> #include <initializer_list> #include <map> @@ -28,7 +28,8 @@ namespace ingen { /** A property value (an Atom with a context). */ -class Property : public Atom { +class Property : public Atom +{ public: enum class Graph { DEFAULT, ///< Default context for "universal" properties @@ -53,12 +54,18 @@ private: Graph _ctx; }; -class Properties : public std::multimap<URI, Property> { +class Properties : public std::multimap<URI, Property> +{ public: using Graph = Property::Graph; Properties() = default; - Properties(const Properties& copy) = default; + + Properties(const Properties&) = default; + Properties& operator=(const Properties&) = default; + + Properties(Properties&&) = default; + Properties& operator=(Properties&&) = default; Properties(std::initializer_list<value_type> l) : std::multimap<URI, Property>(l) @@ -77,7 +84,7 @@ public: } bool contains(const URI& key, const Atom& value) { - for (const_iterator i = find(key); i != end() && i->first == key; ++i) { + for (auto i = find(key); i != end() && i->first == key; ++i) { if (i->second == value) { return true; } diff --git a/include/ingen/QueuedInterface.hpp b/include/ingen/QueuedInterface.hpp index 97fbb731..ab2c2532 100644 --- a/include/ingen/QueuedInterface.hpp +++ b/include/ingen/QueuedInterface.hpp @@ -17,11 +17,10 @@ #ifndef INGEN_QUEUEDINTERFACE_HPP #define INGEN_QUEUEDINTERFACE_HPP -#include "ingen/Interface.hpp" -#include "ingen/Message.hpp" -#include "ingen/URI.hpp" +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/URI.hpp> -#include <algorithm> #include <memory> #include <mutex> #include <utility> @@ -38,20 +37,19 @@ class QueuedInterface : public Interface public: explicit QueuedInterface(std::shared_ptr<Interface> sink) : _sink(std::move(sink)) - { - } + {} URI uri() const override { return URI("ingen:/QueuedInterface"); } void message(const Message& message) override { - std::lock_guard<std::mutex> lock(_mutex); + const std::lock_guard<std::mutex> lock{_mutex}; _messages.emplace_back(message); } void emit() { std::vector<Message> messages; { - std::lock_guard<std::mutex> lock(_mutex); + const std::lock_guard<std::mutex> lock{_mutex}; _messages.swap(messages); } diff --git a/include/ingen/Resource.hpp b/include/ingen/Resource.hpp index 577e8cc0..f6a12bad 100644 --- a/include/ingen/Resource.hpp +++ b/include/ingen/Resource.hpp @@ -17,11 +17,11 @@ #ifndef INGEN_RESOURCE_HPP #define INGEN_RESOURCE_HPP -#include "ingen/Properties.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/ingen.h" -#include "raul/Deletable.hpp" +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/ingen.h> +#include <raul/Deletable.hpp> #include <cassert> #include <utility> @@ -69,9 +69,12 @@ public: static Graph uri_to_graph(const URI& uri) { if (uri == INGEN_NS "externalContext") { return Graph::EXTERNAL; - } else if (uri == INGEN_NS "internalContext") { + } + + if (uri == INGEN_NS "internalContext") { return Graph::INTERNAL; } + return Graph::DEFAULT; } @@ -172,8 +175,8 @@ public: /** Get the ingen type from a set of Properties. * - * If some coherent ingen type is found, true is returned and the appropriate - * output parameter set to true. Otherwise false is returned. + * If some coherent ingen type is found, true is returned and the + * appropriate output parameter set to true. Otherwise false is returned. */ static bool type(const URIs& uris, const Properties& properties, diff --git a/include/ingen/Serialiser.hpp b/include/ingen/Serialiser.hpp index 37eda462..6e9d6ad4 100644 --- a/include/ingen/Serialiser.hpp +++ b/include/ingen/Serialiser.hpp @@ -17,15 +17,17 @@ #ifndef INGEN_SERIALISER_HPP #define INGEN_SERIALISER_HPP -#include "ingen/FilePath.hpp" -#include "ingen/Properties.hpp" -#include "ingen/ingen.h" -#include "sord/sordmm.hpp" +#include <ingen/FilePath.hpp> +#include <ingen/Properties.hpp> +#include <ingen/ingen.h> +#include <sord/sordmm.hpp> #include <memory> #include <string> -namespace raul { class Path; } +namespace raul { +class Path; +} // namespace raul namespace ingen { @@ -54,8 +56,8 @@ public: * * This must be called before any serializing methods. * - * The results of the serialization will be returned by the finish() method after - * the desired objects have been serialised. + * The results of the serialization will be returned by the finish() method + * after the desired objects have been serialised. * * All serialized paths will have the root path chopped from their prefix * (therefore all serialized paths must be descendants of the root) @@ -75,14 +77,14 @@ public: /** Serialize an object (graph, block, or port). * - * @throw std::logic_error + * @throw std::logic_error A serialization hasn't been started. */ virtual void serialise(const std::shared_ptr<const Node>& object, Property::Graph context = Property::Graph::DEFAULT); /** Serialize an arc. * - * @throw std::logic_error + * @throw std::logic_error A serialization hasn't been started. */ virtual void serialise_arc(const Sord::Node& parent, const std::shared_ptr<const Arc>& arc); @@ -98,6 +100,7 @@ public: private: struct Impl; + std::unique_ptr<Impl> me; }; diff --git a/include/ingen/SocketReader.hpp b/include/ingen/SocketReader.hpp index f86a9bd6..d0d62747 100644 --- a/include/ingen/SocketReader.hpp +++ b/include/ingen/SocketReader.hpp @@ -17,15 +17,17 @@ #ifndef INGEN_SOCKETREADER_HPP #define INGEN_SOCKETREADER_HPP -#include "ingen/ingen.h" -#include "serd/serd.h" -#include "sord/sord.h" +#include <ingen/ingen.h> +#include <serd/serd.h> +#include <sord/sord.h> #include <cstddef> #include <memory> #include <thread> -namespace raul { class Socket; } +namespace raul { +class Socket; +} // namespace raul namespace ingen { @@ -72,15 +74,15 @@ private: World& _world; Interface& _iface; - SerdEnv* _env; - SordInserter* _inserter; - SordNode* _msg_node; + SerdEnv* _env{nullptr}; + SordInserter* _inserter{nullptr}; + SordNode* _msg_node{nullptr}; std::shared_ptr<raul::Socket> _socket; - int _socket_error; - bool _exit_flag; + int _socket_error{0}; + bool _exit_flag{false}; std::thread _thread; }; -} // namespace ingen +} // namespace ingen -#endif // INGEN_SOCKETREADER_HPP +#endif // INGEN_SOCKETREADER_HPP diff --git a/include/ingen/SocketWriter.hpp b/include/ingen/SocketWriter.hpp index a0896ad9..e564b524 100644 --- a/include/ingen/SocketWriter.hpp +++ b/include/ingen/SocketWriter.hpp @@ -17,9 +17,9 @@ #ifndef INGEN_SOCKETWRITER_HPP #define INGEN_SOCKETWRITER_HPP -#include "ingen/Message.hpp" -#include "ingen/TurtleWriter.hpp" -#include "ingen/ingen.h" +#include <ingen/Message.hpp> +#include <ingen/TurtleWriter.hpp> +#include <ingen/ingen.h> #include <cstddef> #include <memory> @@ -52,6 +52,6 @@ protected: std::shared_ptr<raul::Socket> _socket; }; -} // namespace ingen +} // namespace ingen -#endif // INGEN_SOCKETWRITER_HPP +#endif // INGEN_SOCKETWRITER_HPP diff --git a/include/ingen/Status.hpp b/include/ingen/Status.hpp index c4ffd4c9..fbd23dc0 100644 --- a/include/ingen/Status.hpp +++ b/include/ingen/Status.hpp @@ -50,7 +50,7 @@ enum class Status { COMPILATION_FAILED }; -static inline const char* +inline const char* ingen_status_string(Status st) { switch (st) { diff --git a/include/ingen/Store.hpp b/include/ingen/Store.hpp index 67ea16fa..d18858fb 100644 --- a/include/ingen/Store.hpp +++ b/include/ingen/Store.hpp @@ -17,17 +17,19 @@ #ifndef INGEN_STORE_HPP #define INGEN_STORE_HPP -#include "ingen/ingen.h" -#include "raul/Deletable.hpp" -#include "raul/Noncopyable.hpp" -#include "raul/Path.hpp" +#include <ingen/ingen.h> +#include <raul/Deletable.hpp> +#include <raul/Noncopyable.hpp> +#include <raul/Path.hpp> #include <map> #include <memory> #include <mutex> #include <utility> -namespace raul { class Symbol; } +namespace raul { +class Symbol; +} // namespace raul namespace ingen { @@ -44,7 +46,7 @@ public: void add(Node* o); Node* get(const raul::Path& path) { - const iterator i = find(path); + const auto i = find(path); return (i == end()) ? nullptr : i->second.get(); } diff --git a/include/ingen/StreamWriter.hpp b/include/ingen/StreamWriter.hpp index 620497f8..5ed260ea 100644 --- a/include/ingen/StreamWriter.hpp +++ b/include/ingen/StreamWriter.hpp @@ -17,9 +17,9 @@ #ifndef INGEN_STREAMWRITER_HPP #define INGEN_STREAMWRITER_HPP -#include "ingen/ColorContext.hpp" -#include "ingen/TurtleWriter.hpp" -#include "ingen/ingen.h" +#include <ingen/ColorContext.hpp> +#include <ingen/TurtleWriter.hpp> +#include <ingen/ingen.h> #include <cstdio> @@ -47,6 +47,6 @@ protected: ColorContext::Color _color; }; -} // namespace ingen +} // namespace ingen -#endif // INGEN_STREAMWRITER_HPP +#endif // INGEN_STREAMWRITER_HPP diff --git a/include/ingen/Tee.hpp b/include/ingen/Tee.hpp index 1e6805cc..c1ac0d31 100644 --- a/include/ingen/Tee.hpp +++ b/include/ingen/Tee.hpp @@ -17,9 +17,9 @@ #ifndef INGEN_TEE_HPP #define INGEN_TEE_HPP -#include "ingen/Interface.hpp" -#include "ingen/Message.hpp" -#include "ingen/URI.hpp" +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/URI.hpp> #include <memory> #include <mutex> @@ -34,7 +34,7 @@ class Tee : public Interface public: using Sinks = std::vector<std::shared_ptr<Interface>>; - explicit Tee(Sinks sinks) : _sinks(std::move(sinks)) {} + explicit Tee(Sinks sinks) noexcept : _sinks(std::move(sinks)) {} std::shared_ptr<Interface> respondee() const override { return _sinks.front()->respondee(); @@ -46,7 +46,7 @@ public: } void message(const Message& message) override { - std::lock_guard<std::mutex> lock(_sinks_mutex); + const std::lock_guard<std::mutex> lock{_sinks_mutex}; for (const auto& s : _sinks) { s->message(message); } diff --git a/include/ingen/TurtleWriter.hpp b/include/ingen/TurtleWriter.hpp index d9aa13d3..07d4e249 100644 --- a/include/ingen/TurtleWriter.hpp +++ b/include/ingen/TurtleWriter.hpp @@ -17,13 +17,13 @@ #ifndef INGEN_TURTLEWRITER_HPP #define INGEN_TURTLEWRITER_HPP -#include "ingen/AtomSink.hpp" -#include "ingen/AtomWriter.hpp" -#include "ingen/URI.hpp" -#include "ingen/ingen.h" -#include "lv2/atom/atom.h" -#include "serd/serd.h" -#include "sratom/sratom.h" +#include <ingen/AtomSink.hpp> +#include <ingen/AtomWriter.hpp> +#include <ingen/URI.hpp> +#include <ingen/ingen.h> +#include <lv2/atom/atom.h> +#include <serd/serd.h> +#include <sratom/sratom.h> #include <cstddef> #include <cstdint> @@ -57,13 +57,13 @@ protected: URIMap& _map; Sratom* _sratom; SerdNode _base; - SerdURI _base_uri; + SerdURI _base_uri{SERD_URI_NULL}; SerdEnv* _env; SerdWriter* _writer; URI _uri; - bool _wrote_prefixes; + bool _wrote_prefixes{false}; }; -} // namespace ingen +} // namespace ingen -#endif // INGEN_TURTLEWRITER_HPP +#endif // INGEN_TURTLEWRITER_HPP diff --git a/include/ingen/URI.hpp b/include/ingen/URI.hpp index b8108224..53812c4b 100644 --- a/include/ingen/URI.hpp +++ b/include/ingen/URI.hpp @@ -17,32 +17,30 @@ #ifndef INGEN_URI_HPP #define INGEN_URI_HPP -#include "ingen/FilePath.hpp" -#include "ingen/ingen.h" -#include "serd/serd.h" -#include "sord/sordmm.hpp" - -#include <boost/utility/string_view.hpp> // IWYU pragma: export -#include <boost/utility/string_view_fwd.hpp> // IWYU pragma: export +#include <ingen/FilePath.hpp> +#include <ingen/ingen.h> +#include <serd/serd.h> +#include <sord/sordmm.hpp> #include <cstddef> #include <cstdint> #include <ostream> #include <string> +#include <string_view> namespace ingen { class INGEN_API URI { public: - using Chunk = boost::string_view; + using Chunk = std::string_view; URI(); explicit URI(const std::string& str); explicit URI(const char* str); URI(const std::string& str, const URI& base); URI(const Sord::Node& node); - URI(SerdNode node); + URI(const SerdNode& node); explicit URI(const FilePath& path); URI(const URI& uri); @@ -54,10 +52,11 @@ public: ~URI(); URI make_relative(const URI& base) const; + URI make_relative(const URI& base, const URI& root) const; bool empty() const { return !_node.buf; } - std::string string() const { return std::string(c_str(), _node.n_bytes); } + std::string string() const { return {c_str(), _node.n_bytes}; } size_t length() const { return _node.n_bytes; } const char* c_str() const @@ -99,10 +98,10 @@ public: } private: - URI(SerdNode node, SerdURI uri); + URI(const SerdNode& node, const SerdURI& uri); static Chunk make_chunk(const SerdChunk& chunk) { - return Chunk(reinterpret_cast<const char*>(chunk.buf), chunk.len); + return {reinterpret_cast<const char*>(chunk.buf), chunk.len}; } SerdURI _uri; @@ -173,4 +172,4 @@ operator<<(std::basic_ostream<Char, Traits>& os, const URI& uri) } // namespace ingen -#endif // INGEN_URI_HPP +#endif // INGEN_URI_HPP diff --git a/include/ingen/URIMap.hpp b/include/ingen/URIMap.hpp index 465f87f1..fbb0523c 100644 --- a/include/ingen/URIMap.hpp +++ b/include/ingen/URIMap.hpp @@ -17,12 +17,12 @@ #ifndef INGEN_URIMAP_HPP #define INGEN_URIMAP_HPP -#include "ingen/LV2Features.hpp" -#include "ingen/ingen.h" -#include "ingen/memory.hpp" -#include "lv2/core/lv2.h" -#include "lv2/urid/urid.h" -#include "raul/Noncopyable.hpp" +#include <ingen/LV2Features.hpp> +#include <ingen/ingen.h> +#include <ingen/memory.hpp> +#include <lv2/core/lv2.h> +#include <lv2/urid/urid.h> +#include <raul/Noncopyable.hpp> #include <cstdint> #include <memory> @@ -34,13 +34,12 @@ namespace ingen { class Log; -class Node; -class World; /** URI to integer map and implementation of LV2 URID extension. * @ingroup IngenShared */ -class INGEN_API URIMap : public raul::Noncopyable { +class INGEN_API URIMap : public raul::Noncopyable +{ public: URIMap(Log& log, LV2_URID_Map* map, LV2_URID_Unmap* unmap); @@ -48,7 +47,8 @@ public: uint32_t map_uri(const std::string& uri) { return map_uri(uri.c_str()); } const char* unmap_uri(uint32_t urid) const; - class Feature : public LV2Features::Feature { + class Feature : public LV2Features::Feature + { public: Feature(const char* URI, void* data) : _feature{URI, data} {} @@ -56,8 +56,7 @@ public: std::shared_ptr<LV2_Feature> feature(World&, Node*) override { - return std::shared_ptr<LV2_Feature>(&_feature, - NullDeleter<LV2_Feature>); + return {&_feature, NullDeleter<LV2_Feature>}; } private: @@ -93,8 +92,13 @@ public: const LV2_URID_Map& urid_map() const { return _urid_map_feature->data(); } LV2_URID_Map& urid_map() { return _urid_map_feature->data(); } - const LV2_URID_Unmap& urid_unmap() const { return _urid_unmap_feature->data(); } - LV2_URID_Unmap& urid_unmap() { return _urid_unmap_feature->data(); } + + const LV2_URID_Unmap& urid_unmap() const + { + return _urid_unmap_feature->data(); + } + + LV2_URID_Unmap& urid_unmap() { return _urid_unmap_feature->data(); } std::shared_ptr<URIDMapFeature> urid_map_feature() { diff --git a/include/ingen/URIs.hpp b/include/ingen/URIs.hpp index cfa00f73..b3a4124f 100644 --- a/include/ingen/URIs.hpp +++ b/include/ingen/URIs.hpp @@ -17,12 +17,12 @@ #ifndef INGEN_URIS_HPP #define INGEN_URIS_HPP -#include "ingen/Atom.hpp" -#include "ingen/URI.hpp" -#include "ingen/ingen.h" -#include "lilv/lilv.h" -#include "lv2/urid/urid.h" -#include "raul/Noncopyable.hpp" +#include <ingen/Atom.hpp> +#include <ingen/URI.hpp> +#include <ingen/ingen.h> +#include <lilv/lilv.h> +#include <lv2/urid/urid.h> +#include <raul/Noncopyable.hpp> namespace ingen { @@ -37,7 +37,8 @@ class URIMap; * * @ingroup ingen */ -class INGEN_API URIs : public raul::Noncopyable { +class INGEN_API URIs : public raul::Noncopyable +{ public: URIs(ingen::Forge& ingen_forge, URIMap* map, LilvWorld* lworld); @@ -69,142 +70,143 @@ public: ingen::Forge& forge; - const Quark atom_AtomPort; - const Quark atom_Bool; - const Quark atom_Chunk; - const Quark atom_Float; - const Quark atom_Int; - const Quark atom_Object; - const Quark atom_Path; - const Quark atom_Sequence; - const Quark atom_Sound; - const Quark atom_String; - const Quark atom_URI; - const Quark atom_URID; - const Quark atom_bufferType; - const Quark atom_eventTransfer; - const Quark atom_supports; - const Quark bufsz_maxBlockLength; - const Quark bufsz_minBlockLength; - const Quark bufsz_sequenceSize; - const Quark doap_name; - const Quark ingen_Arc; - const Quark ingen_Block; - const Quark ingen_BundleEnd; - const Quark ingen_BundleStart; - const Quark ingen_Graph; - const Quark ingen_GraphPrototype; - const Quark ingen_Internal; - const Quark ingen_Redo; - const Quark ingen_Undo; - const Quark ingen_activity; - const Quark ingen_arc; - const Quark ingen_block; - const Quark ingen_broadcast; - const Quark ingen_canvasX; - const Quark ingen_canvasY; - const Quark ingen_enabled; - const Quark ingen_externalContext; - const Quark ingen_file; - const Quark ingen_head; - const Quark ingen_incidentTo; - const Quark ingen_internalContext; - const Quark ingen_loadedBundle; - const Quark ingen_maxRunLoad; - const Quark ingen_meanRunLoad; - const Quark ingen_minRunLoad; - const Quark ingen_numThreads; - const Quark ingen_polyphonic; - const Quark ingen_polyphony; - const Quark ingen_prototype; - const Quark ingen_sprungLayout; - const Quark ingen_tail; - const Quark ingen_uiEmbedded; - const Quark ingen_value; - const Quark log_Error; - const Quark log_Note; - const Quark log_Trace; - const Quark log_Warning; - const Quark lv2_AudioPort; - const Quark lv2_CVPort; - const Quark lv2_ControlPort; - const Quark lv2_InputPort; - const Quark lv2_OutputPort; - const Quark lv2_Plugin; - const Quark lv2_appliesTo; - const Quark lv2_binary; - const Quark lv2_connectionOptional; - const Quark lv2_control; - const Quark lv2_default; - const Quark lv2_designation; - const Quark lv2_enumeration; - const Quark lv2_extensionData; - const Quark lv2_index; - const Quark lv2_integer; - const Quark lv2_maximum; - const Quark lv2_microVersion; - const Quark lv2_minimum; - const Quark lv2_minorVersion; - const Quark lv2_name; - const Quark lv2_port; - const Quark lv2_portProperty; - const Quark lv2_prototype; - const Quark lv2_sampleRate; - const Quark lv2_scalePoint; - const Quark lv2_symbol; - const Quark lv2_toggled; - const Quark midi_Bender; - const Quark midi_ChannelPressure; - const Quark midi_Controller; - const Quark midi_MidiEvent; - const Quark midi_NoteOn; - const Quark midi_binding; - const Quark midi_controllerNumber; - const Quark midi_noteNumber; - const Quark morph_AutoMorphPort; - const Quark morph_MorphPort; - const Quark morph_currentType; - const Quark morph_supportsType; - const Quark opt_interface; - const Quark param_sampleRate; - const Quark patch_Copy; - const Quark patch_Delete; - const Quark patch_Get; - const Quark patch_Message; - const Quark patch_Move; - const Quark patch_Patch; - const Quark patch_Put; - const Quark patch_Response; - const Quark patch_Set; - const Quark patch_add; - const Quark patch_body; - const Quark patch_context; - const Quark patch_destination; - const Quark patch_property; - const Quark patch_remove; - const Quark patch_sequenceNumber; - const Quark patch_subject; - const Quark patch_value; - const Quark patch_wildcard; - const Quark pprops_logarithmic; - const Quark pset_Preset; - const Quark pset_preset; - const Quark rdf_type; - const Quark rdfs_Class; - const Quark rdfs_label; - const Quark rdfs_seeAlso; - const Quark rsz_minimumSize; - const Quark state_loadDefaultState; - const Quark state_state; - const Quark time_Position; - const Quark time_bar; - const Quark time_barBeat; - const Quark time_beatUnit; - const Quark time_beatsPerBar; - const Quark time_beatsPerMinute; - const Quark time_frame; - const Quark time_speed; - const Quark work_schedule; + Quark atom_AtomPort; + Quark atom_Bool; + Quark atom_Chunk; + Quark atom_Float; + Quark atom_Int; + Quark atom_Object; + Quark atom_Path; + Quark atom_Sequence; + Quark atom_Sound; + Quark atom_String; + Quark atom_URI; + Quark atom_URID; + Quark atom_bufferType; + Quark atom_eventTransfer; + Quark atom_supports; + Quark bufsz_maxBlockLength; + Quark bufsz_minBlockLength; + Quark bufsz_sequenceSize; + Quark doap_name; + Quark ingen_Arc; + Quark ingen_Block; + Quark ingen_BundleEnd; + Quark ingen_BundleStart; + Quark ingen_Graph; + Quark ingen_GraphPrototype; + Quark ingen_Internal; + Quark ingen_Redo; + Quark ingen_Undo; + Quark ingen_activity; + Quark ingen_arc; + Quark ingen_block; + Quark ingen_broadcast; + Quark ingen_canvasX; + Quark ingen_canvasY; + Quark ingen_enabled; + Quark ingen_externalContext; + Quark ingen_file; + Quark ingen_head; + Quark ingen_incidentTo; + Quark ingen_internalContext; + Quark ingen_loadedBundle; + Quark ingen_maxRunLoad; + Quark ingen_meanRunLoad; + Quark ingen_minRunLoad; + Quark ingen_numThreads; + Quark ingen_polyphonic; + Quark ingen_polyphony; + Quark ingen_prototype; + Quark ingen_sprungLayout; + Quark ingen_tail; + Quark ingen_uiEmbedded; + Quark ingen_value; + Quark log_Error; + Quark log_Note; + Quark log_Trace; + Quark log_Warning; + Quark lv2_AudioPort; + Quark lv2_CVPort; + Quark lv2_ControlPort; + Quark lv2_InputPort; + Quark lv2_OutputPort; + Quark lv2_Plugin; + Quark lv2_appliesTo; + Quark lv2_binary; + Quark lv2_connectionOptional; + Quark lv2_control; + Quark lv2_default; + Quark lv2_designation; + Quark lv2_enumeration; + Quark lv2_extensionData; + Quark lv2_index; + Quark lv2_integer; + Quark lv2_maximum; + Quark lv2_microVersion; + Quark lv2_minimum; + Quark lv2_minorVersion; + Quark lv2_name; + Quark lv2_port; + Quark lv2_portProperty; + Quark lv2_prototype; + Quark lv2_sampleRate; + Quark lv2_scalePoint; + Quark lv2_symbol; + Quark lv2_toggled; + Quark midi_Bender; + Quark midi_ChannelPressure; + Quark midi_Controller; + Quark midi_MidiEvent; + Quark midi_NoteOn; + Quark midi_binding; + Quark midi_controllerNumber; + Quark midi_noteNumber; + Quark midi_channel; + Quark morph_AutoMorphPort; + Quark morph_MorphPort; + Quark morph_currentType; + Quark morph_supportsType; + Quark opt_interface; + Quark param_sampleRate; + Quark patch_Copy; + Quark patch_Delete; + Quark patch_Get; + Quark patch_Message; + Quark patch_Move; + Quark patch_Patch; + Quark patch_Put; + Quark patch_Response; + Quark patch_Set; + Quark patch_add; + Quark patch_body; + Quark patch_context; + Quark patch_destination; + Quark patch_property; + Quark patch_remove; + Quark patch_sequenceNumber; + Quark patch_subject; + Quark patch_value; + Quark patch_wildcard; + Quark pprops_logarithmic; + Quark pset_Preset; + Quark pset_preset; + Quark rdf_type; + Quark rdfs_Class; + Quark rdfs_label; + Quark rdfs_seeAlso; + Quark rsz_minimumSize; + Quark state_loadDefaultState; + Quark state_state; + Quark time_Position; + Quark time_bar; + Quark time_barBeat; + Quark time_beatUnit; + Quark time_beatsPerBar; + Quark time_beatsPerMinute; + Quark time_frame; + Quark time_speed; + Quark work_schedule; }; inline bool @@ -212,9 +214,12 @@ operator==(const URIs::Quark& lhs, const Atom& rhs) { if (rhs.type() == lhs.urid_atom().type()) { return rhs == lhs.urid_atom(); - } else if (rhs.type() == lhs.uri_atom().type()) { + } + + if (rhs.type() == lhs.uri_atom().type()) { return rhs == lhs.uri_atom(); } + return false; } diff --git a/include/ingen/World.hpp b/include/ingen/World.hpp index ecf1d45a..738012cd 100644 --- a/include/ingen/World.hpp +++ b/include/ingen/World.hpp @@ -17,11 +17,10 @@ #ifndef INGEN_WORLD_HPP #define INGEN_WORLD_HPP -#include "ingen/ingen.h" -#include "lilv/lilv.h" -#include "lv2/log/log.h" -#include "lv2/urid/urid.h" -#include "raul/Noncopyable.hpp" +#include <ingen/ingen.h> +#include <lv2/log/log.h> +#include <lv2/urid/urid.h> +#include <raul/Noncopyable.hpp> #include <memory> #include <mutex> @@ -29,7 +28,9 @@ using LilvWorld = struct LilvWorldImpl; -namespace Sord { class World; } +namespace Sord { +class World; +} // namespace Sord namespace ingen { @@ -62,7 +63,8 @@ class URIs; * * @ingroup IngenShared */ -class INGEN_API World : public raul::Noncopyable { +class INGEN_API World : public raul::Noncopyable +{ public: /** Construct a new Ingen world. * @param map LV2 URID map implementation, or null to use internal. @@ -148,6 +150,6 @@ private: Impl* _impl; }; -} // namespace ingen +} // namespace ingen -#endif // INGEN_WORLD_HPP +#endif // INGEN_WORLD_HPP diff --git a/include/ingen/client/ArcModel.hpp b/include/ingen/client/ArcModel.hpp index a76f274f..21238831 100644 --- a/include/ingen/client/ArcModel.hpp +++ b/include/ingen/client/ArcModel.hpp @@ -17,18 +17,17 @@ #ifndef INGEN_CLIENT_ARCMODEL_HPP #define INGEN_CLIENT_ARCMODEL_HPP -#include "ingen/Arc.hpp" -#include "ingen/client/PortModel.hpp" -#include "ingen/ingen.h" -#include "raul/Path.hpp" +#include <ingen/Arc.hpp> +#include <ingen/client/PortModel.hpp> +#include <ingen/ingen.h> +#include <raul/Path.hpp> #include <cassert> #include <memory> #include <string> #include <utility> -namespace ingen { -namespace client { +namespace ingen::client { /** Class to represent a port->port connections in the engine. * @@ -61,7 +60,6 @@ private: const std::shared_ptr<PortModel> _head; }; -} // namespace client -} // namespace ingen +} // namespace ingen::client #endif // INGEN_CLIENT_ARCMODEL_HPP diff --git a/include/ingen/client/BlockModel.hpp b/include/ingen/client/BlockModel.hpp index 060d454f..db41f4ef 100644 --- a/include/ingen/client/BlockModel.hpp +++ b/include/ingen/client/BlockModel.hpp @@ -17,12 +17,12 @@ #ifndef INGEN_CLIENT_BLOCKMODEL_HPP #define INGEN_CLIENT_BLOCKMODEL_HPP -#include "ingen/Node.hpp" -#include "ingen/URI.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "ingen/client/PluginModel.hpp" // IWYU pragma: keep -#include "ingen/client/signal.hpp" -#include "ingen/ingen.h" +#include <ingen/Node.hpp> +#include <ingen/URI.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/signal.hpp> +#include <ingen/ingen.h> #include <cstdint> #include <memory> diff --git a/include/ingen/client/ClientStore.hpp b/include/ingen/client/ClientStore.hpp index 3aec363f..c649aab3 100644 --- a/include/ingen/client/ClientStore.hpp +++ b/include/ingen/client/ClientStore.hpp @@ -17,12 +17,12 @@ #ifndef INGEN_CLIENT_CLIENTSTORE_HPP #define INGEN_CLIENT_CLIENTSTORE_HPP -#include "ingen/Interface.hpp" -#include "ingen/Message.hpp" -#include "ingen/Store.hpp" -#include "ingen/URI.hpp" -#include "ingen/client/signal.hpp" -#include "ingen/ingen.h" +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/client/signal.hpp> +#include <ingen/ingen.h> #include <map> #include <memory> @@ -78,22 +78,22 @@ public: void message(const Message& msg) override; - void operator()(const BundleBegin&) {} - void operator()(const BundleEnd&) {} + void operator()(const BundleBegin&) noexcept {} + void operator()(const BundleEnd&) noexcept {} void operator()(const Connect&); void operator()(const Copy&); void operator()(const Del&); void operator()(const Delta&); void operator()(const Disconnect&); void operator()(const DisconnectAll&); - void operator()(const Error&) {} - void operator()(const Get&) {} + void operator()(const Error&) noexcept {} + void operator()(const Get&) noexcept {} void operator()(const Move&); void operator()(const Put&); - void operator()(const Redo&) {} - void operator()(const Response&) {} + void operator()(const Redo&) noexcept {} + void operator()(const Response&) noexcept {} void operator()(const SetProperty&); - void operator()(const Undo&) {} + void operator()(const Undo&) noexcept {} INGEN_SIGNAL(new_object, void, std::shared_ptr<ObjectModel>) INGEN_SIGNAL(new_plugin, void, std::shared_ptr<PluginModel>) diff --git a/include/ingen/client/GraphModel.hpp b/include/ingen/client/GraphModel.hpp index 59d1bb65..837a28a5 100644 --- a/include/ingen/client/GraphModel.hpp +++ b/include/ingen/client/GraphModel.hpp @@ -17,11 +17,10 @@ #ifndef INGEN_CLIENT_GRAPHMODEL_HPP #define INGEN_CLIENT_GRAPHMODEL_HPP -#include "ingen/Node.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/signal.hpp" -#include "ingen/ingen.h" +#include <ingen/Node.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/signal.hpp> +#include <ingen/ingen.h> #include <cstdint> #include <memory> @@ -32,12 +31,11 @@ class Path; namespace ingen { -class URI; +class URIs; namespace client { class ArcModel; -class ObjectModel; class PortModel; /** Client's model of a graph. @@ -55,7 +53,6 @@ public: get_arc(const ingen::Node* tail, const ingen::Node* head); bool enabled() const; - bool polyphonic() const; uint32_t internal_poly() const; // Signals @@ -67,12 +64,7 @@ public: private: friend class ClientStore; - GraphModel(URIs& uris, const raul::Path& graph_path) - : BlockModel(uris, - static_cast<const URI&>(uris.ingen_Graph), - graph_path) - { - } + GraphModel(URIs& uris, const raul::Path& graph_path); void clear() override; void add_child(const std::shared_ptr<ObjectModel>& c) override; diff --git a/include/ingen/client/ObjectModel.hpp b/include/ingen/client/ObjectModel.hpp index e92618f8..f9f0e041 100644 --- a/include/ingen/client/ObjectModel.hpp +++ b/include/ingen/client/ObjectModel.hpp @@ -21,19 +21,19 @@ #ifndef INGEN_CLIENT_OBJECTMODEL_HPP #define INGEN_CLIENT_OBJECTMODEL_HPP -#include "ingen/Node.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/signal.hpp" -#include "ingen/ingen.h" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Node.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/signal.hpp> +#include <ingen/ingen.h> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <memory> namespace ingen { class Atom; +class URI; namespace client { diff --git a/include/ingen/client/PluginModel.hpp b/include/ingen/client/PluginModel.hpp index b0a61e94..37b71d0d 100644 --- a/include/ingen/client/PluginModel.hpp +++ b/include/ingen/client/PluginModel.hpp @@ -17,16 +17,16 @@ #ifndef INGEN_CLIENT_PLUGINMODEL_HPP #define INGEN_CLIENT_PLUGINMODEL_HPP -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/signal.hpp" -#include "ingen/ingen.h" -#include "lilv/lilv.h" -#include "raul/Symbol.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/signal.hpp> +#include <ingen/ingen.h> +#include <lilv/lilv.h> +#include <raul/Symbol.hpp> #include <cstdint> #include <map> @@ -124,7 +124,7 @@ private: Atom _type; const LilvPlugin* _lilv_plugin; Presets _presets; - bool _fetched; + bool _fetched{false}; }; } // namespace client diff --git a/include/ingen/client/PluginUI.hpp b/include/ingen/client/PluginUI.hpp index 35a14bd2..6ecaed89 100644 --- a/include/ingen/client/PluginUI.hpp +++ b/include/ingen/client/PluginUI.hpp @@ -19,11 +19,11 @@ #include "signal.hpp" -#include "ingen/LV2Features.hpp" -#include "ingen/Resource.hpp" -#include "ingen/ingen.h" -#include "lilv/lilv.h" -#include "suil/suil.h" +#include <ingen/LV2Features.hpp> +#include <ingen/Resource.hpp> +#include <ingen/ingen.h> +#include <lilv/lilv.h> +#include <suil/suil.h> #include <cstdint> #include <memory> @@ -43,7 +43,8 @@ class BlockModel; * * @ingroup IngenClient */ -class INGEN_API PluginUI { +class INGEN_API PluginUI +{ public: ~PluginUI(); @@ -60,7 +61,7 @@ public: /** Instantiate the UI. * - * If true is returned, instantiation was successfull and the widget can be + * If true is returned, instantiation was successful and the widget can be * obtained with get_widget(). Otherwise, instantiation failed, so there is * no widget and the UI can not be used. */ @@ -81,11 +82,12 @@ public: * The application must connect to this signal to communicate with the * engine and/or update itself as necessary. */ - INGEN_SIGNAL(property_changed, void, - const URI&, // Subject - const URI&, // Predicate - const Atom&, // Object - Resource::Graph) // Context + INGEN_SIGNAL(property_changed, + void, + const URI&, // Subject + const URI&, // Predicate + const Atom&, // Object + Resource::Graph) // Context ingen::World& world() const { return _world; } std::shared_ptr<const BlockModel> block() const { return _block; } @@ -99,11 +101,11 @@ private: ingen::World& _world; std::shared_ptr<const BlockModel> _block; - SuilInstance* _instance; - LilvUIs* _uis; - const LilvUI* _ui; - LilvNode* _ui_node; - LilvNode* _ui_type; + SuilInstance* _instance{nullptr}; + LilvUIs* _uis{nullptr}; + const LilvUI* _ui{nullptr}; + LilvNode* _ui_node{nullptr}; + LilvNode* _ui_type{nullptr}; std::set<uint32_t> _subscribed_ports; static SuilHost* ui_host; diff --git a/include/ingen/client/PortModel.hpp b/include/ingen/client/PortModel.hpp index 9323b84b..c87f2f03 100644 --- a/include/ingen/client/PortModel.hpp +++ b/include/ingen/client/PortModel.hpp @@ -17,16 +17,14 @@ #ifndef INGEN_CLIENT_PORTMODEL_HPP #define INGEN_CLIENT_PORTMODEL_HPP -#include "ingen/Node.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "ingen/client/signal.hpp" -#include "ingen/ingen.h" -#include "raul/Path.hpp" +#include <ingen/Node.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/signal.hpp> +#include <ingen/ingen.h> +#include <raul/Path.hpp> #include <cstdint> -#include <memory> #include <string> namespace ingen { @@ -48,10 +46,10 @@ public: bool supports(const URIs::Quark& value_type) const; - inline uint32_t index() const { return _index; } - inline const Atom& value() const { return get_property(_uris.ingen_value); } - inline bool is_input() const { return (_direction == Direction::INPUT); } - inline bool is_output() const { return (_direction == Direction::OUTPUT); } + uint32_t index() const { return _index; } + const Atom& value() const { return get_property(_uris.ingen_value); } + bool is_input() const { return (_direction == Direction::INPUT); } + bool is_output() const { return (_direction == Direction::OUTPUT); } bool port_property(const URIs::Quark& uri) const; @@ -65,7 +63,7 @@ public: } bool is_uri() const; - inline bool operator==(const PortModel& pm) const { return (path() == pm.path()); } + bool operator==(const PortModel& pm) const { return (path() == pm.path()); } void on_property(const URI& uri, const Atom& value) override; @@ -86,8 +84,8 @@ private: , _direction(dir) {} - void add_child(const std::shared_ptr<ObjectModel>& c) override { throw; } - bool remove_child(const std::shared_ptr<ObjectModel>& c) override { throw; } + void add_child(const std::shared_ptr<ObjectModel>& c) override; + bool remove_child(const std::shared_ptr<ObjectModel>& c) override; void set(const std::shared_ptr<ObjectModel>& model) override; diff --git a/include/ingen/client/SigClientInterface.hpp b/include/ingen/client/SigClientInterface.hpp index 51e05b50..52bceacc 100644 --- a/include/ingen/client/SigClientInterface.hpp +++ b/include/ingen/client/SigClientInterface.hpp @@ -17,14 +17,13 @@ #ifndef INGEN_CLIENT_SIGCLIENTINTERFACE_HPP #define INGEN_CLIENT_SIGCLIENTINTERFACE_HPP -#include "ingen/Interface.hpp" -#include "ingen/Message.hpp" -#include "ingen/URI.hpp" -#include "ingen/client/signal.hpp" -#include "ingen/ingen.h" +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/URI.hpp> +#include <ingen/client/signal.hpp> +#include <ingen/ingen.h> -namespace ingen { -namespace client { +namespace ingen::client { /** A LibSigC++ signal emitting interface for clients to use. * @@ -46,7 +45,7 @@ public: INGEN_SIGNAL(message, void, Message) - /** Fire pending signals. Only does anything on derived classes (that may queue) */ + /** Fire pending signals (for derived classes that may queue). */ virtual bool emit_signals() { return false; } protected: @@ -55,7 +54,6 @@ protected: } }; -} // namespace client -} // namespace ingen +} // namespace ingen::client #endif diff --git a/include/ingen/client/SocketClient.hpp b/include/ingen/client/SocketClient.hpp index 1e75ae80..23f8a3ff 100644 --- a/include/ingen/client/SocketClient.hpp +++ b/include/ingen/client/SocketClient.hpp @@ -14,21 +14,20 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef INGEN_CLIENT_SOCKET_CLIENT_HPP -#define INGEN_CLIENT_SOCKET_CLIENT_HPP +#ifndef INGEN_CLIENT_SOCKETCLIENT_HPP +#define INGEN_CLIENT_SOCKETCLIENT_HPP -#include "ingen/Log.hpp" -#include "ingen/SocketReader.hpp" -#include "ingen/SocketWriter.hpp" -#include "ingen/URI.hpp" -#include "ingen/World.hpp" -#include "ingen/ingen.h" -#include "raul/Socket.hpp" +#include <ingen/Log.hpp> +#include <ingen/SocketReader.hpp> +#include <ingen/SocketWriter.hpp> +#include <ingen/URI.hpp> +#include <ingen/World.hpp> +#include <ingen/ingen.h> +#include <raul/Socket.hpp> #include <cerrno> #include <cstring> #include <memory> -#include <string> namespace ingen { @@ -67,7 +66,7 @@ public: ? raul::Socket::Type::UNIX : raul::Socket::Type::TCP); - std::shared_ptr<raul::Socket> sock(new raul::Socket(type)); + const std::shared_ptr<raul::Socket> sock{new raul::Socket(type)}; if (!sock->connect(uri)) { world.log().error("Failed to connect <%1%> (%2%)\n", sock->uri(), strerror(errno)); @@ -87,7 +86,7 @@ private: SocketReader _reader; }; -} // namespace client -} // namespace ingen +} // namespace client +} // namespace ingen -#endif // INGEN_CLIENT_SOCKET_CLIENT_HPP +#endif // INGEN_CLIENT_SOCKETCLIENT_HPP diff --git a/include/ingen/client/client.h b/include/ingen/client/client.h new file mode 100644 index 00000000..6f7ac9b5 --- /dev/null +++ b/include/ingen/client/client.h @@ -0,0 +1,31 @@ +/* + This file is part of Ingen. + Copyright 2014-2022 David Robillard <http://drobilla.net/> + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef INGEN_CLIENT_CLIENT_H +#define INGEN_CLIENT_CLIENT_H + +#if defined(_WIN32) && !defined(INGEN_CLIENT_STATIC) && \ + defined(INGEN_CLIENT_INTERNAL) +# define INGEN_CLIENT_API __declspec(dllexport) +#elif defined(_WIN32) && !defined(INGEN_CLIENT_STATIC) +# define INGEN_CLIENT_API __declspec(dllimport) +#elif defined(__GNUC__) +# define INGEN_CLIENT_API __attribute__((visibility("default"))) +#else +# define INGEN_CLIENT_API +#endif + +#endif // INGEN_CLIENT_CLIENT_H diff --git a/include/ingen/filesystem.hpp b/include/ingen/filesystem.hpp deleted file mode 100644 index abe7684e..00000000 --- a/include/ingen/filesystem.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2017 David Robillard <http://drobilla.net/> - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef INGEN_FILESYSTEM_HPP -#define INGEN_FILESYSTEM_HPP - -#define _BSD_SOURCE 1 -#define _DEFAULT_SOURCE 1 - -#include "ingen/FilePath.hpp" - -#ifdef _WIN32 -# include <windows.h> -# include <io.h> -# define F_OK 0 -# define mkdir(path, flags) _mkdir(path) -#else -# include <unistd.h> -#endif - -#include <sys/stat.h> - -#include <algorithm> -#include <cerrno> -#include <cstdlib> -#include <memory> -#include <vector> - -/* A minimal subset of the std::filesystem API from C++17. */ - -namespace ingen { -namespace filesystem { - -inline bool exists(const FilePath& path) -{ - return !access(path.c_str(), F_OK); -} - -inline bool is_directory(const FilePath& path) -{ - struct stat info{}; - stat(path.c_str(), &info); - return S_ISDIR(info.st_mode); -} - -inline bool create_directories(const FilePath& path) -{ - std::vector<FilePath> paths; - for (FilePath p = path; p != path.root_directory(); p = p.parent_path()) { - paths.emplace_back(p); - } - - for (auto p = paths.rbegin(); p != paths.rend(); ++p) { - if (mkdir(p->c_str(), 0755) && errno != EEXIST) { - return false; - } - } - - return true; -} - -inline FilePath current_path() -{ - struct Freer { void operator()(char* const ptr) { free(ptr); } }; - - std::unique_ptr<char, Freer> cpath(realpath(".", nullptr)); - - return FilePath(cpath.get()); -} - -} // namespace filesystem -} // namespace ingen - -#endif // INGEN_FILESYSTEM_HPP diff --git a/include/ingen/fmt.hpp b/include/ingen/fmt.hpp index b2924d29..bfc339e5 100644 --- a/include/ingen/fmt.hpp +++ b/include/ingen/fmt.hpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2016 David Robillard <http://drobilla.net/> + Copyright 2007-2023 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -27,8 +27,10 @@ template <typename... Args> std::string fmt(const char* fmt, Args&&... args) { - boost::format f(fmt); - std::initializer_list<char> l{(static_cast<void>(f % args), char{})...}; + boost::format f{fmt}; // NOLINT(misc-const-correctness) + const std::initializer_list<char> l{ + (static_cast<void>(f % std::forward<Args>(args)), char{})...}; + (void)l; return boost::str(f); } diff --git a/include/ingen/ingen.h b/include/ingen/ingen.h index ccdb5596..9292de46 100644 --- a/include/ingen/ingen.h +++ b/include/ingen/ingen.h @@ -17,21 +17,14 @@ #ifndef INGEN_INGEN_H #define INGEN_INGEN_H -#ifdef INGEN_SHARED -# ifdef _WIN32 -# define INGEN_LIB_IMPORT __declspec(dllimport) -# define INGEN_LIB_EXPORT __declspec(dllexport) -# else -# define INGEN_LIB_IMPORT __attribute__((visibility("default"))) -# define INGEN_LIB_EXPORT __attribute__((visibility("default"))) -# endif -# ifdef INGEN_INTERNAL -# define INGEN_API INGEN_LIB_EXPORT -# else -# define INGEN_API INGEN_LIB_IMPORT -# endif +#if defined(_WIN32) && !defined(INGEN_STATIC) && defined(INGEN_INTERNAL) +# define INGEN_API __declspec(dllexport) +#elif defined(_WIN32) && !defined(INGEN_STATIC) +# define INGEN_API __declspec(dllimport) +#elif defined(__GNUC__) +# define INGEN_API __attribute__((visibility("default"))) #else -# define INGEN_API +# define INGEN_API #endif #define INGEN_NS "http://drobilla.net/ns/ingen#" diff --git a/include/ingen/memory.hpp b/include/ingen/memory.hpp index 6a62d317..a1dba436 100644 --- a/include/ingen/memory.hpp +++ b/include/ingen/memory.hpp @@ -18,16 +18,14 @@ #define INGEN_MEMORY_HPP #include <cstdlib> -#include <memory> -#include <utility> namespace ingen { template <class T> -void NullDeleter(T* ptr) {} +void NullDeleter(T* ptr) noexcept {} template <class T> -struct FreeDeleter { void operator()(T* const ptr) { free(ptr); } }; +struct FreeDeleter { void operator()(T* const ptr) noexcept { free(ptr); } }; } // namespace ingen diff --git a/include/ingen/paths.hpp b/include/ingen/paths.hpp index fefdf364..bf8d8ecc 100644 --- a/include/ingen/paths.hpp +++ b/include/ingen/paths.hpp @@ -17,8 +17,8 @@ #ifndef INGEN_PATHS_HPP #define INGEN_PATHS_HPP -#include "ingen/URI.hpp" -#include "raul/Path.hpp" +#include <ingen/URI.hpp> +#include <raul/Path.hpp> #include <cstddef> #include <string> @@ -32,10 +32,10 @@ inline bool uri_is_path(const URI& uri) const size_t root_len = main_uri().string().length(); if (uri == main_uri()) { return true; - } else { - return uri.string().substr(0, root_len + 1) == - main_uri().string() + "/"; } + + return uri.string().substr(0, root_len + 1) == + main_uri().string() + "/"; } inline raul::Path uri_to_path(const URI& uri) diff --git a/include/ingen/runtime_paths.hpp b/include/ingen/runtime_paths.hpp index 30e877fb..54bda90e 100644 --- a/include/ingen/runtime_paths.hpp +++ b/include/ingen/runtime_paths.hpp @@ -17,8 +17,8 @@ #ifndef INGEN_RUNTIME_PATHS_HPP #define INGEN_RUNTIME_PATHS_HPP -#include "ingen/FilePath.hpp" -#include "ingen/ingen.h" +#include <ingen/FilePath.hpp> +#include <ingen/ingen.h> #include <string> #include <vector> diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..3510d895 --- /dev/null +++ b/meson.build @@ -0,0 +1,346 @@ +# Copyright 2020-2023 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +project( + 'ingen', + 'cpp', + default_options: [ + 'b_ndebug=if-release', + 'buildtype=release', + 'cpp_std=c++17', + ], + license: 'GPLv3+', + meson_version: '>= 0.56.0', + version: '0.5.1', +) + +ingen_src_root = meson.current_source_dir() +ingen_build_root = meson.current_build_dir() +major_version = meson.project_version().split('.')[0] +versioned_name = '@0@-@1@'.format(meson.project_name(), major_version) + +####################### +# Compilers and Flags # +####################### + +# Required tools +cpp = meson.get_compiler('cpp') + +# Set global warning suppressions +warning_level = get_option('warning_level') +cpp_suppressions = [] +if cpp.get_id() == 'clang' + if warning_level == 'everything' + cpp_suppressions = [ + '-Wno-c++17-extensions', + '-Wno-c++98-compat', + '-Wno-c++98-compat-pedantic', + '-Wno-cast-align', + '-Wno-cast-function-type-strict', + '-Wno-cast-qual', + '-Wno-documentation-unknown-command', + '-Wno-exit-time-destructors', + '-Wno-float-conversion', + '-Wno-float-equal', + '-Wno-format-nonliteral', + '-Wno-global-constructors', + '-Wno-implicit-float-conversion', + '-Wno-padded', + '-Wno-reserved-id-macro', + '-Wno-shorten-64-to-32', + '-Wno-sign-conversion', + '-Wno-switch-default', + '-Wno-switch-enum', + '-Wno-unreachable-code', + '-Wno-unsafe-buffer-usage', + '-Wno-vla', + '-Wno-weak-vtables', + ] + + if not meson.is_cross_build() + cpp_suppressions += [ + '-Wno-poison-system-directories', + ] + endif + + if host_machine.system() in ['darwin', 'freebsd'] + cpp_suppressions += [ + '-Wno-comma', # boost + '-Wno-deprecated-copy', # boost + '-Wno-disabled-macro-expansion', # boost + '-Wno-documentation', # JACK + '-Wno-documentation-deprecated-sync', # JACK + '-Wno-extra-semi-stmt', # boost + '-Wno-old-style-cast', # boost + '-Wno-redundant-parens', # boost + '-Wno-suggest-destructor-override', # boost + '-Wno-suggest-override', # boost + '-Wno-unused-template', # boost + '-Wno-zero-as-null-pointer-constant', # boost + ] + endif + endif + + if warning_level in ['everything', '3'] + cpp_suppressions += [ + '-Wno-unused-parameter', + '-Wno-vla-extension', + '-Wno-nullability-extension', + ] + endif + +elif cpp.get_id() == 'gcc' + if warning_level == 'everything' + cpp_suppressions = [ + '-Wno-abi-tag', + '-Wno-alloc-zero', + '-Wno-cast-align', + '-Wno-cast-qual', + '-Wno-conditionally-supported', + '-Wno-conversion', + '-Wno-effc++', + '-Wno-float-conversion', + '-Wno-float-equal', + '-Wno-format', + '-Wno-format-nonliteral', + '-Wno-format-truncation', + '-Wno-inline', + '-Wno-multiple-inheritance', + '-Wno-null-dereference', + '-Wno-old-style-cast', + '-Wno-padded', + '-Wno-redundant-tags', + '-Wno-sign-conversion', + '-Wno-stack-protector', + '-Wno-strict-overflow', + '-Wno-suggest-attribute=cold', + '-Wno-suggest-attribute=const', + '-Wno-suggest-attribute=format', + '-Wno-suggest-attribute=noreturn', + '-Wno-suggest-attribute=pure', + '-Wno-suggest-final-methods', + '-Wno-suggest-final-types', + '-Wno-suggest-override', + '-Wno-switch-default', + '-Wno-switch-enum', + '-Wno-unreachable-code', + '-Wno-unused-const-variable', + '-Wno-useless-cast', + ] + endif + + if warning_level in ['everything', '3'] + cpp_suppressions += ['-Wno-vla'] + endif + + if warning_level in ['everything', '3', '2'] + cpp_suppressions += ['-Wno-unused-parameter'] + endif +endif + +cpp_suppressions = cpp.get_supported_arguments(cpp_suppressions) + +########################## +# LV2 Path Configuration # +########################## + +lv2dir = get_option('lv2dir') +prefix = get_option('prefix') +if lv2dir == '' + if target_machine.system() == 'darwin' and prefix == '/' + lv2dir = '/Library/Audio/Plug-Ins/LV2' + elif target_machine.system() == 'haiku' and prefix == '/' + lv2dir = '/boot/common/add-ons/lv2' + elif target_machine.system() == 'windows' and prefix == 'C:/' + lv2dir = 'C:/Program Files/Common/LV2' + else + lv2dir = prefix / get_option('libdir') / 'lv2' + endif +endif + +########################## +# Platform Configuration # +########################## + +# TODO: Distinguish modules from libraries and move modules to a subdirectory +ingen_data_dir = ( + prefix / get_option('datadir') / 'ingen' # / versioned_name +) +ingen_module_dir = ( + prefix / get_option('libdir') # / versioned_name +) + +# Use versioned name everywhere to support parallel major version installations +if host_machine.system() == 'windows' + if get_option('default_library') == 'both' + error('default_library=both is not supported on Windows') + endif + soversion = '' +else + soversion = meson.project_version().split('.')[0] +endif + +platform_defines = [ + '-DINGEN_DATA_DIR="@0@"'.format(ingen_data_dir), + '-DINGEN_MODULE_DIR="@0@"'.format(ingen_module_dir), + '-DINGEN_VERSION="@0@"'.format(meson.project_version()), +] + +if host_machine.system() == 'darwin' + platform_defines += [ + '-D_DARWIN_C_SOURCE', + '-D_POSIX_C_SOURCE=200809L', + ] +elif host_machine.system() == 'windows' + platform_defines += [ + '-DINGEN_NO_POSIX', + ] +elif host_machine.system() in ['gnu', 'linux'] + platform_defines += [ + '-D_POSIX_C_SOURCE=200809L', + '-D_XOPEN_SOURCE=600', + ] +endif + +socket_code = '''#include <sys/socket.h> +int main(void) { return socket(AF_UNIX, SOCK_STREAM, 0); }''' + +have_socket = cpp.compiles(socket_code, args: platform_defines, name: 'socket') + +platform_defines += ['-DHAVE_SOCKET=@0@'.format(have_socket.to_int())] + +####################### +# Common Dependencies # +####################### + +boost_dep = dependency('boost', include_type: 'system') +thread_dep = dependency('threads') + +serd_dep = dependency( + 'serd-0', + include_type: 'system', + version: '>= 0.30.4', +) + +sord_dep = dependency( + 'sord-0', + include_type: 'system', + version: '>= 0.16.15', +) + +sratom_dep = dependency( + 'sratom-0', + include_type: 'system', + version: '>= 0.6.0', +) + +suil_dep = dependency( + 'suil-0', + include_type: 'system', + version: '>= 0.10.0', +) + +lv2_dep = dependency( + 'lv2', + include_type: 'system', + version: '>= 1.18.0', +) + +lilv_dep = dependency( + 'lilv-0', + include_type: 'system', + version: '>= 0.24.21', +) + +raul_dep = dependency( + 'raul-2', + include_type: 'system', + version: '>= 2.0.0', +) + +####################### +# Driver Dependencies # +####################### + +portaudio_dep = dependency( + 'portaudio-2.0', + include_type: 'system', + required: get_option('portaudio'), + version: '>= 2.0.0', +) + +jack_dep = dependency( + 'jack', + include_type: 'system', + required: get_option('jack'), + version: '>= 0.120.0', +) + +jack_port_rename_code = '''#include <jack/jack.h> +int main(void) { return !!&jack_port_rename; }''' + +platform_defines += '-DHAVE_JACK_PORT_RENAME=@0@'.format( + cpp.compiles( + jack_port_rename_code, + args: platform_defines, + dependencies: [jack_dep], + name: 'jack_port_rename', + ).to_int(), +) + +############# +# Libraries # +############# + +# Set appropriate arguments for building against the library type +if get_option('default_library') == 'static' + add_project_arguments(['-DINGEN_STATIC'], language: ['cpp']) +endif + +subdir('src') + +######################## +# Programs and Scripts # +######################## + +executable( + 'ingen', + files('src/ingen/ingen.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_dep, raul_dep, serd_dep], + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, +) + +install_man(files('doc/ingen.1')) + +subdir('scripts') + +######## +# Data # +######## + +install_data( + files('src/ingen/ingen.desktop'), + install_dir: get_option('datadir') / 'applications', +) + +subdir('bundles') +subdir('icons') + +######### +# Tests # +######### + +subdir('tests') + +if not meson.is_subproject() + summary('Install prefix', get_option('prefix')) + + summary('Data', ingen_data_dir) + summary('Executables', get_option('prefix') / get_option('bindir')) + summary('LV2 bundles', lv2dir) + summary('Man pages', get_option('prefix') / get_option('mandir')) + summary('Modules', ingen_module_dir) +endif diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000..a838a29c --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,29 @@ +# Copyright 2020-2023 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +option('bindings_py', type: 'feature', yield: true, + description: 'Build Python bindings') + +option('checks', type: 'boolean', value: true, yield: true, + description: 'Check for features with the build system') + +option('docs', type: 'feature', yield: true, + description: 'Build documentation') + +option('gui', type: 'feature', yield: true, + description: 'Build GUI') + +option('jack', type: 'feature', yield: true, + description: 'Build JACK audio and MIDI support') + +option('lint', type: 'boolean', value: false, yield: true, + description: 'Run code quality checks') + +option('lv2dir', type: 'string', value: '', yield: true, + description: 'LV2 bundle installation directory') + +option('portaudio', type: 'feature', yield: true, + description: 'Build PortAudio driver') + +option('title', type: 'string', value: 'Ingen', + description: 'Project title') diff --git a/scripts/meson.build b/scripts/meson.build new file mode 100644 index 00000000..bd352b08 --- /dev/null +++ b/scripts/meson.build @@ -0,0 +1,22 @@ +# Copyright 2020-2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +scripts = files( + 'ingenams', + 'ingenish', +) + +foreach script : scripts + install_data( + script, + install_dir: get_option('bindir'), + install_mode: 'rwxr-xr-x', + ) +endforeach + +pymod = import('python') +py = pymod.find_installation('python3', required: get_option('bindings_py')) + +if py.found() + py.install_sources(files('ingen.py')) +endif diff --git a/src/.clang-tidy b/src/.clang-tidy new file mode 100644 index 00000000..83a09b52 --- /dev/null +++ b/src/.clang-tidy @@ -0,0 +1,32 @@ +Checks: > + -*-avoid-c-arrays, + -*-macro-to-enum, + -*-vararg, + -android-cloexec-*, + -boost-use-ranges, + -bugprone-easily-swappable-parameters, + -bugprone-multi-level-implicit-pointer-conversion, + -bugprone-unchecked-optional-access, + -cert-dcl50-cpp, + -cert-err33-c, + -cert-err34-c, + -clang-analyzer-optin.core.EnumCastOutOfRange, + -clang-analyzer-optin.cplusplus.VirtualCall, + -clang-analyzer-valist.Uninitialized, + -concurrency-mt-unsafe, + -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-no-malloc, + -cppcoreguidelines-owning-memory, + -cppcoreguidelines-pro-bounds-array-to-pointer-decay, + -cppcoreguidelines-pro-bounds-pointer-arithmetic, + -cppcoreguidelines-pro-type-const-cast, + -cppcoreguidelines-pro-type-reinterpret-cast, + -cppcoreguidelines-pro-type-union-access, + -fuchsia-statically-constructed-objects, + -hicpp-no-array-decay, + -hicpp-no-malloc, + -misc-no-recursion, + -misc-unused-parameters, + -readability-function-cognitive-complexity, + -readability-static-accessed-through-instance, +InheritParentConfig: true diff --git a/src/AtomForge.cpp b/src/AtomForge.cpp new file mode 100644 index 00000000..727bd64e --- /dev/null +++ b/src/AtomForge.cpp @@ -0,0 +1,130 @@ +/* + This file is part of Ingen. + Copyright 2007-2024 David Robillard <http://drobilla.net/> + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <ingen/AtomForge.hpp> +#include <ingen/memory.hpp> + +#include <lv2/atom/atom.h> +#include <lv2/atom/forge.h> +#include <lv2/atom/util.h> +#include <lv2/urid/urid.h> +#include <sord/sord.h> +#include <sord/sordmm.hpp> +#include <sratom/sratom.h> + +#include <cassert> +#include <cstring> +#include <utility> + +namespace ingen { + +AtomForge::AtomForge(LV2_URID_Map& map) + : LV2_Atom_Forge{} + , _sratom{sratom_new(&map)} + , _buf{static_cast<LV2_Atom*>(calloc(8, sizeof(LV2_Atom)))} +{ + lv2_atom_forge_init(this, &map); + lv2_atom_forge_set_sink(this, c_append, c_deref, this); +} + +void +AtomForge::read(Sord::World& world, + SordModel* const model, + const SordNode* const node) +{ + sratom_read(_sratom.get(), this, world.c_obj(), model, node); +} + +const LV2_Atom* +AtomForge::atom() const +{ + return _buf.get(); +} + +void +AtomForge::clear() +{ + lv2_atom_forge_set_sink(this, c_append, c_deref, this); + _size = 0; + *_buf = {0U, 0U}; +} + +Sratom& +AtomForge::sratom() +{ + return *_sratom; +} + +intptr_t +AtomForge::append(const void* const data, const uint32_t len) +{ + // Record offset of the start of this write (+1 to avoid null) + const auto ref = static_cast<intptr_t>(_size + 1U); + + // Update size and reallocate if necessary + if (lv2_atom_pad_size(_size + len) > _capacity) { + const size_t new_size = lv2_atom_pad_size(_size + len); + + // Release buffer and try to realloc it + auto* const old = _buf.release(); + auto* const new_buf = static_cast<LV2_Atom*>(realloc(old, new_size)); + if (!new_buf) { + // Failure, reclaim old buffer and signal error to caller + _buf = AtomPtr{old, FreeDeleter<LV2_Atom>{}}; + return 0; + } + + // Adopt new buffer and update capacity to make room for the new data + std::unique_ptr<LV2_Atom, FreeDeleter<LV2_Atom>> ptr{new_buf}; + _capacity = new_size; + _buf = std::move(ptr); + } + + // Append new data + memcpy(reinterpret_cast<uint8_t*>(_buf.get()) + _size, data, len); + _size += len; + return ref; +} + +LV2_Atom* +AtomForge::deref(const intptr_t ref) +{ + /* Make some assumptions and do unnecessary math to appease + -Wcast-align. This is questionable at best, though the forge should + only dereference references to aligned atoms. */ + LV2_Atom* const ptr = _buf.get(); + assert((ref - 1) % sizeof(LV2_Atom) == 0); + return static_cast<LV2_Atom*>(ptr + ((ref - 1) / sizeof(LV2_Atom))); + + // Alternatively: + // return (LV2_Atom*)((uint8_t*)_buf.get() + ref - 1); +} + +LV2_Atom_Forge_Ref +AtomForge::c_append(void* const self, + const void* const data, + const uint32_t len) +{ + return static_cast<AtomForge*>(self)->append(data, len); +} + +LV2_Atom* +AtomForge::c_deref(void* const self, const LV2_Atom_Forge_Ref ref) +{ + return static_cast<AtomForge*>(self)->deref(ref); +} + +} // namespace ingen diff --git a/src/AtomReader.cpp b/src/AtomReader.cpp index 74476b83..21cb9e40 100644 --- a/src/AtomReader.cpp +++ b/src/AtomReader.cpp @@ -14,30 +14,31 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Atom.hpp" -#include "ingen/AtomReader.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/Message.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/Status.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" -#include "ingen/paths.hpp" -#include "lv2/atom/atom.h" -#include "lv2/atom/util.h" -#include "raul/Path.hpp" - -#include <boost/optional/optional.hpp> +#include <ingen/AtomReader.hpp> + +#include <ingen/Atom.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Message.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/paths.hpp> +#include <lv2/atom/atom.h> +#include <lv2/atom/util.h> +#include <raul/Path.hpp> #include <cstdint> #include <cstring> +#include <optional> #include <string> namespace ingen { +enum class Status; + AtomReader::AtomReader(URIMap& map, URIs& uris, Log& log, Interface& iface) : _map(map) , _uris(uris) @@ -71,52 +72,57 @@ AtomReader::get_props(const LV2_Atom_Object* obj, const Atom type(sizeof(int32_t), _uris.atom_URID, &obj->body.otype); props.emplace(_uris.rdf_type, type); } - LV2_ATOM_OBJECT_FOREACH(obj, p) { + LV2_ATOM_OBJECT_FOREACH (obj, p) { Atom val; get_atom(&p->value, val); props.emplace(URI(_map.unmap_uri(p->key)), val); } } -boost::optional<URI> +std::optional<URI> AtomReader::atom_to_uri(const LV2_Atom* atom) { if (!atom) { - return boost::optional<URI>(); - } else if (atom->type == _uris.atom_URI) { + return {}; + } + + if (atom->type == _uris.atom_URI) { const char* str = static_cast<const char*>(LV2_ATOM_BODY_CONST(atom)); if (URI::is_valid(str)) { return URI(str); - } else { - _log.warn("Invalid URI <%1%>\n", str); } + + _log.warn("Invalid URI <%1%>\n", str); } else if (atom->type == _uris.atom_Path) { const char* str = static_cast<const char*>(LV2_ATOM_BODY_CONST(atom)); if (!strncmp(str, "file://", 5)) { return URI(str); - } else { - return URI(std::string("file://") + str); } - } else if (atom->type == _uris.atom_URID) { + + return URI(std::string("file://") + str); + } + + if (atom->type == _uris.atom_URID) { const char* str = _map.unmap_uri(reinterpret_cast<const LV2_Atom_URID*>(atom)->body); if (str) { return URI(str); - } else { - _log.warn("Unknown URID %1%\n", str); } + + _log.warn("Unknown URID %1%\n", str); } - return boost::optional<URI>(); + + return {}; } -boost::optional<raul::Path> +std::optional<raul::Path> AtomReader::atom_to_path(const LV2_Atom* atom) { - boost::optional<URI> uri = atom_to_uri(atom); + std::optional<URI> uri = atom_to_uri(atom); if (uri && uri_is_path(*uri)) { return uri_to_path(*uri); } - return boost::optional<raul::Path>(); + return {}; } Resource::Graph @@ -124,7 +130,7 @@ AtomReader::atom_to_context(const LV2_Atom* atom) { Resource::Graph ctx = Resource::Graph::DEFAULT; if (atom) { - boost::optional<URI> maybe_uri = atom_to_uri(atom); + std::optional<URI> maybe_uri = atom_to_uri(atom); if (maybe_uri) { ctx = Resource::uri_to_graph(*maybe_uri); } else { @@ -168,7 +174,7 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id) _uris.patch_sequenceNumber.urid(), &number, nullptr); - const boost::optional<URI> subject_uri = atom_to_uri(subject); + const std::optional<URI> subject_uri = atom_to_uri(subject); const int32_t seq = ((number && number->type == _uris.atom_Int) ? reinterpret_cast<const LV2_Atom_Int*>(number)->body @@ -195,7 +201,9 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id) if (subject_uri && !body) { _iface(Del{seq, *subject_uri}); return true; - } else if (body && body->body.otype == _uris.ingen_Arc) { + } + + if (body && body->body.otype == _uris.ingen_Arc) { const LV2_Atom* tail = nullptr; const LV2_Atom* head = nullptr; const LV2_Atom* incidentTo = nullptr; @@ -205,10 +213,10 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id) _uris.ingen_incidentTo.urid(), &incidentTo, nullptr); - boost::optional<raul::Path> subject_path(atom_to_path(subject)); - boost::optional<raul::Path> tail_path(atom_to_path(tail)); - boost::optional<raul::Path> head_path(atom_to_path(head)); - boost::optional<raul::Path> other_path(atom_to_path(incidentTo)); + std::optional<raul::Path> subject_path(atom_to_path(subject)); + std::optional<raul::Path> tail_path(atom_to_path(tail)); + std::optional<raul::Path> head_path(atom_to_path(head)); + std::optional<raul::Path> other_path(atom_to_path(incidentTo)); if (tail_path && head_path) { _iface(Disconnect{seq, *tail_path, *head_path}); } else if (subject_path && other_path) { @@ -228,7 +236,9 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id) if (!body) { _log.warn("Put message has no body\n"); return false; - } else if (!subject_uri) { + } + + if (!subject_uri) { _log.warn("Put message has no subject\n"); return false; } @@ -245,8 +255,8 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id) return false; } - boost::optional<raul::Path> tail_path(atom_to_path(tail)); - boost::optional<raul::Path> head_path(atom_to_path(head)); + std::optional<raul::Path> tail_path(atom_to_path(tail)); + std::optional<raul::Path> head_path(atom_to_path(head)); if (tail_path && head_path) { _iface(Connect{seq, *tail_path, *head_path}); } else { @@ -275,7 +285,9 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id) reinterpret_cast<const LV2_Atom*>(prop)->type != _uris.atom_URID) { _log.warn("Set message missing property\n"); return false; - } else if (!value) { + } + + if (!value) { _log.warn("Set message missing value\n"); return false; } @@ -304,7 +316,9 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id) if (!remove) { _log.warn("Patch message has no remove\n"); return false; - } else if (!add) { + } + + if (!add) { _log.warn("Patch message has no add\n"); return false; } @@ -336,7 +350,7 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id) } - boost::optional<URI> dest_uri(atom_to_uri(dest)); + std::optional<URI> dest_uri(atom_to_uri(dest)); if (!dest_uri) { _log.warn("Copy message has non-URI destination\n"); return false; @@ -356,13 +370,13 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id) return false; } - boost::optional<raul::Path> subject_path(atom_to_path(subject)); + std::optional<raul::Path> subject_path(atom_to_path(subject)); if (!subject_path) { _log.warn("Move message has non-path subject\n"); return false; } - boost::optional<raul::Path> dest_path(atom_to_path(dest)); + std::optional<raul::Path> dest_path(atom_to_path(dest)); if (!dest_path) { _log.warn("Move message has non-path destination\n"); return false; @@ -377,10 +391,13 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id) if (!number || number->type != _uris.atom_Int) { _log.warn("Response message has no sequence number\n"); return false; - } else if (!body || body->type != _uris.atom_Int) { + } + + if (!body || body->type != _uris.atom_Int) { _log.warn("Response message body is not integer\n"); return false; } + _iface(Response{reinterpret_cast<const LV2_Atom_Int*>(number)->body, static_cast<ingen::Status>( reinterpret_cast<const LV2_Atom_Int*>(body)->body), diff --git a/src/AtomWriter.cpp b/src/AtomWriter.cpp index 6b60a3a5..5200cfde 100644 --- a/src/AtomWriter.cpp +++ b/src/AtomWriter.cpp @@ -47,30 +47,29 @@ * manipulating data in this model which resemble HTTP methods. */ -#include "ingen/AtomWriter.hpp" - -#include "ingen/Atom.hpp" -#include "ingen/AtomForge.hpp" -#include "ingen/AtomSink.hpp" -#include "ingen/Message.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" -#include "ingen/paths.hpp" -#include "lv2/atom/forge.h" -#include "lv2/urid/urid.h" -#include "raul/Path.hpp" -#include "serd/serd.h" - -#include <boost/variant/apply_visitor.hpp> +#include <ingen/AtomWriter.hpp> + +#include <ingen/Atom.hpp> +#include <ingen/AtomForge.hpp> +#include <ingen/AtomSink.hpp> +#include <ingen/Message.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/paths.hpp> +#include <lv2/atom/forge.h> +#include <lv2/urid/urid.h> +#include <raul/Path.hpp> +#include <serd/serd.h> #include <cassert> #include <cstdint> #include <map> #include <string> #include <utility> +#include <variant> namespace ingen { @@ -79,8 +78,7 @@ AtomWriter::AtomWriter(URIMap& map, URIs& uris, AtomSink& sink) , _uris(uris) , _sink(sink) , _forge(map.urid_map()) -{ -} +{} void AtomWriter::finish_msg() @@ -93,7 +91,7 @@ AtomWriter::finish_msg() void AtomWriter::message(const Message& message) { - boost::apply_visitor(*this, message); + std::visit(*this, message); } /** @page protocol @@ -296,8 +294,8 @@ AtomWriter::operator()(const Delta& message) * Send a [Copy](http://lv2plug.in/ns/ext/copy#Copy) to copy an object from * its current location (subject) to another (destination). * - * If both the subject and destination are inside Ingen, like block paths, then the old object - * is copied by, for example, creating a new plugin instance. + * If both the subject and destination are inside Ingen, like block paths, then + * the old object is copied by, for example, creating a new plugin instance. * * If the subject is a filename (file URI or atom:Path) and the destination is * inside Ingen, then the subject must be an Ingen graph file or bundle, which @@ -437,7 +435,8 @@ AtomWriter::operator()(const Undo& message) /** @page protocol * @subsection Undo * - * Use [ingen:Redo](http://drobilla.net/ns/ingen#Redo) to redo the last undone change. + * Use [ingen:Redo](http://drobilla.net/ns/ingen#Redo) to redo the last undone + * change. * * @code{.ttl} * [] a ingen:Redo . @@ -630,8 +629,7 @@ AtomWriter::operator()(const Response& response) void AtomWriter::operator()(const Error&) -{ -} +{} /** @page protocol * @section loading Loading and Unloading Bundles diff --git a/src/ClashAvoider.cpp b/src/ClashAvoider.cpp index ece002f8..ed4dc91a 100644 --- a/src/ClashAvoider.cpp +++ b/src/ClashAvoider.cpp @@ -14,19 +14,18 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/ClashAvoider.hpp" -#include "ingen/Store.hpp" -#include "ingen/URI.hpp" -#include "ingen/paths.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" - -#include <boost/optional/optional.hpp> +#include <ingen/ClashAvoider.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <cassert> #include <cctype> #include <cstdio> #include <cstdlib> +#include <optional> #include <sstream> #include <string> #include <utility> @@ -42,9 +41,9 @@ ClashAvoider::map_uri(const URI& in) { if (uri_is_path(in)) { return path_to_uri(map_path(uri_to_path(in))); - } else { - return in; } + + return in; } raul::Path @@ -63,7 +62,7 @@ ClashAvoider::map_path(const raul::Path& in) // Path without _n suffix std::string base_path_str = in; if (has_offset) { - base_path_str = base_path_str.substr(0, base_path_str.find_last_of('_')); + base_path_str.resize(base_path_str.find_last_of('_')); } raul::Path base_path(base_path_str); @@ -71,67 +70,62 @@ ClashAvoider::map_path(const raul::Path& in) auto m = _symbol_map.find(in); if (m != _symbol_map.end()) { return m->second; - } else { - using InsertRecord = std::pair<SymbolMap::iterator, bool>; - - // See if parent is mapped - raul::Path parent = in.parent(); - do { - auto p = _symbol_map.find(parent); - if (p != _symbol_map.end()) { - const raul::Path mapped = raul::Path( - p->second.base() + in.substr(parent.base().length())); - InsertRecord i = _symbol_map.emplace(in, mapped); - return i.first->second; + } + + // See if parent is mapped + raul::Path parent = in.parent(); + do { + auto p = _symbol_map.find(parent); + if (p != _symbol_map.end()) { + const auto mapped = raul::Path{p->second.base() + + in.substr(parent.base().length())}; + + auto i = _symbol_map.emplace(in, mapped); + return i.first->second; + } + parent = parent.parent(); + } while (!parent.is_root()); + + if (!exists(in) && _symbol_map.find(in) == _symbol_map.end()) { + // No clash, use symbol unmodified + auto i = _symbol_map.emplace(in, in); + assert(i.second); + return i.first->second; + } + + // Append _2 _3 etc until an unused symbol is found + while (true) { + auto o = _offsets.find(base_path); + if (o != _offsets.end()) { + offset = ++o->second; + } + + if (offset == 0) { + offset = 2; + } + + std::stringstream ss; + ss << base_path << "_" << offset; + if (!exists(raul::Path(ss.str()))) { + std::string name = base_path.symbol(); + if (name.empty()) { + name = "_"; } - parent = parent.parent(); - } while (!parent.is_root()); - if (!exists(in) && _symbol_map.find(in) == _symbol_map.end()) { - // No clash, use symbol unmodified - InsertRecord i = _symbol_map.emplace(in, in); - assert(i.second); + const raul::Symbol sym{name}; + const std::string str{ss.str()}; + + auto i = _symbol_map.emplace(in, raul::Path(str)); + + offset = _store.child_name_offset(in.parent(), sym, false); + _offsets.emplace(base_path, offset); return i.first->second; + } + if (o != _offsets.end()) { + offset = ++o->second; } else { - // Append _2 _3 etc until an unused symbol is found - while (true) { - auto o = _offsets.find(base_path); - if (o != _offsets.end()) { - offset = ++o->second; - } else { - std::string parent_str = in.parent().base(); - parent_str = parent_str.substr(0, parent_str.find_last_of('/')); - if (parent_str.empty()) { - parent_str = "/"; - } - } - - if (offset == 0) { - offset = 2; - } - - std::stringstream ss; - ss << base_path << "_" << offset; - if (!exists(raul::Path(ss.str()))) { - std::string name = base_path.symbol(); - if (name.empty()) { - name = "_"; - } - raul::Symbol sym(name); - std::string str = ss.str(); - InsertRecord i = _symbol_map.emplace(in, raul::Path(str)); - offset = _store.child_name_offset(in.parent(), sym, false); - _offsets.emplace(base_path, offset); - return i.first->second; - } else { - if (o != _offsets.end()) { - offset = ++o->second; - } else { - ++offset; - } - } - } + ++offset; } } } @@ -142,7 +136,7 @@ ClashAvoider::exists(const raul::Path& path) const return _store.find(path) != _store.end(); } -static boost::optional<size_t> +static std::optional<size_t> numeric_suffix_start(const std::string& str) { if (!isdigit(str[str.length() - 1])) { @@ -158,13 +152,13 @@ numeric_suffix_start(const std::string& str) } std::string -ClashAvoider::adjust_name(const raul::Path& old_path, - const raul::Path& new_path, - std::string name) +ClashAvoider::adjust_name(const raul::Path& old_path, + const raul::Path& new_path, + const std::string& name) { const auto name_suffix_start = numeric_suffix_start(name); if (!name_suffix_start) { - return name; // No numeric suffix, just re-use old label + return name; // No numeric suffix, just reuse old label } const auto name_suffix = atoi(name.c_str() + *name_suffix_start); @@ -177,11 +171,11 @@ ClashAvoider::adjust_name(const raul::Path& old_path, const auto offset = new_suffix - old_suffix; return (name.substr(0, *name_suffix_start) + std::to_string(name_suffix + offset)); - } else { - // Add 1 to previous label suffix - return (name.substr(0, *name_suffix_start) + - std::to_string(name_suffix + 1)); } + + // Add 1 to previous label suffix + return (name.substr(0, *name_suffix_start) + + std::to_string(name_suffix + 1)); } } // namespace ingen diff --git a/src/ColorContext.cpp b/src/ColorContext.cpp index ac797518..9706cb81 100644 --- a/src/ColorContext.cpp +++ b/src/ColorContext.cpp @@ -14,10 +14,11 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/ColorContext.hpp" +#include <ingen/ColorContext.hpp> + #include "ingen_config.h" -#ifdef HAVE_ISATTY +#if USE_ISATTY # include <unistd.h> #else inline int isatty(int fd) { return 0; } @@ -41,4 +42,4 @@ ColorContext::~ColorContext() } } -} // namespace ingen +} // namespace ingen diff --git a/src/Configuration.cpp b/src/Configuration.cpp index 5b5d75bd..9abdc288 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -14,26 +14,34 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Configuration.hpp" -#include "ingen/Forge.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/filesystem.hpp" -#include "ingen/fmt.hpp" -#include "ingen/ingen.h" -#include "ingen/runtime_paths.hpp" -#include "lv2/urid/urid.h" -#include "serd/serd.h" -#include "sord/sord.h" -#include "sord/sordmm.hpp" -#include "sratom/sratom.h" +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/FilePath.hpp> +#include <ingen/Forge.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/fmt.hpp> +#include <ingen/ingen.h> +#include <ingen/runtime_paths.hpp> +#include <lv2/urid/urid.h> +#include <serd/serd.h> +#include <sord/sord.h> +#include <sord/sordmm.hpp> +#include <sratom/sratom.h> #include <algorithm> #include <cassert> #include <cerrno> #include <cstdint> +#include <cstdio> #include <cstdlib> #include <cstring> +#include <filesystem> +#include <list> +#include <map> #include <memory> +#include <ostream> +#include <string> +#include <system_error> #include <thread> #include <utility> #include <vector> @@ -54,8 +62,9 @@ Configuration::Configuration(Forge& forge) " ingen -g # Run GUI, connect to running engine\n" " ingen -eg # Run engine and GUI in one process\n" " ingen -eg foo.ingen # Run engine and GUI and load a graph") - , _max_name_length(0) { + static const auto default_n_threads = static_cast<int32_t>(std::max(std::thread::hardware_concurrency(), 1U)); + add("atomicBundles", "atomic-bundles", 'a', "Execute bundles atomically", GLOBAL, forge.Bool, forge.make(false)); add("bufferSize", "buffer-size", 'b', "Buffer size in samples", GLOBAL, forge.Int, forge.make(1024)); add("clientPort", "client-port", 'C', "Client port", GLOBAL, forge.Int, Atom()); @@ -78,7 +87,7 @@ Configuration::Configuration(Forge& forge) add("flushLog", "flush-log", 'f', "Flush logs after every entry", GLOBAL, forge.Bool, forge.make(false)); add("dump", "dump", 'd', "Print debug output", SESSION, forge.Bool, forge.make(false)); add("trace", "trace", 't', "Show LV2 plugin trace messages", SESSION, forge.Bool, forge.make(false)); - add("threads", "threads", 'p', "Number of processing threads", GLOBAL, forge.Int, forge.make(int32_t(std::max(std::thread::hardware_concurrency(), 1U)))); + add("threads", "threads", 'p', "Number of processing threads", GLOBAL, forge.Int, forge.make(default_n_threads)); add("humanNames", "human-names", 0, "Show human names in GUI", GUI, forge.Bool, forge.make(true)); add("portLabels", "port-labels", 0, "Show port labels in GUI", GUI, forge.Bool, forge.make(true)); add("graphDirectory", "graph-directory", 0, "Default directory for opening graphs", GUI, forge.String, Atom()); @@ -110,19 +119,22 @@ Configuration::variable_string(LV2_URID type) const { if (type == _forge.String) { return "=STRING"; - } else if (type == _forge.Int) { + } + + if (type == _forge.Int) { return "=INT"; } + return ""; } void Configuration::print_usage(const std::string& program, std::ostream& os) { - os << "Usage: " << program << " [OPTION]... [GRAPH]" << std::endl; - os << _shortdesc << std::endl << std::endl; - os << _desc << std::endl << std::endl; - os << "Options:" << std::endl; + os << "Usage: " << program << " [OPTION]... [GRAPH]\n"; + os << _shortdesc << "\n\n"; + os << _desc << "\n\n"; + os << "Options:\n"; for (const auto& o : _options) { const Option& option = o.second; os << " "; @@ -131,10 +143,10 @@ Configuration::print_usage(const std::string& program, std::ostream& os) } else { os << " "; } - os.width(_max_name_length + 11); + os.width(static_cast<std::streamsize>(_max_name_length + 11)); os << std::left; os << (std::string("--") + o.first + variable_string(option.type)); - os << option.desc << std::endl; + os << option.desc << "\n"; } } @@ -143,8 +155,8 @@ Configuration::set_value_from_string(Configuration::Option& option, const std::string& value) { if (option.type == _forge.Int) { - char* endptr = nullptr; - int intval = static_cast<int>(strtol(value.c_str(), &endptr, 10)); + char* endptr = nullptr; + const int intval = static_cast<int>(strtol(value.c_str(), &endptr, 10)); if (endptr && *endptr == '\0') { option.value = _forge.make(intval); } else { @@ -155,7 +167,7 @@ Configuration::set_value_from_string(Configuration::Option& option, option.value = _forge.alloc(value.c_str()); assert(option.value.type() == _forge.String); } else if (option.type == _forge.Bool) { - option.value = _forge.make(bool(!strcmp(value.c_str(), "true"))); + option.value = _forge.make(!strcmp(value.c_str(), "true")); assert(option.value.type() == _forge.Bool); } else { throw OptionError(fmt("Bad option type `%1%'", option.name)); @@ -170,7 +182,7 @@ Configuration::parse(int argc, char** argv) for (int i = 1; i < argc; ++i) { if (argv[i][0] != '-' || !strcmp(argv[i], "-")) { // File argument - const Options::iterator o = _options.find("load"); + const auto o = _options.find("load"); if (!o->second.value.is_valid()) { _options.find("load")->second.value = _forge.alloc(argv[i]); } else { @@ -181,17 +193,19 @@ Configuration::parse(int argc, char** argv) std::string name = std::string(argv[i]).substr(2); const char* equals = strchr(argv[i], '='); if (equals) { - name = name.substr(0, name.find('=')); + name.resize(name.find('=')); } - const Options::iterator o = _options.find(name); + const auto o = _options.find(name); if (o == _options.end()) { throw OptionError(fmt("Unrecognized option `%1%'", name)); - } else if (o->second.type == _forge.Bool) { // --flag + } + + if (o->second.type == _forge.Bool) { // --flag o->second.value = _forge.make(true); - } else if (equals) { // --opt=val + } else if (equals) { // --opt=val set_value_from_string(o->second, equals + 1); - } else if (++i < argc) { // --opt val + } else if (++i < argc) { // --opt val set_value_from_string(o->second, argv[i]); } else { throw OptionError(fmt("Missing value for `%1%'", name)); @@ -200,22 +214,22 @@ Configuration::parse(int argc, char** argv) // Short option const size_t len = strlen(argv[i]); for (size_t j = 1; j < len; ++j) { - const char letter = argv[i][j]; - const ShortNames::iterator n = _short_names.find(letter); + const char letter = argv[i][j]; + const auto n = _short_names.find(letter); if (n == _short_names.end()) { throw OptionError(fmt("Unrecognized option `%1%'", letter)); } - const Options::iterator o = _options.find(n->second); - if (j < len - 1) { // Non-final POSIX style flag + const auto o = _options.find(n->second); + if (j < len - 1) { // Non-final POSIX style flag if (o->second.type != _forge.Bool) { throw OptionError( fmt("Missing value for `%1%'", letter)); } o->second.value = _forge.make(true); - } else if (o->second.type == _forge.Bool) { // -f + } else if (o->second.type == _forge.Bool) { // -f o->second.value = _forge.make(true); - } else if (++i < argc) { // -v val + } else if (++i < argc) { // -v val set_value_from_string(o->second, argv[i]); } else { throw OptionError(fmt("Missing value for `%1%'", letter)); @@ -228,7 +242,7 @@ Configuration::parse(int argc, char** argv) bool Configuration::load(const FilePath& path) { - if (!filesystem::exists(path)) { + if (!std::filesystem::exists(path)) { return false; } @@ -242,14 +256,17 @@ Configuration::load(const FilePath& path) SerdEnv* env = serd_env_new(&node); model.load_file(env, SERD_TURTLE, uri, uri); - Sord::Node nodemm(world, Sord::Node::URI, reinterpret_cast<const char*>(node.buf)); - Sord::Node nil; - for (Sord::Iter i = model.find(nodemm, nil, nil); !i.end(); ++i) { - const Sord::Node& pred = i.get_predicate(); - const Sord::Node& obj = i.get_object(); + const Sord::Node nodemm{world, + Sord::Node::URI, + reinterpret_cast<const char*>(node.buf)}; + + const Sord::Node nil; + for (auto i = model.find(nodemm, nil, nil); !i.end(); ++i) { + const auto& pred = i.get_predicate(); + const auto& obj = i.get_object(); if (pred.to_string().substr(0, sizeof(INGEN_NS) - 1) == INGEN_NS) { const std::string key = pred.to_string().substr(sizeof(INGEN_NS) - 1); - const Keys::iterator k = _keys.find(key); + const auto k = _keys.find(key); if (k != _keys.end() && obj.type() == Sord::Node::LITERAL) { set_value_from_string(_options.find(k->second)->second, obj.to_string()); @@ -275,15 +292,17 @@ Configuration::save(URIMap& uri_map, } // Create parent directories if necessary - const FilePath dir = path.parent_path(); - if (!filesystem::create_directories(dir)) { + const FilePath dir = path.parent_path(); + std::error_code ec; + std::filesystem::create_directories(dir, ec); + if (ec) { throw FileError(fmt("Error creating directory %1% (%2%)", dir, strerror(errno))); } // Attempt to open file for writing - std::unique_ptr<FILE, decltype(&fclose)> file{fopen(path.c_str(), "w"), - &fclose}; + const std::unique_ptr<FILE, int (*)(FILE*)> file{ + fopen(path.c_str(), "w"), &fclose}; if (!file) { throw FileError(fmt("Failed to open file %1% (%2%)", path, strerror(errno))); @@ -338,7 +357,7 @@ Configuration::save(URIMap& uri_map, } const std::string key(std::string("ingen:") + o.second.key); - SerdNode pred = serd_node_from_string( + const SerdNode pred = serd_node_from_string( SERD_CURIE, reinterpret_cast<const uint8_t*>(key.c_str())); sratom_write(sratom, &uri_map.urid_unmap(), 0, &base, &pred, value.type(), value.size(), value.get_body()); @@ -380,9 +399,9 @@ Configuration::option(const std::string& long_name) const auto o = _options.find(long_name); if (o == _options.end()) { return nil; - } else { - return o->second.value; } + + return o->second.value; } bool diff --git a/src/FilePath.cpp b/src/FilePath.cpp deleted file mode 100644 index d16c133c..00000000 --- a/src/FilePath.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2018 David Robillard <http://drobilla.net/> - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "ingen/FilePath.hpp" - -#include <algorithm> -#include <string> -#include <utility> - -namespace ingen { - -template <typename Char> -static bool -is_sep(const Char chr) -{ -#ifdef USE_WINDOWS_FILE_PATHS - return chr == L'/' || chr == preferred_separator; -#else - return chr == '/'; -#endif -} - -FilePath& -FilePath::operator=(FilePath&& path) noexcept -{ - _str = std::move(path._str); - path.clear(); - return *this; -} - -FilePath& -FilePath::operator=(string_type&& str) -{ - _str = std::move(str); - return *this; -} - -FilePath& -FilePath::operator/=(const FilePath& path) -{ - const FilePath::string_type& str = path.string(); - if (!_str.empty() && !is_sep(_str.back()) && !str.empty() && - !is_sep(str.front())) { - _str += preferred_separator; - } - - _str += str; - return *this; -} - -FilePath& -FilePath::operator+=(const FilePath& path) -{ - return operator+=(path.native()); -} - -FilePath& -FilePath::operator+=(const string_type& str) -{ - _str += str; - return *this; -} - -FilePath& -FilePath::operator+=(const value_type* str) -{ - _str += str; - return *this; -} - -FilePath& -FilePath::operator+=(value_type chr) -{ - _str += chr; - return *this; -} - -FilePath& -FilePath::operator+=(boost::basic_string_view<value_type> sv) -{ - _str.append(sv.data(), sv.size()); - return *this; -} - -FilePath -FilePath::root_name() -{ -#ifdef USE_WINDOWS_FILE_PATHS - if (_str.length() >= 2 && _str[0] >= 'A' && _str[0] <= 'Z' && - _str[1] == ':') { - return FilePath(_str.substr(0, 2)); - } -#endif - - return FilePath(); -} - -FilePath -FilePath::root_directory() const -{ -#ifdef USE_WINDOWS_FILE_PATHS - const auto name = root_name().string(); - return name.empty() ? Path() : Path(name + preferred_separator); -#endif - - return _str[0] == '/' ? FilePath("/") : FilePath(); -} - -FilePath -FilePath::root_path() const -{ -#ifdef USE_WINDOWS_FILE_PATHS - const auto name = root_name(); - return name.empty() ? FilePath() : name / root_directory(); -#endif - return root_directory(); -} - -FilePath -FilePath::relative_path() const -{ - const auto root = root_path(); - return root.empty() ? FilePath() - : FilePath(_str.substr(root.string().length())); -} - -FilePath -FilePath::parent_path() const -{ - if (empty() || *this == root_path()) { - return *this; - } - - const auto first_sep = find_first_sep(); - const auto last_sep = find_last_sep(); - return ((last_sep == std::string::npos || last_sep == first_sep) - ? root_path() - : FilePath(_str.substr(0, last_sep))); -} - -FilePath -FilePath::filename() const -{ - return ((empty() || *this == root_path()) - ? FilePath() - : FilePath(_str.substr(find_last_sep() + 1))); -} - -FilePath -FilePath::stem() const -{ - const auto name = filename(); - const auto dot = name.string().find('.'); - return ((dot == std::string::npos) ? name - : FilePath(name.string().substr(0, dot))); -} - -FilePath -FilePath::extension() const -{ - const auto name = filename().string(); - const auto dot = name.find('.'); - return ((dot == std::string::npos) ? FilePath() - : FilePath(name.substr(dot, dot))); -} - -bool -FilePath::is_absolute() const -{ -#ifdef USE_WINDOWS_FILE_PATHS - return !root_name().empty(); -#else - return !root_directory().empty(); -#endif -} - -std::size_t -FilePath::find_first_sep() const -{ - const auto i = std::find_if(_str.begin(), _str.end(), is_sep<value_type>); - return i == _str.end() ? std::string::npos : (i - _str.begin()); -} - -std::size_t -FilePath::find_last_sep() const -{ - const auto i = std::find_if(_str.rbegin(), _str.rend(), is_sep<value_type>); - return (i == _str.rend() ? std::string::npos - : (_str.length() - 1 - (i - _str.rbegin()))); -} - -bool -operator==(const FilePath& lhs, const FilePath& rhs) noexcept -{ - return lhs.string() == rhs.string(); -} - -bool -operator!=(const FilePath& lhs, const FilePath& rhs) noexcept -{ - return !(lhs == rhs); -} - -bool -operator<(const FilePath& lhs, const FilePath& rhs) noexcept -{ - return lhs.string().compare(rhs.string()) < 0; -} - -bool -operator<=(const FilePath& lhs, const FilePath& rhs) noexcept -{ - return !(rhs < lhs); -} - -bool -operator>(const FilePath& lhs, const FilePath& rhs) noexcept -{ - return rhs < lhs; -} - -bool -operator>=(const FilePath& lhs, const FilePath& rhs) noexcept -{ - return !(lhs < rhs); -} - -FilePath -operator/(const FilePath& lhs, const FilePath& rhs) -{ - return FilePath(lhs) /= rhs; -} - -} // namespace ingen diff --git a/src/Forge.cpp b/src/Forge.cpp index 6b8f7b14..8b222c64 100644 --- a/src/Forge.cpp +++ b/src/Forge.cpp @@ -14,13 +14,16 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Forge.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIMap.hpp" -#include "lv2/atom/forge.h" -#include "lv2/urid/urid.h" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <lv2/atom/forge.h> +#include <lv2/urid/urid.h> +#include <cstdint> #include <sstream> +#include <string> namespace ingen { @@ -35,7 +38,7 @@ Atom Forge::make_urid(const ingen::URI& u) { const LV2_URID urid = _map.map_uri(u.string()); - return Atom(sizeof(int32_t), URID, &urid); + return {sizeof(int32_t), URID, &urid}; } std::string diff --git a/src/LV2Features.cpp b/src/LV2Features.cpp index ebce8780..c33ba4c4 100644 --- a/src/LV2Features.cpp +++ b/src/LV2Features.cpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2015 David Robillard <http://drobilla.net/> + Copyright 2007-2024 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -14,10 +14,11 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/LV2Features.hpp" +#include <ingen/LV2Features.hpp> -#include "lv2/core/lv2.h" +#include <lv2/core/lv2.h> +#include <algorithm> #include <cstdlib> #include <memory> @@ -37,12 +38,10 @@ LV2Features::add_feature(const std::shared_ptr<Feature>& feature) } LV2Features::FeatureArray::FeatureArray(FeatureVector& features) - : _features(features) + : _features(features) + , _array{static_cast<LV2_Feature**>( + calloc(features.size() + 1, sizeof(LV2_Feature*)))} { - _array = static_cast<LV2_Feature**>( - malloc(sizeof(LV2_Feature*) * (features.size() + 1))); - - _array[features.size()] = nullptr; for (size_t i = 0; i < features.size(); ++i) { _array[i] = features[i].get(); } @@ -60,12 +59,9 @@ LV2Features::is_supported(const std::string& uri) const return true; } - for (const auto& f : _features) { - if (f->uri() == uri) { - return true; - } - } - return false; + return std::any_of(_features.begin(), + _features.end(), + [&uri](const auto& f) { return f->uri() == uri; }); } std::shared_ptr<LV2Features::FeatureArray> @@ -73,7 +69,7 @@ LV2Features::lv2_features(World& world, Node* node) const { FeatureArray::FeatureVector vec; for (const auto& f : _features) { - std::shared_ptr<LV2_Feature> fptr = f->feature(world, node); + const std::shared_ptr<LV2_Feature> fptr = f->feature(world, node); if (fptr) { vec.push_back(fptr); } diff --git a/src/Library.cpp b/src/Library.cpp index a8a7107e..4add6577 100644 --- a/src/Library.cpp +++ b/src/Library.cpp @@ -14,7 +14,8 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Library.hpp" +#include <ingen/FilePath.hpp> +#include <ingen/Library.hpp> #ifdef _WIN32 # include <windows.h> diff --git a/src/Log.cpp b/src/Log.cpp index 55c2193a..fbcaeca1 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2016 David Robillard <http://drobilla.net/> + Copyright 2007-2024 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -14,73 +14,70 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Log.hpp" +#include <ingen/Log.hpp> -#include "ingen/ColorContext.hpp" -#include "ingen/Node.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "lv2/core/lv2.h" -#include "lv2/log/log.h" -#include "lv2/urid/urid.h" -#include "raul/Path.hpp" +#include <ingen/ColorContext.hpp> +#include <ingen/Node.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <lv2/core/lv2.h> +#include <lv2/log/log.h> +#include <lv2/urid/urid.h> +#include <raul/Path.hpp> #include <cstdio> #include <cstdlib> +#include <memory> namespace ingen { Log::Log(LV2_Log_Log* log, URIs& uris) : _log(log) , _uris(uris) - , _flush(false) - , _trace(false) {} void Log::rt_error(const char* msg) { #ifndef NDEBUG - va_list args; - vtprintf(_uris.log_Error, msg, args); + tprintf(_uris.log_Error, msg); #endif } void Log::error(const std::string& msg) { - va_list args; - vtprintf(_uris.log_Error, msg.c_str(), args); + tprintf(_uris.log_Error, msg.c_str()); } void Log::warn(const std::string& msg) { - va_list args; - vtprintf(_uris.log_Warning, msg.c_str(), args); + tprintf(_uris.log_Warning, msg.c_str()); } void Log::info(const std::string& msg) { - va_list args; - vtprintf(_uris.log_Note, msg.c_str(), args); + tprintf(_uris.log_Note, msg.c_str()); } void Log::trace(const std::string& msg) { - va_list args; - vtprintf(_uris.log_Trace, msg.c_str(), args); + tprintf(_uris.log_Trace, msg.c_str()); } -void -Log::print(FILE* stream, const std::string& msg) const +int +Log::tprintf(LV2_URID type, const char* fmt, ...) { - fprintf(stream, "%s", msg.c_str()); - if (_flush) { - fflush(stdout); - } + va_list args; + va_start(args, fmt); + + const int ret = vtprintf(type, fmt, args); + + va_end(args); + return ret; } int @@ -89,23 +86,25 @@ Log::vtprintf(LV2_URID type, const char* fmt, va_list args) int ret = 0; if (type == _uris.log_Trace && !_trace) { return 0; - } else if (_sink) { + } + + if (_sink) { _sink(type, fmt, args); } if (_log) { ret = _log->vprintf(_log->handle, type, fmt, args); } else if (type == _uris.log_Error) { - ColorContext ctx(stderr, ColorContext::Color::RED); + const ColorContext ctx{stderr, ColorContext::Color::RED}; ret = vfprintf(stderr, fmt, args); } else if (type == _uris.log_Warning) { - ColorContext ctx(stderr, ColorContext::Color::YELLOW); + const ColorContext ctx{stderr, ColorContext::Color::YELLOW}; ret = vfprintf(stderr, fmt, args); } else if (type == _uris.log_Note) { - ColorContext ctx(stderr, ColorContext::Color::GREEN); + const ColorContext ctx{stderr, ColorContext::Color::GREEN}; ret = vfprintf(stdout, fmt, args); } else if (_trace && type == _uris.log_Trace) { - ColorContext ctx(stderr, ColorContext::Color::GREEN); + const ColorContext ctx{stderr, ColorContext::Color::GREEN}; ret = vfprintf(stderr, fmt, args); } else { fprintf(stderr, "Unknown log type %u\n", type); @@ -120,11 +119,10 @@ Log::vtprintf(LV2_URID type, const char* fmt, va_list args) static int log_vprintf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, va_list args) { - auto* f = static_cast<Log::Feature::Handle*>(handle); - va_list noargs = {}; + auto* const f = static_cast<Log::Feature::Handle*>(handle); - int ret = f->log->vtprintf(type, f->node->path().c_str(), noargs); - ret += f->log->vtprintf(type, ": ", noargs); + int ret = f->log->tprintf(type, f->node->path().c_str()); + ret += f->log->tprintf(type, ": "); ret += f->log->vtprintf(type, fmt, args); return ret; @@ -162,7 +160,7 @@ Log::Feature::feature(World& world, Node* block) f->URI = LV2_LOG__log; f->data = &handle->lv2_log; - return std::shared_ptr<LV2_Feature>(f, &free_log_feature); + return {f, &free_log_feature}; } -} // namespace ingen +} // namespace ingen diff --git a/src/Parser.cpp b/src/Parser.cpp index f54c4249..c03f0abf 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -14,39 +14,43 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Parser.hpp" - -#include "ingen/Atom.hpp" -#include "ingen/AtomForge.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/filesystem.hpp" -#include "ingen/paths.hpp" -#include "lv2/atom/atom.h" -#include "lv2/core/lv2.h" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" -#include "serd/serd.h" -#include "sord/sord.h" -#include "sord/sordmm.hpp" - +#include <ingen/Parser.hpp> + +#include <ingen/Atom.hpp> +#include <ingen/AtomForge.hpp> +#include <ingen/FilePath.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/ingen.h> +#include <ingen/paths.hpp> +#include <lv2/atom/atom.h> +#include <lv2/core/lv2.h> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> +#include <serd/serd.h> +#include <sord/sord.h> +#include <sord/sordmm.hpp> + +#include <algorithm> #include <cassert> #include <cstdint> #include <cstring> +#include <filesystem> #include <map> #include <set> #include <string> +#include <string_view> #include <utility> -#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#" -#define NS_RDFS "http://www.w3.org/2000/01/rdf-schema#" +#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#" +#define NS_RDFS "http://www.w3.org/2000/01/rdf-schema#" namespace ingen { @@ -55,27 +59,29 @@ Parser::find_resources(Sord::World& world, const URI& manifest_uri, const URI& type_uri) { - const Sord::URI base (world, manifest_uri.string()); - const Sord::URI type (world, type_uri.string()); - const Sord::URI rdf_type (world, NS_RDF "type"); + const Sord::URI base(world, manifest_uri.string()); + const Sord::URI type(world, type_uri.string()); + const Sord::URI rdf_type(world, NS_RDF "type"); const Sord::URI rdfs_seeAlso(world, NS_RDFS "seeAlso"); const Sord::Node nil; - SerdEnv* env = serd_env_new(sord_node_to_serd_node(base.c_obj())); + SerdEnv* env = serd_env_new(sord_node_to_serd_node(base.c_obj())); Sord::Model model(world, manifest_uri.string()); model.load_file(env, SERD_TURTLE, manifest_uri.string()); std::set<ResourceRecord> resources; - for (Sord::Iter i = model.find(nil, rdf_type, type); !i.end(); ++i) { - const Sord::Node resource = i.get_subject(); - const std::string resource_uri = resource.to_c_string(); - Sord::Iter f = model.find(resource, rdfs_seeAlso, nil); - std::string file_path; + for (auto i = model.find(nil, rdf_type, type); !i.end(); ++i) { + const auto resource = i.get_subject(); + auto f = model.find(resource, rdfs_seeAlso, nil); + + std::string file_path; if (!f.end()) { - uint8_t* p = serd_file_uri_parse(f.get_object().to_u_string(), nullptr); + uint8_t* p = + serd_file_uri_parse(f.get_object().to_u_string(), nullptr); file_path = reinterpret_cast<const char*>(p); serd_free(p); } + resources.insert(ResourceRecord(resource, file_path)); } @@ -83,44 +89,43 @@ Parser::find_resources(Sord::World& world, return resources; } -static boost::optional<raul::Path> +static std::optional<raul::Path> get_path(const URI& base, const URI& uri) { - const URI relative = uri.make_relative(base); + const URI relative = uri.make_relative(base, base); const std::string uri_str = "/" + relative.string(); return raul::Path::is_valid(uri_str) ? raul::Path(uri_str) - : boost::optional<raul::Path>(); + : std::optional<raul::Path>(); } static bool skip_property(ingen::URIs& uris, const Sord::Node& predicate) { - return (predicate == INGEN__file || - predicate == uris.ingen_arc || - predicate == uris.ingen_block || - predicate == uris.lv2_port); + return (predicate == INGEN__file || predicate == uris.ingen_arc || + predicate == uris.ingen_block || predicate == uris.lv2_port); } static Properties -get_properties(ingen::World& world, - Sord::Model& model, - const Sord::Node& subject, - Resource::Graph ctx, - const boost::optional<Properties>& data = {}) +get_properties(ingen::World& world, + Sord::Model& model, + const Sord::Node& subject, + Resource::Graph ctx, + const std::optional<Properties>& data = {}) { AtomForge forge(world.uri_map().urid_map()); const Sord::Node nil; Properties props; - for (Sord::Iter i = model.find(subject, nil, nil); !i.end(); ++i) { + for (auto i = model.find(subject, nil, nil); !i.end(); ++i) { if (!skip_property(world.uris(), i.get_predicate())) { forge.clear(); - forge.read( - *world.rdf_world(), model.c_obj(), i.get_object().c_obj()); + forge.read(*world.rdf_world(), + model.c_obj(), + i.get_object().c_obj()); const LV2_Atom* atom = forge.atom(); Atom atomm; - atomm = Forge::alloc( - atom->size, atom->type, LV2_ATOM_BODY_CONST(atom)); + atomm = + Forge::alloc(atom->size, atom->type, LV2_ATOM_BODY_CONST(atom)); props.emplace(i.get_predicate(), Property(atomm, ctx)); } } @@ -147,7 +152,7 @@ get_properties(ingen::World& world, using PortRecord = std::pair<raul::Path, Properties>; -static boost::optional<PortRecord> +static std::optional<PortRecord> get_port(ingen::World& world, Sord::Model& model, const Sord::Node& subject, @@ -162,19 +167,18 @@ get_port(ingen::World& world, // Get index if requested (for Graphs) if (index) { - Properties::const_iterator i = props.find(uris.lv2_index); - if (i == props.end() - || i->second.type() != world.forge().Int - || i->second.get<int32_t>() < 0) { + const auto i = props.find(uris.lv2_index); + if (i == props.end() || i->second.type() != world.forge().Int || + i->second.get<int32_t>() < 0) { world.log().error("Port %1% has no valid index\n", subject); - return boost::optional<PortRecord>(); + return {}; } *index = i->second.get<int32_t>(); } // Get symbol - Properties::const_iterator s = props.find(uris.lv2_symbol); - std::string sym; + auto s = props.find(uris.lv2_symbol); + std::string sym; if (s != props.end() && s->second.type() == world.forge().String) { sym = s->second.ptr<char>(); } else { @@ -182,80 +186,78 @@ get_port(ingen::World& world, const size_t last_slash = subject_str.find_last_of('/'); sym = ((last_slash == std::string::npos) - ? subject_str - : subject_str.substr(last_slash + 1)); + ? subject_str + : subject_str.substr(last_slash + 1)); } if (!raul::Symbol::is_valid(sym)) { world.log().error("Port %1% has invalid symbol `%2%'\n", subject, sym); - return boost::optional<PortRecord>(); + return {}; } const raul::Symbol port_sym(sym); const raul::Path port_path(parent.child(port_sym)); - props.erase(uris.lv2_symbol); // Don't set symbol property in engine + props.erase(uris.lv2_symbol); // Don't set symbol property in engine return make_pair(port_path, props); } -static boost::optional<raul::Path> -parse( - World& world, - Interface& target, - Sord::Model& model, - const URI& base_uri, - Sord::Node& subject, - const boost::optional<raul::Path>& parent = boost::optional<raul::Path>(), - const boost::optional<raul::Symbol>& symbol = boost::optional<raul::Symbol>(), - const boost::optional<Properties>& data = boost::optional<Properties>()); - -static boost::optional<raul::Path> +static std::optional<raul::Path> +parse(World& world, + Interface& target, + Sord::Model& model, + const URI& base_uri, + Sord::Node& subject, + const std::optional<raul::Path>& parent = std::optional<raul::Path>(), + const std::optional<raul::Symbol>& symbol = std::optional<raul::Symbol>(), + const std::optional<Properties>& data = std::optional<Properties>()); + +static std::optional<raul::Path> parse_graph( - World& world, - Interface& target, - Sord::Model& model, - const URI& base_uri, - const Sord::Node& subject, - Resource::Graph ctx, - const boost::optional<raul::Path>& parent = boost::optional<raul::Path>(), - const boost::optional<raul::Symbol>& symbol = boost::optional<raul::Symbol>(), - const boost::optional<Properties>& data = boost::optional<Properties>()); - -static boost::optional<raul::Path> + World& world, + Interface& target, + Sord::Model& model, + const URI& base_uri, + const Sord::Node& subject, + Resource::Graph ctx, + const std::optional<raul::Path>& parent = std::optional<raul::Path>(), + const std::optional<raul::Symbol>& symbol = std::optional<raul::Symbol>(), + const std::optional<Properties>& data = std::optional<Properties>()); + +static std::optional<raul::Path> parse_block( - World& world, - Interface& target, - Sord::Model& model, - const URI& base_uri, - const Sord::Node& subject, - const raul::Path& path, - const boost::optional<Properties>& data = boost::optional<Properties>()); + World& world, + Interface& target, + Sord::Model& model, + const URI& base_uri, + const Sord::Node& subject, + const raul::Path& path, + const std::optional<Properties>& data = std::optional<Properties>()); static bool -parse_arcs( - World& world, - Interface& target, - Sord::Model& model, - const URI& base_uri, - const Sord::Node& subject, - const raul::Path& graph); - -static boost::optional<raul::Path> -parse_block(ingen::World& world, - ingen::Interface& target, - Sord::Model& model, - const URI& base_uri, - const Sord::Node& subject, - const raul::Path& path, - const boost::optional<Properties>& data) +parse_arcs(World& world, + Interface& target, + Sord::Model& model, + const URI& base_uri, + const Sord::Node& subject, + const raul::Path& graph); + +static std::optional<raul::Path> +parse_block(ingen::World& world, + ingen::Interface& target, + Sord::Model& model, + const URI& base_uri, + const Sord::Node& subject, + const raul::Path& path, + const std::optional<Properties>& data) { const URIs& uris = world.uris(); // Try lv2:prototype and old ingen:prototype for backwards compatibility - const Sord::URI prototype_predicates[] = { - Sord::URI(*world.rdf_world(), uris.lv2_prototype), - Sord::URI(*world.rdf_world(), uris.ingen_prototype) - }; + const Sord::URI prototype_predicates[] = {Sord::URI(*world.rdf_world(), + uris.lv2_prototype), + Sord::URI(*world.rdf_world(), + uris.ingen_prototype)}; // Get prototype Sord::Node prototype; @@ -268,8 +270,9 @@ parse_block(ingen::World& world, if (!prototype.is_valid()) { world.log().error("Block %1% (%2%) missing mandatory lv2:prototype\n", - subject, path); - return boost::optional<raul::Path>(); + subject, + path); + return {}; } const auto* type_uri = @@ -282,87 +285,96 @@ parse_block(ingen::World& world, serd_uri_parse(reinterpret_cast<const uint8_t*>(base_uri.c_str()), &base_uri_parts); - SerdURI ignored; - SerdNode sub_uri = serd_node_new_uri_from_string( - type_uri, - &base_uri_parts, - &ignored); + SerdURI ignored; + const SerdNode sub_uri = + serd_node_new_uri_from_string(type_uri, &base_uri_parts, &ignored); - const std::string sub_uri_str = reinterpret_cast<const char*>(sub_uri.buf); - const std::string sub_file = sub_uri_str + "/main.ttl"; + const std::string sub_uri_str = + reinterpret_cast<const char*>(sub_uri.buf); + const std::string sub_file = sub_uri_str + "/main.ttl"; const SerdNode sub_base = serd_node_from_string( SERD_URI, reinterpret_cast<const uint8_t*>(sub_file.c_str())); Sord::Model sub_model(*world.rdf_world(), sub_file); - SerdEnv* env = serd_env_new(&sub_base); + SerdEnv* env = serd_env_new(&sub_base); sub_model.load_file(env, SERD_TURTLE, sub_file); serd_env_free(env); - Sord::URI sub_node(*world.rdf_world(), sub_file); - parse_graph(world, target, sub_model, sub_base, - sub_node, Resource::Graph::INTERNAL, - path.parent(), raul::Symbol(path.symbol()), data); - - parse_graph(world, target, model, base_uri, - subject, Resource::Graph::EXTERNAL, - path.parent(), raul::Symbol(path.symbol()), data); + const Sord::URI sub_node{*world.rdf_world(), sub_file}; + parse_graph(world, + target, + sub_model, + sub_base, + sub_node, + Resource::Graph::INTERNAL, + path.parent(), + raul::Symbol(path.symbol()), + data); + + parse_graph(world, + target, + model, + base_uri, + subject, + Resource::Graph::EXTERNAL, + path.parent(), + raul::Symbol(path.symbol()), + data); } else { // Prototype is non-file URI, plugin Properties props = get_properties( - world, model, subject, Resource::Graph::DEFAULT, data); + world, model, subject, Resource::Graph::DEFAULT, data); props.emplace(uris.rdf_type, uris.forge.make_urid(uris.ingen_Block)); target.put(path_to_uri(path), props); } return path; } -static boost::optional<raul::Path> -parse_graph(ingen::World& world, - ingen::Interface& target, - Sord::Model& model, - const URI& base_uri, - const Sord::Node& subject, - Resource::Graph ctx, - const boost::optional<raul::Path>& parent, - const boost::optional<raul::Symbol>& symbol, - const boost::optional<Properties>& data) +static std::optional<raul::Path> +parse_graph(ingen::World& world, + ingen::Interface& target, + Sord::Model& model, + const URI& base_uri, + const Sord::Node& subject, + Resource::Graph ctx, + const std::optional<raul::Path>& parent, + const std::optional<raul::Symbol>& symbol, + const std::optional<Properties>& data) { const URIs& uris = world.uris(); const Sord::URI ingen_block(*world.rdf_world(), uris.ingen_block); - const Sord::URI lv2_port(*world.rdf_world(), LV2_CORE__port); + const Sord::URI lv2_port(*world.rdf_world(), LV2_CORE__port); const Sord::Node& graph = subject; const Sord::Node nil; // Build graph path and symbol - raul::Path graph_path; + raul::Path graph_path{"/"}; if (parent && symbol) { graph_path = parent->child(*symbol); } else if (parent) { graph_path = *parent; - } else { - graph_path = raul::Path("/"); } // Create graph - Properties props = get_properties(world, model, subject, ctx, data); + const Properties props = get_properties(world, model, subject, ctx, data); target.put(path_to_uri(graph_path), props, ctx); // For each port on this graph using PortRecords = std::map<uint32_t, PortRecord>; PortRecords ports; - for (Sord::Iter p = model.find(graph, lv2_port, nil); !p.end(); ++p) { + for (auto p = model.find(graph, lv2_port, nil); !p.end(); ++p) { Sord::Node port = p.get_object(); // Get all properties - uint32_t index = 0; - boost::optional<PortRecord> port_record = get_port( - world, model, port, ctx, graph_path, &index); + uint32_t index = 0; + std::optional<PortRecord> port_record = + get_port(world, model, port, ctx, graph_path, &index); if (!port_record) { world.log().error("Invalid port %1%\n", port); - return boost::optional<raul::Path>(); + return {}; } // Store port information in ports map @@ -370,50 +382,51 @@ parse_graph(ingen::World& world, ports[index] = *port_record; } else { world.log().error("Ignored port %1% with duplicate index %2%\n", - port, index); + port, + index); } } // Create ports in order by index for (const auto& p : ports) { - target.put(path_to_uri(p.second.first), - p.second.second, - ctx); + target.put(path_to_uri(p.second.first), p.second.second, ctx); } if (ctx != Resource::Graph::INTERNAL) { - return {graph_path}; // Not parsing graph internals, finished now + return {graph_path}; // Not parsing graph internals, finished now } // For each block in this graph - for (Sord::Iter n = model.find(subject, ingen_block, nil); !n.end(); ++n) { - Sord::Node node = n.get_object(); - URI node_uri = node; + for (auto n = model.find(subject, ingen_block, nil); !n.end(); ++n) { + const Sord::Node node = n.get_object(); + const URI node_uri = node; assert(!node_uri.path().empty() && node_uri.path() != "/"); const raul::Path block_path = graph_path.child( - raul::Symbol(FilePath(node_uri.path()).stem().string())); + raul::Symbol(FilePath(node_uri.path()).stem().string())); // Parse and create block - parse_block(world, target, model, base_uri, node, block_path, - boost::optional<Properties>()); + parse_block( + world, target, model, base_uri, node, block_path, std::nullopt); // For each port on this block - for (Sord::Iter p = model.find(node, lv2_port, nil); !p.end(); ++p) { + for (auto p = model.find(node, lv2_port, nil); !p.end(); ++p) { Sord::Node port = p.get_object(); Resource::Graph subctx = Resource::Graph::DEFAULT; - if (!model.find(node, - Sord::URI(*world.rdf_world(), uris.rdf_type), - Sord::URI(*world.rdf_world(), uris.ingen_Graph)).end()) { + if (!model + .find(node, + Sord::URI(*world.rdf_world(), uris.rdf_type), + Sord::URI(*world.rdf_world(), uris.ingen_Graph)) + .end()) { subctx = Resource::Graph::EXTERNAL; } // Get all properties - boost::optional<PortRecord> port_record = get_port( - world, model, port, subctx, block_path, nullptr); + std::optional<PortRecord> port_record = + get_port(world, model, port, subctx, block_path, nullptr); if (!port_record) { world.log().error("Invalid port %1%\n", port); - return boost::optional<raul::Path>(); + return {}; } // Create port and/or set all port properties @@ -430,12 +443,12 @@ parse_graph(ingen::World& world, } static bool -parse_arc(ingen::World& world, - ingen::Interface& target, - Sord::Model& model, - const URI& base_uri, - const Sord::Node& subject, - const raul::Path& graph) +parse_arc(ingen::World& world, + ingen::Interface& target, + Sord::Model& model, + const URI& base_uri, + const Sord::Node& subject, + const raul::Path& graph) { const URIs& uris = world.uris(); @@ -443,26 +456,28 @@ parse_arc(ingen::World& world, const Sord::URI ingen_head(*world.rdf_world(), uris.ingen_head); const Sord::Node nil; - Sord::Iter t = model.find(subject, ingen_tail, nil); - Sord::Iter h = model.find(subject, ingen_head, nil); + auto t = model.find(subject, ingen_tail, nil); + auto h = model.find(subject, ingen_head, nil); if (t.end()) { world.log().error("Arc has no tail\n"); return false; - } else if (h.end()) { + } + + if (h.end()) { world.log().error("Arc has no head\n"); return false; } - const boost::optional<raul::Path> tail_path = get_path( - base_uri, t.get_object()); + const std::optional<raul::Path> tail_path = + get_path(base_uri, t.get_object()); if (!tail_path) { world.log().error("Arc tail has invalid URI\n"); return false; } - const boost::optional<raul::Path> head_path = get_path( - base_uri, h.get_object()); + const std::optional<raul::Path> head_path = + get_path(base_uri, h.get_object()); if (!head_path) { world.log().error("Arc head has invalid URI\n"); return false; @@ -471,7 +486,9 @@ parse_arc(ingen::World& world, if (!(++t).end()) { world.log().error("Arc has multiple tails\n"); return false; - } else if (!(++h).end()) { + } + + if (!(++h).end()) { world.log().error("Arc has multiple heads\n"); return false; } @@ -482,56 +499,62 @@ parse_arc(ingen::World& world, } static bool -parse_arcs(ingen::World& world, - ingen::Interface& target, - Sord::Model& model, - const URI& base_uri, - const Sord::Node& subject, - const raul::Path& graph) +parse_arcs(ingen::World& world, + ingen::Interface& target, + Sord::Model& model, + const URI& base_uri, + const Sord::Node& subject, + const raul::Path& graph) { const Sord::URI ingen_arc(*world.rdf_world(), world.uris().ingen_arc); const Sord::Node nil; - for (Sord::Iter i = model.find(subject, ingen_arc, nil); !i.end(); ++i) { + for (auto i = model.find(subject, ingen_arc, nil); !i.end(); ++i) { parse_arc(world, target, model, base_uri, i.get_object(), graph); } return true; } -static boost::optional<raul::Path> -parse(ingen::World& world, - ingen::Interface& target, - Sord::Model& model, - const URI& base_uri, - Sord::Node& subject, - const boost::optional<raul::Path>& parent, - const boost::optional<raul::Symbol>& symbol, - const boost::optional<Properties>& data) +static std::optional<raul::Path> +parse(ingen::World& world, + ingen::Interface& target, + Sord::Model& model, + const URI& base_uri, + Sord::Node& subject, + const std::optional<raul::Path>& parent, + const std::optional<raul::Symbol>& symbol, + const std::optional<Properties>& data) { const URIs& uris = world.uris(); - const Sord::URI graph_class (*world.rdf_world(), uris.ingen_Graph); - const Sord::URI block_class (*world.rdf_world(), uris.ingen_Block); - const Sord::URI arc_class (*world.rdf_world(), uris.ingen_Arc); + const Sord::URI graph_class(*world.rdf_world(), uris.ingen_Graph); + const Sord::URI block_class(*world.rdf_world(), uris.ingen_Block); + const Sord::URI arc_class(*world.rdf_world(), uris.ingen_Arc); const Sord::URI internal_class(*world.rdf_world(), uris.ingen_Internal); - const Sord::URI in_port_class (*world.rdf_world(), LV2_CORE__InputPort); + const Sord::URI in_port_class(*world.rdf_world(), LV2_CORE__InputPort); const Sord::URI out_port_class(*world.rdf_world(), LV2_CORE__OutputPort); - const Sord::URI lv2_class (*world.rdf_world(), LV2_CORE__Plugin); - const Sord::URI rdf_type (*world.rdf_world(), uris.rdf_type); + const Sord::URI lv2_class(*world.rdf_world(), LV2_CORE__Plugin); + const Sord::URI rdf_type(*world.rdf_world(), uris.rdf_type); const Sord::Node nil; // Parse explicit subject graph if (subject.is_valid()) { - return parse_graph(world, target, model, base_uri, - subject, Resource::Graph::INTERNAL, - parent, symbol, data); + return parse_graph(world, + target, + model, + base_uri, + subject, + Resource::Graph::INTERNAL, + parent, + symbol, + data); } // Get all subjects and their types (?subject a ?type) - using Subjects = std::map< Sord::Node, std::set<Sord::Node> >; + using Subjects = std::map<Sord::Node, std::set<Sord::Node>>; Subjects subjects; - for (Sord::Iter i = model.find(subject, rdf_type, nil); !i.end(); ++i) { + for (auto i = model.find(subject, rdf_type, nil); !i.end(); ++i) { const Sord::Node& rdf_class = i.get_object(); assert(rdf_class.is_uri()); @@ -549,77 +572,82 @@ parse(ingen::World& world, for (const auto& i : subjects) { const Sord::Node& s = i.first; const std::set<Sord::Node>& types = i.second; - boost::optional<raul::Path> ret; + std::optional<raul::Path> ret; if (types.find(graph_class) != types.end()) { - ret = parse_graph(world, target, model, base_uri, - s, Resource::Graph::INTERNAL, - parent, symbol, data); + ret = parse_graph(world, + target, + model, + base_uri, + s, + Resource::Graph::INTERNAL, + parent, + symbol, + data); } else if (types.find(block_class) != types.end()) { - const raul::Path rel_path(*get_path(base_uri, s)); + const raul::Path rel_path{*get_path(base_uri, s)}; const raul::Path path = parent ? parent->child(rel_path) : rel_path; ret = parse_block(world, target, model, base_uri, s, path, data); } else if (types.find(in_port_class) != types.end() || types.find(out_port_class) != types.end()) { - const raul::Path rel_path(*get_path(base_uri, s)); + const raul::Path rel_path{*get_path(base_uri, s)}; const raul::Path path = parent ? parent->child(rel_path) : rel_path; - const Properties properties = get_properties( - world, model, s, Resource::Graph::DEFAULT, data); + const Properties properties = + get_properties(world, model, s, Resource::Graph::DEFAULT, data); target.put(path_to_uri(path), properties); ret = path; } else if (types.find(arc_class) != types.end()) { - raul::Path parent_path(parent ? parent.get() : raul::Path("/")); + const raul::Path parent_path{parent ? parent.value() : raul::Path("/")}; parse_arc(world, target, model, base_uri, s, parent_path); } else { world.log().error("Subject has no known types\n"); } } - return boost::optional<raul::Path>(); + return {}; } bool -Parser::parse_file(ingen::World& world, - ingen::Interface& target, - const FilePath& path, - const boost::optional<raul::Path>& parent, - const boost::optional<raul::Symbol>& symbol, - const boost::optional<Properties>& data) +Parser::parse_file(ingen::World& world, + ingen::Interface& target, + const FilePath& path, + const std::optional<raul::Path>& parent, + const std::optional<raul::Symbol>& symbol, + const std::optional<Properties>& data) { // Get absolute file path FilePath file_path = path; if (!file_path.is_absolute()) { - file_path = filesystem::current_path() / file_path; + file_path = std::filesystem::current_path() / file_path; } // Find file to use as manifest - const bool is_bundle = filesystem::is_directory(file_path); + const bool is_bundle = std::filesystem::is_directory(file_path); const FilePath manifest_path = - (is_bundle ? file_path / "manifest.ttl" : file_path); + (is_bundle ? file_path / "manifest.ttl" : file_path); - URI manifest_uri(manifest_path); + const URI manifest_uri{manifest_path}; // Find graphs in manifest - const std::set<ResourceRecord> resources = find_resources( - *world.rdf_world(), manifest_uri, URI(INGEN__Graph)); + const std::set<ResourceRecord> resources = + find_resources(*world.rdf_world(), manifest_uri, URI(INGEN__Graph)); if (resources.empty()) { world.log().error("No graphs found in %1%\n", path); return false; } - /* Choose the graph to load. If this is a manifest, then there should only be - one, but if this is a graph file, subgraphs will be returned as well. - In this case, choose the one with the file URI. */ - URI uri; - for (const ResourceRecord& r : resources) { - if (r.uri == URI(manifest_path)) { - uri = r.uri; - file_path = r.filename; - break; - } - } + // Try to find the graph with the manifest path for a URI + const auto m = std::find_if(resources.begin(), + resources.end(), + [manifest_path](const auto& r) { + return r.uri == URI(manifest_path); + }); - if (uri.empty()) { + URI uri; + if (m != resources.end()) { + uri = m->uri; + file_path = m->filename; + } else { // Didn't find a graph with the same URI as the file, use the first uri = (*resources.begin()).uri; file_path = (*resources.begin()).filename; @@ -631,13 +659,16 @@ Parser::parse_file(ingen::World& world, } // Initialise parsing environment - const URI file_uri = URI(file_path); - const auto* uri_c_str = reinterpret_cast<const uint8_t*>(uri.c_str()); - SerdNode base_node = serd_node_from_string(SERD_URI, uri_c_str); - SerdEnv* env = serd_env_new(&base_node); + const URI file_uri = URI(file_path); + const auto* uri_c_str = reinterpret_cast<const uint8_t*>(uri.c_str()); + const SerdNode base_node = serd_node_from_string(SERD_URI, uri_c_str); + SerdEnv* env = serd_env_new(&base_node); // Load graph into model - Sord::Model model(*world.rdf_world(), uri.string(), SORD_SPO|SORD_PSO, false); + Sord::Model model(*world.rdf_world(), + uri.string(), + SORD_SPO | SORD_PSO, + false); model.load_file(env, SERD_TURTLE, file_uri); serd_env_free(env); @@ -650,37 +681,36 @@ Parser::parse_file(ingen::World& world, } Sord::Node subject(*world.rdf_world(), Sord::Node::URI, uri.string()); - boost::optional<raul::Path> parsed_path - = parse(world, target, model, model.base_uri(), - subject, parent, symbol, data); + std::optional<raul::Path> parsed_path = parse( + world, target, model, model.base_uri(), subject, parent, symbol, data); if (parsed_path) { target.set_property(path_to_uri(*parsed_path), URI(INGEN__file), world.forge().alloc_uri(uri.string())); return true; - } else { - world.log().warn("Document URI lost\n"); - return false; } + + world.log().warn("Document URI lost\n"); + return false; } -boost::optional<URI> -Parser::parse_string(ingen::World& world, - ingen::Interface& target, - const std::string& str, - const URI& base_uri, - const boost::optional<raul::Path>& parent, - const boost::optional<raul::Symbol>& symbol, - const boost::optional<Properties>& data) +std::optional<URI> +Parser::parse_string(ingen::World& world, + ingen::Interface& target, + const std::string& str, + const URI& base_uri, + const std::optional<raul::Path>& parent, + const std::optional<raul::Symbol>& symbol, + const std::optional<Properties>& data) { // Load string into model - Sord::Model model(*world.rdf_world(), base_uri, SORD_SPO|SORD_PSO, false); + Sord::Model model(*world.rdf_world(), base_uri, SORD_SPO | SORD_PSO, false); SerdEnv* env = serd_env_new(nullptr); if (!base_uri.empty()) { const SerdNode base = serd_node_from_string( - SERD_URI, reinterpret_cast<const uint8_t*>(base_uri.c_str())); + SERD_URI, reinterpret_cast<const uint8_t*>(base_uri.c_str())); serd_env_set_base_uri(env, &base); } model.load_string(env, SERD_TURTLE, str.c_str(), str.length(), base_uri); diff --git a/src/Resource.cpp b/src/Resource.cpp index 0bd4b95f..29a82772 100644 --- a/src/Resource.cpp +++ b/src/Resource.cpp @@ -14,11 +14,13 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Resource.hpp" +#include <ingen/Resource.hpp> -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/URIs.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> #include <map> #include <utility> @@ -29,9 +31,8 @@ bool Resource::add_property(const URI& uri, const Atom& value, Graph ctx) { // Ignore duplicate statements - using iterator = Properties::const_iterator; - const std::pair<iterator, iterator> range = _properties.equal_range(uri); - for (iterator i = range.first; i != range.second && i != _properties.end(); ++i) { + const auto range = _properties.equal_range(uri); + for (auto i = range.first; i != range.second && i != _properties.end(); ++i) { if (i->second == value && i->second.context() == ctx) { return false; } @@ -52,6 +53,8 @@ Resource::add_property(const URI& uri, const Atom& value, Graph ctx) const Atom& Resource::set_property(const URI& uri, const Atom& value, Resource::Graph ctx) { + assert(uri != _uris.ingen_activity); // Always ephemeral + // Erase existing property in this context for (auto i = _properties.find(uri); (i != _properties.end()) && (i->first == uri);) { @@ -65,16 +68,10 @@ Resource::set_property(const URI& uri, const Atom& value, Resource::Graph ctx) i = next; } - if (uri != _uris.ingen_activity) { - // Insert new property - const Atom& v = _properties.emplace(uri, Property(value, ctx))->second; - on_property(uri, v); - return v; - } else { - // Announce ephemeral activity, but do not store - on_property(uri, value); - return value; - } + // Insert new property + const Atom& v = _properties.emplace(uri, Property(value, ctx))->second; + on_property(uri, v); + return v; } const Atom& @@ -119,8 +116,9 @@ Resource::has_property(const URI& uri, const Atom& value) const bool Resource::has_property(const URI& uri, const URIs::Quark& value) const { - Properties::const_iterator i = _properties.find(uri); - for (; (i != _properties.end()) && (i->first == uri); ++i) { + for (auto i = _properties.find(uri); + (i != _properties.end()) && (i->first == uri); + ++i) { if (value == i->second) { return true; } @@ -138,7 +136,8 @@ const Atom& Resource::get_property(const URI& uri) const { static const Atom nil; - Properties::const_iterator i = _properties.find(uri); + + const auto i = _properties.find(uri); return (i != _properties.end()) ? i->second : nil; } @@ -150,11 +149,10 @@ Resource::type(const URIs& uris, bool& port, bool& is_output) { - using iterator = Properties::const_iterator; - const std::pair<iterator, iterator> types_range = properties.equal_range(uris.rdf_type); + const auto types_range = properties.equal_range(uris.rdf_type); graph = block = port = is_output = false; - for (iterator i = types_range.first; i != types_range.second; ++i) { + for (auto i = types_range.first; i != types_range.second; ++i) { const Atom& atom = i->second; if (atom.type() != uris.forge.URI && atom.type() != uris.forge.URID) { continue; // Non-URI type, ignore garbage data @@ -176,14 +174,14 @@ Resource::type(const URIs& uris, if (graph && block && !port) { // => graph block = false; return true; - } else if (port && (graph || block)) { // nonsense + } + + if (port && (graph || block)) { // nonsense port = false; return false; - } else if (graph || block || port) { // recognized type - return true; - } else { // unknown - return false; } + + return graph || block || port; // recognized type } void diff --git a/src/Serialiser.cpp b/src/Serialiser.cpp index 3dfa862b..785e12ba 100644 --- a/src/Serialiser.cpp +++ b/src/Serialiser.cpp @@ -14,55 +14,52 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Serialiser.hpp" - -#include "ingen/Arc.hpp" -#include "ingen/Atom.hpp" -#include "ingen/FilePath.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Log.hpp" -#include "ingen/Node.hpp" -#include "ingen/Resource.hpp" -#include "ingen/Store.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/filesystem.hpp" -#include "ingen/runtime_paths.hpp" -#include "lv2/core/lv2.h" -#include "lv2/state/state.h" -#include "lv2/ui/ui.h" -#include "lv2/urid/urid.h" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" -#include "serd/serd.h" -#include "sord/sord.h" -#include "sord/sordmm.hpp" -#include "sratom/sratom.h" +#include <ingen/Serialiser.hpp> + +#include <ingen/Arc.hpp> +#include <ingen/Atom.hpp> +#include <ingen/FilePath.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Log.hpp> +#include <ingen/Node.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/ingen.h> +#include <lv2/core/lv2.h> +#include <lv2/state/state.h> +#include <lv2/ui/ui.h> +#include <lv2/urid/urid.h> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> +#include <serd/serd.h> +#include <sord/sord.h> +#include <sord/sordmm.hpp> +#include <sratom/sratom.h> #include <cassert> #include <cstdint> #include <cstring> -#include <map> +#include <filesystem> #include <memory> #include <set> #include <stdexcept> #include <string> +#include <string_view> #include <utility> namespace ingen { -struct Serialiser::Impl -{ +struct Serialiser::Impl { explicit Impl(World& world) : _root_path("/") - , _mode(Mode::TO_FILE) , _world(world) - , _model(nullptr) , _sratom(sratom_new(&_world.uri_map().urid_map())) - { - } + {} ~Impl() { sratom_free(_sratom); } @@ -105,11 +102,11 @@ struct Serialiser::Impl std::string finish(); raul::Path _root_path; - Mode _mode; + Mode _mode{Mode::TO_FILE}; URI _base_uri; FilePath _basename; World& _world; - Sord::Model* _model; + Sord::Model* _model{nullptr}; Sratom* _sratom; }; @@ -122,7 +119,6 @@ Serialiser::Impl::write_manifest(const FilePath& bundle_path, const std::shared_ptr<const Node>&) { const FilePath manifest_path(bundle_path / "manifest.ttl"); - const FilePath binary_path(ingen_module_path("lv2")); start_to_file(raul::Path("/"), manifest_path); @@ -194,19 +190,19 @@ Serialiser::Impl::write_bundle(const std::shared_ptr<const Node>& graph, const URI& uri) { FilePath path(uri.path()); - if (filesystem::exists(path) && !filesystem::is_directory(path)) { + if (std::filesystem::exists(path) && !std::filesystem::is_directory(path)) { path = path.parent_path(); } _world.log().info("Writing bundle %1%\n", path); - filesystem::create_directories(path); + std::filesystem::create_directories(path); const FilePath main_file = path / "main.ttl"; const raul::Path old_root_path = _root_path; start_to_file(graph->path(), main_file); - std::set<const Resource*> plugins = + const std::set<const Resource*> plugins = serialise_graph(graph, Sord::URI(_model->world(), main_file, _base_uri)); @@ -262,7 +258,7 @@ Serialiser::Impl::finish() { std::string ret; if (_mode == Mode::TO_FILE) { - SerdStatus st = _model->write_to_file(_base_uri, SERD_TURTLE); + const SerdStatus st = _model->write_to_file(_base_uri, SERD_TURTLE); if (st) { _world.log().error("Error writing file %1% (%2%)\n", _base_uri, @@ -352,13 +348,13 @@ Serialiser::Impl::serialise_graph(const std::shared_ptr<const Node>& graph, std::set<const Resource*> plugins; const Store::const_range kids = _world.store()->children_range(graph); - for (Store::const_iterator n = kids.first; n != kids.second; ++n) { + for (auto n = kids.first; n != kids.second; ++n) { if (n->first.parent() != graph->path()) { continue; } if (n->second->graph_type() == Node::GraphType::GRAPH) { - std::shared_ptr<Node> subgraph = n->second; + const std::shared_ptr<Node> subgraph = n->second; SerdURI base_uri; serd_uri_parse(reinterpret_cast<const uint8_t*>(_base_uri.c_str()), @@ -379,7 +375,7 @@ Serialiser::Impl::serialise_graph(const std::shared_ptr<const Node>& graph, subgraph_node.buf)); // Save our state - URI my_base_uri = _base_uri; + const URI my_base_uri = _base_uri; Sord::Model* my_model = _model; // Write child bundle within this bundle @@ -398,7 +394,7 @@ Serialiser::Impl::serialise_graph(const std::shared_ptr<const Node>& graph, serd_node_free(&subgraph_node); } else if (n->second->graph_type() == Node::GraphType::BLOCK) { - std::shared_ptr<const Node> block = n->second; + const std::shared_ptr<const Node> block = n->second; const Sord::URI class_id(world, block->plugin()->uri()); const Sord::Node block_id(path_rdf_node(n->second->path())); @@ -458,7 +454,7 @@ Serialiser::Impl::serialise_block(const std::shared_ptr<const Node>& block, if (_base_uri.scheme() == "file") { const FilePath base_path = _base_uri.file_path(); const FilePath graph_dir = base_path.parent_path(); - const FilePath state_dir = graph_dir / block->symbol(); + const FilePath state_dir = graph_dir / std::string(block->symbol()); const FilePath state_file = state_dir / "state.ttl"; if (block->save_state(state_dir)) { _model->add_statement(block_id, @@ -482,7 +478,7 @@ Serialiser::Impl::serialise_port(const Node* port, Resource::Graph context, const Sord::Node& port_id) { - URIs& uris = _world.uris(); + const URIs& uris = _world.uris(); Sord::World& world = _model->world(); Properties props = port->properties(context); @@ -519,7 +515,7 @@ void Serialiser::serialise_arc(const Sord::Node& parent, const std::shared_ptr<const Arc>& arc) { - return me->serialise_arc(parent, arc); + me->serialise_arc(parent, arc); } void @@ -560,9 +556,8 @@ void Serialiser::Impl::serialise_properties(Sord::Node id, const Properties& props) { LV2_URID_Unmap* unmap = &_world.uri_map().urid_unmap(); - SerdNode base = serd_node_from_string(SERD_URI, - reinterpret_cast<const uint8_t*>( - _base_uri.c_str())); + const SerdNode base = serd_node_from_string( + SERD_URI, reinterpret_cast<const uint8_t*>(_base_uri.c_str())); SerdEnv* env = serd_env_new(&base); SordInserter* inserter = sord_inserter_new(_model->c_obj(), env); diff --git a/src/SocketReader.cpp b/src/SocketReader.cpp index e643b9a2..5499fb66 100644 --- a/src/SocketReader.cpp +++ b/src/SocketReader.cpp @@ -14,16 +14,18 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/SocketReader.hpp" - -#include "ingen/AtomForge.hpp" -#include "ingen/AtomReader.hpp" -#include "ingen/Log.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/World.hpp" -#include "lv2/urid/urid.h" -#include "raul/Socket.hpp" -#include "sord/sordmm.hpp" +#include <ingen/SocketReader.hpp> + +#include <ingen/AtomForge.hpp> +#include <ingen/AtomReader.hpp> +#include <ingen/Log.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/World.hpp> +#include <lv2/urid/urid.h> +#include <raul/Socket.hpp> +#include <serd/serd.h> +#include <sord/sord.h> +#include <sord/sordmm.hpp> #include <cerrno> #include <cstdint> @@ -41,12 +43,7 @@ SocketReader::SocketReader(ingen::World& world, std::shared_ptr<raul::Socket> sock) : _world(world) , _iface(iface) - , _env() - , _inserter(nullptr) - , _msg_node(nullptr) , _socket(std::move(sock)) - , _socket_error(0) - , _exit_flag(false) , _thread(&SocketReader::run, this) {} @@ -127,7 +124,7 @@ SocketReader::run() AtomForge forge(map); { // Lock RDF world - std::lock_guard<std::mutex> lock(_world.rdf_mutex()); + const std::lock_guard<std::mutex> lock{_world.rdf_mutex()}; // Use <ingen:/> as base URI, so relative URIs are like bundle paths base_uri = sord_new_uri(world->c_obj(), @@ -170,19 +167,23 @@ SocketReader::run() const int ret = poll(&pfd, 1, -1); if (ret == -1 || (pfd.revents & (POLLERR|POLLHUP|POLLNVAL))) { on_hangup(); - break; // Hangup - } else if (!ret) { - continue; // No data, shouldn't happen + break; // Hangup + } + + if (!ret) { + continue; // No data, shouldn't happen } // Lock RDF world - std::lock_guard<std::mutex> lock(_world.rdf_mutex()); + const std::lock_guard<std::mutex> lock{_world.rdf_mutex()}; // Read until the next '.' - SerdStatus st = serd_reader_read_chunk(reader); + const SerdStatus st = serd_reader_read_chunk(reader); if (st == SERD_FAILURE || !_msg_node) { - continue; // Read nothing, e.g. just whitespace - } else if (st) { + continue; // Read nothing, e.g. just whitespace + } + + if (st) { _world.log().error("Read error: %1%\n", serd_strerror(st)); continue; } @@ -200,7 +201,7 @@ SocketReader::run() } // Lock RDF world - std::lock_guard<std::mutex> lock(_world.rdf_mutex()); + const std::lock_guard<std::mutex> lock{_world.rdf_mutex()}; // Destroy everything sord_inserter_free(_inserter); @@ -210,4 +211,4 @@ SocketReader::run() _socket.reset(); } -} // namespace ingen +} // namespace ingen diff --git a/src/SocketWriter.cpp b/src/SocketWriter.cpp index 0e5948e5..7512ecbd 100644 --- a/src/SocketWriter.cpp +++ b/src/SocketWriter.cpp @@ -14,17 +14,18 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/SocketWriter.hpp" +#include <ingen/SocketWriter.hpp> -#include "ingen/URI.hpp" -#include "raul/Socket.hpp" - -#include <boost/variant/get.hpp> +#include <ingen/Message.hpp> +#include <ingen/TurtleWriter.hpp> +#include <ingen/URI.hpp> +#include <raul/Socket.hpp> #include <memory> #include <sys/socket.h> #include <sys/types.h> #include <utility> +#include <variant> #ifndef MSG_NOSIGNAL # define MSG_NOSIGNAL 0 @@ -44,7 +45,7 @@ void SocketWriter::message(const Message& message) { TurtleWriter::message(message); - if (boost::get<BundleEnd>(&message)) { + if (std::get_if<BundleEnd>(&message)) { // Send a null byte to indicate end of bundle const char end[] = { 0 }; send(_socket->fd(), end, 1, MSG_NOSIGNAL); @@ -54,7 +55,7 @@ SocketWriter::message(const Message& message) size_t SocketWriter::text_sink(const void* buf, size_t len) { - ssize_t ret = send(_socket->fd(), buf, len, MSG_NOSIGNAL); + const ssize_t ret = send(_socket->fd(), buf, len, MSG_NOSIGNAL); if (ret < 0) { return 0; } diff --git a/src/Store.cpp b/src/Store.cpp index fe5527a5..ab8425cb 100644 --- a/src/Store.cpp +++ b/src/Store.cpp @@ -14,11 +14,11 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Store.hpp" +#include <ingen/Store.hpp> -#include "ingen/Node.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Node.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <cassert> #include <cstdint> @@ -67,7 +67,7 @@ Store::find_descendants_end(const iterator parent) Store::const_iterator Store::find_descendants_end(const const_iterator parent) const { - const_iterator descendants_end = parent; + auto descendants_end = parent; ++descendants_end; while (descendants_end != end() && descendants_end->first.is_child_of(parent->first)) { @@ -80,9 +80,9 @@ Store::find_descendants_end(const const_iterator parent) const Store::const_range Store::children_range(const std::shared_ptr<const Node>& o) const { - const const_iterator parent = find(o->path()); + const auto parent = find(o->path()); if (parent != end()) { - const_iterator first_child = parent; + auto first_child = parent; ++first_child; return std::make_pair(first_child, find_descendants_end(parent)); } @@ -93,7 +93,7 @@ void Store::remove(const iterator top, Objects& removed) { if (top != end()) { - const iterator descendants_end = find_descendants_end(top); + const auto descendants_end = find_descendants_end(top); removed.insert(top, descendants_end); erase(top, descendants_end); } @@ -109,15 +109,15 @@ Store::rename(const iterator top, const raul::Path& new_path) remove(top, removed); // Rename all the removed objects - for (Objects::const_iterator i = removed.begin(); i != removed.end(); ++i) { - const raul::Path path = (i->first == old_path) + for (const auto& r : removed) { + const auto path = (r.first == old_path) ? new_path : new_path.child( - raul::Path(i->first.substr(old_path.base().length() - 1))); + raul::Path(r.first.substr(old_path.base().length() - 1))); - i->second->set_path(path); - assert(find(path) == end()); // Shouldn't be dropping objects! - emplace(path, i->second); + r.second->set_path(path); + assert(find(path) == end()); // Shouldn't be dropping objects! + emplace(path, r.second); } } @@ -134,14 +134,13 @@ Store::child_name_offset(const raul::Path& parent, if (offset > 0) { ss << "_" << offset; } + if (find(parent.child(raul::Symbol(ss.str()))) == end() && (allow_zero || offset > 0)) { break; - } else if (offset == 0) { - offset = 2; - } else { - ++offset; } + + offset = (offset == 0) ? 2 : (offset + 1); } return offset; diff --git a/src/StreamWriter.cpp b/src/StreamWriter.cpp index d8a93a0b..c40389e4 100644 --- a/src/StreamWriter.cpp +++ b/src/StreamWriter.cpp @@ -14,10 +14,11 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/StreamWriter.hpp" +#include <ingen/StreamWriter.hpp> -#include "ingen/ColorContext.hpp" -#include "ingen/URI.hpp" +#include <ingen/ColorContext.hpp> +#include <ingen/TurtleWriter.hpp> +#include <ingen/URI.hpp> namespace ingen { @@ -34,7 +35,7 @@ StreamWriter::StreamWriter(URIMap& map, size_t StreamWriter::text_sink(const void* buf, size_t len) { - ColorContext ctx(_stream, _color); + const ColorContext ctx{_stream, _color}; return fwrite(buf, 1, len, _stream); } diff --git a/src/TurtleWriter.cpp b/src/TurtleWriter.cpp index 07e06afe..e19c14e2 100644 --- a/src/TurtleWriter.cpp +++ b/src/TurtleWriter.cpp @@ -14,10 +14,15 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/TurtleWriter.hpp" +#include <ingen/TurtleWriter.hpp> -#include "ingen/URIMap.hpp" -#include "lv2/atom/atom.h" +#include <ingen/AtomWriter.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/ingen.h> +#include <lv2/atom/atom.h> +#include <serd/serd.h> +#include <sratom/sratom.h> #include <utility> @@ -40,20 +45,18 @@ write_prefix(void* handle, const SerdNode* name, const SerdNode* uri) } TurtleWriter::TurtleWriter(URIMap& map, URIs& uris, URI uri) - : AtomWriter(map, uris, *this) - , _map(map) - , _sratom(sratom_new(&map.urid_map())) - , _base(SERD_NODE_NULL) - , _base_uri(SERD_URI_NULL) - , _uri(std::move(uri)) - , _wrote_prefixes(false) + : AtomWriter{map, uris, *this} + , _map{map} + , _sratom{sratom_new(&map.urid_map())} + , _base{serd_node_from_string(SERD_URI, USTR("ingen:/"))} + , _env{serd_env_new(&_base)} + , _uri{std::move(uri)} { // Use <ingen:/> as base URI, so relative URIs are like bundle paths - _base = serd_node_from_string(SERD_URI, USTR("ingen:/")); - serd_uri_parse(_base.buf, &_base_uri); + + serd_uri_parse(USTR("ingen:/"), &_base_uri); // Set up serialisation environment - _env = serd_env_new(&_base); serd_env_set_prefix_from_strings(_env, USTR("atom"), USTR("http://lv2plug.in/ns/ext/atom#")); serd_env_set_prefix_from_strings(_env, USTR("doap"), USTR("http://usefulinc.com/ns/doap#")); serd_env_set_prefix_from_strings(_env, USTR("ingen"), USTR(INGEN_NS)); @@ -66,6 +69,7 @@ TurtleWriter::TurtleWriter(URIMap& map, URIs& uris, URI uri) serd_env_set_prefix_from_strings(_env, USTR("xsd"), USTR("http://www.w3.org/2001/XMLSchema#")); // Make a Turtle writer that writes to text_sink + // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer) _writer = serd_writer_new( SERD_TURTLE, static_cast<SerdStyle>(SERD_STYLE_RESOLVED|SERD_STYLE_ABBREVIATED|SERD_STYLE_CURIED), diff --git a/src/URI.cpp b/src/URI.cpp index 1763a8bd..3161b7d2 100644 --- a/src/URI.cpp +++ b/src/URI.cpp @@ -14,18 +14,17 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/URI.hpp" +#include <ingen/URI.hpp> -#include "ingen/FilePath.hpp" +#include <ingen/FilePath.hpp> +#include <serd/serd.h> +#include <sord/sordmm.hpp> #include <cassert> namespace ingen { -URI::URI() - : _uri(SERD_URI_NULL) - , _node(SERD_NODE_NULL) -{} +URI::URI() : _uri(SERD_URI_NULL), _node(SERD_NODE_NULL) {} URI::URI(const std::string& str) : _uri(SERD_URI_NULL) @@ -33,14 +32,16 @@ URI::URI(const std::string& str) str.c_str()), nullptr, &_uri)) -{} +{ +} URI::URI(const char* str) : _uri(SERD_URI_NULL) , _node(serd_node_new_uri_from_string(reinterpret_cast<const uint8_t*>(str), nullptr, &_uri)) -{} +{ +} URI::URI(const std::string& str, const URI& base) : _uri(SERD_URI_NULL) @@ -48,27 +49,23 @@ URI::URI(const std::string& str, const URI& base) str.c_str()), &base._uri, &_uri)) -{} - -URI::URI(SerdNode node) - : _uri(SERD_URI_NULL) - , _node(serd_node_new_uri_from_node(&node, nullptr, &_uri)) { - assert(node.type == SERD_URI); } -URI::URI(SerdNode node, SerdURI uri) - : _uri(uri) - , _node(node) +URI::URI(const SerdNode& node) + : _uri(SERD_URI_NULL) + , _node(serd_node_new_uri_from_node(&node, nullptr, &_uri)) { assert(node.type == SERD_URI); } -URI::URI(const Sord::Node& node) - : URI(*node.to_serd_node()) +URI::URI(const SerdNode& node, const SerdURI& uri) : _uri(uri), _node(node) { + assert(node.type == SERD_URI); } +URI::URI(const Sord::Node& node) : URI(*node.to_serd_node()) {} + URI::URI(const FilePath& path) : _uri(SERD_URI_NULL) , _node( @@ -76,12 +73,13 @@ URI::URI(const FilePath& path) nullptr, &_uri, true)) -{} +{ +} URI::URI(const URI& uri) - : _uri(SERD_URI_NULL) - , _node(serd_node_new_uri(&uri._uri, nullptr, &_uri)) -{} + : _uri(SERD_URI_NULL), _node(serd_node_new_uri(&uri._uri, nullptr, &_uri)) +{ +} URI& URI::operator=(const URI& uri) @@ -94,9 +92,7 @@ URI::operator=(const URI& uri) return *this; } -URI::URI(URI&& uri) noexcept - : _uri(uri._uri) - , _node(uri._node) +URI::URI(URI&& uri) noexcept : _uri(uri._uri), _node(uri._node) { uri._node = SERD_NODE_NULL; uri._uri = SERD_URI_NULL; @@ -122,9 +118,21 @@ URI::~URI() URI URI::make_relative(const URI& base) const { - SerdURI uri; - SerdNode node = serd_node_new_relative_uri(&_uri, &base._uri, nullptr, &uri); - return URI(node, uri); + SerdURI uri; + const SerdNode node = + serd_node_new_relative_uri(&_uri, &base._uri, nullptr, &uri); + + return {node, uri}; +} + +URI +URI::make_relative(const URI& base, const URI& root) const +{ + SerdURI uri; + const SerdNode node = + serd_node_new_relative_uri(&_uri, &base._uri, &root._uri, &uri); + + return {node, uri}; } -} // namespace ingen +} // namespace ingen diff --git a/src/URIMap.cpp b/src/URIMap.cpp index 1f627e1e..25764762 100644 --- a/src/URIMap.cpp +++ b/src/URIMap.cpp @@ -14,11 +14,11 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/URIMap.hpp" +#include <ingen/URIMap.hpp> -#include "ingen/Log.hpp" -#include "ingen/URI.hpp" -#include "lv2/urid/urid.h" +#include <ingen/Log.hpp> +#include <ingen/URI.hpp> +#include <lv2/urid/urid.h> #include <cassert> #include <cstdint> @@ -29,8 +29,7 @@ namespace ingen { URIMap::URIMap(Log& log, LV2_URID_Map* map, LV2_URID_Unmap* unmap) : _urid_map_feature(new URIDMapFeature(this, map, log)) , _urid_unmap_feature(new URIDUnmapFeature(this, unmap)) -{ -} +{} URIMap::URIDMapFeature::URIDMapFeature(URIMap* map, LV2_URID_Map* impl, @@ -51,9 +50,9 @@ LV2_URID URIMap::URIDMapFeature::default_map(LV2_URID_Map_Handle h, const char* c_uri) { - auto* const map(static_cast<URIMap*>(h)); - std::string uri(c_uri); - std::lock_guard<std::mutex> lock(map->_mutex); + auto* const map{static_cast<URIMap*>(h)}; + std::string uri{c_uri}; + const std::lock_guard<std::mutex> lock{map->_mutex}; auto record = map->_map.emplace(uri, map->_map.size() + 1); const auto id = record.first->second; @@ -93,8 +92,8 @@ const char* URIMap::URIDUnmapFeature::default_unmap(LV2_URID_Unmap_Handle h, LV2_URID urid) { - auto* const map(static_cast<URIMap*>(h)); - std::lock_guard<std::mutex> lock(map->_mutex); + auto* const map{static_cast<URIMap*>(h)}; + const std::lock_guard<std::mutex> lock{map->_mutex}; return (urid > 0 && urid <= map->_unmap.size() ? map->_unmap[urid - 1].c_str() diff --git a/src/URIs.cpp b/src/URIs.cpp index a2ad6819..49eb1707 100644 --- a/src/URIs.cpp +++ b/src/URIs.cpp @@ -14,25 +14,27 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/URIs.hpp" +#include <ingen/URIs.hpp> -#include "ingen/Forge.hpp" -#include "ingen/ingen.h" -#include "lv2/atom/atom.h" -#include "lv2/buf-size/buf-size.h" -#include "lv2/core/lv2.h" -#include "lv2/log/log.h" -#include "lv2/midi/midi.h" -#include "lv2/morph/morph.h" -#include "lv2/options/options.h" -#include "lv2/parameters/parameters.h" -#include "lv2/patch/patch.h" -#include "lv2/port-props/port-props.h" -#include "lv2/presets/presets.h" -#include "lv2/resize-port/resize-port.h" -#include "lv2/state/state.h" -#include "lv2/time/time.h" -#include "lv2/worker/worker.h" +#include <ingen/Forge.hpp> +#include <ingen/URI.hpp> +#include <ingen/ingen.h> +#include <lilv/lilv.h> +#include <lv2/atom/atom.h> +#include <lv2/buf-size/buf-size.h> +#include <lv2/core/lv2.h> +#include <lv2/log/log.h> +#include <lv2/midi/midi.h> +#include <lv2/morph/morph.h> +#include <lv2/options/options.h> +#include <lv2/parameters/parameters.h> +#include <lv2/patch/patch.h> +#include <lv2/port-props/port-props.h> +#include <lv2/presets/presets.h> +#include <lv2/resize-port/resize-port.h> +#include <lv2/state/state.h> +#include <lv2/time/time.h> +#include <lv2/worker/worker.h> namespace ingen { @@ -155,6 +157,7 @@ URIs::URIs(Forge& ingen_forge, URIMap* map, LilvWorld* lworld) , midi_binding (forge, map, lworld, LV2_MIDI__binding) , midi_controllerNumber (forge, map, lworld, LV2_MIDI__controllerNumber) , midi_noteNumber (forge, map, lworld, LV2_MIDI__noteNumber) + , midi_channel (forge, map, lworld, LV2_MIDI__channel) , morph_AutoMorphPort (forge, map, lworld, LV2_MORPH__AutoMorphPort) , morph_MorphPort (forge, map, lworld, LV2_MORPH__MorphPort) , morph_currentType (forge, map, lworld, LV2_MORPH__currentType) diff --git a/src/World.cpp b/src/World.cpp index 27d92632..7e643002 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -14,32 +14,32 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/World.hpp" - -#include "ingen/Atom.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/DataAccess.hpp" -#include "ingen/EngineBase.hpp" -#include "ingen/FilePath.hpp" -#include "ingen/Forge.hpp" -#include "ingen/InstanceAccess.hpp" -#include "ingen/LV2Features.hpp" -#include "ingen/Library.hpp" -#include "ingen/Log.hpp" -#include "ingen/Module.hpp" -#include "ingen/Parser.hpp" -#include "ingen/Serialiser.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" -#include "ingen/ingen.h" -#include "ingen/runtime_paths.hpp" -#include "lilv/lilv.h" -#include "lv2/log/log.h" -#include "lv2/urid/urid.h" -#include "sord/sordmm.hpp" +#include <ingen/World.hpp> + +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/DataAccess.hpp> +#include <ingen/EngineBase.hpp> +#include <ingen/Forge.hpp> +#include <ingen/InstanceAccess.hpp> +#include <ingen/LV2Features.hpp> +#include <ingen/Library.hpp> +#include <ingen/Log.hpp> +#include <ingen/Module.hpp> +#include <ingen/Parser.hpp> +#include <ingen/Serialiser.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/ingen.h> +#include <ingen/runtime_paths.hpp> +#include <lilv/lilv.h> +#include <lv2/log/log.h> +#include <lv2/urid/urid.h> +#include <sord/sordmm.hpp> #include <cstdint> +#include <filesystem> #include <list> #include <map> #include <memory> @@ -72,6 +72,8 @@ ingen_load_library(Log& log, const string& name) return nullptr; } + log.info("Loading module %1%\n", path); + std::unique_ptr<Library> library = std::make_unique<Library>(path); if (*library) { return library; @@ -88,9 +90,7 @@ class World::Impl { public: Impl(LV2_URID_Map* map, LV2_URID_Unmap* unmap, LV2_Log_Log* log_feature) - : argc(nullptr) - , argv(nullptr) - , lv2_features(nullptr) + : lv2_features(new LV2Features()) , rdf_world(new Sord::World()) , lilv_world(lilv_world_new(), lilv_world_free) , uri_map(log, map, unmap) @@ -99,7 +99,6 @@ public: , conf(forge) , log(log_feature, uris) { - lv2_features = new LV2Features(); lv2_features->add_feature(uri_map.urid_map_feature()); lv2_features->add_feature(uri_map.urid_unmap_feature()); lv2_features->add_feature(std::make_shared<InstanceAccess>()); @@ -185,8 +184,8 @@ public: using LilvWorldUPtr = std::unique_ptr<LilvWorld, decltype(&lilv_world_free)>; - int* argc; - char*** argv; + int* argc{nullptr}; + char*** argv{nullptr}; LV2Features* lv2_features; std::unique_ptr<Sord::World> rdf_world; LilvWorldUPtr lilv_world; @@ -344,7 +343,7 @@ World::load_module(const char* name) if (i != _impl->modules.end()) { return true; } - log().info("Loading %1% module\n", name); + std::unique_ptr<ingen::Library> lib = ingen_load_library(log(), name); ingen::Module* (*module_load)() = @@ -387,8 +386,8 @@ std::shared_ptr<Interface> World::new_interface(const URI& engine_uri, const std::shared_ptr<Interface>& respondee) { - const Impl::InterfaceFactories::const_iterator i = - _impl->interface_factories.find(std::string(engine_uri.scheme())); + const auto i = + _impl->interface_factories.find(std::string{engine_uri.scheme()}); if (i == _impl->interface_factories.end()) { log().warn("Unknown URI scheme `%1%'\n", engine_uri.scheme()); return nullptr; @@ -401,8 +400,7 @@ World::new_interface(const URI& engine_uri, bool World::run(const std::string& mime_type, const std::string& filename) { - const Impl::ScriptRunners::const_iterator i = - _impl->script_runners.find(mime_type); + const auto i = _impl->script_runners.find(mime_type); if (i == _impl->script_runners.end()) { log().warn("Unknown script MIME type `%1%'\n", mime_type); return false; diff --git a/src/client/.clang-tidy b/src/client/.clang-tidy new file mode 100644 index 00000000..2561514f --- /dev/null +++ b/src/client/.clang-tidy @@ -0,0 +1,3 @@ +Checks: > + -google-readability-todo, +InheritParentConfig: true diff --git a/src/client/BlockModel.cpp b/src/client/BlockModel.cpp index cdfb3fcd..beef0117 100644 --- a/src/client/BlockModel.cpp +++ b/src/client/BlockModel.cpp @@ -14,17 +14,21 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/client/BlockModel.hpp" - -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/PluginModel.hpp" -#include "ingen/client/PortModel.hpp" -#include "lilv/lilv.h" -#include "lv2/core/lv2.h" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include <ingen/client/BlockModel.hpp> + +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <lilv/lilv.h> +#include <lv2/core/lv2.h> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> + +#include <sigc++/signal.h> #include <algorithm> #include <cassert> @@ -35,8 +39,7 @@ #include <string> #include <utility> -namespace ingen { -namespace client { +namespace ingen::client { BlockModel::BlockModel(URIs& uris, const std::shared_ptr<PluginModel>& plugin, @@ -47,8 +50,7 @@ BlockModel::BlockModel(URIs& uris, , _num_values(0) , _min_values(nullptr) , _max_values(nullptr) -{ -} +{} BlockModel::BlockModel(URIs& uris, URI plugin_uri, const raul::Path& path) : ObjectModel(uris, path) @@ -56,8 +58,7 @@ BlockModel::BlockModel(URIs& uris, URI plugin_uri, const raul::Path& path) , _num_values(0) , _min_values(nullptr) , _max_values(nullptr) -{ -} +{} BlockModel::BlockModel(const BlockModel& copy) : ObjectModel(copy) @@ -78,23 +79,26 @@ BlockModel::~BlockModel() void BlockModel::remove_port(const std::shared_ptr<PortModel>& port) { - for (auto i = _ports.begin(); i != _ports.end(); ++i) { - if ((*i) == port) { - _ports.erase(i); - break; - } + const auto i = std::find_if(_ports.begin(), + _ports.end(), + [&port](const auto& p) { return p == port; }); + + if (i != _ports.end()) { + _ports.erase(i); + _signal_removed_port.emit(port); } - _signal_removed_port.emit(port); } void BlockModel::remove_port(const raul::Path& port_path) { - for (auto i = _ports.begin(); i != _ports.end(); ++i) { - if ((*i)->path() == port_path) { - _ports.erase(i); - break; - } + const auto i = + std::find_if(_ports.begin(), _ports.end(), [&port_path](const auto& p) { + return p->path() == port_path; + }); + + if (i != _ports.end()) { + _ports.erase(i); } } @@ -206,8 +210,9 @@ BlockModel::default_port_value_range( } if (port->port_property(_uris.lv2_sampleRate)) { - min *= srate; - max *= srate; + const auto frate = static_cast<float>(srate); + min *= frate; + max *= frate; } } @@ -221,7 +226,7 @@ BlockModel::port_value_range(const std::shared_ptr<const PortModel>& port, default_port_value_range(port, min, max); - // Possibly overriden + // Possibly overridden const Atom& min_atom = port->get_property(_uris.lv2_minimum); const Atom& max_atom = port->get_property(_uris.lv2_maximum); if (min_atom.type() == _uris.forge.Float) { @@ -236,8 +241,9 @@ BlockModel::port_value_range(const std::shared_ptr<const PortModel>& port, } if (port->port_property(_uris.lv2_sampleRate)) { - min *= srate; - max *= srate; + const auto frate = static_cast<float>(srate); + min *= frate; + max *= frate; } } @@ -247,11 +253,13 @@ BlockModel::label() const const Atom& name_property = get_property(_uris.lv2_name); if (name_property.type() == _uris.forge.String) { return name_property.ptr<char>(); - } else if (plugin_model()) { + } + + if (plugin_model()) { return plugin_model()->human_name(); - } else { - return symbol().c_str(); } + + return symbol().c_str(); } std::string @@ -293,5 +301,4 @@ BlockModel::set(const std::shared_ptr<ObjectModel>& model) ObjectModel::set(model); } -} // namespace client -} // namespace ingen +} // namespace ingen::client diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp index d8238c8a..9f224db3 100644 --- a/src/client/ClientStore.cpp +++ b/src/client/ClientStore.cpp @@ -14,26 +14,28 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/client/ClientStore.hpp" - -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Log.hpp" -#include "ingen/Node.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/ArcModel.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "ingen/client/PluginModel.hpp" -#include "ingen/client/PortModel.hpp" -#include "ingen/client/SigClientInterface.hpp" -#include "ingen/paths.hpp" -#include "raul/Path.hpp" - -#include <boost/variant/apply_visitor.hpp> +#include <ingen/client/ClientStore.hpp> + +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Log.hpp> +#include <ingen/Message.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ArcModel.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <ingen/client/SigClientInterface.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <sigc++/signal.h> + #include <sigc++/functors/mem_fun.h> #include <cassert> @@ -41,9 +43,9 @@ #include <memory> #include <string> #include <utility> +#include <variant> -namespace ingen { -namespace client { +namespace ingen::client { ClientStore::ClientStore(URIs& uris, Log& log, @@ -76,12 +78,12 @@ ClientStore::add_object(const std::shared_ptr<ObjectModel>& object) std::dynamic_pointer_cast<ObjectModel>(existing->second)->set(object); } else { if (!object->path().is_root()) { - std::shared_ptr<ObjectModel> parent = _object(object->path().parent()); + const std::shared_ptr<ObjectModel> parent = _object(object->path().parent()); if (parent) { assert(object->path().is_child_of(parent->path())); object->set_parent(parent); parent->add_child(object); - assert(parent && (object->parent() == parent)); + assert(object->parent() == parent); (*this)[object->path()] = object; _signal_new_object.emit(object); @@ -103,7 +105,7 @@ std::shared_ptr<ObjectModel> ClientStore::remove_object(const raul::Path& path) { // Find the object, the "top" of the tree to remove - const iterator top = find(path); + const auto top = find(path); if (top == end()) { return nullptr; } @@ -142,7 +144,7 @@ ClientStore::remove_object(const raul::Path& path) std::shared_ptr<PluginModel> ClientStore::_plugin(const URI& uri) { - const Plugins::iterator i = _plugins->find(uri); + const auto i = _plugins->find(uri); return (i == _plugins->end()) ? std::shared_ptr<PluginModel>() : (*i).second; } @@ -152,7 +154,7 @@ ClientStore::_plugin(const Atom& uri) /* FIXME: Should probably be stored with URIs rather than strings, to make this a fast case. */ - const Plugins::iterator i = _plugins->find(URI(_uris.forge.str(uri, false))); + const auto i = _plugins->find(URI(_uris.forge.str(uri, false))); return (i == _plugins->end()) ? std::shared_ptr<PluginModel>() : (*i).second; } @@ -165,15 +167,15 @@ ClientStore::plugin(const URI& uri) const std::shared_ptr<ObjectModel> ClientStore::_object(const raul::Path& path) { - const iterator i = find(path); + const auto i = find(path); if (i == end()) { return nullptr; - } else { - auto model = std::dynamic_pointer_cast<ObjectModel>(i->second); - assert(model); - assert(model->path().is_root() || model->parent()); - return model; } + + auto model = std::dynamic_pointer_cast<ObjectModel>(i->second); + assert(model); + assert(model->path().is_root() || model->parent()); + return model; } std::shared_ptr<const ObjectModel> @@ -187,9 +189,9 @@ ClientStore::_resource(const URI& uri) { if (uri_is_path(uri)) { return _object(uri_to_path(uri)); - } else { - return _plugin(uri); } + + return _plugin(uri); } std::shared_ptr<const Resource> @@ -201,7 +203,7 @@ ClientStore::resource(const URI& uri) const void ClientStore::add_plugin(const std::shared_ptr<PluginModel>& pm) { - std::shared_ptr<PluginModel> existing = _plugin(pm->uri()); + const std::shared_ptr<PluginModel> existing = _plugin(pm->uri()); if (existing) { existing->set(pm); } else { @@ -235,7 +237,7 @@ ClientStore::operator()(const Copy&) void ClientStore::operator()(const Move& msg) { - const iterator top = find(msg.old_path); + const auto top = find(msg.old_path); if (top != end()) { rename(top, msg.new_path); } @@ -244,14 +246,12 @@ ClientStore::operator()(const Move& msg) void ClientStore::message(const Message& msg) { - boost::apply_visitor(*this, msg); + std::visit(*this, msg); } void ClientStore::operator()(const Put& msg) { - using Iterator = Properties::const_iterator; - const auto& uri = msg.uri; const auto& properties = msg.properties; @@ -263,12 +263,12 @@ ClientStore::operator()(const Put& msg) is_graph, is_block, is_port, is_output); // Check for specially handled types - const Iterator t = properties.find(_uris.rdf_type); + const auto t = properties.find(_uris.rdf_type); if (t != properties.end()) { const Atom& type(t->second); if (_uris.pset_Preset == type) { - const Iterator p = properties.find(_uris.lv2_appliesTo); - const Iterator l = properties.find(_uris.rdfs_label); + const auto p = properties.find(_uris.lv2_appliesTo); + const auto l = properties.find(_uris.rdfs_label); std::shared_ptr<PluginModel> plug; if (p == properties.end()) { _log.error("Preset <%1%> with no plugin\n", uri.c_str()); @@ -283,10 +283,12 @@ ClientStore::operator()(const Put& msg) plug->add_preset(uri, l->second.ptr<char>()); } return; - } else if (_uris.ingen_Graph == type) { + } + + if (_uris.ingen_Graph == type) { is_graph = true; } else if (_uris.ingen_Internal == type || _uris.lv2_Plugin == type) { - std::shared_ptr<PluginModel> p(new PluginModel(uris(), uri, type, properties)); + const std::shared_ptr<PluginModel> p{new PluginModel(uris(), uri, type, properties)}; add_plugin(p); return; } @@ -310,7 +312,7 @@ ClientStore::operator()(const Put& msg) } if (is_graph) { - std::shared_ptr<GraphModel> model(new GraphModel(uris(), path)); + const std::shared_ptr<GraphModel> model{new GraphModel(uris(), path)}; model->set_properties(properties); add_object(model); } else if (is_block) { @@ -331,23 +333,23 @@ ClientStore::operator()(const Put& msg) add_plugin(plug); } - std::shared_ptr<BlockModel> bm(new BlockModel(uris(), plug, path)); + const std::shared_ptr<BlockModel> bm{new BlockModel(uris(), plug, path)}; bm->set_properties(properties); add_object(bm); } else { _log.warn("Block %1% has no prototype\n", path.c_str()); } } else if (is_port) { - PortModel::Direction pdir = (is_output) + const PortModel::Direction pdir = (is_output) ? PortModel::Direction::OUTPUT : PortModel::Direction::INPUT; - uint32_t index = 0; - const Iterator i = properties.find(_uris.lv2_index); + uint32_t index = 0; + const auto i = properties.find(_uris.lv2_index); if (i != properties.end() && i->second.type() == _uris.forge.Int) { index = i->second.get<int32_t>(); } - std::shared_ptr<PortModel> p(new PortModel(uris(), path, index, pdir)); + const std::shared_ptr<PortModel> p{new PortModel(uris(), path, index, pdir)}; p->set_properties(properties); add_object(p); } else { @@ -371,7 +373,7 @@ ClientStore::operator()(const Delta& msg) const raul::Path path(uri_to_path(uri)); - std::shared_ptr<ObjectModel> obj = _object(path); + const std::shared_ptr<ObjectModel> obj = _object(path); if (obj) { obj->remove_properties(msg.remove); obj->add_properties(msg.add); @@ -392,7 +394,7 @@ ClientStore::operator()(const SetProperty& msg) predicate.c_str(), _uris.forge.str(value, false)); return; } - std::shared_ptr<Resource> subject = _resource(subject_uri); + const std::shared_ptr<Resource> subject = _resource(subject_uri); if (subject) { if (predicate == _uris.ingen_activity) { /* Activity is transient, trigger any live actions (like GUI @@ -402,7 +404,7 @@ ClientStore::operator()(const SetProperty& msg) subject->set_property(predicate, value, msg.ctx); } } else { - std::shared_ptr<PluginModel> plugin = _plugin(subject_uri); + const std::shared_ptr<PluginModel> plugin = _plugin(subject_uri); if (plugin) { plugin->set_property(predicate, value); } else if (predicate != _uris.ingen_activity) { @@ -450,14 +452,14 @@ ClientStore::attempt_connection(const raul::Path& tail_path, auto head = std::dynamic_pointer_cast<PortModel>(_object(head_path)); if (tail && head) { - std::shared_ptr<GraphModel> graph = connection_graph(tail_path, head_path); - std::shared_ptr<ArcModel> arc(new ArcModel(tail, head)); + const std::shared_ptr<GraphModel> graph = connection_graph(tail_path, head_path); + const std::shared_ptr<ArcModel> arc(new ArcModel(tail, head)); graph->add_arc(arc); return true; - } else { - _log.warn("Failed to connect %1% => %2%\n", tail_path, head_path); - return false; } + + _log.warn("Failed to connect %1% => %2%\n", tail_path, head_path); + return false; } void @@ -501,5 +503,4 @@ ClientStore::operator()(const DisconnectAll& msg) } } -} // namespace client -} // namespace ingen +} // namespace ingen::client diff --git a/src/client/GraphModel.cpp b/src/client/GraphModel.cpp index d4104742..fe119361 100644 --- a/src/client/GraphModel.cpp +++ b/src/client/GraphModel.cpp @@ -14,15 +14,17 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/client/GraphModel.hpp" - -#include "ingen/Atom.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/ArcModel.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "ingen/client/PortModel.hpp" -#include "raul/Path.hpp" +#include <ingen/client/GraphModel.hpp> + +#include <ingen/Atom.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ArcModel.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <raul/Path.hpp> +#include <sigc++/signal.h> #include <cassert> #include <map> @@ -31,7 +33,15 @@ #include <utility> namespace ingen { -namespace client { +class Node; +} // namespace ingen + +namespace ingen::client { + +GraphModel::GraphModel(URIs& uris, const raul::Path& graph_path) + : BlockModel{uris, static_cast<const URI&>(uris.ingen_Graph), graph_path} +{ +} void GraphModel::add_child(const std::shared_ptr<ObjectModel>& c) @@ -75,7 +85,7 @@ GraphModel::remove_arcs_on(const std::shared_ptr<PortModel>& p) { // Remove any connections which referred to this object, // since they can't possibly exist anymore - for (auto j = _arcs.begin(); j != _arcs.end();) { + for (auto j = _graph_arcs.begin(); j != _graph_arcs.end();) { auto next = j; ++next; @@ -85,7 +95,7 @@ GraphModel::remove_arcs_on(const std::shared_ptr<PortModel>& p) || arc->head_path().parent() == p->path() || arc->head_path() == p->path()) { _signal_removed_arc.emit(arc); - _arcs.erase(j); // Cuts our reference + _graph_arcs.erase(j); // Cuts our reference } j = next; } @@ -94,23 +104,23 @@ GraphModel::remove_arcs_on(const std::shared_ptr<PortModel>& p) void GraphModel::clear() { - _arcs.clear(); + _graph_arcs.clear(); BlockModel::clear(); - assert(_arcs.empty()); + assert(_graph_arcs.empty()); assert(_ports.empty()); } std::shared_ptr<ArcModel> GraphModel::get_arc(const Node* tail, const Node* head) { - auto i = _arcs.find(std::make_pair(tail, head)); - if (i != _arcs.end()) { + auto i = _graph_arcs.find(std::make_pair(tail, head)); + if (i != _graph_arcs.end()) { return std::dynamic_pointer_cast<ArcModel>(i->second); - } else { - return nullptr; } + + return nullptr; } /** Add a connection to this graph. @@ -135,15 +145,16 @@ GraphModel::add_arc(const std::shared_ptr<ArcModel>& arc) assert(arc->head()->parent().get() == this || arc->head()->parent()->parent().get() == this); - std::shared_ptr<ArcModel> existing = get_arc( + const std::shared_ptr<ArcModel> existing = get_arc( arc->tail().get(), arc->head().get()); if (existing) { assert(arc->tail() == existing->tail()); assert(arc->head() == existing->head()); } else { - _arcs.emplace(std::make_pair(arc->tail().get(), arc->head().get()), - arc); + _graph_arcs.emplace(std::make_pair(arc->tail().get(), + arc->head().get()), + arc); _signal_new_arc.emit(arc); } } @@ -151,11 +162,11 @@ GraphModel::add_arc(const std::shared_ptr<ArcModel>& arc) void GraphModel::remove_arc(const Node* tail, const Node* head) { - auto i = _arcs.find(std::make_pair(tail, head)); - if (i != _arcs.end()) { + auto i = _graph_arcs.find(std::make_pair(tail, head)); + if (i != _graph_arcs.end()) { auto arc = std::dynamic_pointer_cast<ArcModel>(i->second); _signal_removed_arc.emit(arc); - _arcs.erase(i); + _graph_arcs.erase(i); } } @@ -173,12 +184,4 @@ GraphModel::internal_poly() const return poly.is_valid() ? poly.get<int32_t>() : 1; } -bool -GraphModel::polyphonic() const -{ - const Atom& poly = get_property(_uris.ingen_polyphonic); - return poly.is_valid() && poly.get<int32_t>(); -} - -} // namespace client -} // namespace ingen +} // namespace ingen::client diff --git a/src/client/ObjectModel.cpp b/src/client/ObjectModel.cpp index c172c445..4baa895c 100644 --- a/src/client/ObjectModel.cpp +++ b/src/client/ObjectModel.cpp @@ -14,14 +14,17 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/client/ObjectModel.hpp" - -#include "ingen/Atom.hpp" -#include "ingen/Node.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URIs.hpp" -#include "ingen/paths.hpp" +#include <ingen/client/ObjectModel.hpp> + +#include <ingen/Atom.hpp> +#include <ingen/Node.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URIs.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> +#include <sigc++/signal.h> #include <cassert> #include <cstdint> @@ -29,23 +32,20 @@ #include <string> #include <utility> -namespace ingen { -namespace client { +namespace ingen::client { ObjectModel::ObjectModel(URIs& uris, const raul::Path& path) : Node(uris, path) , _path(path) , _symbol((path == "/") ? "root" : path.symbol()) -{ -} +{} ObjectModel::ObjectModel(const ObjectModel& copy) : Node(copy) , _parent(copy._parent) , _path(copy._path) , _symbol(copy._symbol) -{ -} +{} bool ObjectModel::is_a(const URIs::Quark& type) const @@ -115,5 +115,4 @@ ObjectModel::set_parent(const std::shared_ptr<ObjectModel>& p) _parent = p; } -} // namespace client -} // namespace ingen +} // namespace ingen::client diff --git a/src/client/PluginModel.cpp b/src/client/PluginModel.cpp index 4dddd147..f4dfccd2 100644 --- a/src/client/PluginModel.cpp +++ b/src/client/PluginModel.cpp @@ -14,25 +14,29 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/client/PluginModel.hpp" - -#include "ingen/Atom.hpp" -#include "ingen/client/PluginUI.hpp" -#include "lv2/core/lv2.h" - -#include <boost/optional/optional.hpp> +#include <ingen/client/PluginModel.hpp> + +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/PluginUI.hpp> +#include <lilv/lilv.h> +#include <lv2/core/lv2.h> +#include <raul/Symbol.hpp> +#include <sigc++/signal.h> #include <cctype> #include <cstring> -#include <iosfwd> #include <memory> #include <string> #include <utility> using std::string; -namespace ingen { -namespace client { +namespace ingen::client { LilvWorld* PluginModel::_lilv_world = nullptr; const LilvPlugins* PluginModel::_lilv_plugins = nullptr; @@ -45,13 +49,12 @@ PluginModel::PluginModel(URIs& uris, const Properties& properties) : Resource(uris, uri) , _type(type) - , _fetched(false) { if (!_type.is_valid()) { if (uri.string().find("ingen-internals") != string::npos) { _type = uris.ingen_Internal.urid_atom(); } else { - _type = uris.lv2_Plugin.urid_atom(); // Assume LV2 and hope for the best... + _type = uris.lv2_Plugin.urid_atom(); // Assume LV2 and hope for the best... } } @@ -106,37 +109,43 @@ PluginModel::get_property(const URI& key) const size_t last_delim = last_uri_delim(str); while (last_delim != string::npos && !contains_alpha_after(str, last_delim)) { - str = str.substr(0, last_delim); + str.resize(last_delim); last_delim = last_uri_delim(str); } str = str.substr(last_delim + 1); - std::string symbol = raul::Symbol::symbolify(str); + const std::string symbol = raul::Symbol::symbolify(str); set_property(_uris.lv2_symbol, _uris.forge.alloc(symbol)); return get_property(key); } if (_lilv_plugin) { - boost::optional<const Atom&> ret; - LilvNode* lv2_pred = lilv_new_uri(_lilv_world, key.c_str()); - LilvNodes* values = lilv_plugin_get_value(_lilv_plugin, lv2_pred); + const Atom* ret = nullptr; + LilvNode* lv2_pred = lilv_new_uri(_lilv_world, key.c_str()); + LilvNodes* values = lilv_plugin_get_value(_lilv_plugin, lv2_pred); lilv_node_free(lv2_pred); - LILV_FOREACH(nodes, i, values) { + LILV_FOREACH (nodes, i, values) { const LilvNode* value = lilv_nodes_get(values, i); if (lilv_node_is_uri(value)) { - ret = set_property( + ret = &set_property( key, _uris.forge.make_urid(URI(lilv_node_as_uri(value)))); break; - } else if (lilv_node_is_string(value)) { - ret = set_property( + } + + if (lilv_node_is_string(value)) { + ret = &set_property( key, _uris.forge.alloc(lilv_node_as_string(value))); break; - } else if (lilv_node_is_float(value)) { - ret = set_property( + } + + if (lilv_node_is_float(value)) { + ret = &set_property( key, _uris.forge.make(lilv_node_as_float(value))); break; - } else if (lilv_node_is_int(value)) { - ret = set_property( + } + + if (lilv_node_is_int(value)) { + ret = &set_property( key, _uris.forge.make(lilv_node_as_int(value))); break; } @@ -181,9 +190,9 @@ PluginModel::default_block_symbol() const const Atom& name_atom = get_property(_uris.lv2_symbol); if (name_atom.is_valid() && name_atom.type() == _uris.forge.String) { return raul::Symbol::symbolify(name_atom.ptr<char>()); - } else { - return raul::Symbol("_"); } + + return raul::Symbol("_"); } string @@ -192,9 +201,9 @@ PluginModel::human_name() const const Atom& name_atom = get_property(_uris.doap_name); if (name_atom.type() == _uris.forge.String) { return name_atom.ptr<char>(); - } else { - return default_block_symbol().c_str(); } + + return default_block_symbol().c_str(); } string @@ -218,7 +227,7 @@ PluginModel::port_scale_points(const uint32_t index) const if (_lilv_plugin) { const LilvPort* port = lilv_plugin_get_port_by_index(_lilv_plugin, index); LilvScalePoints* sp = lilv_port_get_scale_points(_lilv_plugin, port); - LILV_FOREACH(scale_points, i, sp) { + LILV_FOREACH (scale_points, i, sp) { const LilvScalePoint* p = lilv_scale_points_get(sp, i); points.emplace( lilv_node_as_float(lilv_scale_point_get_value(p)), @@ -257,9 +266,9 @@ heading(const std::string& text, bool html, unsigned level) if (html) { const std::string tag = std::string("h") + std::to_string(level); return std::string("<") + tag + ">" + text + "</" + tag + ">\n"; - } else { - return text + ":\n\n"; } + + return text + ":\n\n"; } static std::string @@ -267,9 +276,9 @@ link(const std::string& addr, bool html) { if (html) { return std::string("<a href=\"") + addr + "\">" + addr + "</a>"; - } else { - return addr; } + + return addr; } std::string @@ -357,5 +366,4 @@ PluginModel::set_lilv_world(LilvWorld* world) _lilv_plugins = lilv_world_get_all_plugins(_lilv_world); } -} // namespace client -} // namespace ingen +} // namespace ingen::client diff --git a/src/client/PluginUI.cpp b/src/client/PluginUI.cpp index 7292d8b2..c4aa748f 100644 --- a/src/client/PluginUI.cpp +++ b/src/client/PluginUI.cpp @@ -14,20 +14,24 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/client/PluginUI.hpp" - -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Log.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/PortModel.hpp" -#include "lv2/atom/atom.h" -#include "lv2/core/lv2.h" -#include "lv2/ui/ui.h" -#include "raul/Symbol.hpp" +#include <ingen/client/PluginUI.hpp> + +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/LV2Features.hpp> +#include <ingen/Log.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <lilv/lilv.h> +#include <lv2/atom/atom.h> +#include <lv2/core/lv2.h> +#include <lv2/ui/ui.h> +#include <raul/Symbol.hpp> +#include <suil/suil.h> #include <sigc++/signal.h> @@ -36,8 +40,7 @@ #include <string> #include <utility> -namespace ingen { -namespace client { +namespace ingen::client { SuilHost* PluginUI::ui_host = nullptr; @@ -78,7 +81,7 @@ lv2_ui_write(SuilController controller, const float value = *static_cast<const float*>(buffer); if (port->value().type() == uris.atom_Float && value == port->value().get<float>()) { - return; // Ignore feedback + return; // Ignore feedback } ui->signal_property_changed()( @@ -89,9 +92,9 @@ lv2_ui_write(SuilController controller, } else if (format == uris.atom_eventTransfer.urid()) { const auto* atom = static_cast<const LV2_Atom*>(buffer); - Atom val = Forge::alloc(atom->size, - atom->type, - LV2_ATOM_BODY_CONST(atom)); + const Atom val = + Forge::alloc(atom->size, atom->type, LV2_ATOM_BODY_CONST(atom)); + ui->signal_property_changed()(port->uri(), uris.ingen_activity, val, @@ -123,8 +126,8 @@ lv2_ui_subscribe(SuilController controller, uint32_t protocol, const LV2_Feature* const* features) { - auto* const ui = static_cast<PluginUI*>(controller); - std::shared_ptr<const PortModel> port = get_port(ui, port_index); + auto* const ui = static_cast<PluginUI*>(controller); + const std::shared_ptr<const PortModel> port = get_port(ui, port_index); if (!port) { return 1; } @@ -166,17 +169,15 @@ PluginUI::PluginUI(ingen::World& world, const LilvNode* ui_type) : _world(world) , _block(std::move(block)) - , _instance(nullptr) , _uis(uis) , _ui(ui) , _ui_node(lilv_node_duplicate(lilv_ui_get_uri(ui))) , _ui_type(lilv_node_duplicate(ui_type)) -{ -} +{} PluginUI::~PluginUI() { - for (uint32_t i : _subscribed_ports) { + for (const uint32_t i : _subscribed_ports) { lv2_ui_unsubscribe(this, i, 0, nullptr); } suil_instance_free(_instance); @@ -205,7 +206,7 @@ PluginUI::create(ingen::World& world, LilvUIs* uis = lilv_plugin_get_uis(plugin); const LilvUI* ui = nullptr; const LilvNode* ui_type = nullptr; - LILV_FOREACH(uis, u, uis) { + LILV_FOREACH (uis, u, uis) { const LilvUI* this_ui = lilv_uis_get(uis, u); if (lilv_ui_is_supported(this_ui, suil_ui_supported, @@ -247,7 +248,7 @@ PluginUI::instantiate() LilvNode* ui_plugin = lilv_new_uri(lworld, LV2_UI__plugin); LilvNodes* notes = lilv_world_find_nodes( lworld, lilv_ui_get_uri(_ui), ui_portNotification, nullptr); - LILV_FOREACH(nodes, n, notes) { + LILV_FOREACH (nodes, n, notes) { const LilvNode* note = lilv_nodes_get(notes, n); const LilvNode* sym = lilv_world_get(lworld, note, uris.lv2_symbol, nullptr); const LilvNode* plug = lilv_world_get(lworld, note, ui_plugin, nullptr); @@ -262,7 +263,7 @@ PluginUI::instantiate() plugin_uri, lilv_node_as_string(_ui_node)); } else if (!strcmp(lilv_node_as_uri(plug), plugin_uri.c_str())) { // Notification is valid and for this plugin - uint32_t index = lv2_ui_port_index(this, lilv_node_as_string(sym)); + const uint32_t index = lv2_ui_port_index(this, lilv_node_as_string(sym)); if (index != LV2UI_INVALID_PORT_INDEX) { lv2_ui_subscribe(this, index, 0, nullptr); _subscribed_ports.insert(index); @@ -296,7 +297,7 @@ PluginUI::instantiate() if (!_instance) { _world.log().error("Failed to instantiate LV2 UI\n"); // Cancel any subscriptions - for (uint32_t i : _subscribed_ports) { + for (const uint32_t i : _subscribed_ports) { lv2_ui_unsubscribe(this, i, 0, nullptr); } return false; @@ -346,5 +347,4 @@ PluginUI::is_resizable() const return !fs_matches && !nrs_matches; } -} // namespace client -} // namespace ingen +} // namespace ingen::client diff --git a/src/client/PortModel.cpp b/src/client/PortModel.cpp index 0d695a54..14a5297e 100644 --- a/src/client/PortModel.cpp +++ b/src/client/PortModel.cpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2015 David Robillard <http://drobilla.net/> + Copyright 2007-2024 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -14,21 +14,22 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/client/PortModel.hpp" +#include <ingen/client/PortModel.hpp> -#include "ingen/Properties.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "lv2/urid/urid.h" +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <lv2/urid/urid.h> +#include <sigc++/signal.h> +#include <algorithm> #include <cstdint> +#include <exception> #include <map> #include <memory> -#include <utility> -namespace ingen { -namespace client { +namespace ingen::client { void PortModel::on_property(const URI& uri, const Atom& value) @@ -61,14 +62,24 @@ PortModel::port_property(const URIs::Quark& uri) const bool PortModel::is_uri() const { - // FIXME: Resource::has_property doesn't work, URI != URID - for (const auto& p : properties()) { - if (p.second.type() == _uris.atom_URID && - static_cast<LV2_URID>(p.second.get<int32_t>()) == _uris.atom_URID) { - return true; - } - } - return false; + return std::any_of( + properties().begin(), properties().end(), [this](const auto& p) { + return (p.second.type() == _uris.atom_URID && + static_cast<LV2_URID>(p.second.template get<int32_t>()) == + _uris.atom_URID); + }); +} + +void +PortModel::add_child(const std::shared_ptr<ObjectModel>&) +{ + std::terminate(); +} + +bool +PortModel::remove_child(const std::shared_ptr<ObjectModel>&) +{ + std::terminate(); } void @@ -84,5 +95,4 @@ PortModel::set(const std::shared_ptr<ObjectModel>& model) } } -} // namespace client -} // namespace ingen +} // namespace ingen::client diff --git a/src/client/ingen_client.cpp b/src/client/ingen_client.cpp index f4d6bbc7..88619115 100644 --- a/src/client/ingen_client.cpp +++ b/src/client/ingen_client.cpp @@ -14,24 +14,19 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Module.hpp" +#include <ingen/Module.hpp> -namespace ingen { - -class World; - -namespace client { +namespace ingen::client { struct ClientModule : public ingen::Module { void load(ingen::World& world) override {} }; -} // namespace client -} // namespace ingen +} // namespace ingen::client extern "C" { -ingen::Module* +INGEN_MODULE_EXPORT ingen::Module* ingen_module_load() { return new ingen::client::ClientModule(); diff --git a/src/client/meson.build b/src/client/meson.build new file mode 100644 index 00000000..7c040634 --- /dev/null +++ b/src/client/meson.build @@ -0,0 +1,50 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +################ +# Dependencies # +################ + +sigcpp_dep = dependency('sigc++-2.0', include_type: 'system') + +########## +# Module # +########## + +client_sources = files( + 'BlockModel.cpp', + 'ClientStore.cpp', + 'GraphModel.cpp', + 'ObjectModel.cpp', + 'PluginModel.cpp', + 'PluginUI.cpp', + 'PortModel.cpp', + 'ingen_client.cpp', +) + +client_dependencies = [ + boost_dep, + ingen_dep, + lilv_dep, + lv2_dep, + raul_dep, + sigcpp_dep, + suil_dep, +] + +libingen_client = shared_library( + 'ingen_client', + client_sources, + cpp_args: cpp_suppressions + platform_defines + ['-DINGEN_CLIENT_INTERNAL'], + dependencies: client_dependencies, + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: ingen_module_dir, +) + +ingen_client_dep = declare_dependency( + dependencies: client_dependencies, + link_with: libingen_client, +) diff --git a/src/client/wscript b/src/client/wscript deleted file mode 100644 index d63fb56c..00000000 --- a/src/client/wscript +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python - - -def build(bld): - obj = bld(features = 'cxx cxxshlib', - cflags = ['-fvisibility=hidden'], - includes = ['../../', '../../include'], - export_includes = ['../../include'], - name = 'libingen_client', - target = 'ingen_client', - install_path = '${LIBDIR}', - use = 'libingen', - uselib = 'GLIBMM LV2 LILV SUIL RAUL SERD SORD SIGCPP') - - obj.source = ''' - BlockModel.cpp - ClientStore.cpp - GraphModel.cpp - ObjectModel.cpp - PluginModel.cpp - PluginUI.cpp - PortModel.cpp - ingen_client.cpp - ''' diff --git a/src/gui/.clang-tidy b/src/gui/.clang-tidy index 7f216d2c..99bd2aba 100644 --- a/src/gui/.clang-tidy +++ b/src/gui/.clang-tidy @@ -1,74 +1,29 @@ Checks: > - *, - -*-avoid-c-arrays, - -*-else-after-return, - -*-magic-numbers, - -*-member-init, - -*-named-parameter, -*-narrowing-conversions, - -*-non-private-member-variables-in-classes, - -*-special-member-functions, - -*-uppercase-literal-suffix, - -abseil-string-find-str-contains, -android-cloexec-*, -bugprone-branch-clone, -bugprone-exception-escape, -bugprone-macro-parentheses, -bugprone-parent-virtual-call, -bugprone-reserved-identifier, - -bugprone-signed-char-misuse, -bugprone-suspicious-string-compare, -cert-dcl21-cpp, -cert-dcl37-c, - -cert-dcl50-cpp, -cert-dcl51-cpp, - -cert-err34-c, -cert-err58-cpp, -cert-str34-c, - -clang-analyzer-alpha.*, -clang-analyzer-core.CallAndMessage, - -clang-analyzer-optin.cplusplus.VirtualCall, - -clang-analyzer-valist.Uninitialized, - -cppcoreguidelines-avoid-non-const-global-variables, -cppcoreguidelines-macro-usage, - -cppcoreguidelines-no-malloc, - -cppcoreguidelines-owning-memory, - -cppcoreguidelines-pro-bounds-array-to-pointer-decay, -cppcoreguidelines-pro-bounds-constant-array-index, - -cppcoreguidelines-pro-bounds-pointer-arithmetic, - -cppcoreguidelines-pro-type-const-cast, - -cppcoreguidelines-pro-type-cstyle-cast, - -cppcoreguidelines-pro-type-reinterpret-cast, -cppcoreguidelines-pro-type-static-cast-downcast, - -cppcoreguidelines-pro-type-union-access, -cppcoreguidelines-pro-type-vararg, -cppcoreguidelines-slicing, - -fuchsia-*, -google-default-arguments, - -google-explicit-constructor, -google-readability-todo, -google-runtime-int, -google-runtime-references, - -hicpp-explicit-conversions, -hicpp-multiway-paths-covered, - -hicpp-no-array-decay, - -hicpp-no-malloc, - -hicpp-signed-bitwise, -hicpp-vararg, -llvm-header-guard, - -llvmlibc-*, - -misc-no-recursion, - -misc-unused-parameters, - -modernize-use-trailing-return-type, -readability-convert-member-functions-to-static, - -readability-implicit-bool-conversion, - -readability-use-anyofallof, -CheckOptions: - - key: modernize-use-override.AllowOverrideAndFinal - value: 'true' -CheckOptions: - - key: cppcoreguidelines-explicit-virtual-functions.AllowOverrideAndFinal - value: 'true' -WarningsAsErrors: '*' -HeaderFilterRegex: 'include/ingen/.*|tests/.*|src/.*' -FormatStyle: file +InheritParentConfig: true diff --git a/src/gui/App.cpp b/src/gui/App.cpp index dc51df1d..260afdba 100644 --- a/src/gui/App.cpp +++ b/src/gui/App.cpp @@ -27,31 +27,37 @@ #include "WindowFactory.hpp" #include "rgba.hpp" -#include "ingen/Atom.hpp" -#include "ingen/ColorContext.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/EngineBase.hpp" -#include "ingen/FilePath.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/QueuedInterface.hpp" -#include "ingen/StreamWriter.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/PluginModel.hpp" -#include "ingen/client/PortModel.hpp" -#include "ingen/client/SigClientInterface.hpp" -#include "ingen/runtime_paths.hpp" -#include "lilv/lilv.h" -#include "suil/suil.h" - -#include <boost/variant/get.hpp> +#include <ingen/Atom.hpp> +#include <ingen/ColorContext.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/EngineBase.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Message.hpp> +#include <ingen/Properties.hpp> +#include <ingen/QueuedInterface.hpp> +#include <ingen/Resource.hpp> +#include <ingen/Status.hpp> +#include <ingen/StreamWriter.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <ingen/client/SigClientInterface.hpp> +#include <ingen/fmt.hpp> +#include <ingen/runtime_paths.hpp> +#include <lilv/lilv.h> +#include <lv2/urid/urid.h> +#include <suil/suil.h> + #include <glib.h> #include <glibmm/main.h> #include <glibmm/miscutils.h> #include <glibmm/propertyproxy.h> +#include <glibmm/ustring.h> #include <gtk/gtk.h> #include <gtkmm/aboutdialog.h> #include <gtkmm/dialog.h> @@ -62,20 +68,21 @@ #include <gtkmm/stock.h> #include <gtkmm/widget.h> #include <sigc++/functors/mem_fun.h> +#include <sigc++/functors/slot.h> #include <algorithm> #include <cassert> +#include <cstdarg> #include <cstdio> #include <exception> -#include <functional> #include <iostream> #include <map> #include <memory> #include <string> #include <utility> +#include <variant> -namespace ingen { -namespace gui { +namespace ingen::gui { Gtk::Main* App::_main = nullptr; @@ -83,15 +90,6 @@ App::App(ingen::World& world) : _style(new Style(*this)) , _window_factory(new WindowFactory(*this)) , _world(world) - , _sample_rate(48000) - , _block_length(1024) - , _n_threads(1) - , _mean_run_load(0.0f) - , _min_run_load(0.0f) - , _max_run_load(0.0f) - , _enable_signal(true) - , _requested_plugins(false) - , _is_plugin(false) { _world.conf().load_default("ingen", "gui.ttl"); @@ -108,11 +106,10 @@ App::App(ingen::World& world) client::PluginModel::set_rdf_world(*world.rdf_world()); client::PluginModel::set_lilv_world(world.lilv_world()); - world.log().set_sink(std::bind(&MessagesWindow::log, - _messages_window, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3)); + world.log().set_sink( + [this](const LV2_URID type, const char* fmt, va_list args) { + return _messages_window->log(type, fmt, args); + }); } App::~App() @@ -248,13 +245,13 @@ App::serialiser() void App::message(const Message& msg) { - if (const Response* const r = boost::get<Response>(&msg)) { + if (const Response* const r = std::get_if<Response>(&msg)) { response(r->id, r->status, r->subject); - } else if (const Error* const e = boost::get<Error>(&msg)) { + } else if (const Error* const e = std::get_if<Error>(&msg)) { error_message(e->message); - } else if (const Put* const p = boost::get<Put>(&msg)) { + } else if (const Put* const p = std::get_if<Put>(&msg)) { put(p->uri, p->properties, p->ctx); - } else if (const SetProperty* const s = boost::get<SetProperty>(&msg)) { + } else if (const SetProperty* const s = std::get_if<SetProperty>(&msg)) { property_change(s->subject, s->predicate, s->value, s->ctx); } } @@ -326,7 +323,9 @@ App::property_change(const URI& subject, { if (subject != URI("ingen:/engine")) { return; - } else if (key == uris().param_sampleRate && value.type() == forge().Int) { + } + + if (key == uris().param_sampleRate && value.type() == forge().Int) { _sample_rate = value.get<int32_t>(); } else if (key == uris().bufsz_maxBlockLength && value.type() == forge().Int) { _block_length = value.get<int32_t>(); @@ -376,7 +375,7 @@ App::status_text() const void App::port_activity(Port* port) { - std::pair<ActivityPorts::iterator, bool> inserted = _activity_ports.emplace(port, false); + const auto inserted = _activity_ports.emplace(port, false); if (inserted.second) { inserted.first->second = false; } @@ -509,5 +508,4 @@ App::sample_rate() const return _sample_rate; } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/App.hpp b/src/gui/App.hpp index c09d1cd5..0138f25a 100644 --- a/src/gui/App.hpp +++ b/src/gui/App.hpp @@ -17,14 +17,13 @@ #ifndef INGEN_GUI_APP_HPP #define INGEN_GUI_APP_HPP -#include "ingen/Message.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/Status.hpp" -#include "ingen/URI.hpp" -#include "ingen/World.hpp" -#include "ingen/ingen.h" -#include "lilv/lilv.h" +#include <ingen/Message.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/World.hpp> +#include <ingen/ingen.h> +#include <lilv/lilv.h> #include <sigc++/signal.h> @@ -42,6 +41,8 @@ class Window; namespace ingen { +enum class Status; + class Atom; class Forge; class Interface; @@ -76,6 +77,11 @@ class INGEN_API App public: ~App(); + App(const App&) = delete; + App& operator=(const App&) = delete; + App(App&&) = delete; + App& operator=(App&&) = delete; + void error_message(const std::string& str); void attach(const std::shared_ptr<ingen::Interface>& client); @@ -97,7 +103,7 @@ public: bool signal() const { return _enable_signal; } void enable_signals(bool b) { _enable_signal = b; } bool disable_signals() { - bool old = _enable_signal; + const bool old = _enable_signal; _enable_signal = false; return old; } @@ -139,9 +145,9 @@ public: sigc::signal<void, const std::string&> signal_status_text_changed; - inline ingen::World& world() const { return _world; } - inline ingen::URIs& uris() const { return _world.uris(); } - inline ingen::Log& log() const { return _world.log(); } + ingen::World& world() const { return _world; } + ingen::URIs& uris() const { return _world.uris(); } + ingen::Log& log() const { return _world.log(); } protected: explicit App(ingen::World& world); @@ -177,20 +183,20 @@ protected: ingen::World& _world; - int32_t _sample_rate; - int32_t _block_length; - int32_t _n_threads; - float _mean_run_load; - float _min_run_load; - float _max_run_load; + int32_t _sample_rate{48000}; + int32_t _block_length{1024}; + int32_t _n_threads{1}; + float _mean_run_load{0.0f}; + float _min_run_load{0.0f}; + float _max_run_load{0.0f}; std::string _status_text; using ActivityPorts = std::unordered_map<Port*, bool>; ActivityPorts _activity_ports; - bool _enable_signal; - bool _requested_plugins; - bool _is_plugin; + bool _enable_signal{true}; + bool _requested_plugins{false}; + bool _is_plugin{false}; }; } // namespace gui diff --git a/src/gui/Arc.cpp b/src/gui/Arc.cpp index c9260d12..c13cf4a7 100644 --- a/src/gui/Arc.cpp +++ b/src/gui/Arc.cpp @@ -16,10 +16,12 @@ #include "Arc.hpp" -#include "ingen/URI.hpp" -#include "ingen/client/ArcModel.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/PortModel.hpp" +#include <ganv/Edge.hpp> +#include <ingen/URI.hpp> +#include <ingen/client/ArcModel.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PortModel.hpp> #include <glib-object.h> @@ -27,13 +29,7 @@ #define NS_INTERNALS "http://drobilla.net/ns/ingen-internals#" -namespace ingen { - -namespace client { -class ObjectModel; -} // namespace client - -namespace gui { +namespace ingen::gui { Arc::Arc(Ganv::Canvas& canvas, const std::shared_ptr<const client::ArcModel>& model, @@ -41,8 +37,8 @@ Arc::Arc(Ganv::Canvas& canvas, Ganv::Node* dst) : Ganv::Edge(canvas, src, dst), _arc_model(model) { - std::shared_ptr<const client::ObjectModel> tparent = model->tail()->parent(); - std::shared_ptr<const client::BlockModel> tparent_block; + const std::shared_ptr<const client::ObjectModel> tparent = model->tail()->parent(); + std::shared_ptr<const client::BlockModel> tparent_block; if ((tparent_block = std::dynamic_pointer_cast<const client::BlockModel>(tparent))) { if (tparent_block->plugin_uri() == NS_INTERNALS "BlockDelay") { g_object_set(_gobj, "dash-length", 4.0, nullptr); @@ -51,5 +47,4 @@ Arc::Arc(Ganv::Canvas& canvas, } } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/Arc.hpp b/src/gui/Arc.hpp index 746f6d61..ad1bc6f2 100644 --- a/src/gui/Arc.hpp +++ b/src/gui/Arc.hpp @@ -17,7 +17,7 @@ #ifndef INGEN_GUI_ARC_HPP #define INGEN_GUI_ARC_HPP -#include "ganv/Edge.hpp" +#include <ganv/Edge.hpp> #include <memory> @@ -28,7 +28,9 @@ class Node; namespace ingen { -namespace client { class ArcModel; } +namespace client { +class ArcModel; +} // namespace client namespace gui { diff --git a/src/gui/BreadCrumbs.cpp b/src/gui/BreadCrumbs.cpp index 4e257d88..5bd4d30a 100644 --- a/src/gui/BreadCrumbs.cpp +++ b/src/gui/BreadCrumbs.cpp @@ -19,25 +19,27 @@ #include "App.hpp" #include "GraphView.hpp" -#include "ingen/client/SigClientInterface.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Message.hpp> +#include <ingen/URI.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/SigClientInterface.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> -#include <boost/variant/get.hpp> -#include <glibmm/signalproxy.h> #include <sigc++/adaptors/bind.h> #include <sigc++/functors/mem_fun.h> +#include <algorithm> #include <string> +#include <variant> -namespace ingen { -namespace gui { +namespace ingen::gui { using std::string; BreadCrumbs::BreadCrumbs(App& app) : _active_path("/") , _full_path("/") - , _enable_signal(true) { app.sig_client()->signal_message().connect( sigc::mem_fun(this, &BreadCrumbs::message)); @@ -48,13 +50,13 @@ BreadCrumbs::BreadCrumbs(App& app) std::shared_ptr<GraphView> BreadCrumbs::view(const raul::Path& path) { - for (const auto& b : _breadcrumbs) { - if (b->path() == path) { - return b->view(); - } - } + const auto b = std::find_if(_breadcrumbs.begin(), + _breadcrumbs.end(), + [&path](const auto* crumb) { + return crumb->path() == path; + }); - return nullptr; + return b == _breadcrumbs.end() ? nullptr : (*b)->view(); } /** Sets up the crumbs to display `path`. @@ -66,19 +68,19 @@ void BreadCrumbs::build(const raul::Path& path, const std::shared_ptr<GraphView>& view) { - bool old_enable_signal = _enable_signal; + const bool old_enable_signal = _enable_signal; _enable_signal = false; if (!_breadcrumbs.empty() && (path.is_parent_of(_full_path) || path == _full_path)) { // Moving to a path we already contain, just switch the active button - for (const auto& b : _breadcrumbs) { + for (auto* b : _breadcrumbs) { if (b->path() == path) { b->set_active(true); if (!b->view()) { b->set_view(view); } - // views are expensive, having two around for the same graph is a bug + // Views are expensive, having two around is a bug assert(b->view() == view); } else { @@ -87,13 +89,12 @@ BreadCrumbs::build(const raul::Path& path, } _active_path = path; - _enable_signal = old_enable_signal; } else if (!_breadcrumbs.empty() && path.is_child_of(_full_path)) { - // Moving to a child of the full path, just append crumbs (preserve view cache) + // Moving to a child of the full path, append crumbs (preserve cache) string suffix = path.substr(_full_path.length()); - while (suffix.length() > 0) { + while (!suffix.empty()) { if (suffix[0] == '/') { suffix = suffix.substr(1); } @@ -105,25 +106,25 @@ BreadCrumbs::build(const raul::Path& path, but->show(); if (suffix.find('/') == string::npos) { break; - } else { - suffix = suffix.substr(suffix.find('/') + 1); } + + suffix = suffix.substr(suffix.find('/') + 1); } - for (const auto& b : _breadcrumbs) { + for (auto* b : _breadcrumbs) { b->set_active(false); } _breadcrumbs.back()->set_active(true); } else { - // Rebuild from scratch - // Getting here is bad unless absolutely necessary, since the GraphView cache is lost + /* Rebuild from scratch. Getting here is bad unless absolutely + necessary, since the GraphView cache is lost. */ _full_path = path; _active_path = path; // Empty existing breadcrumbs - for (const auto& b : _breadcrumbs) { + for (auto* b : _breadcrumbs) { remove(*b); } _breadcrumbs.clear(); @@ -136,7 +137,7 @@ BreadCrumbs::build(const raul::Path& path, raul::Path working_path("/"); string suffix = path.substr(1); - while (suffix.length() > 0) { + while (!suffix.empty()) { if (suffix[0] == '/') { suffix = suffix.substr(1); } @@ -149,9 +150,9 @@ BreadCrumbs::build(const raul::Path& path, but->show(); if (suffix.find('/') == string::npos) { break; - } else { - suffix = suffix.substr(suffix.find('/')+1); } + + suffix = suffix.substr(suffix.find('/')+1); } } @@ -197,7 +198,7 @@ BreadCrumbs::breadcrumb_clicked(BreadCrumb* crumb) void BreadCrumbs::message(const Message& msg) { - if (const Del* const del = boost::get<Del>(&msg)) { + if (const Del* const del = std::get_if<Del>(&msg)) { object_destroyed(del->uri); } } @@ -205,15 +206,19 @@ BreadCrumbs::message(const Message& msg) void BreadCrumbs::object_destroyed(const URI& uri) { - for (auto i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { - if ((*i)->path() == uri.c_str()) { - // Remove all crumbs after the removed one (inclusive) - for (auto j = i; j != _breadcrumbs.end(); ) { - BreadCrumb* bc = *j; - j = _breadcrumbs.erase(j); - remove(*bc); - } - break; + const auto i = std::find_if(_breadcrumbs.begin(), + _breadcrumbs.end(), + [&uri](const auto& b) { + return b->path() == uri.c_str(); + }); + + if (i != _breadcrumbs.end()) { + // Remove all crumbs after the removed one (inclusive) + for (auto j = i; j != _breadcrumbs.end();) { + BreadCrumb* const bc = *j; + + j = _breadcrumbs.erase(j); + remove(*bc); } } } @@ -221,12 +226,11 @@ BreadCrumbs::object_destroyed(const URI& uri) void BreadCrumbs::object_moved(const raul::Path& old_path, const raul::Path& new_path) { - for (const auto& b : _breadcrumbs) { + for (auto* b : _breadcrumbs) { if (b->path() == old_path) { b->set_path(new_path); } } } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/BreadCrumbs.hpp b/src/gui/BreadCrumbs.hpp index d877d0c5..89a339f2 100644 --- a/src/gui/BreadCrumbs.hpp +++ b/src/gui/BreadCrumbs.hpp @@ -19,11 +19,12 @@ #include "GraphView.hpp" -#include "ingen/Message.hpp" -#include "ingen/URI.hpp" -#include "ingen/client/GraphModel.hpp" -#include "raul/Path.hpp" +#include <ingen/Message.hpp> +#include <ingen/URI.hpp> +#include <ingen/client/GraphModel.hpp> +#include <raul/Path.hpp> +#include <glibmm/ustring.h> #include <gtkmm/box.h> #include <gtkmm/label.h> #include <gtkmm/object.h> @@ -35,8 +36,7 @@ #include <memory> #include <string> -namespace ingen { -namespace gui { +namespace ingen::gui { class App; @@ -71,7 +71,7 @@ private: { public: BreadCrumb(const raul::Path& path, - const std::shared_ptr<GraphView>& view = nullptr) + const std::shared_ptr<GraphView>& view) : _path(path), _view(view) { assert(!view || view->graph()->path() == path); @@ -81,6 +81,10 @@ private: show_all(); } + explicit BreadCrumb(const raul::Path& path) + : BreadCrumb{path, nullptr} + {} + void set_view(const std::shared_ptr<GraphView>& view) { assert(!view || view->graph()->path() == _path); _view = view; @@ -118,11 +122,10 @@ private: raul::Path _active_path; raul::Path _full_path; - bool _enable_signal; + bool _enable_signal{true}; std::list<BreadCrumb*> _breadcrumbs; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui #endif // INGEN_GUI_BREADCRUMBS_HPP diff --git a/src/gui/ConnectWindow.cpp b/src/gui/ConnectWindow.cpp index ea1a6e27..edafdfa4 100644 --- a/src/gui/ConnectWindow.cpp +++ b/src/gui/ConnectWindow.cpp @@ -20,30 +20,33 @@ #include "Window.hpp" #include "WindowFactory.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/EngineBase.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/QueuedInterface.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" // IWYU pragma: keep -#include "ingen/client/SigClientInterface.hpp" -#include "ingen/client/SocketClient.hpp" -#include "ingen/paths.hpp" -#include "raul/Path.hpp" -#include "raul/Process.hpp" - -#include <boost/variant/get.hpp> +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/EngineBase.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Message.hpp> +#include <ingen/QueuedInterface.hpp> +#include <ingen/Status.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/SigClientInterface.hpp> +#include <ingen/client/SocketClient.hpp> +#include <ingen/fmt.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Process.hpp> + #include <glib.h> #include <glibmm/main.h> -#include <glibmm/signalproxy.h> #include <glibmm/ustring.h> #include <gtkmm/builder.h> #include <gtkmm/button.h> +#include <gtkmm/dialog.h> #include <gtkmm/entry.h> #include <gtkmm/enums.h> #include <gtkmm/image.h> @@ -55,6 +58,7 @@ #include <gtkmm/stock.h> #include <sigc++/adaptors/bind.h> #include <sigc++/functors/mem_fun.h> +#include <sigc++/functors/slot.h> #include <sigc++/signal.h> #include <limits> @@ -62,44 +66,22 @@ #include <string> #include <sys/time.h> #include <utility> +#include <variant> -namespace ingen { -namespace gui { +namespace ingen::gui { ConnectWindow::ConnectWindow(BaseObjectType* cobject, Glib::RefPtr<Gtk::Builder> xml) : Dialog(cobject) , _xml(std::move(xml)) - , _icon(nullptr) - , _progress_bar(nullptr) - , _progress_label(nullptr) - , _url_entry(nullptr) - , _server_radio(nullptr) - , _port_spinbutton(nullptr) - , _launch_radio(nullptr) - , _internal_radio(nullptr) - , _activate_button(nullptr) - , _deactivate_button(nullptr) - , _disconnect_button(nullptr) - , _connect_button(nullptr) - , _quit_button(nullptr) - , _mode(Mode::CONNECT_REMOTE) - , _connect_uri("unix:///tmp/ingen.sock") - , _ping_id(-1) - , _attached(false) - , _finished_connecting(false) - , _widgets_loaded(false) - , _connect_stage(0) - , _quit_flag(false) -{ -} +{} void ConnectWindow::message(const Message& msg) { - if (const Response* const r = boost::get<Response>(&msg)) { + if (const Response* const r = std::get_if<Response>(&msg)) { ingen_response(r->id, r->status, r->subject); - } else if (const Error* const e = boost::get<Error>(&msg)) { + } else if (const Error* const e = std::get_if<Error>(&msg)) { error(e->message); } } @@ -131,7 +113,7 @@ ConnectWindow::start(App& app, ingen::World& world) } set_connected_to(world.interface()); - connect(bool(world.interface())); + connect(!!world.interface()); } void @@ -218,7 +200,7 @@ ConnectWindow::connect_remote(const URI& uri) auto sci = std::make_shared<client::SigClientInterface>(); auto qi = std::make_shared<QueuedInterface>(sci); - std::shared_ptr<ingen::Interface> iface(world.new_interface(uri, qi)); + const std::shared_ptr<ingen::Interface> iface{world.new_interface(uri, qi)}; if (iface) { world.set_interface(iface); _app->attach(qi); @@ -236,10 +218,10 @@ ConnectWindow::connect(bool existing) if (_app->client()) { error("Already connected"); return; - } else if (_attached) { - _attached = false; } + _attached = false; + set_connecting_widget_states(); _connect_stage = 0; @@ -286,10 +268,14 @@ ConnectWindow::connect(bool existing) if (!world.load_module("server")) { error("Failed to load server module"); return; - } else if (!world.load_module("jack")) { + } + + if (!world.load_module("jack")) { error("Failed to load jack module"); return; - } else if (!world.engine()->activate()) { + } + + if (!world.engine()->activate()) { error("Failed to activate engine"); return; } @@ -457,18 +443,17 @@ ConnectWindow::internal_toggled() void ConnectWindow::next_stage() { - static const char* labels[] = { - "Connecting...", - "Pinging engine...", - "Attaching to engine...", - "Requesting root graph...", - "Waiting for root graph...", - "Connected" - }; - - ++_connect_stage; if (_widgets_loaded) { + static const char* labels[] = { + "Connecting...", + "Pinging engine...", + "Attaching to engine...", + "Requesting root graph...", + "Waiting for root graph...", + "Connected" + }; + _progress_label->set_text(labels[_connect_stage]); } } @@ -491,8 +476,8 @@ ConnectWindow::gtk_callback() // Show if attempted connection goes on for a noticeable amount of time if (!is_visible()) { - const float ms_since_start = (now.tv_sec - start.tv_sec) * 1000.0f + - (now.tv_usec - start.tv_usec) * 0.001f; + const float ms_since_start = ((now.tv_sec - start.tv_sec) * 1000.0f) + + ((now.tv_usec - start.tv_usec) * 0.001f); if (ms_since_start > 500) { present(); set_connecting_widget_states(); @@ -500,8 +485,8 @@ ConnectWindow::gtk_callback() } if (_connect_stage == 0) { - const float ms_since_last = (now.tv_sec - last.tv_sec) * 1000.0f + - (now.tv_usec - last.tv_usec) * 0.001f; + const float ms_since_last = ((now.tv_sec - last.tv_sec) * 1000.0f) + + ((now.tv_usec - last.tv_usec) * 0.001f); if (ms_since_last >= 250) { last = now; if (_mode == Mode::INTERNAL) { @@ -530,8 +515,8 @@ ConnectWindow::gtk_callback() if (_attached) { next_stage(); } else { - const float ms_since_last = (now.tv_sec - last.tv_sec) * 1000.0f + - (now.tv_usec - last.tv_usec) * 0.001f; + const float ms_since_last = ((now.tv_sec - last.tv_sec) * 1000.0f) + + ((now.tv_usec - last.tv_usec) * 0.001f); if (attempts > 10) { error("Failed to ping engine"); _connect_stage = -1; @@ -577,9 +562,9 @@ ConnectWindow::gtk_callback() _progress_label->set_text(std::string("Disconnected")); } return false; - } else { - return true; } + + return true; } void @@ -589,5 +574,4 @@ ConnectWindow::quit() Gtk::Main::quit(); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/ConnectWindow.hpp b/src/gui/ConnectWindow.hpp index 6fc4dbfb..cd9059e1 100644 --- a/src/gui/ConnectWindow.hpp +++ b/src/gui/ConnectWindow.hpp @@ -19,13 +19,11 @@ #include "Window.hpp" -#include "ingen/Message.hpp" -#include "ingen/Status.hpp" -#include "ingen/URI.hpp" +#include <ingen/Message.hpp> +#include <ingen/URI.hpp> #include <glibmm/refptr.h> #include <gtkmm/builder.h> -#include <gtkmm/dialog.h> #include <cstdint> #include <memory> @@ -43,6 +41,8 @@ class SpinButton; namespace ingen { +enum class Status; + class Interface; class World; @@ -100,28 +100,28 @@ private: const Glib::RefPtr<Gtk::Builder> _xml; - Gtk::Image* _icon; - Gtk::ProgressBar* _progress_bar; - Gtk::Label* _progress_label; - Gtk::Entry* _url_entry; - Gtk::RadioButton* _server_radio; - Gtk::SpinButton* _port_spinbutton; - Gtk::RadioButton* _launch_radio; - Gtk::RadioButton* _internal_radio; - Gtk::Button* _activate_button; - Gtk::Button* _deactivate_button; - Gtk::Button* _disconnect_button; - Gtk::Button* _connect_button; - Gtk::Button* _quit_button; - - Mode _mode; - URI _connect_uri; - int32_t _ping_id; - bool _attached; - bool _finished_connecting; - bool _widgets_loaded; - int _connect_stage; - bool _quit_flag; + Gtk::Image* _icon{nullptr}; + Gtk::ProgressBar* _progress_bar{nullptr}; + Gtk::Label* _progress_label{nullptr}; + Gtk::Entry* _url_entry{nullptr}; + Gtk::RadioButton* _server_radio{nullptr}; + Gtk::SpinButton* _port_spinbutton{nullptr}; + Gtk::RadioButton* _launch_radio{nullptr}; + Gtk::RadioButton* _internal_radio{nullptr}; + Gtk::Button* _activate_button{nullptr}; + Gtk::Button* _deactivate_button{nullptr}; + Gtk::Button* _disconnect_button{nullptr}; + Gtk::Button* _connect_button{nullptr}; + Gtk::Button* _quit_button{nullptr}; + + Mode _mode{Mode::CONNECT_REMOTE}; + URI _connect_uri{"unix:///tmp/ingen.sock"}; + int32_t _ping_id{-1}; + bool _attached{false}; + bool _finished_connecting{false}; + bool _widgets_loaded{false}; + int _connect_stage{0}; + bool _quit_flag{false}; }; } // namespace gui diff --git a/src/gui/GraphBox.cpp b/src/gui/GraphBox.cpp index f994d47c..47c567e3 100644 --- a/src/gui/GraphBox.cpp +++ b/src/gui/GraphBox.cpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2017 David Robillard <http://drobilla.net/> + Copyright 2007-2024 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -27,35 +27,36 @@ #include "ThreadedLoader.hpp" #include "WidgetFactory.hpp" #include "WindowFactory.hpp" - -#include "ganv/canvas.h" -#include "ingen/Atom.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "ingen/client/PluginModel.hpp" -#include "ingen/client/PortModel.hpp" -#include "ingen/fmt.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include "ingen_config.h" + +#include <ganv/canvas.h> +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <ingen/fmt.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <gdk/gdk.h> +#include <glib.h> #include <glib/gstdio.h> #include <glibmm/convert.h> #include <glibmm/fileutils.h> #include <glibmm/miscutils.h> #include <glibmm/propertyproxy.h> #include <glibmm/refptr.h> -#include <glibmm/signalproxy.h> #include <glibmm/ustring.h> #include <gtkmm/alignment.h> #include <gtkmm/box.h> @@ -87,10 +88,11 @@ #include <sigc++/functors/mem_fun.h> #include <sigc++/signal.h> -#ifdef HAVE_WEBKIT -#include <webkit/webkit.h> +#if USE_WEBKIT +# include <webkit/webkit.h> #endif +#include <algorithm> #include <cassert> #include <cstdint> #include <cstdio> @@ -100,7 +102,6 @@ #include <sstream> #include <string> #include <utility> -#include <vector> namespace ingen { @@ -227,7 +228,7 @@ GraphBox::GraphBox(BaseObjectType* cobject, _menu_view_graph_properties->signal_activate().connect( sigc::mem_fun(this, &GraphBox::event_show_properties)); - Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); + const Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); clipboard->signal_owner_change().connect( sigc::mem_fun(this, &GraphBox::event_clipboard_changed)); @@ -249,8 +250,12 @@ std::shared_ptr<GraphBox> GraphBox::create(App& app, const std::shared_ptr<const GraphModel>& graph) { GraphBox* result = nullptr; - Glib::RefPtr<Gtk::Builder> xml = WidgetFactory::create("graph_win"); + const Glib::RefPtr<Gtk::Builder> xml = WidgetFactory::create("graph_win"); xml->get_widget_derived("graph_win_vbox", result); + if (!result) { + return {}; + } + result->init_box(app); result->set_graph(graph, nullptr); @@ -378,14 +383,14 @@ GraphBox::set_graph(const std::shared_ptr<const GraphModel>& graph, _menu_view_control_window->property_sensitive() = false; - for (const auto& p : graph->ports()) { - if (_app->can_control(p.get())) { - _menu_view_control_window->property_sensitive() = true; - break; - } - } + _menu_view_control_window->property_sensitive() = + std::any_of(graph->ports().begin(), + graph->ports().end(), + [this](const auto& p) { + return _app->can_control(p.get()); + }); - _menu_parent->property_sensitive() = bool(graph->parent()); + _menu_parent->property_sensitive() = !!graph->parent(); new_port_connection = graph->signal_new_port().connect( sigc::mem_fun(this, &GraphBox::graph_port_added)); @@ -421,14 +426,12 @@ GraphBox::graph_port_removed(const std::shared_ptr<const PortModel>& port) return; } - for (const auto& p : _graph->ports()) { - if (p->is_input() && _app->can_control(p.get())) { - _menu_view_control_window->property_sensitive() = true; - return; - } - } - - _menu_view_control_window->property_sensitive() = false; + _menu_view_control_window->property_sensitive() = + std::any_of(_graph->ports().begin(), + _graph->ports().end(), + [this](const auto& p) { + return p->is_input() && _app->can_control(p.get()); + }); } void @@ -449,7 +452,7 @@ GraphBox::set_documentation(const std::string& doc, bool html) _doc_scrolledwindow->hide(); return; } -#ifdef HAVE_WEBKIT +#if USE_WEBKIT WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new()); webkit_web_view_load_html_string(view, doc.c_str(), ""); Gtk::Widget* widget = Gtk::manage(Glib::wrap(GTK_WIDGET(view))); @@ -534,7 +537,7 @@ GraphBox::event_show_engine() void GraphBox::event_clipboard_changed(GdkEventOwnerChange* ev) { - Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); + const Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); _menu_paste->set_sensitive(clipboard->wait_is_text_available()); } @@ -716,18 +719,17 @@ GraphBox::event_export_image() dialog.set_transient_for(*_window); } - using Types = std::map<std::string, std::string>; - Types types; + std::map<std::string, std::string> types; types["*.dot"] = "Graphviz DOT"; types["*.pdf"] = "Portable Document Format"; types["*.ps"] = "PostScript"; types["*.svg"] = "Scalable Vector Graphics"; - for (Types::const_iterator t = types.begin(); t != types.end(); ++t) { + for (const auto& t : types) { Gtk::FileFilter filt; - filt.add_pattern(t->first); - filt.set_name(t->second); + filt.add_pattern(t.first); + filt.set_name(t.second); dialog.add_filter(filt); - if (t->first == "*.pdf") { + if (t.first == "*.pdf") { dialog.set_filter(filt); } } @@ -882,10 +884,10 @@ GraphBox::event_refresh_activated() void GraphBox::event_fullscreen_toggled() { - // FIXME: ugh, use GTK signals to track state and know for sure - static bool is_fullscreen = false; - if (_window) { + // FIXME: ugh, use GTK signals to track state and know for sure + static bool is_fullscreen = false; + if (!is_fullscreen) { _window->fullscreen(); is_fullscreen = true; @@ -927,8 +929,7 @@ GraphBox::event_animate_signals_toggled() _app->interface()->set_property( URI("ingen:/clients/this"), _app->uris().ingen_broadcast, - _app->forge().make( - static_cast<bool>(_menu_animate_signals->get_active()))); + _app->forge().make(_menu_animate_signals->get_active())); } void diff --git a/src/gui/GraphBox.hpp b/src/gui/GraphBox.hpp index cfc4a67f..07962a3d 100644 --- a/src/gui/GraphBox.hpp +++ b/src/gui/GraphBox.hpp @@ -17,7 +17,7 @@ #ifndef INGEN_GUI_GRAPH_BOX_HPP #define INGEN_GUI_GRAPH_BOX_HPP -#include "ingen/ingen.h" +#include <ingen/ingen.h> #include <gdk/gdk.h> #include <glibmm/ustring.h> diff --git a/src/gui/GraphCanvas.cpp b/src/gui/GraphCanvas.cpp index 77c33052..3090186a 100644 --- a/src/gui/GraphCanvas.cpp +++ b/src/gui/GraphCanvas.cpp @@ -14,9 +14,10 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include "GraphCanvas.hpp" + #include "App.hpp" #include "Arc.hpp" -#include "GraphCanvas.hpp" #include "GraphPortModule.hpp" #include "GraphWindow.hpp" #include "NodeModule.hpp" @@ -27,46 +28,48 @@ #include "WidgetFactory.hpp" #include "WindowFactory.hpp" -#include "ganv/Canvas.hpp" -#include "ganv/Edge.hpp" -#include "ganv/Module.hpp" -#include "ganv/Node.hpp" -#include "ganv/Port.hpp" -#include "ganv/canvas.h" -#include "ganv/edge.h" -#include "ganv/module.h" -#include "ganv/types.h" -#include "ingen/Arc.hpp" -#include "ingen/Atom.hpp" -#include "ingen/ClashAvoider.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/Node.hpp" -#include "ingen/Parser.hpp" -#include "ingen/Serialiser.hpp" -#include "ingen/Store.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/client/ArcModel.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "ingen/client/PluginModel.hpp" -#include "ingen/client/PortModel.hpp" -#include "ingen/paths.hpp" -#include "raul/Symbol.hpp" -#include "sord/sordmm.hpp" - -#include <boost/optional/optional.hpp> +#include <ganv/Canvas.hpp> +#include <ganv/Edge.hpp> +#include <ganv/Module.hpp> +#include <ganv/Node.hpp> +#include <ganv/Port.hpp> +#include <ganv/canvas.h> +#include <ganv/edge.h> +#include <ganv/module.h> +#include <ganv/types.h> +#include <ingen/Arc.hpp> +#include <ingen/Atom.hpp> +#include <ingen/ClashAvoider.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Node.hpp> +#include <ingen/Parser.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/Serialiser.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ArcModel.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> +#include <sord/sordmm.hpp> + #include <gdk/gdk.h> #include <gdk/gdkkeysyms-compat.h> #include <gdkmm/window.h> #include <glib.h> #include <glibmm/refptr.h> -#include <glibmm/signalproxy.h> #include <glibmm/ustring.h> #include <gtkmm/builder.h> #include <gtkmm/checkmenuitem.h> @@ -77,9 +80,9 @@ #include <gtkmm/menu.h> #include <gtkmm/menu_elems.h> #include <gtkmm/menuitem.h> -#include <gtkmm/menushell.h> #include <gtkmm/object.h> #include <gtkmm/stock.h> +#include <gtkmm/stockid.h> #include <sigc++/adaptors/bind.h> #include <sigc++/functors/mem_fun.h> #include <sigc++/signal.h> @@ -93,6 +96,7 @@ #include <map> #include <memory> #include <mutex> +#include <optional> #include <set> #include <sstream> #include <string> @@ -129,12 +133,8 @@ GraphCanvas::GraphCanvas(App& app, : Canvas(width, height) , _app(app) , _graph(std::move(graph)) - , _auto_position_count(0) - , _menu_x(0) - , _menu_y(0) - , _paste_count(0) { - Glib::RefPtr<Gtk::Builder> xml = WidgetFactory::create("canvas_menu"); + const Glib::RefPtr<Gtk::Builder> xml = WidgetFactory::create("canvas_menu"); xml->get_widget("canvas_menu", _menu); xml->get_widget("canvas_menu_add_audio_input", _menu_add_audio_input); @@ -253,7 +253,7 @@ GraphCanvas::build_menus() _menu->reorder_child(*internal_menu_item, 4); } - // Build skeleton LV2 plugin class heirarchy for 'Plugin' menu + // Build skeleton LV2 plugin class hierarchy for 'Plugin' menu if (_plugin_menu) { _plugin_menu->clear(); } else { @@ -269,7 +269,7 @@ GraphCanvas::build_menus() sigc::mem_fun(this, &GraphCanvas::load_plugin)); } - // Add known plugins to menu heirarchy + // Add known plugins to menu hierarchy auto plugins = _app.store()->plugins(); for (const auto& p : *plugins) { add_plugin(p.second); @@ -284,7 +284,7 @@ GraphCanvas::build() const Store::const_range kids = _app.store()->children_range(_graph); // Create modules for blocks - for (Store::const_iterator i = kids.first; i != kids.second; ++i) { + for (auto i = kids.first; i != kids.second; ++i) { auto block = std::dynamic_pointer_cast<BlockModel>(i->second); if (block && block->parent() == _graph) { add_block(block); @@ -305,7 +305,7 @@ GraphCanvas::build() static void show_module_human_names(GanvNode* node, void* data) { - bool b = *static_cast<bool*>(data); + const bool b = *static_cast<bool*>(data); if (GANV_IS_MODULE(node)) { Ganv::Module* module = Glib::wrap(GANV_MODULE(node)); auto* nmod = dynamic_cast<NodeModule*>(module); @@ -440,14 +440,14 @@ GraphCanvas::get_port_view(const std::shared_ptr<PortModel>& port) return ppm ? *ppm->begin() : dynamic_cast<Ganv::Port*>(module); - } else { - module = dynamic_cast<NodeModule*>(_views[port->parent()]); - if (module) { - for (auto* p : *module) { - auto* pv = dynamic_cast<gui::Port*>(p); - if (pv && pv->model() == port) { - return pv; - } + } + + module = dynamic_cast<NodeModule*>(_views[port->parent()]); + if (module) { + for (auto* p : *module) { + auto* pv = dynamic_cast<gui::Port*>(p); + if (pv && pv->model() == port) { + return pv; } } } @@ -482,7 +482,7 @@ GraphCanvas::disconnection(const std::shared_ptr<const ArcModel>& arc) if (arc->head()->is_a(_app.uris().lv2_AudioPort)) { auto* const h = dynamic_cast<gui::Port*>(head); if (h) { - h->activity(_app.forge().make(0.0f)); // Reset peaks + h->activity(_app.forge().make(0.0f)); // Reset peaks } } } else { @@ -614,14 +614,14 @@ destroy_node(GanvNode* node, void* data) return; } - App* app = static_cast<App*>(data); + const App* app = static_cast<App*>(data); Ganv::Module* module = Glib::wrap(GANV_MODULE(node)); - auto* node_module = dynamic_cast<NodeModule*>(module); + const auto* node_module = dynamic_cast<NodeModule*>(module); if (node_module) { app->interface()->del(node_module->block()->uri()); } else { - auto* port_module = dynamic_cast<GraphPortModule*>(module); + const auto* port_module = dynamic_cast<GraphPortModule*>(module); if (port_module && strcmp(port_module->port()->path().symbol(), "control") && strcmp(port_module->port()->path().symbol(), "notify")) { @@ -633,11 +633,11 @@ destroy_node(GanvNode* node, void* data) static void destroy_arc(GanvEdge* arc, void* data) { - App* app = static_cast<App*>(data); + const App* app = static_cast<App*>(data); Ganv::Edge* arcmm = Glib::wrap(arc); - Port* tail = dynamic_cast<Port*>(arcmm->get_tail()); - Port* head = dynamic_cast<Port*>(arcmm->get_head()); + const Port* tail = dynamic_cast<Port*>(arcmm->get_tail()); + const Port* head = dynamic_cast<Port*>(arcmm->get_head()); app->interface()->disconnect(tail->model()->path(), head->model()->path()); } @@ -662,12 +662,12 @@ serialise_node(GanvNode* node, void* data) } Ganv::Module* module = Glib::wrap(GANV_MODULE(node)); - auto* node_module = dynamic_cast<NodeModule*>(module); + const auto* node_module = dynamic_cast<NodeModule*>(module); if (node_module) { serialiser->serialise(node_module->block()); } else { - auto* port_module = dynamic_cast<GraphPortModule*>(module); + const auto* port_module = dynamic_cast<GraphPortModule*>(module); if (port_module) { serialiser->serialise(port_module->port()); } @@ -682,7 +682,7 @@ serialise_arc(GanvEdge* arc, void* data) return; } - auto* garc = dynamic_cast<gui::Arc*>(Glib::wrap(GANV_EDGE(arc))); + const auto* garc = dynamic_cast<gui::Arc*>(Glib::wrap(GANV_EDGE(arc))); if (garc) { serialiser->serialise_arc(Sord::Node(), garc->model()); } @@ -691,7 +691,7 @@ serialise_arc(GanvEdge* arc, void* data) void GraphCanvas::copy_selection() { - std::lock_guard<std::mutex> lock(_app.world().rdf_mutex()); + const std::lock_guard<std::mutex> lock{_app.world().rdf_mutex()}; Serialiser serialiser(_app.world()); serialiser.start_to_string(_graph->path(), _graph->base_uri()); @@ -699,7 +699,7 @@ GraphCanvas::copy_selection() for_each_selected_node(serialise_node, &serialiser); for_each_selected_edge(serialise_arc, &serialiser); - Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); + const Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); clipboard->set_text(serialiser.finish()); _paste_count = 0; } @@ -707,9 +707,7 @@ GraphCanvas::copy_selection() void GraphCanvas::paste() { - using PropIter = Properties::const_iterator; - - std::lock_guard<std::mutex> lock(_app.world().rdf_mutex()); + const std::lock_guard<std::mutex> lock{_app.world().rdf_mutex()}; const Glib::ustring str = Gtk::Clipboard::get()->wait_for_text(); auto parser = _app.loader()->parser(); @@ -732,7 +730,7 @@ GraphCanvas::paste() {{uris.rdf_type, Property(uris.ingen_Graph)}}); // Parse clipboard text into clipboard store - boost::optional<URI> base_uri = parser->parse_string( + std::optional<URI> base_uri = parser->parse_string( _app.world(), clipboard, str, main_uri()); // Figure out the copy graph base path @@ -740,7 +738,7 @@ GraphCanvas::paste() if (base_uri) { std::string base = *base_uri; if (base[base.size() - 1] == '/') { - base = base.substr(0, base.size() - 1); + base.resize(base.size() - 1); } copy_root = uri_to_path(URI(base)); } @@ -807,8 +805,8 @@ GraphCanvas::paste() } // Set coordinates so paste origin is at the mouse pointer - PropIter xi = node->properties().find(uris.ingen_canvasX); - PropIter yi = node->properties().find(uris.ingen_canvasY); + const auto xi = node->properties().find(uris.ingen_canvasX); + const auto yi = node->properties().find(uris.ingen_canvasY); if (xi != node->properties().end()) { const float x = xi->second.get<float>() - min_x + paste_x; props.insert({xi->first, Property(_app.forge().make(x), @@ -880,7 +878,7 @@ GraphCanvas::menu_add_port(const string& sym_base, uris.rdf_type, Property(is_output ? uris.lv2_OutputPort : uris.lv2_InputPort)); props.emplace(uris.lv2_index, - _app.forge().make(int32_t(_graph->num_ports()))); + _app.forge().make(static_cast<int32_t>(_graph->num_ports()))); props.emplace(uris.lv2_name, _app.forge().alloc(name.c_str())); _app.interface()->put(path_to_uri(path), props); } @@ -893,8 +891,8 @@ GraphCanvas::load_plugin(const std::weak_ptr<PluginModel>& weak_plugin) return; } - raul::Symbol symbol = plugin->default_block_symbol(); - unsigned offset = _app.store()->child_name_offset(_graph->path(), symbol); + raul::Symbol symbol = plugin->default_block_symbol(); + const unsigned offset = _app.store()->child_name_offset(_graph->path(), symbol); if (offset != 0) { std::stringstream ss; ss << symbol << "_" << offset; diff --git a/src/gui/GraphCanvas.hpp b/src/gui/GraphCanvas.hpp index b1e60aa3..38f3ab08 100644 --- a/src/gui/GraphCanvas.hpp +++ b/src/gui/GraphCanvas.hpp @@ -17,12 +17,12 @@ #ifndef INGEN_GUI_GRAPHCANVAS_HPP #define INGEN_GUI_GRAPHCANVAS_HPP -#include "ganv/Canvas.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URI.hpp" -#include "lilv/lilv.h" -#include "raul/Path.hpp" +#include <ganv/Canvas.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <lilv/lilv.h> +#include <raul/Path.hpp> #include <gdk/gdk.h> @@ -141,12 +141,12 @@ private: using Views = std::map<std::shared_ptr<const client::ObjectModel>, Ganv::Module*>; Views _views; - int _auto_position_count; + int _auto_position_count{0}; std::pair<int, int> _auto_position_scroll_offsets; - int _menu_x; - int _menu_y; - int _paste_count; + int _menu_x{0}; + int _menu_y{0}; + int _paste_count{0}; // Track pasted objects so they can be selected when they arrive std::set<raul::Path> _pastees; diff --git a/src/gui/GraphPortModule.cpp b/src/gui/GraphPortModule.cpp index 3206f80b..cd471d97 100644 --- a/src/gui/GraphPortModule.cpp +++ b/src/gui/GraphPortModule.cpp @@ -14,22 +14,24 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include "GraphPortModule.hpp" + #include "App.hpp" #include "GraphCanvas.hpp" -#include "GraphPortModule.hpp" #include "Port.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "raul/Symbol.hpp" - -#include "ingen/Configuration.hpp" -#include "ingen/Interface.hpp" -#include "ingen/client/GraphModel.hpp" // IWYU pragma: keep -#include "ingen/client/PortModel.hpp" +#include <ganv/Module.hpp> +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <raul/Symbol.hpp> #include <sigc++/functors/mem_fun.h> #include <sigc++/signal.h> @@ -41,16 +43,13 @@ #include <string> #include <utility> -namespace ingen { - -namespace gui { +namespace ingen::gui { GraphPortModule::GraphPortModule( GraphCanvas& canvas, const std::shared_ptr<const client::PortModel>& model) : Ganv::Module(canvas, "", 0, 0, false) // FIXME: coords? , _model(model) - , _port(nullptr) { assert(model); @@ -169,5 +168,4 @@ GraphPortModule::set_selected(gboolean b) } } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/GraphPortModule.hpp b/src/gui/GraphPortModule.hpp index 5ce7ea57..a8091f38 100644 --- a/src/gui/GraphPortModule.hpp +++ b/src/gui/GraphPortModule.hpp @@ -17,8 +17,8 @@ #ifndef INGEN_GUI_GRAPHPORTMODULE_HPP #define INGEN_GUI_GRAPHPORTMODULE_HPP -#include "ganv/Module.hpp" -#include "ingen/URI.hpp" +#include <ganv/Module.hpp> +#include <ingen/URI.hpp> #include <gdk/gdk.h> #include <glib.h> @@ -33,9 +33,7 @@ class Atom; namespace client { class PortModel; } // namespace client -} // namespace ingen -namespace ingen { namespace gui { class App; @@ -76,7 +74,7 @@ protected: void property_changed(const URI& key, const Atom& value); std::shared_ptr<const client::PortModel> _model; - Port* _port; + Port* _port{nullptr}; }; } // namespace gui diff --git a/src/gui/GraphTreeWindow.cpp b/src/gui/GraphTreeWindow.cpp index e1ef158f..1d141271 100644 --- a/src/gui/GraphTreeWindow.cpp +++ b/src/gui/GraphTreeWindow.cpp @@ -14,23 +14,25 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "App.hpp" #include "GraphTreeWindow.hpp" + +#include "App.hpp" #include "Window.hpp" #include "WindowFactory.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <glibmm/propertyproxy.h> -#include <glibmm/signalproxy.h> #include <gtkmm/builder.h> #include <gtkmm/cellrenderer.h> #include <gtkmm/cellrenderertoggle.h> @@ -45,6 +47,7 @@ #include <cassert> #include <cstdint> #include <memory> +#include <string> namespace ingen { @@ -56,8 +59,6 @@ namespace gui { GraphTreeWindow::GraphTreeWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Window(cobject) - , _graphs_treeview(nullptr) - , _enable_signal(true) { xml->get_widget_derived("graphs_treeview", _graphs_treeview); @@ -108,8 +109,8 @@ void GraphTreeWindow::add_graph(const std::shared_ptr<GraphModel>& pm) { if (!pm->parent()) { - Gtk::TreeModel::iterator iter = _graph_treestore->append(); - Gtk::TreeModel::Row row = *iter; + const auto iter = _graph_treestore->append(); + auto row = *iter; if (pm->path().is_root()) { row[_graph_tree_columns.name_col] = _app->interface()->uri().string(); } else { @@ -119,12 +120,13 @@ GraphTreeWindow::add_graph(const std::shared_ptr<GraphModel>& pm) row[_graph_tree_columns.graph_model_col] = pm; _graphs_treeview->expand_row(_graph_treestore->get_path(iter), true); } else { - Gtk::TreeModel::Children children = _graph_treestore->children(); - Gtk::TreeModel::iterator c = find_graph(children, pm->parent()); + const auto& children = _graph_treestore->children(); + auto c = find_graph(children, pm->parent()); if (c != children.end()) { - Gtk::TreeModel::iterator iter = _graph_treestore->append(c->children()); - Gtk::TreeModel::Row row = *iter; + const auto iter = _graph_treestore->append(c->children()); + auto row = *iter; + row[_graph_tree_columns.name_col] = pm->symbol().c_str(); row[_graph_tree_columns.enabled_col] = pm->enabled(); row[_graph_tree_columns.graph_model_col] = pm; @@ -148,7 +150,7 @@ GraphTreeWindow::add_graph(const std::shared_ptr<GraphModel>& pm) void GraphTreeWindow::remove_graph(const std::shared_ptr<GraphModel>& pm) { - Gtk::TreeModel::iterator i = find_graph(_graph_treestore->children(), pm); + const auto i = find_graph(_graph_treestore->children(), pm); if (i != _graph_treestore->children().end()) { _graph_treestore->erase(i); } @@ -158,12 +160,14 @@ Gtk::TreeModel::iterator GraphTreeWindow::find_graph(Gtk::TreeModel::Children root, const std::shared_ptr<client::ObjectModel>& graph) { - for (Gtk::TreeModel::iterator c = root.begin(); c != root.end(); ++c) { - std::shared_ptr<GraphModel> pm = (*c)[_graph_tree_columns.graph_model_col]; + for (auto c = root.begin(); c != root.end(); ++c) { + const std::shared_ptr<GraphModel> pm = (*c)[_graph_tree_columns.graph_model_col]; if (graph == pm) { return c; - } else if (!(*c)->children().empty()) { - Gtk::TreeModel::iterator ret = find_graph(c->children(), graph); + } + + if (!(*c)->children().empty()) { + auto ret = find_graph(c->children(), graph); if (ret != c->children().end()) { return ret; } @@ -177,10 +181,12 @@ GraphTreeWindow::find_graph(Gtk::TreeModel::Children root, void GraphTreeWindow::show_graph_menu(GdkEventButton* ev) { - Gtk::TreeModel::iterator active = _graph_tree_selection->get_selected(); + const auto active = _graph_tree_selection->get_selected(); if (active) { - Gtk::TreeModel::Row row = *active; - std::shared_ptr<GraphModel> pm = row[_graph_tree_columns.graph_model_col]; + auto row = *active; + auto col = _graph_tree_columns.graph_model_col; + + const std::shared_ptr<GraphModel>& pm = row[col]; if (pm) { _app->log().warn("TODO: graph menu from tree window"); } @@ -191,9 +197,10 @@ void GraphTreeWindow::event_graph_activated(const Gtk::TreeModel::Path& path, Gtk::TreeView::Column* col) { - Gtk::TreeModel::iterator active = _graph_treestore->get_iter(path); - Gtk::TreeModel::Row row = *active; - std::shared_ptr<GraphModel> pm = row[_graph_tree_columns.graph_model_col]; + const auto active = _graph_treestore->get_iter(path); + auto row = *active; + + const std::shared_ptr<GraphModel> pm = row[_graph_tree_columns.graph_model_col]; _app->window_factory()->present_graph(pm); } @@ -201,17 +208,17 @@ GraphTreeWindow::event_graph_activated(const Gtk::TreeModel::Path& path, void GraphTreeWindow::event_graph_enabled_toggled(const Glib::ustring& path_str) { - Gtk::TreeModel::Path path(path_str); - Gtk::TreeModel::iterator active = _graph_treestore->get_iter(path); - Gtk::TreeModel::Row row = *active; + const Gtk::TreeModel::Path path{path_str}; + auto active = _graph_treestore->get_iter(path); + auto row = *active; - std::shared_ptr<GraphModel> pm = row[_graph_tree_columns.graph_model_col]; + const std::shared_ptr<GraphModel> pm = row[_graph_tree_columns.graph_model_col]; assert(pm); if (_enable_signal) { _app->set_property(pm->uri(), _app->uris().ingen_enabled, - _app->forge().make(static_cast<bool>(!pm->enabled()))); + _app->forge().make(!pm->enabled())); } } @@ -224,9 +231,9 @@ GraphTreeWindow::graph_property_changed( const URIs& uris = _app->uris(); _enable_signal = false; if (key == uris.ingen_enabled && value.type() == uris.forge.Bool) { - Gtk::TreeModel::iterator i = find_graph(_graph_treestore->children(), graph); + const auto i = find_graph(_graph_treestore->children(), graph); if (i != _graph_treestore->children().end()) { - Gtk::TreeModel::Row row = *i; + auto row = *i; row[_graph_tree_columns.enabled_col] = value.get<int32_t>(); } else { _app->log().error("Unable to find graph %1%\n", graph->path()); @@ -240,11 +247,9 @@ GraphTreeWindow::graph_moved(const std::shared_ptr<GraphModel>& graph) { _enable_signal = false; - Gtk::TreeModel::iterator i - = find_graph(_graph_treestore->children(), graph); - + auto i = find_graph(_graph_treestore->children(), graph); if (i != _graph_treestore->children().end()) { - Gtk::TreeModel::Row row = *i; + auto row = *i; row[_graph_tree_columns.name_col] = graph->symbol().c_str(); } else { _app->log().error("Unable to find graph %1%\n", graph->path()); diff --git a/src/gui/GraphTreeWindow.hpp b/src/gui/GraphTreeWindow.hpp index 1a719a81..6f33f258 100644 --- a/src/gui/GraphTreeWindow.hpp +++ b/src/gui/GraphTreeWindow.hpp @@ -19,7 +19,7 @@ #include "Window.hpp" -#include "ingen/URI.hpp" +#include <ingen/URI.hpp> #include <gdk/gdk.h> #include <glibmm/refptr.h> @@ -29,7 +29,6 @@ #include <gtkmm/treeselection.h> #include <gtkmm/treestore.h> #include <gtkmm/treeview.h> -#include <gtkmm/window.h> #include <memory> @@ -87,10 +86,9 @@ protected: find_graph(Gtk::TreeModel::Children root, const std::shared_ptr<client::ObjectModel>& graph); - GraphTreeView* _graphs_treeview; + GraphTreeView* _graphs_treeview{nullptr}; - struct GraphTreeModelColumns : public Gtk::TreeModel::ColumnRecord - { + struct GraphTreeModelColumns : public Gtk::TreeModel::ColumnRecord { GraphTreeModelColumns() { add(name_col); add(enabled_col); @@ -105,7 +103,7 @@ protected: GraphTreeModelColumns _graph_tree_columns; Glib::RefPtr<Gtk::TreeStore> _graph_treestore; Glib::RefPtr<Gtk::TreeSelection> _graph_tree_selection; - bool _enable_signal; + bool _enable_signal{true}; }; /** Derived TreeView class to support context menus for graphs */ @@ -115,13 +113,12 @@ public: GraphTreeView(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Gtk::TreeView(cobject) - , _window(nullptr) {} void set_window(GraphTreeWindow* win) { _window = win; } bool on_button_press_event(GdkEventButton* ev) override { - bool ret = Gtk::TreeView::on_button_press_event(ev); + const bool ret = Gtk::TreeView::on_button_press_event(ev); if ((ev->type == GDK_BUTTON_PRESS) && (ev->button == 3)) { _window->show_graph_menu(ev); @@ -131,7 +128,7 @@ public: } private: - GraphTreeWindow* _window; + GraphTreeWindow* _window{nullptr}; }; } // namespace gui diff --git a/src/gui/GraphView.cpp b/src/gui/GraphView.cpp index bd493499..8d1e1777 100644 --- a/src/gui/GraphView.cpp +++ b/src/gui/GraphView.cpp @@ -14,21 +14,21 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include "GraphView.hpp" + #include "App.hpp" #include "GraphCanvas.hpp" -#include "GraphView.hpp" #include "WidgetFactory.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/GraphModel.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/GraphModel.hpp> #include <glibmm/propertyproxy.h> #include <glibmm/refptr.h> -#include <glibmm/signalproxy.h> #include <gtkmm/adjustment.h> #include <gtkmm/builder.h> #include <gtkmm/enums.h> @@ -45,6 +45,7 @@ #include <cstdint> #include <map> #include <memory> +#include <string> #include <utility> namespace ingen { @@ -119,8 +120,9 @@ GraphView::set_graph(const std::shared_ptr<const GraphModel>& graph) std::shared_ptr<GraphView> GraphView::create(App& app, const std::shared_ptr<const GraphModel>& graph) { - GraphView* result = nullptr; - Glib::RefPtr<Gtk::Builder> xml = WidgetFactory::create("warehouse_win"); + GraphView* result = nullptr; + const Glib::RefPtr<Gtk::Builder> xml = + WidgetFactory::create("warehouse_win"); xml->get_widget_derived("graph_view_box", result); if (!result) { @@ -141,8 +143,7 @@ GraphView::process_toggled() _app->set_property(_graph->uri(), _app->uris().ingen_enabled, - _app->forge().make( - static_cast<bool>(_process_but->get_active()))); + _app->forge().make(_process_but->get_active())); } void diff --git a/src/gui/GraphView.hpp b/src/gui/GraphView.hpp index 0b6aee1e..812f2cbc 100644 --- a/src/gui/GraphView.hpp +++ b/src/gui/GraphView.hpp @@ -48,7 +48,7 @@ namespace gui { class App; class GraphCanvas; -/** The graph specific contents of a GraphWindow (ie the canvas and whatever else). +/** The graph specific contents of a GraphWindow (the canvas and whatever else). * * \ingroup GUI */ diff --git a/src/gui/GraphWindow.cpp b/src/gui/GraphWindow.cpp index 38273a8e..a6978e46 100644 --- a/src/gui/GraphWindow.cpp +++ b/src/gui/GraphWindow.cpp @@ -25,17 +25,13 @@ #include <glibmm/refptr.h> #include <gtkmm/builder.h> #include <gtkmm/layout.h> +#include <gtkmm/window.h> -namespace ingen { -namespace gui { +namespace ingen::gui { GraphWindow::GraphWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Window(cobject) - , _box(nullptr) - , _position_stored(false) - , _x(0) - , _y(0) { property_visible() = false; @@ -84,5 +80,4 @@ GraphWindow::on_key_press_event(GdkEventKey* event) return Gtk::Window::on_key_press_event(event); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/GraphWindow.hpp b/src/gui/GraphWindow.hpp index 290e0e00..9936b5df 100644 --- a/src/gui/GraphWindow.hpp +++ b/src/gui/GraphWindow.hpp @@ -21,7 +21,6 @@ #include "Window.hpp" #include <gdk/gdk.h> -#include <gtkmm/window.h> #include <memory> #include <string> @@ -45,8 +44,6 @@ class PortModel; namespace gui { -class App; - /** A window for a graph. * * \ingroup GUI @@ -85,10 +82,10 @@ protected: bool on_key_press_event(GdkEventKey* event) override; private: - GraphBox* _box; - bool _position_stored; - int _x; - int _y; + GraphBox* _box{nullptr}; + bool _position_stored{false}; + int _x{0}; + int _y{0}; }; } // namespace gui diff --git a/src/gui/LoadGraphWindow.cpp b/src/gui/LoadGraphWindow.cpp index 7a80a2bf..5124face 100644 --- a/src/gui/LoadGraphWindow.cpp +++ b/src/gui/LoadGraphWindow.cpp @@ -19,24 +19,24 @@ #include "App.hpp" #include "ThreadedLoader.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/FilePath.hpp" -#include "ingen/Forge.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/runtime_paths.hpp" -#include "raul/Path.hpp" - -#include <boost/optional/optional.hpp> +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/FilePath.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/runtime_paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> + #include <glibmm/fileutils.h> #include <glibmm/miscutils.h> #include <glibmm/propertyproxy.h> #include <glibmm/refptr.h> -#include <glibmm/signalproxy.h> #include <glibmm/slisthandle.h> #include <gtkmm/builder.h> #include <gtkmm/button.h> @@ -52,6 +52,7 @@ #include <list> #include <map> #include <memory> +#include <optional> #include <sstream> #include <string> #include <utility> @@ -187,8 +188,8 @@ LoadGraphWindow::ok_clicked() if (_import) { // If unset load_graph will load value - boost::optional<raul::Path> parent; - boost::optional<raul::Symbol> symbol; + std::optional<raul::Path> parent; + std::optional<raul::Symbol> symbol; if (!_graph->path().is_root()) { parent = _graph->path().parent(); symbol = _graph->symbol(); @@ -198,7 +199,7 @@ LoadGraphWindow::ok_clicked() true, FilePath(get_filename()), parent, symbol, _initial_data); } else { - std::list<Glib::ustring> uri_list = get_filenames(); + const std::list<Glib::ustring> uri_list = get_filenames(); for (const auto& u : uri_list) { // Cascade Atom& x = _initial_data.find(uris.ingen_canvasX)->second; @@ -237,23 +238,23 @@ raul::Symbol LoadGraphWindow::symbol_from_filename(const Glib::ustring& filename) { std::string symbol_str = Glib::path_get_basename(get_filename()); - symbol_str = symbol_str.substr(0, symbol_str.find('.')); + symbol_str.resize(symbol_str.find('.')); return raul::Symbol::symbolify(symbol_str); } raul::Symbol LoadGraphWindow::avoid_symbol_clash(const raul::Symbol& symbol) { - unsigned offset = _app->store()->child_name_offset( + const unsigned offset = _app->store()->child_name_offset( _graph->path(), symbol); if (offset != 0) { std::stringstream ss; ss << symbol << "_" << offset; return raul::Symbol(ss.str()); - } else { - return symbol; } + + return symbol; } void diff --git a/src/gui/LoadGraphWindow.hpp b/src/gui/LoadGraphWindow.hpp index b2063d75..bfa2590e 100644 --- a/src/gui/LoadGraphWindow.hpp +++ b/src/gui/LoadGraphWindow.hpp @@ -17,8 +17,8 @@ #ifndef INGEN_GUI_LOADGRAPHWINDOW_HPP #define INGEN_GUI_LOADGRAPHWINDOW_HPP -#include "ingen/Properties.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Properties.hpp> +#include <raul/Symbol.hpp> #include <glibmm/ustring.h> #include <gtkmm/filechooserdialog.h> @@ -40,7 +40,9 @@ class SpinButton; namespace ingen { -namespace client { class GraphModel; } +namespace client { +class GraphModel; +} // namespace client namespace gui { diff --git a/src/gui/LoadPluginWindow.cpp b/src/gui/LoadPluginWindow.cpp index 5a9536a2..3d8b2cd5 100644 --- a/src/gui/LoadPluginWindow.cpp +++ b/src/gui/LoadPluginWindow.cpp @@ -14,26 +14,28 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "App.hpp" #include "LoadPluginWindow.hpp" + +#include "App.hpp" #include "Window.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/client/PluginModel.hpp" -#include "ingen/paths.hpp" -#include "lilv/lilv.h" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/paths.hpp> +#include <lilv/lilv.h> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <gdk/gdkkeysyms-compat.h> #include <glibmm/listhandle.h> #include <glibmm/propertyproxy.h> -#include <glibmm/signalproxy.h> #include <glibmm/ustring.h> #include <gtkmm/builder.h> #include <gtkmm/button.h> @@ -41,9 +43,12 @@ #include <gtkmm/combobox.h> #include <gtkmm/enums.h> #include <gtkmm/messagedialog.h> +#include <gtkmm/object.h> #include <gtkmm/treeiter.h> +#include <gtkmm/treepath.h> #include <gtkmm/treeview.h> #include <gtkmm/treeviewcolumn.h> +#include <gtkmm/window.h> #include <sigc++/adaptors/bind.h> #include <sigc++/functors/mem_fun.h> #include <sigc++/signal.h> @@ -102,8 +107,9 @@ LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, _criteria_liststore = Gtk::ListStore::create(_criteria_columns); _filter_combo->set_model(_criteria_liststore); - Gtk::TreeModel::iterator iter = _criteria_liststore->append(); - Gtk::TreeModel::Row row = *iter; + auto iter = _criteria_liststore->append(); + auto row = *iter; + row[_criteria_columns._col_label] = "Name contains"; row[_criteria_columns._col_criteria] = CriteriaColumns::Criteria::NAME; _filter_combo->set_active(iter); @@ -326,8 +332,8 @@ LoadPluginWindow::add_plugin(const std::shared_ptr<const PluginModel>& plugin) return; } - Gtk::TreeModel::iterator iter = _plugins_liststore->append(); - Gtk::TreeModel::Row row = *iter; + auto iter = _plugins_liststore->append(); + auto row = *iter; _rows.emplace(plugin->uri(), iter); set_row(row, plugin); @@ -349,19 +355,22 @@ LoadPluginWindow::plugin_activated(const Gtk::TreeModel::Path& path, void LoadPluginWindow::plugin_selection_changed() { - size_t n_selected = _selection->get_selected_rows().size(); + const size_t n_selected = _selection->get_selected_rows().size(); if (n_selected == 0) { _name_offset = 0; _name_entry->set_text(""); _name_entry->set_sensitive(false); } else if (n_selected == 1) { - Gtk::TreeModel::iterator iter = _plugins_liststore->get_iter( - *_selection->get_selected_rows().begin()); + auto iter = _plugins_liststore->get_iter( + *_selection->get_selected_rows().begin()); if (iter) { - Gtk::TreeModel::Row row = *iter; - auto p = row.get_value(_plugins_columns._col_plugin); - _name_offset = _app->store()->child_name_offset( - _graph->path(), p->default_block_symbol()); + auto row = *iter; + auto p = row.get_value(_plugins_columns._col_plugin); + + _name_offset = + _app->store()->child_name_offset(_graph->path(), + p->default_block_symbol()); + _name_entry->set_text(generate_module_name(p, _name_offset)); _name_entry->set_sensitive(true); } else { @@ -397,11 +406,11 @@ LoadPluginWindow::generate_module_name( void LoadPluginWindow::load_plugin(const Gtk::TreeModel::iterator& iter) { - const URIs& uris = _app->uris(); - Gtk::TreeModel::Row row = *iter; - auto plugin = row.get_value(_plugins_columns._col_plugin); - bool polyphonic = _polyphonic_checkbutton->get_active(); - string name = _name_entry->get_text(); + const URIs& uris = _app->uris(); + auto row = *iter; + auto plugin = row.get_value(_plugins_columns._col_plugin); + const bool polyphonic = _polyphonic_checkbutton->get_active(); + string name = _name_entry->get_text(); if (name.empty()) { name = generate_module_name(plugin, _name_offset); @@ -415,8 +424,8 @@ LoadPluginWindow::load_plugin(const Gtk::TreeModel::iterator& iter) dialog.run(); } else { - raul::Path path = _graph->path().child(raul::Symbol::symbolify(name)); - Properties props = _initial_data; + const raul::Path path = _graph->path().child(raul::Symbol::symbolify(name)); + Properties props = _initial_data; props.emplace(uris.rdf_type, Property(uris.ingen_Block)); props.emplace(uris.lv2_prototype, _app->forge().make_urid(plugin->uri())); props.emplace(uris.ingen_polyphonic, _app->forge().make(polyphonic)); @@ -451,8 +460,8 @@ LoadPluginWindow::filter_changed() transform(search.begin(), search.end(), search.begin(), ::toupper); // Get selected criteria - const Gtk::TreeModel::Row row = *(_filter_combo->get_active()); - CriteriaColumns::Criteria criteria = row[_criteria_columns._col_criteria]; + const auto row = *(_filter_combo->get_active()); + const CriteriaColumns::Criteria criteria = row[_criteria_columns._col_criteria]; string field; @@ -511,9 +520,9 @@ LoadPluginWindow::on_key_press_event(GdkEventKey* event) if (event->keyval == GDK_w && event->state & GDK_CONTROL_MASK) { hide(); return true; - } else { - return Gtk::Window::on_key_press_event(event); } + + return Gtk::Window::on_key_press_event(event); } void @@ -523,7 +532,7 @@ LoadPluginWindow::plugin_property_changed(const URI& plugin, { const URIs& uris = _app->uris(); if (predicate == uris.doap_name) { - Rows::const_iterator i = _rows.find(plugin); + const auto i = _rows.find(plugin); if (i != _rows.end() && value.type() == uris.forge.String) { (*i->second)[_plugins_columns._col_name] = value.ptr<char>(); } diff --git a/src/gui/LoadPluginWindow.hpp b/src/gui/LoadPluginWindow.hpp index 46c5e816..eab48913 100644 --- a/src/gui/LoadPluginWindow.hpp +++ b/src/gui/LoadPluginWindow.hpp @@ -19,9 +19,9 @@ #include "Window.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URI.hpp" -#include "ingen/client/ClientStore.hpp" +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/client/ClientStore.hpp> #include <gdk/gdk.h> #include <glibmm/refptr.h> @@ -30,7 +30,6 @@ #include <gtkmm/treemodel.h> #include <gtkmm/treemodelcolumn.h> #include <gtkmm/treeselection.h> -#include <gtkmm/window.h> #include <map> #include <memory> @@ -88,7 +87,8 @@ protected: private: /** Columns for the plugin list */ - class ModelColumns : public Gtk::TreeModel::ColumnRecord { + class ModelColumns : public Gtk::TreeModel::ColumnRecord + { public: ModelColumns() { add(_col_name); @@ -110,7 +110,8 @@ private: }; /** Column for the filter criteria combo box. */ - class CriteriaColumns : public Gtk::TreeModel::ColumnRecord { + class CriteriaColumns : public Gtk::TreeModel::ColumnRecord + { public: enum class Criteria { NAME, TYPE, PROJECT, AUTHOR, URI, }; diff --git a/src/gui/MessagesWindow.cpp b/src/gui/MessagesWindow.cpp index 2e0fdb61..993fbb33 100644 --- a/src/gui/MessagesWindow.cpp +++ b/src/gui/MessagesWindow.cpp @@ -18,13 +18,14 @@ #include "App.hpp" #include "Window.hpp" +#include "ingen_config.h" -#include "ingen/URIs.hpp" -#include "lv2/urid/urid.h" +#include <ingen/URIs.hpp> +#include <lv2/urid/urid.h> #include <gdkmm/color.h> #include <glibmm/propertyproxy.h> -#include <glibmm/signalproxy.h> +#include <glibmm/ustring.h> #include <gtkmm/builder.h> #include <gtkmm/button.h> #include <gtkmm/enums.h> @@ -38,8 +39,8 @@ #include <string> #include <utility> -namespace ingen { -namespace gui { +namespace ingen::gui { + using std::string; MessagesWindow::MessagesWindow(BaseObjectType* cobject, @@ -83,7 +84,7 @@ MessagesWindow::init_window(App& app) void MessagesWindow::post_error(const string& msg) { - Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); + const Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); text_buf->insert_with_tag(text_buf->end(), msg, _error_tag); text_buf->insert(text_buf->end(), "\n"); @@ -100,9 +101,9 @@ MessagesWindow::post_error(const string& msg) int MessagesWindow::log(LV2_URID type, const char* fmt, va_list args) { - std::lock_guard<std::mutex> lock(_mutex); + const std::lock_guard<std::mutex> lock{_mutex}; -#ifdef HAVE_VASPRINTF +#if USE_VASPRINTF char* buf = nullptr; const int len = vasprintf(&buf, fmt, args); #else @@ -124,7 +125,7 @@ MessagesWindow::flush() std::string line; { - std::lock_guard<std::mutex> lock(_mutex); + const std::lock_guard<std::mutex> lock{_mutex}; if (!_stream.rdbuf()->in_avail()) { return; } @@ -132,7 +133,7 @@ MessagesWindow::flush() std::getline(_stream, line, '\0'); } - Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); + const Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); auto t = _tags.find(type); if (t != _tags.end()) { @@ -150,10 +151,9 @@ MessagesWindow::flush() void MessagesWindow::clear_clicked() { - Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); + const Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); text_buf->erase(text_buf->begin(), text_buf->end()); _clear_button->set_sensitive(false); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/MessagesWindow.hpp b/src/gui/MessagesWindow.hpp index ab82193d..0a70e76c 100644 --- a/src/gui/MessagesWindow.hpp +++ b/src/gui/MessagesWindow.hpp @@ -19,11 +19,10 @@ #include "Window.hpp" -#include "lv2/urid/urid.h" +#include <lv2/urid/urid.h> #include <glibmm/refptr.h> #include <gtkmm/texttag.h> -#include <gtkmm/window.h> #include <cstdarg> #include <map> @@ -37,10 +36,7 @@ class Button; class TextView; } // namespace Gtk -namespace ingen { -namespace gui { - -class App; +namespace ingen::gui { /** Messages Window. * @@ -67,15 +63,14 @@ private: std::mutex _mutex; std::stringstream _stream; - Gtk::TextView* _textview; - Gtk::Button* _clear_button; - Gtk::Button* _close_button; + Gtk::TextView* _textview{nullptr}; + Gtk::Button* _clear_button{nullptr}; + Gtk::Button* _close_button{nullptr}; Glib::RefPtr<Gtk::TextTag> _error_tag; std::map< LV2_URID, Glib::RefPtr<Gtk::TextTag> > _tags; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui #endif // INGEN_GUI_MESSAGESWINDOW_HPP diff --git a/src/gui/NewSubgraphWindow.cpp b/src/gui/NewSubgraphWindow.cpp index 9b6c4a1a..3d6bf019 100644 --- a/src/gui/NewSubgraphWindow.cpp +++ b/src/gui/NewSubgraphWindow.cpp @@ -19,20 +19,20 @@ #include "App.hpp" #include "Window.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/paths.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <glibmm/propertyproxy.h> #include <glibmm/refptr.h> -#include <glibmm/signalproxy.h> #include <glibmm/ustring.h> #include <gtkmm/adjustment.h> #include <gtkmm/builder.h> @@ -40,6 +40,7 @@ #include <gtkmm/entry.h> #include <gtkmm/label.h> #include <gtkmm/spinbutton.h> +#include <gtkmm/window.h> #include <sigc++/functors/mem_fun.h> #include <cstdint> @@ -47,8 +48,7 @@ #include <string> #include <utility> -namespace ingen { -namespace gui { +namespace ingen::gui { NewSubgraphWindow::NewSubgraphWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) @@ -94,7 +94,7 @@ NewSubgraphWindow::set_graph(std::shared_ptr<const client::GraphModel> graph) void NewSubgraphWindow::name_changed() { - std::string name = _name_entry->get_text(); + const std::string name = _name_entry->get_text(); if (!raul::Symbol::is_valid(name)) { _message_label->set_text("Name contains invalid characters."); _ok_button->property_sensitive() = false; @@ -118,8 +118,8 @@ NewSubgraphWindow::ok_clicked() // Create graph Properties props; props.emplace(_app->uris().rdf_type, Property(_app->uris().ingen_Graph)); - props.emplace(_app->uris().ingen_polyphony, _app->forge().make(int32_t(poly))); - props.emplace(_app->uris().ingen_enabled, _app->forge().make(bool(true))); + props.emplace(_app->uris().ingen_polyphony, _app->forge().make(static_cast<int32_t>(poly))); + props.emplace(_app->uris().ingen_enabled, _app->forge().make(true)); _app->interface()->put( path_to_uri(path), props, Resource::Graph::INTERNAL); @@ -138,5 +138,4 @@ NewSubgraphWindow::cancel_clicked() hide(); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/NewSubgraphWindow.hpp b/src/gui/NewSubgraphWindow.hpp index 9897e6c2..b0fb24d2 100644 --- a/src/gui/NewSubgraphWindow.hpp +++ b/src/gui/NewSubgraphWindow.hpp @@ -19,9 +19,7 @@ #include "Window.hpp" -#include "ingen/Properties.hpp" - -#include <gtkmm/window.h> +#include <ingen/Properties.hpp> #include <memory> @@ -39,7 +37,9 @@ class SpinButton; namespace ingen { -namespace client { class GraphModel; } +namespace client { +class GraphModel; +} // namespace client namespace gui { @@ -68,11 +68,11 @@ private: Properties _initial_data; std::shared_ptr<const client::GraphModel> _graph; - Gtk::Entry* _name_entry; - Gtk::Label* _message_label; - Gtk::SpinButton* _poly_spinbutton; - Gtk::Button* _ok_button; - Gtk::Button* _cancel_button; + Gtk::Entry* _name_entry{nullptr}; + Gtk::Label* _message_label{nullptr}; + Gtk::SpinButton* _poly_spinbutton{nullptr}; + Gtk::Button* _ok_button{nullptr}; + Gtk::Button* _cancel_button{nullptr}; }; } // namespace gui diff --git a/src/gui/NodeMenu.cpp b/src/gui/NodeMenu.cpp index 517d0018..2815194c 100644 --- a/src/gui/NodeMenu.cpp +++ b/src/gui/NodeMenu.cpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2015 David Robillard <http://drobilla.net/> + Copyright 2007-2024 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -19,22 +19,22 @@ #include "App.hpp" #include "ObjectMenu.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "ingen/client/PluginModel.hpp" -#include "ingen/client/PortModel.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <raul/Symbol.hpp> #include <glib.h> #include <glibmm/convert.h> #include <glibmm/miscutils.h> #include <glibmm/refptr.h> -#include <glibmm/signalproxy.h> #include <glibmm/ustring.h> #include <gtkmm/box.h> #include <gtkmm/builder.h> @@ -46,15 +46,17 @@ #include <gtkmm/filechooserdialog.h> #include <gtkmm/image.h> #include <gtkmm/label.h> +#include <gtkmm/menu.h> #include <gtkmm/menu_elems.h> #include <gtkmm/menuitem.h> -#include <gtkmm/menushell.h> #include <gtkmm/object.h> #include <gtkmm/separatormenuitem.h> #include <gtkmm/stock.h> +#include <gtkmm/stockid.h> #include <sigc++/adaptors/bind.h> #include <sigc++/functors/mem_fun.h> +#include <algorithm> #include <cstdint> #include <map> #include <memory> @@ -62,13 +64,11 @@ #include <utility> #include <vector> -namespace ingen { -namespace gui { +namespace ingen::gui { NodeMenu::NodeMenu(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : ObjectMenu(cobject, xml) - , _presets_menu(nullptr) { xml->get_widget("node_popup_gui_menuitem", _popup_gui_menuitem); xml->get_widget("node_embed_gui_menuitem", _embed_gui_menuitem); @@ -162,6 +162,12 @@ NodeMenu::init(App& app, const std::shared_ptr<const client::BlockModel>& block) _enable_signal = true; } +std::shared_ptr<const client::BlockModel> +NodeMenu::block() const +{ + return std::dynamic_pointer_cast<const client::BlockModel>(_object); +} + void NodeMenu::add_preset(const URI& uri, const std::string& label) { @@ -185,7 +191,7 @@ NodeMenu::on_menu_enabled() { _app->set_property(_object->uri(), _app->uris().ingen_enabled, - _app->forge().make(bool(_enabled_menuitem->get_active()))); + _app->forge().make(_enabled_menuitem->get_active())); } void @@ -201,7 +207,7 @@ NodeMenu::on_menu_randomize() bm->port_value_range(p, min, max, _app->sample_rate()); const auto r = static_cast<float>(g_random_double_range(0.0, 1.0)); - const float val = r * (max - min) + min; + const float val = (r * (max - min)) + min; _app->set_property(p->uri(), _app->uris().ingen_value, _app->forge().make(val)); @@ -247,7 +253,7 @@ NodeMenu::on_save_preset_activated() const std::string real_path = Glib::build_filename(dirname, bundle, file); const std::string real_uri = Glib::filename_to_uri(real_path); - Properties props{ + const Properties props{ { _app->uris().rdf_type, _app->uris().pset_Preset }, { _app->uris().rdfs_label, @@ -269,14 +275,11 @@ NodeMenu::on_preset_activated(const std::string& uri) bool NodeMenu::has_control_inputs() { - for (const auto& p : block()->ports()) { - if (p->is_input() && p->is_numeric()) { - return true; - } - } - - return false; + return std::any_of(block()->ports().begin(), + block()->ports().end(), + [](const auto& p) { + return p->is_input() && p->is_numeric(); + }); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/NodeMenu.hpp b/src/gui/NodeMenu.hpp index 8a1e5f06..0427672c 100644 --- a/src/gui/NodeMenu.hpp +++ b/src/gui/NodeMenu.hpp @@ -19,9 +19,8 @@ #include "ObjectMenu.hpp" -#include "ingen/URI.hpp" +#include <ingen/URI.hpp> -#include <gtkmm/menu.h> #include <sigc++/connection.h> #include <sigc++/signal.h> @@ -35,6 +34,7 @@ template <class T> class RefPtr; namespace Gtk { class Builder; class CheckMenuItem; +class Menu; class MenuItem; } // namespace Gtk @@ -66,9 +66,7 @@ public: sigc::signal<void, bool> signal_embed_gui; protected: - std::shared_ptr<const client::BlockModel> block() const { - return std::dynamic_pointer_cast<const client::BlockModel>(_object); - } + std::shared_ptr<const client::BlockModel> block() const; void add_preset(const URI& uri, const std::string& label); @@ -79,11 +77,11 @@ protected: void on_save_preset_activated(); void on_preset_activated(const std::string& uri); - Gtk::MenuItem* _popup_gui_menuitem; - Gtk::CheckMenuItem* _embed_gui_menuitem; - Gtk::CheckMenuItem* _enabled_menuitem; - Gtk::MenuItem* _randomize_menuitem; - Gtk::Menu* _presets_menu; + Gtk::MenuItem* _popup_gui_menuitem{nullptr}; + Gtk::CheckMenuItem* _embed_gui_menuitem{nullptr}; + Gtk::CheckMenuItem* _enabled_menuitem{nullptr}; + Gtk::MenuItem* _randomize_menuitem{nullptr}; + Gtk::Menu* _presets_menu{nullptr}; sigc::connection _preset_connection; }; diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp index fe111572..deb8fe52 100644 --- a/src/gui/NodeModule.cpp +++ b/src/gui/NodeModule.cpp @@ -25,28 +25,30 @@ #include "SubgraphModule.hpp" #include "WidgetFactory.hpp" #include "WindowFactory.hpp" - -#include "ganv/Port.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/GraphModel.hpp" // IWYU pragma: keep -#include "ingen/client/PluginModel.hpp" -#include "ingen/client/PluginUI.hpp" -#include "ingen/client/PortModel.hpp" -#include "lv2/atom/util.h" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include "ingen_config.h" + +#include <ganv/Module.hpp> +#include <ganv/Port.hpp> +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PluginUI.hpp> +#include <ingen/client/PortModel.hpp> +#include <lv2/atom/util.h> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <glibmm/main.h> -#include <glibmm/signalproxy.h> #include <glibmm/ustring.h> #include <gtkmm/container.h> #include <gtkmm/eventbox.h> @@ -55,6 +57,7 @@ #include <sigc++/adaptors/bind.h> #include <sigc++/adaptors/retype_return.h> #include <sigc++/functors/mem_fun.h> +#include <sigc++/functors/slot.h> #include <sigc++/signal.h> #include <cassert> @@ -77,9 +80,6 @@ NodeModule::NodeModule(GraphCanvas& canvas, const std::shared_ptr<const BlockModel>& block) : Ganv::Module(canvas, block->path().symbol(), 0, 0, true) , _block(block) - , _gui_widget(nullptr) - , _gui_window(nullptr) - , _initialised(false) { block->signal_new_port().connect( sigc::mem_fun(this, &NodeModule::new_port_view)); @@ -129,7 +129,7 @@ bool NodeModule::idle_init() { if (_block->ports().empty()) { - return true; // Need to embed GUI, but ports haven't shown up yet + return true; // Need to embed GUI, but ports haven't shown up yet } // Ports have arrived, embed GUI and deregister this callback @@ -209,7 +209,7 @@ NodeModule::show_human_names(bool b) if (name_property.type() == uris.forge.String) { label = name_property.ptr<char>(); } else { - Glib::ustring hn = block()->plugin_model()->port_human_name( + const Glib::ustring hn = block()->plugin_model()->port_human_name( port->model()->index()); if (!hn.empty()) { label = hn; @@ -410,9 +410,9 @@ NodeModule::popup_gui() _gui_window->present(); return true; - } else { - app().log().warn("No LV2 GUI for %1%\n", _block->path()); } + + app().log().warn("No LV2 GUI for %1%\n", _block->path()); } return false; @@ -451,9 +451,13 @@ NodeModule::on_event(GdkEvent* ev) { if (ev->type == GDK_BUTTON_PRESS && ev->button.button == 3) { return show_menu(&ev->button); - } else if (ev->type == GDK_2BUTTON_PRESS) { + } + + if (ev->type == GDK_2BUTTON_PRESS) { return on_double_click(&ev->button); - } else if (ev->type == GDK_ENTER_NOTIFY) { + } + + if (ev->type == GDK_ENTER_NOTIFY) { GraphBox* const box = app().window_factory()->graph_box( std::dynamic_pointer_cast<const GraphModel>(_block->parent())); if (box) { @@ -530,9 +534,10 @@ NodeModule::on_selected(gboolean selected) if (selected && win->documentation_is_visible()) { std::string doc; - bool html = false; -#ifdef HAVE_WEBKIT - html = true; +#if USE_WEBKIT + const bool html = true; +#else + const bool html = false; #endif if (block()->plugin_model()) { doc = block()->plugin_model()->documentation(html); diff --git a/src/gui/NodeModule.hpp b/src/gui/NodeModule.hpp index 1ca7955c..64ad8f66 100644 --- a/src/gui/NodeModule.hpp +++ b/src/gui/NodeModule.hpp @@ -17,8 +17,8 @@ #ifndef INGEN_GUI_NODEMODULE_HPP #define INGEN_GUI_NODEMODULE_HPP -#include "ganv/Module.hpp" -#include "ingen/URI.hpp" +#include <ganv/Module.hpp> +#include <ingen/URI.hpp> #include <gdk/gdk.h> #include <glib.h> @@ -42,8 +42,7 @@ class PortModel; } // namespace client } // namespace ingen -namespace ingen { -namespace gui { +namespace ingen::gui { class App; class GraphCanvas; @@ -106,14 +105,13 @@ protected: bool show_menu(GdkEventButton* ev); std::shared_ptr<const client::BlockModel> _block; - NodeMenu* _menu; + NodeMenu* _menu{nullptr}; std::shared_ptr<client::PluginUI> _plugin_ui; - Gtk::Widget* _gui_widget; - Gtk::Window* _gui_window; ///< iff popped up - bool _initialised; + Gtk::Widget* _gui_widget{nullptr}; + Gtk::Window* _gui_window{nullptr}; ///< iff popped up + bool _initialised{false}; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui #endif // INGEN_GUI_NODEMODULE_HPP diff --git a/src/gui/ObjectMenu.cpp b/src/gui/ObjectMenu.cpp index 5f78144f..8c41ff10 100644 --- a/src/gui/ObjectMenu.cpp +++ b/src/gui/ObjectMenu.cpp @@ -19,15 +19,15 @@ #include "App.hpp" #include "WindowFactory.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/ObjectModel.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ObjectModel.hpp> #include <glibmm/refptr.h> -#include <glibmm/signalproxy.h> #include <gtkmm/builder.h> #include <gtkmm/checkmenuitem.h> #include <gtkmm/menuitem.h> @@ -39,19 +39,11 @@ #include <cstdint> #include <memory> -namespace ingen { -namespace gui { +namespace ingen::gui { ObjectMenu::ObjectMenu(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Gtk::Menu(cobject) - , _app(nullptr) - , _polyphonic_menuitem(nullptr) - , _disconnect_menuitem(nullptr) - , _rename_menuitem(nullptr) - , _destroy_menuitem(nullptr) - , _properties_menuitem(nullptr) - , _enable_signal(false) { xml->get_widget("object_learn_menuitem", _learn_menuitem); xml->get_widget("object_unlearn_menuitem", _unlearn_menuitem); @@ -126,7 +118,7 @@ ObjectMenu::on_menu_polyphonic() _app->set_property( _object->uri(), _app->uris().ingen_polyphonic, - _app->forge().make(bool(_polyphonic_menuitem->get_active()))); + _app->forge().make(_polyphonic_menuitem->get_active())); } } @@ -153,5 +145,4 @@ ObjectMenu::on_menu_properties() _app->window_factory()->present_properties(_object); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/ObjectMenu.hpp b/src/gui/ObjectMenu.hpp index 214c8307..5a4c83f4 100644 --- a/src/gui/ObjectMenu.hpp +++ b/src/gui/ObjectMenu.hpp @@ -17,7 +17,7 @@ #ifndef INGEN_GUI_OBJECTMENU_HPP #define INGEN_GUI_OBJECTMENU_HPP -#include "ingen/URI.hpp" +#include <ingen/URI.hpp> #include <gtkmm/menu.h> @@ -76,18 +76,18 @@ protected: void property_changed(const URI& predicate, const Atom& value); - App* _app; + App* _app{nullptr}; std::shared_ptr<const client::ObjectModel> _object; - Gtk::MenuItem* _learn_menuitem; - Gtk::MenuItem* _unlearn_menuitem; - Gtk::CheckMenuItem* _polyphonic_menuitem; - Gtk::MenuItem* _disconnect_menuitem; - Gtk::MenuItem* _rename_menuitem; - Gtk::MenuItem* _destroy_menuitem; - Gtk::MenuItem* _properties_menuitem; - Gtk::SeparatorMenuItem* _separator_menuitem; - - bool _enable_signal; + Gtk::MenuItem* _learn_menuitem{nullptr}; + Gtk::MenuItem* _unlearn_menuitem{nullptr}; + Gtk::CheckMenuItem* _polyphonic_menuitem{nullptr}; + Gtk::MenuItem* _disconnect_menuitem{nullptr}; + Gtk::MenuItem* _rename_menuitem{nullptr}; + Gtk::MenuItem* _destroy_menuitem{nullptr}; + Gtk::MenuItem* _properties_menuitem{nullptr}; + Gtk::SeparatorMenuItem* _separator_menuitem{nullptr}; + + bool _enable_signal{false}; }; } // namespace gui diff --git a/src/gui/PluginMenu.cpp b/src/gui/PluginMenu.cpp index 7ddfd075..26bbed08 100644 --- a/src/gui/PluginMenu.cpp +++ b/src/gui/PluginMenu.cpp @@ -16,15 +16,15 @@ #include "PluginMenu.hpp" -#include "ingen/Log.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/client/PluginModel.hpp" +#include <ingen/Log.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/PluginModel.hpp> +#include <lilv/lilv.h> #include <glibmm/ustring.h> #include <gtkmm/menu_elems.h> #include <gtkmm/menuitem.h> -#include <gtkmm/menushell.h> #include <gtkmm/object.h> #include <sigc++/adaptors/bind.h> #include <sigc++/functors/mem_fun.h> @@ -32,8 +32,7 @@ #include <memory> #include <utility> -namespace ingen { -namespace gui { +namespace ingen::gui { PluginMenu::PluginMenu(ingen::World& world) : _world(world) @@ -56,7 +55,7 @@ PluginMenu::clear() // Build skeleton LV2Children children; - LILV_FOREACH(plugin_classes, i, classes) { + LILV_FOREACH (plugin_classes, i, classes) { const LilvPluginClass* c = lilv_plugin_classes_get(classes, i); const LilvNode* p = lilv_plugin_class_get_parent_uri(c); if (!p) { @@ -78,8 +77,6 @@ PluginMenu::clear() void PluginMenu::add_plugin(const std::shared_ptr<client::PluginModel>& p) { - using iterator = ClassMenus::iterator; - if (!p->lilv_plugin() || lilv_plugin_is_replaced(p->lilv_plugin())) { return; } @@ -88,7 +85,7 @@ PluginMenu::add_plugin(const std::shared_ptr<client::PluginModel>& p) const LilvNode* class_uri = lilv_plugin_class_get_uri(pc); const char* class_uri_str = lilv_node_as_string(class_uri); - std::pair<iterator, iterator> range = _class_menus.equal_range(class_uri_str); + const auto range = _class_menus.equal_range(class_uri_str); if (range.first == _class_menus.end() || range.first == range.second || range.first->second.menu == this) { // Add to uncategorized plugin menu @@ -112,16 +109,14 @@ PluginMenu::build_plugin_class_menu(Gtk::Menu* menu, const LilvNode* class_uri = lilv_plugin_class_get_uri(plugin_class); const char* class_uri_str = lilv_node_as_string(class_uri); - const std::pair<LV2Children::const_iterator, LV2Children::const_iterator> kids - = children.equal_range(class_uri_str); - + const auto kids = children.equal_range(class_uri_str); if (kids.first == children.end()) { return 0; } // Add submenus ancestors.insert(class_uri_str); - for (LV2Children::const_iterator i = kids.first; i != kids.second; ++i) { + for (auto i = kids.first; i != kids.second; ++i) { const LilvPluginClass* c = i->second; const char* sub_label_str = lilv_node_as_string(lilv_plugin_class_get_label(c)); const char* sub_uri_str = lilv_node_as_string(lilv_plugin_class_get_uri(c)); @@ -131,7 +126,7 @@ PluginMenu::build_plugin_class_menu(Gtk::Menu* menu, return 0; } - Gtk::Menu_Helpers::MenuElem menu_elem = Gtk::Menu_Helpers::MenuElem( + const Gtk::Menu_Helpers::MenuElem menu_elem = Gtk::Menu_Helpers::MenuElem( std::string("_") + sub_label_str); menu->items().push_back(menu_elem); Gtk::MenuItem* menu_item = &(menu->items().back()); @@ -139,7 +134,7 @@ PluginMenu::build_plugin_class_menu(Gtk::Menu* menu, Gtk::Menu* submenu = Gtk::manage(new Gtk::Menu()); menu_item->set_submenu(*submenu); - size_t num_child_items = build_plugin_class_menu( + const size_t num_child_items = build_plugin_class_menu( submenu, c, classes, children, ancestors); _class_menus.emplace(sub_uri_str, MenuRecord(menu_item, submenu)); @@ -163,10 +158,10 @@ PluginMenu::add_plugin_to_menu(MenuRecord& menu, LilvNode* ingen_Graph = lilv_new_uri(lworld, uris.ingen_Graph.c_str()); LilvNode* rdf_type = lilv_new_uri(lworld, uris.rdf_type.c_str()); - bool is_graph = lilv_world_ask(lworld, - lilv_plugin_get_uri(p->lilv_plugin()), - rdf_type, - ingen_Graph); + const bool is_graph = lilv_world_ask(lworld, + lilv_plugin_get_uri(p->lilv_plugin()), + rdf_type, + ingen_Graph); menu.menu->items().push_back( Gtk::Menu_Helpers::MenuElem( @@ -187,5 +182,4 @@ PluginMenu::load_plugin(const std::weak_ptr<client::PluginModel>& weak_plugin) signal_load_plugin.emit(weak_plugin); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/PluginMenu.hpp b/src/gui/PluginMenu.hpp index 2cf130bb..eb0a565a 100644 --- a/src/gui/PluginMenu.hpp +++ b/src/gui/PluginMenu.hpp @@ -17,7 +17,7 @@ #ifndef INGEN_GUI_PLUGINMENU_HPP #define INGEN_GUI_PLUGINMENU_HPP -#include "lilv/lilv.h" +#include <lilv/lilv.h> #include <gtkmm/menu.h> #include <sigc++/signal.h> @@ -36,7 +36,9 @@ namespace ingen { class World; -namespace client { class PluginModel; } +namespace client { +class PluginModel; +} // namespace client namespace gui { @@ -48,7 +50,7 @@ namespace gui { class PluginMenu : public Gtk::Menu { public: - PluginMenu(ingen::World& world); + explicit PluginMenu(ingen::World& world); void clear(); void add_plugin(const std::shared_ptr<client::PluginModel>& p); @@ -57,7 +59,9 @@ public: private: struct MenuRecord { - MenuRecord(Gtk::MenuItem* i, Gtk::Menu* m) : item(i), menu(m) {} + MenuRecord(Gtk::MenuItem* i, Gtk::Menu* m) noexcept : item(i), menu(m) + {} + Gtk::MenuItem* item; Gtk::Menu* menu; }; diff --git a/src/gui/Port.cpp b/src/gui/Port.cpp index 65b415e3..4d11e309 100644 --- a/src/gui/Port.cpp +++ b/src/gui/Port.cpp @@ -24,32 +24,33 @@ #include "Style.hpp" #include "WidgetFactory.hpp" #include "WindowFactory.hpp" +#include "ingen_config.h" #include "rgba.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Log.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/GraphModel.hpp" // IWYU pragma: keep -#include "ingen/client/ObjectModel.hpp" -#include "ingen/client/PluginModel.hpp" -#include "ingen/client/PortModel.hpp" -#include "lilv/lilv.h" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" -#include "sord/sordmm.hpp" - -#include <glibmm/signalproxy.h> +#include <ganv/Port.hpp> +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Log.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <lilv/lilv.h> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> +#include <sord/sordmm.hpp> + +#include <glibmm/ustring.h> #include <gtkmm/menu.h> #include <gtkmm/menu_elems.h> #include <gtkmm/menuitem.h> -#include <gtkmm/menushell.h> #include <gtkmm/object.h> #include <sigc++/adaptors/bind.h> #include <sigc++/functors/mem_fun.h> @@ -222,14 +223,14 @@ Port::on_value_changed(double value) const URIs& uris = _app.uris(); const Atom& current_value = model()->value(); if (current_value.type() != uris.forge.Float) { - return; // Non-float, unsupported + return; // Non-float, unsupported } if (current_value.get<float>() == static_cast<float>(value)) { - return; // No change + return; // No change } - const Atom atom = _app.forge().make(float(value)); + const Atom atom = _app.forge().make(static_cast<float>(value)); _app.set_property(model()->uri(), _app.world().uris().ingen_value, atom); @@ -264,7 +265,7 @@ Port::build_enum_menu() auto block = std::dynamic_pointer_cast<BlockModel>(model()->parent()); Gtk::Menu* menu = Gtk::manage(new Gtk::Menu()); - PluginModel::ScalePoints points = block->plugin_model()->port_scale_points( + const PluginModel::ScalePoints points = block->plugin_model()->port_scale_points( model()->index()); for (const auto& p : points) { menu->items().push_back(Gtk::Menu_Helpers::MenuElem(p.second)); @@ -309,13 +310,13 @@ Port::build_uri_menu() rdfs::URISet ranges; LilvNodes* range = lilv_world_find_nodes( world.lilv_world(), designation, rdfs_range, nullptr); - LILV_FOREACH(nodes, r, range) { + LILV_FOREACH (nodes, r, range) { ranges.insert(URI(lilv_node_as_string(lilv_nodes_get(range, r)))); } rdfs::classes(world, ranges, false); // Get all objects in range - rdfs::Objects values = rdfs::instances(world, ranges); + const rdfs::Objects values = rdfs::instances(world, ranges); // Add a menu item for each such class for (const auto& v : values) { @@ -356,7 +357,9 @@ Port::on_event(GdkEvent* ev) Gtk::Menu* menu = build_enum_menu(); menu->popup(ev->button.button, ev->button.time); return true; - } else if (model()->is_uri()) { + } + + if (model()->is_uri()) { Gtk::Menu* menu = build_uri_menu(); if (menu) { menu->popup(ev->button.button, ev->button.time); @@ -374,7 +377,7 @@ Port::on_event(GdkEvent* ev) return false; } -inline static uint32_t +static inline uint32_t peak_color(float peak) { static const uint32_t min = 0x4A8A0EC0; @@ -384,9 +387,9 @@ peak_color(float peak) if (peak < 1.0f) { return rgba_interpolate(min, max, peak); - } else { - return rgba_interpolate(peak_min, peak_max, fminf(peak, 2.0f) - 1.0f); } + + return rgba_interpolate(peak_min, peak_max, fminf(peak, 2.0f) - 1.0f); } void @@ -550,9 +553,10 @@ Port::on_selected(gboolean b) GraphWindow* win = _app.window_factory()->parent_graph_window(block); if (win && win->documentation_is_visible() && block->plugin_model()) { - bool html = false; -#ifdef HAVE_WEBKIT - html = true; +#if USE_WEBKIT + const bool html = true; +#else + const bool html = false; #endif const std::string& doc = block->plugin_model()->port_documentation( pm->index(), html); diff --git a/src/gui/Port.hpp b/src/gui/Port.hpp index 534734ad..bfd8e15d 100644 --- a/src/gui/Port.hpp +++ b/src/gui/Port.hpp @@ -17,7 +17,7 @@ #ifndef INGEN_GUI_PORT_HPP #define INGEN_GUI_PORT_HPP -#include "ganv/Port.hpp" +#include <ganv/Port.hpp> #include <gdk/gdk.h> #include <glib.h> @@ -38,7 +38,9 @@ namespace ingen { class URI; class Atom; -namespace client { class PortModel; } +namespace client { +class PortModel; +} // namespace client namespace gui { diff --git a/src/gui/PortMenu.cpp b/src/gui/PortMenu.cpp index 652ac05d..373425cf 100644 --- a/src/gui/PortMenu.cpp +++ b/src/gui/PortMenu.cpp @@ -19,24 +19,25 @@ #include "App.hpp" #include "ObjectMenu.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/GraphModel.hpp" // IWYU pragma: keep -#include "ingen/client/ObjectModel.hpp" -#include "ingen/client/PortModel.hpp" -#include "ingen/paths.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <glibmm/refptr.h> -#include <glibmm/signalproxy.h> #include <gtkmm/builder.h> #include <gtkmm/checkmenuitem.h> +#include <gtkmm/menu.h> #include <gtkmm/menuitem.h> #include <gtkmm/separatormenuitem.h> #include <sigc++/functors/mem_fun.h> @@ -55,7 +56,6 @@ namespace gui { PortMenu::PortMenu(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : ObjectMenu(cobject, xml) - , _internal_graph_port(false) { xml->get_widget("object_menu", _port_menu); xml->get_widget("port_set_min_menuitem", _set_min_menuitem); @@ -169,7 +169,7 @@ PortMenu::on_menu_expose() auto block = std::dynamic_pointer_cast<const BlockModel>(port->parent()); const std::string label = block->label() + " " + block->port_label(port); - const raul::Path path = raul::Path(block->path() + raul::Symbol("_" + port->symbol())); + const auto path = raul::Path{block->path() + raul::Symbol("_" + port->symbol())}; ingen::Resource r(*_object); r.remove_property(uris.lv2_index, uris.patch_wildcard); diff --git a/src/gui/PortMenu.hpp b/src/gui/PortMenu.hpp index 75a25cde..cf7f9c62 100644 --- a/src/gui/PortMenu.hpp +++ b/src/gui/PortMenu.hpp @@ -19,8 +19,6 @@ #include "ObjectMenu.hpp" -#include <gtkmm/menu.h> - #include <memory> namespace Glib { @@ -29,6 +27,7 @@ template <class T> class RefPtr; namespace Gtk { class Builder; +class Menu; class MenuItem; } // namespace Gtk @@ -63,14 +62,14 @@ private: void on_menu_reset_range(); void on_menu_expose(); - Gtk::Menu* _port_menu; - Gtk::MenuItem* _set_min_menuitem; - Gtk::MenuItem* _set_max_menuitem; - Gtk::MenuItem* _reset_range_menuitem; - Gtk::MenuItem* _expose_menuitem; + Gtk::Menu* _port_menu{nullptr}; + Gtk::MenuItem* _set_min_menuitem{nullptr}; + Gtk::MenuItem* _set_max_menuitem{nullptr}; + Gtk::MenuItem* _reset_range_menuitem{nullptr}; + Gtk::MenuItem* _expose_menuitem{nullptr}; /// True iff this is a (flipped) port on a GraphPortModule in its graph - bool _internal_graph_port; + bool _internal_graph_port{false}; }; } // namespace gui diff --git a/src/gui/PropertiesWindow.cpp b/src/gui/PropertiesWindow.cpp index afcfa827..0dde0ab2 100644 --- a/src/gui/PropertiesWindow.cpp +++ b/src/gui/PropertiesWindow.cpp @@ -14,29 +14,32 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "App.hpp" #include "PropertiesWindow.hpp" + +#include "App.hpp" #include "RDFS.hpp" #include "URIEntry.hpp" #include "Window.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "lilv/lilv.h" -#include "lv2/urid/urid.h" -#include "raul/Path.hpp" -#include "sord/sordmm.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <lilv/lilv.h> +#include <lv2/urid/urid.h> +#include <raul/Path.hpp> +#include <sord/sordmm.hpp> #include <glibmm/containers.h> #include <glibmm/propertyproxy.h> -#include <glibmm/signalproxy.h> #include <glibmm/ustring.h> +#include <gtk/gtk.h> #include <gtkmm/alignment.h> #include <gtkmm/bin.h> #include <gtkmm/box.h> @@ -53,6 +56,7 @@ #include <gtkmm/table.h> #include <gtkmm/treeiter.h> #include <gtkmm/widget.h> +#include <gtkmm/window.h> #include <sigc++/adaptors/bind.h> #include <sigc++/functors/mem_fun.h> #include <sigc++/signal.h> @@ -76,7 +80,6 @@ using URISet = std::set<URI>; PropertiesWindow::PropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Window(cobject) - , _value_type(0) { xml->get_widget("properties_vbox", _vbox); xml->get_widget("properties_scrolledwindow", _scrolledwindow); @@ -185,16 +188,24 @@ PropertiesWindow::datatype_supported(const rdfs::URISet& types, if (types.find(_app->uris().atom_Int) != types.end()) { *widget_type = _app->uris().atom_Int; return true; - } else if (types.find(_app->uris().atom_Float) != types.end()) { + } + + if (types.find(_app->uris().atom_Float) != types.end()) { *widget_type = _app->uris().atom_Float; return true; - } else if (types.find(_app->uris().atom_Bool) != types.end()) { + } + + if (types.find(_app->uris().atom_Bool) != types.end()) { *widget_type = _app->uris().atom_Bool; return true; - } else if (types.find(_app->uris().atom_String) != types.end()) { + } + + if (types.find(_app->uris().atom_String) != types.end()) { *widget_type = _app->uris().atom_String; return true; - } else if (types.find(_app->uris().atom_URID) != types.end()) { + } + + if (types.find(_app->uris().atom_URID) != types.end()) { *widget_type = _app->uris().atom_URID; return true; } @@ -276,8 +287,9 @@ PropertiesWindow::set_object(const std::shared_ptr<const ObjectModel>& model) } for (const auto& e : entries) { - Gtk::ListStore::iterator ki = _key_store->append(); - Gtk::ListStore::Row row = *ki; + auto ki = _key_store->append(); + auto row = *ki; + row[_combo_columns.uri_col] = e.second.string(); row[_combo_columns.label_col] = e.first; } @@ -332,7 +344,9 @@ PropertiesWindow::create_value_widget(const URI& key, widget->signal_value_changed().connect( sigc::bind(sigc::mem_fun(this, &PropertiesWindow::on_change), key)); return widget; - } else if (type == _app->uris().atom_Float) { + } + + if (type == _app->uris().atom_Float) { Gtk::SpinButton* widget = manage(new Gtk::SpinButton(0.0, 4)); widget->property_numeric() = true; widget->set_snap_to_ticks(false); @@ -344,7 +358,9 @@ PropertiesWindow::create_value_widget(const URI& key, widget->signal_value_changed().connect( sigc::bind(sigc::mem_fun(this, &PropertiesWindow::on_change), key)); return widget; - } else if (type == _app->uris().atom_Bool) { + } + + if (type == _app->uris().atom_Bool) { Gtk::CheckButton* widget = manage(new Gtk::CheckButton()); if (value.is_valid()) { widget->set_active(value.get<int32_t>()); @@ -352,7 +368,9 @@ PropertiesWindow::create_value_widget(const URI& key, widget->signal_toggled().connect( sigc::bind(sigc::mem_fun(this, &PropertiesWindow::on_change), key)); return widget; - } else if (type == _app->uris().atom_String) { + } + + if (type == _app->uris().atom_String) { Gtk::Entry* widget = manage(new Gtk::Entry()); if (value.is_valid()) { widget->set_text(value.ptr<char>()); @@ -360,14 +378,16 @@ PropertiesWindow::create_value_widget(const URI& key, widget->signal_changed().connect( sigc::bind(sigc::mem_fun(this, &PropertiesWindow::on_change), key)); return widget; - } else if (type == _app->uris().atom_URID) { + } + + if (type == _app->uris().atom_URID) { const char* str = (value.is_valid() ? world.uri_map().unmap_uri(value.get<int32_t>()) : ""); - LilvNode* pred = lilv_new_uri(lworld, key.c_str()); - URISet ranges = rdfs::range(world, pred, true); - URIEntry* widget = manage(new URIEntry(_app, ranges, str ? str : "")); + LilvNode* pred = lilv_new_uri(lworld, key.c_str()); + const URISet ranges = rdfs::range(world, pred, true); + URIEntry* widget = manage(new URIEntry(_app, ranges, str ? str : "")); widget->signal_changed().connect( sigc::bind(sigc::mem_fun(this, &PropertiesWindow::on_change), key)); lilv_node_free(pred); @@ -383,10 +403,10 @@ PropertiesWindow::create_value_widget(const URI& key, if (type == _app->uris().atom_URI || type == _app->uris().rdfs_Class || is_class) { - LilvNode* pred = lilv_new_uri(lworld, key.c_str()); - URISet ranges = rdfs::range(world, pred, true); - const char* str = value.is_valid() ? value.ptr<const char>() : ""; - URIEntry* widget = manage(new URIEntry(_app, ranges, str)); + LilvNode* pred = lilv_new_uri(lworld, key.c_str()); + const URISet ranges = rdfs::range(world, pred, true); + const char* str = value.is_valid() ? value.ptr<const char>() : ""; + URIEntry* widget = manage(new URIEntry(_app, ranges, str)); widget->signal_changed().connect( sigc::bind(sigc::mem_fun(this, &PropertiesWindow::on_change), key)); lilv_node_free(pred); @@ -465,7 +485,7 @@ PropertiesWindow::remove_property(const URI& key, const Atom& value) Atom PropertiesWindow::get_value(LV2_URID type, Gtk::Widget* value_widget) { - Forge& forge = _app->forge(); + const Forge& forge = _app->forge(); if (type == forge.Int) { auto* spin = dynamic_cast<Gtk::SpinButton*>(value_widget); @@ -484,9 +504,11 @@ PropertiesWindow::get_value(LV2_URID type, Gtk::Widget* value_widget) } } else if (type == forge.URI || type == forge.URID) { auto* uri_entry = dynamic_cast<URIEntry*>(value_widget); - if (uri_entry && URI::is_valid(uri_entry->get_text())) { - return _app->forge().make_urid(URI(uri_entry->get_text())); - } else { + if (uri_entry) { + if (URI::is_valid(uri_entry->get_text())) { + return _app->forge().make_urid(URI(uri_entry->get_text())); + } + _app->log().error("Invalid URI <%1%>\n", uri_entry->get_text()); } } else if (type == forge.String) { @@ -496,7 +518,7 @@ PropertiesWindow::get_value(LV2_URID type, Gtk::Widget* value_widget) } } - return Atom(); + return {}; } void @@ -521,12 +543,12 @@ PropertiesWindow::on_change(const URI& key) std::string PropertiesWindow::active_key() const { - const Gtk::ListStore::iterator iter = _key_combo->get_active(); + const auto iter = _key_combo->get_active(); if (!iter) { return ""; } - Glib::ustring prop_uri = (*iter)[_combo_columns.uri_col]; + const Glib::ustring prop_uri = (*iter)[_combo_columns.uri_col]; return prop_uri; } diff --git a/src/gui/PropertiesWindow.hpp b/src/gui/PropertiesWindow.hpp index 780c2ba1..e788d140 100644 --- a/src/gui/PropertiesWindow.hpp +++ b/src/gui/PropertiesWindow.hpp @@ -19,15 +19,14 @@ #include "Window.hpp" -#include "ingen/Atom.hpp" -#include "ingen/URI.hpp" -#include "lv2/urid/urid.h" +#include <ingen/Atom.hpp> +#include <ingen/URI.hpp> +#include <lv2/urid/urid.h> #include <glibmm/refptr.h> #include <gtkmm/liststore.h> #include <gtkmm/treemodel.h> #include <gtkmm/treemodelcolumn.h> -#include <gtkmm/window.h> #include <sigc++/connection.h> #include <map> @@ -54,7 +53,9 @@ class Widget; namespace ingen { -namespace client { class ObjectModel; } +namespace client { +class ObjectModel; +} // namespace client namespace gui { @@ -129,16 +130,16 @@ private: Glib::RefPtr<Gtk::ListStore> _key_store; sigc::connection _property_connection; sigc::connection _property_removed_connection; - Gtk::VBox* _vbox; - Gtk::ScrolledWindow* _scrolledwindow; - Gtk::Table* _table; - Gtk::ComboBox* _key_combo; - LV2_URID _value_type; - Gtk::Bin* _value_bin; - Gtk::Button* _add_button; - Gtk::Button* _cancel_button; - Gtk::Button* _apply_button; - Gtk::Button* _ok_button; + Gtk::VBox* _vbox{nullptr}; + Gtk::ScrolledWindow* _scrolledwindow{nullptr}; + Gtk::Table* _table{nullptr}; + Gtk::ComboBox* _key_combo{nullptr}; + LV2_URID _value_type{0}; + Gtk::Bin* _value_bin{nullptr}; + Gtk::Button* _add_button{nullptr}; + Gtk::Button* _cancel_button{nullptr}; + Gtk::Button* _apply_button{nullptr}; + Gtk::Button* _ok_button{nullptr}; }; } // namespace gui diff --git a/src/gui/RDFS.cpp b/src/gui/RDFS.cpp index ed8d7e8c..09af81af 100644 --- a/src/gui/RDFS.cpp +++ b/src/gui/RDFS.cpp @@ -14,21 +14,20 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Forge.hpp" -#include "ingen/Log.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "lilv/lilv.h" - #include "RDFS.hpp" +#include <ingen/Forge.hpp> +#include <ingen/Log.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <lilv/lilv.h> + #include <utility> -namespace ingen { -namespace gui { -namespace rdfs { +namespace ingen::gui::rdfs { std::string label(World& world, const LilvNode* node) @@ -76,10 +75,10 @@ closure(World& world, const LilvNode* pred, URISet& types, bool super) world.lilv_world(), type, pred, nullptr) : lilv_world_find_nodes( world.lilv_world(), nullptr, pred, type); - LILV_FOREACH(nodes, m, matches) { + LILV_FOREACH (nodes, m, matches) { const LilvNode* klass_node = lilv_nodes_get(matches, m); if (lilv_node_is_uri(klass_node)) { - URI klass(lilv_node_as_uri(klass_node)); + const URI klass{lilv_node_as_uri(klass_node)}; if (!types.count(klass)) { ++added; klasses.insert(klass); @@ -118,20 +117,17 @@ datatypes(World& world, URISet& types, bool super) URISet types(World& world, const std::shared_ptr<const client::ObjectModel>& model) { - using PropIter = Properties::const_iterator; - using PropRange = std::pair<PropIter, PropIter>; - // Start with every rdf:type URISet types; types.insert(URI(LILV_NS_RDFS "Resource")); - PropRange range = model->properties().equal_range(world.uris().rdf_type); + const auto range = model->properties().equal_range(world.uris().rdf_type); for (auto t = range.first; t != range.second; ++t) { if (t->second.type() == world.forge().URI || t->second.type() == world.forge().URID) { const URI type(world.forge().str(t->second, false)); types.insert(type); if (world.uris().ingen_Graph == type) { - // Add lv2:Plugin as a type for graphs so plugin properties show up + // Add lv2:Plugin as a type so plugin properties show up types.insert(world.uris().lv2_Plugin); } } else { @@ -149,8 +145,8 @@ URISet properties(World& world, const std::shared_ptr<const client::ObjectModel>& model) { - URISet properties; - URISet types = rdfs::types(world, model); + URISet properties; + const URISet types = rdfs::types(world, model); LilvNode* rdf_type = lilv_new_uri(world.lilv_world(), LILV_NS_RDF "type"); @@ -161,13 +157,13 @@ properties(World& world, LilvNodes* props = lilv_world_find_nodes( world.lilv_world(), nullptr, rdf_type, rdf_Property); - LILV_FOREACH(nodes, p, props) { + LILV_FOREACH (nodes, p, props) { const LilvNode* prop = lilv_nodes_get(props, p); if (lilv_node_is_uri(prop)) { LilvNodes* domains = lilv_world_find_nodes( world.lilv_world(), prop, rdfs_domain, nullptr); unsigned n_matching_domains = 0; - LILV_FOREACH(nodes, d, domains) { + LILV_FOREACH (nodes, d, domains) { const LilvNode* domain_node = lilv_nodes_get(domains, d); if (!lilv_node_is_uri(domain_node)) { // TODO: Blank node domains (e.g. unions) @@ -208,7 +204,7 @@ instances(World& world, const URISet& types) LilvNode* type = lilv_new_uri(world.lilv_world(), t.c_str()); LilvNodes* objects = lilv_world_find_nodes( world.lilv_world(), nullptr, rdf_type, type); - LILV_FOREACH(nodes, o, objects) { + LILV_FOREACH (nodes, o, objects) { const LilvNode* object = lilv_nodes_get(objects, o); if (!lilv_node_is_uri(object)) { continue; @@ -233,7 +229,7 @@ range(World& world, const LilvNode* prop, bool recursive) world.lilv_world(), prop, rdfs_range, nullptr); URISet ranges; - LILV_FOREACH(nodes, n, nodes) { + LILV_FOREACH (nodes, n, nodes) { if (lilv_node_is_uri(lilv_nodes_get(nodes, n))) { ranges.insert(URI(lilv_node_as_string(lilv_nodes_get(nodes, n)))); } @@ -260,6 +256,4 @@ is_a(World& world, const LilvNode* inst, const LilvNode* klass) return is_instance; } -} // namespace rdfs -} // namespace gui -} // namespace ingen +} // namespace ingen::gui::rdfs diff --git a/src/gui/RDFS.hpp b/src/gui/RDFS.hpp index 4fac5546..e4c2b673 100644 --- a/src/gui/RDFS.hpp +++ b/src/gui/RDFS.hpp @@ -17,8 +17,8 @@ #ifndef INGEN_GUI_RDF_HPP #define INGEN_GUI_RDF_HPP -#include "ingen/URI.hpp" -#include "lilv/lilv.h" +#include <ingen/URI.hpp> +#include <lilv/lilv.h> #include <map> #include <memory> @@ -29,11 +29,11 @@ namespace ingen { class World; -namespace client { class ObjectModel; } +namespace client { +class ObjectModel; +} // namespace client -namespace gui { - -namespace rdfs { +namespace gui::rdfs { /** Set of URIs. */ using URISet = std::set<URI>; @@ -77,8 +77,7 @@ URISet range(World& world, const LilvNode* prop, bool recursive); /** Return true iff `inst` is-a `klass`. */ bool is_a(World& world, const LilvNode* inst, const LilvNode* klass); -} // namespace rdfs -} // namespace gui +} // namespace gui::rdfs } // namespace ingen #endif // INGEN_GUI_RDF_HPP diff --git a/src/gui/RenameWindow.cpp b/src/gui/RenameWindow.cpp index e2c1e98c..569baea8 100644 --- a/src/gui/RenameWindow.cpp +++ b/src/gui/RenameWindow.cpp @@ -19,24 +19,24 @@ #include "App.hpp" #include "Window.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "ingen/paths.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <glibmm/propertyproxy.h> #include <glibmm/refptr.h> -#include <glibmm/signalproxy.h> #include <glibmm/ustring.h> #include <gtkmm/builder.h> #include <gtkmm/button.h> #include <gtkmm/entry.h> #include <gtkmm/label.h> +#include <gtkmm/window.h> #include <sigc++/functors/mem_fun.h> #include <memory> diff --git a/src/gui/RenameWindow.hpp b/src/gui/RenameWindow.hpp index 004ca784..9c97d234 100644 --- a/src/gui/RenameWindow.hpp +++ b/src/gui/RenameWindow.hpp @@ -19,8 +19,6 @@ #include "Window.hpp" -#include <gtkmm/window.h> - #include <memory> namespace Glib { @@ -63,11 +61,11 @@ private: std::shared_ptr<const client::ObjectModel> _object; - Gtk::Entry* _symbol_entry; - Gtk::Entry* _label_entry; - Gtk::Label* _message_label; - Gtk::Button* _cancel_button; - Gtk::Button* _ok_button; + Gtk::Entry* _symbol_entry{nullptr}; + Gtk::Entry* _label_entry{nullptr}; + Gtk::Label* _message_label{nullptr}; + Gtk::Button* _cancel_button{nullptr}; + Gtk::Button* _ok_button{nullptr}; }; } // namespace gui diff --git a/src/gui/Style.cpp b/src/gui/Style.cpp index 5be83688..f1f1b12b 100644 --- a/src/gui/Style.cpp +++ b/src/gui/Style.cpp @@ -18,31 +18,23 @@ #include "App.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/PortModel.hpp" +#include <ingen/URIs.hpp> +#include <ingen/client/PortModel.hpp> #include <string> -namespace ingen { -namespace gui { +namespace ingen::gui { Style::Style(App& app) - // Colours from the Tango palette with modified V - : _app(app) + : _app(app) +{ #ifdef INGEN_USE_LIGHT_THEME - , _audio_port_color(0xC8E6ABFF) // Green - , _control_port_color(0xAAC0E6FF) // Blue - , _cv_port_color(0xACE6E0FF) // Teal (between audio and control) - , _event_port_color(0xE6ABABFF) // Red - , _string_port_color(0xD8ABE6FF) // Plum -#else - , _audio_port_color(0x4A8A0EFF) // Green - , _control_port_color(0x244678FF) // Blue - , _cv_port_color(0x248780FF) // Teal (between audio and control) - , _event_port_color(0x960909FF) // Red - , _string_port_color(0x5C3566FF) // Plum + _audio_port_color = 0xC8E6ABFF; + _control_port_color = 0xAAC0E6FF; + _cv_port_color = 0xACE6E0FF; + _event_port_color = 0xE6ABABFF; + _string_port_color = 0xD8ABE6FF; #endif -{ } /** Loads settings from the rc file. Passing no parameter will load from @@ -76,22 +68,32 @@ uint32_t Style::get_port_color(const client::PortModel* p) { const URIs& uris = _app.uris(); + if (p->is_a(uris.lv2_AudioPort)) { return _audio_port_color; - } else if (p->is_a(uris.lv2_ControlPort)) { + } + + if (p->is_a(uris.lv2_ControlPort)) { return _control_port_color; - } else if (p->is_a(uris.lv2_CVPort)) { + } + + if (p->is_a(uris.lv2_CVPort)) { return _cv_port_color; - } else if (p->supports(uris.atom_String)) { + } + + if (p->supports(uris.atom_String)) { return _string_port_color; - } else if (_app.can_control(p)) { + } + + if (_app.can_control(p)) { return _control_port_color; - } else if (p->is_a(uris.atom_AtomPort)) { + } + + if (p->is_a(uris.atom_AtomPort)) { return _event_port_color; } return 0x555555FF; } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/Style.hpp b/src/gui/Style.hpp index bc94d64a..20d560a8 100644 --- a/src/gui/Style.hpp +++ b/src/gui/Style.hpp @@ -45,11 +45,12 @@ public: private: App& _app; - uint32_t _audio_port_color; - uint32_t _control_port_color; - uint32_t _cv_port_color; - uint32_t _event_port_color; - uint32_t _string_port_color; + // Colours from the Tango palette with modified V + uint32_t _audio_port_color{0x4A8A0EFF}; // Green + uint32_t _control_port_color{0x244678FF}; // Blue + uint32_t _cv_port_color{0x248780FF}; // Teal {between audio/control} + uint32_t _event_port_color{0x960909FF}; // Red + uint32_t _string_port_color{0x5C3566FF}; // Plum }; } // namespace gui diff --git a/src/gui/SubgraphModule.cpp b/src/gui/SubgraphModule.cpp index fee602b5..a1b14bb6 100644 --- a/src/gui/SubgraphModule.cpp +++ b/src/gui/SubgraphModule.cpp @@ -20,16 +20,17 @@ #include "NodeModule.hpp" #include "WindowFactory.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URIs.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/GraphModel.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/GraphModel.hpp> #include <cassert> #include <memory> +#include <utility> namespace ingen { diff --git a/src/gui/ThreadedLoader.cpp b/src/gui/ThreadedLoader.cpp index 663529da..abbedbaf 100644 --- a/src/gui/ThreadedLoader.cpp +++ b/src/gui/ThreadedLoader.cpp @@ -18,29 +18,31 @@ #include "App.hpp" -#include "ingen/Log.hpp" -#include "ingen/Parser.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Serialiser.hpp" -#include "ingen/URI.hpp" -#include "ingen/World.hpp" -#include "ingen/client/GraphModel.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" - -#include <boost/optional/optional.hpp> +#include <ingen/FilePath.hpp> +#include <ingen/Log.hpp> +#include <ingen/Parser.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Serialiser.hpp> +#include <ingen/URI.hpp> +#include <ingen/World.hpp> +#include <ingen/client/GraphModel.hpp> +#include <raul/Path.hpp> +#include <raul/Semaphore.hpp> +#include <raul/Symbol.hpp> + #include <glibmm/ustring.h> #include <sigc++/adaptors/bind.h> #include <sigc++/adaptors/retype_return.h> #include <sigc++/functors/mem_fun.h> #include <cassert> +#include <filesystem> #include <memory> +#include <optional> #include <string> +#include <string_view> #include <utility> -using boost::optional; - namespace ingen { class Interface; @@ -49,9 +51,7 @@ namespace gui { ThreadedLoader::ThreadedLoader(App& app, std::shared_ptr<Interface> engine) : _app(app) - , _sem(0) , _engine(std::move(engine)) - , _exit_flag(false) , _thread(&ThreadedLoader::run, this) { if (!parser()) { @@ -78,7 +78,7 @@ void ThreadedLoader::run() { while (_sem.wait() && !_exit_flag) { - std::lock_guard<std::mutex> lock(_mutex); + const std::lock_guard<std::mutex> lock{_mutex}; while (!_events.empty()) { _events.front()(); _events.pop_front(); @@ -87,20 +87,20 @@ ThreadedLoader::run() } void -ThreadedLoader::load_graph(bool merge, - const FilePath& file_path, - const optional<raul::Path>& engine_parent, - const optional<raul::Symbol>& engine_symbol, - const optional<Properties>& engine_data) +ThreadedLoader::load_graph(bool merge, + const FilePath& file_path, + const std::optional<raul::Path>& engine_parent, + const std::optional<raul::Symbol>& engine_symbol, + const std::optional<Properties>& engine_data) { - std::lock_guard<std::mutex> lock(_mutex); + const std::lock_guard<std::mutex> lock{_mutex}; Glib::ustring engine_base = ""; if (engine_parent) { if (merge) { - engine_base = engine_parent.get(); + engine_base = *engine_parent; } else { - engine_base = engine_parent.get().base(); + engine_base = engine_parent->base(); } } @@ -115,12 +115,13 @@ ThreadedLoader::load_graph(bool merge, } void -ThreadedLoader::load_graph_event(const FilePath& file_path, - const optional<raul::Path>& engine_parent, - const optional<raul::Symbol>& engine_symbol, - const optional<Properties>& engine_data) +ThreadedLoader::load_graph_event( + const FilePath& file_path, + const std::optional<raul::Path>& engine_parent, + const std::optional<raul::Symbol>& engine_symbol, + const std::optional<Properties>& engine_data) { - std::lock_guard<std::mutex> lock(_app.world().rdf_mutex()); + const std::lock_guard<std::mutex> lock{_app.world().rdf_mutex()}; _app.world().parser()->parse_file(_app.world(), *_app.world().interface(), @@ -135,7 +136,7 @@ ThreadedLoader::save_graph( const std::shared_ptr<const client::GraphModel>& model, const URI& uri) { - std::lock_guard<std::mutex> lock(_mutex); + const std::lock_guard<std::mutex> lock{_mutex}; _events.emplace_back(sigc::hide_return( sigc::bind(sigc::mem_fun(this, &ThreadedLoader::save_graph_event), @@ -152,7 +153,7 @@ ThreadedLoader::save_graph_event( { assert(uri.scheme() == "file"); if (_app.serialiser()) { - std::lock_guard<std::mutex> lock(_app.world().rdf_mutex()); + const std::lock_guard<std::mutex> lock{_app.world().rdf_mutex()}; if (uri.string().find(".ingen") != std::string::npos) { _app.serialiser()->write_bundle(model, uri); diff --git a/src/gui/ThreadedLoader.hpp b/src/gui/ThreadedLoader.hpp index 5e9392bc..27ba7c8c 100644 --- a/src/gui/ThreadedLoader.hpp +++ b/src/gui/ThreadedLoader.hpp @@ -17,20 +17,17 @@ #ifndef INGEN_GUI_THREADEDLOADER_HPP #define INGEN_GUI_THREADEDLOADER_HPP -#include "ingen/FilePath.hpp" -#include "raul/Semaphore.hpp" +#include <ingen/FilePath.hpp> +#include <raul/Semaphore.hpp> #include <sigc++/functors/slot.h> #include <list> #include <memory> #include <mutex> +#include <optional> #include <thread> -namespace boost { -template <class T> class optional; -} // namespace boost - namespace raul { class Path; class Symbol; @@ -43,7 +40,9 @@ class Parser; class Properties; class URI; -namespace client { class GraphModel; } +namespace client { +class GraphModel; +} // namespace client namespace gui { @@ -51,7 +50,7 @@ class App; /** Thread for loading graph files. * - * This is a seperate thread so it can send all the loading message without + * This is a separate thread so it can send all the loading message without * blocking everything else, so the app can respond to the incoming events * caused as a result of the graph loading, while the graph loads. * @@ -68,11 +67,11 @@ public: ~ThreadedLoader(); - void load_graph(bool merge, - const FilePath& file_path, - const boost::optional<raul::Path>& engine_parent, - const boost::optional<raul::Symbol>& engine_symbol, - const boost::optional<Properties>& engine_data); + void load_graph(bool merge, + const FilePath& file_path, + const std::optional<raul::Path>& engine_parent, + const std::optional<raul::Symbol>& engine_symbol, + const std::optional<Properties>& engine_data); void save_graph(const std::shared_ptr<const client::GraphModel>& model, const URI& uri); @@ -80,26 +79,26 @@ public: std::shared_ptr<Parser> parser(); private: - void load_graph_event(const FilePath& file_path, - const boost::optional<raul::Path>& engine_parent, - const boost::optional<raul::Symbol>& engine_symbol, - const boost::optional<Properties>& engine_data); + void load_graph_event(const FilePath& file_path, + const std::optional<raul::Path>& engine_parent, + const std::optional<raul::Symbol>& engine_symbol, + const std::optional<Properties>& engine_data); void save_graph_event(const std::shared_ptr<const client::GraphModel>& model, const URI& uri); - /** Returns nothing and takes no parameters (because they have all been bound) */ + /// Returns nothing and takes no parameters (because they're all bound) using Closure = sigc::slot<void>; void run(); App& _app; - raul::Semaphore _sem; + raul::Semaphore _sem{0}; std::shared_ptr<Interface> _engine; std::mutex _mutex; std::list<Closure> _events; - bool _exit_flag; + bool _exit_flag{false}; std::thread _thread; }; diff --git a/src/gui/URIEntry.cpp b/src/gui/URIEntry.cpp index 036e7a0b..92320009 100644 --- a/src/gui/URIEntry.cpp +++ b/src/gui/URIEntry.cpp @@ -19,15 +19,15 @@ #include "App.hpp" #include "RDFS.hpp" -#include "ingen/World.hpp" +#include <ingen/URI.hpp> +#include <ingen/World.hpp> +#include <lilv/lilv.h> #include <gdk/gdk.h> -#include <glibmm/helperlist.h> #include <gtkmm/button.h> #include <gtkmm/menu.h> #include <gtkmm/menu_elems.h> #include <gtkmm/menuitem.h> -#include <gtkmm/menushell.h> #include <gtkmm/object.h> #include <sigc++/adaptors/bind.h> #include <sigc++/functors/mem_fun.h> @@ -35,8 +35,7 @@ #include <map> #include <utility> -namespace ingen { -namespace gui { +namespace ingen::gui { URIEntry::URIEntry(App* app, std::set<URI> types, const std::string& value) : Gtk::HBox(false, 4) @@ -67,7 +66,7 @@ URIEntry::build_value_menu() LilvNode* rdfs_Datatype = lilv_new_uri(lworld, LILV_NS_RDFS "Datatype"); LilvNode* rdfs_subClassOf = lilv_new_uri(lworld, LILV_NS_RDFS "subClassOf"); - rdfs::Objects values = rdfs::instances(world, _types); + const rdfs::Objects values = rdfs::instances(world, _types); for (const auto& v : values) { const LilvNode* inst = lilv_new_uri(lworld, v.second.c_str()); @@ -131,11 +130,11 @@ URIEntry::build_subclass_menu(const LilvNode* klass) // Put subclasses/types in a map keyed by label (to sort menu) std::map<std::string, const LilvNode*> entries; - LILV_FOREACH(nodes, s, subclasses) { + LILV_FOREACH (nodes, s, subclasses) { const LilvNode* node = lilv_nodes_get(subclasses, s); entries.emplace(rdfs::label(world, node), node); } - LILV_FOREACH(nodes, s, subtypes) { + LILV_FOREACH (nodes, s, subtypes) { const LilvNode* node = lilv_nodes_get(subtypes, s); entries.emplace(rdfs::label(world, node), node); } @@ -203,5 +202,4 @@ URIEntry::menu_button_event(GdkEvent* ev) return true; } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/URIEntry.hpp b/src/gui/URIEntry.hpp index cc8f96a3..45fa6894 100644 --- a/src/gui/URIEntry.hpp +++ b/src/gui/URIEntry.hpp @@ -17,8 +17,8 @@ #ifndef INGEN_GUI_URI_ENTRY_HPP #define INGEN_GUI_URI_ENTRY_HPP -#include "ingen/URI.hpp" -#include "lilv/lilv.h" +#include <ingen/URI.hpp> +#include <lilv/lilv.h> #include <gdk/gdk.h> #include <glibmm/signalproxy.h> @@ -34,12 +34,12 @@ class Button; class Menu; } // namespace Gtk -namespace ingen { -namespace gui { +namespace ingen::gui { class App; -class URIEntry : public Gtk::HBox { +class URIEntry : public Gtk::HBox +{ public: /** Create a widget for entering URIs. * @@ -72,7 +72,6 @@ private: Gtk::Entry* _entry; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui #endif // INGEN_GUI_URI_ENTRY_HPP diff --git a/src/gui/WidgetFactory.cpp b/src/gui/WidgetFactory.cpp index 2bd7b5fd..33660d77 100644 --- a/src/gui/WidgetFactory.cpp +++ b/src/gui/WidgetFactory.cpp @@ -16,20 +16,18 @@ #include "WidgetFactory.hpp" -#include "ingen/FilePath.hpp" -#include "ingen/runtime_paths.hpp" +#include <ingen/runtime_paths.hpp> #include <cstdlib> #include <fstream> #include <stdexcept> #include <string> -namespace ingen { -namespace gui { +namespace ingen::gui { Glib::ustring WidgetFactory::ui_filename = ""; -inline static bool +static inline bool is_readable(const std::string& filename) { std::ifstream fs(filename.c_str()); @@ -72,10 +70,9 @@ WidgetFactory::create(const std::string& toplevel_widget) if (toplevel_widget.empty()) { return Gtk::Builder::create_from_file(ui_filename); - } else { - return Gtk::Builder::create_from_file(ui_filename, toplevel_widget.c_str()); } + + return Gtk::Builder::create_from_file(ui_filename, toplevel_widget.c_str()); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/WidgetFactory.hpp b/src/gui/WidgetFactory.hpp index 11ef71d1..d10a5e1a 100644 --- a/src/gui/WidgetFactory.hpp +++ b/src/gui/WidgetFactory.hpp @@ -19,32 +19,32 @@ #include <glibmm/refptr.h> #include <glibmm/ustring.h> -#include <gtkmm/builder.h> // IWYU pragma: keep +#include <gtkmm/builder.h> #include <string> -namespace ingen { -namespace gui { +namespace ingen::gui { /** Loads widgets from an XML description. * Purely static. * * \ingroup GUI */ -class WidgetFactory { +class WidgetFactory +{ public: static Glib::RefPtr<Gtk::Builder> create(const std::string& toplevel_widget=""); template<typename T> static void get_widget(const Glib::ustring& name, T*& widget) { - Glib::RefPtr<Gtk::Builder> xml = create(name); + const Glib::RefPtr<Gtk::Builder> xml = create(name); xml->get_widget(name, widget); } template<typename T> static void get_widget_derived(const Glib::ustring& name, T*& widget) { - Glib::RefPtr<Gtk::Builder> xml = create(name); + const Glib::RefPtr<Gtk::Builder> xml = create(name); xml->get_widget_derived(name, widget); } @@ -53,7 +53,6 @@ private: static Glib::ustring ui_filename; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui #endif // INGEN_GUI_WIDGETFACTORY_HPP diff --git a/src/gui/Window.hpp b/src/gui/Window.hpp index acf75942..756ba8f0 100644 --- a/src/gui/Window.hpp +++ b/src/gui/Window.hpp @@ -22,9 +22,7 @@ #include <gtkmm/dialog.h> #include <gtkmm/window.h> -namespace ingen { - -namespace gui { +namespace ingen::gui { class App; @@ -38,8 +36,7 @@ public: explicit Window(BaseObjectType* cobject) : Gtk::Window(cobject) - { - } + {} virtual void init_window(App& app) { _app = &app; } @@ -66,8 +63,7 @@ public: explicit Dialog(BaseObjectType* cobject) : Gtk::Dialog(cobject) - { - } + {} virtual void init_dialog(App& app) { _app = &app; } @@ -82,7 +78,6 @@ public: App* _app = nullptr; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui #endif // INGEN_GUI_WINDOW_HPP diff --git a/src/gui/WindowFactory.cpp b/src/gui/WindowFactory.cpp index 4e48f157..78acf4fb 100644 --- a/src/gui/WindowFactory.cpp +++ b/src/gui/WindowFactory.cpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2015 David Robillard <http://drobilla.net/> + Copyright 2007-2024 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -14,9 +14,10 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include "WindowFactory.hpp" + #include "App.hpp" #include "GraphBox.hpp" -#include "GraphView.hpp" #include "GraphWindow.hpp" #include "LoadGraphWindow.hpp" #include "LoadPluginWindow.hpp" @@ -24,18 +25,18 @@ #include "PropertiesWindow.hpp" #include "RenameWindow.hpp" #include "WidgetFactory.hpp" -#include "WindowFactory.hpp" -#include "ingen/Log.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/client/ObjectModel.hpp" +#include <ingen/Log.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <raul/Path.hpp> #include <gdkmm/window.h> -#include <glibmm/signalproxy.h> #include <sigc++/adaptors/bind.h> #include <sigc++/functors/mem_fun.h> +#include <algorithm> #include <cassert> #include <memory> #include <stdexcept> @@ -44,6 +45,8 @@ namespace ingen { +class Properties; + using client::BlockModel; using client::GraphModel; using client::ObjectModel; @@ -52,11 +55,6 @@ namespace gui { WindowFactory::WindowFactory(App& app) : _app(app) - , _main_box(nullptr) - , _load_plugin_win(nullptr) - , _load_graph_win(nullptr) - , _new_subgraph_win(nullptr) - , _properties_win(nullptr) { WidgetFactory::get_widget_derived("load_plugin_win", _load_plugin_win); WidgetFactory::get_widget_derived("load_graph_win", _load_graph_win); @@ -98,14 +96,9 @@ WindowFactory::clear() size_t WindowFactory::num_open_graph_windows() { - size_t ret = 0; - for (const auto& w : _graph_windows) { - if (w.second->is_visible()) { - ++ret; - } - } - - return ret; + return std::count_if(_graph_windows.begin(), + _graph_windows.end(), + [](const auto& w) { return w.second->is_visible(); }); } GraphBox* @@ -114,9 +107,9 @@ WindowFactory::graph_box(const std::shared_ptr<const GraphModel>& graph) GraphWindow* window = graph_window(graph); if (window) { return window->box(); - } else { - return _main_box; } + + return _main_box; } GraphWindow* @@ -153,8 +146,6 @@ WindowFactory::present_graph(const std::shared_ptr<const GraphModel>& graph, GraphWindow* preferred, const std::shared_ptr<GraphView>& view) { - assert(!view || view->graph() == graph); - auto w = _graph_windows.find(graph->path()); if (w != _graph_windows.end()) { @@ -178,8 +169,6 @@ GraphWindow* WindowFactory::new_graph_window(const std::shared_ptr<const GraphModel>& graph, const std::shared_ptr<GraphView>& view) { - assert(!view || view->graph() == graph); - GraphWindow* win = nullptr; WidgetFactory::get_widget_derived("graph_win", win); if (!win) { @@ -235,7 +224,7 @@ WindowFactory::present_load_plugin( int width = 0; int height = 0; w->second->get_size(width, height); - _load_plugin_win->set_default_size(width - width / 8, height / 2); + _load_plugin_win->set_default_size(width - (width / 8), height / 2); } _load_plugin_win->set_title( std::string("Load Plugin - ") + graph->path() + " - Ingen"); diff --git a/src/gui/WindowFactory.hpp b/src/gui/WindowFactory.hpp index 581e2e0f..e643505a 100644 --- a/src/gui/WindowFactory.hpp +++ b/src/gui/WindowFactory.hpp @@ -17,8 +17,8 @@ #ifndef INGEN_GUI_WINDOWFACTORY_HPP #define INGEN_GUI_WINDOWFACTORY_HPP -#include "ingen/Properties.hpp" -#include "raul/Path.hpp" +#include <ingen/Properties.hpp> +#include <raul/Path.hpp> #include <gdk/gdk.h> @@ -52,7 +52,8 @@ class RenameWindow; * as well as an enumeration of all windows (the goal being to reduce that * number as much as possible). */ -class WindowFactory { +class WindowFactory +{ public: explicit WindowFactory(App& app); ~WindowFactory(); @@ -106,13 +107,13 @@ private: const std::shared_ptr<GraphView>& view); App& _app; - GraphBox* _main_box; + GraphBox* _main_box{nullptr}; GraphWindowMap _graph_windows; - LoadPluginWindow* _load_plugin_win; - LoadGraphWindow* _load_graph_win; - NewSubgraphWindow* _new_subgraph_win; - PropertiesWindow* _properties_win; - RenameWindow* _rename_win; + LoadPluginWindow* _load_plugin_win{nullptr}; + LoadGraphWindow* _load_graph_win{nullptr}; + NewSubgraphWindow* _new_subgraph_win{nullptr}; + PropertiesWindow* _properties_win{nullptr}; + RenameWindow* _rename_win{nullptr}; }; } // namespace gui diff --git a/src/gui/ingen_gui.cpp b/src/gui/ingen_gui.cpp index 118a9000..7fba2d50 100644 --- a/src/gui/ingen_gui.cpp +++ b/src/gui/ingen_gui.cpp @@ -16,27 +16,27 @@ #include "App.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Module.hpp" -#include "ingen/QueuedInterface.hpp" -#include "ingen/URI.hpp" -#include "ingen/World.hpp" -#include "ingen/client/SigClientInterface.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Module.hpp> +#include <ingen/QueuedInterface.hpp> +#include <ingen/URI.hpp> +#include <ingen/World.hpp> +#include <ingen/client/SigClientInterface.hpp> #include <glibmm/thread.h> #include <memory> +#include <string> -namespace ingen { -namespace gui { +namespace ingen::gui { struct GUIModule : public Module { using SigClientInterface = client::SigClientInterface; void load(World& world) override { - URI uri(world.conf().option("connect").ptr<char>()); + const URI uri{world.conf().option("connect").ptr<char>()}; if (!world.interface()) { world.set_interface( world.new_interface(URI(uri), make_client(world))); @@ -63,12 +63,11 @@ struct GUIModule : public Module { std::shared_ptr<gui::App> app; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui extern "C" { -ingen::Module* +INGEN_MODULE_EXPORT ingen::Module* ingen_module_load() { Glib::thread_init(); diff --git a/src/gui/ingen_gui.ui b/src/gui/ingen_gui.ui.in index 9e751064..9e751064 100644 --- a/src/gui/ingen_gui.ui +++ b/src/gui/ingen_gui.ui.in diff --git a/src/gui/ingen_gui_lv2.cpp b/src/gui/ingen_gui_lv2.cpp index ffa50779..67290c76 100644 --- a/src/gui/ingen_gui_lv2.cpp +++ b/src/gui/ingen_gui_lv2.cpp @@ -17,28 +17,28 @@ #include "App.hpp" #include "GraphBox.hpp" -#include "ingen/AtomReader.hpp" -#include "ingen/AtomSink.hpp" -#include "ingen/AtomWriter.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" // IWYU pragma: keep -#include "ingen/client/SigClientInterface.hpp" -#include "ingen/ingen.h" -#include "ingen/paths.hpp" -#include "ingen/runtime_paths.hpp" -#include "lv2/atom/atom.h" -#include "lv2/atom/util.h" -#include "lv2/core/lv2.h" -#include "lv2/log/log.h" -#include "lv2/ui/ui.h" -#include "lv2/urid/urid.h" -#include "raul/Path.hpp" +#include <ingen/AtomReader.hpp> +#include <ingen/AtomSink.hpp> +#include <ingen/AtomWriter.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/SigClientInterface.hpp> +#include <ingen/ingen.h> +#include <ingen/paths.hpp> +#include <ingen/runtime_paths.hpp> +#include <lv2/atom/atom.h> +#include <lv2/atom/util.h> +#include <lv2/core/lv2.h> +#include <lv2/log/log.h> +#include <lv2/ui/ui.h> +#include <lv2/urid/urid.h> +#include <raul/Path.hpp> #include <cstdint> #include <cstring> @@ -49,7 +49,8 @@ namespace ingen { /** A sink that writes atoms to a port via the UI extension. */ -struct IngenLV2AtomSink : public AtomSink { +class IngenLV2AtomSink : public AtomSink { +public: IngenLV2AtomSink(URIs& uris, LV2UI_Write_Function ui_write, LV2UI_Controller ui_controller) @@ -67,25 +68,18 @@ struct IngenLV2AtomSink : public AtomSink { return true; } +private: URIs& _uris; LV2UI_Write_Function _ui_write; LV2UI_Controller _ui_controller; }; struct IngenLV2UI { - IngenLV2UI() - : argc(0) - , argv(nullptr) - , forge(nullptr) - , world(nullptr) - , sink(nullptr) - {} - - int argc; - char** argv; - Forge* forge; - World* world; - IngenLV2AtomSink* sink; + int argc{0}; + char** argv{nullptr}; + Forge* forge{nullptr}; + World* world{nullptr}; + IngenLV2AtomSink* sink{nullptr}; std::shared_ptr<gui::App> app; std::shared_ptr<gui::GraphBox> view; std::shared_ptr<Interface> engine; diff --git a/src/gui/meson.build b/src/gui/meson.build new file mode 100644 index 00000000..810c7829 --- /dev/null +++ b/src/gui/meson.build @@ -0,0 +1,179 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +################ +# Dependencies # +################ + +gui_defines = platform_defines + +glibmm_dep = dependency( + 'glibmm-2.4', + include_type: 'system', + required: get_option('gui'), + version: '>= 2.14.0', +) + +gthread_dep = dependency( + 'gthread-2.0', + include_type: 'system', + required: get_option('gui'), + version: '>= 2.14.0', +) + +gtkmm_dep = dependency( + 'gtkmm-2.4', + include_type: 'system', + required: get_option('gui'), + version: '>= 2.14.0', +) + +ganv_dep = dependency( + 'ganv-1', + include_type: 'system', + required: get_option('gui'), + version: '>= 1.5.2', +) + +webkit_dep = dependency( + 'webkit-1.0', + include_type: 'system', + required: false, + version: '>= 1.4.0', +) + +build_gui = ( + glibmm_dep.found() + and gthread_dep.found() + and gtkmm_dep.found() + and ganv_dep.found() +) + +if webkit_dep.found() + gui_defines += ['-DHAVE_WEBKIT=1'] +else + gui_defines += ['-DHAVE_WEBKIT=0'] +endif + +########## +# Module # +########## + +if build_gui + gui_sources = files( + 'App.cpp', + 'Arc.cpp', + 'BreadCrumbs.cpp', + 'ConnectWindow.cpp', + 'GraphBox.cpp', + 'GraphCanvas.cpp', + 'GraphPortModule.cpp', + 'GraphTreeWindow.cpp', + 'GraphView.cpp', + 'GraphWindow.cpp', + 'LoadGraphWindow.cpp', + 'LoadPluginWindow.cpp', + 'MessagesWindow.cpp', + 'NewSubgraphWindow.cpp', + 'NodeMenu.cpp', + 'NodeModule.cpp', + 'ObjectMenu.cpp', + 'PluginMenu.cpp', + 'Port.cpp', + 'PortMenu.cpp', + 'PropertiesWindow.cpp', + 'RDFS.cpp', + 'RenameWindow.cpp', + 'Style.cpp', + 'SubgraphModule.cpp', + 'ThreadedLoader.cpp', + 'URIEntry.cpp', + 'WidgetFactory.cpp', + 'WindowFactory.cpp', + 'ingen_gui.cpp', + ) + + gui_dependencies = [ + boost_dep, + ganv_dep, + glibmm_dep, + gthread_dep, + gtkmm_dep, + ingen_client_dep, + ingen_dep, + lilv_dep, + raul_dep, + sigcpp_dep, + suil_dep, + thread_dep, + webkit_dep, + ] + + gui_suppressions = [] + if cpp.get_id() == 'clang' + gui_suppressions += [ + '-Wno-reserved-identifier', # Ganv + ] + endif + + gui_suppressions = cpp.get_supported_arguments(gui_suppressions) + gui_suppressions += cpp_suppressions + + gui_args = gui_suppressions + gui_defines + ['-DINGEN_GUI_INTERNAL'] + + libingen_gui = shared_library( + 'ingen_gui', + gui_sources, + cpp_args: gui_args, + dependencies: gui_dependencies, + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: ingen_module_dir, + ) + + ingen_gui_dep = declare_dependency( + dependencies: gui_dependencies, + link_with: libingen_gui, + ) + + ########## + # LV2 UI # + ########## + + ingen_gui_lv2 = shared_library( + 'ingen_gui_lv2', + files('ingen_gui_lv2.cpp'), + cpp_args: gui_args, + dependencies: [ingen_gui_dep], + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: lv2dir / 'ingen.lv2', + ) + + ############### + # Shared Data # + ############### + + config = configuration_data() + config.set('INGEN_VERSION', meson.project_version()) + + configure_file( + configuration: config, + input: files('ingen_gui.ui.in'), + install: true, + install_dir: ingen_data_dir, + output: 'ingen_gui.ui', + ) + + configure_file( + copy: true, + input: files('ingen_style.rc'), + install: true, + install_dir: ingen_data_dir, + output: '@PLAINNAME@', + ) +endif diff --git a/src/gui/rgba.hpp b/src/gui/rgba.hpp index bd8de2d2..e01a069d 100644 --- a/src/gui/rgba.hpp +++ b/src/gui/rgba.hpp @@ -20,10 +20,9 @@ #include <cmath> #include <cstdint> -namespace ingen { -namespace gui { +namespace ingen::gui { -static inline uint32_t +inline uint32_t rgba_to_uint(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { return ((static_cast<uint32_t>(r) << 24) | @@ -32,10 +31,10 @@ rgba_to_uint(uint8_t r, uint8_t g, uint8_t b, uint8_t a) (static_cast<uint32_t>(a))); } -static inline uint8_t +inline uint8_t mono_interpolate(uint8_t v1, uint8_t v2, float f) { - return static_cast<int>(rintf((v2) * (f) + (v1) * (1 - (f)))); + return static_cast<uint8_t>(rintf((v2 * f) + (v1 * (1.0f - f)))); } #define RGBA_R(x) (static_cast<uint32_t>(x) >> 24) @@ -43,7 +42,7 @@ mono_interpolate(uint8_t v1, uint8_t v2, float f) #define RGBA_B(x) ((static_cast<uint32_t>(x) >> 8) & 0xFF) #define RGBA_A(x) (static_cast<uint32_t>(x) & 0xFF) -static inline uint32_t +inline uint32_t rgba_interpolate(uint32_t c1, uint32_t c2, float f) { return rgba_to_uint( @@ -53,7 +52,6 @@ rgba_interpolate(uint32_t c1, uint32_t c2, float f) mono_interpolate(RGBA_A(c1), RGBA_A(c2), f)); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui #endif // INGEN_GUI_RGBA_HPP diff --git a/src/gui/wscript b/src/gui/wscript deleted file mode 100644 index f2471933..00000000 --- a/src/gui/wscript +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env python - -import waflib.Utils as Utils -import waflib.Options as Options - - -def options(ctx): - opt = ctx.configuration_options() - opt.add_option('--light-theme', action='store_true', dest='light_theme', - help='use light coloured theme') - - -def configure(conf): - conf.check_pkg('glibmm-2.4 >= 2.14.0', - uselib_store='GLIBMM', - system=True, - mandatory=False) - conf.check_pkg('gthread-2.0 >= 2.14.0', - uselib_store='GTHREAD', - system=True, - mandatory=False) - conf.check_pkg('gtkmm-2.4 >= 2.14.0', - uselib_store='GTKMM', - system=True, - mandatory=False) - conf.check_pkg('ganv-1 >= 1.5.4', - uselib_store='GANV', - mandatory=False) - if not Options.options.no_webkit: - conf.check_pkg('webkit-1.0 >= 1.4.0', - uselib_store='WEBKIT', - system=True, - mandatory=False) - - if conf.env.HAVE_GANV and conf.env.HAVE_GTKMM: - conf.env.INGEN_BUILD_GUI = 1 - - if Options.options.light_theme: - conf.define('INGEN_USE_LIGHT_THEME', 1) - - -def build(bld): - obj = bld(features = 'cxx cxxshlib', - cflags = ['-fvisibility=hidden'], - export_includes = ['../../include'], - includes = ['../../', '../../include'], - name = 'libingen_gui', - target = 'ingen_gui', - install_path = '${LIBDIR}', - use = 'libingen libingen_client', - uselib = ''' - GANV - GLADEMM - GLIBMM - GNOMECANVAS - GTKMM - LILV - LV2 - RAUL - SIGCPP - SERD - SORD - SRATOM - SOUP - SUIL - WEBKIT - ''') - - obj.source = ''' - App.cpp - Arc.cpp - BreadCrumbs.cpp - ConnectWindow.cpp - GraphBox.cpp - GraphCanvas.cpp - GraphPortModule.cpp - GraphTreeWindow.cpp - GraphView.cpp - GraphWindow.cpp - LoadGraphWindow.cpp - LoadPluginWindow.cpp - MessagesWindow.cpp - NewSubgraphWindow.cpp - NodeMenu.cpp - NodeModule.cpp - ObjectMenu.cpp - PluginMenu.cpp - Port.cpp - PortMenu.cpp - PropertiesWindow.cpp - RDFS.cpp - RenameWindow.cpp - Style.cpp - SubgraphModule.cpp - ThreadedLoader.cpp - URIEntry.cpp - WidgetFactory.cpp - WindowFactory.cpp - ingen_gui.cpp - ''' - - # XML UI definition - bld(features = 'subst', - source = 'ingen_gui.ui', - target = '../../ingen_gui.ui', - install_path = '${DATADIR}/ingen', - chmod = Utils.O755, - INGEN_VERSION = bld.env.INGEN_VERSION) - - # Gtk style - bld(features = 'subst', - is_copy = True, - source = 'ingen_style.rc', - target = '../../ingen_style.rc', - install_path = '${DATADIR}/ingen', - chmod = Utils.O755) - - # LV2 UI - obj = bld(features = 'cxx cxxshlib', - cflags = ['-fvisibility=hidden'], - source = 'ingen_gui_lv2.cpp', - includes = ['.', '../../', '../../include'], - name = 'ingen_gui_lv2', - target = 'ingen_gui_lv2', - install_path = '${LV2DIR}/ingen.lv2/', - use = 'libingen libingen_gui', - uselib = 'LV2 SERD SORD SRATOM LILV RAUL GLIBMM GTKMM') diff --git a/src/include/ingen_config.h b/src/include/ingen_config.h new file mode 100644 index 00000000..6d5f36e0 --- /dev/null +++ b/src/include/ingen_config.h @@ -0,0 +1,216 @@ +// Copyright 2021-2022 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +/* + Configuration header that defines reasonable defaults at compile time. + + This allows compile-time configuration from the command line, while still + allowing the source to be built "as-is" without any configuration. The idea + is to support an advanced build system with configuration checks, while still + allowing the code to be simply "thrown at a compiler" with features + determined from the compiler or system headers. Everything can be + overridden, so it should never be necessary to edit this file to build + successfully. + + To ensure that all configure checks are performed, the build system can + define INGEN_NO_DEFAULT_CONFIG to disable defaults. In this case, it must + define all HAVE_FEATURE symbols below to 1 or 0 to enable or disable + features. Any missing definitions will generate a compiler warning. + + To ensure that this header is always included properly, all code that uses + configuration variables includes this header and checks their value with #if + (not #ifdef). Variables like USE_FEATURE are internal and should never be + defined on the command line. +*/ + +#ifndef INGEN_CONFIG_H +#define INGEN_CONFIG_H + +// Define version unconditionally so a warning will catch a mismatch +#define INGEN_VERSION "0.5.1" + +#if !defined(INGEN_NO_DEFAULT_CONFIG) + +// We need unistd.h to check _POSIX_VERSION +# ifndef INGEN_NO_POSIX +# ifdef __has_include +# if __has_include(<unistd.h>) +# include <unistd.h> +# endif +# elif defined(__unix__) +# include <unistd.h> +# endif +# endif + +// POSIX.1-2001: fileno() +# ifndef HAVE_FILENO +# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L +# define HAVE_FILENO 1 +# else +# define HAVE_FILENO 0 +# endif +# endif + +// POSIX.1-2001: isatty() +# ifndef HAVE_ISATTY +# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L +# define HAVE_ISATTY 1 +# else +# define HAVE_ISATTY 0 +# endif +# endif + +// POSIX.1-2001: posix_memalign() +# ifndef HAVE_POSIX_MEMALIGN +# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L +# define HAVE_POSIX_MEMALIGN 1 +# else +# define HAVE_POSIX_MEMALIGN 0 +# endif +# endif + +// BSD and GNU: vasprintf() +# ifndef HAVE_VASPRINTF +# if defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +# define HAVE_VASPRINTF 1 +# else +# define HAVE_VASPRINTF 0 +# endif +# endif + +// JACK +# ifndef HAVE_JACK +# ifdef __has_include +# if __has_include("jack/jack.h") +# define HAVE_JACK 1 +# else +# define HAVE_JACK 0 +# endif +# else +# define HAVE_JACK 0 +# endif +# endif + +// JACK metadata API +# ifndef HAVE_JACK_METADATA +# ifdef __has_include +# if __has_include("jack/metadata.h") +# define HAVE_JACK_METADATA 1 +# else +# define HAVE_JACK_METADATA 0 +# endif +# else +# define HAVE_JACK_METADATA 0 +# endif +# endif + +// JACK jack_port_rename() function +# ifndef HAVE_JACK_PORT_RENAME +# define HAVE_JACK_PORT_RENAME HAVE_JACK +# endif + +// BSD sockets +# ifndef HAVE_SOCKET +# ifdef __has_include +# if __has_include("sys/socket.h") +# define HAVE_SOCKET 1 +# else +# define HAVE_SOCKET 0 +# endif +# else +# define HAVE_SOCKET 0 +# endif +# endif + +// Webkit +# ifndef HAVE_WEBKIT +# ifdef __has_include +# if __has_include(<webkit/webkit.h>) +# define HAVE_WEBKIT 1 +# else +# define HAVE_WEBKIT 0 +# endif +# else +# define HAVE_WEBKIT 0 +# endif +# endif + +// Installation directories +# ifndef INGEN_DATA_DIR +# define INGEN_DATA_DIR "/usr/local/share/ingen" +# endif +# ifndef INGEN_MODULE_DIR +# define INGEN_MODULE_DIR "/usr/local/lib/ingen" +# endif +# ifndef INGEN_BUNDLE_DIR +# define INGEN_BUNDLE_DIR "/usr/local/lib/lv2/ingen.lv2" +# endif + +#endif // !defined(INGEN_NO_DEFAULT_CONFIG) + +/* + Make corresponding USE_FEATURE defines based on the HAVE_FEATURE defines from + above or the command line. The code checks for these using #if (not #ifdef), + so there will be an undefined warning if it checks for an unknown feature, + and this header is always required by any code that checks for features, even + if the build system defines them all. +*/ + +#if defined(HAVE_FILENO) +# define USE_FILENO HAVE_FILENO +#else +# define USE_FILENO 0 +#endif + +#if defined(HAVE_ISATTY) +# define USE_ISATTY HAVE_ISATTY +#else +# define USE_ISATTY 0 +#endif + +#if defined(HAVE_POSIX_MEMALIGN) +# define USE_POSIX_MEMALIGN HAVE_POSIX_MEMALIGN +#else +# define USE_POSIX_MEMALIGN 0 +#endif + +#if defined(HAVE_SOCKET) +# define USE_SOCKET HAVE_SOCKET +#else +# define USE_SOCKET 0 +#endif + +#if defined(HAVE_VASPRINTF) +# define USE_VASPRINTF HAVE_VASPRINTF +#else +# define USE_VASPRINTF 0 +#endif + +#if defined(HAVE_WEBKIT) +# define USE_WEBKIT HAVE_WEBKIT +#else +# define USE_WEBKIT 0 +#endif + +#if defined(HAVE_JACK_METADATA) +# define USE_JACK_METADATA HAVE_JACK_METADATA +#else +# define USE_JACK_METADATA 0 +#endif + +#if defined(HAVE_JACK_PORT_TYPE_GET_BUFFER_SIZE) +# define USE_JACK_PORT_TYPE_GET_BUFFER_SIZE \ + HAVE_JACK_PORT_TYPE_GET_BUFFER_SIZE +#else +# define USE_JACK_PORT_TYPE_GET_BUFFER_SIZE 0 +#endif + +#if defined(HAVE_JACK_PORT_RENAME) +# define USE_JACK_PORT_RENAME HAVE_JACK_PORT_RENAME +#else +# define USE_JACK_PORT_RENAME 0 +#endif + +#define INGEN_BUNDLED 0 + +#endif // INGEN_CONFIG_H diff --git a/src/ingen/.clang-tidy b/src/ingen/.clang-tidy new file mode 100644 index 00000000..e7bf0b6a --- /dev/null +++ b/src/ingen/.clang-tidy @@ -0,0 +1,3 @@ +Checks: > + -bugprone-exception-escape, +InheritParentConfig: true diff --git a/src/ingen/ingen.cpp b/src/ingen/ingen.cpp index c7c3ef74..7f1a587e 100644 --- a/src/ingen/ingen.cpp +++ b/src/ingen/ingen.cpp @@ -14,29 +14,26 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Atom.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/EngineBase.hpp" -#include "ingen/FilePath.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Message.hpp" -#include "ingen/Parser.hpp" -#include "ingen/URI.hpp" -#include "ingen/World.hpp" -#include "ingen/fmt.hpp" -#include "ingen/paths.hpp" -#include "ingen/runtime_paths.hpp" -#include "ingen_config.h" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" -#include "serd/serd.h" - -#ifdef HAVE_SOCKET +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/EngineBase.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/Parser.hpp> +#include <ingen/URI.hpp> +#include <ingen/World.hpp> +#include <ingen/fmt.hpp> +#include <ingen/paths.hpp> +#include <ingen/runtime_paths.hpp> +#include <ingen_config.h> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> +#include <serd/serd.h> + +#if USE_SOCKET #include "ingen/client/SocketClient.hpp" #endif -#include <boost/optional/optional.hpp> - #include <chrono> #include <csignal> #include <cstdint> @@ -45,6 +42,7 @@ #include <iostream> #include <memory> #include <mutex> +#include <optional> #include <string> #include <thread> @@ -99,16 +97,19 @@ run(int argc, char** argv) { // Create world try { - world = std::unique_ptr<ingen::World>( - new ingen::World(nullptr, nullptr, nullptr)); + world = std::make_unique<ingen::World>(nullptr, nullptr, nullptr); world->load_configuration(argc, argv); if (argc <= 1) { world->conf().print_usage("ingen", std::cout); return EXIT_FAILURE; - } else if (world->conf().option("help").get<int32_t>()) { + } + + if (world->conf().option("help").get<int32_t>()) { world->conf().print_usage("ingen", std::cout); return EXIT_SUCCESS; - } else if (world->conf().option("version").get<int32_t>()) { + } + + if (world->conf().option("version").get<int32_t>()) { return print_version(); } } catch (std::exception& e) { @@ -130,11 +131,11 @@ run(int argc, char** argv) ingen_try(world->load_module("server"), "Failed to load server module"); - ingen_try(bool(world->engine()), "Unable to create engine"); + ingen_try(!!world->engine(), "Unable to create engine"); world->engine()->listen(); } -#ifdef HAVE_SOCKET +#if USE_SOCKET client::SocketClient::register_factories(*world); #endif @@ -177,8 +178,8 @@ run(int argc, char** argv) // Load a graph if (conf.option("load").is_valid()) { - boost::optional<raul::Path> parent; - boost::optional<raul::Symbol> symbol; + std::optional<raul::Path> parent; + std::optional<raul::Symbol> symbol; const Atom& path_option = conf.option("path"); if (path_option.is_valid()) { @@ -194,14 +195,14 @@ run(int argc, char** argv) } } - ingen_try(bool(world->parser()), "Failed to create parser"); + ingen_try(!!world->parser(), "Failed to create parser"); const std::string graph = conf.option("load").ptr<char>(); engine_interface->get(URI("ingen:/plugins")); engine_interface->get(main_uri()); - std::lock_guard<std::mutex> lock(world->rdf_mutex()); + const std::lock_guard<std::mutex> lock{world->rdf_mutex()}; world->parser()->parse_file( *world, *engine_interface, graph, parent, symbol); } else if (conf.option("server-load").is_valid()) { diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 00000000..bbd4bb5f --- /dev/null +++ b/src/meson.build @@ -0,0 +1,69 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +sources = files( + 'AtomForge.cpp', + 'AtomReader.cpp', + 'AtomWriter.cpp', + 'ClashAvoider.cpp', + 'ColorContext.cpp', + 'Configuration.cpp', + 'Forge.cpp', + 'LV2Features.cpp', + 'Library.cpp', + 'Log.cpp', + 'Parser.cpp', + 'Resource.cpp', + 'Serialiser.cpp', + 'Store.cpp', + 'StreamWriter.cpp', + 'TurtleWriter.cpp', + 'URI.cpp', + 'URIMap.cpp', + 'URIs.cpp', + 'World.cpp', + 'runtime_paths.cpp', +) + +if have_socket + sources += files('SocketReader.cpp', 'SocketWriter.cpp') +endif + +ingen_deps = [ + boost_dep, + lv2_dep, + raul_dep, + serd_dep, + thread_dep, + + sord_dep, + + lilv_dep, + sratom_dep, +] + +ingen_include_dirs = include_directories('../include', 'include') + +libingen = shared_library( + versioned_name, + sources, + cpp_args: cpp_suppressions + platform_defines, + darwin_versions: [major_version + '.0.0', meson.project_version()], + dependencies: ingen_deps, + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + soversion: soversion, + version: meson.project_version(), +) + +ingen_dep = declare_dependency( + dependencies: ingen_deps, + include_directories: include_directories('../include'), + link_with: libingen, +) + +subdir('server') +subdir('client') +subdir('gui') diff --git a/src/runtime_paths.cpp b/src/runtime_paths.cpp index 38eb681f..17167e9a 100644 --- a/src/runtime_paths.cpp +++ b/src/runtime_paths.cpp @@ -14,15 +14,15 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/runtime_paths.hpp" +#include <ingen/runtime_paths.hpp> + +#include <ingen/FilePath.hpp> -#include "ingen/FilePath.hpp" -#include "ingen/filesystem.hpp" #include "ingen_config.h" -#include <algorithm> #include <cstdlib> #include <dlfcn.h> +#include <filesystem> #include <sstream> #include <string> @@ -45,7 +45,8 @@ static const char* const library_suffix = ".so"; #endif static std::vector<FilePath> -parse_search_path(const char* search_path, std::vector<FilePath> defaults) +parse_search_path(const char* search_path, + const std::vector<FilePath>& defaults) { if (!search_path) { return defaults; @@ -70,7 +71,7 @@ set_bundle_path_from_code(void (*function)()) Dl_info dli; dladdr(reinterpret_cast<void*>(function), &dli); -#ifdef BUNDLE +#if INGEN_BUNDLED char bin_loc[PATH_MAX]; realpath(dli.dli_fname, bin_loc); #else @@ -92,7 +93,7 @@ find_in_search_path(const std::string& name, { for (const auto& dir : search_path) { FilePath path = dir / name; - if (filesystem::exists(path)) { + if (std::filesystem::exists(path)) { return path; } } @@ -117,7 +118,7 @@ data_file_path(const std::string& name) std::vector<FilePath> ingen_module_dirs() { -#ifdef BUNDLE +#if INGEN_BUNDLED const FilePath default_dir = FilePath(bundle_path) / INGEN_MODULE_DIR; #else const FilePath default_dir = INGEN_MODULE_DIR; @@ -138,22 +139,28 @@ FilePath user_config_dir() { if (const char* xdg_config_home = getenv("XDG_CONFIG_HOME")) { - return FilePath(xdg_config_home); - } else if (const char* home = getenv("HOME")) { + return {xdg_config_home}; + } + + if (const char* home = getenv("HOME")) { return FilePath(home) / ".config"; } - return FilePath(); + + return {}; } FilePath user_data_dir() { if (const char* xdg_data_home = getenv("XDG_DATA_HOME")) { - return FilePath(xdg_data_home); - } else if (const char* home = getenv("HOME")) { + return {xdg_data_home}; + } + + if (const char* home = getenv("HOME")) { return FilePath(home) / ".local/share"; } - return FilePath(); + + return {}; } std::vector<FilePath> @@ -186,7 +193,7 @@ data_dirs() std::vector<FilePath> paths = system_data_dirs(); const FilePath user_dir = user_data_dir(); -#ifdef BUNDLE +#if INGEN_BUNDLED paths.insert(paths.begin(), bundle_path / INGEN_DATA_DIR); #endif diff --git a/src/server/.clang-tidy b/src/server/.clang-tidy index fc51d942..a580cc7e 100644 --- a/src/server/.clang-tidy +++ b/src/server/.clang-tidy @@ -1,62 +1,21 @@ Checks: > - *, -*-avoid-c-arrays, - -*-else-after-return, - -*-magic-numbers, - -*-named-parameter, -*-narrowing-conversions, -*-non-private-member-variables-in-classes, - -*-special-member-functions, - -*-uppercase-literal-suffix, -*-vararg, - -abseil-string-find-str-contains, - -android-cloexec-*, -bugprone-branch-clone, -bugprone-parent-virtual-call, -bugprone-reserved-identifier, - -bugprone-signed-char-misuse, -bugprone-suspicious-string-compare, - -cert-str34-c, - -clang-analyzer-optin.cplusplus.VirtualCall, - -cppcoreguidelines-avoid-non-const-global-variables, - -cppcoreguidelines-macro-usage, - -cppcoreguidelines-no-malloc, - -cppcoreguidelines-owning-memory, - -cppcoreguidelines-pro-bounds-array-to-pointer-decay, + -cert-dcl37-c, + -cert-dcl51-cpp, -cppcoreguidelines-pro-bounds-constant-array-index, - -cppcoreguidelines-pro-bounds-pointer-arithmetic, - -cppcoreguidelines-pro-type-const-cast, - -cppcoreguidelines-pro-type-cstyle-cast, - -cppcoreguidelines-pro-type-reinterpret-cast, -cppcoreguidelines-pro-type-static-cast-downcast, - -cppcoreguidelines-pro-type-union-access, - -fuchsia-*, - -google-default-arguments, - -google-explicit-constructor, -google-readability-todo, -google-runtime-int, -google-runtime-references, - -hicpp-explicit-conversions, -hicpp-multiway-paths-covered, - -hicpp-no-array-decay, - -hicpp-no-malloc, - -hicpp-signed-bitwise, -llvm-header-guard, - -llvmlibc-*, - -misc-no-recursion, - -misc-unused-parameters, - -modernize-use-default-member-init, - -modernize-use-trailing-return-type, + -misc-redundant-expression, -portability-simd-intrinsics, - -readability-implicit-bool-conversion, - -readability-redundant-member-init, - -readability-use-anyofallof, -CheckOptions: - - key: modernize-use-override.AllowOverrideAndFinal - value: 'true' -CheckOptions: - - key: cppcoreguidelines-explicit-virtual-functions.AllowOverrideAndFinal - value: 'true' -WarningsAsErrors: '*' -HeaderFilterRegex: 'include/ingen/.*|tests/.*|src/.*' -FormatStyle: file +InheritParentConfig: true diff --git a/src/server/ArcImpl.cpp b/src/server/ArcImpl.cpp index 689be199..2c5b4ee1 100644 --- a/src/server/ArcImpl.cpp +++ b/src/server/ArcImpl.cpp @@ -22,15 +22,14 @@ #include "PortImpl.hpp" #include "PortType.hpp" -#include "ingen/URIs.hpp" -#include "raul/Path.hpp" +#include <ingen/URIs.hpp> +#include <raul/Path.hpp> #include <algorithm> #include <cassert> #include <string> -namespace ingen { -namespace server { +namespace ingen::server { /** Constructor for an arc from a block's output port. * @@ -85,33 +84,30 @@ ArcImpl::can_connect(const PortImpl* src, const InputPort* dst) { const ingen::URIs& uris = src->bufs().uris(); return ( - // (Audio | Control | CV) => (Audio | Control | CV) - ( (src->is_a(PortType::ID::CONTROL) || - src->is_a(PortType::ID::AUDIO) || - src->is_a(PortType::ID::CV)) - && (dst->is_a(PortType::ID::CONTROL) - || dst->is_a(PortType::ID::AUDIO) - || dst->is_a(PortType::ID::CV))) + // (Audio | Control | CV) => (Audio | Control | CV) + ((src->is_a(PortType::CONTROL) || src->is_a(PortType::AUDIO) || + src->is_a(PortType::CV)) && + (dst->is_a(PortType::CONTROL) || dst->is_a(PortType::AUDIO) || + dst->is_a(PortType::CV))) - // Equal types - || (src->type() == dst->type() && - src->buffer_type() == dst->buffer_type()) + // Equal types + || + (src->type() == dst->type() && src->buffer_type() == dst->buffer_type()) - // Control => atom:Float Value - || (src->is_a(PortType::ID::CONTROL) && dst->supports(uris.atom_Float)) + // Control => atom:Float Value + || (src->is_a(PortType::CONTROL) && dst->supports(uris.atom_Float)) - // Audio => atom:Sound Value - || (src->is_a(PortType::ID::AUDIO) && dst->supports(uris.atom_Sound)) + // Audio => atom:Sound Value + || (src->is_a(PortType::AUDIO) && dst->supports(uris.atom_Sound)) - // atom:Float Value => Control - || (src->supports(uris.atom_Float) && dst->is_a(PortType::ID::CONTROL)) + // atom:Float Value => Control + || (src->supports(uris.atom_Float) && dst->is_a(PortType::CONTROL)) - // atom:Float Value => CV - || (src->supports(uris.atom_Float) && dst->is_a(PortType::ID::CV)) + // atom:Float Value => CV + || (src->supports(uris.atom_Float) && dst->is_a(PortType::CV)) - // atom:Sound Value => Audio - || (src->supports(uris.atom_Sound) && dst->is_a(PortType::ID::AUDIO))); + // atom:Sound Value => Audio + || (src->supports(uris.atom_Sound) && dst->is_a(PortType::AUDIO))); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/ArcImpl.hpp b/src/server/ArcImpl.hpp index 09c59c8f..5be51187 100644 --- a/src/server/ArcImpl.hpp +++ b/src/server/ArcImpl.hpp @@ -17,23 +17,16 @@ #ifndef INGEN_ENGINE_ARC_IMPL_HPP #define INGEN_ENGINE_ARC_IMPL_HPP -// IWYU pragma: no_include "raul/Path.hpp" - #include "BufferRef.hpp" -#include "ingen/Arc.hpp" -#include "raul/Noncopyable.hpp" +#include <ingen/Arc.hpp> +#include <raul/Noncopyable.hpp> #include <boost/intrusive/slist_hook.hpp> #include <cstdint> -namespace raul { -class Path; // IWYU pragma: keep -} // namespace raul - -namespace ingen { -namespace server { +namespace ingen::server { class InputPort; class PortImpl; @@ -60,8 +53,8 @@ public: ArcImpl(PortImpl* tail, PortImpl* head); ~ArcImpl() override; - inline PortImpl* tail() const { return _tail; } - inline PortImpl* head() const { return _head; } + PortImpl* tail() const { return _tail; } + PortImpl* head() const { return _head; } const raul::Path& tail_path() const override; const raul::Path& head_path() const override; @@ -83,7 +76,6 @@ protected: PortImpl* const _head; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_ARC_IMPL_HPP diff --git a/src/server/BlockFactory.cpp b/src/server/BlockFactory.cpp index 14a50098..a70de0b6 100644 --- a/src/server/BlockFactory.cpp +++ b/src/server/BlockFactory.cpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2015 David Robillard <http://drobilla.net/> + Copyright 2007-2024 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -22,28 +22,30 @@ #include "PortType.hpp" #include "ThreadManager.hpp" -#include "ingen/LV2Features.hpp" -#include "ingen/Log.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "internals/BlockDelay.hpp" -#include "internals/Controller.hpp" -#include "internals/Note.hpp" -#include "internals/Time.hpp" -#include "internals/Trigger.hpp" -#include "lilv/lilv.h" - +#include <ingen/LV2Features.hpp> +#include <ingen/Log.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <internals/BlockDelay.hpp> +#include <internals/Controller.hpp> +#include <internals/Note.hpp> +#include <internals/Time.hpp> +#include <internals/Trigger.hpp> +#include <lilv/lilv.h> + +#include <algorithm> #include <cstdint> +#include <iterator> #include <memory> +#include <string> #include <utility> #include <vector> -namespace ingen { -namespace server { +namespace ingen::server { BlockFactory::BlockFactory(ingen::World& world) : _world(world) - , _has_loaded(false) { load_internal_plugins(); } @@ -84,11 +86,10 @@ BlockFactory::refresh() } // Add any resurrected plugins to response - for (const auto& z : zombies) { - if (!z->is_zombie()) { - new_plugins.insert(z); - } - } + std::copy_if(zombies.begin(), + zombies.end(), + std::inserter(new_plugins, new_plugins.end()), + [](const auto& z) { return !z->is_zombie(); }); return new_plugins; } @@ -97,7 +98,7 @@ PluginImpl* BlockFactory::plugin(const URI& uri) { load_plugin(uri); - const Plugins::const_iterator i = _plugins.find(uri); + const auto i = _plugins.find(uri); return ((i != _plugins.end()) ? i->second.get() : nullptr); } @@ -149,21 +150,23 @@ BlockFactory::load_lv2_plugins() // Build an array of port type nodes for checking compatibility using Types = std::vector<std::shared_ptr<LilvNode>>; Types types; - for (unsigned t = PortType::ID::AUDIO; t <= PortType::ID::ATOM; ++t) { - const URI& uri(PortType(static_cast<PortType::ID>(t)).uri()); + for (auto t = static_cast<unsigned>(PortType::AUDIO); + t <= static_cast<unsigned>(PortType::ATOM); + ++t) { + const URI uri = port_type_uri(static_cast<PortType>(t)); types.push_back(std::shared_ptr<LilvNode>( lilv_new_uri(_world.lilv_world(), uri.c_str()), lilv_node_free)); } const LilvPlugins* plugins = lilv_world_get_all_plugins(_world.lilv_world()); - LILV_FOREACH(plugins, i, plugins) { + LILV_FOREACH (plugins, i, plugins) { const LilvPlugin* lv2_plug = lilv_plugins_get(plugins, i); const URI uri(lilv_node_as_uri(lilv_plugin_get_uri(lv2_plug))); // Ignore plugins that require features Ingen doesn't support LilvNodes* features = lilv_plugin_get_required_features(lv2_plug); bool supported = true; - LILV_FOREACH(nodes, f, features) { + LILV_FOREACH (nodes, f, features) { const char* feature = lilv_node_as_uri(lilv_nodes_get(features, f)); if (!_world.lv2_features().is_supported(feature)) { supported = false; @@ -187,13 +190,13 @@ BlockFactory::load_lv2_plugins() const uint32_t n_ports = lilv_plugin_get_num_ports(lv2_plug); for (uint32_t p = 0; p < n_ports; ++p) { const LilvPort* port = lilv_plugin_get_port_by_index(lv2_plug, p); - supported = false; - for (const auto& t : types) { - if (lilv_port_is_a(lv2_plug, port, t.get())) { - supported = true; - break; - } - } + supported = + std::any_of(types.begin(), + types.end(), + [&lv2_plug, &port](const auto& t) { + return lilv_port_is_a(lv2_plug, port, t.get()); + }); + if (!supported && !lilv_port_has_property(lv2_plug, port, @@ -221,5 +224,4 @@ BlockFactory::load_lv2_plugins() _world.log().info("Loaded %1% plugins\n", _plugins.size()); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/BlockFactory.hpp b/src/server/BlockFactory.hpp index 7cf28325..68699d8a 100644 --- a/src/server/BlockFactory.hpp +++ b/src/server/BlockFactory.hpp @@ -17,8 +17,8 @@ #ifndef INGEN_ENGINE_BLOCKFACTORY_HPP #define INGEN_ENGINE_BLOCKFACTORY_HPP -#include "ingen/URI.hpp" -#include "raul/Noncopyable.hpp" +#include <ingen/URI.hpp> +#include <raul/Noncopyable.hpp> #include <map> #include <memory> @@ -62,7 +62,7 @@ private: Plugins _plugins; ingen::World& _world; - bool _has_loaded; + bool _has_loaded{false}; }; } // namespace server diff --git a/src/server/BlockImpl.cpp b/src/server/BlockImpl.cpp index 26e83eb8..b4f407c3 100644 --- a/src/server/BlockImpl.cpp +++ b/src/server/BlockImpl.cpp @@ -20,20 +20,21 @@ #include "GraphImpl.hpp" #include "PluginImpl.hpp" #include "PortImpl.hpp" +#include "PortType.hpp" #include "RunContext.hpp" #include "ThreadManager.hpp" -#include "lv2/urid/urid.h" -#include "raul/Array.hpp" -#include "raul/Symbol.hpp" +#include <lv2/urid/urid.h> +#include <raul/Array.hpp> +#include <raul/Symbol.hpp> +#include <algorithm> #include <cassert> #include <cstdint> #include <initializer_list> #include <string> -namespace ingen { -namespace server { +namespace ingen::server { BlockImpl::BlockImpl(PluginImpl* plugin, const raul::Symbol& symbol, @@ -43,10 +44,7 @@ BlockImpl::BlockImpl(PluginImpl* plugin, : NodeImpl(plugin->uris(), parent, symbol) , _plugin(plugin) , _polyphony((polyphonic && parent) ? parent->internal_poly() : 1) - , _mark(Mark::UNVISITED) , _polyphonic(polyphonic) - , _activated(false) - , _enabled(true) { assert(_plugin); assert(_polyphony > 0); @@ -204,13 +202,15 @@ BlockImpl::bypass(RunContext& ctx) } // Dumb bypass - for (PortType t : { PortType::AUDIO, PortType::CV, PortType::ATOM }) { + for (const PortType t : { PortType::AUDIO, PortType::CV, PortType::ATOM }) { for (uint32_t i = 0;; ++i) { - PortImpl* in = nth_port_by_type(i, true, t); - PortImpl* out = nth_port_by_type(i, false, t); + const PortImpl* in = nth_port_by_type(i, true, t); + const PortImpl* out = nth_port_by_type(i, false, t); if (!out) { - break; // Finished writing all outputs - } else if (in) { + break; // Finished writing all outputs + } + + if (in) { // Copy corresponding input to output for (uint32_t v = 0; v < _polyphony; ++v) { out->buffer(v)->copy(ctx, in->buffer(v).get()); @@ -242,13 +242,11 @@ BlockImpl::process(RunContext& ctx) // Find earliest offset of a value change SampleCount chunk_end = ctx.nframes(); for (uint32_t i = 0; _ports && i < _ports->size(); ++i) { - PortImpl* const port = _ports->at(i); + const PortImpl* const port = _ports->at(i); if (port->type() == PortType::CONTROL && port->is_input()) { const SampleCount o = port->next_value_offset( offset, ctx.nframes()); - if (o < chunk_end) { - chunk_end = o; - } + chunk_end = std::min(o, chunk_end); } } @@ -266,7 +264,7 @@ BlockImpl::process(RunContext& ctx) // Emit control port outputs as events for (uint32_t i = 0; _ports && i < _ports->size(); ++i) { - PortImpl* const port = _ports->at(i); + const PortImpl* const port = _ports->at(i); if (port->type() == PortType::CONTROL && port->is_output()) { // TODO: Only emit events when value has actually changed? for (uint32_t v = 0; v < _polyphony; ++v) { @@ -298,5 +296,4 @@ BlockImpl::set_port_buffer(uint32_t, uint32_t, const BufferRef&, SampleCount) << " buffer " << buf << " offset " << offset << std::endl;*/ } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/BlockImpl.hpp b/src/server/BlockImpl.hpp index c285bdac..69564ff4 100644 --- a/src/server/BlockImpl.hpp +++ b/src/server/BlockImpl.hpp @@ -19,24 +19,22 @@ #include "BufferRef.hpp" #include "NodeImpl.hpp" -#include "PortType.hpp" #include "State.hpp" #include "types.hpp" -#include "ingen/Node.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URI.hpp" -#include "lilv/lilv.h" -#include "lv2/urid/urid.h" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <lilv/lilv.h> +#include <lv2/urid/urid.h> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> #include <boost/intrusive/slist_hook.hpp> -#include <boost/optional/optional.hpp> #include <cstdint> #include <memory> +#include <optional> #include <set> namespace raul { @@ -44,6 +42,9 @@ class Symbol; } // namespace raul namespace ingen { + +enum class PortType; + namespace server { class BufferFactory; @@ -62,7 +63,7 @@ class Worker; * \ingroup engine */ class BlockImpl : public NodeImpl - , public boost::intrusive::slist_base_hook<> // In GraphImpl + , public boost::intrusive::slist_base_hook<> // In GraphImpl { public: using Ports = raul::Array<PortImpl*>; @@ -115,14 +116,16 @@ public: {} /** Save current state as preset. */ - virtual boost::optional<Resource> - save_preset(const URI& bundle, - const Properties& props) { return boost::optional<Resource>(); } + virtual std::optional<Resource> + save_preset(const URI& bundle, const Properties& props) + { + return std::nullopt; + } /** Learn the next incoming MIDI event (for internals) */ virtual void learn() {} - /** Do whatever needs doing in the process thread before process() is called */ + /** Do any necessary preparation in the process thread before process(). */ virtual void pre_process(RunContext& ctx); /** Run block for an entire process cycle (calls run()). */ @@ -208,10 +211,10 @@ protected: uint32_t _polyphony; std::set<BlockImpl*> _providers; ///< Blocks connected to this one's input ports std::set<BlockImpl*> _dependants; ///< Blocks this one's output ports are connected to - Mark _mark; ///< Mark for graph compilation algorithm + Mark _mark{Mark::UNVISITED}; ///< Mark for graph walks bool _polyphonic; - bool _activated; - bool _enabled; + bool _activated{false}; + bool _enabled{true}; }; } // namespace server diff --git a/src/server/Broadcaster.cpp b/src/server/Broadcaster.cpp index 6d32db84..76b21fc6 100644 --- a/src/server/Broadcaster.cpp +++ b/src/server/Broadcaster.cpp @@ -19,19 +19,17 @@ #include "BlockFactory.hpp" #include "PluginImpl.hpp" -#include "ingen/Interface.hpp" +#include <ingen/Interface.hpp> #include <cstddef> -#include <map> #include <memory> #include <utility> -namespace ingen { -namespace server { +namespace ingen::server { Broadcaster::~Broadcaster() { - std::lock_guard<std::mutex> lock(_clients_mutex); + const std::lock_guard<std::mutex> lock{_clients_mutex}; _clients.clear(); _broadcastees.clear(); } @@ -41,7 +39,7 @@ Broadcaster::~Broadcaster() void Broadcaster::register_client(const std::shared_ptr<Interface>& client) { - std::lock_guard<std::mutex> lock(_clients_mutex); + const std::lock_guard<std::mutex> lock{_clients_mutex}; _clients.insert(client); } @@ -52,7 +50,7 @@ Broadcaster::register_client(const std::shared_ptr<Interface>& client) bool Broadcaster::unregister_client(const std::shared_ptr<Interface>& client) { - std::lock_guard<std::mutex> lock(_clients_mutex); + const std::lock_guard<std::mutex> lock{_clients_mutex}; const size_t erased = _clients.erase(client); _broadcastees.erase(client); return (erased > 0); @@ -73,7 +71,7 @@ Broadcaster::set_broadcast(const std::shared_ptr<Interface>& client, void Broadcaster::send_plugins(const BlockFactory::Plugins& plugins) { - std::lock_guard<std::mutex> lock(_clients_mutex); + const std::lock_guard<std::mutex> lock{_clients_mutex}; for (const auto& c : _clients) { send_plugins_to(c.get(), plugins); } @@ -93,5 +91,4 @@ Broadcaster::send_plugins_to(Interface* client, client->bundle_end(); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/Broadcaster.hpp b/src/server/Broadcaster.hpp index 8e9848f4..4cdf65ca 100644 --- a/src/server/Broadcaster.hpp +++ b/src/server/Broadcaster.hpp @@ -19,18 +19,17 @@ #include "BlockFactory.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Message.hpp" -#include "ingen/URI.hpp" -#include "raul/Noncopyable.hpp" +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/URI.hpp> +#include <raul/Noncopyable.hpp> #include <atomic> #include <memory> #include <mutex> #include <set> -namespace ingen { -namespace server { +namespace ingen::server { /** Broadcaster for all clients. * @@ -76,7 +75,8 @@ public: * This makes doing the right thing in recursive functions that send * updates simple (e.g. Event::post_process()). */ - class Transfer : public raul::Noncopyable { + class Transfer : public raul::Noncopyable + { public: explicit Transfer(Broadcaster& b) : broadcaster(b) { if (++broadcaster._bundle_depth == 1) { @@ -97,7 +97,7 @@ public: send_plugins_to(Interface*, const BlockFactory::Plugins& plugins); void message(const Message& msg) override { - std::lock_guard<std::mutex> lock(_clients_mutex); + const std::lock_guard<std::mutex> lock{_clients_mutex}; for (const auto& c : _clients) { if (c != _ignore_client) { c->message(msg); @@ -120,7 +120,6 @@ private: std::shared_ptr<Interface> _ignore_client; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_BROADCASTER_HPP diff --git a/src/server/Buffer.cpp b/src/server/Buffer.cpp index 36dfaf19..0c4c0951 100644 --- a/src/server/Buffer.cpp +++ b/src/server/Buffer.cpp @@ -18,15 +18,16 @@ #include "BufferFactory.hpp" #include "Engine.hpp" +#include "PortType.hpp" #include "RunContext.hpp" - -#include "ingen/Atom.hpp" -#include "ingen/Log.hpp" -#include "ingen/URIs.hpp" #include "ingen_config.h" -#include "lv2/atom/atom.h" -#include "lv2/atom/util.h" -#include "lv2/urid/urid.h" + +#include <ingen/Atom.hpp> +#include <ingen/Log.hpp> +#include <ingen/URIs.hpp> +#include <lv2/atom/atom.h> +#include <lv2/atom/util.h> +#include <lv2/urid/urid.h> #include <algorithm> #include <cstdint> @@ -38,8 +39,7 @@ # include <xmmintrin.h> #endif -namespace ingen { -namespace server { +namespace ingen::server { Buffer::Buffer(BufferFactory& bufs, LV2_URID type, @@ -48,13 +48,10 @@ Buffer::Buffer(BufferFactory& bufs, bool external, void*) : _factory(bufs) - , _next(nullptr) , _buf(external ? nullptr : aligned_alloc(capacity)) - , _latest_event(0) , _type(type) , _value_type(value_type) , _capacity(capacity) - , _refs(0) , _external(external) { if (!external && !_buf) { @@ -135,7 +132,7 @@ Buffer::render_sequence(const RunContext& ctx, const Buffer* src, bool add) float value = init ? init->body : 0.0f; SampleCount offset = ctx.offset(); - LV2_ATOM_SEQUENCE_FOREACH(seq, ev) { + LV2_ATOM_SEQUENCE_FOREACH (seq, ev) { if (ev->time.frames >= offset && ev->body.type == atom_Float) { write_block(value, offset, ev->time.frames, add); value = reinterpret_cast<const LV2_Atom_Float*>(&ev->body)->body; @@ -150,7 +147,9 @@ Buffer::copy(const RunContext& ctx, const Buffer* src) { if (!_buf) { return; - } else if (_type == src->type()) { + } + + if (_type == src->type()) { const uint32_t src_size = src->size(); if (src_size <= _capacity) { memcpy(_buf, src->_buf, src_size); @@ -173,7 +172,12 @@ void Buffer::resize(uint32_t capacity) { if (!_external) { - _buf = realloc(_buf, capacity); + void* const new_buf = realloc(_buf, capacity); + if (!new_buf) { + throw std::bad_alloc{}; + } + + _buf = new_buf; _capacity = capacity; clear(); } else { @@ -184,18 +188,18 @@ Buffer::resize(uint32_t capacity) void* Buffer::port_data(PortType port_type, SampleCount offset) { - switch (port_type.id()) { - case PortType::ID::CONTROL: + switch (port_type) { + case PortType::CONTROL: return &_value_buffer->get<LV2_Atom_Float>()->body; - case PortType::ID::CV: - case PortType::ID::AUDIO: + case PortType::CV: + case PortType::AUDIO: if (_type == _factory.uris().atom_Float) { return &get<LV2_Atom_Float>()->body; } else if (_type == _factory.uris().atom_Sound) { return static_cast<Sample*>(_buf) + offset; } break; - case PortType::ID::ATOM: + case PortType::ATOM: if (_type != _factory.uris().atom_Sound) { return _buf; } @@ -209,8 +213,7 @@ Buffer::port_data(PortType port_type, SampleCount offset) const void* Buffer::port_data(PortType port_type, SampleCount offset) const { - return const_cast<void*>( - const_cast<Buffer*>(this)->port_data(port_type, offset)); + return const_cast<Buffer*>(this)->port_data(port_type, offset); } #ifdef __SSE__ @@ -218,7 +221,7 @@ Buffer::port_data(PortType port_type, SampleCount offset) const static inline __m128 mm_abs_ps(__m128 x) { - const __m128 sign_mask = _mm_set1_ps(-0.0f); // -0.0f = 1 << 31 + const __m128 sign_mask = _mm_set1_ps(-0.0f); // -0.0f = 1 << 31 return _mm_andnot_ps(sign_mask, x); } #endif @@ -259,7 +262,7 @@ Buffer::peak(const RunContext& ctx) const #else const Sample* const buf = samples(); float peak = 0.0f; - for (SampleCount i = 0; i < context.nframes(); ++i) { + for (SampleCount i = 0; i < ctx.nframes(); ++i) { peak = fmaxf(peak, fabsf(buf[i])); } return peak; @@ -300,7 +303,7 @@ Buffer::append_event(int64_t frames, auto* atom = get<LV2_Atom>(); if (atom->type == _factory.uris().atom_Chunk) { - clear(); // Chunk initialized with prepare_output_write(), clear + clear(); // Chunk initialized with prepare_output_write(), clear } if (sizeof(LV2_Atom) + atom->size + lv2_atom_pad_size(size) > _capacity) { @@ -340,14 +343,14 @@ Buffer::append_event_buffer(const Buffer* buf) reinterpret_cast<const LV2_Atom_Sequence*>(buf->get<LV2_Atom>()); if (seq->atom.type == _factory.uris().atom_Chunk) { - clear(); // Chunk initialized with prepare_output_write(), clear + clear(); // Chunk initialized with prepare_output_write(), clear } const uint32_t total_size = lv2_atom_total_size(&seq->atom); uint8_t* const end = reinterpret_cast<uint8_t*>(seq) + total_size; const uint32_t n_bytes = bseq->atom.size - sizeof(bseq->body); if (sizeof(LV2_Atom) + total_size + n_bytes >= _capacity) { - return false; // Not enough space + return false; // Not enough space } memcpy(end, bseq + 1, n_bytes); @@ -363,7 +366,7 @@ Buffer::next_value_offset(SampleCount offset, SampleCount end) const { if (_type == _factory.uris().atom_Sequence && _value_type) { const auto* seq = get<const LV2_Atom_Sequence>(); - LV2_ATOM_SEQUENCE_FOREACH(seq, ev) { + LV2_ATOM_SEQUENCE_FOREACH (seq, ev) { if (ev->time.frames > offset && ev->time.frames < end && ev->body.type == _value_type) { @@ -416,10 +419,12 @@ Buffer::update_value_buffer(SampleCount offset) auto* seq = get<LV2_Atom_Sequence>(); LV2_Atom_Event* latest = nullptr; - LV2_ATOM_SEQUENCE_FOREACH(seq, ev) { + LV2_ATOM_SEQUENCE_FOREACH (seq, ev) { if (ev->time.frames > offset) { break; - } else if (ev->body.type == _value_type) { + } + + if (ev->body.type == _value_type) { latest = ev; } } @@ -433,9 +438,9 @@ Buffer::update_value_buffer(SampleCount offset) void* Buffer::aligned_alloc(size_t size) { -#ifdef HAVE_POSIX_MEMALIGN +#if USE_POSIX_MEMALIGN void* buf = nullptr; - if (!posix_memalign(static_cast<void**>(&buf), 16, size)) { + if (!posix_memalign(&buf, 16, size)) { memset(buf, 0, size); return buf; } @@ -457,5 +462,4 @@ intrusive_ptr_release(Buffer* b) b->deref(); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/Buffer.hpp b/src/server/Buffer.hpp index 21364fd9..2c32076b 100644 --- a/src/server/Buffer.hpp +++ b/src/server/Buffer.hpp @@ -19,13 +19,12 @@ #include "BufferFactory.hpp" #include "BufferRef.hpp" -#include "PortType.hpp" +#include "server.h" #include "types.hpp" -#include "ingen/URIs.hpp" -#include "ingen/ingen.h" -#include "lv2/atom/atom.h" -#include "lv2/urid/urid.h" +#include <ingen/URIs.hpp> +#include <lv2/atom/atom.h> +#include <lv2/urid/urid.h> #include <atomic> #include <cassert> @@ -34,13 +33,15 @@ namespace ingen { +enum class PortType; + class Atom; namespace server { class RunContext; -class INGEN_API Buffer +class INGEN_SERVER_API Buffer { public: Buffer(BufferFactory& bufs, @@ -61,10 +62,10 @@ public: void* port_data(PortType port_type, SampleCount offset); const void* port_data(PortType port_type, SampleCount offset) const; - inline LV2_URID type() const { return _type; } - inline LV2_URID value_type() const { return _value_type; } - inline uint32_t capacity() const { return _capacity; } - inline uint32_t size() const { + LV2_URID type() const { return _type; } + LV2_URID value_type() const { return _value_type; } + uint32_t capacity() const { return _capacity; } + uint32_t size() const { return is_audio() ? _capacity : sizeof(LV2_Atom) + get<LV2_Atom>()->size; } @@ -78,52 +79,60 @@ public: */ void set_type(GetFn get_func, LV2_URID type, LV2_URID value_type); - inline bool is_audio() const { + bool is_audio() const { return _type == _factory.uris().atom_Sound; } - inline bool is_control() const { + bool is_control() const { return _type == _factory.uris().atom_Float; } - inline bool is_sequence() const { + bool is_sequence() const { return _type == _factory.uris().atom_Sequence; } /// Audio or float buffers only - inline const Sample* samples() const { + const Sample* samples() const { if (is_control()) { return static_cast<const Sample*>( LV2_ATOM_BODY_CONST(get<LV2_Atom_Float>())); - } else if (is_audio()) { + } + + if (is_audio()) { return static_cast<const Sample*>(_buf); } + return nullptr; } /// Audio buffers only - inline Sample* samples() { + Sample* samples() { if (is_control()) { return static_cast<Sample*>(LV2_ATOM_BODY(get<LV2_Atom_Float>())); - } else if (is_audio()) { + } + + if (is_audio()) { return static_cast<Sample*>(_buf); } + return nullptr; } /// Numeric buffers only - inline Sample value_at(SampleCount offset) const { + Sample value_at(SampleCount offset) const { if (is_audio() || is_control()) { return samples()[offset]; - } else if (_value_buffer) { + } + + if (_value_buffer) { return reinterpret_cast<const LV2_Atom_Float*>(value())->body; } + return 0.0f; } - inline void set_block(const Sample val, - const SampleCount start, - const SampleCount end) + void + set_block(const Sample val, const SampleCount start, const SampleCount end) { if (is_sequence()) { append_event(start, sizeof(val), _factory.uris().atom_Float, @@ -142,9 +151,8 @@ public: } } - inline void add_block(const Sample val, - const SampleCount start, - const SampleCount end) + void + add_block(const Sample val, const SampleCount start, const SampleCount end) { assert(is_audio() || is_control()); assert(end <= _capacity / sizeof(Sample)); @@ -155,10 +163,10 @@ public: } } - inline void write_block(const Sample val, - const SampleCount start, - const SampleCount end, - const bool add) + void write_block(const Sample val, + const SampleCount start, + const SampleCount end, + const bool add) { if (add) { add_block(val, start, end); @@ -212,9 +220,9 @@ public: template<typename T> const T* get() const { return reinterpret_cast<const T*>(_buf); } template<typename T> T* get() { return reinterpret_cast<T*>(_buf); } - inline void ref() { ++_refs; } + void ref() { ++_refs; } - inline void deref() { + void deref() { if ((--_refs) == 0) { recycle(); } @@ -229,15 +237,15 @@ private: BufferFactory& _factory; // NOLINTNEXTLINE(clang-analyzer-webkit.NoUncountedMemberChecker) - Buffer* _next; ///< Intrusive linked list for BufferFactory + Buffer* _next{nullptr}; ///< Intrusive linked list for BufferFactory void* _buf; ///< Actual buffer memory BufferRef _value_buffer; ///< Value buffer for numeric sequences - int64_t _latest_event; + int64_t _latest_event{0}; LV2_URID _type; LV2_URID _value_type; uint32_t _capacity; - std::atomic<unsigned> _refs; ///< Intrusive reference count + std::atomic<unsigned> _refs{0}; ///< Intrusive reference count bool _external; ///< Buffer is externally allocated }; diff --git a/src/server/BufferFactory.cpp b/src/server/BufferFactory.cpp index 4ecdfc3b..b8f6ee35 100644 --- a/src/server/BufferFactory.cpp +++ b/src/server/BufferFactory.cpp @@ -19,17 +19,16 @@ #include "Buffer.hpp" #include "Engine.hpp" -#include "ingen/Log.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "lv2/atom/atom.h" -#include "lv2/urid/urid.h" +#include <ingen/Log.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <lv2/atom/atom.h> +#include <lv2/urid/urid.h> #include <algorithm> #include <memory> -namespace ingen { -namespace server { +namespace ingen::server { BufferFactory::BufferFactory(Engine& engine, URIs& uris) : _free_audio(nullptr) @@ -38,10 +37,8 @@ BufferFactory::BufferFactory(Engine& engine, URIs& uris) , _free_object(nullptr) , _engine(engine) , _uris(uris) - , _seq_size(0) , _silent_buffer(nullptr) -{ -} +{} BufferFactory::~BufferFactory() { @@ -101,19 +98,25 @@ BufferFactory::default_size(LV2_URID type) const { if (type == _uris.atom_Float) { return sizeof(LV2_Atom_Float); - } else if (type == _uris.atom_Sound) { + } + + if (type == _uris.atom_Sound) { return audio_buffer_size(_engine.block_length()); - } else if (type == _uris.atom_URID) { + } + + if (type == _uris.atom_URID) { return sizeof(LV2_Atom_URID); - } else if (type == _uris.atom_Sequence) { - if (_seq_size == 0) { + } + + if (type == _uris.atom_Sequence) { + if (_seq_size == 0U) { return _engine.sequence_size(); - } else { - return _seq_size; } - } else { - return 0; + + return _seq_size; } + + return 0; } Buffer* @@ -146,7 +149,7 @@ BufferFactory::get_buffer(LV2_URID type, try_head->_next = nullptr; try_head->set_type(&BufferFactory::get_buffer, type, value_type); try_head->clear(); - return BufferRef(try_head); + return {try_head}; } BufferRef @@ -155,12 +158,12 @@ BufferFactory::claim_buffer(LV2_URID type, LV2_URID value_type, uint32_t) Buffer* try_head = try_get_buffer(type); if (!try_head) { _engine.world().log().rt_error("Failed to obtain buffer"); - return BufferRef(); + return {}; } try_head->_next = nullptr; try_head->set_type(&BufferFactory::claim_buffer, type, value_type); - return BufferRef(try_head); + return {try_head}; } BufferRef @@ -181,7 +184,7 @@ BufferFactory::create(LV2_URID type, LV2_URID value_type, uint32_t capacity) capacity = std::max(capacity, default_size(_uris.atom_Sound)); } - return BufferRef(new Buffer(*this, type, value_type, capacity)); + return {new Buffer(*this, type, value_type, capacity)}; } void @@ -195,5 +198,4 @@ BufferFactory::recycle(Buffer* buf) } while (!head_ptr.compare_exchange_weak(try_head, buf)); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/BufferFactory.hpp b/src/server/BufferFactory.hpp index 19a61bed..dbadaede 100644 --- a/src/server/BufferFactory.hpp +++ b/src/server/BufferFactory.hpp @@ -17,18 +17,20 @@ #ifndef INGEN_ENGINE_BUFFERFACTORY_HPP #define INGEN_ENGINE_BUFFERFACTORY_HPP -#include "ingen/URIs.hpp" -#include "ingen/ingen.h" -#include "lv2/urid/urid.h" - #include "BufferRef.hpp" +#include "server.h" #include "types.hpp" +#include <ingen/URIs.hpp> +#include <lv2/urid/urid.h> + #include <atomic> #include <cstdint> #include <mutex> -namespace raul { class Maid; } +namespace raul { +class Maid; +} // namespace raul namespace ingen { @@ -39,7 +41,8 @@ namespace server { class Buffer; class Engine; -class INGEN_API BufferFactory { +class INGEN_SERVER_API BufferFactory +{ public: BufferFactory(Engine& engine, URIs& uris); ~BufferFactory(); @@ -82,29 +85,33 @@ private: Buffer* try_get_buffer(LV2_URID type); - inline std::atomic<Buffer*>& free_list(LV2_URID type) { + std::atomic<Buffer*>& free_list(LV2_URID type) { if (type == _uris.atom_Float) { return _free_control; - } else if (type == _uris.atom_Sound) { + } + + if (type == _uris.atom_Sound) { return _free_audio; - } else if (type == _uris.atom_Sequence) { + } + + if (type == _uris.atom_Sequence) { return _free_sequence; - } else { - return _free_object; } + + return _free_object; } static void free_list(Buffer* head); - std::atomic<Buffer*> _free_audio; - std::atomic<Buffer*> _free_control; - std::atomic<Buffer*> _free_sequence; - std::atomic<Buffer*> _free_object; + std::atomic<Buffer*> _free_audio{nullptr}; + std::atomic<Buffer*> _free_control{nullptr}; + std::atomic<Buffer*> _free_sequence{nullptr}; + std::atomic<Buffer*> _free_object{nullptr}; std::mutex _mutex; Engine& _engine; URIs& _uris; - uint32_t _seq_size; + uint32_t _seq_size{0U}; BufferRef _silent_buffer; }; diff --git a/src/server/BufferRef.hpp b/src/server/BufferRef.hpp index 958fcb06..cc5b840f 100644 --- a/src/server/BufferRef.hpp +++ b/src/server/BufferRef.hpp @@ -17,22 +17,20 @@ #ifndef INGEN_ENGINE_BUFFER_REF_HPP #define INGEN_ENGINE_BUFFER_REF_HPP -#include "ingen/ingen.h" +#include "server.h" #include <boost/smart_ptr/intrusive_ptr.hpp> // IWYU pragma: export -namespace ingen { -namespace server { +namespace ingen::server { class Buffer; using BufferRef = boost::intrusive_ptr<Buffer>; // Defined in Buffer.cpp -INGEN_API void intrusive_ptr_add_ref(Buffer* b); -INGEN_API void intrusive_ptr_release(Buffer* b); +INGEN_SERVER_API void intrusive_ptr_add_ref(Buffer* b); +INGEN_SERVER_API void intrusive_ptr_release(Buffer* b); -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_BUFFER_REF_HPP diff --git a/src/server/ClientUpdate.cpp b/src/server/ClientUpdate.cpp index 5034257b..008e9843 100644 --- a/src/server/ClientUpdate.cpp +++ b/src/server/ClientUpdate.cpp @@ -23,11 +23,14 @@ #include "PortImpl.hpp" #include "PortType.hpp" -#include "ingen/Arc.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Node.hpp" -#include "ingen/URIs.hpp" +#include <ingen/Arc.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <raul/Path.hpp> #include <boost/intrusive/slist.hpp> @@ -38,8 +41,7 @@ #include <memory> #include <utility> -namespace ingen { -namespace server { +namespace ingen::server { void ClientUpdate::put(const URI& uri, @@ -166,5 +168,4 @@ ClientUpdate::send(Interface& dest) } } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/ClientUpdate.hpp b/src/server/ClientUpdate.hpp index 9fadae90..1d16e6d6 100644 --- a/src/server/ClientUpdate.hpp +++ b/src/server/ClientUpdate.hpp @@ -17,10 +17,10 @@ #ifndef INGEN_ENGINE_CLIENTUPDATE_HPP #define INGEN_ENGINE_CLIENTUPDATE_HPP -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URI.hpp" -#include "raul/Path.hpp" +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <raul/Path.hpp> #include <string> #include <vector> diff --git a/src/server/CompiledGraph.cpp b/src/server/CompiledGraph.cpp index e644d982..89fc8843 100644 --- a/src/server/CompiledGraph.cpp +++ b/src/server/CompiledGraph.cpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2015-2017 David Robillard <http://drobilla.net/> + Copyright 2015-2024 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -21,13 +21,12 @@ #include "GraphImpl.hpp" #include "ThreadManager.hpp" -#include "ingen/Atom.hpp" -#include "ingen/ColorContext.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Log.hpp" -#include "ingen/World.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" +#include <ingen/Atom.hpp> +#include <ingen/ColorContext.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Log.hpp> +#include <ingen/World.hpp> +#include <raul/Path.hpp> #include <boost/intrusive/slist.hpp> @@ -36,14 +35,16 @@ #include <cstdint> #include <cstdio> #include <exception> +#include <functional> #include <limits> +#include <memory> #include <utility> -namespace ingen { -namespace server { +namespace ingen::server { /** Graph contains ambiguous feedback with no delay nodes. */ -class FeedbackException : public std::exception { +class FeedbackException : public std::exception +{ public: explicit FeedbackException(const BlockImpl* n) : node(n) @@ -60,26 +61,24 @@ public: static bool has_provider_with_many_dependants(const BlockImpl* n) { - for (const auto* p : n->providers()) { - if (p->dependants().size() > 1) { - return true; - } - } - - return false; + return std::any_of(n->providers().begin(), + n->providers().end(), + [](const auto* p) { + return p->dependants().size() > 1; + }); } CompiledGraph::CompiledGraph(GraphImpl* graph) - : _master(std::unique_ptr<Task>(new Task(Task::Mode::SEQUENTIAL))) + : _master{std::make_unique<Task>(Task::Mode::SEQUENTIAL)} { compile_graph(graph); } -raul::managed_ptr<CompiledGraph> -CompiledGraph::compile(raul::Maid& maid, GraphImpl& graph) +std::unique_ptr<CompiledGraph> +CompiledGraph::compile(GraphImpl& graph) { try { - return maid.make_managed<CompiledGraph>(&graph); + return std::unique_ptr<CompiledGraph>(new CompiledGraph(&graph)); } catch (const FeedbackException& e) { Log& log = graph.engine().log(); if (e.node && e.root) { @@ -95,13 +94,11 @@ CompiledGraph::compile(raul::Maid& maid, GraphImpl& graph) static size_t num_unvisited_dependants(const BlockImpl* block) { - size_t count = 0; - for (const BlockImpl* b : block->dependants()) { - if (b->get_mark() == BlockImpl::Mark::UNVISITED) { - ++count; - } - } - return count; + return std::count_if(block->dependants().begin(), + block->dependants().end(), + [](const auto* b) { + return b->get_mark() == BlockImpl::Mark::UNVISITED; + }); } static size_t @@ -160,7 +157,7 @@ CompiledGraph::compile_graph(GraphImpl* graph) _master = Task::simplify(std::move(_master)); if (graph->engine().world().conf().option("trace").get<int32_t>()) { - ColorContext ctx(stderr, ColorContext::Color::YELLOW); + const ColorContext ctx{stderr, ColorContext::Color::YELLOW}; dump(graph->path()); } } @@ -285,5 +282,4 @@ CompiledGraph::dump(const std::string& name) const sink(")\n"); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/CompiledGraph.hpp b/src/server/CompiledGraph.hpp index 8c2bb815..1949563d 100644 --- a/src/server/CompiledGraph.hpp +++ b/src/server/CompiledGraph.hpp @@ -19,16 +19,14 @@ #include "Task.hpp" -#include "raul/Maid.hpp" -#include "raul/Noncopyable.hpp" +#include <raul/Noncopyable.hpp> #include <cstddef> #include <memory> #include <set> #include <string> -namespace ingen { -namespace server { +namespace ingen::server { class BlockImpl; class GraphImpl; @@ -40,18 +38,15 @@ class RunContext; * execute the nodes in order and have nodes always executed before any of * their dependencies. */ -class CompiledGraph : public raul::Maid::Disposable - , public raul::Noncopyable +class CompiledGraph : public raul::Noncopyable { public: - static raul::managed_ptr<CompiledGraph> compile(raul::Maid& maid, GraphImpl& graph); + static std::unique_ptr<CompiledGraph> compile(GraphImpl& graph); void run(RunContext& ctx); private: - friend class raul::Maid; ///< Allow make_managed to construct - - CompiledGraph(GraphImpl* graph); + explicit CompiledGraph(GraphImpl* graph); using BlockSet = std::set<BlockImpl*>; @@ -73,13 +68,12 @@ private: std::unique_ptr<Task> _master; }; -inline raul::managed_ptr<CompiledGraph> -compile(raul::Maid& maid, GraphImpl& graph) +inline std::unique_ptr<CompiledGraph> +compile(GraphImpl& graph) { - return CompiledGraph::compile(maid, graph); + return CompiledGraph::compile(graph); } -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_COMPILEDGRAPH_HPP diff --git a/src/server/ControlBindings.cpp b/src/server/ControlBindings.cpp index 8bf52dfd..489d5384 100644 --- a/src/server/ControlBindings.cpp +++ b/src/server/ControlBindings.cpp @@ -23,18 +23,18 @@ #include "RunContext.hpp" #include "ThreadManager.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Log.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "lv2/atom/atom.h" -#include "lv2/atom/forge.h" -#include "lv2/atom/util.h" -#include "lv2/midi/midi.h" -#include "lv2/urid/urid.h" -#include "raul/Path.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Log.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <lv2/atom/atom.h> +#include <lv2/atom/forge.h> +#include <lv2/atom/util.h> +#include <lv2/midi/midi.h> +#include <lv2/urid/urid.h> +#include <raul/Path.hpp> #include <boost/intrusive/bstree.hpp> @@ -43,8 +43,7 @@ #include <cstring> #include <string> -namespace ingen { -namespace server { +namespace ingen::server { ControlBindings::ControlBindings(Engine& engine) : _engine(engine) @@ -74,6 +73,12 @@ ControlBindings::port_binding(PortImpl* port) const return binding_key(binding); } +static int16_t +get_atom_num(const LV2_Atom* const atom) +{ + return static_cast<int16_t>(reinterpret_cast<const LV2_Atom_Int*>(atom)->body); +} + ControlBindings::Key ControlBindings::binding_key(const Atom& binding) const { @@ -83,9 +88,31 @@ ControlBindings::binding_key(const Atom& binding) const if (binding.type() == uris.atom_Object) { const auto* obj = static_cast<const LV2_Atom_Object_Body*>(binding.get_body()); if (obj->otype == uris.midi_Bender) { - key = Key(Type::MIDI_BENDER); + lv2_atom_object_body_get(binding.size(), + obj, + uris.midi_channel.urid(), + &num, + nullptr); + if (!num) { + _engine.log().rt_error("Bender binding missing channel\n"); + } else if (num->type != uris.atom_Int) { + _engine.log().rt_error("Bender channel not an integer\n"); + } else { + key = Key(Type::MIDI_BENDER, get_atom_num(num)); + } } else if (obj->otype == uris.midi_ChannelPressure) { - key = Key(Type::MIDI_CHANNEL_PRESSURE); + lv2_atom_object_body_get(binding.size(), + obj, + uris.midi_channel.urid(), + &num, + nullptr); + if (!num) { + _engine.log().rt_error("Pressure binding missing channel\n"); + } else if (num->type != uris.atom_Int) { + _engine.log().rt_error("Pressure channel not an integer\n"); + } else { + key = Key(Type::MIDI_CHANNEL_PRESSURE, get_atom_num(num)); + } } else if (obj->otype == uris.midi_Controller) { lv2_atom_object_body_get(binding.size(), obj, @@ -97,7 +124,7 @@ ControlBindings::binding_key(const Atom& binding) const } else if (num->type != uris.atom_Int) { _engine.log().rt_error("Controller number not an integer\n"); } else { - key = Key(Type::MIDI_CC, reinterpret_cast<LV2_Atom_Int*>(num)->body); + key = Key(Type::MIDI_CC, get_atom_num(num)); } } else if (obj->otype == uris.midi_NoteOn) { lv2_atom_object_body_get(binding.size(), @@ -110,7 +137,7 @@ ControlBindings::binding_key(const Atom& binding) const } else if (num->type != uris.atom_Int) { _engine.log().rt_error("Note number not an integer\n"); } else { - key = Key(Type::MIDI_NOTE, reinterpret_cast<LV2_Atom_Int*>(num)->body); + key = Key(Type::MIDI_NOTE, get_atom_num(num)); } } } else if (binding.type()) { @@ -120,21 +147,28 @@ ControlBindings::binding_key(const Atom& binding) const } ControlBindings::Key -ControlBindings::midi_event_key(uint16_t, const uint8_t* buf, uint16_t& value) +ControlBindings::midi_event_key(const uint8_t* buf, uint16_t& value) { switch (lv2_midi_message_type(buf)) { case LV2_MIDI_MSG_CONTROLLER: - value = static_cast<int8_t>(buf[2]); - return {Type::MIDI_CC, static_cast<int8_t>(buf[1])}; + value = buf[2]; + return {Type::MIDI_CC, + static_cast<int16_t>(((buf[0] & 0x0FU) << 8U) | buf[1])}; case LV2_MIDI_MSG_BENDER: - value = (static_cast<int8_t>(buf[2]) << 7) + static_cast<int8_t>(buf[1]); - return {Type::MIDI_BENDER}; + value = static_cast<uint16_t>((buf[2] << 7U) + buf[1]); + return {Type::MIDI_BENDER, static_cast<int16_t>((buf[0] & 0x0FU))}; case LV2_MIDI_MSG_CHANNEL_PRESSURE: - value = static_cast<int8_t>(buf[1]); - return {Type::MIDI_CHANNEL_PRESSURE}; + value = buf[1]; + return {Type::MIDI_CHANNEL_PRESSURE, + static_cast<int16_t>((buf[0] & 0x0FU))}; case LV2_MIDI_MSG_NOTE_ON: - value = 1.0f; - return {Type::MIDI_NOTE, static_cast<int8_t>(buf[1])}; + value = 1; + return {Type::MIDI_NOTE, + static_cast<int16_t>(((buf[0] & 0x0FU) << 8U) | buf[1])}; + case LV2_MIDI_MSG_NOTE_OFF: + value = 0; + return {Type::MIDI_NOTE, + static_cast<int16_t>(((buf[0] & 0x0FU) << 8U) | buf[1])}; default: return {}; } @@ -152,9 +186,9 @@ ControlBindings::set_port_binding(RunContext&, binding->port = port; _bindings->insert(*binding); return true; - } else { - return false; } + + return false; } void @@ -165,15 +199,16 @@ ControlBindings::port_value_changed(RunContext& ctx, { const ingen::URIs& uris = ctx.engine().world().uris(); if (!!key) { - int16_t value = port_value_to_control( - ctx, port, key.type, value_atom); + const int16_t value = + port_value_to_control(ctx, port, key.type, value_atom); + uint16_t size = 0; uint8_t buf[4]; switch (key.type) { case Type::MIDI_CC: size = 3; buf[0] = LV2_MIDI_MSG_CONTROLLER; - buf[1] = key.num; + buf[1] = static_cast<uint8_t>(key.num); buf[2] = static_cast<int8_t>(value); break; case Type::MIDI_CHANNEL_PRESSURE: @@ -194,7 +229,7 @@ ControlBindings::port_value_changed(RunContext& ctx, } else if (value == 0) { buf[0] = LV2_MIDI_MSG_NOTE_OFF; } - buf[1] = key.num; + buf[1] = static_cast<uint8_t>(key.num); buf[2] = 0x64; // MIDI spec default break; default: @@ -215,7 +250,7 @@ ControlBindings::start_learn(PortImpl* port) ThreadManager::assert_thread(THREAD_PRE_PROCESS); Binding* b = _learn_binding.load(); if (!b) { - _learn_binding = new Binding(Type::NULL_CONTROL, port); + _learn_binding = new Binding(); } else { b->port = port; } @@ -262,7 +297,7 @@ ControlBindings::control_to_port_value(RunContext& ctx, float max = 1.0f; get_range(ctx, port, &min, &max); - return normal * (max - min) + min; + return (normal * (max - min)) + min; } int16_t @@ -282,24 +317,18 @@ ControlBindings::port_value_to_control(RunContext& ctx, const float value = value_atom.get<float>(); float normal = (value - min) / (max - min); - if (normal < 0.0f) { - normal = 0.0f; - } - - if (normal > 1.0f) { - normal = 1.0f; - } + normal = std::max(0.0f, std::min(1.0f, normal)); if (port->is_logarithmic()) { - normal = logf(normal * (static_cast<float>(M_E) - 1.0f) + 1.0f); + normal = logf((normal * (static_cast<float>(M_E) - 1.0f)) + 1.0f); } switch (type) { case Type::MIDI_CC: case Type::MIDI_CHANNEL_PRESSURE: - return lrintf(normal * 127.0f); + return static_cast<int16_t>(lrintf(normal * 127.0f)); case Type::MIDI_BENDER: - return lrintf(normal * 16383.0f); + return static_cast<int16_t>(lrintf(normal * 16383.0f)); case Type::MIDI_NOTE: return (value > 0.0f) ? 1 : 0; default: @@ -322,9 +351,13 @@ forge_binding(const URIs& uris, break; case ControlBindings::Type::MIDI_BENDER: lv2_atom_forge_object(forge, &frame, 0, uris.midi_Bender); + lv2_atom_forge_key(forge, uris.midi_channel); + lv2_atom_forge_int(forge, value); break; case ControlBindings::Type::MIDI_CHANNEL_PRESSURE: lv2_atom_forge_object(forge, &frame, 0, uris.midi_ChannelPressure); + lv2_atom_forge_key(forge, uris.midi_channel); + lv2_atom_forge_int(forge, value); break; case ControlBindings::Type::MIDI_NOTE: lv2_atom_forge_object(forge, &frame, 0, uris.midi_NoteOn); @@ -353,7 +386,7 @@ ControlBindings::set_port_value(RunContext& ctx, // TODO: Set port value property so it is saved port->set_control_value(ctx, ctx.start(), val); - URIs& uris = ctx.engine().world().uris(); + const URIs& uris = ctx.engine().world().uris(); ctx.notify(uris.ingen_value, ctx.start(), port, sizeof(float), _forge.Float, &val); } @@ -411,22 +444,22 @@ ControlBindings::pre_process(RunContext& ctx, Buffer* buffer) _feedback->clear(); if ((!_learn_binding && _bindings->empty()) || !buffer->get<LV2_Atom>()) { - return; // Don't bother reading input + return; // Don't bother reading input } auto* seq = buffer->get<LV2_Atom_Sequence>(); - LV2_ATOM_SEQUENCE_FOREACH(seq, ev) { + LV2_ATOM_SEQUENCE_FOREACH (seq, ev) { if (ev->body.type == uris.midi_MidiEvent) { const auto* buf = static_cast<const uint8_t*>(LV2_ATOM_BODY(&ev->body)); - const Key key = midi_event_key(ev->body.size, buf, value); + const Key key = midi_event_key(buf, value); if (_learn_binding && !!key) { - finish_learn(ctx, key); // Learn new binding + finish_learn(ctx, key); // Learn new binding } // Set all controls bound to this key const Binding k = {key, nullptr}; - for (Bindings::const_iterator i = _bindings->lower_bound(k); + for (auto i = _bindings->lower_bound(k); i != _bindings->end() && i->key == key; ++i) { set_port_value(ctx, i->port, key.type, value); @@ -443,5 +476,4 @@ ControlBindings::post_process(RunContext&, Buffer* buffer) } } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/ControlBindings.hpp b/src/server/ControlBindings.hpp index 1c231e22..0e6dbf63 100644 --- a/src/server/ControlBindings.hpp +++ b/src/server/ControlBindings.hpp @@ -19,9 +19,10 @@ #include "BufferRef.hpp" -#include "lv2/atom/forge.h" -#include "raul/Maid.hpp" +#include <lv2/atom/forge.h> +#include <raul/Maid.hpp> +#include <boost/intrusive/options.hpp> #include <boost/intrusive/set.hpp> #include <boost/intrusive/set_hook.hpp> @@ -30,15 +31,9 @@ #include <memory> #include <vector> -namespace raul { class Path; } - -namespace boost { -namespace intrusive { - -template <class Compare> struct compare; - -} // namespace intrusive -} // namespace boost +namespace raul { +class Path; +} // namespace raul namespace ingen { @@ -51,7 +46,8 @@ class Engine; class RunContext; class PortImpl; -class ControlBindings { +class ControlBindings +{ public: enum class Type : uint16_t { NULL_CONTROL, @@ -64,15 +60,20 @@ public: }; struct Key { - Key(Type t=Type::NULL_CONTROL, int16_t n=0) : type(t), num(n) {} - inline bool operator<(const Key& other) const { + Key(Type t, int16_t n) noexcept : type{t}, num{n} {} + Key() noexcept : Key{Type::NULL_CONTROL, 0U} {} + + bool operator<(const Key& other) const { return ((type < other.type) || (type == other.type && num < other.num)); } - inline bool operator==(const Key& other) const { + + bool operator==(const Key& other) const { return type == other.type && num == other.num; } - inline bool operator!() const { return type == Type::NULL_CONTROL; } + + bool operator!() const { return type == Type::NULL_CONTROL; } + Type type; int16_t num; }; @@ -80,9 +81,10 @@ public: /** One binding of a controller to a port. */ struct Binding : public boost::intrusive::set_base_hook<>, public raul::Maid::Disposable { - Binding(Key k=Key(), PortImpl* p=nullptr) : key(k), port(p) {} + Binding(Key k, PortImpl* p) noexcept : key{k}, port{p} {} + Binding() noexcept : Binding{Key{}, nullptr} {} - inline bool operator<(const Binding& rhs) const { return key < rhs.key; } + bool operator<(const Binding& rhs) const { return key < rhs.key; } Key key; PortImpl* port; @@ -129,7 +131,7 @@ private: boost::intrusive::compare<BindingLess>>; static Key - midi_event_key(uint16_t size, const uint8_t* buf, uint16_t& value); + midi_event_key(const uint8_t* buf, uint16_t& value); void set_port_value(RunContext& ctx, PortImpl* port, diff --git a/src/server/DirectDriver.hpp b/src/server/DirectDriver.hpp index 7c683493..bc52fc3a 100644 --- a/src/server/DirectDriver.hpp +++ b/src/server/DirectDriver.hpp @@ -24,20 +24,17 @@ #include "RunContext.hpp" #include "types.hpp" -#include "raul/Path.hpp" +#include <raul/Path.hpp> #include <boost/intrusive/slist.hpp> #include <cstddef> +#include <cstdint> #include <string> -namespace boost { -namespace intrusive { - +namespace boost::intrusive { template <bool Enabled> struct cache_last; - -} // namespace intrusive -} // namespace boost +} // namespace boost::intrusive namespace ingen { @@ -51,12 +48,13 @@ class Buffer; /** Driver for running Ingen directly as a library. * \ingroup engine */ -class DirectDriver : public Driver { +class DirectDriver : public Driver +{ public: DirectDriver(Engine& engine, double sample_rate, SampleCount block_length, - size_t seq_size) + uint32_t seq_size) : _engine(engine) , _sample_rate(sample_rate) , _block_length(block_length) @@ -103,7 +101,7 @@ public: SampleCount block_length() const override { return _block_length; } - size_t seq_size() const override { return _seq_size; } + uint32_t seq_size() const override { return _seq_size; } SampleCount sample_rate() const override { return _sample_rate; } @@ -123,7 +121,7 @@ private: Ports _ports; SampleCount _sample_rate; SampleCount _block_length; - size_t _seq_size; + uint32_t _seq_size; }; } // namespace server diff --git a/src/server/Driver.hpp b/src/server/Driver.hpp index 1bc6213d..112fb8ba 100644 --- a/src/server/Driver.hpp +++ b/src/server/Driver.hpp @@ -19,12 +19,14 @@ #include "types.hpp" -#include "ingen/URI.hpp" -#include "raul/Noncopyable.hpp" +#include <ingen/URI.hpp> +#include <raul/Noncopyable.hpp> #include <cstddef> -namespace raul { class Path; } +namespace raul { +class Path; +} // namespace raul namespace ingen { @@ -44,7 +46,8 @@ class RunContext; * * \ingroup engine */ -class Driver : public raul::Noncopyable { +class Driver : public raul::Noncopyable +{ public: virtual ~Driver() = default; @@ -95,7 +98,7 @@ public: virtual SampleCount block_length() const = 0; /** Return the event buffer size in bytes */ - virtual size_t seq_size() const = 0; + virtual uint32_t seq_size() const = 0; /** Return the sample rate in Hz */ virtual SampleRate sample_rate() const = 0; diff --git a/src/server/DuplexPort.cpp b/src/server/DuplexPort.cpp index ce516b46..1e07afd2 100644 --- a/src/server/DuplexPort.cpp +++ b/src/server/DuplexPort.cpp @@ -23,23 +23,24 @@ #include "Engine.hpp" #include "GraphImpl.hpp" #include "NodeImpl.hpp" - -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Node.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URIs.hpp" -#include "lv2/urid/urid.h" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" +#include "PortType.hpp" + +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Node.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <lv2/urid/urid.h> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> #include <algorithm> #include <map> #include <memory> #include <utility> -namespace ingen { -namespace server { +namespace ingen::server { DuplexPort::DuplexPort(BufferFactory& bufs, GraphImpl* parent, @@ -96,7 +97,7 @@ DuplexPort::duplicate(Engine& engine, GraphImpl* parent) { BufferFactory& bufs = *engine.buffer_factory(); - const Atom polyphonic = get_property(bufs.uris().ingen_polyphonic); + const Atom& polyphonic = get_property(bufs.uris().ingen_polyphonic); auto* dup = new DuplexPort( bufs, parent, symbol, _index, @@ -154,9 +155,12 @@ DuplexPort::get_buffers(BufferFactory& bufs, { if (!_is_driver_port && is_output()) { return InputPort::get_buffers(bufs, get, voices, poly, num_in_arcs); - } else if (!_is_driver_port && is_input()) { + } + + if (!_is_driver_port && is_input()) { return PortImpl::get_buffers(bufs, get, voices, poly, num_in_arcs); } + return false; } @@ -165,9 +169,12 @@ DuplexPort::setup_buffers(RunContext& ctx, BufferFactory& bufs, uint32_t poly) { if (!_is_driver_port && is_output()) { return InputPort::setup_buffers(ctx, bufs, poly); - } else if (!_is_driver_port && is_input()) { + } + + if (!_is_driver_port && is_input()) { return PortImpl::setup_buffers(ctx, bufs, poly); } + return false; } @@ -251,5 +258,4 @@ DuplexPort::next_value_offset(SampleCount offset, SampleCount end) const return PortImpl::next_value_offset(offset, end); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/DuplexPort.hpp b/src/server/DuplexPort.hpp index cdd764a0..fb3eb74e 100644 --- a/src/server/DuplexPort.hpp +++ b/src/server/DuplexPort.hpp @@ -19,32 +19,32 @@ #include "InputPort.hpp" #include "PortImpl.hpp" -#include "PortType.hpp" +#include "server.h" #include "types.hpp" -#include "ingen/URI.hpp" -#include "ingen/ingen.h" -#include "lv2/urid/urid.h" -#include "raul/Maid.hpp" +#include <lv2/urid/urid.h> +#include <raul/Maid.hpp> #include <boost/intrusive/slist_hook.hpp> #include <cstddef> #include <cstdint> -namespace raul { class Symbol; } +namespace raul { +class Symbol; +} // namespace raul namespace ingen { +enum class PortType; + class Atom; -class Properties; namespace server { class BufferFactory; class Engine; class GraphImpl; -class RunContext; /** A duplex Port (both an input and output port on a Graph) * @@ -55,7 +55,7 @@ class RunContext; * * \ingroup engine */ -class INGEN_API DuplexPort final +class INGEN_SERVER_API DuplexPort final : public InputPort , public boost::intrusive::slist_base_hook<> // In GraphImpl { diff --git a/src/server/Engine.cpp b/src/server/Engine.cpp index b48b291f..4d753bbc 100644 --- a/src/server/Engine.cpp +++ b/src/server/Engine.cpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2017 David Robillard <http://drobilla.net/> + Copyright 2007-2024 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -19,7 +19,6 @@ #include "BlockFactory.hpp" #include "Broadcaster.hpp" #include "BufferFactory.hpp" -#include "BufferRef.hpp" #include "ControlBindings.hpp" #include "DirectDriver.hpp" #include "Driver.hpp" @@ -39,30 +38,32 @@ #include "events/CreateGraph.hpp" #include "ingen_config.h" -#ifdef HAVE_SOCKET +#if USE_SOCKET #include "SocketListener.hpp" #endif -#include "ingen/Atom.hpp" -#include "ingen/AtomReader.hpp" -#include "ingen/ColorContext.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/LV2Features.hpp" -#include "ingen/Log.hpp" -#include "ingen/Resource.hpp" -#include "ingen/Store.hpp" -#include "ingen/StreamWriter.hpp" -#include "ingen/Tee.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "lv2/buf-size/buf-size.h" -#include "lv2/state/state.h" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "raul/RingBuffer.hpp" +#include <ingen/Atom.hpp> +#include <ingen/AtomReader.hpp> +#include <ingen/Clock.hpp> +#include <ingen/ColorContext.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/LV2Features.hpp> +#include <ingen/Log.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/Store.hpp> +#include <ingen/StreamWriter.hpp> +#include <ingen/Tee.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <lv2/buf-size/buf-size.h> +#include <lv2/state/state.h> +#include <raul/Maid.hpp> +#include <raul/Path.hpp> +#include <raul/RingBuffer.hpp> #include <algorithm> #include <cmath> @@ -71,11 +72,11 @@ #include <limits> #include <map> #include <memory> +#include <string> #include <thread> #include <utility> -namespace ingen { -namespace server { +namespace ingen::server { thread_local unsigned ThreadManager::flags(0); bool ThreadManager::single_threaded(true); @@ -98,25 +99,22 @@ Engine::Engine(ingen::World& world) , _interface(_event_writer) , _atom_interface( new AtomReader(world.uri_map(), world.uris(), world.log(), *_interface)) - , _root_graph(nullptr) - , _cycle_start_time(0) , _rand_engine(reinterpret_cast<uintptr_t>(this)) - , _uniform_dist(0.0f, 1.0f) - , _quit_flag(false) - , _reset_load_flag(false) , _atomic_bundles(world.conf().option("atomic-bundles").get<int32_t>()) - , _activated(false) { if (!world.store()) { world.set_store(std::make_shared<ingen::Store>()); } for (int i = 0; i < world.conf().option("threads").get<int32_t>(); ++i) { + const bool is_threaded = (i > 0); _notifications.emplace_back( - std::make_unique<raul::RingBuffer>(uint32_t(24 * event_queue_size()))); + std::make_unique<raul::RingBuffer>(24U * event_queue_size())); _run_contexts.emplace_back( - std::make_unique<RunContext>( - *this, _notifications.back().get(), unsigned(i), i > 0)); + std::make_unique<RunContext>(*this, + _notifications.back().get(), + static_cast<unsigned>(i), + is_threaded)); } _world.lv2_features().add_feature(_worker->schedule_feature()); @@ -187,7 +185,7 @@ Engine::~Engine() void Engine::listen() { -#ifdef HAVE_SOCKET +#if USE_SOCKET _listener = std::make_unique<SocketListener>(*this); #endif } @@ -244,12 +242,11 @@ Engine::emit_notifications(FrameTime end) bool Engine::pending_notifications() { - for (const auto& ctx : _run_contexts) { - if (ctx->pending_notifications()) { - return true; - } - } - return false; + return std::any_of(_run_contexts.begin(), + _run_contexts.end(), + [](const auto& ctx) { + return ctx->pending_notifications(); + }); } bool @@ -303,16 +300,17 @@ Engine::block_length() const return _driver->block_length(); } -size_t +uint32_t Engine::sequence_size() const { return _driver->seq_size(); } -size_t +uint32_t Engine::event_queue_size() const { - return _world.conf().option("queue-size").get<int32_t>(); + return static_cast<uint32_t>( + std::max(0, _world.conf().option("queue-size").get<int32_t>())); } void @@ -386,7 +384,7 @@ Engine::reset_load() } void -Engine::init(double sample_rate, uint32_t block_length, size_t seq_size) +Engine::init(double sample_rate, uint32_t block_length, uint32_t seq_size) { set_driver(std::make_shared<DirectDriver>( *this, sample_rate, block_length, seq_size)); @@ -537,5 +535,4 @@ Engine::unregister_client(const std::shared_ptr<Interface>& client) return _broadcaster->unregister_client(client); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/Engine.hpp b/src/server/Engine.hpp index b5b6a311..8fa1d169 100644 --- a/src/server/Engine.hpp +++ b/src/server/Engine.hpp @@ -19,12 +19,12 @@ #include "Event.hpp" #include "Load.hpp" +#include "server.h" #include "types.hpp" -#include "ingen/Clock.hpp" -#include "ingen/EngineBase.hpp" -#include "ingen/Properties.hpp" -#include "ingen/ingen.h" +#include <ingen/Clock.hpp> +#include <ingen/EngineBase.hpp> +#include <ingen/Properties.hpp> #include <chrono> #include <condition_variable> @@ -75,7 +75,7 @@ class Worker; @ingroup engine */ -class INGEN_API Engine final : public EngineBase +class INGEN_SERVER_API Engine final : public EngineBase { public: explicit Engine(ingen::World& world); @@ -85,7 +85,7 @@ public: Engine& operator=(const Engine&) = delete; // EngineBase methods - void init(double sample_rate, uint32_t block_length, size_t seq_size) override; + void init(double sample_rate, uint32_t block_length, uint32_t seq_size) override; bool supports_dynamic_ports() const override; bool activate() override; void deactivate() override; @@ -114,7 +114,7 @@ public: * * This value is comparable to the value returned by current_time(). */ - inline uint64_t cycle_start_time(const RunContext&) const { + uint64_t cycle_start_time(const RunContext&) const { return _cycle_start_time; } @@ -170,8 +170,8 @@ public: SampleRate sample_rate() const; SampleCount block_length() const; - size_t sequence_size() const; - size_t event_queue_size() const; + uint32_t sequence_size() const; + uint32_t event_queue_size() const; size_t n_threads() const { return _run_contexts.size(); } bool atomic_bundles() const { return _atomic_bundles; } @@ -199,24 +199,24 @@ private: std::shared_ptr<EventWriter> _event_writer; std::shared_ptr<Interface> _interface; std::unique_ptr<AtomReader> _atom_interface; - GraphImpl* _root_graph; + GraphImpl* _root_graph{nullptr}; std::vector<std::unique_ptr<raul::RingBuffer>> _notifications; std::vector<std::unique_ptr<RunContext>> _run_contexts; - uint64_t _cycle_start_time; + uint64_t _cycle_start_time{0}; Load _run_load; Clock _clock; std::mt19937 _rand_engine; - std::uniform_real_distribution<float> _uniform_dist; + std::uniform_real_distribution<float> _uniform_dist{0.0f, 1.0f}; std::condition_variable _tasks_available; std::mutex _tasks_mutex; - bool _quit_flag; - bool _reset_load_flag; + bool _quit_flag{false}; + bool _reset_load_flag{false}; bool _atomic_bundles; - bool _activated; + bool _activated{false}; }; } // namespace server diff --git a/src/server/EnginePort.hpp b/src/server/EnginePort.hpp index ecfe59b3..d7e73f63 100644 --- a/src/server/EnginePort.hpp +++ b/src/server/EnginePort.hpp @@ -19,15 +19,14 @@ #include "DuplexPort.hpp" -#include "raul/Deletable.hpp" -#include "raul/Noncopyable.hpp" +#include <raul/Deletable.hpp> +#include <raul/Noncopyable.hpp> #include <boost/intrusive/slist_hook.hpp> #include <cstdint> -namespace ingen { -namespace server { +namespace ingen::server { /** A "system" port (e.g. a Jack port, an external port on Ingen). * @@ -40,9 +39,6 @@ class EnginePort : public raul::Noncopyable public: explicit EnginePort(DuplexPort* port) : _graph_port(port) - , _buffer(nullptr) - , _handle(nullptr) - , _driver_index(0) {} void set_buffer(void* buf) { _buffer = buf; } @@ -57,12 +53,11 @@ public: protected: DuplexPort* _graph_port; - void* _buffer; - void* _handle; - uint32_t _driver_index; + void* _buffer{nullptr}; + void* _handle{nullptr}; + uint32_t _driver_index{0}; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_ENGINE_PORT_HPP diff --git a/src/server/Event.hpp b/src/server/Event.hpp index e00aa0d1..3c9c5c26 100644 --- a/src/server/Event.hpp +++ b/src/server/Event.hpp @@ -19,12 +19,12 @@ #include "types.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Status.hpp" -#include "ingen/URI.hpp" -#include "ingen/paths.hpp" -#include "raul/Deletable.hpp" -#include "raul/Noncopyable.hpp" +#include <ingen/Interface.hpp> +#include <ingen/Status.hpp> +#include <ingen/URI.hpp> +#include <ingen/paths.hpp> +#include <raul/Deletable.hpp> +#include <raul/Noncopyable.hpp> #include <atomic> #include <cstdint> @@ -36,8 +36,7 @@ namespace raul { class Path; } // namespace raul -namespace ingen { -namespace server { +namespace ingen::server { class Engine; class RunContext; @@ -63,10 +62,10 @@ public: /** Execution mode for events that block and unblock preprocessing. */ enum class Execution { - NORMAL, ///< Normal pipelined execution - ATOMIC, ///< Block pre-processing until this event is executed - BLOCK, ///< Begin atomic block of events - UNBLOCK ///< Finish atomic executed block of events + NORMAL, ///< Normal pipelined execution + ATOMIC, ///< Block pre-processing until this event is executed + BLOCK, ///< Begin atomic block of events + UNBLOCK ///< Finish atomic executed block of events }; /** Claim position in undo stack before pre-processing (non-realtime). */ @@ -85,13 +84,13 @@ public: virtual void undo(Interface& target) {} /** Return true iff this event has been pre-processed. */ - inline bool is_prepared() const { return _status != Status::NOT_PREPARED; } + bool is_prepared() const { return _status != Status::NOT_PREPARED; } /** Return the time stamp of this event. */ - inline SampleCount time() const { return _time; } + SampleCount time() const { return _time; } /** Set the time stamp of this event. */ - inline void set_time(SampleCount time) { _time = time; } + void set_time(SampleCount time) { _time = time; } /** Get the next event to be processed after this one. */ Event* next() const { return _next.load(); } @@ -111,10 +110,13 @@ public: /** Set the undo mode of this event. */ void set_mode(Mode mode) { _mode = mode; } - inline Engine& engine() { return _engine; } + Engine& engine() { return _engine; } protected: - Event(Engine& engine, std::shared_ptr<Interface> client, int32_t id, FrameTime time) + Event(Engine& engine, + std::shared_ptr<Interface> client, + int32_t id, + FrameTime time) noexcept : _engine(engine) , _next(nullptr) , _request_client(std::move(client)) @@ -134,22 +136,22 @@ protected: , _mode(Mode::NORMAL) {} - inline bool pre_process_done(Status st) { + bool pre_process_done(Status st) { _status = st; return st == Status::SUCCESS; } - inline bool pre_process_done(Status st, const URI& subject) { + bool pre_process_done(Status st, const URI& subject) { _err_subject = subject; return pre_process_done(st); } - inline bool pre_process_done(Status st, const raul::Path& subject) { + bool pre_process_done(Status st, const raul::Path& subject) { return pre_process_done(st, path_to_uri(subject)); } /** Respond to the originating client. */ - inline Status respond() { + Status respond() { if (_request_client && _request_id) { _request_client->response(_request_id, _status, _err_subject); } @@ -166,7 +168,6 @@ protected: Mode _mode; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_EVENT_HPP diff --git a/src/server/EventWriter.cpp b/src/server/EventWriter.cpp index 9001b01a..fff9226a 100644 --- a/src/server/EventWriter.cpp +++ b/src/server/EventWriter.cpp @@ -18,27 +18,25 @@ #include "Engine.hpp" -#include "events/Connect.hpp" -#include "events/Copy.hpp" -#include "events/Delete.hpp" -#include "events/Delta.hpp" -#include "events/Disconnect.hpp" -#include "events/DisconnectAll.hpp" -#include "events/Get.hpp" -#include "events/Mark.hpp" -#include "events/Move.hpp" -#include "events/Undo.hpp" - -#include <boost/variant/apply_visitor.hpp> - -namespace ingen { -namespace server { +#include <events/Connect.hpp> +#include <events/Copy.hpp> +#include <events/Delete.hpp> +#include <events/Delta.hpp> +#include <events/Disconnect.hpp> +#include <events/DisconnectAll.hpp> +#include <events/Get.hpp> +#include <events/Mark.hpp> +#include <events/Move.hpp> +#include <events/Undo.hpp> +#include <ingen/Message.hpp> + +#include <variant> + +namespace ingen::server { EventWriter::EventWriter(Engine& engine) : _engine(engine) - , _event_mode(Event::Mode::NORMAL) -{ -} +{} SampleCount EventWriter::now() const @@ -49,7 +47,7 @@ EventWriter::now() const void EventWriter::message(const Message& msg) { - boost::apply_visitor(*this, msg); + std::visit(*this, msg); } void @@ -152,5 +150,4 @@ EventWriter::operator()(const Get& msg) _event_mode); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/EventWriter.hpp b/src/server/EventWriter.hpp index 184cefb7..55ee1158 100644 --- a/src/server/EventWriter.hpp +++ b/src/server/EventWriter.hpp @@ -20,14 +20,13 @@ #include "Event.hpp" #include "types.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Message.hpp" -#include "ingen/URI.hpp" +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/URI.hpp> #include <memory> -namespace ingen { -namespace server { +namespace ingen::server { class Engine; @@ -62,25 +61,24 @@ public: void operator()(const Delta&); void operator()(const Disconnect&); void operator()(const DisconnectAll&); - void operator()(const Error&) {} + void operator()(const Error&) noexcept {} void operator()(const Get&); void operator()(const Move&); void operator()(const Put&); void operator()(const Redo&); - void operator()(const Response&) {} + void operator()(const Response&) noexcept {} void operator()(const SetProperty&); void operator()(const Undo&); protected: Engine& _engine; std::shared_ptr<Interface> _respondee; - Event::Mode _event_mode; + Event::Mode _event_mode{Event::Mode::NORMAL}; private: SampleCount now() const; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_EVENTWRITER_HPP diff --git a/src/server/FrameTimer.hpp b/src/server/FrameTimer.hpp index 8a155777..0078f99c 100644 --- a/src/server/FrameTimer.hpp +++ b/src/server/FrameTimer.hpp @@ -20,8 +20,7 @@ #include <cmath> #include <cstdint> -namespace ingen { -namespace server { +namespace ingen::server { /** Delay-locked loop for monotonic sample time. * @@ -43,8 +42,7 @@ public: , b(sqrt(2) * omega) , c(omega * omega) , nper(period_size) - { - } + {} /** Update the timer for current real time `usec` and frame `frame`. */ void update(uint64_t usec, uint64_t frame) { @@ -96,16 +94,15 @@ private: const double b; const double c; - uint64_t nper = 0u; + uint64_t nper = 0U; double e2 = 0.0; double t0 = 0.0; double t1 = 0.0; - uint64_t n0 = 0u; - uint64_t n1 = 0u; + uint64_t n0 = 0U; + uint64_t n1 = 0U; bool initialized = false; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_FRAMETIMER_HPP diff --git a/src/server/GraphImpl.cpp b/src/server/GraphImpl.cpp index a668312d..9e44a4d4 100644 --- a/src/server/GraphImpl.cpp +++ b/src/server/GraphImpl.cpp @@ -28,24 +28,24 @@ #include "PortImpl.hpp" #include "ThreadManager.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "lv2/urid/urid.h" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Forge.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <lv2/urid/urid.h> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> +#include <raul/Symbol.hpp> #include <cassert> #include <cstddef> #include <map> #include <memory> -#include <type_traits> +#include <string> #include <unordered_map> -namespace ingen { -namespace server { +namespace ingen::server { GraphImpl::GraphImpl(Engine& engine, const raul::Symbol& symbol, @@ -61,7 +61,6 @@ GraphImpl::GraphImpl(Engine& engine, , _engine(engine) , _poly_pre(internal_poly) , _poly_process(internal_poly) - , _process(false) { assert(internal_poly >= 1); assert(internal_poly <= 128); @@ -123,7 +122,7 @@ GraphImpl::duplicate(Engine& engine, } // Add duplicates of all arcs - for (const auto& a : _arcs) { + for (const auto& a : _graph_arcs) { auto arc = std::dynamic_pointer_cast<ArcImpl>(a.second); if (arc) { auto t = port_map.find(arc->tail()); @@ -286,38 +285,40 @@ void GraphImpl::add_arc(const std::shared_ptr<ArcImpl>& a) { ThreadManager::assert_thread(THREAD_PRE_PROCESS); - _arcs.emplace(std::make_pair(a->tail(), a->head()), a); + _graph_arcs.emplace(std::make_pair(a->tail(), a->head()), a); } std::shared_ptr<ArcImpl> GraphImpl::remove_arc(const PortImpl* tail, const PortImpl* dst_port) { ThreadManager::assert_thread(THREAD_PRE_PROCESS); - auto i = _arcs.find(std::make_pair(tail, dst_port)); - if (i != _arcs.end()) { + auto i = _graph_arcs.find(std::make_pair(tail, dst_port)); + if (i != _graph_arcs.end()) { auto arc = std::dynamic_pointer_cast<ArcImpl>(i->second); - _arcs.erase(i); + _graph_arcs.erase(i); return arc; - } else { - return nullptr; } + + return nullptr; } bool GraphImpl::has_arc(const PortImpl* tail, const PortImpl* dst_port) const { ThreadManager::assert_thread(THREAD_PRE_PROCESS); - auto i = _arcs.find(std::make_pair(tail, dst_port)); - return (i != _arcs.end()); + auto i = _graph_arcs.find(std::make_pair(tail, dst_port)); + return (i != _graph_arcs.end()); } -void -GraphImpl::set_compiled_graph(raul::managed_ptr<CompiledGraph>&& cg) +std::unique_ptr<CompiledGraph> +GraphImpl::swap_compiled_graph(std::unique_ptr<CompiledGraph> cg) { if (_compiled_graph && _compiled_graph != cg) { _engine.reset_load(); } - _compiled_graph = std::move(cg); + + _compiled_graph.swap(cg); + return cg; } uint32_t @@ -331,7 +332,7 @@ bool GraphImpl::has_port_with_index(uint32_t index) const { BufferFactory& bufs = *_engine.buffer_factory(); - const auto index_atom = bufs.forge().make(int32_t(index)); + const auto index_atom = bufs.forge().make(static_cast<int32_t>(index)); for (const auto& p : _inputs) { if (p.has_property(bufs.uris().lv2_index, index_atom)) { @@ -391,5 +392,4 @@ GraphImpl::build_ports_array(raul::Maid& maid) return result; } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/GraphImpl.hpp b/src/server/GraphImpl.hpp index cbbd57de..6c852106 100644 --- a/src/server/GraphImpl.hpp +++ b/src/server/GraphImpl.hpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2015 David Robillard <http://drobilla.net/> + Copyright 2007-2023 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -20,12 +20,13 @@ #include "BlockImpl.hpp" #include "DuplexPort.hpp" #include "ThreadManager.hpp" +#include "server.h" #include "types.hpp" -#include "ingen/Node.hpp" -#include "lv2/urid/urid.h" -#include "raul/Maid.hpp" +#include <lv2/urid/urid.h> +#include <raul/Maid.hpp> +#include <boost/intrusive/options.hpp> #include <boost/intrusive/slist.hpp> #include <cassert> @@ -37,16 +38,7 @@ namespace raul { class Symbol; } // namespace raul -namespace boost { -namespace intrusive { - -template <bool Enabled> struct constant_time_size; - -} // namespace intrusive -} // namespace boost - -namespace ingen { -namespace server { +namespace ingen::server { class ArcImpl; class BufferFactory; @@ -63,7 +55,7 @@ class RunContext; * * \ingroup engine */ -class GraphImpl final : public BlockImpl +class INGEN_SERVER_API GraphImpl final : public BlockImpl { public: GraphImpl(Engine& engine, @@ -105,9 +97,14 @@ public: * Audio thread. * * \param ctx Process context + * * \param bufs New set of buffers - * \param poly Must be < the most recent value passed to prepare_internal_poly. - * \param maid Any objects no longer needed will be pushed to this + * + * \param poly Must be < the most recent value passed to + * prepare_internal_poly. + * + * \param maid Any objects no longer needed will be + * pushed to this */ bool apply_internal_poly(RunContext& ctx, BufferFactory& bufs, @@ -184,7 +181,8 @@ public: bool has_arc(const PortImpl* tail, const PortImpl* dst_port) const; /** Set a new compiled graph to run, and return the old one. */ - void set_compiled_graph(raul::managed_ptr<CompiledGraph>&& cg); + [[nodiscard]] std::unique_ptr<CompiledGraph> + swap_compiled_graph(std::unique_ptr<CompiledGraph> cg); const raul::managed_ptr<Ports>& external_ports() { return _ports; } @@ -203,17 +201,18 @@ public: Engine& engine() { return _engine; } private: - Engine& _engine; - uint32_t _poly_pre; ///< Pre-process thread only - uint32_t _poly_process; ///< Process thread only - raul::managed_ptr<CompiledGraph> _compiled_graph; ///< Process thread only - PortList _inputs; ///< Pre-process thread only - PortList _outputs; ///< Pre-process thread only - Blocks _blocks; ///< Pre-process thread only - bool _process; ///< True iff graph is enabled + using CompiledGraphPtr = std::unique_ptr<CompiledGraph>; + + Engine& _engine; + uint32_t _poly_pre; ///< Pre-process thread only + uint32_t _poly_process; ///< Process thread only + CompiledGraphPtr _compiled_graph; ///< Process thread only + PortList _inputs; ///< Pre-process thread only + PortList _outputs; ///< Pre-process thread only + Blocks _blocks; ///< Pre-process thread only + bool _process{false}; ///< True iff graph is enabled }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_GRAPHIMPL_HPP diff --git a/src/server/GraphPlugin.hpp b/src/server/GraphPlugin.hpp index b7a281f5..302141e7 100644 --- a/src/server/GraphPlugin.hpp +++ b/src/server/GraphPlugin.hpp @@ -19,15 +19,14 @@ #include "PluginImpl.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "lilv/lilv.h" -#include "raul/Symbol.hpp" +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <lilv/lilv.h> +#include <raul/Symbol.hpp> #include <string> -namespace ingen { -namespace server { +namespace ingen::server { class BlockImpl; class BufferFactory; @@ -66,7 +65,6 @@ private: const std::string _name; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_GRAPHPLUGIN_HPP diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp index 10a525cc..01622209 100644 --- a/src/server/InputPort.cpp +++ b/src/server/InputPort.cpp @@ -23,22 +23,23 @@ #include "BufferRef.hpp" #include "GraphImpl.hpp" #include "NodeImpl.hpp" +#include "PortType.hpp" #include "RunContext.hpp" #include "mix.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Node.hpp" -#include "ingen/URIs.hpp" -#include "lv2/urid/urid.h" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Node.hpp> +#include <ingen/URIs.hpp> +#include <lv2/urid/urid.h> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> +#include <algorithm> #include <cassert> #include <cstdlib> #include <memory> -namespace ingen { -namespace server { +namespace ingen::server { InputPort::InputPort(BufferFactory& bufs, BlockImpl* parent, @@ -50,7 +51,6 @@ InputPort::InputPort(BufferFactory& bufs, const Atom& value, size_t buffer_size) : PortImpl(bufs, parent, symbol, index, poly, type, buffer_type, value, buffer_size, false) - , _num_arcs(0) { const ingen::URIs& uris = bufs.uris(); @@ -178,7 +178,7 @@ InputPort::pre_run(RunContext& ctx) { if ((_user_buffer || !_arcs.empty()) && !direct_connect()) { const uint32_t src_poly = max_tail_poly(ctx); - const uint32_t max_n_srcs = _arcs.size() * src_poly + 1; + const uint32_t max_n_srcs = (_arcs.size() * src_poly) + 1; for (uint32_t v = 0; v < _poly; ++v) { if (!buffer(v)->get<void>()) { @@ -232,9 +232,7 @@ InputPort::next_value_offset(SampleCount offset, SampleCount end) const for (const auto& arc : _arcs) { const SampleCount o = arc.tail()->next_value_offset(offset, end); - if (o < earliest) { - earliest = o; - } + earliest = std::min(o, earliest); } return earliest; @@ -262,5 +260,4 @@ InputPort::direct_connect() const && buffer(0)->type() != _bufs.uris().atom_Sequence; } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/InputPort.hpp b/src/server/InputPort.hpp index 9357c3ff..f3c6e553 100644 --- a/src/server/InputPort.hpp +++ b/src/server/InputPort.hpp @@ -17,31 +17,27 @@ #ifndef INGEN_ENGINE_INPUTPORT_HPP #define INGEN_ENGINE_INPUTPORT_HPP -#include "ArcImpl.hpp" // IWYU pragma: keep +#include "ArcImpl.hpp" #include "PortImpl.hpp" -#include "PortType.hpp" #include "types.hpp" -#include "lv2/urid/urid.h" -#include "raul/Maid.hpp" +#include <lv2/urid/urid.h> +#include <raul/Maid.hpp> +#include <boost/intrusive/options.hpp> #include <boost/intrusive/slist.hpp> #include <cstdint> #include <cstdlib> -namespace raul { class Symbol; } - -namespace boost { -namespace intrusive { - -template <bool Enabled> struct constant_time_size; - -} // namespace intrusive -} // namespace boost +namespace raul { +class Symbol; +} // namespace raul namespace ingen { +enum class PortType; + class Atom; namespace server { @@ -100,7 +96,7 @@ public: /** Like `get_buffers`, but for the pre-process thread. * - * This uses the "current" number of arcs fromthe perspective of the + * This uses the "current" number of arcs from the perspective of the * pre-process thread to allocate buffers for application of a * connection/disconnection/etc in the next process cycle. */ @@ -136,8 +132,8 @@ protected: uint32_t poly, size_t num_in_arcs) const override; - size_t _num_arcs; ///< Pre-process thread - Arcs _arcs; ///< Audio thread + size_t _num_arcs{0}; ///< Pre-process thread + Arcs _arcs; ///< Audio thread }; } // namespace server diff --git a/src/server/InternalBlock.cpp b/src/server/InternalBlock.cpp index 68e1f3e8..2eb0d411 100644 --- a/src/server/InternalBlock.cpp +++ b/src/server/InternalBlock.cpp @@ -23,8 +23,8 @@ #include "PluginImpl.hpp" #include "PortImpl.hpp" -#include "ingen/URIs.hpp" -#include "raul/Array.hpp" +#include <ingen/URIs.hpp> +#include <raul/Array.hpp> #include <boost/smart_ptr/intrusive_ptr.hpp> @@ -43,7 +43,6 @@ class Atom; namespace server { class GraphImpl; -class RunContext; InternalBlock::InternalBlock(PluginImpl* plugin, const raul::Symbol& symbol, diff --git a/src/server/InternalBlock.hpp b/src/server/InternalBlock.hpp index 2357f405..9eca9716 100644 --- a/src/server/InternalBlock.hpp +++ b/src/server/InternalBlock.hpp @@ -24,13 +24,10 @@ namespace raul { class Symbol; } // namespace raul -namespace ingen { -namespace server { +namespace ingen::server { -class Engine; class GraphImpl; class PluginImpl; -class RunContext; /** An internal Block implemented inside Ingen. * @@ -52,7 +49,6 @@ public: void pre_process(RunContext& ctx) override; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_BLOCKIMPL_HPP diff --git a/src/server/InternalPlugin.cpp b/src/server/InternalPlugin.cpp index 0355ff1e..7670c931 100644 --- a/src/server/InternalPlugin.cpp +++ b/src/server/InternalPlugin.cpp @@ -24,12 +24,14 @@ #include "internals/Trigger.hpp" #include "types.hpp" -#include "ingen/URIs.hpp" +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <lilv/lilv.h> +#include <raul/Symbol.hpp> #include <utility> -namespace ingen { -namespace server { +namespace ingen::server { InternalPlugin::InternalPlugin(URIs& uris, const URI& uri, raul::Symbol symbol) : PluginImpl(uris, uris.ingen_Internal.urid_atom(), uri) @@ -51,22 +53,29 @@ InternalPlugin::instantiate(BufferFactory& bufs, if (uri() == NS_INTERNALS "BlockDelay") { return new internals::BlockDelayNode( this, bufs, symbol, polyphonic, parent, srate); - } else if (uri() == NS_INTERNALS "Controller") { + } + + if (uri() == NS_INTERNALS "Controller") { return new internals::ControllerNode( this, bufs, symbol, polyphonic, parent, srate); - } else if (uri() == NS_INTERNALS "Note") { + } + + if (uri() == NS_INTERNALS "Note") { return new internals::NoteNode( this, bufs, symbol, polyphonic, parent, srate); - } else if (uri() == NS_INTERNALS "Time") { + } + + if (uri() == NS_INTERNALS "Time") { return new internals::TimeNode( this, bufs, symbol, polyphonic, parent, srate); - } else if (uri() == NS_INTERNALS "Trigger") { + } + + if (uri() == NS_INTERNALS "Trigger") { return new internals::TriggerNode( this, bufs, symbol, polyphonic, parent, srate); - } else { - return nullptr; } + + return nullptr; } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/InternalPlugin.hpp b/src/server/InternalPlugin.hpp index 9dfabc5f..4d715491 100644 --- a/src/server/InternalPlugin.hpp +++ b/src/server/InternalPlugin.hpp @@ -19,9 +19,9 @@ #include "PluginImpl.hpp" -#include "ingen/URI.hpp" -#include "lilv/lilv.h" -#include "raul/Symbol.hpp" +#include <ingen/URI.hpp> +#include <lilv/lilv.h> +#include <raul/Symbol.hpp> #define NS_INTERNALS "http://drobilla.net/ns/ingen-internals#" @@ -31,11 +31,6 @@ class URIs; namespace server { -class BlockImpl; -class BufferFactory; -class Engine; -class GraphImpl; - /** Implementation of an Internal plugin. */ class InternalPlugin : public PluginImpl diff --git a/src/server/JackDriver.cpp b/src/server/JackDriver.cpp index f03689cb..e508c850 100644 --- a/src/server/JackDriver.cpp +++ b/src/server/JackDriver.cpp @@ -21,6 +21,7 @@ #include "BufferRef.hpp" #include "DuplexPort.hpp" #include "Engine.hpp" +#include "FrameTimer.hpp" #include "GraphImpl.hpp" #include "PortType.hpp" #include "RunContext.hpp" @@ -28,55 +29,45 @@ #include "ingen_config.h" #include "util.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Log.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "lv2/atom/atom.h" -#include "lv2/atom/forge.h" -#include "lv2/atom/util.h" -#include "raul/Path.hpp" - +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Log.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <lv2/atom/atom.h> +#include <lv2/atom/forge.h> +#include <lv2/atom/util.h> +#include <raul/Path.hpp> +#include <raul/Semaphore.hpp> + +#include <jack/jack.h> #include <jack/midiport.h> #include <jack/transport.h> -#ifdef HAVE_JACK_METADATA +#if USE_JACK_METADATA #include "jackey.h" #include <jack/metadata.h> #endif #include <cassert> #include <chrono> +#include <cstdint> #include <map> #include <string> #include <utility> using jack_sample_t = jack_default_audio_sample_t; -namespace ingen { -namespace server { +namespace ingen::server { JackDriver::JackDriver(Engine& engine) - : _engine(engine) - , _forge() - , _sem(0) - , _flag(false) - , _client(nullptr) - , _block_length(0) - , _seq_size(0) - , _sample_rate(0) - , _is_activated(false) - , _position() - , _transport_state() - , _old_bpm(120.0) - , _old_frame(0) - , _old_rolling(false) + : _engine(engine) + , _forge() + , _midi_event_type(_engine.world().uris().midi_MidiEvent) { - _midi_event_type = _engine.world().uris().midi_MidiEvent; lv2_atom_forge_init(&_forge, &engine.world().uri_map().urid_map()); } @@ -102,7 +93,7 @@ JackDriver::attach(const std::string& server_name, } } - // Either server name not specified, or supplied server name does not exist + // Server name not specified, or that server doesn't exist // Connect to default server if (!_client) { if ((_client = jack_client_open(client_name.c_str(), JackNullOption, nullptr))) { @@ -121,7 +112,8 @@ JackDriver::attach(const std::string& server_name, _sample_rate = jack_get_sample_rate(_client); _block_length = jack_get_buffer_size(_client); - _seq_size = jack_port_type_get_buffer_size(_client, JACK_DEFAULT_MIDI_TYPE); + _seq_size = static_cast<uint32_t>( + jack_port_type_get_buffer_size(_client, JACK_DEFAULT_MIDI_TYPE)); _fallback_buffer = AudioBufPtr( static_cast<float*>( @@ -136,6 +128,8 @@ JackDriver::attach(const std::string& server_name, register_port(p); } + _timer = std::make_unique<FrameTimer>(_block_length, _sample_rate); + return true; } @@ -165,10 +159,10 @@ JackDriver::activate() if (jack_activate(_client)) { _engine.log().error("Could not activate Jack client, aborting\n"); return false; - } else { - _engine.log().info("Activated Jack client `%1%'\n", - world.conf().option("jack-name").ptr<char>()); } + + _engine.log().info("Activated Jack client `%1%'\n", + world.conf().option("jack-name").ptr<char>()); return true; } @@ -269,14 +263,14 @@ void JackDriver::rename_port(const raul::Path& old_path, const raul::Path& new_path) { - EnginePort* eport = get_port(old_path); + const EnginePort* eport = get_port(old_path); if (eport) { -#ifdef HAVE_JACK_PORT_RENAME +#if USE_JACK_PORT_RENAME jack_port_rename(_client, static_cast<jack_port_t*>(eport->handle()), new_path.substr(1).c_str()); #else - jack_port_set_name((jack_port_t*)eport->handle(), + jack_port_set_name(static_cast<jack_port_t*>(eport->handle()), new_path.substr(1).c_str()); #endif } @@ -287,7 +281,7 @@ JackDriver::port_property(const raul::Path& path, const URI& uri, const Atom& value) { -#ifdef HAVE_JACK_METADATA +#if USE_JACK_METADATA EnginePort* eport = get_port(path); if (eport) { const auto* const jport = @@ -303,7 +297,7 @@ JackDriver::port_property_internal(const jack_port_t* jport, const URI& uri, const Atom& value) { -#ifdef HAVE_JACK_METADATA +#if USE_JACK_METADATA if (uri == _engine.world().uris().lv2_name) { jack_set_property(_client, jack_port_uuid(jport), JACK_METADATA_PRETTY_NAME, value.ptr<char>(), "text/plain"); @@ -398,7 +392,7 @@ JackDriver::post_process_port(RunContext& ctx, EnginePort* port) const auto* seq = graph_buf->get<LV2_Atom_Sequence>(); jack_midi_clear_buffer(jack_buf); - LV2_ATOM_SEQUENCE_FOREACH(seq, ev) { + LV2_ATOM_SEQUENCE_FOREACH (seq, ev) { const auto* buf = static_cast<const uint8_t*>(LV2_ATOM_BODY(&ev->body)); @@ -469,6 +463,12 @@ JackDriver::append_time_events(RunContext& ctx, Buffer& buffer) static_cast<const uint8_t*>(LV2_ATOM_BODY_CONST(lpos))); } +SampleCount +JackDriver::frame_time() const +{ + return _timer->frame_time(_engine.current_time()) + _engine.block_length(); +} + /**** Jack Callbacks ****/ /** Jack process callback, drives entire audio thread. @@ -491,6 +491,7 @@ JackDriver::_process_cb(jack_nframes_t nframes) _transport_state = jack_transport_query(_client, &_position); + _timer->update(_engine.current_time(), start_of_current_cycle - _engine.block_length()); _engine.locate(start_of_current_cycle, nframes); // Read input @@ -532,18 +533,22 @@ JackDriver::_shutdown_cb() int JackDriver::_block_length_cb(jack_nframes_t nframes) { + const URIs& uris = _engine.world().uris(); + if (_engine.root_graph()) { _block_length = nframes; - _seq_size = jack_port_type_get_buffer_size(_client, JACK_DEFAULT_MIDI_TYPE); + _seq_size = static_cast<uint32_t>( + jack_port_type_get_buffer_size(_client, JACK_DEFAULT_MIDI_TYPE)); _engine.root_graph()->set_buffer_size( - _engine.run_context(), *_engine.buffer_factory(), PortType::AUDIO, + _engine.run_context(), *_engine.buffer_factory(), + uris.atom_Sound, _engine.buffer_factory()->audio_buffer_size(nframes)); _engine.root_graph()->set_buffer_size( - _engine.run_context(), *_engine.buffer_factory(), PortType::ATOM, + _engine.run_context(), *_engine.buffer_factory(), + uris.atom_Sequence, _seq_size); } return 0; } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/JackDriver.hpp b/src/server/JackDriver.hpp index d4ea03d0..4c8e779e 100644 --- a/src/server/JackDriver.hpp +++ b/src/server/JackDriver.hpp @@ -18,47 +18,35 @@ #define INGEN_ENGINE_JACKAUDIODRIVER_HPP #include "Driver.hpp" -#include "EnginePort.hpp" // IWYU pragma: keep +#include "EnginePort.hpp" #include "types.hpp" -#include "ingen/URI.hpp" -#include "ingen/memory.hpp" // IWYU pragma: keep -#include "lv2/atom/forge.h" -#include "raul/Semaphore.hpp" +#include <ingen/URI.hpp> +#include <ingen/memory.hpp> +#include <lv2/atom/forge.h> +#include <raul/Semaphore.hpp> +#include <boost/intrusive/options.hpp> #include <boost/intrusive/slist.hpp> -#include <jack/jack.h> -#include <jack/thread.h> +#include <jack/transport.h> // IWYU pragma: keep #include <jack/types.h> +#include <jack/thread.h> + #include <atomic> -#include <cstddef> #include <cstdint> #include <exception> #include <memory> #include <string> -namespace raul { -class Path; -} // namespace raul - -namespace boost { -namespace intrusive { - -template <bool Enabled> struct cache_last; - -} // namespace intrusive -} // namespace boost - namespace ingen { class Atom; namespace server { -class Buffer; -class DuplexPort; class Engine; +class FrameTimer; class RunContext; /** The Jack Driver. @@ -96,8 +84,8 @@ public: /** Transport state for this frame. * Intended to only be called from the audio thread. */ - inline const jack_position_t* position() { return &_position; } - inline jack_transport_state_t transport_state() { return _transport_state; } + const jack_position_t* position() { return &_position; } + jack_transport_state_t transport_state() { return _transport_state; } void append_time_events(RunContext& ctx, Buffer& buffer) override; @@ -107,14 +95,13 @@ public: jack_client_t* jack_client() const { return _client; } SampleCount block_length() const override { return _block_length; } - size_t seq_size() const override { return _seq_size; } + uint32_t seq_size() const override { return _seq_size; } SampleCount sample_rate() const override { return _sample_rate; } - SampleCount frame_time() const override { - return _client ? jack_frame_time(_client) : 0; - } + SampleCount frame_time() const override; - class PortRegistrationFailedException : public std::exception {}; + class PortRegistrationFailedException : public std::exception + {}; private: friend class JackPort; @@ -122,16 +109,21 @@ private: static void thread_init_cb(void* jack_driver); // Static JACK callbacks which call the non-static callbacks (methods) - inline static void shutdown_cb(void* const jack_driver) { - return static_cast<JackDriver*>(jack_driver)->_shutdown_cb(); + + static void shutdown_cb(void* const jack_driver) { + static_cast<JackDriver*>(jack_driver)->_shutdown_cb(); } - inline static int process_cb(jack_nframes_t nframes, void* const jack_driver) { + + static int process_cb(jack_nframes_t nframes, void* const jack_driver) { return static_cast<JackDriver*>(jack_driver)->_process_cb(nframes); } - inline static int block_length_cb(jack_nframes_t nframes, void* const jack_driver) { + + static int block_length_cb(jack_nframes_t nframes, void* const jack_driver) { return static_cast<JackDriver*>(jack_driver)->_block_length_cb(nframes); } + // Internal methods for processing + void pre_process_port(RunContext& ctx, EnginePort* port); void post_process_port(RunContext& ctx, EnginePort* port) const; @@ -150,23 +142,24 @@ protected: using AudioBufPtr = std::unique_ptr<float, FreeDeleter<float>>; - Engine& _engine; - Ports _ports; - AudioBufPtr _fallback_buffer; - LV2_Atom_Forge _forge; - raul::Semaphore _sem; - std::atomic<bool> _flag; - jack_client_t* _client; - jack_nframes_t _block_length; - size_t _seq_size; - jack_nframes_t _sample_rate; - uint32_t _midi_event_type; - bool _is_activated; - jack_position_t _position; - jack_transport_state_t _transport_state; - double _old_bpm; - jack_nframes_t _old_frame; - bool _old_rolling; + Engine& _engine; + Ports _ports; + AudioBufPtr _fallback_buffer; + LV2_Atom_Forge _forge; + raul::Semaphore _sem{0}; + std::unique_ptr<FrameTimer> _timer; + std::atomic<bool> _flag{false}; + jack_client_t* _client{nullptr}; + jack_nframes_t _block_length{0}; + uint32_t _seq_size{0}; + jack_nframes_t _sample_rate{0}; + uint32_t _midi_event_type; + bool _is_activated{false}; + jack_position_t _position{}; + jack_transport_state_t _transport_state{}; + double _old_bpm{120.0}; + jack_nframes_t _old_frame{0}; + bool _old_rolling{false}; }; } // namespace server diff --git a/src/server/LV2Block.cpp b/src/server/LV2Block.cpp index 026b7d06..ad7b28ae 100644 --- a/src/server/LV2Block.cpp +++ b/src/server/LV2Block.cpp @@ -14,12 +14,13 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include "LV2Block.hpp" + #include "Buffer.hpp" #include "BufferFactory.hpp" #include "Engine.hpp" #include "GraphImpl.hpp" #include "InputPort.hpp" -#include "LV2Block.hpp" #include "LV2Plugin.hpp" #include "OutputPort.hpp" #include "PortImpl.hpp" @@ -27,24 +28,27 @@ #include "RunContext.hpp" #include "Worker.hpp" -#include "ingen/Atom.hpp" -#include "ingen/FilePath.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Log.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "lv2/core/lv2.h" -#include "lv2/options/options.h" -#include "lv2/state/state.h" -#include "lv2/urid/urid.h" -#include "lv2/worker/worker.h" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Atom.hpp> +#include <ingen/FilePath.hpp> +#include <ingen/Forge.hpp> +#include <ingen/LV2Features.hpp> +#include <ingen/Log.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <lilv/lilv.h> +#include <lv2/core/lv2.h> +#include <lv2/options/options.h> +#include <lv2/state/state.h> +#include <lv2/urid/urid.h> +#include <lv2/worker/worker.h> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <algorithm> #include <cassert> @@ -52,11 +56,11 @@ #include <cstdint> #include <map> #include <memory> +#include <optional> #include <string> #include <utility> -namespace ingen { -namespace server { +namespace ingen::server { /** Partially construct a LV2Block. * @@ -70,7 +74,6 @@ LV2Block::LV2Block(LV2Plugin* plugin, SampleRate srate) : BlockImpl(plugin, symbol, polyphonic, parent, srate) , _lv2_plugin(plugin) - , _worker_iface(nullptr) { assert(_lv2_plugin); } @@ -110,7 +113,7 @@ LV2Block::make_instance(URIs& uris, } for (uint32_t p = 0; p < num_ports(); ++p) { - PortImpl* const port = _ports->at(p); + const PortImpl* const port = _ports->at(p); Buffer* const buffer = (preparing) ? port->prepared_buffer(voice).get() : port->buffer(voice).get(); @@ -223,7 +226,7 @@ LV2Block::apply_poly(RunContext& ctx, uint32_t poly) /** Instantiate self from LV2 plugin descriptor. * - * Implemented as a seperate function (rather than in the constructor) to + * Implemented as a separate function (rather than in the constructor) to * allow graceful error-catching of broken plugins. * * Returns whether or not plugin was successfully instantiated. If return @@ -271,7 +274,7 @@ LV2Block::instantiate(BufferFactory& bufs, const LilvState* state) is_morph = true; LilvNodes* types = lilv_port_get_value( plug, id, uris.morph_supportsType); - LILV_FOREACH(nodes, i, types) { + LILV_FOREACH (nodes, i, types) { const LilvNode* type = lilv_nodes_get(types, i); if (lilv_node_equals(type, uris.lv2_CVPort)) { port_type = PortType::CV; @@ -302,7 +305,7 @@ LV2Block::instantiate(BufferFactory& bufs, const LilvState* state) if (!buffer_type) { LilvNodes* types = lilv_port_get_value( plug, id, uris.atom_bufferType); - LILV_FOREACH(nodes, i, types) { + LILV_FOREACH (nodes, i, types) { const LilvNode* type = lilv_nodes_get(types, i); if (lilv_node_is_uri(type)) { buffer_type = world.uri_map().map_uri( @@ -327,7 +330,7 @@ LV2Block::instantiate(BufferFactory& bufs, const LilvState* state) if (port_type == PortType::ATOM) { // Get default value, and its length LilvNodes* defaults = lilv_port_get_value(plug, id, uris.lv2_default); - LILV_FOREACH(nodes, i, defaults) { + LILV_FOREACH (nodes, i, defaults) { const LilvNode* d = lilv_nodes_get(defaults, i); if (lilv_node_is_string(d)) { const char* str_val = lilv_node_as_string(d); @@ -347,10 +350,10 @@ LV2Block::instantiate(BufferFactory& bufs, const LilvState* state) // Get minimum size, if set in data LilvNodes* sizes = lilv_port_get_value(plug, id, uris.rsz_minimumSize); - LILV_FOREACH(nodes, i, sizes) { + LILV_FOREACH (nodes, i, sizes) { const LilvNode* d = lilv_nodes_get(sizes, i); if (lilv_node_is_int(d)) { - uint32_t size_val = lilv_node_as_int(d); + const uint32_t size_val = lilv_node_as_int(d); port_buffer_size = std::max(port_buffer_size, size_val); } } @@ -415,7 +418,7 @@ LV2Block::instantiate(BufferFactory& bufs, const LilvState* state) nullptr }; for (int p = 0; preds[p]; ++p) { LilvNodes* values = lilv_port_get_value(plug, id, preds[p]); - LILV_FOREACH(nodes, v, values) { + LILV_FOREACH (nodes, v, values) { const LilvNode* value = lilv_nodes_get(values, v); if (lilv_node_is_uri(value)) { port->add_property(URI(lilv_node_as_uri(preds[p])), @@ -482,7 +485,7 @@ LV2Block::save_state(const FilePath& dir) const World& world = _lv2_plugin->world(); LilvWorld* lworld = world.lilv_world(); - StatePtr state{ + const StatePtr state{ lilv_state_new_from_instance(_lv2_plugin->lilv_plugin(), const_cast<LV2Block*>(this)->instance(0), &world.uri_map().urid_map(), @@ -497,7 +500,9 @@ LV2Block::save_state(const FilePath& dir) const if (!state) { return false; - } else if (lilv_state_get_num_properties(state.get()) == 0) { + } + + if (lilv_state_get_num_properties(state.get()) == 0) { return false; } @@ -520,7 +525,7 @@ LV2Block::duplicate(Engine& engine, const SampleRate rate = engine.sample_rate(); // Get current state - StatePtr state{ + const StatePtr state{ lilv_state_new_from_instance(_lv2_plugin->lilv_plugin(), instance(0), &engine.world().uri_map().urid_map(), @@ -588,10 +593,10 @@ LV2_Worker_Status LV2Block::work(uint32_t size, const void* data) { if (_worker_iface) { - std::lock_guard<std::mutex> lock(_work_mutex); + const std::lock_guard<std::mutex> lock{_work_mutex}; - LV2_Handle inst = lilv_instance_get_handle(instance(0)); - LV2_Worker_Status st = _worker_iface->work(inst, work_respond, this, size, data); + LV2_Handle inst = lilv_instance_get_handle(instance(0)); + const LV2_Worker_Status st = _worker_iface->work(inst, work_respond, this, size, data); if (st) { parent_graph()->engine().log().error( "Error calling %1% work method\n", _path); @@ -691,8 +696,8 @@ get_port_value(const char* port_symbol, uint32_t* size, uint32_t* type) { - auto* const block = static_cast<LV2Block*>(user_data); - auto* const port = block->port_by_symbol(port_symbol); + auto* const block = static_cast<LV2Block*>(user_data); + const auto* const port = block->port_by_symbol(port_symbol); if (port && port->is_input() && port->value().is_valid()) { *size = port->value().size(); @@ -703,7 +708,7 @@ get_port_value(const char* port_symbol, return nullptr; } -boost::optional<Resource> +std::optional<Resource> LV2Block::save_preset(const URI& uri, const Properties& props) { @@ -716,20 +721,20 @@ LV2Block::save_preset(const URI& uri, const FilePath dirname = path.parent_path(); const FilePath basename = path.stem(); - StatePtr state{lilv_state_new_from_instance(_lv2_plugin->lilv_plugin(), - instance(0), - lmap, - nullptr, - nullptr, - nullptr, - path.c_str(), - get_port_value, - this, - LV2_STATE_IS_NATIVE, - nullptr)}; + const StatePtr state{lilv_state_new_from_instance(_lv2_plugin->lilv_plugin(), + instance(0), + lmap, + nullptr, + nullptr, + nullptr, + path.c_str(), + get_port_value, + this, + LV2_STATE_IS_NATIVE, + nullptr)}; if (state) { - const Properties::const_iterator l = props.find(_uris.rdfs_label); + const auto l = props.find(_uris.rdfs_label); if (l != props.end() && l->second.type() == _uris.atom_String) { lilv_state_set_label(state.get(), l->second.ptr<char>()); } @@ -756,7 +761,7 @@ LV2Block::save_preset(const URI& uri, return {preset}; } - return boost::optional<Resource>(); + return {}; } void @@ -772,5 +777,4 @@ LV2Block::set_port_buffer(uint32_t voice, buf ? buf->port_data(_ports->at(port_num)->type(), offset) : nullptr); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/LV2Block.hpp b/src/server/LV2Block.hpp index c8f9e59a..78b5ffac 100644 --- a/src/server/LV2Block.hpp +++ b/src/server/LV2Block.hpp @@ -22,22 +22,21 @@ #include "State.hpp" #include "types.hpp" -#include "ingen/LV2Features.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URI.hpp" -#include "lilv/lilv.h" -#include "lv2/worker/worker.h" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" -#include "raul/Noncopyable.hpp" - +#include <ingen/LV2Features.hpp> +#include <lilv/lilv.h> +#include <lv2/worker/worker.h> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> +#include <raul/Noncopyable.hpp> + +#include <boost/intrusive/options.hpp> #include <boost/intrusive/slist.hpp> #include <boost/intrusive/slist_hook.hpp> -#include <boost/optional/optional.hpp> #include <cstdint> #include <cstdlib> #include <cstring> +#include <filesystem> #include <memory> #include <mutex> @@ -45,33 +44,16 @@ namespace raul { class Symbol; } // namespace raul -namespace boost { -namespace intrusive { - -template <bool Enabled> -struct cache_last; - -template <bool Enabled> -struct constant_time_size; - -} // namespace intrusive -} // namespace boost - namespace ingen { -class FilePath; -class Resource; class URIs; class World; namespace server { class BufferFactory; -class Engine; class GraphImpl; class LV2Plugin; -class RunContext; -class Worker; /** An instance of a LV2 plugin. * @@ -91,7 +73,7 @@ public: bool instantiate(BufferFactory& bufs, const LilvState* state); LilvInstance* instance() override { return instance(0); } - bool save_state(const FilePath& dir) const override; + bool save_state(const std::filesystem::path& dir) const override; BlockImpl* duplicate(Engine& engine, const raul::Symbol& symbol, @@ -113,19 +95,19 @@ public: void apply_state(const std::unique_ptr<Worker>& worker, const LilvState* state) override; - boost::optional<Resource> save_preset(const URI& uri, - const Properties& props) override; + std::optional<Resource> save_preset(const URI& uri, + const Properties& props) override; void set_port_buffer(uint32_t voice, uint32_t port_num, const BufferRef& buf, SampleCount offset) override; - static StatePtr load_state(World& world, const FilePath& path); + static StatePtr load_state(World& world, const std::filesystem::path& path); protected: struct Instance : public raul::Noncopyable { - explicit Instance(LilvInstance* i) : instance(i) {} + explicit Instance(LilvInstance* i) noexcept : instance(i) {} ~Instance() { lilv_instance_free(instance); } @@ -135,7 +117,7 @@ protected: std::shared_ptr<Instance> make_instance(URIs& uris, SampleRate rate, uint32_t voice, bool preparing); - inline LilvInstance* instance(uint32_t voice) { + LilvInstance* instance(uint32_t voice) { return static_cast<LilvInstance*>((*_instances)[voice]->instance); } @@ -151,9 +133,8 @@ protected: struct Response : public raul::Maid::Disposable , public raul::Noncopyable - , public boost::intrusive::slist_base_hook<> - { - inline Response(uint32_t s, const void* d) + , public boost::intrusive::slist_base_hook<> { + Response(uint32_t s, const void* d) : size(s) , data(malloc(s)) { @@ -179,7 +160,7 @@ protected: LV2Plugin* _lv2_plugin; raul::managed_ptr<Instances> _instances; raul::managed_ptr<Instances> _prepared_instances; - const LV2_Worker_Interface* _worker_iface; + const LV2_Worker_Interface* _worker_iface{nullptr}; std::mutex _work_mutex; Responses _responses; std::shared_ptr<LV2Features::FeatureArray> _features; diff --git a/src/server/LV2Options.hpp b/src/server/LV2Options.hpp index 2ae1c6d7..b1b57429 100644 --- a/src/server/LV2Options.hpp +++ b/src/server/LV2Options.hpp @@ -17,10 +17,10 @@ #ifndef INGEN_ENGINE_LV2OPTIONS_HPP #define INGEN_ENGINE_LV2OPTIONS_HPP -#include "ingen/LV2Features.hpp" -#include "ingen/URIs.hpp" -#include "lv2/core/lv2.h" -#include "lv2/options/options.h" +#include <ingen/LV2Features.hpp> +#include <ingen/URIs.hpp> +#include <lv2/core/lv2.h> +#include <lv2/options/options.h> #include <cstdint> #include <cstdlib> @@ -34,7 +34,8 @@ class World; namespace server { -class LV2Options : public ingen::LV2Features::Feature { +class LV2Options : public ingen::LV2Features::Feature +{ public: explicit LV2Options(const URIs& uris) : _uris(uris) @@ -65,7 +66,7 @@ public: f->URI = LV2_OPTIONS__options; f->data = malloc(sizeof(options)); memcpy(f->data, options, sizeof(options)); - return std::shared_ptr<LV2_Feature>(f, &free_feature); + return {f, &free_feature}; } private: diff --git a/src/server/LV2Plugin.cpp b/src/server/LV2Plugin.cpp index 7a43ba67..87072ab0 100644 --- a/src/server/LV2Plugin.cpp +++ b/src/server/LV2Plugin.cpp @@ -19,16 +19,18 @@ #include "Engine.hpp" #include "LV2Block.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Log.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" +#include <ingen/Forge.hpp> +#include <ingen/Log.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <lilv/lilv.h> +#include <raul/Symbol.hpp> #include <cstdlib> #include <string> -namespace ingen { -namespace server { +namespace ingen::server { LV2Plugin::LV2Plugin(World& world, const LilvPlugin* lplugin) : PluginImpl(world.uris(), @@ -70,18 +72,18 @@ LV2Plugin::symbol() const { std::string working = uri(); if (working.back() == '/') { - working = working.substr(0, working.length() - 1); + working.resize(working.length() - 1); } - while (working.length() > 0) { - size_t last_slash = working.find_last_of('/'); + while (!working.empty()) { + const size_t last_slash = working.find_last_of('/'); const std::string symbol = working.substr(last_slash+1); if ( (symbol[0] >= 'a' && symbol[0] <= 'z') || (symbol[0] >= 'A' && symbol[0] <= 'Z') ) { return raul::Symbol::symbolify(symbol); - } else { - working = working.substr(0, last_slash); } + + working.resize(last_slash); } return raul::Symbol("lv2_symbol"); @@ -101,9 +103,9 @@ LV2Plugin::instantiate(BufferFactory& bufs, if (!b->instantiate(bufs, state)) { delete b; return nullptr; - } else { - return b; } + + return b; } void @@ -114,7 +116,7 @@ LV2Plugin::load_presets() LilvNodes* presets = lilv_plugin_get_related(_lilv_plugin, uris.pset_Preset); if (presets) { - LILV_FOREACH(nodes, i, presets) { + LILV_FOREACH (nodes, i, presets) { const LilvNode* preset = lilv_nodes_get(presets, i); lilv_world_load_resource(lworld, preset); @@ -140,5 +142,4 @@ LV2Plugin::load_presets() PluginImpl::load_presets(); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/LV2Plugin.hpp b/src/server/LV2Plugin.hpp index fa007327..c94e88f7 100644 --- a/src/server/LV2Plugin.hpp +++ b/src/server/LV2Plugin.hpp @@ -19,9 +19,8 @@ #include "PluginImpl.hpp" -#include "ingen/URI.hpp" -#include "lilv/lilv.h" -#include "raul/Symbol.hpp" +#include <ingen/URI.hpp> +#include <lilv/lilv.h> namespace ingen { @@ -29,11 +28,6 @@ class World; namespace server { -class BlockImpl; -class BufferFactory; -class Engine; -class GraphImpl; - /** Implementation of an LV2 plugin (loaded shared library). */ class LV2Plugin : public PluginImpl diff --git a/src/server/LV2ResizeFeature.hpp b/src/server/LV2ResizeFeature.hpp index ddad2ea7..66720e0d 100644 --- a/src/server/LV2ResizeFeature.hpp +++ b/src/server/LV2ResizeFeature.hpp @@ -21,13 +21,12 @@ #include "Buffer.hpp" #include "PortImpl.hpp" -#include "ingen/LV2Features.hpp" -#include "lv2/resize-port/resize-port.h" +#include <ingen/LV2Features.hpp> +#include <lv2/resize-port/resize-port.h> #include <memory> -namespace ingen { -namespace server { +namespace ingen::server { struct ResizeFeature : public ingen::LV2Features::Feature { static LV2_Resize_Port_Status resize_port( @@ -62,7 +61,6 @@ struct ResizeFeature : public ingen::LV2Features::Feature { } }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_LV2RESIZEFEATURE_HPP diff --git a/src/server/Load.hpp b/src/server/Load.hpp index f69d0659..a5216f7e 100644 --- a/src/server/Load.hpp +++ b/src/server/Load.hpp @@ -21,11 +21,9 @@ #include <cstdint> #include <limits> -namespace ingen { -namespace server { +namespace ingen::server { -struct Load -{ +struct Load { void update(uint64_t time, uint64_t available) { const uint64_t load = time * 100 / available; if (load < min) { @@ -40,8 +38,8 @@ struct Load mean = load; changed = true; } else { - const float a = mean + (static_cast<float>(load) - mean) / - static_cast<float>(++n); + const float a = mean + ((static_cast<float>(load) - mean) / + static_cast<float>(++n)); if (a != mean) { changed = floorf(a) != floorf(mean); @@ -57,7 +55,6 @@ struct Load bool changed = false; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_LOAD_HPP diff --git a/src/server/NodeImpl.cpp b/src/server/NodeImpl.cpp index d914ae1c..e820a44e 100644 --- a/src/server/NodeImpl.cpp +++ b/src/server/NodeImpl.cpp @@ -20,15 +20,15 @@ #include "GraphImpl.hpp" #include "ThreadManager.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Properties.hpp" -#include "raul/Path.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Node.hpp> +#include <ingen/Properties.hpp> +#include <raul/Path.hpp> #include <map> #include <utility> -namespace ingen { -namespace server { +namespace ingen::server { NodeImpl::NodeImpl(const ingen::URIs& uris, NodeImpl* parent, @@ -37,8 +37,7 @@ NodeImpl::NodeImpl(const ingen::URIs& uris, , _parent(parent) , _path(parent ? parent->path().child(symbol) : raul::Path("/")) , _symbol(symbol) -{ -} +{} const Atom& NodeImpl::get_property(const URI& key) const @@ -55,5 +54,4 @@ NodeImpl::parent_graph() const return dynamic_cast<GraphImpl*>(reinterpret_cast<BlockImpl*>(_parent)); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/NodeImpl.hpp b/src/server/NodeImpl.hpp index 8acce161..fcf2f57f 100644 --- a/src/server/NodeImpl.hpp +++ b/src/server/NodeImpl.hpp @@ -17,17 +17,15 @@ #ifndef INGEN_ENGINE_NODEIMPL_HPP #define INGEN_ENGINE_NODEIMPL_HPP -#include "ingen/Node.hpp" -#include "ingen/URI.hpp" -#include "ingen/paths.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Node.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <cstdint> namespace ingen { -class Atom; class URIs; namespace server { diff --git a/src/server/OutputPort.hpp b/src/server/OutputPort.hpp index 61fb44f5..b19cd361 100644 --- a/src/server/OutputPort.hpp +++ b/src/server/OutputPort.hpp @@ -20,7 +20,7 @@ #include "PortImpl.hpp" #include "PortType.hpp" -#include "lv2/urid/urid.h" +#include <lv2/urid/urid.h> #include <cstddef> #include <cstdint> diff --git a/src/server/PluginImpl.hpp b/src/server/PluginImpl.hpp index 3d7d596f..8e3642c0 100644 --- a/src/server/PluginImpl.hpp +++ b/src/server/PluginImpl.hpp @@ -17,11 +17,11 @@ #ifndef INGEN_ENGINE_PLUGINIMPL_HPP #define INGEN_ENGINE_PLUGINIMPL_HPP -#include "ingen/Atom.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URI.hpp" -#include "lilv/lilv.h" -#include "raul/Symbol.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <lilv/lilv.h> +#include <raul/Symbol.hpp> #include <map> #include <string> @@ -48,10 +48,7 @@ public: PluginImpl(ingen::URIs& uris, const Atom& type, const URI& uri) : Resource(uris, uri) , _type(type) - , _presets_loaded(false) - , _is_zombie(false) - { - } + {} PluginImpl(const PluginImpl&) = delete; PluginImpl& operator=(const PluginImpl&) = delete; @@ -90,8 +87,8 @@ public: protected: Atom _type; Presets _presets; - bool _presets_loaded; - bool _is_zombie; + bool _presets_loaded{false}; + bool _is_zombie{false}; }; } // namespace server diff --git a/src/server/PortAudioDriver.cpp b/src/server/PortAudioDriver.cpp index fcb9cf67..ef893478 100644 --- a/src/server/PortAudioDriver.cpp +++ b/src/server/PortAudioDriver.cpp @@ -14,17 +14,19 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include "PortAudioDriver.hpp" + #include "DuplexPort.hpp" #include "Engine.hpp" #include "FrameTimer.hpp" -#include "PortAudioDriver.hpp" #include "PortType.hpp" #include "RunContext.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "raul/Path.hpp" + +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <raul/Path.hpp> #include <portaudio.h> @@ -32,8 +34,7 @@ #include <cstring> #include <string> -namespace ingen { -namespace server { +namespace ingen::server { static bool pa_error(const char* msg, PaError err) @@ -47,17 +48,8 @@ PortAudioDriver::PortAudioDriver(Engine& engine) : _engine(engine) , _inputParameters() , _outputParameters() - , _sem(0) - , _stream(nullptr) - , _seq_size(4096) , _block_length(engine.world().conf().option("buffer-size").get<int32_t>()) - , _sample_rate(48000) - , _n_inputs(0) - , _n_outputs(0) - , _flag(false) - , _is_activated(false) -{ -} +{} PortAudioDriver::~PortAudioDriver() { @@ -78,7 +70,9 @@ PortAudioDriver::attach() _outputParameters.device = Pa_GetDefaultOutputDevice(); if (_inputParameters.device == paNoDevice) { return pa_error("No default input device", paDeviceUnavailable); - } else if (_outputParameters.device == paNoDevice) { + } + + if (_outputParameters.device == paNoDevice) { return pa_error("No default output device", paDeviceUnavailable); } @@ -91,8 +85,7 @@ PortAudioDriver::attach() _sample_rate = in_dev->defaultSampleRate; - _timer = std::unique_ptr<FrameTimer>( - new FrameTimer(_block_length, _sample_rate)); + _timer = std::make_unique<FrameTimer>(_block_length, _sample_rate); return true; } @@ -184,26 +177,22 @@ PortAudioDriver::remove_port(RunContext&, EnginePort* port) void PortAudioDriver::register_port(EnginePort& port) -{ -} +{} void PortAudioDriver::unregister_port(EnginePort& port) -{ -} +{} void PortAudioDriver::rename_port(const raul::Path& old_path, const raul::Path& new_path) -{ -} +{} void PortAudioDriver::port_property(const raul::Path& path, const URI& uri, const Atom& value) -{ -} +{} EnginePort* PortAudioDriver::create_port(DuplexPort* graph_port) @@ -265,8 +254,7 @@ PortAudioDriver::post_process_port(RunContext&, EnginePort* port, const void* inputs, void* outputs) -{ -} +{} int PortAudioDriver::process_cb(const void* inputs, @@ -294,5 +282,4 @@ PortAudioDriver::process_cb(const void* inputs, return 0; } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/PortAudioDriver.hpp b/src/server/PortAudioDriver.hpp index 5f2bf7a1..6c7bfb9e 100644 --- a/src/server/PortAudioDriver.hpp +++ b/src/server/PortAudioDriver.hpp @@ -18,39 +18,21 @@ #define INGEN_ENGINE_PORTAUDIODRIVER_HPP #include "Driver.hpp" -#include "EnginePort.hpp" // IWYU pragma: keep +#include "EnginePort.hpp" #include "types.hpp" -#include "ingen/URI.hpp" -#include "raul/Semaphore.hpp" +#include <raul/Semaphore.hpp> +#include <boost/intrusive/options.hpp> #include <boost/intrusive/slist.hpp> #include <portaudio.h> #include <atomic> -#include <cstddef> #include <cstdint> #include <memory> -namespace raul { class Path; } +namespace ingen::server { -namespace boost { -namespace intrusive { - -template <bool Enabled> -struct cache_last; - -} // namespace intrusive -} // namespace boost - -namespace ingen { - -class Atom; - -namespace server { - -class Buffer; -class DuplexPort; class Engine; class FrameTimer; class RunContext; @@ -83,21 +65,21 @@ public: int real_time_priority() override { return 80; } SampleCount block_length() const override { return _block_length; } - size_t seq_size() const override { return _seq_size; } + uint32_t seq_size() const override { return _seq_size; } SampleCount sample_rate() const override { return _sample_rate; } private: friend class PortAudioPort; - inline static int - pa_process_cb(const void* inputs, - void* outputs, - unsigned long nframes, - const PaStreamCallbackTimeInfo* time, - PaStreamCallbackFlags flags, - void* handle) { + static int pa_process_cb(const void* inputs, + void* outputs, + unsigned long nframes, + const PaStreamCallbackTimeInfo* time, + PaStreamCallbackFlags flags, + void* handle) + { return static_cast<PortAudioDriver*>(handle)->process_cb( - inputs, outputs, nframes, time, flags); + inputs, outputs, nframes, time, flags); } int process_cb(const void* inputs, @@ -124,19 +106,18 @@ protected: Ports _ports; PaStreamParameters _inputParameters; PaStreamParameters _outputParameters; - raul::Semaphore _sem; + raul::Semaphore _sem{0U}; std::unique_ptr<FrameTimer> _timer; - PaStream* _stream; - size_t _seq_size; + PaStream* _stream{nullptr}; + uint32_t _seq_size{4096U}; uint32_t _block_length; - uint32_t _sample_rate; - uint32_t _n_inputs; - uint32_t _n_outputs; - std::atomic<bool> _flag; - bool _is_activated; + uint32_t _sample_rate{48000U}; + uint32_t _n_inputs{0U}; + uint32_t _n_outputs{0U}; + std::atomic<bool> _flag{false}; + bool _is_activated{false}; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_PORTAUDIODRIVER_HPP diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp index 68392707..f6eed11f 100644 --- a/src/server/PortImpl.cpp +++ b/src/server/PortImpl.cpp @@ -23,15 +23,17 @@ #include "PortType.hpp" #include "ThreadManager.hpp" -#include "ingen/Forge.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "lv2/atom/atom.h" -#include "lv2/atom/util.h" -#include "lv2/urid/urid.h" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Node.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <lv2/atom/atom.h> +#include <lv2/atom/util.h> +#include <lv2/urid/urid.h> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> +#include <raul/Path.hpp> #include <algorithm> #include <cassert> @@ -39,10 +41,9 @@ #include <memory> #include <utility> -namespace ingen { -namespace server { +namespace ingen::server { -static const uint32_t monitor_rate = 25.0; // Hz +static const uint32_t monitor_rate = 25.0; // Hz /** The length of time between monitor updates in frames */ static inline uint32_t @@ -67,24 +68,12 @@ PortImpl::PortImpl(BufferFactory& bufs, , _index(index) , _poly(poly) , _buffer_size(buffer_size) - , _frames_since_monitor(0) - , _monitor_value(0.0f) - , _peak(0.0f) , _type(type) , _buffer_type(buffer_type) , _value(value) , _min(bufs.forge().make(0.0f)) , _max(bufs.forge().make(1.0f)) , _voices(bufs.maid().make_managed<Voices>(poly)) - , _connected_flag(false) - , _monitored(false) - , _force_monitor_update(false) - , _is_morph(false) - , _is_auto_morph(false) - , _is_logarithmic(false) - , _is_sample_rate(false) - , _is_toggled(false) - , _is_driver_port(false) , _is_output(is_output) { assert(block != nullptr); @@ -148,13 +137,13 @@ PortImpl::set_type(PortType port_type, LV2_URID buffer_type) remove_property(uris.rdf_type, uris.lv2_CVPort); remove_property(uris.rdf_type, uris.lv2_ControlPort); remove_property(uris.rdf_type, uris.atom_AtomPort); - add_property(uris.rdf_type, world.forge().make_urid(port_type.uri())); + add_property(uris.rdf_type, world.forge().make_urid(port_type_uri(port_type))); // Update audio thread types _type = port_type; _buffer_type = buffer_type; if (!_buffer_type) { - switch (_type.id()) { + switch (_type) { case PortType::CONTROL: _buffer_type = uris.atom_Float; break; @@ -250,7 +239,7 @@ PortImpl::set_voice_value(const RunContext& ctx, FrameTime time, Sample value) { - switch (_type.id()) { + switch (_type) { case PortType::CONTROL: if (buffer(voice)->value()) { const_cast<LV2_Atom_Float*>( @@ -302,9 +291,9 @@ PortImpl::set_voice_value(const RunContext& ctx, void PortImpl::update_set_state(const RunContext& ctx, uint32_t v) { - Voice& voice = _voices->at(v); - SetState& state = voice.set_state; - BufferRef buf = voice.buffer; + Voice& voice = _voices->at(v); + SetState& state = voice.set_state; + const BufferRef buf = voice.buffer; switch (state.state) { case SetState::State::SET: break; @@ -342,9 +331,13 @@ PortImpl::prepare_poly(BufferFactory& bufs, uint32_t poly) if (_is_driver_port || _parent->is_main() || (_type == PortType::ATOM && !_value.is_valid())) { return false; - } else if (_poly == poly) { + } + + if (_poly == poly) { return true; - } else if (_prepared_voices && _prepared_voices->size() != poly) { + } + + if (_prepared_voices && _prepared_voices->size() != poly) { _prepared_voices.reset(); } @@ -365,7 +358,9 @@ PortImpl::apply_poly(RunContext& ctx, uint32_t poly) if (_parent->is_main() || (_type == PortType::ATOM && !_value.is_valid())) { return false; - } else if (!_prepared_voices) { + } + + if (!_prepared_voices) { return true; } @@ -426,7 +421,7 @@ PortImpl::set_is_driver_port(BufferFactory&) void PortImpl::clear_buffers(const RunContext& ctx) { - switch (_type.id()) { + switch (_type) { case PortType::AUDIO: default: for (uint32_t v = 0; v < _poly; ++v) { @@ -459,17 +454,17 @@ PortImpl::monitor(RunContext& ctx, bool send_now) _frames_since_monitor += ctx.nframes(); const bool time_to_send = send_now || _frames_since_monitor >= period; - const bool is_sequence = (_type.id() == PortType::ATOM && + const bool is_sequence = (_type == PortType::ATOM && _buffer_type == _bufs.uris().atom_Sequence); if (!time_to_send && !(is_sequence && _monitored) && (!is_sequence && buffer(0)->value())) { return; } - Forge& forge = ctx.engine().world().forge(); - URIs& uris = ctx.engine().world().uris(); - LV2_URID key = 0; - float val = 0.0f; - switch (_type.id()) { + const Forge& forge = ctx.engine().world().forge(); + const URIs& uris = ctx.engine().world().uris(); + LV2_URID key = 0; + float val = 0.0f; + switch (_type) { case PortType::UNKNOWN: break; case PortType::AUDIO: @@ -491,7 +486,7 @@ PortImpl::monitor(RunContext& ctx, bool send_now) } else if (_monitored) { /* Sequence explicitly monitored, send everything. */ const auto* seq = reinterpret_cast<const LV2_Atom_Sequence*>(atom); - LV2_ATOM_SEQUENCE_FOREACH(seq, ev) { + LV2_ATOM_SEQUENCE_FOREACH (seq, ev) { ctx.notify(uris.ingen_activity, ctx.start() + ev->time.frames, this, @@ -542,9 +537,7 @@ PortImpl::next_value_offset(SampleCount offset, SampleCount end) const SampleCount earliest = end; for (uint32_t v = 0; v < _poly; ++v) { const SampleCount o = _voices->at(v).buffer->next_value_offset(offset, end); - if (o < earliest) { - earliest = o; - } + earliest = std::min(o, earliest); } return earliest; } @@ -570,8 +563,7 @@ PortImpl::pre_process(RunContext& ctx) void PortImpl::pre_run(RunContext&) -{ -} +{} void PortImpl::post_process(RunContext& ctx) @@ -584,5 +576,4 @@ PortImpl::post_process(RunContext& ctx) monitor(ctx); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/PortImpl.hpp b/src/server/PortImpl.hpp index d79bb6cd..c202d4a0 100644 --- a/src/server/PortImpl.hpp +++ b/src/server/PortImpl.hpp @@ -20,17 +20,15 @@ #include "BufferFactory.hpp" #include "BufferRef.hpp" #include "NodeImpl.hpp" -#include "PortType.hpp" #include "RunContext.hpp" +#include "server.h" #include "types.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Node.hpp" -#include "ingen/URIs.hpp" -#include "ingen/ingen.h" -#include "lv2/urid/urid.h" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" +#include <ingen/Atom.hpp> +#include <ingen/URIs.hpp> +#include <lv2/urid/urid.h> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> #include <atomic> #include <cstdint> @@ -43,6 +41,8 @@ class Symbol; namespace ingen { +enum class PortType; + class Properties; namespace server { @@ -57,7 +57,7 @@ class BlockImpl; * * \ingroup engine */ -class INGEN_API PortImpl : public NodeImpl +class INGEN_SERVER_API PortImpl : public NodeImpl { public: struct SetState { @@ -91,10 +91,8 @@ public: }; struct Voice { - Voice() : buffer(nullptr) {} - SetState set_state; - BufferRef buffer; + BufferRef buffer{nullptr}; }; using Voices = raul::Array<Voice>; @@ -147,10 +145,11 @@ public: void set_minimum(const Atom& min) { _min.set_rt(min); } void set_maximum(const Atom& max) { _max.set_rt(max); } - inline BufferRef buffer(uint32_t voice) const { + BufferRef buffer(uint32_t voice) const { return _voices->at((_poly == 1) ? 0 : voice).buffer; } - inline BufferRef prepared_buffer(uint32_t voice) const { + + BufferRef prepared_buffer(uint32_t voice) const { return _prepared_voices->at(voice).buffer; } @@ -207,7 +206,7 @@ public: uint32_t index() const { return _index; } void set_index(RunContext&, uint32_t index) { _index = index; } - inline bool is_a(PortType type) const { return _type == type; } + bool is_a(PortType type) const { return _type == type; } bool has_value() const; @@ -299,9 +298,9 @@ protected: uint32_t _index; uint32_t _poly; uint32_t _buffer_size; - uint32_t _frames_since_monitor; - float _monitor_value; - float _peak; + uint32_t _frames_since_monitor{0}; + float _monitor_value{0.0f}; + float _peak{0.0f}; PortType _type; LV2_URID _buffer_type; Atom _value; @@ -310,15 +309,15 @@ protected: raul::managed_ptr<Voices> _voices; raul::managed_ptr<Voices> _prepared_voices; BufferRef _user_buffer; - std::atomic_flag _connected_flag; - bool _monitored; - bool _force_monitor_update; - bool _is_morph; - bool _is_auto_morph; - bool _is_logarithmic; - bool _is_sample_rate; - bool _is_toggled; - bool _is_driver_port; + std::atomic_flag _connected_flag{false}; + bool _monitored{false}; + bool _force_monitor_update{false}; + bool _is_morph{false}; + bool _is_auto_morph{false}; + bool _is_logarithmic{false}; + bool _is_sample_rate{false}; + bool _is_toggled{false}; + bool _is_driver_port{false}; bool _is_output; }; diff --git a/src/server/PortType.hpp b/src/server/PortType.hpp index f84c271f..294c056a 100644 --- a/src/server/PortType.hpp +++ b/src/server/PortType.hpp @@ -14,80 +14,60 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef INGEN_INTERFACE_PORTTYPE_HPP -#define INGEN_INTERFACE_PORTTYPE_HPP +#ifndef INGEN_ENGINE_PORTTYPE_HPP +#define INGEN_ENGINE_PORTTYPE_HPP -#include "ingen/URI.hpp" - -#include "lv2/atom/atom.h" -#include "lv2/core/lv2.h" - -#include <cassert> +#include <ingen/URI.hpp> +#include <lv2/atom/atom.h> +#include <lv2/core/lv2.h> namespace ingen { -/** The type of a port. - * - * This type refers to the type of the port itself (not necessarily the type - * of its contents). Ports with different types can contain the same type of - * data, but may e.g. have different access semantics. - */ -class PortType { -public: - enum ID { - UNKNOWN = 0, - AUDIO = 1, - CONTROL = 2, - CV = 3, - ATOM = 4 - }; - - explicit PortType(const URI& uri) - : _id(UNKNOWN) - { - if (uri == type_uri(AUDIO)) { - _id = AUDIO; - } else if (uri == type_uri(CONTROL)) { - _id = CONTROL; - } else if (uri == type_uri(CV)) { - _id = CV; - } else if (uri == type_uri(ATOM)) { - _id = ATOM; - } - } - - PortType(ID id) : _id(id) {} - - inline const URI& uri() const { return type_uri(_id); } - inline ID id() const { return _id; } - - inline bool operator==(const ID& id) const { return (_id == id); } - inline bool operator!=(const ID& id) const { return (_id != id); } - inline bool operator==(const PortType& type) const { return (_id == type._id); } - inline bool operator!=(const PortType& type) const { return (_id != type._id); } - inline bool operator<(const PortType& type) const { return (_id < type._id); } - - inline bool is_audio() { return _id == AUDIO; } - inline bool is_control() { return _id == CONTROL; } - inline bool is_cv() { return _id == CV; } - inline bool is_atom() { return _id == ATOM; } +/// The type of a port +enum class PortType { + UNKNOWN, + AUDIO, + CONTROL, + CV, + ATOM, +}; -private: - static inline const URI& type_uri(unsigned id_num) { - assert(id_num <= ATOM); - static const URI uris[] = { - URI("http://www.w3.org/2002/07/owl#Nothing"), - URI(LV2_CORE__AudioPort), - URI(LV2_CORE__ControlPort), - URI(LV2_CORE__CVPort), - URI(LV2_ATOM__AtomPort) - }; - return uris[id_num]; +/// Return the URI for `port_type` +inline URI +port_type_uri(const PortType port_type) +{ + switch (port_type) { + case PortType::UNKNOWN: + break; + case PortType::AUDIO: + return URI{LV2_CORE__AudioPort}; + case PortType::CONTROL: + return URI{LV2_CORE__ControlPort}; + case PortType::CV: + return URI{LV2_CORE__CVPort}; + case PortType::ATOM: + return URI{LV2_ATOM__AtomPort}; } - ID _id; -}; + return URI{"http://www.w3.org/2002/07/owl#Nothing"}; +} + +/// Return the type with the given `uri`, or #PortType::UNKNOWN +inline PortType +port_type_from_uri(const URI& uri) +{ + static const URI lv2_AudioPort = URI{LV2_CORE__AudioPort}; + static const URI lv2_ControlPort = URI{LV2_CORE__ControlPort}; + static const URI lv2_CVPort = URI{LV2_CORE__CVPort}; + static const URI atom_AtomPort = URI{LV2_ATOM__AtomPort}; + + return (uri == lv2_AudioPort) ? PortType::AUDIO + : (uri == lv2_ControlPort) ? PortType::CONTROL + : (uri == lv2_CVPort) ? PortType::CV + : (uri == atom_AtomPort) ? PortType::ATOM + : PortType::UNKNOWN; +} } // namespace ingen -#endif // INGEN_INTERFACE_PORTTYPE_HPP +#endif // INGEN_ENGINE_PORTTYPE_HPP diff --git a/src/server/PostProcessor.cpp b/src/server/PostProcessor.cpp index 5a0a8f3e..4c071ecd 100644 --- a/src/server/PostProcessor.cpp +++ b/src/server/PostProcessor.cpp @@ -21,14 +21,12 @@ #include <cassert> -namespace ingen { -namespace server { +namespace ingen::server { -class PreProcessContext; - -class Sentinel : public Event { +class Sentinel : public Event +{ public: - explicit Sentinel(Engine& engine) : Event(engine) {} + explicit Sentinel(Engine& engine) noexcept : Event(engine) {} bool pre_process(PreProcessContext&) override { return false; } void execute(RunContext&) override {} @@ -40,8 +38,7 @@ PostProcessor::PostProcessor(Engine& engine) , _head(new Sentinel(engine)) , _tail(_head.load()) , _max_time(0) -{ -} +{} PostProcessor::~PostProcessor() { @@ -99,7 +96,7 @@ PostProcessor::process() // Post-process event ev->post_process(); - next = ev->next(); // [1] (see below) + next = ev->next(); // [1] (see below) } while (next && next->time() < end_time); /* Reached the tail (as far as we're concerned). There may be successors @@ -112,5 +109,4 @@ PostProcessor::process() _engine.emit_notifications(end_time); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/PostProcessor.hpp b/src/server/PostProcessor.hpp index ab8ba6bc..7b2a3035 100644 --- a/src/server/PostProcessor.hpp +++ b/src/server/PostProcessor.hpp @@ -17,14 +17,12 @@ #ifndef INGEN_ENGINE_POSTPROCESSOR_HPP #define INGEN_ENGINE_POSTPROCESSOR_HPP +#include "server.h" #include "types.hpp" -#include "ingen/ingen.h" - #include <atomic> -namespace ingen { -namespace server { +namespace ingen::server { class Engine; class Event; @@ -41,7 +39,7 @@ class RunContext; * * \ingroup engine */ -class INGEN_API PostProcessor +class INGEN_SERVER_API PostProcessor { public: explicit PostProcessor(Engine& engine); @@ -68,7 +66,6 @@ private: std::atomic<FrameTime> _max_time; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_POSTPROCESSOR_HPP diff --git a/src/server/PreProcessContext.hpp b/src/server/PreProcessContext.hpp index fa7d07c5..7c97af3c 100644 --- a/src/server/PreProcessContext.hpp +++ b/src/server/PreProcessContext.hpp @@ -20,12 +20,10 @@ #include "CompiledGraph.hpp" #include "GraphImpl.hpp" -#include "raul/Maid.hpp" - +#include <memory> #include <unordered_set> -namespace ingen { -namespace server { +namespace ingen::server { /** Event pre-processing context. * @@ -50,12 +48,14 @@ public: bool must_compile(GraphImpl& graph) { if (!graph.enabled()) { return false; - } else if (_in_bundle) { + } + + if (_in_bundle) { _dirty_graphs.insert(&graph); return false; - } else { - return true; } + + return true; } /** Compile graph and return the result if necessary. @@ -63,13 +63,9 @@ public: * This may return null when an atomic bundle is deferring compilation, in * which case the graph is flagged as dirty for later compilation. */ - raul::Maid::managed_ptr<CompiledGraph> - maybe_compile(raul::Maid& maid, GraphImpl& graph) + [[nodiscard]] std::unique_ptr<CompiledGraph> maybe_compile(GraphImpl& graph) { - if (must_compile(graph)) { - return compile(maid, graph); - } - return nullptr; + return must_compile(graph) ? compile(graph) : nullptr; } /** Return all graphs that require compilation after an atomic bundle. */ @@ -81,7 +77,6 @@ private: bool _in_bundle = false; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_PREPROCESSCONTEXT_HPP diff --git a/src/server/PreProcessor.cpp b/src/server/PreProcessor.cpp index b2f0fd46..b3bad0b2 100644 --- a/src/server/PreProcessor.cpp +++ b/src/server/PreProcessor.cpp @@ -24,26 +24,22 @@ #include "ThreadManager.hpp" #include "UndoStack.hpp" -#include "ingen/Atom.hpp" -#include "ingen/AtomWriter.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/World.hpp" +#include <ingen/Atom.hpp> +#include <ingen/AtomWriter.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/World.hpp> +#include <raul/Semaphore.hpp> #include <cassert> #include <cstdint> #include <cstdio> #include <memory> +#include <string> -namespace ingen { -namespace server { +namespace ingen::server { PreProcessor::PreProcessor(Engine& engine) : _engine(engine) - , _sem(0) - , _head(nullptr) - , _tail(nullptr) - , _block_state(BlockState::UNBLOCKED) - , _exit_flag(false) , _thread(&PreProcessor::run, this) {} @@ -61,7 +57,7 @@ PreProcessor::event(Event* const ev, Event::Mode mode) { // TODO: Probably possible to make this lock-free with CAS ThreadManager::assert_not_thread(THREAD_IS_REAL_TIME); - std::lock_guard<std::mutex> lock(_mutex); + const std::lock_guard<std::mutex> lock{_mutex}; assert(!ev->is_prepared()); assert(!ev->next()); @@ -69,7 +65,7 @@ PreProcessor::event(Event* const ev, Event::Mode mode) /* Note that tail is only used here, not in process(). The head must be checked first here, since if it is null the tail pointer is junk. */ - Event* const head = _head.load(); + const Event* const head = _head.load(); if (!head) { _head = ev; _tail = ev; @@ -114,12 +110,14 @@ PreProcessor::process(RunContext& ctx, PostProcessor& dest, size_t limit) } if (_block_state == BlockState::BLOCKED) { - break; // Waiting for PRE_UNBLOCKED - } else if (ev->time() < ctx.start()) { - ev->set_time(ctx.start()); // Too late, nudge to context start + break; // Waiting for PRE_UNBLOCKED + } + + if (ev->time() < ctx.start()) { + ev->set_time(ctx.start()); // Too late, nudge to context start } else if (_block_state != BlockState::PROCESSING && ev->time() >= ctx.end()) { - break; // Event is for a future cycle + break; // Event is for a future cycle } // Execute event @@ -144,7 +142,7 @@ PreProcessor::process(RunContext& ctx, PostProcessor& dest, size_t limit) if (n_processed > 0) { #ifndef NDEBUG - Engine& engine = ctx.engine(); + const Engine& engine = ctx.engine(); if (engine.world().conf().option("trace").get<int32_t>()) { const uint64_t start = engine.cycle_start_time(ctx); const uint64_t end = engine.current_time(); @@ -153,7 +151,7 @@ PreProcessor::process(RunContext& ctx, PostProcessor& dest, size_t limit) } #endif - auto* next = static_cast<Event*>(last->next()); + auto* next = last->next(); last->next(nullptr); dest.append(ctx, head, last); @@ -245,9 +243,8 @@ PreProcessor::run() wait_for_block_state(BlockState::UNBLOCKED); } - back = static_cast<Event*>(ev->next()); + back = ev->next(); } } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/PreProcessor.hpp b/src/server/PreProcessor.hpp index 05027638..03ba5dd7 100644 --- a/src/server/PreProcessor.hpp +++ b/src/server/PreProcessor.hpp @@ -19,7 +19,7 @@ #include "Event.hpp" -#include "raul/Semaphore.hpp" +#include <raul/Semaphore.hpp> #include <atomic> #include <chrono> @@ -27,8 +27,7 @@ #include <mutex> #include <thread> -namespace ingen { -namespace server { +namespace ingen::server { class Engine; class PostProcessor; @@ -42,7 +41,7 @@ public: ~PreProcessor(); /** Return true iff no events are enqueued. */ - inline bool empty() const { return !_head.load(); } + bool empty() const { return !_head.load(); } /** Enqueue an event. * This is safe to call from any non-realtime thread (it locks). @@ -61,11 +60,11 @@ protected: private: enum class BlockState { - UNBLOCKED, ///< Normal, unblocked execution - PRE_BLOCKED, ///< Preprocess thread has enqueued blocking event - BLOCKED, ///< Process thread has reached blocking event - PRE_UNBLOCKED, ///< Preprocess thread has enqueued unblocking event - PROCESSING ///< Process thread is executing all events in-between + UNBLOCKED, ///< Normal, unblocked execution + PRE_BLOCKED, ///< Preprocess thread has enqueued blocking event + BLOCKED, ///< Process thread has reached blocking event + PRE_UNBLOCKED, ///< Preprocess thread has enqueued unblocking event + PROCESSING ///< Process thread is executing all events in-between }; void wait_for_block_state(const BlockState state) { @@ -76,15 +75,14 @@ private: Engine& _engine; std::mutex _mutex; - raul::Semaphore _sem; - std::atomic<Event*> _head; - std::atomic<Event*> _tail; - std::atomic<BlockState> _block_state; - bool _exit_flag; + raul::Semaphore _sem{0}; + std::atomic<Event*> _head{nullptr}; + std::atomic<Event*> _tail{nullptr}; + std::atomic<BlockState> _block_state{BlockState::UNBLOCKED}; + bool _exit_flag{false}; std::thread _thread; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_PREPROCESSOR_HPP diff --git a/src/server/RunContext.cpp b/src/server/RunContext.cpp index a61e4afb..29985ccf 100644 --- a/src/server/RunContext.cpp +++ b/src/server/RunContext.cpp @@ -22,32 +22,30 @@ #include "PortImpl.hpp" #include "Task.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Log.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "lv2/urid/urid.h" -#include "raul/RingBuffer.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Log.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <lv2/urid/urid.h> +#include <raul/RingBuffer.hpp> #include <cerrno> #include <cstring> #include <pthread.h> #include <sched.h> -namespace ingen { -namespace server { +namespace ingen::server { -struct Notification -{ - explicit inline Notification(PortImpl* p = nullptr, - FrameTime f = 0, - LV2_URID k = 0, - uint32_t s = 0, - LV2_URID t = 0) - : port(p), time(f), key(k), size(s), type(t) +struct Notification { + explicit Notification(PortImpl* p = nullptr, + FrameTime f = 0, + LV2_URID k = 0, + uint32_t s = 0, + LV2_URID t = 0) + : port(p), time(f), key(k), size(s), type(t) {} PortImpl* port; @@ -63,22 +61,13 @@ RunContext::RunContext(Engine& engine, bool threaded) : _engine(engine) , _event_sink(event_sink) - , _task(nullptr) , _thread(threaded ? new std::thread(&RunContext::run, this) : nullptr) , _id(id) - , _start(0) - , _end(0) - , _offset(0) - , _nframes(0) - , _rate(0) - , _realtime(true) {} RunContext::RunContext(const RunContext& copy) : _engine(copy._engine) , _event_sink(copy._event_sink) - , _task(nullptr) - , _thread(nullptr) , _id(copy._id) , _start(copy._start) , _end(copy._end) @@ -171,9 +160,9 @@ void RunContext::set_priority(int priority) { if (_thread) { - pthread_t pthread = _thread->native_handle(); - const int policy = (priority > 0) ? SCHED_FIFO : SCHED_OTHER; - sched_param sp{}; + const pthread_t pthread = _thread->native_handle(); + const int policy = (priority > 0) ? SCHED_FIFO : SCHED_OTHER; + sched_param sp{}; sp.sched_priority = (priority > 0) ? priority : 0; if (pthread_setschedparam(pthread, policy, &sp)) { _engine.log().error( @@ -204,5 +193,4 @@ RunContext::run() } } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/RunContext.hpp b/src/server/RunContext.hpp index 92aa1cf8..44304c5e 100644 --- a/src/server/RunContext.hpp +++ b/src/server/RunContext.hpp @@ -19,15 +19,14 @@ #include "types.hpp" -#include "lv2/urid/urid.h" -#include "raul/RingBuffer.hpp" +#include <lv2/urid/urid.h> +#include <raul/RingBuffer.hpp> #include <cstdint> #include <memory> #include <thread> -namespace ingen { -namespace server { +namespace ingen::server { class Engine; class PortImpl; @@ -103,17 +102,17 @@ public: * cycle (other than the fact that it must be processed in significantly * less time to avoid a dropout when running in real time). */ - inline uint64_t duration() const { + uint64_t duration() const { return static_cast<uint64_t>(_nframes) * 1e6 / _rate; } - inline void locate(FrameTime s, SampleCount nframes) { + void locate(FrameTime s, SampleCount nframes) { _start = s; _end = s + nframes; _nframes = nframes; } - inline void slice(SampleCount offset, SampleCount nframes) { + void slice(SampleCount offset, SampleCount nframes) { _offset = offset; _nframes = nframes; } @@ -129,35 +128,34 @@ public: void join(); - inline Engine& engine() const { return _engine; } - inline Task* task() const { return _task; } - inline unsigned id() const { return _id; } - inline FrameTime start() const { return _start; } - inline FrameTime time() const { return _start + _offset; } - inline FrameTime end() const { return _end; } - inline SampleCount offset() const { return _offset; } - inline SampleCount nframes() const { return _nframes; } - inline SampleCount rate() const { return _rate; } - inline bool realtime() const { return _realtime; } + Engine& engine() const { return _engine; } + Task* task() const { return _task; } + unsigned id() const { return _id; } + FrameTime start() const { return _start; } + FrameTime time() const { return _start + _offset; } + FrameTime end() const { return _end; } + SampleCount offset() const { return _offset; } + SampleCount nframes() const { return _nframes; } + SampleCount rate() const { return _rate; } + bool realtime() const { return _realtime; } protected: void run(); - Engine& _engine; ///< Engine we're running in - raul::RingBuffer* _event_sink; ///< Updates from process context - Task* _task; ///< Currently executing task - std::unique_ptr<std::thread> _thread; ///< Thread (or null for main) - unsigned _id; ///< Context ID - - FrameTime _start; ///< Start frame of this cycle, timeline relative - FrameTime _end; ///< End frame of this cycle, timeline relative - SampleCount _offset; ///< Offset into data buffers - SampleCount _nframes; ///< Number of frames past offset to process - SampleCount _rate; ///< Sample rate in Hz - bool _realtime; ///< True iff context is hard realtime + Engine& _engine; ///< Engine we're running in + raul::RingBuffer* _event_sink; ///< Updates from notify() + Task* _task{nullptr}; ///< Currently executing task + std::unique_ptr<std::thread> _thread; ///< Thread (or null for main) + unsigned _id; ///< Context ID + + FrameTime _start{0}; ///< Start frame of this cycle (timeline) + FrameTime _end{0}; ///< End frame of this cycle (timeline) + SampleCount _offset{0}; ///< Offset into data buffers + SampleCount _nframes{0}; ///< Number of frames past offset to process + SampleCount _rate{0}; ///< Sample rate in Hz + bool _realtime{true}; ///< True iff context is hard realtime }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_RUNCONTEXT_HPP diff --git a/src/server/SocketListener.cpp b/src/server/SocketListener.cpp index 445374c4..fb961ee2 100644 --- a/src/server/SocketListener.cpp +++ b/src/server/SocketListener.cpp @@ -19,15 +19,16 @@ #include "Engine.hpp" #include "SocketServer.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Log.hpp" -#include "ingen/URI.hpp" -#include "ingen/World.hpp" -#include "raul/Socket.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Log.hpp> +#include <ingen/URI.hpp> +#include <ingen/World.hpp> +#include <raul/Socket.hpp> #include <poll.h> #include <sys/stat.h> +#include <sys/types.h> #include <unistd.h> #include <cerrno> @@ -40,8 +41,7 @@ #include <string> #include <thread> -namespace ingen { -namespace server { +namespace ingen::server { static constexpr const char* const unix_scheme = "unix://"; @@ -51,7 +51,7 @@ get_link_target(const char* link_path) // Stat the link to get the required size for the target path struct stat link_stat{}; if (lstat(link_path, &link_stat)) { - return std::string(); + return {}; } // Allocate buffer and read link target @@ -63,7 +63,7 @@ get_link_target(const char* link_path) } free(target); - return std::string(); + return {}; } static void ingen_listen(Engine* engine, @@ -141,7 +141,7 @@ ingen_listen(Engine* engine, raul::Socket* unix_sock, raul::Socket* net_sock) } if (unix_sock->fd() == -1 && net_sock->fd() == -1) { - return; // No sockets to listen to, exit thread + return; // No sockets to listen to, exit thread } struct pollfd pfds[2]; @@ -165,10 +165,14 @@ ingen_listen(Engine* engine, raul::Socket* unix_sock, raul::Socket* net_sock) if (ret == -1) { world.log().error("Poll error: %1%\n", strerror(errno)); break; - } else if (ret == 0) { + } + + if (ret == 0) { world.log().warn("Poll returned with no data\n"); continue; - } else if ((pfds[0].revents & POLLHUP) || pfds[1].revents & POLLHUP) { + } + + if ((pfds[0].revents & POLLHUP) || pfds[1].revents & POLLHUP) { break; } @@ -192,5 +196,4 @@ ingen_listen(Engine* engine, raul::Socket* unix_sock, raul::Socket* net_sock) } } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/SocketListener.hpp b/src/server/SocketListener.hpp index 70a2d46b..a96105ef 100644 --- a/src/server/SocketListener.hpp +++ b/src/server/SocketListener.hpp @@ -14,13 +14,12 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "raul/Socket.hpp" +#include <raul/Socket.hpp> #include <memory> #include <thread> -namespace ingen { -namespace server { +namespace ingen::server { class Engine; @@ -28,7 +27,7 @@ class Engine; class SocketListener { public: - SocketListener(Engine& engine); + explicit SocketListener(Engine& engine); ~SocketListener(); private: @@ -37,5 +36,4 @@ private: std::unique_ptr<std::thread> thread; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/SocketServer.hpp b/src/server/SocketServer.hpp index ac8aa611..608d180d 100644 --- a/src/server/SocketServer.hpp +++ b/src/server/SocketServer.hpp @@ -21,24 +21,23 @@ #include "Engine.hpp" -#include "ingen/Atom.hpp" -#include "ingen/ColorContext.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Interface.hpp" -#include "ingen/SocketReader.hpp" -#include "ingen/SocketWriter.hpp" -#include "ingen/StreamWriter.hpp" -#include "ingen/Tee.hpp" -#include "ingen/URI.hpp" -#include "ingen/World.hpp" -#include "raul/Socket.hpp" +#include <ingen/Atom.hpp> +#include <ingen/ColorContext.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Interface.hpp> +#include <ingen/SocketReader.hpp> +#include <ingen/SocketWriter.hpp> +#include <ingen/StreamWriter.hpp> +#include <ingen/Tee.hpp> +#include <ingen/URI.hpp> +#include <ingen/World.hpp> +#include <raul/Socket.hpp> #include <cstdint> #include <cstdio> #include <memory> -namespace ingen { -namespace server { +namespace ingen::server { /** The server side of an Ingen socket connection. */ class SocketServer @@ -86,7 +85,6 @@ private: std::shared_ptr<SocketWriter> _writer; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server -#endif // INGEN_SERVER_SOCKET_SERVER_HPP +#endif // INGEN_SERVER_SOCKET_SERVER_HPP diff --git a/src/server/State.hpp b/src/server/State.hpp index b5a3f7c0..976cf67d 100644 --- a/src/server/State.hpp +++ b/src/server/State.hpp @@ -17,21 +17,18 @@ #ifndef INGEN_ENGINE_STATE_HPP #define INGEN_ENGINE_STATE_HPP -#include "lilv/lilv.h" +#include <lilv/lilv.h> #include <memory> -namespace ingen { -namespace server { +namespace ingen::server { -struct StateDeleter -{ +struct StateDeleter { void operator()(LilvState* state) { lilv_state_free(state); } }; using StatePtr = std::unique_ptr<LilvState, StateDeleter>; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_STATE_HPP diff --git a/src/server/Task.cpp b/src/server/Task.cpp index ec9568b3..345a4711 100644 --- a/src/server/Task.cpp +++ b/src/server/Task.cpp @@ -19,12 +19,12 @@ #include "BlockImpl.hpp" #include "RunContext.hpp" -#include "raul/Path.hpp" +#include <raul/Path.hpp> #include <cstddef> +#include <memory> -namespace ingen { -namespace server { +namespace ingen::server { void Task::run(RunContext& ctx) @@ -93,7 +93,7 @@ Task::get_task(RunContext& ctx) } if (_done_end >= _children.size()) { - return nullptr; // All child tasks are finished + return nullptr; // All child tasks are finished } // All child tasks claimed, but some are unfinished, steal a task @@ -116,7 +116,7 @@ Task::simplify(std::unique_ptr<Task>&& task) return std::move(task); } - std::unique_ptr<Task> ret = std::unique_ptr<Task>(new Task(task->mode())); + std::unique_ptr<Task> ret = std::make_unique<Task>(task->mode()); for (auto&& c : task->_children) { auto child = simplify(std::move(c)); if (!child->empty()) { @@ -162,5 +162,4 @@ Task::dump(const std::function<void(const std::string&)>& sink, } } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/Task.hpp b/src/server/Task.hpp index a7657499..f2141bd5 100644 --- a/src/server/Task.hpp +++ b/src/server/Task.hpp @@ -17,7 +17,6 @@ #ifndef INGEN_ENGINE_TASK_HPP #define INGEN_ENGINE_TASK_HPP -#include <algorithm> #include <atomic> #include <cassert> #include <deque> @@ -26,30 +25,29 @@ #include <string> #include <utility> -namespace ingen { -namespace server { +namespace ingen::server { class BlockImpl; class RunContext; -class Task { +class Task +{ public: enum class Mode { - SINGLE, ///< Single block to run - SEQUENTIAL, ///< Elements must be run sequentially in order - PARALLEL ///< Elements may be run in any order in parallel + SINGLE, ///< Single block to run + SEQUENTIAL, ///< Elements must be run sequentially in order + PARALLEL ///< Elements may be run in any order in parallel }; - Task(Mode mode, BlockImpl* block = nullptr) + Task(Mode mode, BlockImpl* block) : _block(block) , _mode(mode) - , _done_end(0) - , _next(0) - , _done(false) { - assert(!(mode == Mode::SINGLE && !block)); + assert(mode != Mode::SINGLE || block); } + explicit Task(Mode mode) : Task{mode, nullptr} {} + Task(const Task&) = delete; Task& operator=(const Task&) = delete; @@ -92,7 +90,7 @@ public: /** Prepend a child to this task. */ void push_front(Task&& task) { - _children.emplace_front(std::unique_ptr<Task>(new Task(std::move(task)))); + _children.emplace_front(std::make_unique<Task>(std::move(task))); } Mode mode() const { return _mode; } @@ -110,15 +108,14 @@ private: _children.emplace_back(std::move(t)); } - Children _children; ///< Vector of child tasks - BlockImpl* _block; ///< Used for SINGLE only - Mode _mode; ///< Execution mode - unsigned _done_end; ///< Index of rightmost done sub-task - std::atomic<unsigned> _next; ///< Index of next sub-task - std::atomic<bool> _done; ///< Completion phase + Children _children; ///< Vector of child tasks + BlockImpl* _block; ///< Used for SINGLE only + Mode _mode; ///< Execution mode + unsigned _done_end{0}; ///< Index of rightmost done sub-task + std::atomic<unsigned> _next{0}; ///< Index of next sub-task + std::atomic<bool> _done{false}; ///< Completion phase }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_TASK_HPP diff --git a/src/server/ThreadManager.hpp b/src/server/ThreadManager.hpp index 81fb15cb..2e0ad966 100644 --- a/src/server/ThreadManager.hpp +++ b/src/server/ThreadManager.hpp @@ -17,12 +17,11 @@ #ifndef INGEN_ENGINE_THREADMANAGER_HPP #define INGEN_ENGINE_THREADMANAGER_HPP -#include "ingen/ingen.h" +#include "server.h" #include <cassert> -namespace ingen { -namespace server { +namespace ingen::server { enum ThreadFlag { THREAD_IS_REAL_TIME = 1, @@ -31,25 +30,26 @@ enum ThreadFlag { THREAD_MESSAGE = 1 << 3, }; -class INGEN_API ThreadManager { +class INGEN_SERVER_API ThreadManager +{ public: - static inline void set_flag(ThreadFlag f) { + static void set_flag(ThreadFlag f) { #ifndef NDEBUG - flags = (static_cast<unsigned>(flags) | f); + flags |= static_cast<unsigned>(f); #endif } - static inline void unset_flag(ThreadFlag f) { + static void unset_flag(ThreadFlag f) { #ifndef NDEBUG - flags = (static_cast<unsigned>(flags) & (~f)); + flags &= ~static_cast<unsigned>(f); #endif } - static inline void assert_thread(ThreadFlag f) { + static void assert_thread(ThreadFlag f) { assert(single_threaded || (flags & f)); } - static inline void assert_not_thread(ThreadFlag f) { + static void assert_not_thread(ThreadFlag f) { assert(single_threaded || !(flags & f)); } @@ -60,7 +60,6 @@ public: static thread_local unsigned flags; }; -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_THREADMANAGER_HPP diff --git a/src/server/UndoStack.cpp b/src/server/UndoStack.cpp index 97539823..c6555123 100644 --- a/src/server/UndoStack.cpp +++ b/src/server/UndoStack.cpp @@ -16,24 +16,23 @@ #include "UndoStack.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" -#include "lv2/atom/atom.h" -#include "lv2/atom/util.h" -#include "lv2/patch/patch.h" -#include "serd/serd.h" -#include "sratom/sratom.h" +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/ingen.h> +#include <lv2/atom/atom.h> +#include <lv2/atom/util.h> +#include <lv2/patch/patch.h> +#include <serd/serd.h> +#include <sratom/sratom.h> #include <ctime> #include <iterator> -#include <memory> #define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#" #define USTR(s) reinterpret_cast<const uint8_t*>(s) -namespace ingen { -namespace server { +namespace ingen::server { int UndoStack::start_entry() @@ -41,7 +40,7 @@ UndoStack::start_entry() if (_depth == 0) { time_t now = {}; time(&now); - _stack.emplace_back(Entry(now)); + _stack.emplace_back(now); } return ++_depth; } @@ -86,18 +85,18 @@ UndoStack::ignore_later_event(const LV2_Atom* first, int UndoStack::finish_entry() { - if (--_depth > 0) { - return _depth; - } else if (_stack.back().events.empty()) { - // Disregard empty entry - _stack.pop_back(); - } else if (_stack.size() > 1 && _stack.back().events.size() == 1) { - // This entry and the previous one have one event, attempt to merge - auto i = _stack.rbegin(); - ++i; - if (i->events.size() == 1) { - if (ignore_later_event(i->events[0], _stack.back().events[0])) { - _stack.pop_back(); + if (--_depth == 0) { + if (_stack.back().events.empty()) { + // Disregard empty entry + _stack.pop_back(); + } else if (_stack.size() > 1 && _stack.back().events.size() == 1) { + // This entry and the previous one have one event, attempt to merge + auto i = _stack.rbegin(); + ++i; + if (i->events.size() == 1) { + if (ignore_later_event(i->events[0], _stack.back().events[0])) { + _stack.pop_back(); + } } } } @@ -117,7 +116,7 @@ UndoStack::pop() } struct BlankIDs { - explicit BlankIDs(char prefix='b') : c(prefix) {} + explicit BlankIDs(const char prefix = 'b') noexcept : c{prefix} {} SerdNode get() { snprintf(buf, sizeof(buf), "%c%u", c, n++); @@ -126,7 +125,7 @@ struct BlankIDs { char buf[16]{}; unsigned n{0}; - const char c{'b'}; + const char c; }; struct ListContext { @@ -138,8 +137,7 @@ struct ListContext { , s(*subject) , p(*predicate) , flags(statement_flags | SERD_LIST_O_BEGIN) - { - } + {} SerdNode start_node(SerdWriter* writer) { const SerdNode node = ids.get(); @@ -189,8 +187,8 @@ UndoStack::write_entry(Sratom* sratom, strftime(time_str, sizeof(time_str), "%FT%T", gmtime(&entry.time)); // entry rdf:type ingen:UndoEntry - SerdNode p = serd_node_from_string(SERD_URI, USTR(INGEN_NS "time")); - SerdNode o = serd_node_from_string(SERD_LITERAL, USTR(time_str)); + SerdNode p = serd_node_from_string(SERD_URI, USTR(INGEN_NS "time")); + const SerdNode o = serd_node_from_string(SERD_LITERAL, USTR(time_str)); serd_writer_write_statement(writer, SERD_ANON_CONT, nullptr, subject, &p, &o, nullptr, nullptr); p = serd_node_from_string(SERD_URI, USTR(INGEN_NS "events")); @@ -226,7 +224,7 @@ UndoStack::save(FILE* stream, const char* name) const SerdNode base = serd_node_from_string(SERD_URI, USTR("ingen:/")); SerdURI base_uri; - serd_uri_parse(base.buf, &base_uri); + serd_uri_parse(USTR("ingen:/"), &base_uri); SerdWriter* writer = serd_writer_new(SERD_TURTLE, @@ -246,8 +244,8 @@ UndoStack::save(FILE* stream, const char* name) reinterpret_cast<SerdEndSink>(serd_writer_end_anon), writer); - SerdNode s = serd_node_from_string(SERD_BLANK, USTR(name)); - SerdNode p = serd_node_from_string(SERD_URI, USTR(INGEN_NS "entries")); + const SerdNode s = serd_node_from_string(SERD_BLANK, USTR(name)); + const SerdNode p = serd_node_from_string(SERD_URI, USTR(INGEN_NS "entries")); BlankIDs ids('u'); ListContext ctx(ids, 0, &s, &p); @@ -264,5 +262,4 @@ UndoStack::save(FILE* stream, const char* name) serd_writer_free(writer); } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/UndoStack.hpp b/src/server/UndoStack.hpp index 7749b8fb..443497cc 100644 --- a/src/server/UndoStack.hpp +++ b/src/server/UndoStack.hpp @@ -17,14 +17,13 @@ #ifndef INGEN_ENGINE_UNDOSTACK_HPP #define INGEN_ENGINE_UNDOSTACK_HPP -#include "ingen/AtomSink.hpp" -#include "ingen/ingen.h" -#include "lv2/atom/atom.h" -#include "lv2/atom/util.h" -#include "serd/serd.h" -#include "sratom/sratom.h" - -#include <algorithm> +#include <ingen/AtomSink.hpp> +#include <lv2/atom/atom.h> +#include <lv2/atom/util.h> +#include <serd/serd.h> +#include <server.h> +#include <sratom/sratom.h> + #include <cstdint> #include <cstdio> #include <cstdlib> @@ -39,10 +38,12 @@ class URIs; namespace server { -class INGEN_API UndoStack : public AtomSink { +class INGEN_SERVER_API UndoStack : public AtomSink +{ public: struct Entry { - Entry(time_t t=0) : time(t) {} + explicit Entry(time_t t) noexcept : time{t} {} + Entry() noexcept : Entry{0} {} Entry(const Entry& copy) : time(copy.time) @@ -83,7 +84,7 @@ public: std::deque<LV2_Atom*> events; }; - UndoStack(URIs& uris, URIMap& map) : _uris(uris), _map(map), _depth(0) {} + UndoStack(URIs& uris, URIMap& map) noexcept : _uris(uris), _map(map) {} int start_entry(); bool write(const LV2_Atom* msg, int32_t default_id=0) override; @@ -106,7 +107,7 @@ private: URIs& _uris; URIMap& _map; std::deque<Entry> _stack; - int _depth; + int _depth{0}; }; } // namespace server diff --git a/src/server/Worker.cpp b/src/server/Worker.cpp index 77d98612..1c04bb36 100644 --- a/src/server/Worker.cpp +++ b/src/server/Worker.cpp @@ -20,25 +20,23 @@ #include "GraphImpl.hpp" #include "LV2Block.hpp" -#include "ingen/Log.hpp" -#include "ingen/Node.hpp" -#include "lv2/core/lv2.h" -#include "lv2/worker/worker.h" +#include <ingen/Log.hpp> +#include <ingen/Node.hpp> +#include <lv2/core/lv2.h> +#include <lv2/worker/worker.h> +#include <raul/RingBuffer.hpp> +#include <raul/Semaphore.hpp> #include <cstdlib> #include <memory> -namespace ingen { - -class World; - -namespace server { +namespace ingen::server { /// A message in the Worker::_requests ring struct MessageHeader { - LV2Block* block; ///< Node this message is from + LV2Block* block; ///< Node this message is from uint32_t size; ///< Size of following data - // `size' bytes of data follow here + // `size' bytes of data follow here }; static LV2_Worker_Status @@ -46,8 +44,8 @@ schedule(LV2_Worker_Schedule_Handle handle, uint32_t size, const void* data) { - auto* block = static_cast<LV2Block*>(handle); - Engine& engine = block->parent_graph()->engine(); + auto* block = static_cast<LV2Block*>(handle); + const Engine& engine = block->parent_graph()->engine(); return engine.worker()->request(block, size, data); } @@ -57,8 +55,8 @@ schedule_sync(LV2_Worker_Schedule_Handle handle, uint32_t size, const void* data) { - auto* block = static_cast<LV2Block*>(handle); - Engine& engine = block->parent_graph()->engine(); + auto* block = static_cast<LV2Block*>(handle); + const Engine& engine = block->parent_graph()->engine(); return engine.sync_worker()->request(block, size, data); } @@ -72,7 +70,7 @@ Worker::request(LV2Block* block, return block->work(size, data); } - Engine& engine = block->parent_graph()->engine(); + const Engine& engine = block->parent_graph()->engine(); if (_requests.write_space() < sizeof(MessageHeader) + size) { engine.log().error("Work request ring overflow\n"); return LV2_WORKER_ERR_NO_SPACE; @@ -110,19 +108,17 @@ Worker::Schedule::feature(World&, Node* n) f->URI = LV2_WORKER__schedule; f->data = data; - return std::shared_ptr<LV2_Feature>(f, &free_feature); + return {f, &free_feature}; } Worker::Worker(Log& log, uint32_t buffer_size, bool synchronous) : _schedule(new Schedule(synchronous)) , _log(log) - , _sem(0) , _requests(buffer_size) , _responses(buffer_size) , _buffer(static_cast<uint8_t*>(malloc(buffer_size))) , _buffer_size(buffer_size) , _thread(nullptr) - , _exit_flag(false) , _synchronous(synchronous) { if (!synchronous) { @@ -166,5 +162,4 @@ Worker::run() } } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/Worker.hpp b/src/server/Worker.hpp index dd799174..08b75509 100644 --- a/src/server/Worker.hpp +++ b/src/server/Worker.hpp @@ -17,11 +17,11 @@ #ifndef INGEN_ENGINE_WORKER_HPP #define INGEN_ENGINE_WORKER_HPP -#include "ingen/LV2Features.hpp" -#include "lv2/core/lv2.h" -#include "lv2/worker/worker.h" -#include "raul/RingBuffer.hpp" -#include "raul/Semaphore.hpp" +#include <ingen/LV2Features.hpp> +#include <lv2/core/lv2.h> +#include <lv2/worker/worker.h> +#include <raul/RingBuffer.hpp> +#include <raul/Semaphore.hpp> #include <cstdint> #include <memory> @@ -30,8 +30,6 @@ namespace ingen { class Log; -class Node; -class World; namespace server { @@ -44,7 +42,7 @@ public: ~Worker(); struct Schedule : public LV2Features::Feature { - Schedule(bool sync) : synchronous(sync) {} + explicit Schedule(bool sync) noexcept : synchronous(sync) {} const char* uri() const override { return LV2_WORKER__schedule; } @@ -63,13 +61,13 @@ private: std::shared_ptr<Schedule> _schedule; Log& _log; - raul::Semaphore _sem; + raul::Semaphore _sem{0}; raul::RingBuffer _requests; raul::RingBuffer _responses; uint8_t* const _buffer; const uint32_t _buffer_size; std::unique_ptr<std::thread> _thread; - bool _exit_flag; + bool _exit_flag{false}; bool _synchronous; void run(); diff --git a/src/server/events.hpp b/src/server/events.hpp index 5f77b431..7ab20ca7 100644 --- a/src/server/events.hpp +++ b/src/server/events.hpp @@ -17,19 +17,19 @@ #ifndef INGEN_ENGINE_EVENTS_HPP #define INGEN_ENGINE_EVENTS_HPP -#include "events/Connect.hpp" -#include "events/Copy.hpp" -#include "events/CreateBlock.hpp" -#include "events/CreateGraph.hpp" -#include "events/CreatePort.hpp" -#include "events/Delete.hpp" -#include "events/Delta.hpp" -#include "events/Disconnect.hpp" -#include "events/DisconnectAll.hpp" -#include "events/Get.hpp" -#include "events/Mark.hpp" -#include "events/Move.hpp" -#include "events/SetPortValue.hpp" -#include "events/Undo.hpp" +#include <events/Connect.hpp> +#include <events/Copy.hpp> +#include <events/CreateBlock.hpp> +#include <events/CreateGraph.hpp> +#include <events/CreatePort.hpp> +#include <events/Delete.hpp> +#include <events/Delta.hpp> +#include <events/Disconnect.hpp> +#include <events/DisconnectAll.hpp> +#include <events/Get.hpp> +#include <events/Mark.hpp> +#include <events/Move.hpp> +#include <events/SetPortValue.hpp> +#include <events/Undo.hpp> #endif // INGEN_ENGINE_EVENTS_HPP diff --git a/src/server/events/Connect.cpp b/src/server/events/Connect.cpp index 234bc550..6e20be8f 100644 --- a/src/server/events/Connect.cpp +++ b/src/server/events/Connect.cpp @@ -16,6 +16,7 @@ #include "Connect.hpp" +#include "../internals/BlockDelay.hpp" #include "ArcImpl.hpp" #include "BlockImpl.hpp" #include "Broadcaster.hpp" @@ -26,15 +27,16 @@ #include "InputPort.hpp" #include "PortImpl.hpp" #include "PreProcessContext.hpp" -#include "internals/BlockDelay.hpp" #include "types.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Node.hpp" -#include "ingen/Status.hpp" -#include "ingen/Store.hpp" -#include "ingen/paths.hpp" -#include "raul/Maid.hpp" +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/Node.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Status.hpp> +#include <ingen/Store.hpp> +#include <ingen/paths.hpp> +#include <raul/Maid.hpp> #include <cassert> #include <memory> @@ -42,9 +44,7 @@ #include <set> #include <utility> -namespace ingen { -namespace server { -namespace events { +namespace ingen::server::events { Connect::Connect(Engine& engine, const std::shared_ptr<Interface>& client, @@ -52,17 +52,14 @@ Connect::Connect(Engine& engine, const ingen::Connect& msg) : Event(engine, client, msg.seq, timestamp) , _msg(msg) - , _graph(nullptr) - , _head(nullptr) -{ -} +{} Connect::~Connect() = default; bool Connect::pre_process(PreProcessContext& ctx) { - std::lock_guard<Store::Mutex> lock(_engine.store()->mutex()); + const std::lock_guard<Store::Mutex> lock{_engine.store()->mutex()}; Node* tail = _engine.store()->get(_msg.tail); if (!tail) { @@ -137,7 +134,7 @@ Connect::pre_process(PreProcessContext& ctx) head_block->providers().insert(tail_block); if (ctx.must_compile(*_graph)) { - if (!(_compiled_graph = compile(*_engine.maid(), *_graph))) { + if (!(_compiled_graph = compile(*_graph))) { head_block->providers().erase(tail_block); tail_block->dependants().erase(head_block); return Event::pre_process_done(Status::COMPILATION_FAILED); @@ -170,7 +167,7 @@ Connect::execute(RunContext& ctx) } _head->connect_buffers(); if (_compiled_graph) { - _graph->set_compiled_graph(std::move(_compiled_graph)); + _compiled_graph = _graph->swap_compiled_graph(std::move(_compiled_graph)); } } } @@ -178,7 +175,7 @@ Connect::execute(RunContext& ctx) void Connect::post_process() { - Broadcaster::Transfer t(*_engine.broadcaster()); + const Broadcaster::Transfer t{*_engine.broadcaster()}; if (respond() == Status::SUCCESS) { _engine.broadcaster()->message(_msg); if (!_tail_remove.empty() || !_tail_add.empty()) { @@ -198,6 +195,4 @@ Connect::undo(Interface& target) target.disconnect(_msg.tail, _msg.head); } -} // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server::events diff --git a/src/server/events/Connect.hpp b/src/server/events/Connect.hpp index 941c0a25..458df0ef 100644 --- a/src/server/events/Connect.hpp +++ b/src/server/events/Connect.hpp @@ -21,9 +21,9 @@ #include "PortImpl.hpp" #include "types.hpp" -#include "ingen/Message.hpp" -#include "ingen/Properties.hpp" -#include "raul/Maid.hpp" +#include <ingen/Message.hpp> +#include <ingen/Properties.hpp> +#include <raul/Maid.hpp> #include <memory> @@ -38,8 +38,6 @@ class CompiledGraph; class Engine; class GraphImpl; class InputPort; -class PreProcessContext; -class RunContext; namespace events { @@ -64,9 +62,9 @@ public: private: const ingen::Connect _msg; - GraphImpl* _graph; - InputPort* _head; - raul::managed_ptr<CompiledGraph> _compiled_graph; + GraphImpl* _graph{nullptr}; + InputPort* _head{nullptr}; + std::unique_ptr<CompiledGraph> _compiled_graph; std::shared_ptr<ArcImpl> _arc; raul::managed_ptr<PortImpl::Voices> _voices; Properties _tail_remove; diff --git a/src/server/events/Copy.cpp b/src/server/events/Copy.cpp index 9ce7ead6..e75bf1c5 100644 --- a/src/server/events/Copy.cpp +++ b/src/server/events/Copy.cpp @@ -14,7 +14,7 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "events/Copy.hpp" +#include "Copy.hpp" #include "BlockImpl.hpp" #include "Broadcaster.hpp" @@ -23,28 +23,28 @@ #include "GraphImpl.hpp" #include "PreProcessContext.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Parser.hpp" -#include "ingen/Serialiser.hpp" -#include "ingen/Status.hpp" -#include "ingen/Store.hpp" -#include "ingen/URI.hpp" -#include "ingen/World.hpp" -#include "ingen/paths.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" - -#include <boost/optional/optional.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/Node.hpp> +#include <ingen/Parser.hpp> +#include <ingen/Serialiser.hpp> +#include <ingen/Status.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/World.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <map> #include <memory> #include <mutex> +#include <optional> #include <string> +#include <string_view> #include <utility> -namespace ingen { -namespace server { -namespace events { +namespace ingen::server::events { Copy::Copy(Engine& engine, const std::shared_ptr<Interface>& client, @@ -52,9 +52,6 @@ Copy::Copy(Engine& engine, const ingen::Copy& msg) : Event(engine, client, msg.seq, timestamp) , _msg(msg) - , _old_block(nullptr) - , _parent(nullptr) - , _block(nullptr) {} Copy::~Copy() = default; @@ -62,14 +59,14 @@ Copy::~Copy() = default; bool Copy::pre_process(PreProcessContext& ctx) { - std::lock_guard<Store::Mutex> lock(_engine.store()->mutex()); + const std::lock_guard<Store::Mutex> lock{_engine.store()->mutex()}; if (uri_is_path(_msg.old_uri)) { // Old URI is a path within the engine const raul::Path old_path = uri_to_path(_msg.old_uri); // Find the old node - const Store::iterator i = _engine.store()->find(old_path); + const auto i = _engine.store()->find(old_path); if (i == _engine.store()->end()) { return Event::pre_process_done(Status::NOT_FOUND, old_path); } @@ -82,19 +79,23 @@ Copy::pre_process(PreProcessContext& ctx) if (uri_is_path(_msg.new_uri)) { // Copy to path within the engine return engine_to_engine(ctx); - } else if (_msg.new_uri.scheme() == "file") { + } + + if (_msg.new_uri.scheme() == "file") { // Copy to filesystem path (i.e. save) return engine_to_filesystem(ctx); - } else { - return Event::pre_process_done(Status::BAD_REQUEST); } - } else if (_msg.old_uri.scheme() == "file") { + + return Event::pre_process_done(Status::BAD_REQUEST); + } + + if (_msg.old_uri.scheme() == "file") { if (uri_is_path(_msg.new_uri)) { return filesystem_to_engine(ctx); - } else { - // Ingen is not your file manager - return Event::pre_process_done(Status::BAD_REQUEST); } + + // Ingen is not your file manager + return Event::pre_process_done(Status::BAD_REQUEST); } return Event::pre_process_done(Status::BAD_URI); @@ -115,8 +116,8 @@ Copy::engine_to_engine(PreProcessContext& ctx) } // Find new parent graph - const raul::Path parent_path = new_path.parent(); - const Store::iterator p = _engine.store()->find(parent_path); + const raul::Path parent_path = new_path.parent(); + const auto p = _engine.store()->find(parent_path); if (p == _engine.store()->end()) { return Event::pre_process_done(Status::NOT_FOUND, parent_path); } @@ -125,8 +126,7 @@ Copy::engine_to_engine(PreProcessContext& ctx) } // Create new block - if (!(_block = dynamic_cast<BlockImpl*>( - _old_block->duplicate(_engine, raul::Symbol(new_path.symbol()), _parent)))) { + if (!(_block = _old_block->duplicate(_engine, raul::Symbol(new_path.symbol()), _parent))) { return Event::pre_process_done(Status::INTERNAL_ERROR); } @@ -137,7 +137,7 @@ Copy::engine_to_engine(PreProcessContext& ctx) _engine.store()->add(_block); // Compile graph with new block added for insertion in audio thread - _compiled_graph = ctx.maybe_compile(*_engine.maid(), *_parent); + _compiled_graph = ctx.maybe_compile(*_parent); return Event::pre_process_done(Status::SUCCESS); } @@ -164,7 +164,7 @@ Copy::engine_to_filesystem(PreProcessContext&) return Event::pre_process_done(Status::INTERNAL_ERROR); } - std::lock_guard<std::mutex> lock(_engine.world().rdf_mutex()); + const std::lock_guard<std::mutex> lock{_engine.world().rdf_mutex()}; if (ends_with(_msg.new_uri, ".ingen") || ends_with(_msg.new_uri, ".ingen/")) { _engine.world().serialiser()->write_bundle(graph, URI(_msg.new_uri)); @@ -185,13 +185,13 @@ Copy::filesystem_to_engine(PreProcessContext&) return Event::pre_process_done(Status::INTERNAL_ERROR); } - std::lock_guard<std::mutex> lock(_engine.world().rdf_mutex()); + const std::lock_guard<std::mutex> lock{_engine.world().rdf_mutex()}; // Old URI is a filesystem path and new URI is a path within the engine - const std::string src_path(_msg.old_uri.path()); - const raul::Path dst_path = uri_to_path(_msg.new_uri); - boost::optional<raul::Path> dst_parent; - boost::optional<raul::Symbol> dst_symbol; + const std::string src_path(_msg.old_uri.path()); + const raul::Path dst_path = uri_to_path(_msg.new_uri); + std::optional<raul::Path> dst_parent; + std::optional<raul::Symbol> dst_symbol; if (!dst_path.is_root()) { dst_parent = dst_path.parent(); dst_symbol = raul::Symbol(dst_path.symbol()); @@ -208,14 +208,15 @@ void Copy::execute(RunContext&) { if (_block && _compiled_graph) { - _parent->set_compiled_graph(std::move(_compiled_graph)); + _compiled_graph = + _parent->swap_compiled_graph(std::move(_compiled_graph)); } } void Copy::post_process() { - Broadcaster::Transfer t(*_engine.broadcaster()); + const Broadcaster::Transfer t{*_engine.broadcaster()}; if (respond() == Status::SUCCESS) { _engine.broadcaster()->message(_msg); } @@ -229,6 +230,4 @@ Copy::undo(Interface& target) } } -} // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server::events diff --git a/src/server/events/Copy.hpp b/src/server/events/Copy.hpp index f9c507f0..8031bb42 100644 --- a/src/server/events/Copy.hpp +++ b/src/server/events/Copy.hpp @@ -20,8 +20,7 @@ #include "Event.hpp" #include "types.hpp" -#include "ingen/Message.hpp" -#include "raul/Maid.hpp" +#include <ingen/Message.hpp> #include <memory> @@ -36,7 +35,6 @@ class CompiledGraph; class Engine; class GraphImpl; class PreProcessContext; -class RunContext; namespace events { @@ -64,10 +62,10 @@ private: bool filesystem_to_engine(PreProcessContext& ctx); const ingen::Copy _msg; - std::shared_ptr<BlockImpl> _old_block; - GraphImpl* _parent; - BlockImpl* _block; - raul::managed_ptr<CompiledGraph> _compiled_graph; + std::shared_ptr<BlockImpl> _old_block{nullptr}; + GraphImpl* _parent{nullptr}; + BlockImpl* _block{nullptr}; + std::unique_ptr<CompiledGraph> _compiled_graph; }; } // namespace events diff --git a/src/server/events/CreateBlock.cpp b/src/server/events/CreateBlock.cpp index 0898a6a0..55c9b782 100644 --- a/src/server/events/CreateBlock.cpp +++ b/src/server/events/CreateBlock.cpp @@ -28,32 +28,27 @@ #include "State.hpp" #include "types.hpp" -#include "ingen/FilePath.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Node.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/Status.hpp" -#include "ingen/Store.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/paths.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include <ingen/FilePath.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Node.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/Status.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <map> #include <memory> +#include <string> #include <utility> -namespace ingen { -namespace server { - -class RunContext; - -namespace events { +namespace ingen::server::events { CreateBlock::CreateBlock(Engine& engine, const std::shared_ptr<Interface>& client, @@ -64,8 +59,6 @@ CreateBlock::CreateBlock(Engine& engine, : Event(engine, client, id, timestamp) , _path(std::move(path)) , _properties(properties) - , _graph(nullptr) - , _block(nullptr) {} CreateBlock::~CreateBlock() = default; @@ -73,22 +66,24 @@ CreateBlock::~CreateBlock() = default; bool CreateBlock::pre_process(PreProcessContext& ctx) { - using iterator = Properties::const_iterator; - const ingen::URIs& uris = _engine.world().uris(); const std::shared_ptr<Store> store = _engine.store(); // Check sanity of target path if (_path.is_root()) { return Event::pre_process_done(Status::BAD_URI, _path); - } else if (store->get(_path)) { + } + + if (store->get(_path)) { return Event::pre_process_done(Status::EXISTS, _path); - } else if (!(_graph = dynamic_cast<GraphImpl*>(store->get(_path.parent())))) { + } + + if (!(_graph = dynamic_cast<GraphImpl*>(store->get(_path.parent())))) { return Event::pre_process_done(Status::PARENT_NOT_FOUND, _path.parent()); } // Map old ingen:prototype to new lv2:prototype - auto range = _properties.equal_range(uris.ingen_prototype); + const auto range = _properties.equal_range(uris.ingen_prototype); for (auto i = range.first; i != range.second;) { const auto value = i->second; auto next = i; @@ -98,7 +93,7 @@ CreateBlock::pre_process(PreProcessContext& ctx) } // Get prototype - iterator t = _properties.find(uris.lv2_prototype); + const auto t = _properties.find(uris.lv2_prototype); if (t == _properties.end() || !uris.forge.is_uri(t->second)) { // Missing/invalid prototype return Event::pre_process_done(Status::BAD_REQUEST); @@ -107,10 +102,10 @@ CreateBlock::pre_process(PreProcessContext& ctx) const URI prototype(uris.forge.str(t->second, false)); // Find polyphony - const iterator p = _properties.find(uris.ingen_polyphonic); - const bool polyphonic = (p != _properties.end() && - p->second.type() == uris.forge.Bool && - p->second.get<int32_t>()); + const auto p = _properties.find(uris.ingen_polyphonic); + const bool polyphonic = (p != _properties.end() && + p->second.type() == uris.forge.Bool && + p->second.get<int32_t>()); // Find and instantiate/duplicate prototype (plugin/existing node) if (uri_is_path(prototype)) { @@ -119,8 +114,11 @@ CreateBlock::pre_process(PreProcessContext& ctx) store->get(uri_to_path(prototype))); if (!ancestor) { return Event::pre_process_done(Status::PROTOTYPE_NOT_FOUND, prototype); - } else if (!(_block = ancestor->duplicate( - _engine, raul::Symbol(_path.symbol()), _graph))) { + } + + if (!(_block = ancestor->duplicate(_engine, + raul::Symbol(_path.symbol()), + _graph))) { return Event::pre_process_done(Status::CREATION_FAILED, _path); } @@ -167,7 +165,7 @@ CreateBlock::pre_process(PreProcessContext& ctx) /* Compile graph with new block added for insertion in audio thread TODO: Since the block is not connected at this point, a full compilation could be avoided and the block simply appended. */ - _compiled_graph = ctx.maybe_compile(*_engine.maid(), *_graph); + _compiled_graph = ctx.maybe_compile(*_graph); _update.put_block(_block); @@ -178,14 +176,15 @@ void CreateBlock::execute(RunContext&) { if (_status == Status::SUCCESS && _compiled_graph) { - _graph->set_compiled_graph(std::move(_compiled_graph)); + _compiled_graph = + _graph->swap_compiled_graph(std::move(_compiled_graph)); } } void CreateBlock::post_process() { - Broadcaster::Transfer t(*_engine.broadcaster()); + const Broadcaster::Transfer t{*_engine.broadcaster()}; if (respond() == Status::SUCCESS) { _update.send(*_engine.broadcaster()); } @@ -197,6 +196,4 @@ CreateBlock::undo(Interface& target) target.del(_block->uri()); } -} // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server::events diff --git a/src/server/events/CreateBlock.hpp b/src/server/events/CreateBlock.hpp index 97a54b3f..0ee6e36f 100644 --- a/src/server/events/CreateBlock.hpp +++ b/src/server/events/CreateBlock.hpp @@ -21,8 +21,7 @@ #include "Event.hpp" #include "types.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" +#include <raul/Path.hpp> #include <cstdint> #include <memory> @@ -38,8 +37,6 @@ class BlockImpl; class CompiledGraph; class Engine; class GraphImpl; -class PreProcessContext; -class RunContext; namespace events { @@ -68,9 +65,9 @@ private: raul::Path _path; Properties& _properties; ClientUpdate _update; - GraphImpl* _graph; - BlockImpl* _block; - raul::managed_ptr<CompiledGraph> _compiled_graph; + GraphImpl* _graph{nullptr}; + BlockImpl* _block{nullptr}; + std::unique_ptr<CompiledGraph> _compiled_graph; }; } // namespace events diff --git a/src/server/events/CreateGraph.cpp b/src/server/events/CreateGraph.cpp index 2a74ddf0..5df28afa 100644 --- a/src/server/events/CreateGraph.cpp +++ b/src/server/events/CreateGraph.cpp @@ -14,54 +14,50 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "events/CreateGraph.hpp" +#include "CreateGraph.hpp" #include "BlockImpl.hpp" #include "Broadcaster.hpp" #include "CompiledGraph.hpp" +#include "CreatePort.hpp" #include "Engine.hpp" #include "GraphImpl.hpp" #include "PreProcessContext.hpp" -#include "events/CreatePort.hpp" #include "types.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Node.hpp" -#include "ingen/Resource.hpp" -#include "ingen/Status.hpp" -#include "ingen/Store.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/paths.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Node.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/Status.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <boost/intrusive/slist.hpp> #include <map> #include <memory> +#include <string> #include <utility> -namespace ingen { -namespace server { -namespace events { +namespace ingen::server::events { CreateGraph::CreateGraph(Engine& engine, const std::shared_ptr<Interface>& client, int32_t id, SampleCount timestamp, raul::Path path, - const Properties& properties) + Properties properties) : Event(engine, client, id, timestamp) , _path(std::move(path)) - , _properties(properties) - , _graph(nullptr) - , _parent(nullptr) -{ -} + , _properties(std::move(properties)) +{} CreateGraph::~CreateGraph() = default; @@ -136,11 +132,9 @@ CreateGraph::pre_process(PreProcessContext& ctx) const ingen::URIs& uris = _engine.world().uris(); - using iterator = Properties::const_iterator; - - uint32_t ext_poly = 1; - uint32_t int_poly = 1; - iterator p = _properties.find(uris.ingen_polyphony); + uint32_t ext_poly = 1; + uint32_t int_poly = 1; + const auto p = _properties.find(uris.ingen_polyphony); if (p != _properties.end() && p->second.type() == uris.forge.Int) { int_poly = p->second.get<int32_t>(); } @@ -156,7 +150,7 @@ CreateGraph::pre_process(PreProcessContext& ctx) const raul::Symbol symbol(_path.is_root() ? "graph" : _path.symbol()); // Get graph prototype - iterator t = _properties.find(uris.lv2_prototype); + auto t = _properties.find(uris.lv2_prototype); if (t == _properties.end()) { t = _properties.find(uris.lv2_prototype); } @@ -171,8 +165,10 @@ CreateGraph::pre_process(PreProcessContext& ctx) if (!ancestor) { return Event::pre_process_done(Status::PROTOTYPE_NOT_FOUND, prototype); - } else if (!(_graph = dynamic_cast<GraphImpl*>( - ancestor->duplicate(_engine, symbol, _parent)))) { + } + + if (!(_graph = dynamic_cast<GraphImpl*>( + ancestor->duplicate(_engine, symbol, _parent)))) { return Event::pre_process_done(Status::CREATION_FAILED, _path); } } else { @@ -197,7 +193,7 @@ CreateGraph::pre_process(PreProcessContext& ctx) if (_parent->enabled()) { _graph->enable(); } - _compiled_graph = ctx.maybe_compile(*_engine.maid(), *_parent); + _compiled_graph = ctx.maybe_compile(*_parent); } _graph->activate(*_engine.buffer_factory()); @@ -224,7 +220,8 @@ CreateGraph::execute(RunContext& ctx) if (_graph) { if (_parent) { if (_compiled_graph) { - _parent->set_compiled_graph(std::move(_compiled_graph)); + _compiled_graph = + _parent->swap_compiled_graph(std::move(_compiled_graph)); } } else { _engine.set_root_graph(_graph); @@ -240,7 +237,7 @@ CreateGraph::execute(RunContext& ctx) void CreateGraph::post_process() { - Broadcaster::Transfer t(*_engine.broadcaster()); + const Broadcaster::Transfer t{*_engine.broadcaster()}; if (respond() == Status::SUCCESS) { _update.send(*_engine.broadcaster()); } @@ -258,6 +255,4 @@ CreateGraph::undo(Interface& target) target.del(_graph->uri()); } -} // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server::events diff --git a/src/server/events/CreateGraph.hpp b/src/server/events/CreateGraph.hpp index d9e994c0..1d7f04a5 100644 --- a/src/server/events/CreateGraph.hpp +++ b/src/server/events/CreateGraph.hpp @@ -21,9 +21,8 @@ #include "Event.hpp" #include "types.hpp" -#include "ingen/Properties.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" +#include <ingen/Properties.hpp> +#include <raul/Path.hpp> #include <cstdint> #include <list> @@ -38,8 +37,6 @@ namespace server { class CompiledGraph; class Engine; class GraphImpl; -class PreProcessContext; -class RunContext; namespace events { @@ -55,7 +52,7 @@ public: int32_t id, SampleCount timestamp, raul::Path path, - const Properties& properties); + Properties properties); ~CreateGraph() override; @@ -72,9 +69,9 @@ private: const raul::Path _path; Properties _properties; ClientUpdate _update; - GraphImpl* _graph; - GraphImpl* _parent; - raul::managed_ptr<CompiledGraph> _compiled_graph; + GraphImpl* _graph{nullptr}; + GraphImpl* _parent{nullptr}; + std::unique_ptr<CompiledGraph> _compiled_graph; std::list<std::unique_ptr<Event>> _child_events; }; diff --git a/src/server/events/CreatePort.cpp b/src/server/events/CreatePort.cpp index 1fa2a528..b42542f8 100644 --- a/src/server/events/CreatePort.cpp +++ b/src/server/events/CreatePort.cpp @@ -23,31 +23,32 @@ #include "Engine.hpp" #include "GraphImpl.hpp" #include "PortImpl.hpp" - -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Node.hpp" -#include "ingen/Status.hpp" -#include "ingen/Store.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/paths.hpp" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "raul/Symbol.hpp" +#include "PortType.hpp" + +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Node.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Status.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/paths.hpp> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> #include <cassert> #include <map> #include <memory> +#include <string> #include <utility> -namespace ingen { -namespace server { -namespace events { +namespace ingen::server::events { CreatePort::CreatePort(Engine& engine, const std::shared_ptr<Interface>& client, @@ -57,20 +58,12 @@ CreatePort::CreatePort(Engine& engine, const Properties& properties) : Event(engine, client, id, timestamp) , _path(std::move(path)) - , _port_type(PortType::UNKNOWN) - , _buf_type(0) - , _graph(nullptr) - , _graph_port(nullptr) - , _engine_port(nullptr) , _properties(properties) { const ingen::URIs& uris = _engine.world().uris(); - using Iterator = Properties::const_iterator; - using Range = std::pair<Iterator, Iterator>; - - const Range types = properties.equal_range(uris.rdf_type); - for (Iterator i = types.first; i != types.second; ++i) { + const auto types = properties.equal_range(uris.rdf_type); + for (auto i = types.first; i != types.second; ++i) { const Atom& type = i->second; if (type == uris.lv2_AudioPort) { _port_type = PortType::AUDIO; @@ -87,8 +80,8 @@ CreatePort::CreatePort(Engine& engine, } } - const Range buffer_types = properties.equal_range(uris.atom_bufferType); - for (Iterator i = buffer_types.first; i != buffer_types.second; ++i) { + const auto buffer_types = properties.equal_range(uris.atom_bufferType); + for (auto i = buffer_types.first; i != buffer_types.second; ++i) { if (uris.forge.is_uri(i->second)) { _buf_type = _engine.world().uri_map().map_uri( uris.forge.str(i->second, false)); @@ -101,9 +94,13 @@ CreatePort::pre_process(PreProcessContext&) { if (_port_type == PortType::UNKNOWN || !_flow) { return Event::pre_process_done(Status::UNKNOWN_TYPE, _path); - } else if (_path.is_root()) { + } + + if (_path.is_root()) { return Event::pre_process_done(Status::BAD_URI, _path); - } else if (_engine.store()->get(_path)) { + } + + if (_engine.store()->get(_path)) { return Event::pre_process_done(Status::EXISTS, _path); } @@ -111,10 +108,14 @@ CreatePort::pre_process(PreProcessContext&) Node* const parent = _engine.store()->get(parent_path); if (!parent) { return Event::pre_process_done(Status::PARENT_NOT_FOUND, parent_path); - } else if (!(_graph = dynamic_cast<GraphImpl*>(parent))) { + } + + if (!(_graph = dynamic_cast<GraphImpl*>(parent))) { return Event::pre_process_done(Status::INVALID_PARENT, parent_path); - } else if (!_graph->parent() && _engine.activated() && - !_engine.driver()->dynamic_ports()) { + } + + if (!_graph->parent() && _engine.activated() && + !_engine.driver()->dynamic_ports()) { return Event::pre_process_done(Status::CREATION_FAILED, _path); } @@ -123,10 +124,8 @@ CreatePort::pre_process(PreProcessContext&) const uint32_t buf_size = bufs.default_size(_buf_type); const int32_t old_n_ports = _graph->num_ports_non_rt(); - using PropIter = Properties::const_iterator; - - PropIter index_i = _properties.find(uris.lv2_index); - int32_t index = 0; + auto index_i = _properties.find(uris.lv2_index); + int32_t index = 0; if (index_i != _properties.end()) { // Ensure given index is sane and not taken if (index_i->second.type() != uris.forge.Int) { @@ -144,7 +143,7 @@ CreatePort::pre_process(PreProcessContext&) _engine.world().forge().make(index)); } - const PropIter poly_i = _properties.find(uris.ingen_polyphonic); + const auto poly_i = _properties.find(uris.ingen_polyphonic); const bool polyphonic = (poly_i != _properties.end() && poly_i->second.type() == uris.forge.Bool && poly_i->second.get<int32_t>()); @@ -182,7 +181,7 @@ CreatePort::pre_process(PreProcessContext&) _update = _graph_port->properties(); assert(_graph_port->index() == static_cast<uint32_t>(index_i->second.get<int32_t>())); - assert(_graph->num_ports_non_rt() == static_cast<uint32_t>(old_n_ports) + 1u); + assert(_graph->num_ports_non_rt() == static_cast<uint32_t>(old_n_ports) + 1U); assert(_ports_array->size() == _graph->num_ports_non_rt()); assert(_graph_port->index() < _ports_array->size()); return Event::pre_process_done(Status::SUCCESS); @@ -213,7 +212,7 @@ CreatePort::execute(RunContext& ctx) void CreatePort::post_process() { - Broadcaster::Transfer t(*_engine.broadcaster()); + const Broadcaster::Transfer t{*_engine.broadcaster()}; if (respond() == Status::SUCCESS) { _engine.broadcaster()->put(path_to_uri(_path), _update); } @@ -225,6 +224,4 @@ CreatePort::undo(Interface& target) target.del(_graph_port->uri()); } -} // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server::events diff --git a/src/server/events/CreatePort.hpp b/src/server/events/CreatePort.hpp index 73746434..151bf82f 100644 --- a/src/server/events/CreatePort.hpp +++ b/src/server/events/CreatePort.hpp @@ -22,15 +22,14 @@ #include "PortType.hpp" #include "types.hpp" -#include "ingen/Properties.hpp" -#include "lv2/urid/urid.h" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" - -#include <boost/optional/optional.hpp> +#include <ingen/Properties.hpp> +#include <lv2/urid/urid.h> +#include <raul/Maid.hpp> +#include <raul/Path.hpp> #include <cstdint> #include <memory> +#include <optional> namespace ingen { @@ -42,8 +41,6 @@ class DuplexPort; class Engine; class EnginePort; class GraphImpl; -class PreProcessContext; -class RunContext; namespace events { @@ -73,15 +70,15 @@ private: }; raul::Path _path; - PortType _port_type; - LV2_URID _buf_type; - GraphImpl* _graph; - DuplexPort* _graph_port; + PortType _port_type{PortType::UNKNOWN}; + LV2_URID _buf_type{0}; + GraphImpl* _graph{nullptr}; + DuplexPort* _graph_port{nullptr}; raul::managed_ptr<BlockImpl::Ports> _ports_array; ///< New external port array for Graph - EnginePort* _engine_port; ///< Driver port if on the root + EnginePort* _engine_port{nullptr}; ///< Driver port if on the root Properties _properties; Properties _update; - boost::optional<Flow> _flow; + std::optional<Flow> _flow; }; } // namespace events diff --git a/src/server/events/Delete.cpp b/src/server/events/Delete.cpp index 3347b549..9e940ea7 100644 --- a/src/server/events/Delete.cpp +++ b/src/server/events/Delete.cpp @@ -30,31 +30,27 @@ #include "PortImpl.hpp" #include "PreProcessContext.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Node.hpp" -#include "ingen/Status.hpp" -#include "ingen/Store.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/paths.hpp" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/Node.hpp> +#include <ingen/Status.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/paths.hpp> +#include <raul/Array.hpp> +#include <raul/Path.hpp> #include <cassert> #include <cstddef> #include <memory> #include <mutex> #include <string> +#include <string_view> -namespace ingen { -namespace server { - -class RunContext; - -namespace events { +namespace ingen::server::events { Delete::Delete(Engine& engine, const std::shared_ptr<Interface>& client, @@ -62,8 +58,6 @@ Delete::Delete(Engine& engine, const ingen::Del& msg) : Event(engine, client, msg.seq, timestamp) , _msg(msg) - , _engine_port(nullptr) - , _disconnect_event(nullptr) { if (uri_is_path(msg.uri)) { _path = uri_to_path(msg.uri); @@ -72,7 +66,7 @@ Delete::Delete(Engine& engine, Delete::~Delete() { - for (ControlBindings::Binding* b : _removed_bindings) { + for (auto* b : _removed_bindings) { delete b; } } @@ -106,7 +100,7 @@ Delete::pre_process(PreProcessContext& ctx) } // Take a writer lock while we modify the store - std::lock_guard<Store::Mutex> lock(_engine.store()->mutex()); + const std::lock_guard<Store::Mutex> lock{_engine.store()->mutex()}; _engine.store()->remove(iter, _removed_objects); @@ -115,14 +109,14 @@ Delete::pre_process(PreProcessContext& ctx) _disconnect_event = std::make_unique<DisconnectAll>(_engine, parent, _block.get()); _disconnect_event->pre_process(ctx); - _compiled_graph = ctx.maybe_compile(*_engine.maid(), *parent); + _compiled_graph = ctx.maybe_compile(*parent); } else if (_port) { parent->remove_port(*_port); _disconnect_event = std::make_unique<DisconnectAll>(_engine, parent, _port.get()); _disconnect_event->pre_process(ctx); - _compiled_graph = ctx.maybe_compile(*_engine.maid(), *parent); + _compiled_graph = ctx.maybe_compile(*parent); if (parent->enabled()) { _ports_array = parent->build_ports_array(*_engine.maid()); assert(_ports_array->size() == parent->num_ports_non_rt()); @@ -184,14 +178,14 @@ Delete::execute(RunContext& ctx) } if (parent && _compiled_graph) { - parent->set_compiled_graph(std::move(_compiled_graph)); + _compiled_graph = parent->swap_compiled_graph(std::move(_compiled_graph)); } } void Delete::post_process() { - Broadcaster::Transfer t(*_engine.broadcaster()); + const Broadcaster::Transfer t{*_engine.broadcaster()}; if (respond() == Status::SUCCESS && (_block || _port)) { if (_block) { _block->deactivate(); @@ -227,12 +221,10 @@ Delete::undo(Interface& target) if (c.first != _msg.uri.path()) { target.set_property(path_to_uri(c.first), uris.lv2_index, - forge.make(int32_t(c.second.first))); + forge.make(static_cast<int32_t>(c.second.first))); } } } } -} // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server::events diff --git a/src/server/events/Delete.hpp b/src/server/events/Delete.hpp index 50a925b5..7e901f4b 100644 --- a/src/server/events/Delete.hpp +++ b/src/server/events/Delete.hpp @@ -17,35 +17,36 @@ #ifndef INGEN_EVENTS_DELETE_HPP #define INGEN_EVENTS_DELETE_HPP -#include "BlockImpl.hpp" #include "ControlBindings.hpp" #include "Event.hpp" #include "GraphImpl.hpp" #include "types.hpp" -#include "ingen/Message.hpp" -#include "ingen/Store.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" +#include <ingen/Message.hpp> +#include <ingen/Store.hpp> +#include <raul/Maid.hpp> +#include <raul/Path.hpp> #include <cstdint> #include <map> #include <memory> +#include <string> #include <utility> #include <vector> +// IWYU pragma: no_include <iterator> + namespace ingen { class Interface; namespace server { +class BlockImpl; class CompiledGraph; class DuplexPort; class Engine; class EnginePort; -class PreProcessContext; -class RunContext; namespace events { @@ -77,9 +78,9 @@ private: raul::Path _path; std::shared_ptr<BlockImpl> _block; ///< Non-null iff a block std::shared_ptr<DuplexPort> _port; ///< Non-null iff a port - EnginePort* _engine_port; + EnginePort* _engine_port{nullptr}; raul::managed_ptr<GraphImpl::Ports> _ports_array; ///< New (external) ports for Graph - raul::managed_ptr<CompiledGraph> _compiled_graph; ///< Graph's new process order + std::unique_ptr<CompiledGraph> _compiled_graph; ///< Graph's new process order std::unique_ptr<DisconnectAll> _disconnect_event; Store::Objects _removed_objects; IndexChanges _port_index_changes; diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp index b4d46fb9..cba21214 100644 --- a/src/server/events/Delta.cpp +++ b/src/server/events/Delta.cpp @@ -32,53 +32,43 @@ #include "PortType.hpp" #include "SetPortValue.hpp" -#include "ingen/Atom.hpp" -#include "ingen/FilePath.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/Message.hpp" -#include "ingen/Node.hpp" -#include "ingen/Status.hpp" -#include "ingen/Store.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/paths.hpp" -#include "lilv/lilv.h" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" - -#include <algorithm> -#include <map> +#include <ingen/Atom.hpp> +#include <ingen/FilePath.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Message.hpp> +#include <ingen/Node.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/Status.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/paths.hpp> +#include <lilv/lilv.h> +#include <raul/Path.hpp> + #include <memory> #include <mutex> #include <set> #include <string> +#include <string_view> #include <utility> #include <vector> -namespace ingen { -namespace server { - -class PreProcessContext; - -namespace events { +namespace ingen::server::events { Delta::Delta(Engine& engine, const std::shared_ptr<Interface>& client, SampleCount timestamp, const ingen::Put& msg) : Event(engine, client, msg.seq, timestamp) - , _create_event(nullptr) , _subject(msg.uri) , _properties(msg.properties) - , _object(nullptr) - , _graph(nullptr) - , _binding(nullptr) - , _state() , _context(msg.ctx) , _type(Type::PUT) - , _block(false) { init(); } @@ -92,13 +82,8 @@ Delta::Delta(Engine& engine, , _subject(msg.uri) , _properties(msg.add) , _remove(msg.remove) - , _object(nullptr) - , _graph(nullptr) - , _binding(nullptr) - , _state(nullptr) , _context(msg.ctx) , _type(Type::PATCH) - , _block(false) { init(); } @@ -110,13 +95,8 @@ Delta::Delta(Engine& engine, : Event(engine, client, msg.seq, timestamp) , _subject(msg.subject) , _properties{{msg.predicate, msg.value}} - , _object(nullptr) - , _graph(nullptr) - , _binding(nullptr) - , _state(nullptr) , _context(msg.ctx) , _type(Type::SET) - , _block(false) { init(); } @@ -172,12 +152,15 @@ get_file_node(LilvWorld* lworld, const URIs& uris, const Atom& value) { if (value.type() == uris.atom_Path) { return lilv_new_file_uri(lworld, nullptr, value.ptr<char>()); - } else if (uris.forge.is_uri(value)) { + } + + if (uris.forge.is_uri(value)) { const std::string str = uris.forge.str(value, false); if (str.substr(0, 5) == "file:") { return lilv_new_uri(lworld, value.ptr<char>()); } } + return nullptr; } @@ -222,12 +205,12 @@ Delta::pre_process(PreProcessContext& ctx) if ((_preset = block->save_preset(_subject, _properties))) { return Event::pre_process_done(Status::SUCCESS); - } else { - return Event::pre_process_done(Status::FAILURE); } + + return Event::pre_process_done(Status::FAILURE); } - std::lock_guard<Store::Mutex> lock(_engine.store()->mutex()); + const std::lock_guard<Store::Mutex> lock{_engine.store()->mutex()}; _object = is_graph_object ? static_cast<ingen::Resource*>(_engine.store()->get(uri_to_path(_subject))) @@ -239,7 +222,7 @@ Delta::pre_process(PreProcessContext& ctx) } if (is_graph_object && !_object) { - raul::Path path(uri_to_path(_subject)); + const raul::Path path{uri_to_path(_subject)}; bool is_graph = false; bool is_block = false; @@ -260,7 +243,7 @@ Delta::pre_process(PreProcessContext& ctx) } if (_create_event) { if (_create_event->pre_process(ctx)) { - _object = _engine.store()->get(path); // Get object for setting + _object = _engine.store()->get(path); // Get object for setting } else { return Event::pre_process_done(Status::CREATION_FAILED, _subject); } @@ -332,8 +315,8 @@ Delta::pre_process(PreProcessContext& ctx) const Property& value = p.second; SpecialType op = SpecialType::NONE; if (obj) { - Resource& resource = *obj; if (value != uris.patch_wildcard) { + Resource& resource = *obj; if (resource.add_property(key, value, value.context())) { _added.emplace(key, value); } @@ -372,7 +355,7 @@ Delta::pre_process(PreProcessContext& ctx) } } else if ((block = dynamic_cast<BlockImpl*>(_object))) { if (key == uris.midi_binding && value == uris.patch_wildcard) { - op = SpecialType::CONTROL_BINDING; // Internal block learn + op = SpecialType::CONTROL_BINDING; // Internal block learn } else if (key == uris.ingen_enabled) { if (value.type() == uris.forge.Bool) { op = SpecialType::ENABLE; @@ -409,9 +392,9 @@ Delta::pre_process(PreProcessContext& ctx) if (key == uris.ingen_enabled) { if (value.type() == uris.forge.Bool) { op = SpecialType::ENABLE; - // FIXME: defer this until all other metadata has been processed + // FIXME: defer until all other data has been processed if (value.get<int32_t>() && !_graph->enabled()) { - if (!(_compiled_graph = compile(*_engine.maid(), *_graph))) { + if (!(_compiled_graph = compile(*_graph))) { _status = Status::COMPILATION_FAILED; } } @@ -516,7 +499,7 @@ Delta::execute(RunContext& ctx) auto* const block = dynamic_cast<BlockImpl*>(_object); auto* const port = dynamic_cast<PortImpl*>(_object); - std::vector<SpecialType>::const_iterator t = _types.begin(); + auto t = _types.begin(); for (const auto& p : _properties) { const URI& key = p.first; const Atom& value = p.second; @@ -530,7 +513,7 @@ Delta::execute(RunContext& ctx) if (_graph) { if (value.get<int32_t>()) { if (_compiled_graph) { - _graph->set_compiled_graph(std::move(_compiled_graph)); + _compiled_graph = _graph->swap_compiled_graph(std::move(_compiled_graph)); } _graph->enable(); } else { @@ -608,18 +591,18 @@ Delta::post_process() _state.reset(); } - Broadcaster::Transfer t(*_engine.broadcaster()); + const Broadcaster::Transfer t{*_engine.broadcaster()}; if (_create_event) { _create_event->post_process(); if (_create_event->status() != Status::SUCCESS) { - return; // Creation failed, nothing else to do + return; // Creation failed, nothing else to do } } for (auto& s : _set_events) { if (s->synthetic() || s->status() != Status::SUCCESS) { - s->post_process(); // Set failed, report error + s->post_process(); // Set failed, report error } } @@ -687,6 +670,4 @@ Delta::get_execution() const return _block ? Execution::ATOMIC : Execution::NORMAL; } -} // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server::events diff --git a/src/server/events/Delta.hpp b/src/server/events/Delta.hpp index 726d8b48..befbdcc7 100644 --- a/src/server/events/Delta.hpp +++ b/src/server/events/Delta.hpp @@ -18,20 +18,20 @@ #define INGEN_EVENTS_DELTA_HPP #include "ClientUpdate.hpp" +#include "CompiledGraph.hpp" #include "ControlBindings.hpp" #include "Event.hpp" +#include "SetPortValue.hpp" #include "State.hpp" #include "types.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Resource.hpp" -#include "ingen/URI.hpp" -#include "raul/Maid.hpp" - -#include <boost/optional/optional.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> #include <cstdint> #include <memory> +#include <optional> #include <vector> namespace ingen { @@ -43,16 +43,11 @@ struct SetProperty; namespace server { -class CompiledGraph; class Engine; class GraphImpl; -class PreProcessContext; -class RunContext; namespace events { -class SetPortValue; - /** Set properties of a graph object. * \ingroup engine */ @@ -115,10 +110,10 @@ private: Properties _properties; Properties _remove; ClientUpdate _update; - ingen::Resource* _object; - GraphImpl* _graph; - raul::managed_ptr<CompiledGraph> _compiled_graph; - ControlBindings::Binding* _binding; + ingen::Resource* _object{nullptr}; + GraphImpl* _graph{nullptr}; + std::unique_ptr<CompiledGraph> _compiled_graph; + ControlBindings::Binding* _binding{nullptr}; StatePtr _state; Resource::Graph _context; Type _type; @@ -128,9 +123,9 @@ private: std::vector<ControlBindings::Binding*> _removed_bindings; - boost::optional<Resource> _preset; + std::optional<Resource> _preset; - bool _block; + bool _block{false}; }; } // namespace events diff --git a/src/server/events/Disconnect.cpp b/src/server/events/Disconnect.cpp index ea6bb8f0..7189fdd0 100644 --- a/src/server/events/Disconnect.cpp +++ b/src/server/events/Disconnect.cpp @@ -14,7 +14,7 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "events/Disconnect.hpp" +#include "Disconnect.hpp" #include "BlockImpl.hpp" #include "Broadcaster.hpp" @@ -30,14 +30,15 @@ #include "PreProcessContext.hpp" #include "ThreadManager.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Node.hpp" -#include "ingen/Status.hpp" -#include "ingen/Store.hpp" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/Node.hpp> +#include <ingen/Status.hpp> +#include <ingen/Store.hpp> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> +#include <raul/Path.hpp> #include <cassert> #include <cstdint> @@ -47,8 +48,7 @@ #include <string> #include <utility> -namespace ingen { -namespace server { +namespace ingen::server { class RunContext; @@ -60,9 +60,7 @@ Disconnect::Disconnect(Engine& engine, const ingen::Disconnect& msg) : Event(engine, client, msg.seq, timestamp) , _msg(msg) - , _graph(nullptr) -{ -} +{} Disconnect::~Disconnect() = default; @@ -120,7 +118,7 @@ Disconnect::Impl::Impl(Engine& e, bool Disconnect::pre_process(PreProcessContext& ctx) { - std::lock_guard<Store::Mutex> lock(_engine.store()->mutex()); + const std::lock_guard<Store::Mutex> lock{_engine.store()->mutex()}; if (_msg.tail.parent().parent() != _msg.head.parent().parent() && _msg.tail.parent() != _msg.head.parent().parent() @@ -159,7 +157,9 @@ Disconnect::pre_process(PreProcessContext& ctx) if (!_graph) { return Event::pre_process_done(Status::INTERNAL_ERROR, _msg.head); - } else if (!_graph->has_arc(tail, head)) { + } + + if (!_graph->has_arc(tail, head)) { return Event::pre_process_done(Status::NOT_FOUND, _msg.head); } @@ -169,10 +169,10 @@ Disconnect::pre_process(PreProcessContext& ctx) _impl = std::make_unique<Impl>(_engine, _graph, - dynamic_cast<PortImpl*>(tail), + tail, dynamic_cast<InputPort*>(head)); - _compiled_graph = ctx.maybe_compile(*_engine.maid(), *_graph); + _compiled_graph = ctx.maybe_compile(*_graph); return Event::pre_process_done(Status::SUCCESS); } @@ -209,7 +209,8 @@ Disconnect::execute(RunContext& ctx) if (_status == Status::SUCCESS) { if (_impl->execute(ctx, true)) { if (_compiled_graph) { - _graph->set_compiled_graph(std::move(_compiled_graph)); + _compiled_graph = + _graph->swap_compiled_graph(std::move(_compiled_graph)); } } else { _status = Status::NOT_FOUND; @@ -220,7 +221,7 @@ Disconnect::execute(RunContext& ctx) void Disconnect::post_process() { - Broadcaster::Transfer t(*_engine.broadcaster()); + const Broadcaster::Transfer t{*_engine.broadcaster()}; if (respond() == Status::SUCCESS) { _engine.broadcaster()->message(_msg); } @@ -233,5 +234,4 @@ Disconnect::undo(Interface& target) } } // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/events/Disconnect.hpp b/src/server/events/Disconnect.hpp index a835ed27..92dd81d3 100644 --- a/src/server/events/Disconnect.hpp +++ b/src/server/events/Disconnect.hpp @@ -21,8 +21,8 @@ #include "PortImpl.hpp" #include "types.hpp" -#include "ingen/Message.hpp" -#include "raul/Maid.hpp" +#include <ingen/Message.hpp> +#include <raul/Maid.hpp> #include <memory> @@ -37,7 +37,6 @@ class CompiledGraph; class Engine; class GraphImpl; class InputPort; -class PreProcessContext; class RunContext; namespace events { @@ -61,14 +60,15 @@ public: void post_process() override; void undo(Interface& target) override; - class Impl { + class Impl + { public: Impl(Engine& e, GraphImpl* graph, PortImpl* t, InputPort* h); bool execute(RunContext& ctx, bool set_head_buffers); - inline PortImpl* tail() { return _tail; } - inline InputPort* head() { return _head; } + PortImpl* tail() { return _tail; } + InputPort* head() { return _head; } private: Engine& _engine; @@ -80,9 +80,9 @@ public: private: const ingen::Disconnect _msg; - GraphImpl* _graph; + GraphImpl* _graph{nullptr}; std::unique_ptr<Impl> _impl; - raul::managed_ptr<CompiledGraph> _compiled_graph; + std::unique_ptr<CompiledGraph> _compiled_graph; }; } // namespace events diff --git a/src/server/events/DisconnectAll.cpp b/src/server/events/DisconnectAll.cpp index 35254ba0..8e7bfbbe 100644 --- a/src/server/events/DisconnectAll.cpp +++ b/src/server/events/DisconnectAll.cpp @@ -14,35 +14,35 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "events/DisconnectAll.hpp" +#include "DisconnectAll.hpp" #include "ArcImpl.hpp" #include "BlockImpl.hpp" #include "Broadcaster.hpp" #include "CompiledGraph.hpp" +#include "Disconnect.hpp" #include "Engine.hpp" #include "GraphImpl.hpp" #include "InputPort.hpp" #include "NodeImpl.hpp" #include "PortImpl.hpp" #include "PreProcessContext.hpp" -#include "events/Disconnect.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Node.hpp" -#include "ingen/Status.hpp" -#include "ingen/Store.hpp" -#include "raul/Maid.hpp" +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/Node.hpp> +#include <ingen/Status.hpp> +#include <ingen/Store.hpp> +#include <raul/Path.hpp> -#include <map> +#include <algorithm> +#include <iterator> #include <memory> #include <mutex> #include <set> #include <utility> -namespace ingen { -namespace server { -namespace events { +namespace ingen::server::events { DisconnectAll::DisconnectAll(Engine& engine, const std::shared_ptr<Interface>& client, @@ -54,8 +54,7 @@ DisconnectAll::DisconnectAll(Engine& engine, , _block(nullptr) , _port(nullptr) , _deleting(false) -{ -} +{} /** Internal version for use by other events. */ @@ -68,12 +67,11 @@ DisconnectAll::DisconnectAll(Engine& engine, , _block(dynamic_cast<BlockImpl*>(object)) , _port(dynamic_cast<PortImpl*>(object)) , _deleting(true) -{ -} +{} DisconnectAll::~DisconnectAll() { - for (auto& i : _impls) { + for (auto* i : _impls) { delete i; } } @@ -114,28 +112,35 @@ DisconnectAll::pre_process(PreProcessContext& ctx) } // Create disconnect events to erase adjacent arcs in parent - for (const auto& a : adjacent_arcs(_parent)) { - _impls.push_back( - new Disconnect::Impl(_engine, - _parent, - dynamic_cast<PortImpl*>(a->tail()), - dynamic_cast<InputPort*>(a->head()))); - } + const auto& arcs = adjacent_arcs(_parent); + std::transform(arcs.begin(), + arcs.end(), + std::back_inserter(_impls), + [this](const auto& a) { + return new Disconnect::Impl(_engine, + _parent, + a->tail(), + dynamic_cast<InputPort*>(a->head())); + }); // Create disconnect events to erase adjacent arcs in parent's parent if (_port && _parent->parent()) { - GraphImpl* parent_parent = dynamic_cast<GraphImpl*>(_parent->parent()); - for (const auto& a : adjacent_arcs(parent_parent)) { - _impls.push_back( - new Disconnect::Impl(_engine, - parent_parent, - dynamic_cast<PortImpl*>(a->tail()), - dynamic_cast<InputPort*>(a->head()))); - } + auto* const grandparent = dynamic_cast<GraphImpl*>(_parent->parent()); + const auto& parent_arcs = adjacent_arcs(grandparent); + + std::transform(parent_arcs.begin(), + parent_arcs.end(), + std::back_inserter(_impls), + [this, grandparent](const auto& a) { + return new Disconnect::Impl(_engine, + grandparent, + a->tail(), + dynamic_cast<InputPort*>(a->head())); + }); } if (!_deleting && ctx.must_compile(*_parent)) { - if (!(_compiled_graph = compile(*_engine.maid(), *_parent))) { + if (!(_compiled_graph = compile(*_parent))) { return Event::pre_process_done(Status::COMPILATION_FAILED); } } @@ -154,14 +159,14 @@ DisconnectAll::execute(RunContext& ctx) } if (_compiled_graph) { - _parent->set_compiled_graph(std::move(_compiled_graph)); + _compiled_graph = _parent->swap_compiled_graph(std::move(_compiled_graph)); } } void DisconnectAll::post_process() { - Broadcaster::Transfer t(*_engine.broadcaster()); + const Broadcaster::Transfer t{*_engine.broadcaster()}; if (respond() == Status::SUCCESS) { _engine.broadcaster()->message(_msg); } @@ -196,6 +201,4 @@ DisconnectAll::adjacent_arcs(GraphImpl* const graph) return arcs; } -} // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server::events diff --git a/src/server/events/DisconnectAll.hpp b/src/server/events/DisconnectAll.hpp index 70da5dd6..0eeda6f8 100644 --- a/src/server/events/DisconnectAll.hpp +++ b/src/server/events/DisconnectAll.hpp @@ -21,8 +21,7 @@ #include "Event.hpp" #include "types.hpp" -#include "ingen/Message.hpp" -#include "raul/Maid.hpp" +#include <ingen/Message.hpp> #include <list> #include <memory> @@ -41,8 +40,6 @@ class CompiledGraph; class Engine; class GraphImpl; class PortImpl; -class PreProcessContext; -class RunContext; namespace events { @@ -79,7 +76,7 @@ private: BlockImpl* _block; PortImpl* _port; Impls _impls; - raul::managed_ptr<CompiledGraph> _compiled_graph; + std::unique_ptr<CompiledGraph> _compiled_graph; bool _deleting; }; diff --git a/src/server/events/Get.cpp b/src/server/events/Get.cpp index 219af6fe..45e7ea94 100644 --- a/src/server/events/Get.cpp +++ b/src/server/events/Get.cpp @@ -22,24 +22,24 @@ #include "GraphImpl.hpp" #include "PortImpl.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Node.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Status.hpp" -#include "ingen/Store.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/paths.hpp" +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/Node.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Status.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/paths.hpp> #include <cstdint> #include <memory> #include <mutex> +#include <utility> -namespace ingen { -namespace server { -namespace events { +namespace ingen::server::events { Get::Get(Engine& engine, const std::shared_ptr<Interface>& client, @@ -47,22 +47,24 @@ Get::Get(Engine& engine, const ingen::Get& msg) : Event(engine, client, msg.seq, timestamp) , _msg(msg) - , _object(nullptr) - , _plugin(nullptr) {} bool Get::pre_process(PreProcessContext&) { - std::lock_guard<Store::Mutex> lock(_engine.store()->mutex()); + const std::lock_guard<Store::Mutex> lock{_engine.store()->mutex()}; const auto& uri = _msg.subject; if (uri == "ingen:/plugins") { _plugins = _engine.block_factory()->plugins(); return Event::pre_process_done(Status::SUCCESS); - } else if (uri == "ingen:/engine") { + } + + if (uri == "ingen:/engine") { return Event::pre_process_done(Status::SUCCESS); - } else if (uri_is_path(uri)) { + } + + if (uri_is_path(uri)) { if ((_object = _engine.store()->get(uri_to_path(uri)))) { const BlockImpl* block = nullptr; const GraphImpl* graph = nullptr; @@ -79,23 +81,24 @@ Get::pre_process(PreProcessContext&) return Event::pre_process_done(Status::SUCCESS); } return Event::pre_process_done(Status::NOT_FOUND, uri); - } else if ((_plugin = _engine.block_factory()->plugin(uri))) { + } + + if ((_plugin = _engine.block_factory()->plugin(uri))) { _response.put_plugin(_plugin); return Event::pre_process_done(Status::SUCCESS); - } else { - return Event::pre_process_done(Status::NOT_FOUND, uri); } + + return Event::pre_process_done(Status::NOT_FOUND, uri); } void Get::execute(RunContext&) -{ -} +{} void Get::post_process() { - Broadcaster::Transfer t(*_engine.broadcaster()); + const Broadcaster::Transfer t{*_engine.broadcaster()}; if (respond() == Status::SUCCESS && _request_client) { if (_msg.subject == "ingen:/plugins") { _engine.broadcaster()->send_plugins_to(_request_client.get(), _plugins); @@ -104,11 +107,11 @@ Get::post_process() URIs& uris = _engine.world().uris(); Properties props = { { uris.param_sampleRate, - uris.forge.make(int32_t(_engine.sample_rate())) }, + uris.forge.make(static_cast<int32_t>(_engine.sample_rate())) }, { uris.bufsz_maxBlockLength, - uris.forge.make(int32_t(_engine.block_length())) }, + uris.forge.make(static_cast<int32_t>(_engine.block_length())) }, { uris.ingen_numThreads, - uris.forge.make(int32_t(_engine.n_threads())) } }; + uris.forge.make(static_cast<int32_t>(_engine.n_threads())) } }; const Properties load_props = _engine.load_properties(); props.insert(load_props.begin(), load_props.end()); @@ -119,6 +122,4 @@ Get::post_process() } } -} // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server::events diff --git a/src/server/events/Get.hpp b/src/server/events/Get.hpp index fd3f8569..0f5ed235 100644 --- a/src/server/events/Get.hpp +++ b/src/server/events/Get.hpp @@ -17,7 +17,7 @@ #ifndef INGEN_EVENTS_GET_HPP #define INGEN_EVENTS_GET_HPP -#include "ingen/Message.hpp" +#include <ingen/Message.hpp> #include "BlockFactory.hpp" #include "ClientUpdate.hpp" @@ -35,8 +35,6 @@ namespace server { class Engine; class PluginImpl; -class PreProcessContext; -class RunContext; namespace events { @@ -58,8 +56,8 @@ public: private: const ingen::Get _msg; - const Node* _object; - PluginImpl* _plugin; + const Node* _object{nullptr}; + PluginImpl* _plugin{nullptr}; BlockFactory::Plugins _plugins; ClientUpdate _response; }; diff --git a/src/server/events/Mark.cpp b/src/server/events/Mark.cpp index 27ca6630..b60b0432 100644 --- a/src/server/events/Mark.cpp +++ b/src/server/events/Mark.cpp @@ -14,10 +14,7 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "events/Mark.hpp" - -#include "ingen/Message.hpp" -#include "ingen/Status.hpp" +#include "Mark.hpp" #include "CompiledGraph.hpp" #include "Engine.hpp" @@ -25,14 +22,15 @@ #include "PreProcessContext.hpp" #include "UndoStack.hpp" +#include <ingen/Message.hpp> +#include <ingen/Status.hpp> + #include <cassert> #include <memory> #include <unordered_set> #include <utility> -namespace ingen { -namespace server { -namespace events { +namespace ingen::server::events { Mark::Mark(Engine& engine, const std::shared_ptr<Interface>& client, @@ -86,7 +84,7 @@ Mark::pre_process(PreProcessContext& ctx) ctx.set_in_bundle(false); if (!ctx.dirty_graphs().empty()) { for (GraphImpl* g : ctx.dirty_graphs()) { - auto cg = compile(*_engine.maid(), *g); + auto cg = compile(*g); if (cg) { _compiled_graphs.emplace(g, std::move(cg)); } @@ -103,7 +101,7 @@ void Mark::execute(RunContext&) { for (auto& g : _compiled_graphs) { - g.first->set_compiled_graph(std::move(g.second)); + g.second = g.first->swap_compiled_graph(std::move(g.second)); } } @@ -136,6 +134,4 @@ Mark::get_execution() const return Execution::NORMAL; } -} // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server::events diff --git a/src/server/events/Mark.hpp b/src/server/events/Mark.hpp index 7ebab080..e7180764 100644 --- a/src/server/events/Mark.hpp +++ b/src/server/events/Mark.hpp @@ -17,11 +17,10 @@ #ifndef INGEN_EVENTS_MARK_HPP #define INGEN_EVENTS_MARK_HPP +#include "CompiledGraph.hpp" #include "Event.hpp" #include "types.hpp" -#include "raul/Maid.hpp" - #include <map> #include <memory> @@ -33,11 +32,8 @@ struct BundleEnd; namespace server { -class CompiledGraph; class Engine; class GraphImpl; -class PreProcessContext; -class RunContext; namespace events { @@ -73,8 +69,7 @@ public: private: enum class Type { BUNDLE_BEGIN, BUNDLE_END }; - using CompiledGraphs = - std::map<GraphImpl*, raul::managed_ptr<CompiledGraph>>; + using CompiledGraphs = std::map<GraphImpl*, std::unique_ptr<CompiledGraph>>; CompiledGraphs _compiled_graphs; Type _type; diff --git a/src/server/events/Move.cpp b/src/server/events/Move.cpp index d85451c8..80ae5a11 100644 --- a/src/server/events/Move.cpp +++ b/src/server/events/Move.cpp @@ -14,22 +14,23 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include "Move.hpp" + #include "Broadcaster.hpp" #include "Driver.hpp" #include "Engine.hpp" -#include "events/Move.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Status.hpp" -#include "ingen/Store.hpp" -#include "raul/Path.hpp" +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/Status.hpp> +#include <ingen/Store.hpp> +#include <raul/Path.hpp> #include <map> #include <memory> #include <mutex> -namespace ingen { -namespace server { +namespace ingen::server { class EnginePort; @@ -41,19 +42,18 @@ Move::Move(Engine& engine, const ingen::Move& msg) : Event(engine, client, msg.seq, timestamp) , _msg(msg) -{ -} +{} bool Move::pre_process(PreProcessContext&) { - std::lock_guard<Store::Mutex> lock(_engine.store()->mutex()); + const std::lock_guard<Store::Mutex> lock{_engine.store()->mutex()}; if (!_msg.old_path.parent().is_parent_of(_msg.new_path)) { return Event::pre_process_done(Status::PARENT_DIFFERS, _msg.new_path); } - const Store::iterator i = _engine.store()->find(_msg.old_path); + const auto i = _engine.store()->find(_msg.old_path); if (i == _engine.store()->end()) { return Event::pre_process_done(Status::NOT_FOUND, _msg.old_path); } @@ -74,13 +74,12 @@ Move::pre_process(PreProcessContext&) void Move::execute(RunContext&) -{ -} +{} void Move::post_process() { - Broadcaster::Transfer t(*_engine.broadcaster()); + const Broadcaster::Transfer t{*_engine.broadcaster()}; if (respond() == Status::SUCCESS) { _engine.broadcaster()->message(_msg); } @@ -93,5 +92,4 @@ Move::undo(Interface& target) } } // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/events/Move.hpp b/src/server/events/Move.hpp index 3940e825..cca4d310 100644 --- a/src/server/events/Move.hpp +++ b/src/server/events/Move.hpp @@ -20,7 +20,7 @@ #include "Event.hpp" #include "types.hpp" -#include "ingen/Message.hpp" +#include <ingen/Message.hpp> #include <memory> @@ -31,8 +31,6 @@ class Interface; namespace server { class Engine; -class PreProcessContext; -class RunContext; namespace events { diff --git a/src/server/events/SetPortValue.cpp b/src/server/events/SetPortValue.cpp index a1b5bafa..ba6859dd 100644 --- a/src/server/events/SetPortValue.cpp +++ b/src/server/events/SetPortValue.cpp @@ -24,18 +24,17 @@ #include "PortImpl.hpp" #include "RunContext.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Status.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "lv2/atom/atom.h" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Status.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <lv2/atom/atom.h> #include <cassert> #include <memory> -namespace ingen { -namespace server { -namespace events { +namespace ingen::server::events { /** Internal */ SetPortValue::SetPortValue(Engine& engine, @@ -51,13 +50,12 @@ SetPortValue::SetPortValue(Engine& engine, , _value(value) , _activity(activity) , _synthetic(synthetic) -{ -} +{} bool SetPortValue::pre_process(PreProcessContext&) { - ingen::URIs& uris = _engine.world().uris(); + const ingen::URIs& uris = _engine.world().uris(); if (_port->is_output()) { return Event::pre_process_done(Status::DIRECTION_MISMATCH, _port->path()); } @@ -95,8 +93,8 @@ SetPortValue::apply(RunContext& ctx) return; } - ingen::URIs& uris = _engine.world().uris(); - Buffer* buf = _port->buffer(0).get(); + const ingen::URIs& uris = _engine.world().uris(); + Buffer* buf = _port->buffer(0).get(); if (_buffer) { if (_port->user_buffer(ctx)) { @@ -130,7 +128,7 @@ SetPortValue::apply(RunContext& ctx) void SetPortValue::post_process() { - Broadcaster::Transfer t(*_engine.broadcaster()); + const Broadcaster::Transfer t{*_engine.broadcaster()}; if (respond() == Status::SUCCESS && !_activity) { _engine.broadcaster()->set_property( _port->uri(), @@ -139,6 +137,4 @@ SetPortValue::post_process() } } -} // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server::events diff --git a/src/server/events/SetPortValue.hpp b/src/server/events/SetPortValue.hpp index 69d742b8..32a8b761 100644 --- a/src/server/events/SetPortValue.hpp +++ b/src/server/events/SetPortValue.hpp @@ -22,7 +22,7 @@ #include "Event.hpp" #include "types.hpp" -#include "ingen/Atom.hpp" +#include <ingen/Atom.hpp> #include <cstdint> #include <memory> @@ -35,7 +35,6 @@ namespace server { class Engine; class PortImpl; -class PreProcessContext; class RunContext; namespace events { diff --git a/src/server/events/Undo.cpp b/src/server/events/Undo.cpp index 3c91235d..db7c1c86 100644 --- a/src/server/events/Undo.cpp +++ b/src/server/events/Undo.cpp @@ -19,18 +19,16 @@ #include "Engine.hpp" #include "EventWriter.hpp" -#include "ingen/AtomReader.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Message.hpp" -#include "ingen/Status.hpp" -#include "lv2/atom/atom.h" +#include <ingen/AtomReader.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Message.hpp> +#include <ingen/Status.hpp> +#include <lv2/atom/atom.h> #include <deque> #include <memory> -namespace ingen { -namespace server { -namespace events { +namespace ingen::server::events { Undo::Undo(Engine& engine, const std::shared_ptr<Interface>& client, @@ -81,8 +79,7 @@ Undo::pre_process(PreProcessContext&) void Undo::execute(RunContext&) -{ -} +{} void Undo::post_process() @@ -90,6 +87,4 @@ Undo::post_process() respond(); } -} // namespace events -} // namespace server -} // namespace ingen +} // namespace ingen::server::events diff --git a/src/server/events/Undo.hpp b/src/server/events/Undo.hpp index eb9cb70a..818dc754 100644 --- a/src/server/events/Undo.hpp +++ b/src/server/events/Undo.hpp @@ -32,8 +32,6 @@ struct Undo; namespace server { class Engine; -class PreProcessContext; -class RunContext; namespace events { diff --git a/src/server/ingen_engine.cpp b/src/server/ingen_engine.cpp index a5735f33..48955143 100644 --- a/src/server/ingen_engine.cpp +++ b/src/server/ingen_engine.cpp @@ -14,13 +14,11 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -// IWYU pragma: no_include "ingen/Atom.hpp" - #include "Engine.hpp" #include "util.hpp" -#include "ingen/Module.hpp" -#include "ingen/World.hpp" +#include <ingen/Module.hpp> +#include <ingen/World.hpp> #include <memory> @@ -41,7 +39,7 @@ struct EngineModule : public Module { extern "C" { -ingen::Module* +INGEN_MODULE_EXPORT ingen::Module* ingen_module_load() { return new ingen::EngineModule(); diff --git a/src/server/ingen_jack.cpp b/src/server/ingen_jack.cpp index 97d72919..16369d0c 100644 --- a/src/server/ingen_jack.cpp +++ b/src/server/ingen_jack.cpp @@ -17,17 +17,16 @@ #include "Engine.hpp" #include "JackDriver.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Log.hpp" -#include "ingen/Module.hpp" -#include "ingen/World.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Log.hpp> +#include <ingen/Module.hpp> +#include <ingen/World.hpp> #include <memory> #include <string> -namespace ingen { -namespace server { +namespace ingen::server { class Driver; @@ -53,12 +52,11 @@ struct JackModule : public Module { } }; -} // namespace server -} // namespace ingen +} // namespace ingen::server extern "C" { -ingen::Module* +INGEN_MODULE_EXPORT ingen::Module* ingen_module_load() { return new ingen::server::JackModule(); diff --git a/src/server/ingen_lv2.cpp b/src/server/ingen_lv2.cpp index 90b9d944..658f759b 100644 --- a/src/server/ingen_lv2.cpp +++ b/src/server/ingen_lv2.cpp @@ -15,7 +15,6 @@ */ #include "Buffer.hpp" -#include "BufferRef.hpp" #include "Driver.hpp" #include "DuplexPort.hpp" #include "Engine.hpp" @@ -26,46 +25,47 @@ #include "ThreadManager.hpp" #include "types.hpp" -#include "ingen/AtomReader.hpp" -#include "ingen/AtomSink.hpp" -#include "ingen/AtomWriter.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/EngineBase.hpp" -#include "ingen/FilePath.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/Node.hpp" -#include "ingen/Parser.hpp" -#include "ingen/Serialiser.hpp" -#include "ingen/Store.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/ingen.h" -#include "ingen/memory.hpp" -#include "ingen/runtime_paths.hpp" -#include "lv2/atom/atom.h" -#include "lv2/atom/util.h" -#include "lv2/buf-size/buf-size.h" -#include "lv2/core/lv2.h" -#include "lv2/log/log.h" -#include "lv2/log/logger.h" -#include "lv2/options/options.h" -#include "lv2/state/state.h" -#include "lv2/urid/urid.h" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "raul/RingBuffer.hpp" -#include "raul/Semaphore.hpp" -#include "raul/Symbol.hpp" -#include "serd/serd.h" -#include "sord/sordmm.hpp" +#include <ingen/AtomReader.hpp> +#include <ingen/AtomSink.hpp> +#include <ingen/AtomWriter.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/EngineBase.hpp> +#include <ingen/FilePath.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Node.hpp> +#include <ingen/Parser.hpp> +#include <ingen/Serialiser.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/ingen.h> +#include <ingen/memory.hpp> +#include <ingen/runtime_paths.hpp> +#include <lv2/atom/atom.h> +#include <lv2/atom/util.h> +#include <lv2/buf-size/buf-size.h> +#include <lv2/core/lv2.h> +#include <lv2/log/log.h> +#include <lv2/log/logger.h> +#include <lv2/options/options.h> +#include <lv2/state/state.h> +#include <lv2/urid/urid.h> +#include <raul/Maid.hpp> +#include <raul/Path.hpp> +#include <raul/RingBuffer.hpp> +#include <raul/Semaphore.hpp> +#include <raul/Symbol.hpp> +#include <serd/serd.h> +#include <sord/sordmm.hpp> #include <algorithm> #include <cstdint> #include <cstdlib> #include <cstring> +#include <iterator> #include <memory> #include <mutex> #include <set> @@ -74,11 +74,9 @@ #include <utility> #include <vector> -namespace ingen { +// #define CLEAR_GRAPH_ON_RESTORE 1 -class Atom; - -namespace server { +namespace ingen::server { class GraphImpl; @@ -90,7 +88,8 @@ struct LV2Graph : public Parser::ResourceRecord { }; /** Ingen LV2 library. */ -class Lib { +class Lib +{ public: explicit Lib(const char* bundle_path); @@ -99,19 +98,23 @@ public: Graphs graphs; }; +namespace { + inline size_t ui_ring_size(SampleCount block_length) { - return std::max(static_cast<size_t>(8192u), - static_cast<size_t>(block_length) * 16u); + return std::max(static_cast<size_t>(8192U), + static_cast<size_t>(block_length) * 16U); } +} // namespace + class LV2Driver : public Driver, public ingen::AtomSink { public: LV2Driver(Engine& engine, SampleCount block_length, - size_t seq_size, + uint32_t seq_size, SampleCount sample_rate) : _engine(engine) , _main_sem(0) @@ -124,15 +127,9 @@ public: *this) , _from_ui(ui_ring_size(block_length)) , _to_ui(ui_ring_size(block_length)) - , _root_graph(nullptr) - , _notify_capacity(0) , _block_length(block_length) , _seq_size(seq_size) , _sample_rate(sample_rate) - , _frame_time(0) - , _to_ui_overflow_sem(0) - , _to_ui_overflow(false) - , _instantiated(false) {} bool dynamic_ports() const override { return !_instantiated; } @@ -151,11 +148,11 @@ public: lv2_atom_total_size( static_cast<LV2_Atom*>(lv2_buf))); - if (graph_port->symbol() == "control") { // TODO: Safe to use index? + if (graph_port->symbol() == "control") { // TODO: Safe to use index? auto* seq = reinterpret_cast<LV2_Atom_Sequence*>(lv2_buf); bool enqueued = false; - LV2_ATOM_SEQUENCE_FOREACH(seq, ev) + LV2_ATOM_SEQUENCE_FOREACH (seq, ev) { if (AtomReader::is_message(uris, &ev->body)) { enqueued = enqueue_message(&ev->body) || enqueued; @@ -220,13 +217,12 @@ public: virtual GraphImpl* root_graph() { return _root_graph; } EnginePort* get_port(const raul::Path& path) override { - for (auto& p : _ports) { - if (p->graph_port()->path() == path) { - return p; - } - } + const auto i = + std::find_if(_ports.begin(), _ports.end(), [&path](const auto& p) { + return p->graph_port()->path() == path; + }); - return nullptr; + return i == _ports.end() ? nullptr : *i; } /** Add a port. Called only during init or restore. */ @@ -268,7 +264,7 @@ public: const URIs& uris = _engine.world().uris(); auto* seq = static_cast<LV2_Atom_Sequence*>(_ports[0]->buffer()); - LV2_ATOM_SEQUENCE_FOREACH(seq, ev) { + LV2_ATOM_SEQUENCE_FOREACH (seq, ev) { if (ev->body.type == uris.atom_Object) { const LV2_Atom_Object* obj = reinterpret_cast<LV2_Atom_Object*>(&ev->body); @@ -322,7 +318,13 @@ public: break; } - buf = realloc(buf, sizeof(LV2_Atom) + atom.size); + void* const new_buf = realloc(buf, sizeof(LV2_Atom) + atom.size); + if (!new_buf) { + _engine.log().rt_error("Failed to allocate for from-UI ring\n"); + break; + } + + buf = new_buf; memcpy(buf, &atom, sizeof(LV2_Atom)); if (!_from_ui.read(atom.size, @@ -365,14 +367,14 @@ public: if (seq->atom.size + lv2_atom_pad_size( sizeof(LV2_Atom_Event) + atom.size) > _notify_capacity) { - break; // Output port buffer full, resume next time + break; // Output port buffer full, resume next time } auto* ev = reinterpret_cast<LV2_Atom_Event*>( reinterpret_cast<uint8_t*>(seq) + lv2_atom_total_size(&seq->atom)); - ev->time.frames = 0; // TODO: Time? + ev->time.frames = 0; // TODO: Time? ev->body = atom; _to_ui.skip(sizeof(LV2_Atom)); @@ -392,7 +394,7 @@ public: } SampleCount block_length() const override { return _block_length; } - size_t seq_size() const override { return _seq_size; } + uint32_t seq_size() const override { return _seq_size; } SampleCount sample_rate() const override { return _sample_rate; } SampleCount frame_time() const override { return _frame_time; } @@ -413,15 +415,15 @@ private: AtomWriter _writer; raul::RingBuffer _from_ui; raul::RingBuffer _to_ui; - GraphImpl* _root_graph; - uint32_t _notify_capacity; + GraphImpl* _root_graph{nullptr}; + uint32_t _notify_capacity{0}; SampleCount _block_length; - size_t _seq_size; + uint32_t _seq_size; SampleCount _sample_rate; - SampleCount _frame_time; - raul::Semaphore _to_ui_overflow_sem; - bool _to_ui_overflow; - bool _instantiated; + SampleCount _frame_time{0}; + raul::Semaphore _to_ui_overflow_sem{0}; + bool _to_ui_overflow{false}; + bool _instantiated{false}; }; struct IngenPlugin { @@ -465,9 +467,10 @@ find_graphs(const URI& manifest_uri) URI(INGEN__Graph)); Lib::Graphs graphs; - for (const auto& r : resources) { - graphs.push_back(std::make_shared<LV2Graph>(r)); - } + std::transform(resources.begin(), + resources.end(), + std::back_inserter(graphs), + [](const auto& r) { return std::make_shared<LV2Graph>(r); }); return graphs; } @@ -501,7 +504,9 @@ ingen_instantiate(const LV2_Descriptor* descriptor, if (!map) { lv2_log_error(&logger, "host did not provide URI map feature\n"); return nullptr; - } else if (!unmap) { + } + + if (!unmap) { lv2_log_error(&logger, "host did not provide URI unmap feature\n"); return nullptr; } @@ -515,16 +520,16 @@ ingen_instantiate(const LV2_Descriptor* descriptor, nullptr, true); - Lib::Graphs graphs = find_graphs(URI(reinterpret_cast<const char*>(manifest_node.buf))); + const Lib::Graphs graphs = find_graphs(URI(reinterpret_cast<const char*>(manifest_node.buf))); serd_node_free(&manifest_node); - const LV2Graph* graph = nullptr; - for (const auto& g : graphs) { - if (g->uri == descriptor->URI) { - graph = g.get(); - break; - } - } + const auto g = std::find_if(graphs.begin(), + graphs.end(), + [&descriptor](const auto& graph) { + return graph->uri == descriptor->URI; + }); + + const LV2Graph* const graph = g == graphs.end() ? nullptr : g->get(); if (!graph) { lv2_log_error(&logger, "could not find graph <%s>\n", descriptor->URI); @@ -536,11 +541,11 @@ ingen_instantiate(const LV2_Descriptor* descriptor, plugin->world = std::make_unique<ingen::World>(map, unmap, log); plugin->world->load_configuration(plugin->argc, plugin->argv); - LV2_URID bufsz_max = map->map(map->handle, LV2_BUF_SIZE__maxBlockLength); - LV2_URID bufsz_seq = map->map(map->handle, LV2_BUF_SIZE__sequenceSize); - LV2_URID atom_Int = map->map(map->handle, LV2_ATOM__Int); - int32_t block_length = 0; - int32_t seq_size = 0; + const LV2_URID bufsz_max = map->map(map->handle, LV2_BUF_SIZE__maxBlockLength); + const LV2_URID bufsz_seq = map->map(map->handle, LV2_BUF_SIZE__sequenceSize); + const LV2_URID atom_Int = map->map(map->handle, LV2_ATOM__Int); + int32_t block_length = 0; + int32_t seq_size = 0; if (options) { for (const LV2_Options_Option* o = options; o->key; ++o) { if (o->key == bufsz_max && o->type == atom_Int) { @@ -554,7 +559,7 @@ ingen_instantiate(const LV2_Descriptor* descriptor, block_length = 4096; plugin->world->log().warn("No maximum block length given\n"); } - if (seq_size == 0) { + if (seq_size < 1) { seq_size = 16384; plugin->world->log().warn("No maximum sequence size given\n"); } @@ -570,20 +575,21 @@ ingen_instantiate(const LV2_Descriptor* descriptor, plugin->engine = engine; plugin->world->set_engine(engine); - std::shared_ptr<Interface> interface = engine->interface(); + const std::shared_ptr<Interface> interface = engine->interface(); plugin->world->set_interface(interface); ThreadManager::set_flag(THREAD_PRE_PROCESS); ThreadManager::single_threaded = true; - auto* driver = new LV2Driver(*engine, block_length, seq_size, rate); + auto* driver = new LV2Driver( + *engine, block_length, static_cast<uint32_t>(seq_size), rate); engine->set_driver(std::shared_ptr<Driver>(driver)); engine->activate(); ThreadManager::single_threaded = true; - std::lock_guard<std::mutex> lock(plugin->world->rdf_mutex()); + const std::lock_guard<std::mutex> lock{plugin->world->rdf_mutex()}; // Locate to time 0 to process initialization events engine->locate(0, block_length); @@ -605,7 +611,7 @@ ingen_instantiate(const LV2_Descriptor* descriptor, /* Register client after loading graph so the to-ui ring does not overflow. Since we are not yet rolling, it won't be drained, causing a deadlock. */ - std::shared_ptr<Interface> client(&driver->writer(), NullDeleter<Interface>); + const std::shared_ptr<Interface> client{&driver->writer(), NullDeleter<Interface>}; interface->set_respondee(client); engine->register_client(client); @@ -616,8 +622,8 @@ ingen_instantiate(const LV2_Descriptor* descriptor, static void ingen_connect_port(LV2_Handle instance, uint32_t port, void* data) { - auto* me = static_cast<IngenPlugin*>(instance); - Engine* engine = static_cast<Engine*>(me->world->engine().get()); + auto* me = static_cast<IngenPlugin*>(instance); + const Engine* engine = static_cast<Engine*>(me->world->engine().get()); const auto driver = std::static_pointer_cast<LV2Driver>(engine->driver()); if (port < driver->ports().size()) { driver->ports().at(port)->set_buffer(data); @@ -673,6 +679,7 @@ ingen_cleanup(LV2_Handle instance) auto world = std::move(me->world); delete me; + world.reset(); } static void @@ -706,9 +713,9 @@ ingen_save(LV2_Handle instance, return LV2_STATE_ERR_NO_FEATURE; } - LV2_URID ingen_file = plugin->map->map(plugin->map->handle, INGEN__file); - LV2_URID atom_Path = plugin->map->map(plugin->map->handle, - LV2_ATOM__Path); + const LV2_URID ingen_file = plugin->map->map(plugin->map->handle, INGEN__file); + const LV2_URID atom_Path = plugin->map->map(plugin->map->handle, + LV2_ATOM__Path); char* real_path = make_path->path(make_path->handle, "main.ttl"); char* state_path = map_path->abstract_path(map_path->handle, real_path); @@ -716,7 +723,7 @@ ingen_save(LV2_Handle instance, auto root = plugin->world->store()->find(raul::Path("/")); { - std::lock_guard<std::mutex> lock(plugin->world->rdf_mutex()); + const std::lock_guard<std::mutex> lock{plugin->world->rdf_mutex()}; plugin->world->serialiser()->start_to_file( root->second->path(), FilePath{real_path}); @@ -752,10 +759,10 @@ ingen_restore(LV2_Handle instance, return LV2_STATE_ERR_NO_FEATURE; } - LV2_URID ingen_file = plugin->map->map(plugin->map->handle, INGEN__file); - size_t size = 0; - uint32_t type = 0; - uint32_t valflags = 0; + const LV2_URID ingen_file = plugin->map->map(plugin->map->handle, INGEN__file); + size_t size = 0; + uint32_t type = 0; + uint32_t valflags = 0; // Get abstract path to graph file const char* path = static_cast<const char*>( @@ -770,7 +777,7 @@ ingen_restore(LV2_Handle instance, return LV2_STATE_ERR_UNKNOWN; } -#if 0 +#ifdef CLEAR_GRAPH_ON_RESTORE // Remove existing root graph contents std::shared_ptr<Engine> engine = plugin->engine; for (const auto& b : engine->root_graph()->blocks()) { @@ -787,7 +794,7 @@ ingen_restore(LV2_Handle instance, #endif // Load new graph - std::lock_guard<std::mutex> lock(plugin->world->rdf_mutex()); + const std::lock_guard<std::mutex> lock{plugin->world->rdf_mutex()}; plugin->world->parser()->parse_file( *plugin->world, *plugin->world->interface(), real_path); @@ -850,8 +857,8 @@ lib_get_plugin(LV2_Lib_Handle handle, uint32_t index) } } // extern "C" -} // namespace server -} // namespace ingen + +} // namespace ingen::server extern "C" { diff --git a/src/server/ingen_portaudio.cpp b/src/server/ingen_portaudio.cpp index 991470e4..68b1b0bc 100644 --- a/src/server/ingen_portaudio.cpp +++ b/src/server/ingen_portaudio.cpp @@ -14,19 +14,16 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -// IWYU pragma: no_include "ingen/FilePath.hpp" - -#include "PortAudioDriver.hpp" #include "Engine.hpp" +#include "PortAudioDriver.hpp" -#include "ingen/Log.hpp" -#include "ingen/Module.hpp" -#include "ingen/World.hpp" +#include <ingen/Log.hpp> +#include <ingen/Module.hpp> +#include <ingen/World.hpp> #include <memory> -namespace ingen { -namespace server { +namespace ingen::server { class Driver; @@ -46,12 +43,11 @@ struct PortAudioModule : public Module { } }; -} // namespace server -} // namespace ingen +} // namespace ingen::server extern "C" { -ingen::Module* +INGEN_MODULE_EXPORT ingen::Module* ingen_module_load() { return new ingen::server::PortAudioModule(); diff --git a/src/server/internals/BlockDelay.cpp b/src/server/internals/BlockDelay.cpp index 68252fe4..acc68851 100644 --- a/src/server/internals/BlockDelay.cpp +++ b/src/server/internals/BlockDelay.cpp @@ -14,7 +14,7 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "internals/BlockDelay.hpp" +#include "BlockDelay.hpp" #include "BlockImpl.hpp" #include "Buffer.hpp" @@ -24,21 +24,16 @@ #include "OutputPort.hpp" #include "PortType.hpp" -#include "ingen/Forge.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Forge.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> +#include <raul/Symbol.hpp> #include <memory> -namespace ingen { -namespace server { - -class RunContext; - -namespace internals { +namespace ingen::server::internals { InternalPlugin* BlockDelayNode::internal_plugin(URIs& uris) { return new InternalPlugin( @@ -91,6 +86,4 @@ BlockDelayNode::run(RunContext& ctx) _buffer->copy(ctx, _in_port->buffer(0).get()); } -} // namespace internals -} // namespace server -} // namespace ingen +} // namespace ingen::server::internals diff --git a/src/server/internals/BlockDelay.hpp b/src/server/internals/BlockDelay.hpp index 78a03c28..a9667fa0 100644 --- a/src/server/internals/BlockDelay.hpp +++ b/src/server/internals/BlockDelay.hpp @@ -36,7 +36,6 @@ class GraphImpl; class InputPort; class InternalPlugin; class OutputPort; -class RunContext; namespace internals { diff --git a/src/server/internals/Controller.cpp b/src/server/internals/Controller.cpp index d0d8cd39..9103649e 100644 --- a/src/server/internals/Controller.cpp +++ b/src/server/internals/Controller.cpp @@ -14,7 +14,8 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "BlockImpl.hpp" +#include "Controller.hpp" + #include "Buffer.hpp" #include "BufferFactory.hpp" #include "BufferRef.hpp" @@ -24,25 +25,23 @@ #include "PortType.hpp" #include "RunContext.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "internals/Controller.hpp" -#include "lv2/atom/atom.h" -#include "lv2/atom/util.h" -#include "lv2/midi/midi.h" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <lv2/atom/atom.h> +#include <lv2/atom/util.h> +#include <lv2/midi/midi.h> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> +#include <raul/Symbol.hpp> #include <cassert> #include <cmath> #include <initializer_list> #include <memory> -namespace ingen { -namespace server { +namespace ingen::server { class GraphImpl; @@ -60,7 +59,6 @@ ControllerNode::ControllerNode(InternalPlugin* plugin, GraphImpl* parent, SampleRate srate) : InternalBlock(plugin, symbol, false, parent, srate) - , _learning(false) { const ingen::URIs& uris = bufs.uris(); _ports = bufs.maid().make_managed<Ports>(7); @@ -125,7 +123,7 @@ ControllerNode::run(RunContext& ctx) auto* seq = midi_in->get<LV2_Atom_Sequence>(); const BufferRef midi_out = _midi_out_port->buffer(0); - LV2_ATOM_SEQUENCE_FOREACH(seq, ev) { + LV2_ATOM_SEQUENCE_FOREACH (seq, ev) { const auto* buf = static_cast<const uint8_t*>(LV2_ATOM_BODY_CONST(&ev->body)); if (ev->body.type == _midi_in_port->bufs().uris().midi_MidiEvent && ev->body.size >= 3 && @@ -174,7 +172,7 @@ ControllerNode::control(RunContext& ctx, uint8_t control_num, uint8_t val, Frame } const Sample min = logf(min_port_val + 1 + log_offset); const Sample max = logf(max_port_val + 1 + log_offset); - scaled_value = expf(nval * (max - min) + min) - 1 - log_offset; + scaled_value = expf((nval * (max - min)) + min) - 1 - log_offset; } else { scaled_value = ((nval) * (max_port_val - min_port_val)) + min_port_val; } @@ -185,5 +183,4 @@ ControllerNode::control(RunContext& ctx, uint8_t control_num, uint8_t val, Frame } } // namespace internals -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/internals/Controller.hpp b/src/server/internals/Controller.hpp index b5cea110..2a0bc834 100644 --- a/src/server/internals/Controller.hpp +++ b/src/server/internals/Controller.hpp @@ -74,7 +74,7 @@ private: InputPort* _min_port; InputPort* _max_port; OutputPort* _audio_port; - bool _learning; + bool _learning{false}; }; } // namespace internals diff --git a/src/server/internals/Note.cpp b/src/server/internals/Note.cpp index 4952310b..960bca85 100644 --- a/src/server/internals/Note.cpp +++ b/src/server/internals/Note.cpp @@ -14,28 +14,27 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "internals/Note.hpp" +#include "Note.hpp" #include "BlockImpl.hpp" #include "Buffer.hpp" #include "BufferFactory.hpp" -#include "BufferRef.hpp" #include "InputPort.hpp" #include "InternalPlugin.hpp" #include "OutputPort.hpp" #include "PortType.hpp" #include "RunContext.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "lv2/atom/atom.h" -#include "lv2/atom/util.h" -#include "lv2/midi/midi.h" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <lv2/atom/atom.h> +#include <lv2/atom/util.h> +#include <lv2/midi/midi.h> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> +#include <raul/Symbol.hpp> #include <cassert> #include <cmath> @@ -44,8 +43,7 @@ // #define NOTE_DEBUG 1 -namespace ingen { -namespace server { +namespace ingen::server { class GraphImpl; @@ -64,7 +62,6 @@ NoteNode::NoteNode(InternalPlugin* plugin, SampleRate srate) : InternalBlock(plugin, symbol, polyphonic, parent, srate) , _voices(bufs.maid().make_managed<Voices>(_polyphony)) - , _sustain(false) { const ingen::URIs& uris = bufs.uris(); _ports = bufs.maid().make_managed<Ports>(8); @@ -179,7 +176,7 @@ NoteNode::run(RunContext& ctx) Buffer* const midi_in = _midi_in_port->buffer(0).get(); auto* seq = midi_in->get<LV2_Atom_Sequence>(); - LV2_ATOM_SEQUENCE_FOREACH(seq, ev) { + LV2_ATOM_SEQUENCE_FOREACH (seq, ev) { const auto* buf = static_cast<const uint8_t*>(LV2_ATOM_BODY_CONST(&ev->body)); @@ -360,7 +357,7 @@ NoteNode::free_voice(RunContext& ctx, uint32_t voice, FrameTime time) } } - if (replace_key != nullptr) { // Found a key to assign to freed voice + if (replace_key != nullptr) { // Found a key to assign to freed voice assert(&_keys[replace_key_num] == replace_key); assert(replace_key->state == Key::State::ON_UNASSIGNED); @@ -437,5 +434,4 @@ NoteNode::channel_pressure(RunContext& ctx, FrameTime time, float amount) } } // namespace internals -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/internals/Note.hpp b/src/server/internals/Note.hpp index 80816131..2cf6c1e2 100644 --- a/src/server/internals/Note.hpp +++ b/src/server/internals/Note.hpp @@ -20,8 +20,8 @@ #include "InternalBlock.hpp" #include "types.hpp" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" +#include <raul/Array.hpp> +#include <raul/Maid.hpp> #include <cstdint> @@ -105,7 +105,7 @@ private: raul::managed_ptr<Voices> _prepared_voices; Key _keys[128]; - bool _sustain; ///< Whether or not hold pedal is depressed + bool _sustain{false}; ///< Whether or not hold pedal is depressed InputPort* _midi_in_port; OutputPort* _freq_port; diff --git a/src/server/internals/Time.cpp b/src/server/internals/Time.cpp index 651a2f36..2ea09b0b 100644 --- a/src/server/internals/Time.cpp +++ b/src/server/internals/Time.cpp @@ -14,9 +14,8 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "internals/Time.hpp" +#include "Time.hpp" -#include "BlockImpl.hpp" #include "Buffer.hpp" #include "BufferFactory.hpp" #include "BufferRef.hpp" @@ -27,19 +26,18 @@ #include "PortType.hpp" #include "RunContext.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "lv2/atom/atom.h" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <lv2/atom/atom.h> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> +#include <raul/Symbol.hpp> #include <memory> -namespace ingen { -namespace server { +namespace ingen::server { class GraphImpl; @@ -73,8 +71,8 @@ TimeNode::TimeNode(InternalPlugin* plugin, void TimeNode::run(RunContext& ctx) { - BufferRef buf = _notify_port->buffer(0); - auto* seq = buf->get<LV2_Atom_Sequence>(); + const BufferRef buf = _notify_port->buffer(0); + auto* const seq = buf->get<LV2_Atom_Sequence>(); // Initialise output to the empty sequence seq->atom.type = _notify_port->bufs().uris().atom_Sequence; @@ -87,5 +85,4 @@ TimeNode::run(RunContext& ctx) } } // namespace internals -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/internals/Time.hpp b/src/server/internals/Time.hpp index fa3e90e5..228e67a8 100644 --- a/src/server/internals/Time.hpp +++ b/src/server/internals/Time.hpp @@ -34,7 +34,6 @@ class BufferFactory; class GraphImpl; class InternalPlugin; class OutputPort; -class RunContext; namespace internals { diff --git a/src/server/internals/Trigger.cpp b/src/server/internals/Trigger.cpp index 645ffabb..f033a345 100644 --- a/src/server/internals/Trigger.cpp +++ b/src/server/internals/Trigger.cpp @@ -14,9 +14,8 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "internals/Trigger.hpp" +#include "Trigger.hpp" -#include "BlockImpl.hpp" #include "Buffer.hpp" #include "BufferFactory.hpp" #include "BufferRef.hpp" @@ -26,23 +25,22 @@ #include "PortType.hpp" #include "RunContext.hpp" -#include "ingen/Atom.hpp" -#include "ingen/Forge.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "lv2/atom/atom.h" -#include "lv2/atom/util.h" -#include "lv2/midi/midi.h" -#include "raul/Array.hpp" -#include "raul/Maid.hpp" -#include "raul/Symbol.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <lv2/atom/atom.h> +#include <lv2/atom/util.h> +#include <lv2/midi/midi.h> +#include <raul/Array.hpp> +#include <raul/Maid.hpp> +#include <raul/Symbol.hpp> #include <cassert> #include <cmath> #include <memory> -namespace ingen { -namespace server { +namespace ingen::server { class GraphImpl; @@ -60,7 +58,6 @@ TriggerNode::TriggerNode(InternalPlugin* plugin, GraphImpl* parent, SampleRate srate) : InternalBlock(plugin, symbol, false, parent, srate) - , _learning(false) { const ingen::URIs& uris = bufs.uris(); _ports = bufs.maid().make_managed<Ports>(6); @@ -124,7 +121,7 @@ TriggerNode::run(RunContext& ctx) // Initialise output to the empty sequence midi_out->prepare_write(ctx); - LV2_ATOM_SEQUENCE_FOREACH(seq, ev) { + LV2_ATOM_SEQUENCE_FOREACH (seq, ev) { const int64_t t = ev->time.frames; const auto* buf = static_cast<const uint8_t*>(LV2_ATOM_BODY_CONST(&ev->body)); @@ -199,5 +196,4 @@ TriggerNode::note_off(RunContext& ctx, uint8_t note_num, FrameTime time) } } // namespace internals -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/internals/Trigger.hpp b/src/server/internals/Trigger.hpp index d9553c3e..74634202 100644 --- a/src/server/internals/Trigger.hpp +++ b/src/server/internals/Trigger.hpp @@ -71,7 +71,7 @@ public: static InternalPlugin* internal_plugin(URIs& uris); private: - bool _learning; + bool _learning{false}; InputPort* _midi_in_port; OutputPort* _midi_out_port; diff --git a/src/server/meson.build b/src/server/meson.build new file mode 100644 index 00000000..c1fccf5e --- /dev/null +++ b/src/server/meson.build @@ -0,0 +1,135 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +########## +# Module # +########## + +server_sources = files( + 'events/Connect.cpp', + 'events/Copy.cpp', + 'events/CreateBlock.cpp', + 'events/CreateGraph.cpp', + 'events/CreatePort.cpp', + 'events/Delete.cpp', + 'events/Delta.cpp', + 'events/Disconnect.cpp', + 'events/DisconnectAll.cpp', + 'events/Get.cpp', + 'events/Mark.cpp', + 'events/Move.cpp', + 'events/SetPortValue.cpp', + 'events/Undo.cpp', + 'internals/BlockDelay.cpp', + 'internals/Controller.cpp', + 'internals/Note.cpp', + 'internals/Time.cpp', + 'internals/Trigger.cpp', + 'ArcImpl.cpp', + 'BlockFactory.cpp', + 'BlockImpl.cpp', + 'Broadcaster.cpp', + 'Buffer.cpp', + 'BufferFactory.cpp', + 'ClientUpdate.cpp', + 'CompiledGraph.cpp', + 'ControlBindings.cpp', + 'DuplexPort.cpp', + 'Engine.cpp', + 'EventWriter.cpp', + 'GraphImpl.cpp', + 'InputPort.cpp', + 'InternalBlock.cpp', + 'InternalPlugin.cpp', + 'LV2Block.cpp', + 'LV2Plugin.cpp', + 'NodeImpl.cpp', + 'PortImpl.cpp', + 'PostProcessor.cpp', + 'PreProcessor.cpp', + 'RunContext.cpp', + 'SocketListener.cpp', + 'Task.cpp', + 'UndoStack.cpp', + 'Worker.cpp', + 'ingen_engine.cpp', + 'mix.cpp', +) + +server_dependencies = [ + boost_dep, + ingen_dep, + lilv_dep, + raul_dep, + serd_dep, + sord_dep, + sratom_dep, + thread_dep, +] + +server_include_dirs = include_directories( + '.', + '../../include', + '../include', +) + +libingen_server = shared_library( + 'ingen_server', + server_sources, + cpp_args: cpp_suppressions + platform_defines + ['-DINGEN_SERVER_INTERNAL'], + dependencies: server_dependencies, + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: server_include_dirs, + install: true, + install_dir: ingen_module_dir, +) + +ingen_server_dep = declare_dependency( + dependencies: server_dependencies, + link_with: libingen_server, +) + +########### +# Drivers # +########### + +if jack_dep.found() + shared_module( + 'ingen_jack', + files('JackDriver.cpp', 'ingen_jack.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_server_dep, jack_dep], + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: ingen_module_dir, + ) +endif + +if portaudio_dep.found() + shared_module( + 'ingen_portaudio', + files('PortAudioDriver.cpp', 'ingen_portaudio.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_server_dep, portaudio_dep], + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: ingen_module_dir, + ) +endif + +shared_module( + 'ingen_lv2', + files('ingen_lv2.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_server_dep, lv2_dep], + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: lv2dir / 'ingen.lv2', +) diff --git a/src/server/mix.cpp b/src/server/mix.cpp index a1e0c276..32500f97 100644 --- a/src/server/mix.cpp +++ b/src/server/mix.cpp @@ -20,11 +20,10 @@ #include "RunContext.hpp" #include "types.hpp" -#include "lv2/atom/atom.h" -#include "lv2/atom/util.h" +#include <lv2/atom/atom.h> +#include <lv2/atom/util.h> -namespace ingen { -namespace server { +namespace ingen::server { static inline bool is_end(const Buffer* buf, const LV2_Atom_Event* ev) @@ -59,15 +58,15 @@ mix(const RunContext& ctx, const SampleCount end = ctx.nframes(); for (uint32_t i = 1; i < num_srcs; ++i) { const Sample* __restrict const in = srcs[i]->samples(); - if (srcs[i]->is_control()) { // control => audio + if (srcs[i]->is_control()) { // control => audio for (SampleCount j = 0; j < end; ++j) { out[j] += in[0]; } - } else if (srcs[i]->is_audio()) { // audio => audio + } else if (srcs[i]->is_audio()) { // audio => audio for (SampleCount j = 0; j < end; ++j) { out[j] += in[j]; } - } else if (srcs[i]->is_sequence()) { // sequence => audio + } else if (srcs[i]->is_sequence()) { // sequence => audio dst->render_sequence(ctx, srcs[i], true); } } @@ -111,5 +110,4 @@ mix(const RunContext& ctx, } } -} // namespace server -} // namespace ingen +} // namespace ingen::server diff --git a/src/server/mix.hpp b/src/server/mix.hpp index 75e139d3..11a9a1d2 100644 --- a/src/server/mix.hpp +++ b/src/server/mix.hpp @@ -19,8 +19,7 @@ #include <cstdint> -namespace ingen { -namespace server { +namespace ingen::server { class Buffer; class RunContext; @@ -31,7 +30,6 @@ mix(const RunContext& ctx, const Buffer*const* srcs, uint32_t num_srcs); -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_MIX_HPP diff --git a/src/server/server.h b/src/server/server.h new file mode 100644 index 00000000..d4ca5155 --- /dev/null +++ b/src/server/server.h @@ -0,0 +1,31 @@ +/* + This file is part of Ingen. + Copyright 2014-2022 David Robillard <http://drobilla.net/> + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef INGEN_SERVER_SERVER_H +#define INGEN_SERVER_SERVER_H + +#if defined(_WIN32) && !defined(INGEN_SERVER_STATIC) && \ + defined(INGEN_SERVER_INTERNAL) +# define INGEN_SERVER_API __declspec(dllexport) +#elif defined(_WIN32) && !defined(INGEN_SERVER_STATIC) +# define INGEN_SERVER_API __declspec(dllimport) +#elif defined(__GNUC__) +# define INGEN_SERVER_API __attribute__((visibility("default"))) +#else +# define INGEN_SERVER_API +#endif + +#endif // INGEN_SERVER_SERVER_H diff --git a/src/server/util.hpp b/src/server/util.hpp index 3c8d2058..abfa06b6 100644 --- a/src/server/util.hpp +++ b/src/server/util.hpp @@ -17,10 +17,10 @@ #ifndef INGEN_ENGINE_UTIL_HPP #define INGEN_ENGINE_UTIL_HPP -#include "ingen/Log.hpp" +#include <ingen/Log.hpp> #ifdef __SSE__ -#include <xmmintrin.h> // IWYU pragma: keep +#include <xmmintrin.h> #endif #ifdef __clang__ @@ -29,8 +29,7 @@ # define REALTIME #endif -namespace ingen { -namespace server { +namespace ingen::server { /** Set flags to disable denormal processing. */ @@ -43,7 +42,6 @@ set_denormal_flags(ingen::Log& log) #endif } -} // namespace server -} // namespace ingen +} // namespace ingen::server #endif // INGEN_ENGINE_UTIL_HPP diff --git a/src/server/wscript b/src/server/wscript deleted file mode 100644 index 5fdf4583..00000000 --- a/src/server/wscript +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python - - -def build(bld): - core_source = ''' - ArcImpl.cpp - BlockFactory.cpp - BlockImpl.cpp - Broadcaster.cpp - Buffer.cpp - BufferFactory.cpp - CompiledGraph.cpp - ClientUpdate.cpp - ControlBindings.cpp - DuplexPort.cpp - Engine.cpp - EventWriter.cpp - GraphImpl.cpp - InputPort.cpp - InternalBlock.cpp - InternalPlugin.cpp - LV2Block.cpp - LV2Plugin.cpp - NodeImpl.cpp - PortImpl.cpp - PostProcessor.cpp - PreProcessor.cpp - RunContext.cpp - SocketListener.cpp - Task.cpp - UndoStack.cpp - Worker.cpp - events/Connect.cpp - events/Copy.cpp - events/CreateBlock.cpp - events/CreateGraph.cpp - events/CreatePort.cpp - events/Delete.cpp - events/Delta.cpp - events/Disconnect.cpp - events/DisconnectAll.cpp - events/Get.cpp - events/Mark.cpp - events/Move.cpp - events/SetPortValue.cpp - events/Undo.cpp - ingen_engine.cpp - internals/BlockDelay.cpp - internals/Controller.cpp - internals/Note.cpp - internals/Time.cpp - internals/Trigger.cpp - mix.cpp - ''' - - core_libs = 'LV2 LILV RAUL SERD SORD SRATOM' - - bld(features = 'cxx cxxshlib', - source = core_source, - export_includes = ['../../include'], - includes = ['.', '../..', '../../include'], - name = 'libingen_server', - target = 'ingen_server', - install_path = '${LIBDIR}', - use = 'libingen libingen_socket', - uselib = core_libs, - cxxflags = bld.env.PTHREAD_CFLAGS + bld.env.INGEN_TEST_CXXFLAGS, - linkflags = bld.env.PTHREAD_LINKFLAGS + bld.env.INGEN_TEST_LINKFLAGS) - - if bld.env.HAVE_JACK: - bld(features = 'cxx cxxshlib', - source = 'JackDriver.cpp ingen_jack.cpp', - includes = ['.', '../../', '../../include'], - name = 'libingen_jack', - target = 'ingen_jack', - install_path = '${LIBDIR}', - use = 'libingen_server', - uselib = core_libs + ' JACK', - cxxflags = ['-fvisibility=hidden'] + bld.env.PTHREAD_CFLAGS, - linkflags = bld.env.PTHREAD_LINKFLAGS) - - if bld.env.HAVE_PORTAUDIO: - bld(features = 'cxx cxxshlib', - source = 'PortAudioDriver.cpp ingen_portaudio.cpp', - includes = ['.', '../../', '../../include'], - name = 'libingen_portaudio', - target = 'ingen_portaudio', - install_path = '${LIBDIR}', - use = 'libingen_server', - uselib = core_libs + ' PORTAUDIO', - cxxflags = ['-fvisibility=hidden'] + bld.env.PTHREAD_CFLAGS, - linkflags = bld.env.PTHREAD_LINKFLAGS) - - # Ingen LV2 wrapper - if bld.env.INGEN_BUILD_LV2: - bld(features = 'cxx cxxshlib', - source = ' ingen_lv2.cpp ', - cflags = ['-fvisibility=hidden'], - includes = ['../../', '../../include'], - name = 'libingen_lv2', - target = 'ingen_lv2', - install_path = '${LV2DIR}/ingen.lv2/', - use = 'libingen libingen_server', - uselib = core_libs, - cxxflags = ['-fvisibility=hidden'] + bld.env.PTHREAD_CFLAGS, - linkflags = bld.env.PTHREAD_LINKFLAGS) diff --git a/src/wscript b/src/wscript deleted file mode 100644 index a2f576da..00000000 --- a/src/wscript +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python - - -def build(bld): - sources = [ - 'AtomReader.cpp', - 'AtomWriter.cpp', - 'ClashAvoider.cpp', - 'ColorContext.cpp', - 'Configuration.cpp', - 'FilePath.cpp', - 'Forge.cpp', - 'LV2Features.cpp', - 'Library.cpp', - 'Log.cpp', - 'Parser.cpp', - 'Resource.cpp', - 'Serialiser.cpp', - 'Store.cpp', - 'StreamWriter.cpp', - 'TurtleWriter.cpp', - 'URI.cpp', - 'URIMap.cpp', - 'URIs.cpp', - 'World.cpp', - 'runtime_paths.cpp' - ] - if bld.is_defined('HAVE_SOCKET'): - sources += ['SocketReader.cpp', 'SocketWriter.cpp'] - - lib = [] - if bld.is_defined('HAVE_LIBDL'): - lib += ['dl'] - - bld(features = 'cxx cxxshlib', - source = sources, - export_includes = ['../include'], - includes = ['.', '..', '../include'], - name = 'libingen', - target = 'ingen-%s' % bld.env.INGEN_MAJOR_VERSION, - vnum = bld.env.INGEN_VERSION, - install_path = '${LIBDIR}', - lib = lib, - uselib = 'LV2 LILV RAUL SERD SORD SRATOM', - cxxflags = (['-fvisibility=hidden'] + - bld.env.PTHREAD_CFLAGS + bld.env.INGEN_TEST_CXXFLAGS), - linkflags = bld.env.PTHREAD_LINKFLAGS + bld.env.INGEN_TEST_LINKFLAGS) diff --git a/tests/.clang-tidy b/tests/.clang-tidy new file mode 100644 index 00000000..6c26f23c --- /dev/null +++ b/tests/.clang-tidy @@ -0,0 +1,16 @@ +Checks: > + -*-no-malloc, + -*-vararg, + -android-cloexec-fopen, + -cert-err33-c, + -concurrency-mt-unsafe, + -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-owning-memory, + -cppcoreguidelines-pro-bounds-pointer-arithmetic, + -cppcoreguidelines-pro-type-reinterpret-cast, + -cppcoreguidelines-pro-type-union-access, + -fuchsia-statically-constructed-objects, + -google-readability-todo, + -llvm-header-guard, + -readability-function-cognitive-complexity, +InheritParentConfig: true diff --git a/tests/TestClient.hpp b/tests/TestClient.hpp index da749660..72265b14 100644 --- a/tests/TestClient.hpp +++ b/tests/TestClient.hpp @@ -17,13 +17,13 @@ #ifndef INGEN_TESTCLIENT_HPP #define INGEN_TESTCLIENT_HPP -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/Message.hpp" -#include "ingen/Status.hpp" -#include "ingen/URI.hpp" +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Message.hpp> +#include <ingen/Status.hpp> +#include <ingen/URI.hpp> -#include <boost/variant/get.hpp> +#include <variant> #include <cstdlib> @@ -32,14 +32,14 @@ namespace ingen { class TestClient : public Interface { public: - explicit TestClient(Log& log) : _log(log) {} + explicit TestClient(Log& log) noexcept : _log(log) {} ~TestClient() override = default; URI uri() const override { return URI("ingen:testClient"); } void message(const Message& msg) override { - if (const Response* const response = boost::get<Response>(&msg)) { + if (const Response* const response = std::get_if<Response>(&msg)) { if (response->status != Status::SUCCESS) { _log.error("error on message %1%: %2% (%3%)\n", response->id, @@ -47,7 +47,7 @@ public: response->subject); exit(EXIT_FAILURE); } - } else if (const Error* const error = boost::get<Error>(&msg)) { + } else if (const Error* const error = std::get_if<Error>(&msg)) { _log.error("error: %1%\n", error->message); exit(EXIT_FAILURE); } diff --git a/tests/connect_disconnect_node_patch.ttl b/tests/connect_disconnect_node_patch.ttl index 77ada2ad..373b5cbf 100644 --- a/tests/connect_disconnect_node_patch.ttl +++ b/tests/connect_disconnect_node_patch.ttl @@ -13,10 +13,10 @@ <msg1> a patch:Put ; - patch:subject <ingen:/main/sampler> ; + patch:subject <ingen:/main/metro> ; patch:body [ a ingen:Block ; - lv2:prototype <http://lv2plug.in/plugins/eg-sampler> + lv2:prototype <http://lv2plug.in/plugins/eg-metro> ] . <msg2> @@ -85,7 +85,7 @@ patch:body [ a ingen:Arc ; ingen:tail <ingen:/main/control> ; - ingen:head <ingen:/main/sampler/control> + ingen:head <ingen:/main/metro/control> ] . <msg10> diff --git a/tests/ingen_bench.cpp b/tests/ingen_bench.cpp index 2af53f89..ee890401 100644 --- a/tests/ingen_bench.cpp +++ b/tests/ingen_bench.cpp @@ -14,14 +14,14 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Atom.hpp" -#include "ingen/Clock.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/EngineBase.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Parser.hpp" -#include "ingen/World.hpp" -#include "ingen/runtime_paths.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Clock.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/EngineBase.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Parser.hpp> +#include <ingen/World.hpp> +#include <ingen/runtime_paths.hpp> #include <chrono> #include <cstdint> @@ -32,8 +32,7 @@ #include <memory> #include <string> -namespace ingen { -namespace bench { +namespace ingen::bench { namespace { std::unique_ptr<ingen::World> world; @@ -42,7 +41,7 @@ void ingen_try(bool cond, const char* msg) { if (!cond) { - std::cerr << "ingen: Error: " << msg << std::endl; + std::cerr << "ingen: Error: " << msg << "\n"; world.reset(); exit(EXIT_FAILURE); } @@ -62,15 +61,14 @@ run(int argc, char** argv) { // Create world try { - world = std::unique_ptr<ingen::World>{ - new ingen::World(nullptr, nullptr, nullptr)}; + world = std::make_unique<ingen::World>(nullptr, nullptr, nullptr); world->conf().add( "output", "output", 'O', "File to write benchmark output", ingen::Configuration::SESSION, world->forge().String, Atom()); world->load_configuration(argc, argv); } catch (std::exception& e) { - std::cout << "ingen: " << e.what() << std::endl; + std::cout << "ingen: " << e.what() << "\n"; return EXIT_FAILURE; } @@ -78,9 +76,7 @@ run(int argc, char** argv) const Atom& load = world->conf().option("load"); const Atom& out = world->conf().option("output"); if (!load.is_valid() || !out.is_valid()) { - std::cerr << "Usage: ingen_bench --load START_GRAPH --output OUT_FILE" - << std::endl; - + std::cerr << "Usage: ingen_bench --load START_GRAPH --output OUT_FILE\n"; return EXIT_FAILURE; } @@ -92,7 +88,7 @@ run(int argc, char** argv) if (start_graph.empty()) { std::cerr << "error: initial graph '" << static_cast<const char*>(load.get_body()) - << "' does not exist" << std::endl; + << "' does not exist\n"; return EXIT_FAILURE; } @@ -101,7 +97,7 @@ run(int argc, char** argv) "Unable to load server module"); // Initialise engine - ingen_try(bool(world->engine()), + ingen_try(!!world->engine(), "Unable to create engine"); world->engine()->init(48000.0, 4096, 4096); world->engine()->activate(); @@ -109,7 +105,7 @@ run(int argc, char** argv) // Load graph if (!world->parser()->parse_file(*world, *world->interface(), start_graph)) { std::cerr << "error: failed to load initial graph " << start_graph - << std::endl; + << "\n"; return EXIT_FAILURE; } @@ -117,10 +113,10 @@ run(int argc, char** argv) // Run benchmark // TODO: Set up real-time scheduling for this and worker threads - ingen::Clock clock; - const uint32_t n_test_frames = 1 << 20; - const uint32_t block_length = 4096; - const uint64_t t_start = clock.now_microseconds(); + const ingen::Clock clock; + const uint32_t n_test_frames = 1 << 20; + const uint32_t block_length = 4096; + const uint64_t t_start = clock.now_microseconds(); for (uint32_t i = 0; i < n_test_frames; i += block_length) { world->engine()->advance(block_length); world->engine()->run(block_length); @@ -129,14 +125,14 @@ run(int argc, char** argv) const uint64_t t_end = clock.now_microseconds(); // Write log output - std::unique_ptr<FILE, decltype(&fclose)> log{fopen(out_file.c_str(), "a"), - &fclose}; + const std::unique_ptr<FILE, int (*)(FILE*)> log{fopen(out_file.c_str(), "a"), + &fclose}; if (ftell(log.get()) == 0) { fprintf(log.get(), "# n_threads\trun_time\treal_time\n"); } - fprintf(log.get(), "%u\t%f\t%f\n", + fprintf(log.get(), "%d\t%f\t%f\n", world->conf().option("threads").get<int32_t>(), - (t_end - t_start) / 1000000.0, + static_cast<double>(t_end - t_start) / 1000000.0, (n_test_frames / 48000.0)); // Shut down @@ -146,8 +142,7 @@ run(int argc, char** argv) } } // namespace -} // namespace bench -} // namespace ingen +} // namespace ingen::bench int main(int argc, char** argv) diff --git a/tests/ingen_test.cpp b/tests/ingen_test.cpp index 87e02e9f..215d20a1 100644 --- a/tests/ingen_test.cpp +++ b/tests/ingen_test.cpp @@ -16,40 +16,41 @@ #include "TestClient.hpp" -#include "ingen/Atom.hpp" -#include "ingen/AtomForge.hpp" -#include "ingen/AtomReader.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/EngineBase.hpp" -#include "ingen/FilePath.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Parser.hpp" -#include "ingen/Serialiser.hpp" -#include "ingen/Store.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/World.hpp" -#include "ingen/filesystem.hpp" -#include "ingen/fmt.hpp" -#include "ingen/memory.hpp" -#include "ingen/runtime_paths.hpp" -#include "raul/Path.hpp" -#include "serd/serd.h" -#include "sord/sordmm.hpp" -#include "sratom/sratom.h" +#include <ingen/Atom.hpp> +#include <ingen/AtomForge.hpp> +#include <ingen/AtomReader.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/EngineBase.hpp> +#include <ingen/FilePath.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Parser.hpp> +#include <ingen/Serialiser.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/World.hpp> +#include <ingen/fmt.hpp> +#include <ingen/memory.hpp> +#include <ingen/runtime_paths.hpp> +#include <raul/Path.hpp> +#include <serd/serd.h> +#include <sord/sordmm.hpp> +#include <sratom/sratom.h> #include <chrono> #include <cstdint> #include <cstdlib> #include <exception> +#include <filesystem> #include <iostream> #include <map> #include <memory> #include <string> #include <utility> -namespace ingen { -namespace test { +// #define DUMP_EVENTS 1 + +namespace ingen::test { namespace { std::unique_ptr<World> world; @@ -58,7 +59,7 @@ void ingen_try(bool cond, const char* msg) { if (!cond) { - std::cerr << "ingen: Error: " << msg << std::endl; + std::cerr << "ingen: Error: " << msg << "\n"; world.reset(); exit(EXIT_FAILURE); } @@ -67,8 +68,8 @@ ingen_try(bool cond, const char* msg) FilePath real_file_path(const char* path) { - std::unique_ptr<char, FreeDeleter<char>> real_path{realpath(path, nullptr), - FreeDeleter<char>{}}; + const std::unique_ptr<char, FreeDeleter<char>> real_path{realpath(path, nullptr), + FreeDeleter<char>{}}; return FilePath{real_path.get()}; } @@ -78,10 +79,10 @@ run(int argc, char** argv) { // Create world try { - world = std::unique_ptr<World>{new World(nullptr, nullptr, nullptr)}; + world = std::make_unique<World>(nullptr, nullptr, nullptr); world->load_configuration(argc, argv); - } catch (std::exception& e) { - std::cout << "ingen: " << e.what() << std::endl; + } catch (const std::exception& e) { + std::cerr << "ingen: " << e.what() << "\n"; return EXIT_FAILURE; } @@ -90,8 +91,7 @@ run(int argc, char** argv) const Atom& execute = world->conf().option("execute"); if (!load.is_valid() || !execute.is_valid()) { std::cerr - << "Usage: ingen_test --load START_GRAPH --execute COMMANDS_FILE" - << std::endl; + << "Usage: ingen_test --load START_GRAPH --execute COMMANDS_FILE\n"; return EXIT_FAILURE; } @@ -101,14 +101,12 @@ run(int argc, char** argv) const FilePath run_path = real_file_path(static_cast<const char*>(execute.get_body())); if (load_path.empty()) { - std::cerr << "error: initial graph '" << load_path << "' does not exist" - << std::endl; - + std::cerr << "error: initial graph '" << load_path << "' does not exist\n"; return EXIT_FAILURE; - } else if (run_path.empty()) { - std::cerr << "error: command file '" << run_path << "' does not exist" - << std::endl; + } + if (run_path.empty()) { + std::cerr << "error: command file '" << run_path << "' does not exist\n"; return EXIT_FAILURE; } @@ -117,16 +115,14 @@ run(int argc, char** argv) "Unable to load server module"); // Initialise engine - ingen_try(bool(world->engine()), + ingen_try(!!world->engine(), "Unable to create engine"); world->engine()->init(48000.0, 4096, 4096); world->engine()->activate(); // Load graph if (!world->parser()->parse_file(*world, *world->interface(), load_path)) { - std::cerr << "error: failed to load initial graph " << load_path - << std::endl; - + std::cerr << "error: failed to load initial graph " << load_path << "\n"; return EXIT_FAILURE; } world->engine()->flush_events(std::chrono::milliseconds(20)); @@ -144,7 +140,7 @@ run(int argc, char** argv) *world->interface()); // AtomWriter to serialise responses from the engine - std::shared_ptr<Interface> client(new TestClient(world->log())); + const std::shared_ptr<Interface> client{new TestClient(world->log())}; world->interface()->set_respondee(client); world->engine()->register_client(client); @@ -160,13 +156,16 @@ run(int argc, char** argv) SerdEnv* env = serd_env_new(&cmds_file_uri); cmds->load_file(env, SERD_TURTLE, run_path); - Sord::Node nil; - int n_events = 0; + const Sord::Node nil; + int n_events = 0; for (;; ++n_events) { - std::string subject_str = fmt("msg%1%", n_events); - Sord::URI subject(*world->rdf_world(), subject_str, + const std::string subject_str = fmt("msg%1%", n_events); + + Sord::URI subject(*world->rdf_world(), + subject_str, reinterpret_cast<const char*>(cmds_file_uri.buf)); - Sord::Iter iter = cmds->find(subject, nil, nil); + + auto iter = cmds->find(subject, nil, nil); if (iter.end()) { break; } @@ -174,9 +173,9 @@ run(int argc, char** argv) forge.clear(); forge.read(*world->rdf_world(), cmds->c_obj(), subject.c_obj()); -#if 0 +#ifdef DUMP_EVENTS const LV2_Atom* atom = forge.atom(); - cerr << "READ " << atom->size << " BYTES" << endl; + cerr << "READ " << atom->size << " BYTES\n"; cerr << sratom_to_turtle( sratom, &world->uri_map().urid_unmap_feature()->urid_unmap, @@ -185,6 +184,7 @@ run(int argc, char** argv) #endif if (!atom_reader.write(forge.atom(), n_events + 1)) { + delete cmds; return EXIT_FAILURE; } @@ -197,10 +197,10 @@ run(int argc, char** argv) auto r = world->store()->find(raul::Path("/")); const std::string base = run_path.stem(); const std::string out_name = base.substr(0, base.find('.')) + ".out.ingen"; - const FilePath out_path = filesystem::current_path() / out_name; + const FilePath out_path = std::filesystem::current_path() / out_name; world->serialiser()->write_bundle(r->second, URI(out_path)); - // Undo every event (should result in a graph identical to the original) + // Undo every event (makes the graph identical to the original) for (int i = 0; i < n_events; ++i) { world->interface()->undo(); world->engine()->flush_events(std::chrono::milliseconds(20)); @@ -209,10 +209,10 @@ run(int argc, char** argv) // Save completely undone graph r = world->store()->find(raul::Path("/")); const std::string undo_name = base.substr(0, base.find('.')) + ".undo.ingen"; - const FilePath undo_path = filesystem::current_path() / undo_name; + const FilePath undo_path = std::filesystem::current_path() / undo_name; world->serialiser()->write_bundle(r->second, URI(undo_path)); - // Redo every event (should result in a graph identical to the pre-undo output) + // Redo every event (makes the graph identical to the pre-undo output) for (int i = 0; i < n_events; ++i) { world->interface()->redo(); world->engine()->flush_events(std::chrono::milliseconds(20)); @@ -221,7 +221,7 @@ run(int argc, char** argv) // Save completely redone graph r = world->store()->find(raul::Path("/")); const std::string redo_name = base.substr(0, base.find('.')) + ".redo.ingen"; - const FilePath redo_path = filesystem::current_path() / redo_name; + const FilePath redo_path = std::filesystem::current_path() / redo_name; world->serialiser()->write_bundle(r->second, URI(redo_path)); serd_env_free(env); @@ -234,14 +234,18 @@ run(int argc, char** argv) } } // namespace -} // namespace test -} // namespace ingen +} // namespace ingen::test int main(int argc, char** argv) { - ingen::set_bundle_path_from_code( - reinterpret_cast<void (*)()>(&ingen::test::ingen_try)); + try { + ingen::set_bundle_path_from_code( + reinterpret_cast<void (*)()>(&ingen::test::ingen_try)); - return ingen::test::run(argc, argv); + return ingen::test::run(argc, argv); + } catch (const std::exception& e) { + std::cerr << "ingen: " << e.what() << "\n"; + return EXIT_FAILURE; + } } diff --git a/tests/lint/meson.build b/tests/lint/meson.build new file mode 100644 index 00000000..c641cbaa --- /dev/null +++ b/tests/lint/meson.build @@ -0,0 +1,24 @@ +# Copyright 2019-2024 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +if not meson.is_subproject() + # Check code with cppcheck + cppcheck = find_program('cppcheck', required: false) + if cppcheck.found() + compdb_path = join_paths(ingen_build_root, 'compile_commands.json') + suppress_path = join_paths(ingen_src_root, '.suppress.cppcheck') + test( + 'cppcheck', + cppcheck, + args: [ + '--cppcheck-build-dir=' + meson.current_build_dir(), + '--enable=warning,style,performance,portability', + '--error-exitcode=1', + '--project=' + compdb_path, + '--suppressions-list=' + suppress_path, + '-q', + ], + suite: 'code', + ) + endif +endif diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 00000000..1637230b --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,100 @@ +# Copyright 2019-2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +##################### +# Integration Tests # +##################### + +ingen_test = executable( + 'ingen_test', + files('ingen_test.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_dep], +) + +ingen_bench = executable( + 'ingen_bench', + files('ingen_bench.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_dep], +) + +empty_manifest = files('empty.ingen/manifest.ttl') +empty_main = files('empty.ingen/main.ttl') + +integration_tests = [ + 'connect_disconnect_node_node', + 'connect_disconnect_node_patch', + 'connect_disconnect_patch_patch', + 'copy_node', + 'create_delete_node', + 'create_delete_patch', + 'create_delete_poly_patch', + 'create_delete_port', + 'disconnect_all_node', + 'disconnect_all_port', + 'duplicate_node', + 'enable_graph', + 'get_engine', + 'get_node', + 'get_patch', + 'get_plugin', + 'get_plugins', + 'get_port', + 'load_graph', + 'move_node', + 'move_port', + 'move_root_port', + 'poly', + 'put_audio_in', + 'save_graph', + 'set_graph_poly', + 'set_patch_port_value', +] + +test_env = environment( + { + 'INGEN_MODULE_PATH': ':'.join( + [ + ingen_build_root / 'src', + ingen_build_root / 'src' / 'client', + ingen_build_root / 'src' / 'gui', + ingen_build_root / 'src' / 'server', + ], + ), + 'LV2_PATH': ':'.join( + [ + lv2_dep.get_variable( + default_value: lv2dir, + internal: 'lv2dir', + pkgconfig: 'lv2dir', + ), + lv2_dep.get_variable( + default_value: lv2dir, + internal: 'plugindir', + pkgconfig: 'plugindir', + ), + ], + ), + }, +) + +foreach test : integration_tests + test( + test, + ingen_test, + env: test_env, + args: [ + ['--load', empty_manifest], + ['--execute', files(test + '.ttl')], + ], + ) +endforeach + +######## +# Lint # +######## + +if get_option('lint') + subdir('lint') +endif diff --git a/tests/test_utils.hpp b/tests/test_utils.hpp index 57446ac5..4c358739 100644 --- a/tests/test_utils.hpp +++ b/tests/test_utils.hpp @@ -14,9 +14,7 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -// IWYU pragma: no_include "ingen/FilePath.hpp" - -#include "ingen/fmt.hpp" +#include <ingen/fmt.hpp> #include <iostream> #include <string> diff --git a/tests/tst_FilePath.cpp b/tests/tst_FilePath.cpp deleted file mode 100644 index 75744f46..00000000 --- a/tests/tst_FilePath.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2018 David Robillard <http://drobilla.net/> - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "test_utils.hpp" - -#include "ingen/FilePath.hpp" -#include "ingen/fmt.hpp" - -#include <boost/utility/string_view_fwd.hpp> - -#include <string> - -using ingen::FilePath; -using ingen::fmt; - -int -main(int, char**) -{ - EXPECT_EQ(FilePath("/").parent_path(), FilePath("/")); - - EXPECT_TRUE(FilePath("/abs").is_absolute()); - EXPECT_FALSE(FilePath("/abs").is_relative()); - EXPECT_EQ(FilePath("/abs").root_name(), FilePath()); - EXPECT_EQ(FilePath("/abs").root_directory(), FilePath("/")); - EXPECT_EQ(FilePath("/abs").root_path(), FilePath("/")); - EXPECT_EQ(FilePath("/abs").relative_path(), FilePath("abs")); - EXPECT_EQ(FilePath("/abs").parent_path(), FilePath("/")); - EXPECT_EQ(FilePath("/abs").filename(), FilePath("abs")); - EXPECT_EQ(FilePath("/abs").stem(), FilePath("abs")); - EXPECT_EQ(FilePath("/abs").extension(), FilePath()); - - EXPECT_FALSE(FilePath("rel").is_absolute()); - EXPECT_TRUE(FilePath("rel").is_relative()); - EXPECT_EQ(FilePath("rel").root_name(), FilePath()); - EXPECT_EQ(FilePath("rel").root_directory(), FilePath()); - EXPECT_EQ(FilePath("rel").root_path(), FilePath()); - EXPECT_EQ(FilePath("rel").relative_path(), FilePath()); - EXPECT_EQ(FilePath("rel").parent_path(), FilePath()); - EXPECT_EQ(FilePath("rel").filename(), "rel"); - EXPECT_EQ(FilePath("rel").stem(), "rel"); - EXPECT_EQ(FilePath("rel").extension(), FilePath()); - - EXPECT_FALSE(FilePath("file.txt").is_absolute()); - EXPECT_TRUE(FilePath("file.txt").is_relative()); - EXPECT_EQ(FilePath("file.txt").filename(), "file.txt"); - EXPECT_EQ(FilePath("file.txt").stem(), "file"); - EXPECT_EQ(FilePath("file.txt").extension(), ".txt"); - - EXPECT_TRUE(FilePath("/abs/file.txt").is_absolute()); - EXPECT_FALSE(FilePath("/abs/file.txt").is_relative()); - EXPECT_EQ(FilePath("/abs/file.txt").filename(), "file.txt"); - EXPECT_EQ(FilePath("/abs/file.txt").stem(), "file"); - EXPECT_EQ(FilePath("/abs/file.txt").extension(), ".txt"); - - EXPECT_FALSE(FilePath("rel/file.txt").is_absolute()); - EXPECT_TRUE(FilePath("rel/file.txt").is_relative()); - EXPECT_EQ(FilePath("rel/file.txt").filename(), "file.txt"); - EXPECT_EQ(FilePath("rel/file.txt").stem(), "file"); - EXPECT_EQ(FilePath("rel/file.txt").extension(), ".txt"); - - FilePath path("/x"); - EXPECT_EQ(path, "/x"); - path = std::string("/a"); - EXPECT_EQ(path, "/a"); - - path /= FilePath("b"); - EXPECT_EQ(path, "/a/b"); - - path += FilePath("ar"); - EXPECT_EQ(path, "/a/bar"); - - path += std::string("/c"); - EXPECT_EQ(path, "/a/bar/c"); - - path += "a"; - EXPECT_EQ(path, "/a/bar/ca"); - - path += 'r'; - EXPECT_EQ(path, "/a/bar/car"); - - path += boost::string_view("/d"); - EXPECT_EQ(path, "/a/bar/car/d"); - - const FilePath apple("apple"); - const FilePath zebra("zebra"); - EXPECT_TRUE(apple == apple); - EXPECT_TRUE(apple != zebra); - EXPECT_TRUE(apple < zebra); - EXPECT_TRUE(apple <= zebra); - EXPECT_TRUE(apple <= apple); - EXPECT_TRUE(zebra > apple); - EXPECT_TRUE(zebra >= apple); - EXPECT_TRUE(zebra >= zebra); - return 0; -} @@ -1,27 +0,0 @@ -#!/usr/bin/env python - -# Minimal waf script for projects that include waflib directly - -import sys -import inspect -import os - -try: - from waflib import Context, Scripting -except Exception as e: - sys.stderr.write('error: Failed to import waf (%s)\n' % e) - if os.path.exists('.git'): - sys.stderr.write("Are submodules up to date? " - "Try 'git submodule update --init --recursive'\n") - - sys.exit(1) - - -def main(): - script_path = os.path.abspath(inspect.getfile(inspect.getmodule(main))) - project_path = os.path.dirname(script_path) - Scripting.waf_entry_point(os.getcwd(), Context.WAFVERSION, project_path) - - -if __name__ == '__main__': - main() diff --git a/waflib b/waflib deleted file mode 160000 -Subproject b600c928b221a001faeab7bd92786d0b25714bc diff --git a/wscript b/wscript deleted file mode 100644 index 1c6b07dc..00000000 --- a/wscript +++ /dev/null @@ -1,443 +0,0 @@ -#!/usr/bin/env python - -import os - -from waflib import Build, Logs, Options, Utils -from waflib.extras import autowaf - -# Package version -INGEN_VERSION = '0.5.1' -INGEN_MAJOR_VERSION = '0' - -# Mandatory waf variables -APPNAME = 'ingen' # Package name for waf dist -VERSION = INGEN_VERSION # Package version for waf dist -top = '.' # Source directory -out = 'build' # Build directory - -line_just = 47 - - -def options(ctx): - ctx.load('compiler_cxx') - ctx.load('python') - ctx.load('lv2') - ctx.recurse('src/gui') - opt = ctx.configuration_options() - - opt.add_option('--data-dir', type='string', dest='datadir', - help='ingen data install directory [default: PREFIX/share/ingen]') - opt.add_option('--module-dir', type='string', dest='moduledir', - help='ingen module install directory [default: PREFIX/lib/ingen]') - - ctx.add_flags( - opt, - {'no-gui': 'do not build GUI', - 'no-client': 'do not build client library (or GUI)', - 'no-jack': 'do not build jack backend (for ingen.lv2 only)', - 'no-plugin': 'do not build ingen.lv2 plugin', - 'no-python': 'do not install Python bindings', - 'no-webkit': 'do not use webkit to display plugin documentation', - 'no-socket': 'do not build Socket interface', - 'debug-urids': 'print a trace of URI mapping', - 'portaudio': 'build PortAudio backend'}) - - -def configure(conf): - conf.load('compiler_cxx', cache=True) - conf.load('lv2', cache=True) - if not Options.options.no_python: - conf.load('python', cache=True) - - conf.load('autowaf', cache=True) - autowaf.set_cxx_lang(conf, 'c++14') - - if Options.options.strict: - # Check for programs used by lint target - conf.find_program("flake8", var="FLAKE8", mandatory=False) - conf.find_program("clang-tidy", var="CLANG_TIDY", mandatory=False) - conf.find_program("iwyu_tool", var="IWYU_TOOL", mandatory=False) - - if Options.options.ultra_strict: - autowaf.add_compiler_flags(conf.env, 'cxx', { - 'clang': [ - '-Wno-cast-align', - '-Wno-cast-qual', - '-Wno-documentation-unknown-command', - '-Wno-exit-time-destructors', - '-Wno-float-conversion', - '-Wno-float-equal', - '-Wno-format-nonliteral', - '-Wno-global-constructors', - '-Wno-implicit-float-conversion', - '-Wno-implicit-int-conversion', - '-Wno-nullability-extension', - '-Wno-nullable-to-nonnull-conversion', - '-Wno-padded', - '-Wno-reserved-id-macro', - '-Wno-shadow-field', - '-Wno-shorten-64-to-32', - '-Wno-sign-conversion', - '-Wno-switch-enum', - '-Wno-unreachable-code', - '-Wno-unused-parameter', - '-Wno-vla', - '-Wno-vla-extension', - '-Wno-weak-vtables', - ], - 'gcc': [ - '-Wno-cast-align', - '-Wno-cast-qual', - '-Wno-conditionally-supported', - '-Wno-conversion', - '-Wno-effc++', - '-Wno-float-conversion', - '-Wno-float-equal', - '-Wno-format', - '-Wno-format-nonliteral', - '-Wno-multiple-inheritance', - '-Wno-padded', - '-Wno-sign-conversion', - '-Wno-stack-protector', - '-Wno-suggest-attribute=format', - '-Wno-suggest-override', - '-Wno-switch-enum', - '-Wno-unreachable-code', - '-Wno-unused-parameter', - '-Wno-useless-cast', - '-Wno-vla', - ], - }) - - conf.check_cxx(header_name='boost/intrusive/slist.hpp') - - conf.check_pkg('lv2 >= 1.16.0', uselib_store='LV2') - conf.check_pkg('lilv-0 >= 0.21.5', uselib_store='LILV') - conf.check_pkg('suil-0 >= 0.8.7', uselib_store='SUIL') - conf.check_pkg('sratom-0 >= 0.4.6', uselib_store='SRATOM') - conf.check_pkg('raul-1 >= 1.1.0', uselib_store='RAUL') - conf.check_pkg('serd-0 >= 0.30.3', uselib_store='SERD', mandatory=False) - conf.check_pkg('sord-0 >= 0.12.0', uselib_store='SORD', mandatory=False) - - conf.check_pkg('portaudio-2.0', - uselib_store = 'PORTAUDIO', - system = True, - mandatory = False) - - conf.check_pkg('sigc++-2.0', - uselib_store = 'SIGCPP', - system = True, - mandatory = False) - - conf.check_function('cxx', 'posix_memalign', - defines = '_POSIX_C_SOURCE=200809L', - header_name = 'stdlib.h', - define_name = 'HAVE_POSIX_MEMALIGN', - return_type = 'int', - arg_types = 'void**,size_t,size_t', - mandatory = False) - - conf.check_function('cxx', 'isatty', - header_name = 'unistd.h', - defines = '_POSIX_C_SOURCE=200809L', - define_name = 'HAVE_ISATTY', - return_type = 'int', - arg_types = 'int', - mandatory = False) - - conf.check_function('cxx', 'vasprintf', - header_name = 'stdio.h', - defines = '_GNU_SOURCE=1', - define_name = 'HAVE_VASPRINTF', - return_type = 'int', - arg_types = 'char**,const char*,va_list', - mandatory = False) - - conf.check(define_name = 'HAVE_LIBDL', - lib = 'dl', - mandatory = False) - - if not Options.options.no_socket: - conf.check_function('cxx', 'socket', - header_name = 'sys/socket.h', - define_name = 'HAVE_SOCKET', - return_type = 'int', - arg_types = 'int,int,int', - mandatory = False) - - if not Options.options.no_python: - conf.check_python_version((2, 4, 0), mandatory=False) - - if not Options.options.no_plugin: - conf.env.INGEN_BUILD_LV2 = 1 - - if not Options.options.no_jack: - conf.check_pkg('jack >= 0.120.0', - uselib_store = 'JACK', - system = True, - mandatory = False) - - conf.check_function('cxx', 'jack_set_property', - header_name = 'jack/metadata.h', - define_name = 'HAVE_JACK_METADATA', - uselib = 'JACK', - return_type = 'int', - arg_types = '''jack_client_t*, - jack_uuid_t, - const char*, - const char*, - const char*''', - mandatory = False) - conf.check_function('cxx', 'jack_port_rename', - header_name = 'jack/jack.h', - define_name = 'HAVE_JACK_PORT_RENAME', - uselib = 'JACK', - return_type = 'int', - arg_types = 'jack_client_t*,jack_port_t*,const char*', - mandatory = False) - - if Options.options.debug_urids: - conf.define('INGEN_DEBUG_URIDS', 1) - - conf.env.INGEN_TEST_LINKFLAGS = [] - conf.env.INGEN_TEST_CXXFLAGS = [] - if conf.env.BUILD_TESTS: - if not conf.env.NO_COVERAGE: - conf.env.INGEN_TEST_CXXFLAGS += ['--coverage'] - conf.env.INGEN_TEST_LINKFLAGS += ['--coverage'] - - conf.env.PTHREAD_CFLAGS = [] - conf.env.PTHREAD_LINKFLAGS = [] - if conf.check(cflags=['-pthread'], mandatory=False): - conf.env.PTHREAD_CFLAGS = ['-pthread'] - if conf.check(linkflags=['-pthread'], mandatory=False): - if not (conf.env.DEST_OS == 'darwin' and conf.env.CXX_NAME == 'clang'): - conf.env.PTHREAD_LINKFLAGS += ['-pthread'] - if conf.check(linkflags=['-lpthread'], mandatory=False): - conf.env.PTHREAD_LINKFLAGS += ['-lpthread'] - - conf.define('INGEN_SHARED', 1) - conf.define('INGEN_VERSION', INGEN_VERSION) - - if conf.env.HAVE_SIGCPP and not Options.options.no_client: - conf.env.INGEN_BUILD_CLIENT = 1 - else: - Options.options.no_gui = True - - if not Options.options.no_gui: - conf.recurse('src/gui') - - conf.env.INGEN_MAJOR_VERSION = INGEN_MAJOR_VERSION - - conf.define('INGEN_DATA_DIR', os.path.join(conf.env.DATADIR, 'ingen')) - conf.define('INGEN_MODULE_DIR', conf.env.LIBDIR) - conf.define('INGEN_BUNDLE_DIR', os.path.join(conf.env.LV2DIR, 'ingen.lv2')) - - autowaf.set_lib_env(conf, 'ingen', INGEN_VERSION) - conf.run_env.append_unique('XDG_DATA_DIRS', [str(conf.path.get_bld())]) - for i in ['src', 'modules']: - conf.run_env.append_unique(autowaf.lib_path_name, [str(conf.build_path(i))]) - for i in ['src/client', 'src/server', 'src/gui']: - conf.run_env.append_unique('INGEN_MODULE_PATH', [str(conf.build_path(i))]) - - conf.write_config_header('ingen_config.h', remove=False) - - autowaf.display_summary( - conf, - {'GUI': bool(conf.env.INGEN_BUILD_GUI), - 'HTML plugin doc support': bool(conf.env.HAVE_WEBKIT), - 'PortAudio driver': bool(conf.env.HAVE_PORTAUDIO), - 'Jack driver': bool(conf.env.HAVE_JACK), - 'Jack metadata support': conf.is_defined('HAVE_JACK_METADATA'), - 'LV2 plugin driver': bool(conf.env.INGEN_BUILD_LV2), - 'LV2 bundle': conf.env.INGEN_BUNDLE_DIR, - 'LV2 plugin support': bool(conf.env.HAVE_LILV), - 'Socket interface': conf.is_defined('HAVE_SOCKET')}) - - -unit_tests = ['tst_FilePath'] - - -def build(bld): - opts = Options.options - opts.datadir = opts.datadir or bld.env.PREFIX + 'share' - opts.moduledir = opts.moduledir or bld.env.PREFIX + 'lib/ingen' - - # Headers - for i in ['', 'client']: - bld.install_files('${INCLUDEDIR}/ingen/%s' % i, - bld.path.ant_glob('ingen/%s/*' % i)) - - # Python modules - if bld.env.PYTHONDIR: - bld.install_files('${PYTHONDIR}/', 'scripts/ingen.py') - - # Modules - bld.recurse('src') - bld.recurse('src/server') - - if bld.env.INGEN_BUILD_CLIENT: - bld.recurse('src/client') - - if bld.env.INGEN_BUILD_GUI: - bld.recurse('src/gui') - - # Program - bld(features = 'c cxx cxxprogram', - source = 'src/ingen/ingen.cpp', - target = 'ingen', - includes = ['.', 'include'], - use = 'libingen', - uselib = 'SERD SORD SRATOM RAUL LILV LV2', - install_path = '${BINDIR}') - - # Test program - if bld.env.BUILD_TESTS: - for i in ['ingen_test', 'ingen_bench'] + unit_tests: - bld(features = 'cxx cxxprogram', - source = 'tests/%s.cpp' % i, - target = 'tests/%s' % i, - includes = ['.', 'include'], - use = 'libingen', - uselib = 'SERD SORD SRATOM RAUL LILV LV2', - install_path = '', - cxxflags = bld.env.INGEN_TEST_CXXFLAGS, - linkflags = bld.env.INGEN_TEST_LINKFLAGS) - - bld.install_files('${DATADIR}/applications', 'src/ingen/ingen.desktop') - bld.install_files('${BINDIR}', 'scripts/ingenish', chmod=Utils.O755) - bld.install_files('${BINDIR}', 'scripts/ingenams', chmod=Utils.O755) - - # Code documentation - autowaf.build_dox(bld, 'INGEN', INGEN_VERSION, top, out) - - # Ontology documentation - if bld.env.DOCS: - bld(rule='lv2specgen.py ${SRC} ${TGT} -i -p ingen --copy-style --list-email ingen@drobilla.net --list-page http://lists.drobilla.net/listinfo.cgi/ingen-drobilla.net', - source = 'bundles/ingen.lv2/ingen.ttl', - target = 'ingen.lv2/ingen.html') - - # Man page - bld.install_files('${MANDIR}/man1', 'doc/ingen.1') - - # Icons - icon_dir = os.path.join(bld.env.DATADIR, 'icons', 'hicolor') - icon_sizes = [16, 22, 24, 32, 48, 64, 128, 256] - for s in icon_sizes: - d = '%dx%d' % (s, s) - bld.install_as( - os.path.join(icon_dir, d, 'apps', 'ingen.png'), - os.path.join('icons', d, 'ingen.png')) - - bld.install_as( - os.path.join(icon_dir, 'scalable', 'apps', 'ingen.svg'), - os.path.join('icons', 'scalable', 'ingen.svg')) - - bld.install_files('${LV2DIR}/ingen.lv2/', - bld.path.ant_glob('bundles/ingen.lv2/*')) - - # Install template graph bundles - for c in ['Stereo', 'Mono']: - for t in ['Effect', 'Instrument']: - bundle = '%s%s.ingen' % (c, t) - bld.install_files('${LV2DIR}/%s/' % bundle, - bld.path.ant_glob('bundles/%s/*' % bundle)) - - bld.add_post_fun(autowaf.run_ldconfig) - - -class LintContext(Build.BuildContext): - fun = cmd = 'lint' - - -def lint(ctx): - "checks code for style issues" - import subprocess - import sys - - st = 0 - - if "FLAKE8" in ctx.env: - Logs.info("Running flake8") - for i in ["src/client/wscript", - "src/gui/wscript", - "src/server/wscript", - "src/wscript", - "scripts/ingen.py", - "scripts/ingenish", - "scripts/ingenams", - "wscript"]: - st += subprocess.call([ctx.env.FLAKE8[0], - "--ignore", "E221,W504,E251,E501", - i]) - else: - Logs.warn("Not running flake8") - - if "CLANG_TIDY" in ctx.env and "clang" in ctx.env.CXX[0]: - Logs.info("Running clang-tidy") - - import json - - with open('build/compile_commands.json', 'r') as db: - commands = json.load(db) - files = [c['file'] for c in commands] - - for step_files in zip(*(iter(files),) * Options.options.jobs): - procs = [] - for f in step_files: - cmd = [ctx.env.CLANG_TIDY[0], '--quiet', '-p=.', f] - procs += [subprocess.Popen(cmd, cwd='build')] - - for proc in procs: - proc.communicate() - st += proc.returncode - else: - Logs.warn("Not running clang-tidy") - - if "IWYU_TOOL" in ctx.env: - Logs.info("Running include-what-you-use") - cmd = [ctx.env.IWYU_TOOL[0], "-o", "clang", "-p", "build"] - output = subprocess.check_output(cmd).decode('utf-8') - if 'error: ' in output: - sys.stdout.write(output) - st += 1 - else: - Logs.warn("Not running include-what-you-use") - - if st != 0: - Logs.warn("Lint checks failed") - sys.exit(st) - - -def upload_docs(ctx): - # Ontology documentation - os.system('rsync -avz -e ssh bundles/ingen.lv2/ingen.ttl drobilla@drobilla.net:~/drobilla.net/ns/') - os.system('rsync -avz -e ssh build/ingen.lv2/ingen.html drobilla@drobilla.net:~/drobilla.net/ns/') - os.system('rsync -avz -e ssh build/ingen.lv2/style.css drobilla@drobilla.net:~/drobilla.net/ns/') - - # Doxygen documentation - os.system('rsync -ravz --delete -e ssh build/doc/html/* drobilla@drobilla.net:~/drobilla.net/docs/ingen/') - - -def test(tst): - with tst.group('unit') as check: - for i in unit_tests: - check(['./tests/' + i]) - - with tst.group('integration') as check: - empty = tst.src_path('tests/empty.ingen') - empty_main = os.path.join(empty, 'main.ttl') - for i in tst.path.ant_glob('tests/*.ttl'): - base = os.path.basename(i.abspath().replace('.ttl', '')) - - # Run test - check(['./tests/ingen_test', - '--load', empty, - '--execute', os.path.relpath(i.abspath(), os.getcwd())]) - - # Check undo output for changes - check.file_equals(empty_main, base + '.undo.ingen/main.ttl') - - # Check redo output for changes - check.file_equals(base + '.out.ingen/main.ttl', - base + '.redo.ingen/main.ttl') |