]> git.draconx.ca Git - upkg.git/blobdiff - src/uobject/uobject.c
uobject: Add a helper function to load objects from packages.
[upkg.git] / src / uobject / uobject.c
index e5b500b2cd82e695cbadd2b013069a14ba22ff59..7b0a79e4e4a751f2a435582ea1ee934e30afdfbb 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  upkg: tool for manipulating Unreal Tournament packages.
- *  Copyright (C) 2009 Nick Bowler
+ *  Copyright © 2009-2011 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
@@ -23,6 +23,7 @@
 #include <glib-object.h>
 
 #include <uobject/uobject.h>
+#include <uobject/module.h>
 #include "upkg.h"
 #include "pack.h"
 
@@ -141,9 +142,10 @@ decode_property(UObject *o, const char *name, struct upkg_file *f, unsigned long
 }
 
 /* Deserialize properties from an Unreal package. */
-static int deserialize(UObject *o, struct upkg_file *f)
+static int deserialize(UObject *uo)
 {
-       struct u_object_priv *priv = U_OBJECT_GET_PRIV(o);
+       struct u_object_priv *priv = U_OBJECT_GET_PRIV(uo);
+       struct upkg_file *f = uo->pkg_file;
        unsigned long rc, tot_len = 0;
 
        while (1) {
@@ -167,7 +169,7 @@ static int deserialize(UObject *o, struct upkg_file *f)
                        return -1;
                len = rc;
 
-               name = upkg_get_name(f->pkg, tmp);
+               name = upkg_get_name(uo->pkg, tmp);
                if (!name) {
                        return -1;
                } else if (strcmp(name, "None") == 0) {
@@ -175,7 +177,7 @@ static int deserialize(UObject *o, struct upkg_file *f)
                        break;
                }
 
-               rc = decode_property(U_OBJECT(o), name, f, len);
+               rc = decode_property(uo, name, f, len);
                if (rc == 0)
                        return -1;
                len = rc;
@@ -203,17 +205,39 @@ int u_object_deserialize(GObject *obj, struct upkg *pkg, unsigned long idx)
                return -1;
        }
 
-       rc = U_OBJECT_GET_CLASS(obj)->deserialize(uo, f);
+       uo->pkg      = pkg;
+       uo->pkg_file = f;
+
+       rc = U_OBJECT_GET_CLASS(obj)->deserialize(uo);
        if (rc != 0) {
                upkg_export_close(f);
-       } else {
-               uo->pkg      = pkg;
-               uo->pkg_file = f;
+               uo->pkg_file = NULL;
        }
 
        return rc;
 }
 
+GObject *u_object_new_from_package(struct upkg *upkg, unsigned long idx)
+{
+       const struct upkg_export *export;
+       const char *class, *package;
+       GObject *obj = NULL;
+       GType type;
+
+       class = upkg_export_class(upkg, idx, &package);
+
+       type = u_object_module_get_class(package, class);
+       if (type) {
+               obj = g_object_new(type, NULL);
+               if (u_object_deserialize(obj, upkg, idx) != 0) {
+                       g_object_unref(obj);
+                       return NULL;
+               }
+       }
+
+       return obj;
+}
+
 static void u_object_init(UObject *o)
 {
        o->pkg      = NULL;