Commit 80d7d2d8 authored by Robert Manzke's avatar Robert Manzke

geht auch nicht

parent 1c799268
add_library(ctag ctagAudioPluginAM.cpp ctagAudioPluginFM.cpp)
\ No newline at end of file
add_library(ctag plugins.cpp plugin1.cpp)
\ No newline at end of file
#include <iostream>
#include "registerer.hpp"
class ctagAudioPlugin {
public:
virtual ~ctagAudioPlugin() {}
virtual void Process(const float *, float *) const = 0;
};
#include "ctagAudioPluginAM.hpp"
void ctagAudioPluginAM::Process (const float *in, float *out) const {
std::cout << "ctag AM\n";
}
ctagAudioPluginAM::ctagAudioPluginAM(){
std::cout << "Constructor called\n";
}
ctagAudioPluginAM::~ctagAudioPluginAM(){
std::cout << "Destructor called\n";
}
\ No newline at end of file
#include "ctagAudioPlugin.hpp"
#include <iostream>
class ctagAudioPluginAM : public ctagAudioPlugin{
REGISTER("ctagAudioPluginAM", ctagAudioPlugin);
public:
void Process(const float *, float *) const override;
ctagAudioPluginAM();
~ctagAudioPluginAM();
};
\ No newline at end of file
#include "ctagAudioPluginFM.hpp"
void ctagAudioPluginFM::Process (const float *in, float *out) const {
std::cout << "ctag FM\n";
}
ctagAudioPluginFM::ctagAudioPluginFM(){
std::cout << "Constructor called\n";
}
ctagAudioPluginFM::~ctagAudioPluginFM(){
std::cout << "Destructor called\n";
}
\ No newline at end of file
#include "ctagAudioPlugin.hpp"
#include <iostream>
class ctagAudioPluginFM : public ctagAudioPlugin{
REGISTER("ctagAudioPluginFM", ctagAudioPlugin);
public:
void Process(const float *, float *) const override;
ctagAudioPluginFM();
~ctagAudioPluginFM();
};
\ No newline at end of file
/* Could be also split in .h/.cpp, here kept in one file for simplicity */
#include <iostream>
#include "plugins.hpp"
class Plugin1: public PluginSystem::IPlugin {
void DoSomething() {
std::cout << "Plugin1" << std::endl;
}
};
REGISTER_PLUGIN(Plugin1)
\ No newline at end of file
#include "plugins.hpp"
namespace PluginSystem {
PluginFactory&
PluginFactory::Instance() {
static PluginFactory instance;
return instance;
}
void
PluginFactory::Register(IPluginRegistrar* registrar, std::string name) {
registry_[name] = registrar;
}
std::unique_ptr<IPlugin>
PluginFactory::GetPlugin(std::string name) {
/* throws out_of_range if plugin unknown */
IPluginRegistrar* registrar = registry_.at(name);
return registrar->GetPlugin();
}
}
\ No newline at end of file
#include <list>
#include <string>
#include <map>
#include <memory>
namespace PluginSystem {
/* Base class for plugins */
class IPlugin {
public:
virtual void DoSomething() = 0;
};
/*
* Base class for PluginRegistrar
* See PluginRegistrar below for explanations
*/
class IPluginRegistrar {
public:
virtual std::unique_ptr<IPlugin> GetPlugin() = 0;
};
/*
* This is the factory, the common interface to "plugins".
* Plugins registers themselves here and the factory can serve them on
* demand.
* It is a Singleton
*/
class PluginFactory {
public:
/* Get Singleton instance */
static PluginFactory& Instance();
/* Register a new plugin */
void Register(IPluginRegistrar* registrar, std::string name);
/* Get an instance of a plugin based on its name */
/* throws out_of_range if plugin not found */
std::unique_ptr<IPlugin> GetPlugin(std::string name);
private:
/* Holds pointers to plugin registrars */
std::map<std::string, IPluginRegistrar*> registry_;
/* Make constructors private and forbid cloning */
PluginFactory(): registry_() {};
PluginFactory(PluginFactory const&) = delete;
void operator=(PluginFactory const&) = delete;
};
/*
* Helper class that registers a plugin upon construction.
* Actually, the registrar registers itself, and the proxied plugin is only
* created on-demand. This mechanism can be shortened by directly
* registering and instance of the plugin, but the assumption here is that
* instanciating the plugin can be heavy and not necessary.
*/
template<class TPlugin>
class PluginRegistrar: public IPluginRegistrar {
public:
PluginRegistrar(std::string classname);
std::unique_ptr<IPlugin> GetPlugin();
private:
/* That is not really used there, but could be useful */
std::string classname_;
};
/* template functions in header */
template<class TPlugin>
PluginRegistrar<TPlugin>::PluginRegistrar(std::string classname): classname_(classname) {
PluginFactory &factory = PluginFactory::Instance();
factory.Register(this, classname);
}
template<class TPlugin>
std::unique_ptr<IPlugin>
PluginRegistrar<TPlugin>::GetPlugin() {
std::unique_ptr<IPlugin> plugin(new TPlugin());
return plugin;
}
}
/*
* Here is the trick: upon creation of the global variable, the class created
* out of the template will get instanciated once, and will register itself.
* The template contains the information to create a plugin instance.
* An unnamed namespace is used to enclose this later unused variable in the
* compilation unit.
*/
#define REGISTER_PLUGIN(CLASSNAME) \
namespace { \
static PluginSystem::PluginRegistrar<CLASSNAME> \
_registrar( #CLASSNAME ); \
};
\ No newline at end of file
This diff is collapsed.
#include "registerer.hpp"
#include "ctagAudioPlugin.hpp"
#include <iostream>
#include "plugins.hpp"
using factory::Registry;
int main(int argc, char** argv) {
std::unique_ptr<ctagAudioPlugin> plugin = Registry<ctagAudioPlugin>::New("ctagAudioPluginAM");
assert(plugin);
float in[32], out[32];
plugin->Process(in, out);
plugin = nullptr;
}
int main()
{
auto &factory = PluginSystem::PluginFactory::Instance();
auto plugin = factory.GetPlugin("Plugin1");
plugin->DoSomething();
return 0;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment