Use hashmap for factory searches. (nw)

This commit is contained in:
couriersud 2015-07-19 23:02:45 +02:00
parent 6024ddca56
commit c30ac5a27b
6 changed files with 40 additions and 50 deletions

View File

@ -34,18 +34,19 @@ ATTR_COLD const pstring_list_t base_factory_t::def_params()
}
factory_list_t::factory_list_t()
factory_list_t::factory_list_t( setup_t &setup)
: m_setup(setup)
{
}
factory_list_t::~factory_list_t()
{
for (std::size_t i=0; i < m_list.size(); i++)
for (std::size_t i=0; i < size(); i++)
{
base_factory_t *p = m_list[i];
base_factory_t *p = value_at(i);
pfree(p);
}
m_list.clear();
clear();
}
#if 0
@ -65,25 +66,26 @@ device_t *factory_list_t::new_device_by_classname(const pstring &classname) cons
}
#endif
device_t *factory_list_t::new_device_by_name(const pstring &name, setup_t &setup) const
void factory_list_t::error(const pstring &s)
{
base_factory_t *f = factory_by_name(name, setup);
m_setup.netlist().error("%s", s.cstr());
}
device_t *factory_list_t::new_device_by_name(const pstring &name)
{
base_factory_t *f = factory_by_name(name);
return f->Create();
}
base_factory_t * factory_list_t::factory_by_name(const pstring &name, setup_t &setup) const
base_factory_t * factory_list_t::factory_by_name(const pstring &name)
{
for (std::size_t i=0; i < m_list.size(); i++)
if (contains(name))
return (*this)[name];
else
{
base_factory_t *p = m_list[i];
if (p->name() == name)
{
return p;
}
p++;
m_setup.netlist().error("Class %s not found!\n", name.cstr());
return NULL; // appease code analysis
}
setup.netlist().error("Class %s not found!\n", name.cstr());
return NULL; // appease code analysis
}
}

View File

@ -62,35 +62,34 @@ namespace netlist
}
};
class factory_list_t
class factory_list_t : public phashmap_t<pstring, base_factory_t *>
{
public:
typedef plist_t<base_factory_t *> list_t;
factory_list_t();
factory_list_t(setup_t &m_setup);
~factory_list_t();
template<class _C>
ATTR_COLD void register_device(const pstring &name, const pstring &classname,
const pstring &def_param)
{
m_list.add(palloc(factory_t< _C >(name, classname, def_param)));
if (!add(name, palloc(factory_t< _C >(name, classname, def_param))))
error(pstring::sprintf("factory already contains %s", name.cstr()));
}
ATTR_COLD void register_device(base_factory_t *factory)
{
m_list.add(factory);
if (!add(factory->name(), factory))
error(pstring::sprintf("factory already contains %s", factory->name().cstr()));
}
//ATTR_COLD device_t *new_device_by_classname(const pstring &classname) const;
ATTR_COLD device_t *new_device_by_name(const pstring &name, setup_t &setup) const;
ATTR_COLD base_factory_t * factory_by_name(const pstring &name, setup_t &setup) const;
const list_t &list() { return m_list; }
ATTR_COLD device_t *new_device_by_name(const pstring &name);
ATTR_COLD base_factory_t * factory_by_name(const pstring &name);
private:
list_t m_list;
void error(const pstring &s);
setup_t &m_setup;
};
}

View File

@ -360,7 +360,7 @@ void parser_t::device(const pstring &dev_type)
}
else
{
base_factory_t *f = m_setup.factory().factory_by_name(dev_type, m_setup);
base_factory_t *f = m_setup.factory().factory_by_name(dev_type);
device_t *dev;
pstring_list_t termlist = f->term_param_list();
pstring_list_t def_params = f->def_params();

View File

@ -52,7 +52,7 @@ setup_t::setup_t(netlist_t *netlist)
, m_proxy_cnt(0)
{
netlist->set_setup(this);
m_factory = palloc(factory_list_t);
m_factory = palloc(factory_list_t(*this));
}
void setup_t::init()
@ -129,7 +129,7 @@ device_t *setup_t::register_dev(const pstring &classname, const pstring &name)
}
else
{
device_t *dev = factory().new_device_by_name(classname, *this);
device_t *dev = factory().new_device_by_name(classname);
//device_t *dev = factory().new_device_by_classname(classname);
if (dev == NULL)
netlist().error("Class %s not found!\n", classname.cstr());
@ -861,7 +861,7 @@ void setup_t::start_devices()
{
NL_VERBOSE_OUT(("%d: <%s>\n",i, ll[i].cstr()));
NL_VERBOSE_OUT(("%d: <%s>\n",i, ll[i].cstr()));
device_t *nc = factory().new_device_by_name("LOG", *this);
device_t *nc = factory().new_device_by_name("LOG");
pstring name = "log_" + ll[i];
register_dev(nc, name);
register_link(name + ".I", ll[i]);

View File

@ -780,17 +780,6 @@ public:
return m_values[p].m_value;
}
const V& operator[](const K &key) const
{
int p = get_idx(key);
if (p == -1)
{
p = m_values.size();
add(key, V());
}
return m_values[p].m_value;
}
V& value_at(const unsigned pos) { return m_values[pos].m_value; }
const V& value_at(const unsigned pos) const { return m_values[pos].m_value; }

View File

@ -290,7 +290,7 @@ static void listdevices()
{
netlist_tool_t nt;
nt.init();
const netlist::factory_list_t::list_t &list = nt.setup().factory().list();
const netlist::factory_list_t &list = nt.setup().factory();
nt.setup().register_source(palloc(netlist::source_proc_t("dummy", &netlist_dummy)));
nt.setup().include("dummy");
@ -300,11 +300,11 @@ static void listdevices()
for (int i=0; i < list.size(); i++)
{
pstring out = pstring::sprintf("%-20s %s(<id>", list[i]->classname().cstr(),
list[i]->name().cstr() );
netlist::base_factory_t *f = list.value_at(i);
pstring out = pstring::sprintf("%-20s %s(<id>", f->classname().cstr(),
f->name().cstr() );
pstring terms("");
netlist::base_factory_t *f = list[i];
netlist::device_t *d = f->Create();
d->init(nt, pstring::sprintf("dummy%d", i));
d->start_dev();
@ -318,18 +318,18 @@ static void listdevices()
terms += "," + inp;
}
if (list[i]->param_desc().startsWith("+"))
if (f->param_desc().startsWith("+"))
{
out += "," + list[i]->param_desc().substr(1);
out += "," + f->param_desc().substr(1);
terms = "";
}
else if (list[i]->param_desc() == "-")
else if (f->param_desc() == "-")
{
/* no params at all */
}
else
{
out += "," + list[i]->param_desc();
out += "," + f->param_desc();
}
out += ")";
printf("%s\n", out.cstr());