@@ -46,35 +46,60 @@ class JNISingleton : public Object {
4646 RBMap<StringName, MethodData> method_map;
4747 Ref<JavaObject> wrapped_object;
4848
49+ protected:
50+ static void _bind_methods () {
51+ ClassDB::bind_method (D_METHOD (" has_java_method" , " method" ), &JNISingleton::has_java_method);
52+ }
53+
4954public:
5055 virtual Variant callp (const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override {
51- if (wrapped_object.is_valid ()) {
52- RBMap<StringName, MethodData>::Element *E = method_map.find (p_method);
53-
54- // Check the method we're looking for is in the JNISingleton map and that
55- // the arguments match.
56- bool call_error = !E || E->get ().argtypes .size () != p_argcount;
57- if (!call_error) {
58- for (int i = 0 ; i < p_argcount; i++) {
59- if (!Variant::can_convert (p_args[i]->get_type (), E->get ().argtypes [i])) {
60- call_error = true ;
61- break ;
56+ // Godot methods take precedence.
57+ Variant ret = Object::callp (p_method, p_args, p_argcount, r_error);
58+ if (r_error.error == Callable::CallError::CALL_OK) {
59+ return ret;
60+ }
61+
62+ // Check the method we're looking for is in the JNISingleton map.
63+ RBMap<StringName, MethodData>::Element *E = method_map.find (p_method);
64+ if (E) {
65+ if (wrapped_object.is_valid ()) {
66+ // Check that the arguments match.
67+ int method_arg_count = E->get ().argtypes .size ();
68+ if (p_argcount < method_arg_count) {
69+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
70+ } else if (p_argcount > method_arg_count) {
71+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
72+ } else {
73+ // Check the arguments are valid.
74+ bool arguments_valid = true ;
75+ for (int i = 0 ; i < p_argcount; i++) {
76+ if (!Variant::can_convert (p_args[i]->get_type (), E->get ().argtypes [i])) {
77+ arguments_valid = false ;
78+ break ;
79+ }
6280 }
63- }
64- }
6581
66- if (!call_error) {
67- return wrapped_object->callp (p_method, p_args, p_argcount, r_error);
82+ if (arguments_valid) {
83+ return wrapped_object->callp (p_method, p_args, p_argcount, r_error);
84+ } else {
85+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
86+ }
87+ }
88+ } else {
89+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
6890 }
6991 }
70-
71- return Object::callp (p_method, p_args, p_argcount, r_error);
92+ return Variant ();
7293 }
7394
7495 Ref<JavaObject> get_wrapped_object () const {
7596 return wrapped_object;
7697 }
7798
99+ bool has_java_method (const StringName &p_method) const {
100+ return method_map.has (p_method);
101+ }
102+
78103 void add_method (const StringName &p_name, const Vector<Variant::Type> &p_args, Variant::Type p_ret_type) {
79104 MethodData md;
80105 md.argtypes = p_args;
0 commit comments