/* main.c generated by valac, the Vala compiler
 * generated from main.vala, do not modify */


#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gmodule.h>
#include <stdio.h>


#define TYPE_PLUGIN_REGISTRAR (plugin_registrar_get_type ())
#define PLUGIN_REGISTRAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PLUGIN_REGISTRAR, PluginRegistrar))
#define PLUGIN_REGISTRAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PLUGIN_REGISTRAR, PluginRegistrarClass))
#define IS_PLUGIN_REGISTRAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PLUGIN_REGISTRAR))
#define IS_PLUGIN_REGISTRAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PLUGIN_REGISTRAR))
#define PLUGIN_REGISTRAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PLUGIN_REGISTRAR, PluginRegistrarClass))

typedef struct _PluginRegistrar PluginRegistrar;
typedef struct _PluginRegistrarClass PluginRegistrarClass;
typedef struct _PluginRegistrarPrivate PluginRegistrarPrivate;
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_module_close0(var) ((var == NULL) ? NULL : (var = (g_module_close (var), NULL)))

#define TYPE_TEST_PLUGIN (test_plugin_get_type ())
#define TEST_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TEST_PLUGIN, TestPlugin))
#define IS_TEST_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TEST_PLUGIN))
#define TEST_PLUGIN_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TYPE_TEST_PLUGIN, TestPluginIface))

typedef struct _TestPlugin TestPlugin;
typedef struct _TestPluginIface TestPluginIface;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

struct _PluginRegistrar {
	GTypeModule parent_instance;
	PluginRegistrarPrivate * priv;
};

struct _PluginRegistrarClass {
	GTypeModuleClass parent_class;
};

struct _PluginRegistrarPrivate {
	GType t_type;
	GBoxedCopyFunc t_dup_func;
	GDestroyNotify t_destroy_func;
	char* _path;
	GType type;
	GModule* module;
};

typedef GType (*PluginRegistrarRegisterPluginFunction) (GTypeModule* module, void* user_data);
struct _TestPluginIface {
	GTypeInterface parent_iface;
	void (*hello) (TestPlugin* self);
};


static gpointer plugin_registrar_parent_class = NULL;

GType plugin_registrar_get_type (void);
#define PLUGIN_REGISTRAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_PLUGIN_REGISTRAR, PluginRegistrarPrivate))
enum  {
	PLUGIN_REGISTRAR_DUMMY_PROPERTY,
	PLUGIN_REGISTRAR_PATH,
	PLUGIN_REGISTRAR_T_TYPE,
	PLUGIN_REGISTRAR_T_DUP_FUNC,
	PLUGIN_REGISTRAR_T_DESTROY_FUNC
};
static void plugin_registrar_set_path (PluginRegistrar* self, const char* value);
PluginRegistrar* plugin_registrar_new (GType t_type, GBoxedCopyFunc t_dup_func, GDestroyNotify t_destroy_func, const char* name);
PluginRegistrar* plugin_registrar_construct (GType object_type, GType t_type, GBoxedCopyFunc t_dup_func, GDestroyNotify t_destroy_func, const char* name);
static void plugin_registrar_real_unload (GTypeModule* base);
const char* plugin_registrar_get_path (PluginRegistrar* self);
static gboolean plugin_registrar_real_load (GTypeModule* base);
gpointer plugin_registrar_new_object (PluginRegistrar* self);
static void plugin_registrar_finalize (GObject* obj);
static void plugin_registrar_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
static void plugin_registrar_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec);
GType test_plugin_get_type (void);
void test_plugin_hello (TestPlugin* self);
void _vala_main (void);



PluginRegistrar* plugin_registrar_construct (GType object_type, GType t_type, GBoxedCopyFunc t_dup_func, GDestroyNotify t_destroy_func, const char* name) {
	GParameter * __params;
	GParameter * __params_it;
	PluginRegistrar * self;
	char* _tmp0_;
	g_return_val_if_fail (name != NULL, NULL);
	__params = g_new0 (GParameter, 3);
	__params_it = __params;
	__params_it->name = "t-type";
	g_value_init (&__params_it->value, G_TYPE_GTYPE);
	g_value_set_gtype (&__params_it->value, t_type);
	__params_it++;
	__params_it->name = "t-dup-func";
	g_value_init (&__params_it->value, G_TYPE_POINTER);
	g_value_set_pointer (&__params_it->value, t_dup_func);
	__params_it++;
	__params_it->name = "t-destroy-func";
	g_value_init (&__params_it->value, G_TYPE_POINTER);
	g_value_set_pointer (&__params_it->value, t_destroy_func);
	__params_it++;
	self = g_object_newv (object_type, __params_it - __params, __params);
	g_assert (g_module_supported ());
	plugin_registrar_set_path (self, _tmp0_ = g_module_build_path (g_getenv ("PWD"), name));
	_g_free0 (_tmp0_);
	while (__params_it > __params) {
		--__params_it;
		g_value_unset (&__params_it->value);
	}
	g_free (__params);
	return self;
}


PluginRegistrar* plugin_registrar_new (GType t_type, GBoxedCopyFunc t_dup_func, GDestroyNotify t_destroy_func, const char* name) {
	return plugin_registrar_construct (TYPE_PLUGIN_REGISTRAR, t_type, t_dup_func, t_destroy_func, name);
}


static void plugin_registrar_real_unload (GTypeModule* base) {
	PluginRegistrar * self;
	self = (PluginRegistrar*) base;
}


static gboolean plugin_registrar_real_load (GTypeModule* base) {
	PluginRegistrar * self;
	gboolean result = FALSE;
	GModule* _tmp0_;
	void* function = NULL;
	PluginRegistrarRegisterPluginFunction _tmp1_;
	GDestroyNotify register_plugin_target_destroy_notify = NULL;
	void* register_plugin_target = NULL;
	PluginRegistrarRegisterPluginFunction register_plugin;
	self = (PluginRegistrar*) base;
	fprintf (stdout, "Loading plugin with path: '%s'\n", self->priv->_path);
	self->priv->module = (_tmp0_ = g_module_open (self->priv->_path, G_MODULE_BIND_LAZY), _g_module_close0 (self->priv->module), _tmp0_);
	if (self->priv->module == NULL) {
		result = FALSE;
		return result;
	}
	fprintf (stdout, "Loaded module: '%s'\n", g_module_name (self->priv->module));
	g_module_symbol (self->priv->module, "register_plugin", &function);
	register_plugin = (_tmp1_ = (PluginRegistrarRegisterPluginFunction) function, register_plugin_target = NULL, register_plugin_target_destroy_notify = NULL, _tmp1_);
	self->priv->type = register_plugin ((GTypeModule*) self, register_plugin_target);
	fprintf (stdout, "Plugin type: %s\n\n", g_type_name (self->priv->type));
	result = TRUE;
	(register_plugin_target_destroy_notify == NULL) ? NULL : (register_plugin_target_destroy_notify (register_plugin_target), NULL);
	register_plugin = NULL;
	register_plugin_target = NULL;
	register_plugin_target_destroy_notify = NULL;
	return result;
}


gpointer plugin_registrar_new_object (PluginRegistrar* self) {
	gpointer result = NULL;
	GObject* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	result = (_tmp0_ = g_object_new (self->priv->type, NULL), g_object_is_floating (_tmp0_) ? g_object_ref_sink (_tmp0_) : _tmp0_);
	return result;
}


const char* plugin_registrar_get_path (PluginRegistrar* self) {
	const char* result;
	g_return_val_if_fail (self != NULL, NULL);
	result = self->priv->_path;
	return result;
}


static void plugin_registrar_set_path (PluginRegistrar* self, const char* value) {
	char* _tmp0_;
	g_return_if_fail (self != NULL);
	self->priv->_path = (_tmp0_ = g_strdup (value), _g_free0 (self->priv->_path), _tmp0_);
	g_object_notify ((GObject *) self, "path");
}


static void plugin_registrar_class_init (PluginRegistrarClass * klass) {
	plugin_registrar_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (PluginRegistrarPrivate));
	G_TYPE_MODULE_CLASS (klass)->unload = plugin_registrar_real_unload;
	G_TYPE_MODULE_CLASS (klass)->load = plugin_registrar_real_load;
	G_OBJECT_CLASS (klass)->get_property = plugin_registrar_get_property;
	G_OBJECT_CLASS (klass)->set_property = plugin_registrar_set_property;
	G_OBJECT_CLASS (klass)->finalize = plugin_registrar_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), PLUGIN_REGISTRAR_T_TYPE, g_param_spec_gtype ("t-type", "type", "type", G_TYPE_NONE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PLUGIN_REGISTRAR_T_DUP_FUNC, g_param_spec_pointer ("t-dup-func", "dup func", "dup func", G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PLUGIN_REGISTRAR_T_DESTROY_FUNC, g_param_spec_pointer ("t-destroy-func", "destroy func", "destroy func", G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), PLUGIN_REGISTRAR_PATH, g_param_spec_string ("path", "path", "path", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
}


static void plugin_registrar_instance_init (PluginRegistrar * self) {
	self->priv = PLUGIN_REGISTRAR_GET_PRIVATE (self);
}


static void plugin_registrar_finalize (GObject* obj) {
	PluginRegistrar * self;
	self = PLUGIN_REGISTRAR (obj);
	_g_free0 (self->priv->_path);
	_g_module_close0 (self->priv->module);
	G_OBJECT_CLASS (plugin_registrar_parent_class)->finalize (obj);
}


GType plugin_registrar_get_type (void) {
	static volatile gsize plugin_registrar_type_id__volatile = 0;
	if (g_once_init_enter (&plugin_registrar_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (PluginRegistrarClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) plugin_registrar_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (PluginRegistrar), 0, (GInstanceInitFunc) plugin_registrar_instance_init, NULL };
		GType plugin_registrar_type_id;
		plugin_registrar_type_id = g_type_register_static (G_TYPE_TYPE_MODULE, "PluginRegistrar", &g_define_type_info, 0);
		g_once_init_leave (&plugin_registrar_type_id__volatile, plugin_registrar_type_id);
	}
	return plugin_registrar_type_id__volatile;
}


static void plugin_registrar_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
	PluginRegistrar * self;
	self = PLUGIN_REGISTRAR (object);
	switch (property_id) {
		case PLUGIN_REGISTRAR_PATH:
		g_value_set_string (value, plugin_registrar_get_path (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}


static void plugin_registrar_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
	PluginRegistrar * self;
	self = PLUGIN_REGISTRAR (object);
	switch (property_id) {
		case PLUGIN_REGISTRAR_PATH:
		plugin_registrar_set_path (self, g_value_get_string (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
		case PLUGIN_REGISTRAR_T_TYPE:
		self->priv->t_type = g_value_get_gtype (value);
		break;
		case PLUGIN_REGISTRAR_T_DUP_FUNC:
		self->priv->t_dup_func = g_value_get_pointer (value);
		break;
		case PLUGIN_REGISTRAR_T_DESTROY_FUNC:
		self->priv->t_destroy_func = g_value_get_pointer (value);
		break;
	}
}


void _vala_main (void) {
	PluginRegistrar* registrar;
	TestPlugin* plugin;
	registrar = plugin_registrar_new (TYPE_TEST_PLUGIN, (GBoxedCopyFunc) g_object_ref, g_object_unref, "plugin");
	G_TYPE_MODULE_GET_CLASS ((GTypeModule*) registrar)->load ((GTypeModule*) registrar);
	plugin = (TestPlugin*) plugin_registrar_new_object (registrar);
	test_plugin_hello (plugin);
	_g_object_unref0 (registrar);
	_g_object_unref0 (plugin);
}


int main (int argc, char ** argv) {
	g_type_init ();
	_vala_main ();
	return 0;
}




