[gjs: 8/12] cairo: Remove JSClass macros from CairoPath




commit 52110064b8259fc808d61a124ad907938c2cb1b0
Author: Philip Chimento <philip chimento gmail com>
Date:   Mon May 11 11:56:05 2020 -0700

    cairo: Remove JSClass macros from CairoPath
    
    Remove the usage of the GJS_DEFINE_PRIV_FROM_JS and GJS_DEFINE_PROTO
    families of macros from the Cairo path wrapper type. Use CWrapper instead,
    for more type safety and less boilerplate.

 modules/cairo-context.cpp | 16 ++++++--
 modules/cairo-path.cpp    | 95 +++++++++++++----------------------------------
 modules/cairo-private.h   | 42 ++++++++++++++++-----
 modules/cairo.cpp         |  2 +-
 4 files changed, 70 insertions(+), 85 deletions(-)
---
diff --git a/modules/cairo-context.cpp b/modules/cairo-context.cpp
index aff8c7b5..92033b2f 100644
--- a/modules/cairo-context.cpp
+++ b/modules/cairo-context.cpp
@@ -389,8 +389,8 @@ appendPath_func(JSContext *context,
                              "path", &path_wrapper))
         return false;
 
-    cairo_path_t* path = gjs_cairo_path_get_path(context, path_wrapper);
-    if (!path)
+    cairo_path_t* path;
+    if (!CairoPath::for_js_typecheck(context, path_wrapper, &path, &argv))
         return false;
 
     cairo_append_path(cr, path);
@@ -412,7 +412,11 @@ copyPath_func(JSContext *context,
         return false;
 
     path = cairo_copy_path(cr);
-    argv.rval().setObjectOrNull(gjs_cairo_path_from_path(context, path));
+    JSObject* retval = CairoPath::take_c_ptr(context, path);
+    if (!retval)
+        return false;
+
+    argv.rval().setObject(*retval);
     return true;
 }
 
@@ -430,7 +434,11 @@ copyPathFlat_func(JSContext *context,
         return false;
 
     path = cairo_copy_path_flat(cr);
-    argv.rval().setObjectOrNull(gjs_cairo_path_from_path(context, path));
+    JSObject* retval = CairoPath::take_c_ptr(context, path);
+    if (!retval)
+        return false;
+
+    argv.rval().setObject(*retval);
     return true;
 }
 
diff --git a/modules/cairo-path.cpp b/modules/cairo-path.cpp
index 36dbc1b4..a4a82725 100644
--- a/modules/cairo-path.cpp
+++ b/modules/cairo-path.cpp
@@ -1,97 +1,52 @@
 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
 // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
 // SPDX-FileCopyrightText: 2010 Red Hat, Inc.
+// SPDX-FileCopyrightText: 2020 Philip Chimento <philip chimento gmail com>
 
 #include <config.h>
 
 #include <cairo.h>
-#include <glib.h>
+#include <glib.h>  // for g_assert
 
-#include <js/Class.h>
 #include <js/PropertyDescriptor.h>  // for JSPROP_READONLY
 #include <js/PropertySpec.h>
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
-#include <jsapi.h>  // for JS_GetClass, JS_GetInstancePrivate
+#include <jsapi.h>
 
-#include "gjs/jsapi-class.h"
-#include "gjs/jsapi-util.h"
+#include "modules/cairo-private.h"
 
-[[nodiscard]] static JSObject* gjs_cairo_path_get_proto(JSContext*);
-
-struct GjsCairoPath
-    : GjsAutoPointer<cairo_path_t, cairo_path_t, cairo_path_destroy> {
-    explicit GjsCairoPath(cairo_path_t* path) : GjsAutoPointer(path) {}
-};
-
-GJS_DEFINE_PROTO_ABSTRACT("Path", cairo_path, JSCLASS_BACKGROUND_FINALIZE)
-GJS_DEFINE_PRIV_FROM_JS(GjsCairoPath, gjs_cairo_path_class);
-
-static void gjs_cairo_path_finalize(JSFreeOp*, JSObject* obj) {
-    delete static_cast<GjsCairoPath*>(JS_GetPrivate(obj));
-    JS_SetPrivate(obj, nullptr);
-}
-
-/* Properties */
 // clang-format off
-JSPropertySpec gjs_cairo_path_proto_props[] = {
+const JSPropertySpec CairoPath::proto_props[] = {
     JS_STRING_SYM_PS(toStringTag, "Path", JSPROP_READONLY),
     JS_PS_END};
 // clang-format on
 
-JSFunctionSpec gjs_cairo_path_proto_funcs[] = {
-    JS_FS_END
-};
-
-JSFunctionSpec gjs_cairo_path_static_funcs[] = { JS_FS_END };
-
-/**
- * gjs_cairo_path_from_path:
- * @context: the context
- * @path: cairo_path_t to attach to the object
- *
- * Constructs a pattern wrapper given cairo pattern.
- * NOTE: This function takes ownership of the path.
+/*
+ * CairoPath::take_c_ptr():
+ * Same as CWrapper::from_c_ptr(), but always takes ownership of the pointer
+ * rather than copying it. It's not possible to copy a cairo_path_t*.
  */
-JSObject *
-gjs_cairo_path_from_path(JSContext    *context,
-                         cairo_path_t *path)
-{
-    g_return_val_if_fail(context, nullptr);
-    g_return_val_if_fail(path, nullptr);
-
-    JS::RootedObject proto(context, gjs_cairo_path_get_proto(context));
-    JS::RootedObject object(context,
-        JS_NewObjectWithGivenProto(context, &gjs_cairo_path_class, proto));
-    if (!object) {
-        gjs_throw(context, "failed to create path");
+JSObject* CairoPath::take_c_ptr(JSContext* cx, cairo_path_t* ptr) {
+    JS::RootedObject proto(cx, CairoPath::prototype(cx));
+    if (!proto)
         return nullptr;
-    }
 
-    g_assert(!priv_from_js(context, object));
-    JS_SetPrivate(object, new GjsCairoPath(path));
+    JS::RootedObject wrapper(
+        cx, JS_NewObjectWithGivenProto(cx, &CairoPath::klass, proto));
+    if (!wrapper)
+        return nullptr;
 
-    return object;
-}
+    g_assert(!JS_GetPrivate(wrapper));
+    JS_SetPrivate(wrapper, ptr);
 
-/**
- * gjs_cairo_path_get_path:
- * @cx: the context
- * @path_wrapper: path wrapper
- *
- * Returns: the path attached to the wrapper.
- */
-cairo_path_t* gjs_cairo_path_get_path(JSContext* cx,
-                                      JS::HandleObject path_wrapper) {
-    g_return_val_if_fail(cx, nullptr);
-    g_return_val_if_fail(path_wrapper, nullptr);
+    debug_lifecycle(ptr, wrapper, "take_c_ptr");
 
-    GjsCairoPath* priv;
-    if (!priv_from_js_with_typecheck(cx, path_wrapper, &priv)) {
-        gjs_throw(cx, "Expected Cairo.Path but got %s",
-                  JS_GetClass(path_wrapper)->name);
-        return nullptr;
-    }
+    return wrapper;
+}
 
-    return priv->get();
+void CairoPath::finalize_impl(JSFreeOp*, cairo_path_t* path) {
+    if (!path)
+        return;
+    cairo_path_destroy(path);
 }
diff --git a/modules/cairo-private.h b/modules/cairo-private.h
index dd8e97ce..ebe32f75 100644
--- a/modules/cairo-private.h
+++ b/modules/cairo-private.h
@@ -81,17 +81,39 @@ void gjs_cairo_context_init(void);
 void gjs_cairo_surface_init(void);
 
 /* path */
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_cairo_path_define_proto(JSContext              *cx,
-                                 JS::HandleObject        module,
-                                 JS::MutableHandleObject proto);
 
-GJS_JSAPI_RETURN_CONVENTION
-JSObject *       gjs_cairo_path_from_path               (JSContext       *context,
-                                                         cairo_path_t    *path);
-GJS_JSAPI_RETURN_CONVENTION
-cairo_path_t* gjs_cairo_path_get_path(JSContext* cx,
-                                      JS::HandleObject path_wrapper);
+class CairoPath : public CWrapper<CairoPath, cairo_path_t> {
+    friend CWrapperPointerOps<CairoPath, cairo_path_t>;
+    friend CWrapper<CairoPath, cairo_path_t>;
+
+    CairoPath() = delete;
+    CairoPath(CairoPath&) = delete;
+    CairoPath(CairoPath&&) = delete;
+
+    static constexpr GjsGlobalSlot PROTOTYPE_SLOT =
+        GjsGlobalSlot::PROTOTYPE_cairo_path;
+    static constexpr GjsDebugTopic DEBUG_TOPIC = GJS_DEBUG_CAIRO;
+
+    static void finalize_impl(JSFreeOp* fop, cairo_path_t* path);
+
+    static const JSPropertySpec proto_props[];
+    static constexpr js::ClassSpec class_spec = {
+        CairoPath::create_abstract_constructor,
+        nullptr,  // createPrototype
+        nullptr,  // constructorFunctions
+        nullptr,  // constructorProperties
+        nullptr,  // prototypeFunctions
+        CairoPath::proto_props,
+        nullptr,  // finishInit
+    };
+    static constexpr JSClass klass = {
+        "Path", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        &CairoPath::class_ops, &CairoPath::class_spec};
+
+ public:
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* take_c_ptr(JSContext* cx, cairo_path_t* ptr);
+};
 
 /* surface */
 [[nodiscard]] JSObject* gjs_cairo_surface_get_proto(JSContext* cx);
diff --git a/modules/cairo.cpp b/modules/cairo.cpp
index ad994435..2cd7ae5c 100644
--- a/modules/cairo.cpp
+++ b/modules/cairo.cpp
@@ -71,7 +71,7 @@ gjs_js_define_cairo_stuff(JSContext              *context,
 
     return
         gjs_cairo_image_surface_define_proto(context, module, &proto) &&
-        gjs_cairo_path_define_proto(context, module, &proto) &&
+        CairoPath::create_prototype(context, module) &&
 #if CAIRO_HAS_PS_SURFACE
         gjs_cairo_ps_surface_define_proto(context, module, &proto) &&
 #endif


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