Skip to content

Commit 9f76aa3

Browse files
committed
Merge pull request #113282 from dsnopek/required-ptr-get-out-there
Use `RequiredParam`/`RequiredResult` in some high value places
2 parents 25203e2 + fc92ce3 commit 9f76aa3

File tree

79 files changed

+372
-321
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+372
-321
lines changed

core/input/input.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,9 @@ bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) con
415415
}
416416
}
417417

418-
bool Input::is_action_just_pressed_by_event(const StringName &p_action, const Ref<InputEvent> &p_event, bool p_exact) const {
418+
bool Input::is_action_just_pressed_by_event(const StringName &p_action, RequiredParam<InputEvent> rp_event, bool p_exact) const {
419419
ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
420-
ERR_FAIL_COND_V(p_event.is_null(), false);
420+
EXTRACT_PARAM_OR_FAIL_V(p_event, rp_event, false);
421421

422422
if (disable_input) {
423423
return false;
@@ -472,9 +472,9 @@ bool Input::is_action_just_released(const StringName &p_action, bool p_exact) co
472472
}
473473
}
474474

475-
bool Input::is_action_just_released_by_event(const StringName &p_action, const Ref<InputEvent> &p_event, bool p_exact) const {
475+
bool Input::is_action_just_released_by_event(const StringName &p_action, RequiredParam<InputEvent> rp_event, bool p_exact) const {
476476
ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
477-
ERR_FAIL_COND_V(p_event.is_null(), false);
477+
EXTRACT_PARAM_OR_FAIL_V(p_event, rp_event, false);
478478

479479
if (disable_input) {
480480
return false;
@@ -1227,10 +1227,10 @@ void Input::set_custom_mouse_cursor(const Ref<Resource> &p_cursor, CursorShape p
12271227
set_custom_mouse_cursor_func(p_cursor, p_shape, p_hotspot);
12281228
}
12291229

1230-
void Input::parse_input_event(const Ref<InputEvent> &p_event) {
1230+
void Input::parse_input_event(RequiredParam<InputEvent> rp_event) {
12311231
_THREAD_SAFE_METHOD_
12321232

1233-
ERR_FAIL_COND(p_event.is_null());
1233+
EXTRACT_PARAM_OR_FAIL(p_event, rp_event);
12341234

12351235
#ifdef DEBUG_ENABLED
12361236
uint64_t curr_frame = Engine::get_singleton()->get_process_frames();

core/input/input.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,8 @@ class Input : public Object {
321321
bool is_action_pressed(const StringName &p_action, bool p_exact = false) const;
322322
bool is_action_just_pressed(const StringName &p_action, bool p_exact = false) const;
323323
bool is_action_just_released(const StringName &p_action, bool p_exact = false) const;
324-
bool is_action_just_pressed_by_event(const StringName &p_action, const Ref<InputEvent> &p_event, bool p_exact = false) const;
325-
bool is_action_just_released_by_event(const StringName &p_action, const Ref<InputEvent> &p_event, bool p_exact = false) const;
324+
bool is_action_just_pressed_by_event(const StringName &p_action, RequiredParam<InputEvent> p_event, bool p_exact = false) const;
325+
bool is_action_just_released_by_event(const StringName &p_action, RequiredParam<InputEvent> p_event, bool p_exact = false) const;
326326
float get_action_strength(const StringName &p_action, bool p_exact = false) const;
327327
float get_action_raw_strength(const StringName &p_action, bool p_exact = false) const;
328328

@@ -350,7 +350,7 @@ class Input : public Object {
350350
void warp_mouse(const Vector2 &p_position);
351351
Point2 warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect);
352352

353-
void parse_input_event(const Ref<InputEvent> &p_event);
353+
void parse_input_event(RequiredParam<InputEvent> p_event);
354354

355355
void set_gravity(const Vector3 &p_gravity);
356356
void set_accelerometer(const Vector3 &p_accel);

core/input/input_event.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ bool InputEvent::is_echo() const {
8888
return false;
8989
}
9090

91-
Ref<InputEvent> InputEvent::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
91+
RequiredResult<InputEvent> InputEvent::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
9292
return Ref<InputEvent>(const_cast<InputEvent *>(this));
9393
}
9494

@@ -736,7 +736,7 @@ bool InputEventMouseButton::is_double_click() const {
736736
return double_click;
737737
}
738738

739-
Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
739+
RequiredResult<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
740740
Vector2 g = get_global_position();
741741
Vector2 l = p_xform.xform(get_position() + p_local_ofs);
742742

@@ -958,7 +958,7 @@ Vector2 InputEventMouseMotion::get_screen_velocity() const {
958958
return screen_velocity;
959959
}
960960

961-
Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
961+
RequiredResult<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
962962
Ref<InputEventMouseMotion> mm;
963963
mm.instantiate();
964964

@@ -1364,7 +1364,7 @@ bool InputEventScreenTouch::is_double_tap() const {
13641364
return double_tap;
13651365
}
13661366

1367-
Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
1367+
RequiredResult<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
13681368
Ref<InputEventScreenTouch> st;
13691369
st.instantiate();
13701370
st->set_device(get_device());
@@ -1487,7 +1487,7 @@ Vector2 InputEventScreenDrag::get_screen_velocity() const {
14871487
return screen_velocity;
14881488
}
14891489

1490-
Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
1490+
RequiredResult<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
14911491
Ref<InputEventScreenDrag> sd;
14921492

14931493
sd.instantiate();
@@ -1706,7 +1706,7 @@ real_t InputEventMagnifyGesture::get_factor() const {
17061706
return factor;
17071707
}
17081708

1709-
Ref<InputEvent> InputEventMagnifyGesture::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
1709+
RequiredResult<InputEvent> InputEventMagnifyGesture::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
17101710
Ref<InputEventMagnifyGesture> ev;
17111711
ev.instantiate();
17121712

@@ -1748,7 +1748,7 @@ Vector2 InputEventPanGesture::get_delta() const {
17481748
return delta;
17491749
}
17501750

1751-
Ref<InputEvent> InputEventPanGesture::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
1751+
RequiredResult<InputEvent> InputEventPanGesture::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
17521752
Ref<InputEventPanGesture> ev;
17531753
ev.instantiate();
17541754

core/input/input_event.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class InputEvent : public Resource {
8080

8181
virtual String as_text() const = 0;
8282

83-
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
83+
virtual RequiredResult<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
8484

8585
virtual bool action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const;
8686
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const;
@@ -246,7 +246,7 @@ class InputEventMouseButton : public InputEventMouse {
246246
void set_double_click(bool p_double_click);
247247
bool is_double_click() const;
248248

249-
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
249+
virtual RequiredResult<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
250250

251251
virtual bool action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const override;
252252
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override;
@@ -294,7 +294,7 @@ class InputEventMouseMotion : public InputEventMouse {
294294
void set_screen_velocity(const Vector2 &p_velocity);
295295
Vector2 get_screen_velocity() const;
296296

297-
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
297+
virtual RequiredResult<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
298298
virtual String as_text() const override;
299299
virtual String _to_string() override;
300300

@@ -384,7 +384,7 @@ class InputEventScreenTouch : public InputEventFromWindow {
384384
void set_double_tap(bool p_double_tap);
385385
bool is_double_tap() const;
386386

387-
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
387+
virtual RequiredResult<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
388388
virtual String as_text() const override;
389389
virtual String _to_string() override;
390390

@@ -434,7 +434,7 @@ class InputEventScreenDrag : public InputEventFromWindow {
434434
void set_screen_velocity(const Vector2 &p_velocity);
435435
Vector2 get_screen_velocity() const;
436436

437-
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
437+
virtual RequiredResult<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
438438
virtual String as_text() const override;
439439
virtual String _to_string() override;
440440

@@ -502,7 +502,7 @@ class InputEventMagnifyGesture : public InputEventGesture {
502502
void set_factor(real_t p_factor);
503503
real_t get_factor() const;
504504

505-
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
505+
virtual RequiredResult<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
506506
virtual String as_text() const override;
507507
virtual String _to_string() override;
508508

@@ -520,7 +520,7 @@ class InputEventPanGesture : public InputEventGesture {
520520
void set_delta(const Vector2 &p_delta);
521521
Vector2 get_delta() const;
522522

523-
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
523+
virtual RequiredResult<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
524524
virtual String as_text() const override;
525525
virtual String _to_string() override;
526526

core/input/input_map.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone)
196196
input_map[p_action].deadzone = p_deadzone;
197197
}
198198

199-
void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
200-
ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object.");
199+
void InputMap::action_add_event(const StringName &p_action, RequiredParam<InputEvent> rp_event) {
200+
EXTRACT_PARAM_OR_FAIL_MSG(p_event, rp_event, "It's not a reference to a valid InputEvent object.");
201201
ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action));
202202
if (_find_event(input_map[p_action], p_event, true)) {
203203
return; // Already added.
@@ -206,12 +206,14 @@ void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent
206206
input_map[p_action].inputs.push_back(p_event);
207207
}
208208

209-
bool InputMap::action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
209+
bool InputMap::action_has_event(const StringName &p_action, RequiredParam<InputEvent> rp_event) {
210+
EXTRACT_PARAM_OR_FAIL_V(p_event, rp_event, false);
210211
ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, suggest_actions(p_action));
211212
return (_find_event(input_map[p_action], p_event, true) != nullptr);
212213
}
213214

214-
void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
215+
void InputMap::action_erase_event(const StringName &p_action, RequiredParam<InputEvent> rp_event) {
216+
EXTRACT_PARAM_OR_FAIL(p_event, rp_event);
215217
ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action));
216218

217219
List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event, true);
@@ -251,7 +253,8 @@ const List<Ref<InputEvent>> *InputMap::action_get_events(const StringName &p_act
251253
return &E->value.inputs;
252254
}
253255

254-
bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match) const {
256+
bool InputMap::event_is_action(RequiredParam<InputEvent> rp_event, const StringName &p_action, bool p_exact_match) const {
257+
EXTRACT_PARAM_OR_FAIL_V(p_event, rp_event, false);
255258
return event_get_action_status(p_event, p_action, p_exact_match);
256259
}
257260

core/input/input_map.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,13 @@ class InputMap : public Object {
8787

8888
float action_get_deadzone(const StringName &p_action);
8989
void action_set_deadzone(const StringName &p_action, float p_deadzone);
90-
void action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event);
91-
bool action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event);
92-
void action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event);
90+
void action_add_event(const StringName &p_action, RequiredParam<InputEvent> p_event);
91+
bool action_has_event(const StringName &p_action, RequiredParam<InputEvent> p_event);
92+
void action_erase_event(const StringName &p_action, RequiredParam<InputEvent> p_event);
9393
void action_erase_events(const StringName &p_action);
9494

9595
const List<Ref<InputEvent>> *action_get_events(const StringName &p_action);
96-
bool event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false) const;
96+
bool event_is_action(RequiredParam<InputEvent> p_event, const StringName &p_action, bool p_exact_match = false) const;
9797
int event_get_index(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false) const;
9898
bool event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false, bool *r_pressed = nullptr, float *r_strength = nullptr, float *r_raw_strength = nullptr, int *r_event_index = nullptr) const;
9999

core/object/make_virtuals.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,9 @@ def generate_version(argcount, const=False, returns=False, required=False, compa
147147
callptrargsptr += ", "
148148
argtext += f"m_type{i + 1}"
149149
callargtext += f"m_type{i + 1} arg{i + 1}"
150-
callsiargs += f"arg{i + 1}"
150+
callsiargs += f"VariantInternal::make(arg{i + 1})"
151151
callsiargptrs += f"&vargs[{i}]"
152-
callptrargs += (
153-
f"PtrToArg<m_type{i + 1}>::EncodeT argval{i + 1} = (PtrToArg<m_type{i + 1}>::EncodeT)arg{i + 1};\\\n"
154-
)
152+
callptrargs += f"PtrToArg<m_type{i + 1}>::EncodeT argval{i + 1}; PtrToArg<m_type{i + 1}>::encode(arg{i + 1}, &argval{i + 1});\\\n"
155153
callptrargsptr += f"&argval{i + 1}"
156154

157155
if argcount:

core/variant/binder_common.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -670,9 +670,9 @@ void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), co
670670
r_error.error = Callable::CallError::CALL_OK;
671671

672672
#ifdef DEBUG_ENABLED
673-
r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
673+
r_ret = VariantInternal::make((p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...));
674674
#else
675-
r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
675+
r_ret = VariantInternal::make((p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...));
676676
#endif
677677
}
678678

@@ -681,9 +681,9 @@ void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_ar
681681
r_error.error = Callable::CallError::CALL_OK;
682682

683683
#ifdef DEBUG_ENABLED
684-
r_ret = (p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
684+
r_ret = VariantInternal::make((p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...));
685685
#else
686-
r_ret = (p_method)(VariantCaster<P>::cast(*p_args[Is])...);
686+
r_ret = VariantInternal::make((p_method)(VariantCaster<P>::cast(*p_args[Is])...));
687687
#endif // DEBUG_ENABLED
688688
}
689689

@@ -721,9 +721,9 @@ void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) co
721721
r_error.error = Callable::CallError::CALL_OK;
722722

723723
#ifdef DEBUG_ENABLED
724-
r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
724+
r_ret = VariantInternal::make((p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...));
725725
#else
726-
r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
726+
r_ret = VariantInternal::make((p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...));
727727
#endif // DEBUG_ENABLED
728728
(void)p_args;
729729
}
@@ -787,9 +787,9 @@ void call_with_variant_args_retc_static_helper(T *p_instance, R (*p_method)(T *,
787787
r_error.error = Callable::CallError::CALL_OK;
788788

789789
#ifdef DEBUG_ENABLED
790-
r_ret = (p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
790+
r_ret = VariantInternal::make((p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...));
791791
#else
792-
r_ret = (p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...);
792+
r_ret = VariantInternal::make((p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...));
793793
#endif // DEBUG_ENABLED
794794

795795
(void)p_args;

core/variant/method_ptrcall.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,8 @@ struct PtrToArg<T *> {
253253
return likely(p_ptr) ? *reinterpret_cast<T *const *>(p_ptr) : nullptr;
254254
}
255255
typedef Object *EncodeT;
256-
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
257-
*((T **)p_ptr) = p_var;
256+
_FORCE_INLINE_ static void encode(const T *p_var, void *p_ptr) {
257+
*((T **)p_ptr) = const_cast<T *>(p_var);
258258
}
259259
};
260260

@@ -264,8 +264,8 @@ struct PtrToArg<const T *> {
264264
return likely(p_ptr) ? *reinterpret_cast<T *const *>(p_ptr) : nullptr;
265265
}
266266
typedef const Object *EncodeT;
267-
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
268-
*((T **)p_ptr) = p_var;
267+
_FORCE_INLINE_ static void encode(const T *p_var, void *p_ptr) {
268+
*((T **)p_ptr) = const_cast<T *>(p_var);
269269
}
270270
};
271271

core/variant/required_ptr.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232

3333
#include "core/variant/variant.h"
3434

35+
// Using `RequiredResult<T>` as the return type indicates that null will only be returned in the case of an error.
36+
// This allows GDExtension language bindings to use the appropriate error handling mechanism for that language
37+
// when null is returned (for example, throwing an exception), rather than simply returning the value.
3538
template <typename T>
3639
class RequiredResult {
3740
static_assert(!is_fully_defined_v<T> || std::is_base_of_v<Object, T>, "T must be an Object subtype");
@@ -43,9 +46,9 @@ class RequiredResult {
4346
private:
4447
ptr_type _value = ptr_type();
4548

49+
public:
4650
_FORCE_INLINE_ RequiredResult() = default;
4751

48-
public:
4952
RequiredResult(const RequiredResult &p_other) = default;
5053
RequiredResult(RequiredResult &&p_other) = default;
5154
RequiredResult &operator=(const RequiredResult &p_other) = default;
@@ -123,12 +126,13 @@ class RequiredResult {
123126
return _value;
124127
}
125128

126-
_FORCE_INLINE_ operator ptr_type() {
129+
_FORCE_INLINE_ operator ptr_type() const {
127130
return _value;
128131
}
129132

130-
_FORCE_INLINE_ operator Variant() const {
131-
return Variant(_value);
133+
template <typename T_Other, std::enable_if_t<std::is_base_of_v<RefCounted, T> && std::is_base_of_v<T, T_Other>, int> = 0>
134+
_FORCE_INLINE_ operator Ref<T_Other>() const {
135+
return Ref<T_Other>(_value);
132136
}
133137

134138
_FORCE_INLINE_ element_type *operator*() const {
@@ -140,6 +144,10 @@ class RequiredResult {
140144
}
141145
};
142146

147+
// Using `RequiredParam<T>` as an argument type indicates that passing null as that parameter is an error,
148+
// that will prevent the method from doing its intended function.
149+
// This allows GDExtension bindings to use language-specific mechanisms to prevent users from passing null,
150+
// because it is never valid to do so.
143151
template <typename T>
144152
class RequiredParam {
145153
static_assert(!is_fully_defined_v<T> || std::is_base_of_v<Object, T>, "T must be an Object subtype");

0 commit comments

Comments
 (0)