]> git.draconx.ca Git - upkg.git/blobdiff - src/engine/music.c
uobject: Implement an interface for loading/unloading.
[upkg.git] / src / engine / music.c
index 87a549b7e6d538766a2832ff7248afca41bfe50a..f770662995e8f63e2ea359117b005850783b7fc6 100644 (file)
@@ -3,6 +3,7 @@
 #include <glib-object.h>
 
 #include "exportable.h"
+#include "loadable.h"
 #include "uobject.h"
 #include "music.h"
 #include "upkg.h"
 
 struct music_priv {
        struct upkg_file *f;
+       unsigned loaded;
 };
 
 static void exportable_init(UObjectExportable *);
+static void loadable_init(UObjectLoadable *);
 
 G_DEFINE_DYNAMIC_TYPE_EXTENDED(EngineMusic, engine_music, U_OBJECT_TYPE, 0,
        G_IMPLEMENT_INTERFACE(U_OBJECT_TYPE_EXPORTABLE, exportable_init)
+       G_IMPLEMENT_INTERFACE(U_OBJECT_TYPE_LOADABLE, loadable_init)
 );
 
+static int load(GObject *o)
+{
+       struct music_priv *priv = MUSIC_GET_PRIV(o);
+
+       if (!priv->loaded) {
+               g_return_val_if_fail(priv->f != NULL, -1);
+
+               if (upkg_export_seek(priv->f, 0, SEEK_SET) != 0) {
+                       return -1;
+               }
+       }
+
+       priv->loaded++;
+       return 0;
+}
+
+static void unload(GObject *o)
+{
+       struct music_priv *priv = MUSIC_GET_PRIV(o);
+       g_return_if_fail(priv->loaded > 0);
+
+       --priv->loaded;
+}
+
 static int export(GObject *o, FILE *f)
 {
        struct music_priv *priv = MUSIC_GET_PRIV(o);
@@ -54,6 +82,12 @@ static void exportable_init(UObjectExportable *e)
        e->export_name = export_name;
 }
 
+static void loadable_init(UObjectLoadable *l)
+{
+       l->load   = load;
+       l->unload = unload;
+}
+
 static int deserialize(UObject *o, struct upkg_file *f)
 {
        struct music_priv *priv = MUSIC_GET_PRIV(o);
@@ -99,15 +133,28 @@ void music_register(GTypeModule *m)
 
 static void engine_music_init(EngineMusic *m)
 {
+       struct music_priv *priv = MUSIC_GET_PRIV(m);
+       *priv = (struct music_priv){0};
+}
+
+static void engine_music_finalize(GObject *o)
+{
+       struct music_priv *priv = MUSIC_GET_PRIV(o);
+
+       if (priv->loaded >= 1) {
+               priv->loaded = 1;
+               unload(o);
+       }
 }
 
 static void engine_music_class_init(EngineMusicClass *class)
 {
        UObjectClass *uo = U_OBJECT_CLASS(class);
-
+       GObjectClass *go = G_OBJECT_CLASS(class);
        g_type_class_add_private(class, sizeof (struct music_priv));
 
        uo->deserialize = deserialize;
+       go->finalize    = engine_music_finalize;
 }
 
 static void engine_music_class_finalize(EngineMusicClass *class)