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; return false;
} }
const struct particle_info *info = plugin_load_particle(particle_name); const struct particle_iface *iface = plugin_load_particle(particle_name);
if (info == NULL) { if (iface == NULL) {
LOG_ERR( LOG_ERR("%s: invalid particle name: %s",
"%s: invalid particle name: %s",
conf_err_prefix(chain, particle), particle_name); conf_err_prefix(chain, particle), particle_name);
return false; return false;
} }
assert(info->verify_conf != NULL); assert(iface->verify_conf != NULL);
chain_push(chain, particle_name); chain_push(chain, particle_name);
if (!info->verify_conf(chain, values)) if (!iface->verify_conf(chain, values))
return false; return false;
chain_pop(chain); 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( struct particle *common = particle_common_new(
left, right, on_click_template, font, foreground, deco); 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); assert(iface != NULL);
return info->from_conf(pair.value, common); return iface->from_conf(pair.value, common);
} }
struct bar * struct bar *

View file

@ -9,25 +9,6 @@
#include "yml.h" #include "yml.h"
struct bar; 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 { struct particle {
void *private; void *private;
@ -80,3 +61,14 @@ void exposable_render_deco(
void exposable_default_on_mouse( void exposable_default_on_mouse(
struct exposable *exposable, struct bar *bar, struct exposable *exposable, struct bar *bar,
enum mouse_event event, int x, int y); 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; return common;
} }
static struct particle * struct particle *
from_conf(const struct yml_node *node, struct particle *common) from_conf(const struct yml_node *node, struct particle *common)
{ {
return empty_new(common); return empty_new(common);
} }
static bool bool
verify_conf(keychain_t *chain, const struct yml_node *node) verify_conf(keychain_t *chain, const struct yml_node *node)
{ {
static const struct attr_info attrs[] = { 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); 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; return common;
} }
static struct particle * struct particle *
from_conf(const struct yml_node *node, struct particle *common) from_conf(const struct yml_node *node, struct particle *common)
{ {
const struct yml_node *items = yml_get_value(node, "items"); 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); return particle_list_new(common, parts, count, left_spacing, right_spacing);
} }
static bool bool
verify_conf(keychain_t *chain, const struct yml_node *node) verify_conf(keychain_t *chain, const struct yml_node *node)
{ {
static const struct attr_info attrs[] = { 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); 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; return true;
} }
static struct particle * struct particle *
from_conf(const struct yml_node *node, struct particle *common) from_conf(const struct yml_node *node, struct particle *common)
{ {
const struct yml_node *tag = yml_get_value(node, "tag"); 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); default_particle);
} }
static bool bool
verify_conf(keychain_t *chain, const struct yml_node *node) verify_conf(keychain_t *chain, const struct yml_node *node)
{ {
static const struct attr_info attrs[] = { 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); 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; return common;
} }
static struct particle * struct particle *
from_conf(const struct yml_node *node, struct particle *common) from_conf(const struct yml_node *node, struct particle *common)
{ {
const struct yml_node *tag = yml_get_value(node, "tag"); 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)); conf_to_particle(indicator, inherited));
} }
static bool bool
verify_conf(keychain_t *chain, const struct yml_node *node) verify_conf(keychain_t *chain, const struct yml_node *node)
{ {
static const struct attr_info attrs[] = { 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); 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; return common;
} }
static struct particle * struct particle *
from_conf(const struct yml_node *node, struct particle *common) from_conf(const struct yml_node *node, struct particle *common)
{ {
const struct yml_node *tag = yml_get_value(node, "tag"); 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); return ramp_new(common, yml_value_as_string(tag), parts, count);
} }
static bool bool
verify_conf(keychain_t *chain, const struct yml_node *node) verify_conf(keychain_t *chain, const struct yml_node *node)
{ {
static const struct attr_info attrs[] = { 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); 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; return common;
} }
static struct particle * struct particle *
from_conf(const struct yml_node *node, struct particle *common) from_conf(const struct yml_node *node, struct particle *common)
{ {
const struct yml_node *text = yml_get_value(node, "text"); 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); max != NULL ? yml_value_as_int(max) : 0);
} }
static bool bool
verify_conf(keychain_t *chain, const struct yml_node *node) verify_conf(keychain_t *chain, const struct yml_node *node)
{ {
static const struct attr_info attrs[] = { 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); 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; 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); struct plugin *plug = &tll_back(plugins);
dlerror(); /* Clear previous error */ dlerror(); /* Clear previous error */
plug->sym = dlsym(lib, "plugin_info"); const char *dl_error = NULL;
const char *dlsym_error = dlerror(); if (type == PLUGIN_MODULE) {
if (dlsym_error != NULL) { plug->sym = dlsym(lib, "plugin_info");
LOG_ERR("%s: %s: dlsym: %s", type2str(type), name, dlsym_error); 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; return NULL;
} }
@ -88,9 +100,9 @@ plugin_load_module(const char *name)
return plug != NULL ? plug->sym : NULL; return plug != NULL ? plug->sym : NULL;
} }
const struct particle_info * const struct particle_iface *
plugin_load_particle(const char *name) plugin_load_particle(const char *name)
{ {
const struct plugin *plug = plugin_load(name, PLUGIN_PARTICLE); 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 #pragma once
#include "config-verify.h"
#include "module.h" #include "module.h"
#include "particle.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 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 }; enum plugin_type { PLUGIN_MODULE, PLUGIN_PARTICLE };
@ -13,7 +20,10 @@ struct plugin {
enum plugin_type type; enum plugin_type type;
void *lib; void *lib;
const void *sym; union {
void *sym;
struct particle_iface particle;
};
}; };
const struct plugin *plugin_load(const char *name, enum plugin_type type); const struct plugin *plugin_load(const char *name, enum plugin_type type);