summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorPhilip Chimento <philip.chimento@gmail.com>2020-05-05 22:30:12 -0700
committerPhilip Chimento <philip.chimento@gmail.com>2021-01-30 13:56:30 -0800
commite15f239b9ff528bb473b83a7e57313236d4a76b7 (patch)
treefac70849e1413eb48fe23c2f4fa4be943e1ff3de /modules
parentbfea3ebd317c30d3f3ef31be937cbd417723bb1a (diff)
downloadgjs-e15f239b9ff528bb473b83a7e57313236d4a76b7.tar.gz
cairo: Remove JSClass macros from Cairo context
Remove the usage of the GJS_DEFINE_PRIV_FROM_JS and GJS_DEFINE_PROTO families of macros from the Cairo context wrapper type. Use CWrapper instead, for more type safety and less boilerplate. Also requires adding a debug topic for Cairo.
Diffstat (limited to 'modules')
-rw-r--r--modules/cairo-context.cpp98
-rw-r--r--modules/cairo-private.h62
-rw-r--r--modules/cairo.cpp2
3 files changed, 76 insertions, 86 deletions
diff --git a/modules/cairo-context.cpp b/modules/cairo-context.cpp
index 3654cae4..b1693239 100644
--- a/modules/cairo-context.cpp
+++ b/modules/cairo-context.cpp
@@ -6,14 +6,12 @@
#include <vector>
-#include <cairo-gobject.h>
#include <cairo.h>
#include <girepository.h>
#include <glib.h>
#include <js/Array.h> // for JS::NewArrayObject
#include <js/CallArgs.h>
-#include <js/Class.h>
#include <js/Conversions.h>
#include <js/PropertyDescriptor.h> // for JSPROP_READONLY
#include <js/PropertySpec.h>
@@ -28,17 +26,16 @@
#include "gi/arg.h"
#include "gi/foreign.h"
#include "gjs/enum-utils.h"
-#include "gjs/jsapi-class.h"
#include "gjs/jsapi-util-args.h"
#include "gjs/jsapi-util.h"
#include "gjs/macros.h"
#include "modules/cairo-private.h"
-struct GjsCairoContext;
-
#define _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(cx, argc, vp, argv, obj) \
- GJS_GET_PRIV(context, argc, vp, argv, obj, GjsCairoContext, priv); \
- cairo_t* cr = priv->get(); \
+ GJS_GET_THIS(cx, argc, vp, argv, obj); \
+ cairo_t* cr; \
+ if (!CairoContext::for_js_typecheck(cx, obj, &cr, &argv)) \
+ return false; \
if (!cr) \
return true;
@@ -248,64 +245,38 @@ _GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(method) \
argv.rval().setUndefined(); \
_GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
-[[nodiscard]] static JSObject* gjs_cairo_context_get_proto(JSContext*);
-
-struct GjsCairoContext
- : GjsAutoPointer<cairo_t, cairo_t, cairo_destroy, cairo_reference> {
- explicit GjsCairoContext(cairo_t* cr)
- : GjsAutoPointer(cr, GjsAutoTakeOwnership()) {}
-};
-
-GJS_DEFINE_PROTO_WITH_GTYPE("Context", cairo_context,
- CAIRO_GOBJECT_TYPE_CONTEXT,
- JSCLASS_BACKGROUND_FINALIZE)
-GJS_DEFINE_PRIV_FROM_JS(GjsCairoContext, gjs_cairo_context_class);
-
-static void _gjs_cairo_context_construct_internal(JSContext* context,
- JS::HandleObject obj,
- cairo_t* cr) {
- g_assert(!priv_from_js(context, obj));
- JS_SetPrivate(obj, new GjsCairoContext(cr));
-}
-
-GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_context)
-{
- GJS_NATIVE_CONSTRUCTOR_VARIABLES(cairo_context)
+GJS_JSAPI_RETURN_CONVENTION
+cairo_t* CairoContext::constructor_impl(JSContext* context,
+ const JS::CallArgs& argv) {
cairo_t *cr;
- GJS_NATIVE_CONSTRUCTOR_PRELUDE(cairo_context);
-
JS::RootedObject surface_wrapper(context);
if (!gjs_parse_call_args(context, "Context", argv, "o",
"surface", &surface_wrapper))
- return false;
+ return nullptr;
cairo_surface_t* surface =
gjs_cairo_surface_get_surface(context, surface_wrapper);
if (!surface)
- return false;
+ return nullptr;
cr = cairo_create(surface);
if (!gjs_cairo_check_status(context, cairo_status(cr), "context"))
- return false;
-
- _gjs_cairo_context_construct_internal(context, object, cr);
- cairo_destroy(cr);
-
- GJS_NATIVE_CONSTRUCTOR_FINISH(cairo_context);
+ return nullptr;
- return true;
+ return cr;
}
-static void gjs_cairo_context_finalize(JSFreeOp*, JSObject* obj) {
- delete static_cast<GjsCairoContext*>(JS_GetPrivate(obj));
- JS_SetPrivate(obj, nullptr);
+void CairoContext::finalize_impl(JSFreeOp*, cairo_t* cr) {
+ if (!cr)
+ return;
+ cairo_destroy(cr);
}
/* Properties */
// clang-format off
-JSPropertySpec gjs_cairo_context_proto_props[] = {
+const JSPropertySpec CairoContext::proto_props[] = {
JS_STRING_SYM_PS(toStringTag, "Context", JSPROP_READONLY),
JS_PS_END};
// clang-format on
@@ -820,7 +791,8 @@ getGroupTarget_func(JSContext *context,
return true;
}
-JSFunctionSpec gjs_cairo_context_proto_funcs[] = {
+// clang-format off
+const JSFunctionSpec CairoContext::proto_funcs[] = {
JS_FN("$dispose", dispose_func, 0, 0),
JS_FN("appendPath", appendPath_func, 0, 0),
JS_FN("arc", arc_func, 0, 0),
@@ -920,31 +892,7 @@ JSFunctionSpec gjs_cairo_context_proto_funcs[] = {
JS_FN("userToDevice", userToDevice_func, 0, 0),
JS_FN("userToDeviceDistance", userToDeviceDistance_func, 0, 0),
JS_FS_END};
-
-JSFunctionSpec gjs_cairo_context_static_funcs[] = { JS_FS_END };
-
-JSObject *
-gjs_cairo_context_from_context(JSContext *context,
- cairo_t *cr)
-{
- JS::RootedObject proto(context, gjs_cairo_context_get_proto(context));
- JS::RootedObject object(context,
- JS_NewObjectWithGivenProto(context, &gjs_cairo_context_class, proto));
- if (!object)
- return nullptr;
-
- _gjs_cairo_context_construct_internal(context, object, cr);
-
- return object;
-}
-
-cairo_t *
-gjs_cairo_context_get_context(JSContext *context,
- JS::HandleObject object)
-{
- auto* priv = priv_from_js(context, object);
- return priv ? priv->get() : nullptr;
-}
+// clang-format on
[[nodiscard]] static bool context_to_g_argument(
JSContext* context, JS::Value value, const char* arg_name,
@@ -963,9 +911,7 @@ gjs_cairo_context_get_context(JSContext *context,
}
JS::RootedObject obj(context, &value.toObject());
- cairo_t *cr;
-
- cr = gjs_cairo_context_get_context(context, obj);
+ cairo_t* cr = CairoContext::for_js(context, obj);
if (!cr)
return false;
if (transfer == GI_TRANSFER_EVERYTHING)
@@ -981,8 +927,8 @@ context_from_g_argument(JSContext *context,
JS::MutableHandleValue value_p,
GIArgument *arg)
{
- JSObject* obj =
- gjs_cairo_context_from_context(context, gjs_arg_get<cairo_t*>(arg));
+ JSObject* obj = CairoContext::from_c_ptr(
+ context, static_cast<cairo_t*>(arg->v_pointer));
if (!obj) {
gjs_throw(context, "Could not create Cairo context");
return false;
diff --git a/modules/cairo-private.h b/modules/cairo-private.h
index f3f1aec3..601632b1 100644
--- a/modules/cairo-private.h
+++ b/modules/cairo-private.h
@@ -1,6 +1,7 @@
/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2010 litl, LLC.
+// SPDX-FileCopyrightText: 2020 Philip Chimento <philip.chimento@gmail.com>
#ifndef MODULES_CAIRO_PRIVATE_H_
#define MODULES_CAIRO_PRIVATE_H_
@@ -8,11 +9,26 @@
#include <config.h>
#include <cairo-features.h> // for CAIRO_HAS_PDF_SURFACE, CAIRO_HAS_PS_SURFACE
+#include <cairo-gobject.h>
#include <cairo.h>
+#include <glib-object.h>
+#include <js/PropertySpec.h>
#include <js/TypeDecls.h>
+#include "gi/cwrapper.h"
+#include "gi/wrapperutils.h"
+#include "gjs/global.h"
#include "gjs/macros.h"
+#include "util/log.h"
+
+namespace JS {
+class CallArgs;
+}
+namespace js {
+struct ClassSpec;
+}
+struct JSClass;
GJS_JSAPI_RETURN_CONVENTION
bool gjs_cairo_check_status (JSContext *context,
@@ -26,16 +42,44 @@ bool gjs_cairo_region_define_proto(JSContext *cx,
void gjs_cairo_region_init(void);
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_cairo_context_define_proto(JSContext *cx,
- JS::HandleObject module,
- JS::MutableHandleObject proto);
+class CairoContext : public CWrapper<CairoContext, cairo_t> {
+ friend CWrapperPointerOps<CairoContext, cairo_t>;
+ friend CWrapper<CairoContext, cairo_t>;
+
+ CairoContext() = delete;
+ CairoContext(CairoContext&) = delete;
+ CairoContext(CairoContext&&) = delete;
+
+ static constexpr GjsGlobalSlot PROTOTYPE_SLOT =
+ GjsGlobalSlot::PROTOTYPE_cairo_context;
+ static constexpr GjsDebugTopic DEBUG_TOPIC = GJS_DEBUG_CAIRO;
+ static constexpr unsigned constructor_nargs = 1;
+
+ static GType gtype() { return CAIRO_GOBJECT_TYPE_CONTEXT; }
+
+ static cairo_t* copy_ptr(cairo_t* cr) { return cairo_reference(cr); }
+
+ GJS_JSAPI_RETURN_CONVENTION
+ static cairo_t* constructor_impl(JSContext* cx, const JS::CallArgs& args);
+
+ static void finalize_impl(JSFreeOp* fop, cairo_t* cr);
+
+ static const JSFunctionSpec proto_funcs[];
+ static const JSPropertySpec proto_props[];
+ static constexpr js::ClassSpec class_spec = {
+ nullptr, // createConstructor
+ nullptr, // createPrototype
+ nullptr, // constructorFunctions
+ nullptr, // constructorProperties
+ CairoContext::proto_funcs,
+ CairoContext::proto_props,
+ CairoContext::define_gtype_prop,
+ };
+ static constexpr JSClass klass = {
+ "Context", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+ &CairoContext::class_ops, &CairoContext::class_spec};
+};
-[[nodiscard]] cairo_t* gjs_cairo_context_get_context(JSContext* cx,
- JS::HandleObject object);
-GJS_JSAPI_RETURN_CONVENTION
-JSObject * gjs_cairo_context_from_context (JSContext *context,
- cairo_t *cr);
void gjs_cairo_context_init(void);
void gjs_cairo_surface_init(void);
diff --git a/modules/cairo.cpp b/modules/cairo.cpp
index 172de91c..c2d3e764 100644
--- a/modules/cairo.cpp
+++ b/modules/cairo.cpp
@@ -61,7 +61,7 @@ gjs_js_define_cairo_stuff(JSContext *context,
return false;
gjs_cairo_region_init();
- if (!gjs_cairo_context_define_proto(context, module, &proto))
+ if (!CairoContext::create_prototype(context, module))
return false;
gjs_cairo_context_init();