// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* nl_factory.h
*
*
*/
#ifndef NLFACTORY_H_
#define NLFACTORY_H_
#include "plib/palloc.h"
#include "plib/ptypes.h"
#define NETLIB_DEVICE_IMPL(chip) \
static std::unique_ptr<factory::element_t> NETLIB_NAME(chip ## _c)( \
const pstring &name, const pstring &classname, const pstring &def_param) \
{ \
return std::unique_ptr<factory::element_t>(plib::palloc<factory::device_element_t<NETLIB_NAME(chip)>>(name, classname, def_param, pstring(__FILE__))); \
} \
factory::constructor_ptr_t decl_ ## chip = NETLIB_NAME(chip ## _c);
#define NETLIB_DEVICE_IMPL_NS(ns, chip) \
static std::unique_ptr<factory::element_t> NETLIB_NAME(chip ## _c)( \
const pstring &name, const pstring &classname, const pstring &def_param) \
{ \
return std::unique_ptr<factory::element_t>(plib::palloc<factory::device_element_t<ns :: NETLIB_NAME(chip)>>(name, classname, def_param, pstring(__FILE__))); \
} \
factory::constructor_ptr_t decl_ ## chip = NETLIB_NAME(chip ## _c);
namespace netlist {
class netlist_t;
class device_t;
class setup_t;
namespace factory {
// -----------------------------------------------------------------------------
// net_dev class factory
// -----------------------------------------------------------------------------
class element_t : plib::nocopyassignmove
{
public:
element_t(const pstring &name, const pstring &classname,
const pstring &def_param);
element_t(const pstring &name, const pstring &classname,
const pstring &def_param, const pstring &sourcefile);
virtual ~element_t();
virtual plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) = 0;
virtual void macro_actions(netlist_t &anetlist, const pstring &name) {}
const pstring &name() const { return m_name; }
const pstring &classname() const { return m_classname; }
const pstring ¶m_desc() const { return m_def_param; }
const pstring &sourcefile() const { return m_sourcefile; }
private:
pstring m_name; /* device name */
pstring m_classname; /* device class name */
pstring m_def_param; /* default parameter */
pstring m_sourcefile; /* source file */
};
template <class C>
class device_element_t : public element_t
{
public:
device_element_t(const pstring &name, const pstring &classname,
const pstring &def_param)
: element_t(name, classname, def_param) { }
device_element_t(const pstring &name, const pstring &classname,
const pstring &def_param, const pstring &sourcefile)
: element_t(name, classname, def_param, sourcefile) { }
plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
{
return plib::owned_ptr<device_t>::Create<C>(anetlist, name);
}
};
class list_t : public std::vector<std::unique_ptr<element_t>>
{
public:
list_t(setup_t &m_setup);
~list_t();
template<class device_class>
void register_device(const pstring &name, const pstring &classname,
const pstring &def_param)
{
register_device(std::unique_ptr<element_t>(plib::palloc<device_element_t<device_class>>(name, classname, def_param)));
}
void register_device(std::unique_ptr<element_t> &&factory);
element_t * factory_by_name(const pstring &devname);
template <class C>
bool is_class(element_t *f)
{
return dynamic_cast<device_element_t<C> *>(f) != nullptr;
}
private:
setup_t &m_setup;
};
// -----------------------------------------------------------------------------
// factory_creator_ptr_t
// -----------------------------------------------------------------------------
using constructor_ptr_t = std::unique_ptr<element_t> (*)(const pstring &name, const pstring &classname,
const pstring &def_param);
template <typename T>
std::unique_ptr<element_t> constructor_t(const pstring &name, const pstring &classname,
const pstring &def_param)
{
return std::unique_ptr<element_t>(plib::palloc<device_element_t<T>>(name, classname, def_param));
}
// -----------------------------------------------------------------------------
// factory_lib_entry_t: factory class to wrap macro based chips/elements
// -----------------------------------------------------------------------------
class library_element_t : public element_t
{
public:
library_element_t(setup_t &setup, const pstring &name, const pstring &classname,
const pstring &def_param, const pstring &source)
: element_t(name, classname, def_param, source) { }
plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override;
void macro_actions(netlist_t &anetlist, const pstring &name) override;
private:
};
}
namespace devices {
void initialize_factory(factory::list_t &factory);
}
}
#endif /* NLFACTORY_H_ */