particles: get rid of struct particle_info

Since this struct only contained function pointers, make all particles
export those functions directly.

The plugin manager now defines a particle interface struct, and fills
it it by dlsym:ing the functions that used to be in particle_info.
This commit is contained in:
Daniel Eklöf 2019-01-13 17:01:45 +01:00
parent d35695e98a
commit 07b1615a41
11 changed files with 63 additions and 80 deletions

View file

@ -284,18 +284,17 @@ conf_verify_particle_dictionary(keychain_t *chain, const struct yml_node *node)
return false;
}
const struct particle_info *info = plugin_load_particle(particle_name);
if (info == NULL) {
LOG_ERR(
"%s: invalid particle name: %s",
conf_err_prefix(chain, particle), particle_name);
const struct particle_iface *iface = plugin_load_particle(particle_name);
if (iface == NULL) {
LOG_ERR("%s: invalid particle name: %s",
conf_err_prefix(chain, particle), particle_name);
return false;
}
assert(info->verify_conf != NULL);
assert(iface->verify_conf != NULL);
chain_push(chain, particle_name);
if (!info->verify_conf(chain, values))
if (!iface->verify_conf(chain, values))
return false;
chain_pop(chain);

View file

@ -211,10 +211,10 @@ conf_to_particle(const struct yml_node *node, struct conf_inherit inherited)
struct particle *common = particle_common_new(
left, right, on_click_template, font, foreground, deco);
const struct particle_info *info = plugin_load_particle(type);
const struct particle_iface *iface = plugin_load_particle(type);
assert(info != NULL);
return info->from_conf(pair.value, common);
assert(iface != NULL);
return iface->from_conf(pair.value, common);
}
struct bar *

View file

@ -9,25 +9,6 @@
#include "yml.h"
struct bar;
struct particle;
struct exposable;
struct particle_info {
bool (*verify_conf)(keychain_t *chain, const struct yml_node *node);
struct particle *(*from_conf)(
const struct yml_node *node, struct particle *common);
#define PARTICLE_COMMON_ATTRS \
{"margin", false, &conf_verify_int}, \
{"left-margin", false, &conf_verify_int}, \
{"right-margin", false, &conf_verify_int}, \
{"on-click", false, &conf_verify_string}, \
{"font", false, &conf_verify_font}, \
{"foreground", false, &conf_verify_color}, \
{"deco", false, &conf_verify_decoration}, \
{NULL, false, NULL}
};
struct particle {
void *private;
@ -80,3 +61,14 @@ void exposable_render_deco(
void exposable_default_on_mouse(
struct exposable *exposable, struct bar *bar,
enum mouse_event event, int x, int y);
/* List of attributes *all* particles implement */
#define PARTICLE_COMMON_ATTRS \
{"margin", false, &conf_verify_int}, \
{"left-margin", false, &conf_verify_int}, \
{"right-margin", false, &conf_verify_int}, \
{"on-click", false, &conf_verify_string}, \
{"font", false, &conf_verify_font}, \
{"foreground", false, &conf_verify_color}, \
{"deco", false, &conf_verify_decoration}, \
{NULL, false, NULL}

View file

@ -38,13 +38,13 @@ empty_new(struct particle *common)
return common;
}
static struct particle *
struct particle *
from_conf(const struct yml_node *node, struct particle *common)
{
return empty_new(common);
}
static bool
bool
verify_conf(keychain_t *chain, const struct yml_node *node)
{
static const struct attr_info attrs[] = {
@ -53,8 +53,3 @@ verify_conf(keychain_t *chain, const struct yml_node *node)
return conf_verify_dict(chain, node, attrs);
}
const struct particle_info plugin_info = {
.verify_conf = &verify_conf,
.from_conf = &from_conf,
};

View file

@ -162,7 +162,7 @@ particle_list_new(struct particle *common,
return common;
}
static struct particle *
struct particle *
from_conf(const struct yml_node *node, struct particle *common)
{
const struct yml_node *items = yml_get_value(node, "items");
@ -190,7 +190,7 @@ from_conf(const struct yml_node *node, struct particle *common)
return particle_list_new(common, parts, count, left_spacing, right_spacing);
}
static bool
bool
verify_conf(keychain_t *chain, const struct yml_node *node)
{
static const struct attr_info attrs[] = {
@ -203,8 +203,3 @@ verify_conf(keychain_t *chain, const struct yml_node *node)
return conf_verify_dict(chain, node, attrs);
}
const struct particle_info plugin_info = {
.verify_conf = &verify_conf,
.from_conf = &from_conf,
};

View file

@ -195,7 +195,7 @@ verify_map_values(keychain_t *chain, const struct yml_node *node)
return true;
}
static struct particle *
struct particle *
from_conf(const struct yml_node *node, struct particle *common)
{
const struct yml_node *tag = yml_get_value(node, "tag");
@ -226,7 +226,7 @@ from_conf(const struct yml_node *node, struct particle *common)
default_particle);
}
static bool
bool
verify_conf(keychain_t *chain, const struct yml_node *node)
{
static const struct attr_info attrs[] = {
@ -238,8 +238,3 @@ verify_conf(keychain_t *chain, const struct yml_node *node)
return conf_verify_dict(chain, node, attrs);
}
const struct particle_info plugin_info = {
.verify_conf = &verify_conf,
.from_conf = &from_conf,
};

View file

@ -227,7 +227,7 @@ progress_bar_new(struct particle *common, const char *tag, int width,
return common;
}
static struct particle *
struct particle *
from_conf(const struct yml_node *node, struct particle *common)
{
const struct yml_node *tag = yml_get_value(node, "tag");
@ -254,7 +254,7 @@ from_conf(const struct yml_node *node, struct particle *common)
conf_to_particle(indicator, inherited));
}
static bool
bool
verify_conf(keychain_t *chain, const struct yml_node *node)
{
static const struct attr_info attrs[] = {
@ -271,8 +271,3 @@ verify_conf(keychain_t *chain, const struct yml_node *node)
return conf_verify_dict(chain, node, attrs);
}
const struct particle_info plugin_info = {
.verify_conf = &verify_conf,
.from_conf = &from_conf,
};

View file

@ -152,7 +152,7 @@ ramp_new(struct particle *common, const char *tag,
return common;
}
static struct particle *
struct particle *
from_conf(const struct yml_node *node, struct particle *common)
{
const struct yml_node *tag = yml_get_value(node, "tag");
@ -173,7 +173,7 @@ from_conf(const struct yml_node *node, struct particle *common)
return ramp_new(common, yml_value_as_string(tag), parts, count);
}
static bool
bool
verify_conf(keychain_t *chain, const struct yml_node *node)
{
static const struct attr_info attrs[] = {
@ -184,8 +184,3 @@ verify_conf(keychain_t *chain, const struct yml_node *node)
return conf_verify_dict(chain, node, attrs);
}
const struct particle_info plugin_info = {
.verify_conf = &verify_conf,
.from_conf = &from_conf,
};

View file

@ -133,7 +133,7 @@ string_new(struct particle *common, const char *text, size_t max_len)
return common;
}
static struct particle *
struct particle *
from_conf(const struct yml_node *node, struct particle *common)
{
const struct yml_node *text = yml_get_value(node, "text");
@ -145,7 +145,7 @@ from_conf(const struct yml_node *node, struct particle *common)
max != NULL ? yml_value_as_int(max) : 0);
}
static bool
bool
verify_conf(keychain_t *chain, const struct yml_node *node)
{
static const struct attr_info attrs[] = {
@ -156,8 +156,3 @@ verify_conf(keychain_t *chain, const struct yml_node *node)
return conf_verify_dict(chain, node, attrs);
}
const struct particle_info plugin_info = {
.verify_conf = &verify_conf,
.from_conf = &from_conf,
};

View file

@ -66,15 +66,27 @@ plugin_load(const char *name, enum plugin_type type)
return NULL;
}
tll_push_back(plugins, ((struct plugin){strdup(name), type, lib, NULL}));
tll_push_back(plugins, ((struct plugin){strdup(name), type, lib, {NULL}}));
struct plugin *plug = &tll_back(plugins);
dlerror(); /* Clear previous error */
plug->sym = dlsym(lib, "plugin_info");
const char *dl_error = NULL;
const char *dlsym_error = dlerror();
if (dlsym_error != NULL) {
LOG_ERR("%s: %s: dlsym: %s", type2str(type), name, dlsym_error);
if (type == PLUGIN_MODULE) {
plug->sym = dlsym(lib, "plugin_info");
dl_error = dlerror();
} else {
plug->particle.verify_conf = dlsym(lib, "verify_conf");
dl_error = dlerror();
if (dl_error == NULL) {
plug->particle.from_conf = dlsym(lib, "from_conf");
dl_error = dlerror();
}
}
if (dl_error != NULL) {
LOG_ERR("%s: %s: dlsym: %s", type2str(type), name, dl_error);
return NULL;
}
@ -88,9 +100,9 @@ plugin_load_module(const char *name)
return plug != NULL ? plug->sym : NULL;
}
const struct particle_info *
const struct particle_iface *
plugin_load_particle(const char *name)
{
const struct plugin *plug = plugin_load(name, PLUGIN_PARTICLE);
return plug != NULL ? plug->sym : NULL;
return plug != NULL ? &plug->particle : NULL;
}

View file

@ -1,10 +1,17 @@
#pragma once
#include "config-verify.h"
#include "module.h"
#include "particle.h"
struct particle_iface {
bool (*verify_conf)(keychain_t *chain, const struct yml_node *node);
struct particle *(*from_conf)(
const struct yml_node *node, struct particle *common);
};
const struct module_info *plugin_load_module(const char *name);
const struct particle_info *plugin_load_particle(const char *name);
const struct particle_iface *plugin_load_particle(const char *name);
enum plugin_type { PLUGIN_MODULE, PLUGIN_PARTICLE };
@ -13,7 +20,10 @@ struct plugin {
enum plugin_type type;
void *lib;
const void *sym;
union {
void *sym;
struct particle_iface particle;
};
};
const struct plugin *plugin_load(const char *name, enum plugin_type type);