Skip to content

Instantly share code, notes, and snippets.

@igormorgado
Last active June 15, 2020 12:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save igormorgado/8c492021ae6b15c5979015ea0afb9bf3 to your computer and use it in GitHub Desktop.
Save igormorgado/8c492021ae6b15c5979015ea0afb9bf3 to your computer and use it in GitHub Desktop.
#include <glib.h>
#include <glib/gi18n.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
typedef int32_t i32;
// A sample object data
struct data
{
int val;
float real;
char txt[256];
};
// Object header
struct object {
char id[38];
char name[256];
size_t refcount;
struct data data;
};
struct object * object_init();
char * object_get_id (struct object *object);
char * object_get_name (struct object *object);
void object_print (struct object *object);
void _object_print_hash (gpointer key, gpointer value, gpointer user_data);
void object_unref (struct object *object); // Remove a refcount and free it if 0
void object_free (struct object *object); // Remove if refcount == 0;
void object_destroy (struct object *object); // Destroy object ignore refcount
gboolean object_equal (gconstpointer obja, gconstpointer objb);
guint object_hash (gconstpointer obj);
struct manager {
size_t nobjects;
GHashTable * objects;
};
struct manager * manager_init();
bool manager_destroy (struct manager *manager, bool cleanup);
char * manager_new_object (struct manager *manager);
bool manager_add_object (struct manager *manager, struct object *object);
bool manager_del_object (struct manager *manager, const char *id);
bool manager_del_object_by_name (struct manager *manager, const char *name);
void _manager_object_unref (gpointer key, gpointer value, gpointer data);
i32 manager_print (struct manager *manager);
struct object * manager_get_object_by_name(char *name);
struct object * manager_get_object_by_id(char *id);
char * manager_get_object_id_by_name(char *name);
char * manager_get_object_name_by_id(char *id);
int main(int argc, char *argv[]) {
struct manager * mgr = manager_init();
char *oid = manager_new_object(mgr);
manager_new_object(mgr);
manager_new_object(mgr);
manager_print(mgr);
g_print("Objects in manager %zu\n", mgr->nobjects);
g_print("Deleting %s\n", oid);
manager_del_object(mgr, oid);
g_print("Objects in manager %zu\n", mgr->nobjects);
manager_destroy(mgr, true);
return EXIT_SUCCESS;
}
/*
*
* OBJECT FUNCTIONS
*
*/
struct object *
object_init()
{
struct object *self = malloc(sizeof *self);
char *id = g_uuid_string_random();
g_strlcpy(self->id, id, 38);
free(id);
g_strlcpy(self->name, "PLACEHOLDER", 256);
self->refcount = 0;
self->data.val = 42;
self->data.real = 3.1415f;
g_strlcpy(self->data.txt, "DATA PLACEHOLDER", 256);
return self;
}
void
object_destroy (struct object *self)
{
// Debug, use object_print instead...
// g_print("Destroy object id: %s - name: %s - count: %zu\n",
// ((struct object*)self)->id,
// ((struct object*)self)->name,
// ((struct object*)self)->refcount);
free(self);
}
void
object_free (struct object *self)
{
if(self && self->refcount < 1)
{
// Debug, use object_print instead...
// g_print("Free object id: %s - name: %s - count: %zu\n",
// ((struct object*)self)->id,
// ((struct object*)self)->name,
// ((struct object*)self)->refcount);
object_destroy(self);
}
}
void
object_unref (struct object *self)
{
if(self)
{
self->refcount -= 1;
object_free(self);
}
}
void
_object_print_hash(gpointer key, gpointer value, gpointer user_data)
{
object_print ((struct object *)value);
}
void
object_print (struct object *self)
{
g_print("(%s)[%s]: %d, %f, %s\n",
self->id,
self->name,
self->data.val,
self->data.real,
self->data.txt);
}
struct manager *
manager_init()
{
struct manager * self = malloc(sizeof *self);
self->nobjects = 0;
self->objects = g_hash_table_new(object_hash, object_equal);
return self;
}
void
_manager_object_unref(gpointer key, gpointer value, gpointer data)
{
// DEBUG, use object_print instead...
g_print("Unref object id: %s - name: %s - count: %zu\n",
((struct object*)value)->id,
((struct object*)value)->name,
((struct object*)value)->refcount);
((struct manager *)data)->nobjects -= 1;
object_unref((struct object*)value);
}
bool
manager_del_object(struct manager *self, const char *id)
{
bool retval = false;
// TODO: NEED TO USE g_hash_table_full
struct object * obj = g_hash_table_lookup(self->objects, id);
retval = g_hash_table_remove (self->objects, id);
// TODO: NEED TO USE g_hash_table_full
object_unref(obj);
if (retval == true)
{
self->nobjects -= 1;
}
return retval;
}
bool
manager_destroy(struct manager *self, bool clean) {
if(self)
{
if(self->objects)
{
if(clean)
{
g_hash_table_foreach(self->objects, _manager_object_unref, self);
}
g_hash_table_destroy(self->objects);
}
free(self);
return true;
}
return false;
}
bool
manager_add_object(struct manager *self, struct object *object) {
bool retval = false;
retval = g_hash_table_insert(self->objects, object->id, object);
if(retval == true)
{
object->refcount += 1;
}
return retval;
}
char *
manager_new_object(struct manager *self)
{
bool retval = false;
struct object *obj = object_init();
if (obj) {
retval = manager_add_object(self, obj);
}
if(retval == true) {
self->nobjects +=1;
return obj->id;
} else {
return NULL;
}
}
i32
manager_print(struct manager *self)
{
g_hash_table_foreach(self->objects, _object_print_hash, NULL);
return g_hash_table_size(self->objects);
}
gboolean
object_equal(gconstpointer obja, gconstpointer objb) {
return g_str_equal (((struct object *)obja)->id, ((struct object *)objb)->id);
}
guint
object_hash(gconstpointer obj) {
return g_str_hash (((struct object *)obj)->id);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment