Branch data Line data Source code
1 : : /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 : : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
3 : : // SPDX-FileCopyrightText: 2008 litl, LLC
4 : : // SPDX-FileCopyrightText: 2012 Red Hat, Inc.
5 : :
6 : : #ifndef GI_INTERFACE_H_
7 : : #define GI_INTERFACE_H_
8 : :
9 : : #include <config.h>
10 : :
11 : : #include <girepository.h>
12 : : #include <glib-object.h>
13 : : #include <glib.h>
14 : :
15 : : #include <js/CallArgs.h>
16 : : #include <js/PropertySpec.h>
17 : : #include <js/RootingAPI.h>
18 : : #include <js/TypeDecls.h>
19 : : #include <mozilla/Maybe.h>
20 : :
21 : : #include "gi/cwrapper.h"
22 : : #include "gi/info.h"
23 : : #include "gi/wrapperutils.h"
24 : : #include "gjs/jsapi-util.h"
25 : : #include "gjs/macros.h"
26 : : #include "util/log.h"
27 : :
28 : : class InterfacePrototype;
29 : : class InterfaceInstance;
30 : :
31 : : /* For more information on this Base/Prototype/Interface scheme, see the notes
32 : : * in wrapperutils.h.
33 : : *
34 : : * What's unusual about this subclass is that InterfaceInstance should never
35 : : * actually be instantiated. Interfaces can't be constructed, and
36 : : * GIWrapperBase::constructor() is overridden to just throw an exception and not
37 : : * create any JS wrapper object.
38 : : *
39 : : * We use the template classes from wrapperutils.h anyway, because there is
40 : : * still a lot of common code.
41 : : */
42 : :
43 : : class InterfaceBase : public GIWrapperBase<InterfaceBase, InterfacePrototype,
44 : : InterfaceInstance> {
45 : : friend class CWrapperPointerOps<InterfaceBase>;
46 : : friend class GIWrapperBase<InterfaceBase, InterfacePrototype,
47 : : InterfaceInstance>;
48 : :
49 : : protected:
50 : 222 : explicit InterfaceBase(InterfacePrototype* proto = nullptr)
51 : 222 : : GIWrapperBase(proto) {}
52 : :
53 : : static constexpr GjsDebugTopic DEBUG_TOPIC = GJS_DEBUG_GINTERFACE;
54 : : static constexpr const char* DEBUG_TAG = "interface";
55 : :
56 : : static const struct JSClassOps class_ops;
57 : : static const struct JSClass klass;
58 : : static JSFunctionSpec static_methods[];
59 : :
60 : : // JSNative methods
61 : :
62 : : // Overrides GIWrapperBase::constructor().
63 : : GJS_JSAPI_RETURN_CONVENTION
64 : 1 : static bool constructor(JSContext* cx, unsigned argc, JS::Value* vp) {
65 : 1 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
66 : 1 : gjs_throw_abstract_constructor_error(cx, args);
67 : 1 : return false;
68 : : }
69 : :
70 : : GJS_JSAPI_RETURN_CONVENTION
71 : : static bool has_instance(JSContext* cx, unsigned argc, JS::Value* vp);
72 : : };
73 : :
74 : : class InterfacePrototype
75 : : : public GIWrapperPrototype<InterfaceBase, InterfacePrototype,
76 : : InterfaceInstance,
77 : : mozilla::Maybe<GI::AutoInterfaceInfo>,
78 : : mozilla::Maybe<GI::InterfaceInfo>> {
79 : : friend class GIWrapperPrototype<InterfaceBase, InterfacePrototype,
80 : : InterfaceInstance,
81 : : mozilla::Maybe<GI::AutoInterfaceInfo>,
82 : : mozilla::Maybe<GI::InterfaceInfo>>;
83 : : friend class GIWrapperBase<InterfaceBase, InterfacePrototype,
84 : : InterfaceInstance>;
85 : : friend class InterfaceBase; // for has_instance_impl
86 : :
87 : : // the GTypeInterface vtable wrapped by this JS object
88 : : GTypeInterface* m_vtable;
89 : :
90 : : explicit InterfacePrototype(mozilla::Maybe<const GI::InterfaceInfo>, GType);
91 : : ~InterfacePrototype(void);
92 : :
93 : : // JSClass operations
94 : :
95 : : GJS_JSAPI_RETURN_CONVENTION
96 : : bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
97 : : bool* resolved);
98 : :
99 : : GJS_JSAPI_RETURN_CONVENTION
100 : : bool new_enumerate_impl(JSContext* cx, JS::HandleObject obj,
101 : : JS::MutableHandleIdVector properties,
102 : : bool only_enumerable);
103 : :
104 : : // JS methods
105 : :
106 : : GJS_JSAPI_RETURN_CONVENTION
107 : : bool has_instance_impl(JSContext* cx, const JS::CallArgs& args);
108 : : };
109 : :
110 : : class InterfaceInstance
111 : : : public GIWrapperInstance<InterfaceBase, InterfacePrototype,
112 : : InterfaceInstance> {
113 : : friend class GIWrapperInstance<InterfaceBase, InterfacePrototype,
114 : : InterfaceInstance>;
115 : : friend class GIWrapperBase<InterfaceBase, InterfacePrototype,
116 : : InterfaceInstance>;
117 : :
118 : : [[noreturn]] InterfaceInstance(InterfacePrototype* prototype,
119 : : JS::HandleObject obj)
120 : : : GIWrapperInstance(prototype, obj) {
121 : : g_assert_not_reached();
122 : : }
123 : : [[noreturn]] ~InterfaceInstance(void) { g_assert_not_reached(); }
124 : : };
125 : :
126 : : GJS_JSAPI_RETURN_CONVENTION
127 : : bool gjs_lookup_interface_constructor(JSContext *context,
128 : : GType gtype,
129 : : JS::MutableHandleValue value_p);
130 : :
131 : : #endif // GI_INTERFACE_H_
|