Struct thl::ParameterRecord#

struct ParameterRecord#

Collaboration diagram for thl::ParameterRecord:

digraph { graph [bgcolor="#00000000"] node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2] edge [color="#1414CE"] "6" [label="std::atomic< bool >" tooltip="std::atomic< bool >"] "3" [label="std::atomic< double >" tooltip="std::atomic< double >"] "4" [label="std::atomic< float >" tooltip="std::atomic< float >"] "5" [label="std::atomic< int >" tooltip="std::atomic< int >"] "9" [label="std::basic_string< Char >" tooltip="std::basic_string< Char >"] "15" [label="std::basic_string_view< Char >" tooltip="std::basic_string_view< Char >"] "8" [label="std::string" tooltip="std::string"] "14" [label="std::string_view" tooltip="std::string_view"] "2" [label="thl::AtomicCacheEntry" tooltip="thl::AtomicCacheEntry"] "11" [label="thl::NormalizationCurve" tooltip="thl::NormalizationCurve"] "7" [label="thl::ParameterDefinition" tooltip="thl::ParameterDefinition"] "1" [label="thl::ParameterRecord" tooltip="thl::ParameterRecord" fillcolor="#BFBFBF"] "10" [label="thl::Range" tooltip="thl::Range"] "13" [label="thl::modulation::ModulationScope" tooltip="thl::modulation::ModulationScope"] "12" [label="std::vector< std::string >" tooltip="std::vector< std::string >"] "8" -> "9" [dir=forward tooltip="public-inheritance"] "14" -> "15" [dir=forward tooltip="public-inheritance"] "2" -> "3" [dir=forward tooltip="usage"] "2" -> "4" [dir=forward tooltip="usage"] "2" -> "5" [dir=forward tooltip="usage"] "2" -> "6" [dir=forward tooltip="usage"] "7" -> "8" [dir=forward tooltip="usage"] "7" -> "10" [dir=forward tooltip="usage"] "7" -> "12" [dir=forward tooltip="usage"] "7" -> "13" [dir=forward tooltip="usage"] "1" -> "2" [dir=forward tooltip="usage"] "1" -> "7" [dir=forward tooltip="usage"] "1" -> "14" [dir=forward tooltip="usage"] "1" -> "6" [dir=forward tooltip="usage"] "1" -> "8" [dir=forward tooltip="usage"] "10" -> "11" [dir=forward tooltip="usage"] "12" -> "8" [dir=forward tooltip="usage"] }

Consolidated per-parameter storage.

Each parameter gets one heap-allocated ParameterRecord, owned by State::m_storage via unique_ptr. The record holds everything about the parameter: immutable definition (type, range, flags, name, etc.), atomic cache for real-time value access, gesture state, and string value.

Fields are ordered for cache efficiency. m_cache is at offset 0 so that ParameterHandle::load() touches the first cache line of the allocation. alignas(64) on m_def guarantees the hot cache line contains only m_cache (24 B), isolating it from non-RT writes to m_in_gesture / m_string_value (false-sharing prevention).

Cache-Line Layout

m_key is a string_view pointing into the owning std::map node’s key. Set once after map insertion, never modified. Zero-cost, no duplication.

m_def is const — the definition is immutable after construction. RCU publish in create() provides the happens-before guarantee — readers only see the record after m_key and m_def are fully initialized.

Because AtomicCacheEntry is non-copyable/non-movable the record itself is non-copyable/non-movable — always accessed via pointer.

Public Functions

inline explicit ParameterRecord(ParameterDefinition def)#
ParameterRecord(const ParameterRecord&) = delete#
ParameterRecord &operator=(const ParameterRecord&) = delete#

Public Members

AtomicCacheEntry m_cache#

RT-hot: per-sample lock-free access (offset 0 for single cache line fetch)

const ParameterDefinition m_def#

Immutable definition (type, range, flags, name, etc.) alignas(64) ensures m_cache occupies its own cache line.

std::string_view m_key#

Identity (set once after map insertion, never modified)

std::atomic<bool> m_in_gesture = {false}#

Mutable runtime state (non-RT only, separate cache line from m_cache)

std::string m_string_value#