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 : :
20 : : #include "gi/cwrapper.h"
21 : : #include "gi/wrapperutils.h"
22 : : #include "gjs/jsapi-util.h"
23 : : #include "gjs/macros.h"
24 : : #include "util/log.h"
25 : :
26 : : class InterfacePrototype;
27 : : class InterfaceInstance;
28 : :
29 : : /* For more information on this Base/Prototype/Interface scheme, see the notes
30 : : * in wrapperutils.h.
31 : : *
32 : : * What's unusual about this subclass is that InterfaceInstance should never
33 : : * actually be instantiated. Interfaces can't be constructed, and
34 : : * GIWrapperBase::constructor() is overridden to just throw an exception and not
35 : : * create any JS wrapper object.
36 : : *
37 : : * We use the template classes from wrapperutils.h anyway, because there is
38 : : * still a lot of common code.
39 : : */
40 : :
41 : : class InterfaceBase : public GIWrapperBase<InterfaceBase, InterfacePrototype,
42 : : InterfaceInstance> {
43 : : friend class CWrapperPointerOps<InterfaceBase>;
44 : : friend class GIWrapperBase<InterfaceBase, InterfacePrototype,
45 : : InterfaceInstance>;
46 : :
47 : : protected:
48 : 158 : explicit InterfaceBase(InterfacePrototype* proto = nullptr)
49 : 158 : : GIWrapperBase(proto) {}
50 : :
51 : : static constexpr GjsDebugTopic DEBUG_TOPIC = GJS_DEBUG_GINTERFACE;
52 : : static constexpr const char* DEBUG_TAG = "interface";
53 : :
54 : : static const struct JSClassOps class_ops;
55 : : static const struct JSClass klass;
56 : : static JSFunctionSpec static_methods[];
57 : :
58 : : // JSNative methods
59 : :
60 : : // Overrides GIWrapperBase::constructor().
61 : : GJS_JSAPI_RETURN_CONVENTION
62 : 1 : static bool constructor(JSContext* cx, unsigned argc, JS::Value* vp) {
63 : 1 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
64 : 1 : gjs_throw_abstract_constructor_error(cx, args);
65 : 1 : return false;
66 : : }
67 : :
68 : : GJS_JSAPI_RETURN_CONVENTION
69 : : static bool has_instance(JSContext* cx, unsigned argc, JS::Value* vp);
70 : : };
71 : :
72 : : class InterfacePrototype
73 : : : public GIWrapperPrototype<InterfaceBase, InterfacePrototype,
74 : : InterfaceInstance, GIInterfaceInfo> {
75 : : friend class GIWrapperPrototype<InterfaceBase, InterfacePrototype,
76 : : InterfaceInstance, GIInterfaceInfo>;
77 : : friend class GIWrapperBase<InterfaceBase, InterfacePrototype,
78 : : InterfaceInstance>;
79 : : friend class InterfaceBase; // for has_instance_impl
80 : :
81 : : // the GTypeInterface vtable wrapped by this JS object
82 : : GTypeInterface* m_vtable;
83 : :
84 : : static constexpr InfoType::Tag info_type_tag = InfoType::Interface;
85 : :
86 : : explicit InterfacePrototype(GIInterfaceInfo* info, GType gtype);
87 : : ~InterfacePrototype(void);
88 : :
89 : : // JSClass operations
90 : :
91 : : GJS_JSAPI_RETURN_CONVENTION
92 : : bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
93 : : bool* resolved);
94 : :
95 : : GJS_JSAPI_RETURN_CONVENTION
96 : : bool new_enumerate_impl(JSContext* cx, JS::HandleObject obj,
97 : : JS::MutableHandleIdVector properties,
98 : : bool only_enumerable);
99 : :
100 : : // JS methods
101 : :
102 : : GJS_JSAPI_RETURN_CONVENTION
103 : : bool has_instance_impl(JSContext* cx, const JS::CallArgs& args);
104 : : };
105 : :
106 : : class InterfaceInstance
107 : : : public GIWrapperInstance<InterfaceBase, InterfacePrototype,
108 : : InterfaceInstance> {
109 : : friend class GIWrapperInstance<InterfaceBase, InterfacePrototype,
110 : : InterfaceInstance>;
111 : : friend class GIWrapperBase<InterfaceBase, InterfacePrototype,
112 : : InterfaceInstance>;
113 : :
114 : : [[noreturn]] InterfaceInstance(InterfacePrototype* prototype,
115 : : JS::HandleObject obj)
116 : : : GIWrapperInstance(prototype, obj) {
117 : : g_assert_not_reached();
118 : : }
119 : : [[noreturn]] ~InterfaceInstance(void) { g_assert_not_reached(); }
120 : : };
121 : :
122 : : GJS_JSAPI_RETURN_CONVENTION
123 : : bool gjs_lookup_interface_constructor(JSContext *context,
124 : : GType gtype,
125 : : JS::MutableHandleValue value_p);
126 : :
127 : : #endif // GI_INTERFACE_H_
|