Commit 7502f094 authored by Robert Manzke's avatar Robert Manzke

towards a working method

parent 80d7d2d8
add_library(ctag plugins.cpp plugin1.cpp)
\ No newline at end of file
file(GLOB SRCS
*.cpp
*.hpp
)
add_library(ctag ${SRCS})
\ No newline at end of file
// Base class for sound processors
#pragma once
#include <stdint.h>
namespace CTAG{
namespace SP{
struct ProcessData{
float *buf0, *buf1;
uint16_t *control;
uint8_t *trig0, trig1;
uint32_t bufSize;
};
class ctagSoundProcessor{
public:
virtual void Process(const ProcessData &) = 0;
virtual ~ctagSoundProcessor(){};
bool GetIsStereo(){return isStereo;}
protected:
bool isStereo = false;
};
}
}
\ No newline at end of file
#include "ctagSoundProcessorStereoAM.hpp"
#include <iostream>
using namespace CTAG::SP;
ctagSoundProcessorStereoAM::ctagSoundProcessorStereoAM()
{
std::cout << "Constructor" << std::endl;
}
void ctagSoundProcessorStereoAM::Process(const ProcessData &data){
for(uint32_t i=0;i<data.bufSize; i++){
data.buf0[i] = (float)i;
data.buf1[i] = (float)i;
}
}
ctagSoundProcessorStereoAM::~ctagSoundProcessorStereoAM(){
std::cout << "Destructor" << std::endl;
}
#include "ctagSoundProcessor.hpp"
namespace CTAG{
namespace SP{
class ctagSoundProcessorStereoAM : public ctagSoundProcessor{
public:
void Process(const ProcessData &) ;
~ctagSoundProcessorStereoAM();
ctagSoundProcessorStereoAM();
};
}
}
\ 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
#include <iostream>
#include "plugins.hpp"
#include <memory>
#include "ctagSoundProcessor.hpp"
#include "ctagSoundProcessorStereoAM.hpp"
using namespace CTAG::SP;
int main()
{
auto &factory = PluginSystem::PluginFactory::Instance();
auto plugin = factory.GetPlugin("Plugin1");
std::unique_ptr<ctagSoundProcessor> res( new ctagSoundProcessorStereoAM());
plugin->DoSomething();
ProcessData data;
float b0[32], b1[32];
data.buf0 = b0;
data.buf1 = b1;
data.bufSize = 32;
res->Process(data);
for(int i=0;i<32;i++){
std::cout << "Value " << data.buf0[i] << " " << data.buf1[i] << std::endl;
}
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