git subrepo clone (merge) https://github.com/free-audio/clap-helpers.git deps/clap-juce-extensions/clap-libs/clap-helpers
subrepo: subdir: "deps/clap-juce-extensions/clap-libs/clap-helpers" merged: "2bb43c187" upstream: origin: "https://github.com/free-audio/clap-helpers.git" branch: "main" commit: "2bb43c187" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596"
This commit is contained in:
parent
8bbddf66e9
commit
7fe70ed89b
@ -1 +0,0 @@
|
|||||||
Subproject commit 2bb43c18788c689708ead6f127a2d75e772ab389
|
|
136
deps/clap-juce-extensions/clap-libs/clap-helpers/.clang-format
vendored
Normal file
136
deps/clap-juce-extensions/clap-libs/clap-helpers/.clang-format
vendored
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -3
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveMacros: true
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: true
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: true
|
||||||
|
AfterObjCDeclaration: true
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: true
|
||||||
|
AfterExternBlock: true
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: true
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 100
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: true
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 3
|
||||||
|
ContinuationIndentWidth: 3
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: false
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: AfterHash
|
||||||
|
IndentWidth: 3
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: All
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
|
ObjCBlockIndentWidth: 3
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Right
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: true
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
Standard: Latest
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 8
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Never
|
||||||
|
...
|
||||||
|
|
12
deps/clap-juce-extensions/clap-libs/clap-helpers/.gitrepo
vendored
Normal file
12
deps/clap-juce-extensions/clap-libs/clap-helpers/.gitrepo
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
; DO NOT EDIT (unless you know what you are doing)
|
||||||
|
;
|
||||||
|
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||||
|
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||||
|
;
|
||||||
|
[subrepo]
|
||||||
|
remote = https://github.com/free-audio/clap-helpers.git
|
||||||
|
branch = main
|
||||||
|
commit = 2bb43c18788c689708ead6f127a2d75e772ab389
|
||||||
|
parent = 8bbddf66e9d6b4b8e0a4fb98122ace8d70a5c14d
|
||||||
|
method = merge
|
||||||
|
cmdver = 0.4.3
|
25
deps/clap-juce-extensions/clap-libs/clap-helpers/CMakeLists.txt
vendored
Normal file
25
deps/clap-juce-extensions/clap-libs/clap-helpers/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.17)
|
||||||
|
cmake_policy(SET CMP0100 NEW) # handle .hh files
|
||||||
|
project(CLAP_HELPERS C CXX)
|
||||||
|
enable_testing()
|
||||||
|
find_package(Catch2 QUIET)
|
||||||
|
|
||||||
|
add_library(clap-helpers INTERFACE)
|
||||||
|
set_target_properties(clap-helpers PROPERTIES
|
||||||
|
POSITION_INDEPENDENT_CODE ON
|
||||||
|
CXX_STANDARD 11)
|
||||||
|
target_include_directories(clap-helpers INTERFACE include)
|
||||||
|
target_link_libraries(clap-helpers INTERFACE clap-core)
|
||||||
|
|
||||||
|
if (Catch2_FOUND)
|
||||||
|
add_executable(clap-helpers-tests
|
||||||
|
tests/plugin.cc
|
||||||
|
tests/main.cc)
|
||||||
|
set_target_properties(clap-helpers-tests PROPERTIES CXX_STANDARD 11)
|
||||||
|
target_link_libraries(clap-helpers-tests clap-helpers clap-core Catch2::Catch2)
|
||||||
|
target_compile_definitions(clap-helpers-tests PUBLIC -DCATCH_CONFIG_PREFIX_ALL)
|
||||||
|
add_test(NAME test-clap-helpers COMMAND clap-helpers-tests)
|
||||||
|
add_dependencies(clap-tests clap-helpers-tests)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(DIRECTORY include DESTINATION ".")
|
21
deps/clap-juce-extensions/clap-libs/clap-helpers/LICENSE
vendored
Normal file
21
deps/clap-juce-extensions/clap-libs/clap-helpers/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 Alexandre BIQUE
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
9
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/checking-level.hh
vendored
Normal file
9
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/checking-level.hh
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace clap { namespace helpers {
|
||||||
|
enum class CheckingLevel {
|
||||||
|
None,
|
||||||
|
Minimal,
|
||||||
|
Maximal,
|
||||||
|
};
|
||||||
|
}} // namespace clap::helpers
|
148
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/event-list.hh
vendored
Normal file
148
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/event-list.hh
vendored
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <clap/events.h>
|
||||||
|
|
||||||
|
#include "heap.hh"
|
||||||
|
|
||||||
|
namespace clap { namespace helpers {
|
||||||
|
|
||||||
|
class EventList {
|
||||||
|
public:
|
||||||
|
explicit EventList(uint32_t initialHeapSize = 4096,
|
||||||
|
uint32_t initialEventsCapacity = 128,
|
||||||
|
uint32_t maxEventSize = 1024)
|
||||||
|
: _maxEventSize(maxEventSize), _heap(initialHeapSize) {
|
||||||
|
_events.reserve(initialEventsCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
EventList(const EventList &) = delete;
|
||||||
|
EventList(EventList &&) = delete;
|
||||||
|
EventList &operator=(const EventList &) = delete;
|
||||||
|
EventList &operator=(EventList &&) = delete;
|
||||||
|
|
||||||
|
static const constexpr size_t SAFE_ALIGN = 8;
|
||||||
|
|
||||||
|
void reserveEvents(size_t capacity) { _events.reserve(capacity); }
|
||||||
|
|
||||||
|
void reserveHeap(size_t size) { _heap.reserve(size); }
|
||||||
|
|
||||||
|
clap_event_header *allocate(size_t align, size_t size) {
|
||||||
|
assert(size >= sizeof(clap_event_header));
|
||||||
|
if (size > _maxEventSize)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// ensure we have space to store into the vector
|
||||||
|
if (_events.capacity() == _events.size())
|
||||||
|
_events.reserve(_events.capacity() * 2);
|
||||||
|
|
||||||
|
auto ptr = _heap.allocate(align, size);
|
||||||
|
_events.push_back(_heap.offsetFromBase(ptr));
|
||||||
|
auto hdr = static_cast<clap_event_header *>(ptr);
|
||||||
|
hdr->size = size;
|
||||||
|
return hdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
clap_event_header *tryAllocate(size_t align, size_t size) {
|
||||||
|
assert(size >= sizeof(clap_event_header));
|
||||||
|
if (size > _maxEventSize)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// ensure we have space to store into the vector
|
||||||
|
if (_events.capacity() == _events.size())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto ptr = _heap.tryAllocate(align, size);
|
||||||
|
if (!ptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
_events.push_back(_heap.offsetFromBase(ptr));
|
||||||
|
auto hdr = static_cast<clap_event_header *>(ptr);
|
||||||
|
hdr->size = size;
|
||||||
|
return hdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T *allocate() {
|
||||||
|
return allocate(alignof(T), sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
void push(const clap_event_header *h) {
|
||||||
|
auto ptr = allocate(SAFE_ALIGN, h->size);
|
||||||
|
if (!ptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::memcpy(ptr, h, h->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tryPush(const clap_event_header *h) {
|
||||||
|
auto ptr = tryAllocate(SAFE_ALIGN, h->size);
|
||||||
|
if (!ptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::memcpy(ptr, h, h->size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
clap_event_header *get(uint32_t index) const {
|
||||||
|
const auto offset = _events.at(index);
|
||||||
|
auto const ptr = _heap.ptrFromBase(offset);
|
||||||
|
return static_cast<clap_event_header *>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const { return _events.size(); }
|
||||||
|
|
||||||
|
bool empty() const { return _events.empty(); }
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
_heap.clear();
|
||||||
|
_events.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const clap_input_events *clapInputEvents() const noexcept { return &_inputEvents; }
|
||||||
|
|
||||||
|
const clap_output_events *clapOutputEvents() const noexcept { return &_outputEvents; }
|
||||||
|
|
||||||
|
const clap_output_events *clapBoundedOutputEvents() const noexcept {
|
||||||
|
return &_boundedOutputEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static uint32_t clapSize(const struct clap_input_events *list) {
|
||||||
|
auto *self = static_cast<const EventList *>(list->ctx);
|
||||||
|
return self->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const clap_event_header_t *clapGet(const struct clap_input_events *list,
|
||||||
|
uint32_t index) {
|
||||||
|
auto *self = static_cast<const EventList *>(list->ctx);
|
||||||
|
return self->get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool clapPushBack(const struct clap_output_events *list,
|
||||||
|
const clap_event_header *event) {
|
||||||
|
auto *self = static_cast<EventList *>(list->ctx);
|
||||||
|
self->push(event);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool clapBoundedPushBack(const struct clap_output_events *list,
|
||||||
|
const clap_event_header_t *event) {
|
||||||
|
auto *self = static_cast<EventList *>(list->ctx);
|
||||||
|
return self->tryPush(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
const clap_input_events _inputEvents = {this, &clapSize, &clapGet};
|
||||||
|
const clap_output_events _outputEvents = {this, &clapPushBack};
|
||||||
|
const clap_output_events _boundedOutputEvents = {this, &clapBoundedPushBack};
|
||||||
|
|
||||||
|
const uint32_t _maxEventSize;
|
||||||
|
|
||||||
|
Heap _heap;
|
||||||
|
std::vector<uint32_t> _events;
|
||||||
|
};
|
||||||
|
|
||||||
|
}} // namespace clap::helpers
|
84
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/heap.hh
vendored
Normal file
84
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/heap.hh
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace clap { namespace helpers {
|
||||||
|
|
||||||
|
/** Simple heap allocator which ensures alignment. */
|
||||||
|
class Heap {
|
||||||
|
public:
|
||||||
|
explicit Heap(uint32_t initialSize = 4096) { reserve(initialSize); }
|
||||||
|
~Heap() { std::free(_base); }
|
||||||
|
|
||||||
|
Heap(const Heap &) = delete;
|
||||||
|
Heap(Heap &&) = delete;
|
||||||
|
Heap &operator=(const Heap &) = delete;
|
||||||
|
Heap &operator=(Heap &&) = delete;
|
||||||
|
|
||||||
|
void reserve(const size_t heapSize) {
|
||||||
|
if (heapSize <= _size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto *const ptr = static_cast<uint8_t *>(std::realloc(_base, heapSize));
|
||||||
|
if (!ptr)
|
||||||
|
throw std::bad_alloc();
|
||||||
|
|
||||||
|
_base = ptr;
|
||||||
|
_size = heapSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() { _brk = 0; }
|
||||||
|
|
||||||
|
void *tryAllocate(uint32_t align, uint32_t size) {
|
||||||
|
assert(_brk <= _size);
|
||||||
|
void *ptr = _base + _brk;
|
||||||
|
size_t space = _size - _brk;
|
||||||
|
|
||||||
|
if (!std::align(align, size, ptr, space))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto offset = static_cast<uint8_t *>(ptr) - _base;
|
||||||
|
_brk = offset + size;
|
||||||
|
std::memset(ptr, 0, size);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *allocate(uint32_t align, uint32_t size) {
|
||||||
|
assert(_brk <= _size);
|
||||||
|
if (size + _brk > _size)
|
||||||
|
reserve(_size * 2);
|
||||||
|
|
||||||
|
auto ptr = tryAllocate(align, size);
|
||||||
|
assert(ptr);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ptrFromBase(size_t offset) const {
|
||||||
|
assert(offset <= _brk && "out of range");
|
||||||
|
|
||||||
|
return static_cast<uint8_t *>(_base) + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t offsetFromBase(const void *ptr) const {
|
||||||
|
assert(ptr >= _base && "ptr before heap's base");
|
||||||
|
size_t offset = static_cast<const uint8_t *>(ptr) - _base;
|
||||||
|
assert(offset < _size && "ptr after heap's end");
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const { return _size; }
|
||||||
|
|
||||||
|
bool empty() const { return _brk == 0; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t _size = 0;
|
||||||
|
size_t _brk = 0;
|
||||||
|
uint8_t *_base = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
}} // namespace clap::helpers
|
170
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/host-proxy.hh
vendored
Normal file
170
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/host-proxy.hh
vendored
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <clap/clap.h>
|
||||||
|
|
||||||
|
#include "checking-level.hh"
|
||||||
|
#include "misbehaviour-handler.hh"
|
||||||
|
|
||||||
|
namespace clap { namespace helpers {
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
class HostProxy {
|
||||||
|
public:
|
||||||
|
HostProxy(const clap_host *host);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// clap_host //
|
||||||
|
///////////////
|
||||||
|
template <typename T>
|
||||||
|
void getExtension(const T *&ptr, const char *id) noexcept;
|
||||||
|
void requestCallback() noexcept;
|
||||||
|
void requestRestart() noexcept;
|
||||||
|
void requestProcess() noexcept;
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
// clap_host_log //
|
||||||
|
///////////////////
|
||||||
|
bool canUseHostLog() const noexcept;
|
||||||
|
void log(clap_log_severity severity, const char *msg) const noexcept;
|
||||||
|
void hostMisbehaving(const char *msg) const noexcept;
|
||||||
|
void hostMisbehaving(const std::string &msg) const noexcept { hostMisbehaving(msg.c_str()); }
|
||||||
|
void pluginMisbehaving(const char *msg) const noexcept;
|
||||||
|
void pluginMisbehaving(const std::string &msg) const noexcept {
|
||||||
|
pluginMisbehaving(msg.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
// clap_host_thread_check //
|
||||||
|
////////////////////////////
|
||||||
|
bool canUseThreadCheck() const noexcept;
|
||||||
|
bool isMainThread() const noexcept;
|
||||||
|
bool isAudioThread() const noexcept;
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// clap_host_audio_ports_config //
|
||||||
|
//////////////////////////////////
|
||||||
|
bool canUseAudioPortsConfig() const noexcept;
|
||||||
|
void audioPortsConfigRescan() const noexcept;
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
// clap_host_audio_ports //
|
||||||
|
///////////////////////////
|
||||||
|
bool canUseAudioPorts() const noexcept;
|
||||||
|
void audioPortsRescan(uint32_t flags) const noexcept;
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// clap_host_note_ports //
|
||||||
|
//////////////////////////
|
||||||
|
bool canUseNotePorts() const noexcept;
|
||||||
|
void notePortsRescan(uint32_t flags) const noexcept;
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
// clap_host_state //
|
||||||
|
/////////////////////
|
||||||
|
bool canUseState() const noexcept;
|
||||||
|
void stateMarkDirty() const noexcept;
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
// clap_host_latency //
|
||||||
|
///////////////////////
|
||||||
|
bool canUseLatency() const noexcept;
|
||||||
|
void latencyChanged() const noexcept;
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
// clap_host_tail //
|
||||||
|
////////////////////
|
||||||
|
bool canUseTail() const noexcept;
|
||||||
|
void tailChanged() const noexcept;
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
|
// clap_host_note_name //
|
||||||
|
/////////////////////////
|
||||||
|
bool canUseNoteName() const noexcept;
|
||||||
|
void noteNameChanged() const noexcept;
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
// clap_host_params //
|
||||||
|
//////////////////////
|
||||||
|
bool canUseParams() const noexcept;
|
||||||
|
void paramsRescan(clap_param_rescan_flags flags) const noexcept;
|
||||||
|
void paramsClear(clap_id param_id, clap_param_clear_flags flags) const noexcept;
|
||||||
|
void paramsRequestFlush() const noexcept;
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// clap_host_track_info //
|
||||||
|
//////////////////////////
|
||||||
|
bool canUseTrackInfo() const noexcept;
|
||||||
|
bool trackInfoGet(clap_track_info *info) const noexcept;
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
// clap_host_gui //
|
||||||
|
///////////////////
|
||||||
|
bool canUseGui() const noexcept;
|
||||||
|
bool guiRequestResize(uint32_t width, uint32_t height) const noexcept;
|
||||||
|
bool guiRequestShow() const noexcept;
|
||||||
|
bool guiRequestHide() const noexcept;
|
||||||
|
void guiClosed(bool wasDestroyed) const noexcept;
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// clap_host_timer_support //
|
||||||
|
/////////////////////////////
|
||||||
|
bool canUseTimerSupport() const noexcept;
|
||||||
|
bool timerSupportRegister(uint32_t period_ms, clap_id *timer_id) const noexcept;
|
||||||
|
bool timerSupportUnregister(clap_id timer_id) const noexcept;
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// clap_host_fd_support //
|
||||||
|
//////////////////////////
|
||||||
|
bool canUsePosixFdSupport() const noexcept;
|
||||||
|
bool posixFdSupportRegister(int fd, int flags) const noexcept;
|
||||||
|
bool posixFdSupportModify(int fd, int flags) const noexcept;
|
||||||
|
bool posixFdSupportUnregister(int fd) const noexcept;
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// clap_host_quick_controls //
|
||||||
|
//////////////////////////////
|
||||||
|
bool canUseQuickControls() const noexcept;
|
||||||
|
void quickControlsChanged() const noexcept;
|
||||||
|
void quickControlsSuggestPage(clap_id page_id) const noexcept;
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
// clap_host_thread_pool //
|
||||||
|
///////////////////////////
|
||||||
|
bool canUseThreadPool() const noexcept;
|
||||||
|
bool threadPoolRequestExec(uint32_t numTasks) const noexcept;
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// clap_host_voice_info //
|
||||||
|
//////////////////////////
|
||||||
|
bool canUseVoiceInfo() const noexcept;
|
||||||
|
void voiceInfoChanged() const noexcept;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void ensureMainThread(const char *method) const noexcept;
|
||||||
|
void ensureAudioThread(const char *method) const noexcept;
|
||||||
|
|
||||||
|
const clap_host *const _host;
|
||||||
|
|
||||||
|
const clap_host_log *_hostLog = nullptr;
|
||||||
|
const clap_host_thread_check *_hostThreadCheck = nullptr;
|
||||||
|
const clap_host_thread_pool *_hostThreadPool = nullptr;
|
||||||
|
const clap_host_audio_ports *_hostAudioPorts = nullptr;
|
||||||
|
const clap_host_audio_ports_config *_hostAudioPortsConfig = nullptr;
|
||||||
|
const clap_host_note_ports *_hostNotePorts = nullptr;
|
||||||
|
const clap_host_file_reference *_hostFileReference = nullptr;
|
||||||
|
const clap_host_latency *_hostLatency = nullptr;
|
||||||
|
const clap_host_gui *_hostGui = nullptr;
|
||||||
|
const clap_host_timer_support *_hostTimerSupport = nullptr;
|
||||||
|
const clap_host_posix_fd_support *_hostPosixFdSupport = nullptr;
|
||||||
|
const clap_host_params *_hostParams = nullptr;
|
||||||
|
const clap_host_track_info *_hostTrackInfo = nullptr;
|
||||||
|
const clap_host_state *_hostState = nullptr;
|
||||||
|
const clap_host_note_name *_hostNoteName = nullptr;
|
||||||
|
const clap_host_quick_controls *_hostQuickControls = nullptr;
|
||||||
|
const clap_host_voice_info *_hostVoiceInfo = nullptr;
|
||||||
|
const clap_host_tail *_hostTail = nullptr;
|
||||||
|
};
|
||||||
|
}} // namespace clap::helpers
|
546
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/host-proxy.hxx
vendored
Normal file
546
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/host-proxy.hxx
vendored
Normal file
@ -0,0 +1,546 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "host-proxy.hh"
|
||||||
|
|
||||||
|
namespace clap { namespace helpers {
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
HostProxy<h, l>::HostProxy(const ::clap_host *host) : _host(host) {}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::init() {
|
||||||
|
getExtension(_hostLog, CLAP_EXT_LOG);
|
||||||
|
getExtension(_hostThreadCheck, CLAP_EXT_THREAD_CHECK);
|
||||||
|
getExtension(_hostThreadPool, CLAP_EXT_THREAD_POOL);
|
||||||
|
getExtension(_hostAudioPorts, CLAP_EXT_AUDIO_PORTS);
|
||||||
|
getExtension(_hostAudioPortsConfig, CLAP_EXT_AUDIO_PORTS_CONFIG);
|
||||||
|
getExtension(_hostNotePorts, CLAP_EXT_NOTE_PORTS);
|
||||||
|
getExtension(_hostTimerSupport, CLAP_EXT_TIMER_SUPPORT);
|
||||||
|
getExtension(_hostPosixFdSupport, CLAP_EXT_POSIX_FD_SUPPORT);
|
||||||
|
getExtension(_hostFileReference, CLAP_EXT_FILE_REFERENCE);
|
||||||
|
getExtension(_hostLatency, CLAP_EXT_LATENCY);
|
||||||
|
getExtension(_hostGui, CLAP_EXT_GUI);
|
||||||
|
getExtension(_hostParams, CLAP_EXT_PARAMS);
|
||||||
|
getExtension(_hostTrackInfo, CLAP_EXT_TRACK_INFO);
|
||||||
|
getExtension(_hostState, CLAP_EXT_STATE);
|
||||||
|
getExtension(_hostNoteName, CLAP_EXT_NOTE_NAME);
|
||||||
|
getExtension(_hostQuickControls, CLAP_EXT_QUICK_CONTROLS);
|
||||||
|
getExtension(_hostVoiceInfo, CLAP_EXT_VOICE_INFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
template <typename T>
|
||||||
|
void HostProxy<h, l>::getExtension(const T *&ptr, const char *id) noexcept {
|
||||||
|
assert(!ptr);
|
||||||
|
assert(id);
|
||||||
|
|
||||||
|
if (_host->get_extension)
|
||||||
|
ptr = static_cast<const T *>(_host->get_extension(_host, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// clap_host //
|
||||||
|
///////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::requestCallback() noexcept {
|
||||||
|
_host->request_callback(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::requestRestart() noexcept {
|
||||||
|
_host->request_restart(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::requestProcess() noexcept {
|
||||||
|
_host->request_process(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// Logging //
|
||||||
|
/////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseHostLog() const noexcept {
|
||||||
|
return _hostLog && _hostLog->log;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::log(clap_log_severity severity, const char *msg) const noexcept {
|
||||||
|
if (canUseHostLog()) {
|
||||||
|
_hostLog->log(_host, severity, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (severity) {
|
||||||
|
case CLAP_LOG_ERROR:
|
||||||
|
case CLAP_LOG_HOST_MISBEHAVING:
|
||||||
|
std::cerr << msg << std::endl;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
std::clog << msg << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::hostMisbehaving(const char *msg) const noexcept {
|
||||||
|
log(CLAP_LOG_HOST_MISBEHAVING, msg);
|
||||||
|
|
||||||
|
if (h == MisbehaviourHandler::Terminate)
|
||||||
|
std::terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::pluginMisbehaving(const char *msg) const noexcept {
|
||||||
|
log(CLAP_LOG_PLUGIN_MISBEHAVING, msg);
|
||||||
|
|
||||||
|
if (h == MisbehaviourHandler::Terminate)
|
||||||
|
std::terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////
|
||||||
|
// Thread Check //
|
||||||
|
//////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseThreadCheck() const noexcept {
|
||||||
|
return _hostThreadCheck && _hostThreadCheck->is_audio_thread &&
|
||||||
|
_hostThreadCheck->is_main_thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::isMainThread() const noexcept {
|
||||||
|
assert(canUseThreadCheck());
|
||||||
|
return _hostThreadCheck->is_main_thread(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::isAudioThread() const noexcept {
|
||||||
|
assert(canUseThreadCheck());
|
||||||
|
return _hostThreadCheck->is_audio_thread(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::ensureMainThread(const char *method) const noexcept {
|
||||||
|
if (l == CheckingLevel::None)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!canUseThreadCheck() || isMainThread())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::ostringstream msg;
|
||||||
|
msg << "Plugin called the method clap_host_" << method
|
||||||
|
<< "() on wrong thread! It must be called on main thread!";
|
||||||
|
pluginMisbehaving(msg.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::ensureAudioThread(const char *method) const noexcept {
|
||||||
|
if (l == CheckingLevel::None)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!canUseThreadCheck() || isAudioThread())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::ostringstream msg;
|
||||||
|
msg << "Plugin called the method clap_host_" << method
|
||||||
|
<< "() on wrong thread! It must be called on audio thread!";
|
||||||
|
pluginMisbehaving(msg.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// clap_host_audio_ports_config //
|
||||||
|
//////////////////////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseAudioPortsConfig() const noexcept {
|
||||||
|
if (!_hostAudioPortsConfig)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_hostAudioPortsConfig->rescan)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_host_audio_ports_config is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::audioPortsConfigRescan() const noexcept {
|
||||||
|
assert(canUseAudioPortsConfig());
|
||||||
|
ensureMainThread("audio_ports_config.rescan");
|
||||||
|
_hostAudioPortsConfig->rescan(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
// clap_host_audio_ports //
|
||||||
|
///////////////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseAudioPorts() const noexcept {
|
||||||
|
if (!_hostAudioPorts)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_hostAudioPorts->rescan)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_host_audio_ports is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::audioPortsRescan(uint32_t flags) const noexcept {
|
||||||
|
assert(canUseAudioPorts());
|
||||||
|
ensureMainThread("audio_ports.rescan");
|
||||||
|
_hostAudioPorts->rescan(_host, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// clap_host_note_ports //
|
||||||
|
//////////////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseNotePorts() const noexcept {
|
||||||
|
if (!_hostNotePorts)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_hostNotePorts->rescan)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_host_note_ports is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::notePortsRescan(uint32_t flags) const noexcept {
|
||||||
|
assert(canUseNotePorts());
|
||||||
|
ensureMainThread("note_ports.rescan");
|
||||||
|
_hostNotePorts->rescan(_host, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
// clap_host_state //
|
||||||
|
/////////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseState() const noexcept {
|
||||||
|
if (!_hostState)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_hostState->mark_dirty)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_host_state is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::stateMarkDirty() const noexcept {
|
||||||
|
assert(canUseState());
|
||||||
|
ensureMainThread("state.mark_dirty");
|
||||||
|
_hostState->mark_dirty(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
// clap_host_latency //
|
||||||
|
///////////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseLatency() const noexcept {
|
||||||
|
if (!_hostLatency)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_hostLatency->changed)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_host_latency is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::latencyChanged() const noexcept {
|
||||||
|
assert(canUseLatency());
|
||||||
|
ensureMainThread("latency.changed");
|
||||||
|
_hostLatency->changed(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
// clap_host_tail //
|
||||||
|
////////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseTail() const noexcept {
|
||||||
|
if (!_hostTail)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_hostLatency->changed)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_host_tail is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::tailChanged() const noexcept {
|
||||||
|
assert(canUseTail());
|
||||||
|
ensureAudioThread("tail.changed");
|
||||||
|
_hostTail->changed(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
|
// clap_host_note_name //
|
||||||
|
/////////////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseNoteName() const noexcept {
|
||||||
|
if (!_hostNoteName)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_hostNoteName->changed)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_host_note_name is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::noteNameChanged() const noexcept {
|
||||||
|
assert(canUseNoteName());
|
||||||
|
ensureMainThread("note_name.changed");
|
||||||
|
_hostNoteName->changed(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
// clap_host_params //
|
||||||
|
//////////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseParams() const noexcept {
|
||||||
|
if (!_hostParams)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_hostParams->rescan && _hostParams->clear && _hostParams->request_flush)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_host_params is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::paramsRescan(clap_param_rescan_flags flags) const noexcept {
|
||||||
|
assert(canUseParams());
|
||||||
|
ensureMainThread("params.rescan");
|
||||||
|
_hostParams->rescan(_host, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::paramsClear(clap_id param_id,
|
||||||
|
clap_param_clear_flags flags) const noexcept {
|
||||||
|
assert(canUseParams());
|
||||||
|
ensureMainThread("params.clear");
|
||||||
|
_hostParams->clear(_host, param_id, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::paramsRequestFlush() const noexcept {
|
||||||
|
assert(canUseParams());
|
||||||
|
_hostParams->request_flush(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// clap_host_track_info //
|
||||||
|
//////////////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseTrackInfo() const noexcept {
|
||||||
|
if (!_hostTrackInfo)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_hostTrackInfo->get)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_host_track_info is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::trackInfoGet(clap_track_info *info) const noexcept {
|
||||||
|
assert(canUseTrackInfo());
|
||||||
|
ensureMainThread("track_info.get");
|
||||||
|
return _hostTrackInfo->get(_host, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
// clap_host_gui //
|
||||||
|
///////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseGui() const noexcept {
|
||||||
|
if (!_hostGui)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_hostGui->resize_hints_changed && _hostGui->request_resize && _hostGui->request_hide &&
|
||||||
|
_hostGui->request_show && _hostGui->closed)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_host_gui is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::guiRequestResize(uint32_t width, uint32_t height) const noexcept {
|
||||||
|
assert(canUseGui());
|
||||||
|
return _hostGui->request_resize(_host, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::guiRequestShow() const noexcept {
|
||||||
|
assert(canUseGui());
|
||||||
|
return _hostGui->request_show(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::guiRequestHide() const noexcept {
|
||||||
|
assert(canUseGui());
|
||||||
|
return _hostGui->request_hide(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::guiClosed(bool wasDestroyed) const noexcept {
|
||||||
|
assert(canUseGui());
|
||||||
|
_hostGui->closed(_host, wasDestroyed);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
// Timer Support //
|
||||||
|
///////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseTimerSupport() const noexcept {
|
||||||
|
if (!_hostTimerSupport)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto &x = *_hostTimerSupport;
|
||||||
|
if (x.register_timer && x.unregister_timer)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_timer_support is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::timerSupportRegister(uint32_t period_ms,
|
||||||
|
clap_id *timer_id) const noexcept {
|
||||||
|
assert(canUseTimerSupport());
|
||||||
|
ensureMainThread("timer_support.register_timer");
|
||||||
|
return _hostTimerSupport->register_timer(_host, period_ms, timer_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::timerSupportUnregister(clap_id timer_id) const noexcept {
|
||||||
|
assert(canUseTimerSupport());
|
||||||
|
ensureMainThread("timer_support.unregister_timer");
|
||||||
|
return _hostTimerSupport->unregister_timer(_host, timer_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// clap_host_fd_support //
|
||||||
|
//////////////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUsePosixFdSupport() const noexcept {
|
||||||
|
if (!_hostPosixFdSupport)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto &x = *_hostPosixFdSupport;
|
||||||
|
if (x.modify_fd && x.register_fd && x.unregister_fd)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_posix_fd_support is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::posixFdSupportRegister(int fd, int flags) const noexcept {
|
||||||
|
assert(canUsePosixFdSupport());
|
||||||
|
ensureMainThread("posix_fd_support.register");
|
||||||
|
return _hostPosixFdSupport->register_fd(_host, fd, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::posixFdSupportModify(int fd, int flags) const noexcept {
|
||||||
|
assert(canUsePosixFdSupport());
|
||||||
|
ensureMainThread("posix_fd_support.modify");
|
||||||
|
return _hostPosixFdSupport->modify_fd(_host, fd, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::posixFdSupportUnregister(int fd) const noexcept {
|
||||||
|
assert(canUsePosixFdSupport());
|
||||||
|
ensureMainThread("posix_fd_support.unregister");
|
||||||
|
return _hostPosixFdSupport->unregister_fd(_host, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
// clap_host_thread_pool //
|
||||||
|
///////////////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseThreadPool() const noexcept {
|
||||||
|
if (!_hostThreadPool)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_hostThreadPool->request_exec)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_host_thread_pool is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::threadPoolRequestExec(uint32_t numTasks) const noexcept {
|
||||||
|
assert(canUseThreadPool());
|
||||||
|
ensureAudioThread("thread_pool.request_exec");
|
||||||
|
return _hostThreadPool->request_exec(_host, numTasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// clap_host_voice_info //
|
||||||
|
//////////////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseVoiceInfo() const noexcept {
|
||||||
|
if (!_hostVoiceInfo)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_hostVoiceInfo->changed)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_host_voice_info is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::voiceInfoChanged() const noexcept {
|
||||||
|
assert(canUseVoiceInfo());
|
||||||
|
ensureMainThread("voice_info.changed");
|
||||||
|
return _hostVoiceInfo->changed(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// clap_host_quick_controls //
|
||||||
|
//////////////////////////////
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
bool HostProxy<h, l>::canUseQuickControls() const noexcept {
|
||||||
|
if (!_hostQuickControls)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_hostQuickControls->changed && _hostQuickControls->suggest_page)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostMisbehaving("clap_host_quick_controls is partially implemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::quickControlsChanged() const noexcept {
|
||||||
|
assert(canUseQuickControls());
|
||||||
|
ensureMainThread("quick_controls.changed");
|
||||||
|
_hostQuickControls->changed(_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
void HostProxy<h, l>::quickControlsSuggestPage(clap_id page_id) const noexcept {
|
||||||
|
assert(canUseQuickControls());
|
||||||
|
ensureMainThread("quick_controls.suggest_page");
|
||||||
|
_hostQuickControls->suggest_page(_host, page_id);
|
||||||
|
}
|
||||||
|
}} // namespace clap::helpers
|
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace clap { namespace helpers {
|
||||||
|
enum class MisbehaviourHandler {
|
||||||
|
Ignore,
|
||||||
|
Terminate,
|
||||||
|
};
|
||||||
|
}} // namespace clap::helpers
|
75
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/note-end-queue.hh
vendored
Normal file
75
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/note-end-queue.hh
vendored
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include <cassert>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
#include <clap/clap.h>
|
||||||
|
|
||||||
|
namespace clap { namespace helpers {
|
||||||
|
class NoteEndQueue {
|
||||||
|
public:
|
||||||
|
explicit NoteEndQueue(std::size_t initialBucketSize = 19)
|
||||||
|
: _voicesToKill(initialBucketSize) {}
|
||||||
|
|
||||||
|
void onNoteOn(int32_t noteId, int16_t port, int16_t channel, int16_t key) {
|
||||||
|
assert(checkValidEntry(noteId, port, channel, key));
|
||||||
|
_voicesToKill.erase(Entry(noteId, port, channel, key));
|
||||||
|
}
|
||||||
|
|
||||||
|
void onNoteEnd(int32_t noteId, int16_t port, int16_t channel, int16_t key) {
|
||||||
|
assert(checkValidEntry(noteId, port, channel, key));
|
||||||
|
_voicesToKill.insert(Entry(noteId, port, channel, key));
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush(const clap_output_events *out) {
|
||||||
|
clap_event_note ev;
|
||||||
|
ev.velocity = 0;
|
||||||
|
ev.header.flags = 0;
|
||||||
|
ev.header.size = sizeof(ev);
|
||||||
|
ev.header.space_id = CLAP_CORE_EVENT_SPACE_ID;
|
||||||
|
ev.header.time = 0; // time is irrelevant here
|
||||||
|
ev.header.type = CLAP_EVENT_NOTE_END;
|
||||||
|
|
||||||
|
for (auto &e : _voicesToKill) {
|
||||||
|
ev.port_index = e._port;
|
||||||
|
ev.channel = e._channel;
|
||||||
|
ev.key = e._key;
|
||||||
|
ev.note_id = e._noteId;
|
||||||
|
out->try_push(out, &ev.header);
|
||||||
|
}
|
||||||
|
|
||||||
|
_voicesToKill.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool checkValidEntry(int32_t noteId, int16_t port, int16_t channel, int16_t key) {
|
||||||
|
assert(noteId >= -1);
|
||||||
|
assert(port >= 0);
|
||||||
|
assert(channel >= 0 && channel < 16);
|
||||||
|
assert(key >= 0 && key < 127);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Entry {
|
||||||
|
constexpr Entry(int32_t noteId, int16_t port, int16_t channel, int16_t key)
|
||||||
|
: _noteId(noteId), _port(port), _channel(channel), _key(key) {}
|
||||||
|
|
||||||
|
constexpr bool operator==(const Entry &o) const noexcept {
|
||||||
|
return _port == o._port && _channel == o._channel && _key == o._key;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int32_t _noteId;
|
||||||
|
const int16_t _port;
|
||||||
|
const int16_t _channel;
|
||||||
|
const int16_t _key;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EntryHash {
|
||||||
|
std::size_t operator()(const Entry &e) const noexcept {
|
||||||
|
return e._key ^ (e._channel << 8) ^ (e._port << 16) ^ (int64_t(e._noteId) << 32LL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_set<Entry, EntryHash> _voicesToKill;
|
||||||
|
};
|
||||||
|
}} // namespace clap::helpers
|
71
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/param-queue.hh
vendored
Normal file
71
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/param-queue.hh
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <atomic>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace clap { namespace helpers {
|
||||||
|
template <typename T, size_t CAPACITY>
|
||||||
|
class ParamQueue {
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
|
||||||
|
ParamQueue() = default;
|
||||||
|
|
||||||
|
void push(const T &value) {
|
||||||
|
while (!tryPush(value))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tryPush(const T &value) {
|
||||||
|
int w = _writeOffset; // write element
|
||||||
|
int wn = (w + 1) % CAPACITY; // next write element
|
||||||
|
|
||||||
|
if (wn == _readOffset)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_data[w] = value;
|
||||||
|
_writeOffset = wn;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tryPeek(T &value) {
|
||||||
|
int r = _readOffset;
|
||||||
|
if (r == _writeOffset)
|
||||||
|
return false; // empty
|
||||||
|
|
||||||
|
value = _data[r];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void consume() {
|
||||||
|
int r = _readOffset;
|
||||||
|
if (r == _writeOffset) {
|
||||||
|
assert(false && "consume should not have been called");
|
||||||
|
return; // empty
|
||||||
|
}
|
||||||
|
|
||||||
|
int rn = (r + 1) % CAPACITY;
|
||||||
|
_readOffset = rn;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tryPop(T &value) {
|
||||||
|
if (!tryPeek(value))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
consume();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
_writeOffset = 0;
|
||||||
|
_readOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::array<T, CAPACITY> _data;
|
||||||
|
std::atomic<int> _writeOffset = {0};
|
||||||
|
std::atomic<int> _readOffset = {0};
|
||||||
|
};
|
||||||
|
}} // namespace clap::helpers
|
37
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/plugin-proxy.hh
vendored
Normal file
37
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/plugin-proxy.hh
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "host-proxy.hh"
|
||||||
|
|
||||||
|
namespace clap { namespace helpers {
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
class PluginProxy {
|
||||||
|
public:
|
||||||
|
PluginProxy(const clap_host *host, const clap_plugin *plugin);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void getExtension(const T *&ptr, const char *id) noexcept;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void ensureMainThread(const char *method) const noexcept;
|
||||||
|
void ensureAudioThread(const char *method) const noexcept;
|
||||||
|
|
||||||
|
HostProxy<h, l> _host;
|
||||||
|
const clap_plugin *const _plugin;
|
||||||
|
|
||||||
|
const clap_plugin_params *_pluginParams = nullptr;
|
||||||
|
const clap_plugin_quick_controls *_pluginQuickControls = nullptr;
|
||||||
|
const clap_plugin_audio_ports *_pluginAudioPorts = nullptr;
|
||||||
|
const clap_plugin_gui *_pluginGui = nullptr;
|
||||||
|
const clap_plugin_gui_x11 *_pluginGuiX11 = nullptr;
|
||||||
|
const clap_plugin_gui_win32 *_pluginGuiWin32 = nullptr;
|
||||||
|
const clap_plugin_gui_cocoa *_pluginGuiCocoa = nullptr;
|
||||||
|
const clap_plugin_gui_free_standing *_pluginGuiFreeStanding = nullptr;
|
||||||
|
const clap_plugin_timer_support *_pluginTimerSupport = nullptr;
|
||||||
|
const clap_plugin_fd_support *_pluginFdSupport = nullptr;
|
||||||
|
const clap_plugin_thread_pool *_pluginThreadPool = nullptr;
|
||||||
|
const clap_plugin_preset_load *_pluginPresetLoad = nullptr;
|
||||||
|
const clap_plugin_state *_pluginState = nullptr;
|
||||||
|
};
|
||||||
|
}} // namespace clap::helpers
|
434
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/plugin.hh
vendored
Normal file
434
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/plugin.hh
vendored
Normal file
@ -0,0 +1,434 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <functional>
|
||||||
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <clap/clap.h>
|
||||||
|
|
||||||
|
#include "checking-level.hh"
|
||||||
|
#include "host-proxy.hh"
|
||||||
|
#include "misbehaviour-handler.hh"
|
||||||
|
|
||||||
|
namespace clap { namespace helpers {
|
||||||
|
|
||||||
|
/// @brief C++ glue and checks
|
||||||
|
///
|
||||||
|
/// @note for an higher level implementation, see @ref PluginHelper
|
||||||
|
template <MisbehaviourHandler h, CheckingLevel l>
|
||||||
|
class Plugin {
|
||||||
|
public:
|
||||||
|
const clap_plugin *clapPlugin() noexcept { return &_plugin; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Plugin(const clap_plugin_descriptor *desc, const clap_host *host);
|
||||||
|
virtual ~Plugin() = default;
|
||||||
|
|
||||||
|
// not copyable, not moveable
|
||||||
|
Plugin(const Plugin &) = delete;
|
||||||
|
Plugin(Plugin &&) = delete;
|
||||||
|
Plugin &operator=(const Plugin &) = delete;
|
||||||
|
Plugin &operator=(Plugin &&) = delete;
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
|
// Methods to override //
|
||||||
|
/////////////////////////
|
||||||
|
|
||||||
|
//-------------//
|
||||||
|
// clap_plugin //
|
||||||
|
//-------------//
|
||||||
|
virtual bool init() noexcept { return true; }
|
||||||
|
virtual bool
|
||||||
|
activate(double sampleRate, uint32_t minFrameCount, uint32_t maxFrameCount) noexcept {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
virtual void deactivate() noexcept {}
|
||||||
|
virtual bool startProcessing() noexcept { return true; }
|
||||||
|
virtual void stopProcessing() noexcept {}
|
||||||
|
virtual clap_process_status process(const clap_process *process) noexcept {
|
||||||
|
return CLAP_PROCESS_SLEEP;
|
||||||
|
}
|
||||||
|
virtual void reset() noexcept {}
|
||||||
|
virtual void onMainThread() noexcept {}
|
||||||
|
virtual const void *extension(const char *id) noexcept { return nullptr; }
|
||||||
|
|
||||||
|
//---------------------//
|
||||||
|
// clap_plugin_latency //
|
||||||
|
//---------------------//
|
||||||
|
virtual bool implementsLatency() const noexcept { return false; }
|
||||||
|
virtual uint32_t latencyGet() const noexcept { return 0; }
|
||||||
|
|
||||||
|
//------------------//
|
||||||
|
// clap_plugin_tail //
|
||||||
|
//------------------//
|
||||||
|
virtual bool implementsTail() const noexcept { return false; }
|
||||||
|
virtual uint32_t tailGet(const clap_plugin_t *plugin) const noexcept { return 0; }
|
||||||
|
|
||||||
|
//--------------------//
|
||||||
|
// clap_plugin_render //
|
||||||
|
//--------------------//
|
||||||
|
virtual bool implementsRender() const noexcept { return false; }
|
||||||
|
virtual bool renderHasHardRealtimeRequirement() noexcept { return false; }
|
||||||
|
virtual bool renderSetMode(clap_plugin_render_mode mode) noexcept { return false; }
|
||||||
|
|
||||||
|
//-------------------------//
|
||||||
|
// clap_plugin_thread_pool //
|
||||||
|
//-------------------------//
|
||||||
|
virtual bool implementsThreadPool() const noexcept { return false; }
|
||||||
|
virtual void threadPoolExec(uint32_t taskIndex) noexcept {}
|
||||||
|
|
||||||
|
//-------------------//
|
||||||
|
// clap_plugin_state //
|
||||||
|
//-------------------//
|
||||||
|
virtual bool implementsState() const noexcept { return false; }
|
||||||
|
virtual bool stateSave(const clap_ostream *stream) noexcept { return false; }
|
||||||
|
virtual bool stateLoad(const clap_istream *stream) noexcept { return false; }
|
||||||
|
|
||||||
|
//-------------------------//
|
||||||
|
// clap_plugin_preset_load //
|
||||||
|
//-------------------------//
|
||||||
|
virtual bool implementsPresetLoad() const noexcept { return false; }
|
||||||
|
virtual bool presetLoadFromFile(const char *path) noexcept { return false; }
|
||||||
|
|
||||||
|
//------------------------//
|
||||||
|
// clap_plugin_track_info //
|
||||||
|
//------------------------//
|
||||||
|
virtual bool implementsTrackInfo() const noexcept { return false; }
|
||||||
|
virtual void trackInfoChanged() noexcept {}
|
||||||
|
|
||||||
|
//-------------------------//
|
||||||
|
// clap_plugin_audio_ports //
|
||||||
|
//-------------------------//
|
||||||
|
virtual bool implementsAudioPorts() const noexcept { return false; }
|
||||||
|
virtual uint32_t audioPortsCount(bool isInput) const noexcept { return 0; }
|
||||||
|
virtual bool
|
||||||
|
audioPortsInfo(uint32_t index, bool isInput, clap_audio_port_info *info) const noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual uint32_t audioPortsConfigCount() const noexcept { return 0; }
|
||||||
|
virtual bool audioPortsGetConfig(uint32_t index,
|
||||||
|
clap_audio_ports_config *config) const noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual bool audioPortsSetConfig(clap_id configId) noexcept { return false; }
|
||||||
|
|
||||||
|
//--------------------//
|
||||||
|
// clap_plugin_params //
|
||||||
|
//--------------------//
|
||||||
|
virtual bool implementsParams() const noexcept { return false; }
|
||||||
|
virtual uint32_t paramsCount() const noexcept { return 0; }
|
||||||
|
virtual bool paramsInfo(uint32_t paramIndex, clap_param_info *info) const noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual bool paramsValue(clap_id paramId, double *value) noexcept { return false; }
|
||||||
|
virtual bool
|
||||||
|
paramsValueToText(clap_id paramId, double value, char *display, uint32_t size) noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual bool paramsTextToValue(clap_id paramId, const char *display, double *value) noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual void paramsFlush(const clap_input_events *in,
|
||||||
|
const clap_output_events *out) noexcept {}
|
||||||
|
virtual bool isValidParamId(clap_id paramId) const noexcept;
|
||||||
|
|
||||||
|
//----------------------------//
|
||||||
|
// clap_plugin_quick_controls //
|
||||||
|
//----------------------------//
|
||||||
|
virtual bool implementQuickControls() const noexcept { return false; }
|
||||||
|
virtual uint32_t quickControlsPageCount() noexcept { return 0; }
|
||||||
|
virtual bool quickControlsPageGet(uint32_t pageIndex,
|
||||||
|
clap_quick_controls_page *page) noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual void quickControlsSelectPage(clap_id pageId) noexcept {}
|
||||||
|
virtual clap_id quickControlsSelectedPage() noexcept { return CLAP_INVALID_ID; }
|
||||||
|
|
||||||
|
//------------------------//
|
||||||
|
// clap_plugin_note_ports //
|
||||||
|
//------------------------//
|
||||||
|
virtual bool implementsNotePorts() const noexcept { return false; }
|
||||||
|
virtual uint32_t notePortsCount(bool isInput) const noexcept { return 0; }
|
||||||
|
virtual bool
|
||||||
|
notePortsInfo(uint32_t index, bool isInput, clap_note_port_info *info) const noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------//
|
||||||
|
// clap_plugin_note_name //
|
||||||
|
//-----------------------//
|
||||||
|
virtual bool implementsNoteName() const noexcept { return false; }
|
||||||
|
virtual int noteNameCount() noexcept { return 0; }
|
||||||
|
virtual bool noteNameGet(int index, clap_note_name *noteName) noexcept { return false; }
|
||||||
|
|
||||||
|
//---------------------------//
|
||||||
|
// clap_plugin_timer_support //
|
||||||
|
//---------------------------//
|
||||||
|
virtual bool implementsTimerSupport() const noexcept { return false; }
|
||||||
|
virtual void onTimer(clap_id timerId) noexcept {}
|
||||||
|
|
||||||
|
//------------------------------//
|
||||||
|
// clap_plugin_posix_fd_support //
|
||||||
|
//------------------------------//
|
||||||
|
virtual bool implementsPosixFdSupport() const noexcept { return false; }
|
||||||
|
virtual void onPosixFd(int fd, int flags) noexcept {}
|
||||||
|
|
||||||
|
//-----------------//
|
||||||
|
// clap_plugin_gui //
|
||||||
|
//-----------------//
|
||||||
|
virtual bool implementsGui() const noexcept { return false; }
|
||||||
|
virtual bool guiIsApiSupported(const char *api, bool isFloating) noexcept { return false; }
|
||||||
|
virtual bool guiGetPreferredApi(const char **api, bool *is_floating) noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual bool guiCreate(const char *api, bool isFloating) noexcept { return false; }
|
||||||
|
virtual void guiDestroy() noexcept {}
|
||||||
|
virtual bool guiSetScale(double scale) noexcept { return false; }
|
||||||
|
virtual bool guiShow() noexcept { return false; }
|
||||||
|
virtual bool guiHide() noexcept { return false; }
|
||||||
|
virtual bool guiGetSize(uint32_t *width, uint32_t *height) noexcept { return false; }
|
||||||
|
virtual bool guiCanResize() const noexcept { return false; }
|
||||||
|
virtual bool guiGetResizeHints(clap_gui_resize_hints_t *hints) noexcept { return false; }
|
||||||
|
virtual bool guiAdjustSize(uint32_t *width, uint32_t *height) noexcept {
|
||||||
|
return guiGetSize(width, height);
|
||||||
|
}
|
||||||
|
virtual bool guiSetSize(uint32_t width, uint32_t height) noexcept { return false; }
|
||||||
|
virtual void guiSuggestTitle(const char *title) noexcept {}
|
||||||
|
virtual bool guiSetParent(const clap_window *window) noexcept { return false; }
|
||||||
|
virtual bool guiSetTransient(const clap_window *window) noexcept { return false; }
|
||||||
|
|
||||||
|
//------------------------//
|
||||||
|
// clap_plugin_voice_info //
|
||||||
|
//------------------------//
|
||||||
|
virtual bool implementsVoiceInfo() const noexcept { return false; }
|
||||||
|
virtual bool voiceInfoGet(clap_voice_info *info) noexcept { return false; }
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// Logging //
|
||||||
|
/////////////
|
||||||
|
void log(clap_log_severity severity, const char *msg) const noexcept;
|
||||||
|
void hostMisbehaving(const char *msg) const noexcept;
|
||||||
|
void hostMisbehaving(const std::string &msg) const noexcept { hostMisbehaving(msg.c_str()); }
|
||||||
|
|
||||||
|
// Receives a copy of all the logging messages sent to the host.
|
||||||
|
// This is useful to have the messages in both the host's logs and the plugin's logs.
|
||||||
|
virtual void logTee(clap_log_severity severity, const char *msg) const noexcept {}
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
// Thread Checking //
|
||||||
|
/////////////////////
|
||||||
|
void checkMainThread() const noexcept;
|
||||||
|
void checkAudioThread() const noexcept;
|
||||||
|
void checkParamThread() const noexcept;
|
||||||
|
void ensureMainThread(const char *method) const noexcept;
|
||||||
|
void ensureAudioThread(const char *method) const noexcept;
|
||||||
|
void ensureParamThread(const char *method) const noexcept;
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// Utilities //
|
||||||
|
///////////////
|
||||||
|
static Plugin &from(const clap_plugin *plugin, bool requireInitialized = true) noexcept;
|
||||||
|
|
||||||
|
// runs the callback immediately if on the main thread, otherwise queue it.
|
||||||
|
// be aware that the callback may be ran during the plugin destruction phase,
|
||||||
|
// so check isBeingDestroyed() and ajust your code.
|
||||||
|
void runOnMainThread(std::function<void()> callback);
|
||||||
|
|
||||||
|
// This actually runs callbacks on the main thread, you should not need to call it
|
||||||
|
void runCallbacksOnMainThread();
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void initInterface(const T *&ptr, const char *id) noexcept;
|
||||||
|
void initInterfaces() noexcept;
|
||||||
|
|
||||||
|
static uint32_t compareAudioPortsInfo(const clap_audio_port_info &a,
|
||||||
|
const clap_audio_port_info &b) noexcept;
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
// Processing State //
|
||||||
|
//////////////////////
|
||||||
|
bool isActive() const noexcept { return _isActive; }
|
||||||
|
bool isProcessing() const noexcept { return _isProcessing; }
|
||||||
|
int sampleRate() const noexcept {
|
||||||
|
assert(_isActive && "sample rate is only known if the plugin is active");
|
||||||
|
assert(_sampleRate > 0);
|
||||||
|
return _sampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isBeingDestroyed() const noexcept { return _isBeingDestroyed; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
HostProxy<h, l> _host;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/////////////////////
|
||||||
|
// CLAP Interfaces //
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
|
clap_plugin _plugin;
|
||||||
|
// clap_plugin
|
||||||
|
static bool clapInit(const clap_plugin *plugin) noexcept;
|
||||||
|
static void clapDestroy(const clap_plugin *plugin) noexcept;
|
||||||
|
static bool clapActivate(const clap_plugin *plugin,
|
||||||
|
double sample_rate,
|
||||||
|
uint32_t minFrameCount,
|
||||||
|
uint32_t maxFrameCount) noexcept;
|
||||||
|
static void clapDeactivate(const clap_plugin *plugin) noexcept;
|
||||||
|
static bool clapStartProcessing(const clap_plugin *plugin) noexcept;
|
||||||
|
static void clapStopProcessing(const clap_plugin *plugin) noexcept;
|
||||||
|
static void clapReset(const clap_plugin *plugin) noexcept;
|
||||||
|
static clap_process_status clapProcess(const clap_plugin *plugin,
|
||||||
|
const clap_process *process) noexcept;
|
||||||
|
static void clapOnMainThread(const clap_plugin *plugin) noexcept;
|
||||||
|
static const void *clapExtension(const clap_plugin *plugin, const char *id) noexcept;
|
||||||
|
|
||||||
|
// latency
|
||||||
|
static uint32_t clapLatencyGet(const clap_plugin *plugin) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_tail
|
||||||
|
static uint32_t clapTailGet(const clap_plugin_t *plugin) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_render
|
||||||
|
static bool clapRenderHasHardRealtimeRequirement(const clap_plugin_t *plugin) noexcept;
|
||||||
|
static bool clapRenderSetMode(const clap_plugin *plugin,
|
||||||
|
clap_plugin_render_mode mode) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_thread_pool
|
||||||
|
static void clapThreadPoolExec(const clap_plugin *plugin, uint32_t task_index) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_state
|
||||||
|
static bool clapStateSave(const clap_plugin *plugin, const clap_ostream *stream) noexcept;
|
||||||
|
static bool clapStateLoad(const clap_plugin *plugin, const clap_istream *stream) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_preset
|
||||||
|
static bool clapPresetLoadFromFile(const clap_plugin *plugin, const char *path) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_track_info
|
||||||
|
static void clapTrackInfoChanged(const clap_plugin *plugin) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_audio_ports
|
||||||
|
static uint32_t clapAudioPortsCount(const clap_plugin *plugin, bool is_input) noexcept;
|
||||||
|
static bool clapAudioPortsInfo(const clap_plugin *plugin,
|
||||||
|
uint32_t index,
|
||||||
|
bool is_input,
|
||||||
|
clap_audio_port_info *info) noexcept;
|
||||||
|
static uint32_t clapAudioPortsConfigCount(const clap_plugin *plugin) noexcept;
|
||||||
|
static bool clapAudioPortsGetConfig(const clap_plugin *plugin,
|
||||||
|
uint32_t index,
|
||||||
|
clap_audio_ports_config *config) noexcept;
|
||||||
|
static bool clapAudioPortsSetConfig(const clap_plugin *plugin, clap_id config_id) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_params
|
||||||
|
static uint32_t clapParamsCount(const clap_plugin *plugin) noexcept;
|
||||||
|
static bool clapParamsInfo(const clap_plugin *plugin,
|
||||||
|
uint32_t param_index,
|
||||||
|
clap_param_info *param_info) noexcept;
|
||||||
|
static bool
|
||||||
|
clapParamsValue(const clap_plugin *plugin, clap_id param_id, double *value) noexcept;
|
||||||
|
static bool clapParamsValueToText(const clap_plugin *plugin,
|
||||||
|
clap_id param_id,
|
||||||
|
double value,
|
||||||
|
char *display,
|
||||||
|
uint32_t size) noexcept;
|
||||||
|
static bool clapParamsTextToValue(const clap_plugin *plugin,
|
||||||
|
clap_id param_id,
|
||||||
|
const char *display,
|
||||||
|
double *value) noexcept;
|
||||||
|
static void clapParamsFlush(const clap_plugin *plugin,
|
||||||
|
const clap_input_events *in,
|
||||||
|
const clap_output_events *out) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_quick_controls
|
||||||
|
static uint32_t clapQuickControlsPageCount(const clap_plugin *plugin) noexcept;
|
||||||
|
static bool clapQuickControlsPageGet(const clap_plugin *plugin,
|
||||||
|
uint32_t page_index,
|
||||||
|
clap_quick_controls_page *page) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_note_port
|
||||||
|
static uint32_t clapNotePortsCount(const clap_plugin *plugin, bool is_input) noexcept;
|
||||||
|
static bool clapNotePortsInfo(const clap_plugin *plugin,
|
||||||
|
uint32_t index,
|
||||||
|
bool is_input,
|
||||||
|
clap_note_port_info *info) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_note_name
|
||||||
|
static uint32_t clapNoteNameCount(const clap_plugin *plugin) noexcept;
|
||||||
|
static bool clapNoteNameGet(const clap_plugin *plugin,
|
||||||
|
uint32_t index,
|
||||||
|
clap_note_name *note_name) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_timer_support
|
||||||
|
static void clapOnTimer(const clap_plugin *plugin, clap_id timer_id) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_fd_support
|
||||||
|
static void
|
||||||
|
clapOnPosixFd(const clap_plugin *plugin, int fd, clap_posix_fd_flags_t flags) noexcept;
|
||||||
|
|
||||||
|
// clap_plugin_gui
|
||||||
|
static bool
|
||||||
|
clapGuiIsApiSupported(const clap_plugin *plugin, const char *api, bool isFloating) noexcept;
|
||||||
|
static bool clapGuiGetPreferredApi(const clap_plugin_t *plugin,
|
||||||
|
const char **api,
|
||||||
|
bool *is_floating) noexcept;
|
||||||
|
static bool
|
||||||
|
clapGuiCreate(const clap_plugin *plugin, const char *api, bool isFloating) noexcept;
|
||||||
|
static void clapGuiDestroy(const clap_plugin *plugin) noexcept;
|
||||||
|
static bool clapGuiSetScale(const clap_plugin *plugin, double scale) noexcept;
|
||||||
|
static bool
|
||||||
|
clapGuiGetSize(const clap_plugin *plugin, uint32_t *width, uint32_t *height) noexcept;
|
||||||
|
static bool
|
||||||
|
clapGuiSetSize(const clap_plugin *plugin, uint32_t width, uint32_t height) noexcept;
|
||||||
|
static bool clapGuiCanResize(const clap_plugin *plugin) noexcept;
|
||||||
|
static bool clapGuiGetResizeHints(const clap_plugin_t *plugin,
|
||||||
|
clap_gui_resize_hints_t *hints) noexcept;
|
||||||
|
static bool
|
||||||
|
clapGuiAdjustSize(const clap_plugin *plugin, uint32_t *width, uint32_t *height) noexcept;
|
||||||
|
static bool clapGuiShow(const clap_plugin *plugin) noexcept;
|
||||||
|
static bool clapGuiHide(const clap_plugin *plugin) noexcept;
|
||||||
|
static bool clapGuiSetParent(const clap_plugin *plugin, const clap_window *window) noexcept;
|
||||||
|
static bool clapGuiSetTransient(const clap_plugin *plugin,
|
||||||
|
const clap_window *window) noexcept;
|
||||||
|
|
||||||
|
static void clapGuiSuggestTitle(const clap_plugin *plugin, const char *title) noexcept;
|
||||||
|
|
||||||
|
static bool clapVoiceInfoGet(const clap_plugin *plugin, clap_voice_info *info) noexcept;
|
||||||
|
|
||||||
|
// interfaces
|
||||||
|
static const clap_plugin_render _pluginRender;
|
||||||
|
static const clap_plugin_thread_pool _pluginThreadPool;
|
||||||
|
static const clap_plugin_state _pluginState;
|
||||||
|
static const clap_plugin_preset_load _pluginPresetLoad;
|
||||||
|
static const clap_plugin_track_info _pluginTrackInfo;
|
||||||
|
static const clap_plugin_audio_ports _pluginAudioPorts;
|
||||||
|
static const clap_plugin_audio_ports_config _pluginAudioPortsConfig;
|
||||||
|
static const clap_plugin_params _pluginParams;
|
||||||
|
static const clap_plugin_quick_controls _pluginQuickControls;
|
||||||
|
static const clap_plugin_latency _pluginLatency;
|
||||||
|
static const clap_plugin_note_ports _pluginNotePorts;
|
||||||
|
static const clap_plugin_note_name _pluginNoteName;
|
||||||
|
static const clap_plugin_timer_support _pluginTimerSupport;
|
||||||
|
static const clap_plugin_posix_fd_support _pluginPosixFdSupport;
|
||||||
|
static const clap_plugin_gui _pluginGui;
|
||||||
|
static const clap_plugin_voice_info _pluginVoiceInfo;
|
||||||
|
static const clap_plugin_tail _pluginTail;
|
||||||
|
|
||||||
|
// state
|
||||||
|
bool _wasInitialized = false;
|
||||||
|
bool _isActive = false;
|
||||||
|
bool _isProcessing = false;
|
||||||
|
bool _isBeingDestroyed = false;
|
||||||
|
double _sampleRate = 0;
|
||||||
|
|
||||||
|
std::string _guiApi;
|
||||||
|
bool _isGuiCreated = false;
|
||||||
|
bool _isGuiFloating = false;
|
||||||
|
bool _isGuiEmbedded = false;
|
||||||
|
|
||||||
|
std::mutex _mainThredCallbacksLock;
|
||||||
|
std::queue<std::function<void()>> _mainThredCallbacks;
|
||||||
|
};
|
||||||
|
}} // namespace clap::helpers
|
1409
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/plugin.hxx
vendored
Normal file
1409
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/plugin.hxx
vendored
Normal file
File diff suppressed because it is too large
Load Diff
48
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/reducing-param-queue.hh
vendored
Normal file
48
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/reducing-param-queue.hh
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <functional>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <clap/private/macros.h>
|
||||||
|
|
||||||
|
namespace clap { namespace helpers {
|
||||||
|
|
||||||
|
#ifdef CLAP_HAS_CXX20
|
||||||
|
template <typename T>
|
||||||
|
concept UpdatableValue = requires(T &a, const T &b) {
|
||||||
|
// update a with b, b being newer than a
|
||||||
|
{ a.update(b) };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO: when switching to C++20
|
||||||
|
// template <typename K, UpdatableValue V>
|
||||||
|
template <typename K, typename V>
|
||||||
|
class ReducingParamQueue {
|
||||||
|
public:
|
||||||
|
using key_type = K;
|
||||||
|
using value_type = V;
|
||||||
|
using queue_type = std::unordered_map<key_type, value_type>;
|
||||||
|
using consumer_type = const std::function<void(const key_type &key, const value_type &value)>;
|
||||||
|
|
||||||
|
ReducingParamQueue();
|
||||||
|
|
||||||
|
void setCapacity(size_t capacity);
|
||||||
|
|
||||||
|
void set(const key_type &key, const value_type &value);
|
||||||
|
void setOrUpdate(const key_type &key, const value_type &value);
|
||||||
|
void producerDone();
|
||||||
|
|
||||||
|
void consume(const consumer_type &consumer);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
queue_type _queues[2];
|
||||||
|
std::atomic<queue_type *> _free = nullptr;
|
||||||
|
std::atomic<queue_type *> _producer = nullptr;
|
||||||
|
std::atomic<queue_type *> _consumer = nullptr;
|
||||||
|
};
|
||||||
|
}} // namespace clap::helpers
|
72
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/reducing-param-queue.hxx
vendored
Normal file
72
deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/reducing-param-queue.hxx
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "reducing-param-queue.hh"
|
||||||
|
|
||||||
|
namespace clap { namespace helpers {
|
||||||
|
template <typename K, typename V>
|
||||||
|
ReducingParamQueue<K, V>::ReducingParamQueue() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
void ReducingParamQueue<K, V>::reset() {
|
||||||
|
for (auto &q : _queues)
|
||||||
|
q.clear();
|
||||||
|
|
||||||
|
_free = &_queues[0];
|
||||||
|
_producer = &_queues[1];
|
||||||
|
_consumer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
void ReducingParamQueue<K, V>::setCapacity(size_t capacity) {
|
||||||
|
for (auto &q : _queues)
|
||||||
|
q.reserve(2 * capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
void ReducingParamQueue<K, V>::set(const key_type &key, const value_type &value) {
|
||||||
|
_producer.load()->insert_or_assign(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
void ReducingParamQueue<K, V>::setOrUpdate(const key_type &key, const value_type &value) {
|
||||||
|
auto prod = _producer.load();
|
||||||
|
auto res = prod->insert({key, value});
|
||||||
|
if (!res.second && res.first != prod->end())
|
||||||
|
res.first->second.update(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
void ReducingParamQueue<K, V>::producerDone() {
|
||||||
|
if (_consumer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto tmp = _producer.load();
|
||||||
|
_producer = _free.load();
|
||||||
|
_free = nullptr;
|
||||||
|
_consumer = tmp;
|
||||||
|
|
||||||
|
assert(_producer);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
void ReducingParamQueue<K, V>::consume(const consumer_type &consumer) {
|
||||||
|
assert(consumer);
|
||||||
|
|
||||||
|
if (!_consumer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto &x : *_consumer)
|
||||||
|
consumer(x.first, x.second);
|
||||||
|
|
||||||
|
_consumer.load()->clear();
|
||||||
|
if (_free)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_free = _consumer.load();
|
||||||
|
_consumer = nullptr;
|
||||||
|
}
|
||||||
|
}} // namespace clap::helpers
|
2
deps/clap-juce-extensions/clap-libs/clap-helpers/tests/main.cc
vendored
Normal file
2
deps/clap-juce-extensions/clap-libs/clap-helpers/tests/main.cc
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#include <catch2/catch.hpp>
|
18
deps/clap-juce-extensions/clap-libs/clap-helpers/tests/plugin.cc
vendored
Normal file
18
deps/clap-juce-extensions/clap-libs/clap-helpers/tests/plugin.cc
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#include <clap/helpers/param-queue.hh>
|
||||||
|
#include <clap/helpers/plugin.hh>
|
||||||
|
#include <clap/helpers/plugin.hxx>
|
||||||
|
#include <clap/helpers/reducing-param-queue.hh>
|
||||||
|
#include <clap/helpers/reducing-param-queue.hxx>
|
||||||
|
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
|
CATCH_TEST_CASE("Plugin - Link") {
|
||||||
|
clap::helpers::Plugin<clap::helpers::MisbehaviourHandler::Terminate,
|
||||||
|
clap::helpers::CheckingLevel::Maximal> *p0 = nullptr;
|
||||||
|
clap::helpers::Plugin<clap::helpers::MisbehaviourHandler::Terminate,
|
||||||
|
clap::helpers::CheckingLevel::Minimal> *p1 = nullptr;
|
||||||
|
clap::helpers::Plugin<clap::helpers::MisbehaviourHandler::Terminate,
|
||||||
|
clap::helpers::CheckingLevel::None> *p2 = nullptr;
|
||||||
|
clap::helpers::Plugin<clap::helpers::MisbehaviourHandler::Ignore,
|
||||||
|
clap::helpers::CheckingLevel::Maximal> *p3 = nullptr;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user