X-Git-Url: http://git.draconx.ca/gitweb/upkg.git/blobdiff_plain/d323b189345af7ff63c37f7501b70d0674cb74a4..557eccb32013460418b72bb20acd79c018a5e95a:/src/uobject/module.c?ds=sidebyside diff --git a/src/uobject/module.c b/src/uobject/module.c new file mode 100644 index 0000000..1872a8d --- /dev/null +++ b/src/uobject/module.c @@ -0,0 +1,106 @@ +/* + * upkg: tool for manipulating Unreal Tournament packages. + * Copyright (C) 2009 Nick Bowler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "avl.h" + +static unsigned initialized; +static struct avl_table *package_tree; + +static char *str_cpy_lower(char *dst, const char *src) +{ + size_t i; + + for (i = 0; src[i]; i++) + dst[i] = tolower(src[i]); + dst[i] = 0; + + return dst; +} + +static int modcmp(const void *a, const void *b, void *_data) +{ + const GTypeModule *ma = a; + const GTypeModule *mb = b; + + return strcmp(ma->name, mb->name); +} + +int u_object_module_init(void) +{ + if (!initialized) { + package_tree = avl_create(modcmp, NULL, NULL); + if (!package_tree) { + fprintf(stderr, "%s: failed to create package tree.\n", __func__); + return -1; + } + + g_type_init(); + } + + initialized++; + return 0; +} + +int u_object_module_exit(void) +{ + if (--initialized) + return 0; + + avl_destroy(package_tree, NULL); + + return 0; +} + +GType u_object_module_get_class(const char *package, const char *class) +{ + char buf[strlen(package) + strlen(class) + 1]; + GTypeModule search = { .name = str_cpy_lower(buf, package) }; + + GTypeModule *mod = avl_find(package_tree, &search); + if (!mod) { + void **p; + + mod = u_pkg_new_by_name(package); + if (!mod) { + return 0; + } + + p = avl_probe(package_tree, mod); + if (!p) { + g_object_unref(mod); + return 0; + } + } + + if (!g_type_module_use(mod)) + return 0; + + str_cpy_lower(buf+strlen(package), class); + buf[0] = toupper(buf[0]); + buf[strlen(package)] = toupper(buf[strlen(package)]); + return g_type_from_name(buf); +}