[gjs: 6/8] jsapi-util: add GjsAutoTypeClass and use it



commit 12ad87b52bee170a48e45a316f6854c67fdc51e1
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Tue Oct 9 07:21:09 2018 +0200

    jsapi-util: add GjsAutoTypeClass and use it

 gi/arg.cpp       |  6 ++----
 gi/gerror.cpp    |  7 ++-----
 gi/object.cpp    |  9 ++-------
 gi/private.cpp   |  5 ++---
 gi/value.cpp     |  6 ++----
 gjs/jsapi-util.h | 12 ++++++++++++
 6 files changed, 22 insertions(+), 23 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 0fd1b992..96cb7e5b 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -48,13 +48,12 @@ _gjs_flags_value_is_valid(JSContext   *context,
 {
     GFlagsValue *v;
     guint32 tmpval;
-    void *klass;
 
     /* FIXME: Do proper value check for flags with GType's */
     if (gtype == G_TYPE_NONE)
         return true;
 
-    klass = g_type_class_ref(gtype);
+    GjsAutoTypeClass<GTypeClass> klass = g_type_class_ref(gtype);
 
     /* check all bits are defined for flags.. not necessarily desired */
     tmpval = (guint32)value;
@@ -66,7 +65,7 @@ _gjs_flags_value_is_valid(JSContext   *context,
     }
 
     while (tmpval) {
-        v = g_flags_get_first_value((GFlagsClass *) klass, tmpval);
+        v = g_flags_get_first_value(klass.as<GFlagsClass>(), tmpval);
         if (!v) {
             gjs_throw(context,
                       "0x%x is not a valid value for flags %s",
@@ -76,7 +75,6 @@ _gjs_flags_value_is_valid(JSContext   *context,
 
         tmpval &= ~v->value;
     }
-    g_type_class_unref(klass);
 
     return true;
 }
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index 639d3472..7150cf67 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -551,8 +551,6 @@ GError *
 gjs_gerror_make_from_error(JSContext       *cx,
                            JS::HandleObject obj)
 {
-    using AutoEnumClass = std::unique_ptr<GEnumClass, decltype(&g_type_class_unref)>;
-
     if (gjs_typecheck_gerror(cx, obj, false)) {
         /* This is already a GError, just copy it */
         GError *inner = gjs_gerror_from_error(cx, obj);
@@ -577,9 +575,8 @@ gjs_gerror_make_from_error(JSContext       *cx,
     if (!gjs_string_to_utf8(cx, v_message, &message))
         return nullptr;
 
-    AutoEnumClass klass(static_cast<GEnumClass *>(g_type_class_ref(GJS_TYPE_JS_ERROR)),
-                        g_type_class_unref);
-    const GEnumValue *value = g_enum_get_value_by_name(klass.get(), name);
+    GjsAutoTypeClass<GEnumClass> klass = g_type_class_ref(GJS_TYPE_JS_ERROR);
+    const GEnumValue *value = g_enum_get_value_by_name(klass, name);
     int code;
     if (value)
         code = value->value;
diff --git a/gi/object.cpp b/gi/object.cpp
index e3de848e..c1f70086 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -284,10 +284,9 @@ GParamSpec* ObjectPrototype::find_param_spec_from_id(JSContext* cx,
         return nullptr;
 
     GjsAutoChar gname = gjs_hyphen_from_camel(js_prop_name);
-    GObjectClass *gobj_class = G_OBJECT_CLASS(g_type_class_ref(m_gtype));
+    GjsAutoTypeClass<GObjectClass> gobj_class = g_type_class_ref(m_gtype);
     GParamSpec* pspec = g_object_class_find_property(gobj_class, gname);
     GjsAutoParam param_spec(pspec, GjsAutoParam::TakeOwnership());
-    g_type_class_unref(gobj_class);
 
     if (!param_spec) {
         _gjs_proxy_throw_nonexistent_field(cx, m_gtype, js_prop_name);
@@ -2391,7 +2390,6 @@ find_vfunc_info (JSContext *context,
     int length, i;
     GIBaseInfo *ancestor_info;
     GjsAutoInfo<GIStructInfo> struct_info;
-    gpointer implementor_class;
     bool is_interface;
 
     field_info_ret->reset();
@@ -2402,13 +2400,12 @@ find_vfunc_info (JSContext *context,
 
     is_interface = g_base_info_get_type(ancestor_info) == GI_INFO_TYPE_INTERFACE;
 
-    implementor_class = g_type_class_ref(implementor_gtype);
+    GjsAutoTypeClass<void> implementor_class = g_type_class_ref(implementor_gtype);
     if (is_interface) {
         GTypeInstance *implementor_iface_class;
         implementor_iface_class = (GTypeInstance*) g_type_interface_peek(implementor_class,
                                                         ancestor_gtype);
         if (implementor_iface_class == NULL) {
-            g_type_class_unref(implementor_class);
             gjs_throw (context, "Couldn't find GType of implementor of interface %s.",
                        g_type_name(ancestor_gtype));
             return false;
@@ -2422,8 +2419,6 @@ find_vfunc_info (JSContext *context,
         *implementor_vtable_ret = implementor_class;
     }
 
-    g_type_class_unref(implementor_class);
-
     length = g_struct_info_get_n_fields(struct_info);
     for (i = 0; i < length; i++) {
         GjsAutoInfo<GIFieldInfo> field_info =
diff --git a/gi/private.cpp b/gi/private.cpp
index 512530e4..bbfbd8d4 100644
--- a/gi/private.cpp
+++ b/gi/private.cpp
@@ -63,9 +63,8 @@ static bool gjs_override_property(JSContext* cx, unsigned argc, JS::Value* vp) {
         pspec = g_object_interface_find_property(interface_type, name);
         g_type_default_interface_unref(interface_type);
     } else {
-        auto* class_type = static_cast<GTypeClass*>(g_type_class_ref(gtype));
-        pspec = g_object_class_find_property(G_OBJECT_CLASS(class_type), name);
-        g_type_class_unref(class_type);
+        GjsAutoTypeClass<GObjectClass> class_type = g_type_class_ref(gtype);
+        pspec = g_object_class_find_property(class_type, name);
     }
 
     if (!pspec) {
diff --git a/gi/value.cpp b/gi/value.cpp
index 62a21b49..bc265763 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -598,12 +598,10 @@ gjs_value_to_g_value_internal(JSContext      *context,
 
         if (JS::ToInt64(context, value, &value_int64)) {
             GEnumValue *v;
-            gpointer gtype_class = g_type_class_ref(gtype);
+            GjsAutoTypeClass<GEnumClass> enum_class = g_type_class_ref(gtype);
 
             /* See arg.c:_gjs_enum_to_int() */
-            v = g_enum_get_value(G_ENUM_CLASS(gtype_class),
-                                 (int)value_int64);
-            g_type_class_unref(gtype_class);
+            v = g_enum_get_value(enum_class, (int)value_int64);
             if (v == NULL) {
                 gjs_throw(context,
                           "%d is not a valid value for enumeration %s",
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 95aa5a0f..81623b38 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -66,6 +66,18 @@ public:
     }
 };
 
+template<typename T = GTypeClass>
+class GjsAutoTypeClass : public std::unique_ptr<T, decltype(&g_type_class_unref)> {
+public:
+    GjsAutoTypeClass(gpointer ptr = nullptr)
+        : GjsAutoTypeClass::unique_ptr(static_cast<T*>(ptr), g_type_class_unref) {}
+
+    operator T *() const { return GjsAutoTypeClass::unique_ptr::get(); }
+
+    template<typename C>
+    C *as() const { return reinterpret_cast<C*>(operator T *()); }
+};
+
 template<typename T = GIBaseInfo>
 class GjsAutoInfo : public std::unique_ptr<T, decltype(&g_base_info_unref)> {
 public:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]