Mercurial > hg > piper-cpp
diff vamp-support/PreservingPluginHandleMapper.h @ 265:7ada63fe1084
Some neatening
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Fri, 12 Oct 2018 22:18:37 +0100 |
parents | 9a044706ab73 |
children | 5ac494d998b2 |
line wrap: on
line diff
--- a/vamp-support/PreservingPluginHandleMapper.h Fri Oct 12 11:12:25 2018 +0100 +++ b/vamp-support/PreservingPluginHandleMapper.h Fri Oct 12 22:18:37 2018 +0100 @@ -42,19 +42,41 @@ namespace piper_vamp { -//!!! document -- this is a passthrough thing for a single plugin -//!!! handle only, it does not use actually valid Plugin pointers at -//!!! all. Or, better, reimplement in a way that doesn't involve -//!!! such alarmingly invalid reinterpret_casts - +/** + * A PluginHandleMapper that accepts a handle in the handleToPlugin + * method, storing it for later, and returns the same handle from + * pluginToHandle when given the same plugin pointer as it had earlier + * returned from handleToPlugin. It can only remember one handle, and + * knows nothing about actual plugins - the plugin pointer it returns + * is nominal and must never be dereferenced. + */ class PreservingPluginHandleMapper : public PluginHandleMapper { + class NotAPlugin : public Vamp::Plugin + { + #define STR(x) std::string get##x() const { return "not-a-plugin"; } + public: + STR(Identifier) STR(Name) STR(Description) STR(Maker) STR(Copyright) + int getPluginVersion() const { return 1; } + bool initialise(size_t, size_t, size_t) { return false; } + void reset() { } + InputDomain getInputDomain() const { return TimeDomain; } + OutputList getOutputDescriptors() const { return {}; } + FeatureSet process(const float *const *, Vamp::RealTime) { return {}; } + FeatureSet getRemainingFeatures() { return {}; } + NotAPlugin() : Plugin(1) { } + }; + public: PreservingPluginHandleMapper() : - m_handle(0), - m_plugin(0), + m_handle(INVALID_HANDLE), + m_plugin(nullptr), m_omapper(std::make_shared<PreservingPluginOutputIdMapper>()) { } + virtual ~PreservingPluginHandleMapper() { + delete m_plugin; + } + virtual Handle pluginToHandle(Vamp::Plugin *p) const noexcept { if (!p) return INVALID_HANDLE; if (p == m_plugin) return m_handle; @@ -69,10 +91,23 @@ virtual Vamp::Plugin *handleToPlugin(Handle h) const noexcept { if (h == INVALID_HANDLE) return nullptr; + if (h == m_handle) return m_plugin; + if (m_handle != INVALID_HANDLE) { + std::cerr << "PreservingPluginHandleMapper: m_handle " << m_handle + << " is non-null when a new handle is provided, but " + << "this stupid stub class can only handle one handle" + << std::endl; + return nullptr; + } m_handle = h; - //!!! see comment at top - m_plugin = reinterpret_cast<Vamp::Plugin *>(h); - return m_plugin; + // We allocate something here, just so that we can + // sanity-check in the pluginToHandle call that the thing + // passed in is likely to be the pointer we returned from + // handleToPlugin earlier. Allocating an actual plugin allows + // us to return it without running afoul of strict-aliasing + // rules or the C++ object memory model. + m_plugin = new NotAPlugin(); + return m_plugin; } virtual const std::shared_ptr<PluginOutputIdMapper> pluginToOutputIdMapper @@ -89,7 +124,7 @@ private: mutable Handle m_handle; - mutable Vamp::Plugin *m_plugin; + mutable NotAPlugin *m_plugin; std::shared_ptr<PreservingPluginOutputIdMapper> m_omapper; };