Path: blob/master/platform/android/api/java_class_wrapper.h
20801 views
/**************************************************************************/1/* java_class_wrapper.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "core/object/ref_counted.h"33#include "core/variant/typed_array.h"3435#ifdef ANDROID_ENABLED36#include "core/templates/rb_map.h"3738#include <android/log.h>39#include <jni.h>40#endif4142#ifdef ANDROID_ENABLED43class JavaObject;44#endif4546class JavaClass : public RefCounted {47GDCLASS(JavaClass, RefCounted);4849#ifdef ANDROID_ENABLED50enum ArgumentType {51ARG_TYPE_VOID,52ARG_TYPE_BOOLEAN,53ARG_TYPE_BYTE,54ARG_TYPE_CHAR,55ARG_TYPE_SHORT,56ARG_TYPE_INT,57ARG_TYPE_LONG,58ARG_TYPE_FLOAT,59ARG_TYPE_DOUBLE,60ARG_TYPE_STRING, //special case61ARG_TYPE_CHARSEQUENCE,62ARG_TYPE_CALLABLE,63ARG_TYPE_CLASS,64ARG_ARRAY_BIT = 1 << 16,65ARG_NUMBER_CLASS_BIT = 1 << 17,66ARG_TYPE_MASK = (1 << 16) - 167};6869RBMap<StringName, Variant> constant_map;7071struct MethodInfo {72bool _public = false;73bool _static = false;74bool _constructor = false;75Vector<uint32_t> param_types;76Vector<StringName> param_sigs;77uint32_t return_type = 0;78jmethodID method;79};8081_FORCE_INLINE_ static void _convert_to_variant_type(int p_sig, Variant::Type &r_type, float &likelihood) {82likelihood = 1.0;83r_type = Variant::NIL;8485switch (p_sig) {86case ARG_TYPE_VOID:87r_type = Variant::NIL;88break;89case ARG_TYPE_BOOLEAN | ARG_NUMBER_CLASS_BIT:90case ARG_TYPE_BOOLEAN:91r_type = Variant::BOOL;92break;93case ARG_TYPE_BYTE | ARG_NUMBER_CLASS_BIT:94case ARG_TYPE_BYTE:95r_type = Variant::INT;96likelihood = 0.1;97break;98case ARG_TYPE_CHAR | ARG_NUMBER_CLASS_BIT:99case ARG_TYPE_CHAR:100r_type = Variant::INT;101likelihood = 0.2;102break;103case ARG_TYPE_SHORT | ARG_NUMBER_CLASS_BIT:104case ARG_TYPE_SHORT:105r_type = Variant::INT;106likelihood = 0.3;107break;108case ARG_TYPE_INT | ARG_NUMBER_CLASS_BIT:109case ARG_TYPE_INT:110r_type = Variant::INT;111likelihood = 1.0;112break;113case ARG_TYPE_LONG | ARG_NUMBER_CLASS_BIT:114case ARG_TYPE_LONG:115r_type = Variant::INT;116likelihood = 0.5;117break;118case ARG_TYPE_FLOAT | ARG_NUMBER_CLASS_BIT:119case ARG_TYPE_FLOAT:120r_type = Variant::FLOAT;121likelihood = 1.0;122break;123case ARG_TYPE_DOUBLE | ARG_NUMBER_CLASS_BIT:124case ARG_TYPE_DOUBLE:125r_type = Variant::FLOAT;126likelihood = 0.5;127break;128case ARG_TYPE_STRING:129case ARG_TYPE_CHARSEQUENCE:130r_type = Variant::STRING;131break;132case ARG_TYPE_CALLABLE:133r_type = Variant::CALLABLE;134break;135case ARG_TYPE_CLASS:136r_type = Variant::OBJECT;137break;138case ARG_ARRAY_BIT | ARG_TYPE_VOID:139r_type = Variant::NIL;140break;141case ARG_ARRAY_BIT | ARG_TYPE_BOOLEAN:142r_type = Variant::ARRAY;143break;144case ARG_ARRAY_BIT | ARG_TYPE_BYTE:145r_type = Variant::PACKED_BYTE_ARRAY;146likelihood = 1.0;147break;148case ARG_ARRAY_BIT | ARG_TYPE_CHAR:149r_type = Variant::PACKED_BYTE_ARRAY;150likelihood = 0.5;151break;152case ARG_ARRAY_BIT | ARG_TYPE_SHORT:153r_type = Variant::PACKED_INT32_ARRAY;154likelihood = 0.3;155break;156case ARG_ARRAY_BIT | ARG_TYPE_INT:157r_type = Variant::PACKED_INT32_ARRAY;158likelihood = 1.0;159break;160case ARG_ARRAY_BIT | ARG_TYPE_LONG:161r_type = Variant::PACKED_INT32_ARRAY;162likelihood = 0.5;163break;164case ARG_ARRAY_BIT | ARG_TYPE_FLOAT:165r_type = Variant::PACKED_FLOAT32_ARRAY;166likelihood = 1.0;167break;168case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE:169r_type = Variant::PACKED_FLOAT32_ARRAY;170likelihood = 0.5;171break;172case ARG_ARRAY_BIT | ARG_TYPE_STRING:173case ARG_ARRAY_BIT | ARG_TYPE_CHARSEQUENCE:174r_type = Variant::PACKED_STRING_ARRAY;175break;176case ARG_ARRAY_BIT | ARG_TYPE_CLASS:177case ARG_ARRAY_BIT | ARG_TYPE_CALLABLE:178r_type = Variant::ARRAY;179break;180}181}182183_FORCE_INLINE_ static bool _convert_object_to_variant(JNIEnv *env, jobject obj, Variant &var, uint32_t p_sig);184185bool _call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error, Variant &ret);186187friend class JavaClassWrapper;188friend class JavaObject;189String java_class_name;190String java_constructor_name;191HashMap<StringName, List<MethodInfo>> methods;192jclass _class;193#endif194195protected:196static void _bind_methods();197bool _get(const StringName &p_name, Variant &r_ret) const;198199public:200virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;201202String get_java_class_name() const;203TypedArray<Dictionary> get_java_method_list() const;204Ref<JavaClass> get_java_parent_class() const;205bool has_java_method(const StringName &p_method) const;206207#ifdef ANDROID_ENABLED208virtual String _to_string() override;209#endif210211JavaClass();212~JavaClass();213};214215class JavaObject : public RefCounted {216GDCLASS(JavaObject, RefCounted);217218#ifdef ANDROID_ENABLED219Ref<JavaClass> base_class;220friend class JavaClass;221222jobject instance = nullptr;223#endif224225protected:226static void _bind_methods();227228public:229virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;230231Ref<JavaClass> get_java_class() const;232bool has_java_method(const StringName &p_method) const;233234#ifdef ANDROID_ENABLED235virtual String _to_string() override;236237jobject get_instance() { return instance; }238239JavaObject();240JavaObject(const Ref<JavaClass> &p_base, jobject p_instance);241~JavaObject();242#endif243};244245class JavaClassWrapper : public Object {246GDCLASS(JavaClassWrapper, Object);247248#ifdef ANDROID_ENABLED249RBMap<String, Ref<JavaClass>> class_cache;250friend class JavaClass;251jmethodID Class_getConstructors;252jmethodID Class_getDeclaredMethods;253jmethodID Class_getFields;254jmethodID Class_getName;255jmethodID Class_getSuperclass;256jmethodID Constructor_getParameterTypes;257jmethodID Constructor_getModifiers;258jmethodID Method_getParameterTypes;259jmethodID Method_getReturnType;260jmethodID Method_getModifiers;261jmethodID Method_getName;262jmethodID Field_getName;263jmethodID Field_getModifiers;264jmethodID Field_get;265jmethodID Boolean_booleanValue;266jmethodID Byte_byteValue;267jmethodID Character_characterValue;268jmethodID Short_shortValue;269jmethodID Integer_integerValue;270jmethodID Long_longValue;271jmethodID Float_floatValue;272jmethodID Double_doubleValue;273274bool _get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, String &strsig);275#endif276277Ref<JavaObject> exception;278279Ref<JavaClass> _wrap(const String &p_class, bool p_allow_non_public_methods_access = false);280281static JavaClassWrapper *singleton;282283protected:284static void _bind_methods();285286public:287static JavaClassWrapper *get_singleton() { return singleton; }288289Ref<JavaClass> wrap(const String &p_class) {290return _wrap(p_class, false);291}292293Ref<JavaObject> get_exception() {294return exception;295}296297#ifdef ANDROID_ENABLED298Ref<JavaClass> wrap_jclass(jclass p_class, bool p_allow_non_public_methods_access = false);299#endif300JavaClassWrapper();301};302303304