Path: blob/master/platform/android/api/java_class_wrapper.h
11353 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 _static = false;73bool _constructor = false;74Vector<uint32_t> param_types;75Vector<StringName> param_sigs;76uint32_t return_type = 0;77jmethodID method;78};7980_FORCE_INLINE_ static void _convert_to_variant_type(int p_sig, Variant::Type &r_type, float &likelihood) {81likelihood = 1.0;82r_type = Variant::NIL;8384switch (p_sig) {85case ARG_TYPE_VOID:86r_type = Variant::NIL;87break;88case ARG_TYPE_BOOLEAN | ARG_NUMBER_CLASS_BIT:89case ARG_TYPE_BOOLEAN:90r_type = Variant::BOOL;91break;92case ARG_TYPE_BYTE | ARG_NUMBER_CLASS_BIT:93case ARG_TYPE_BYTE:94r_type = Variant::INT;95likelihood = 0.1;96break;97case ARG_TYPE_CHAR | ARG_NUMBER_CLASS_BIT:98case ARG_TYPE_CHAR:99r_type = Variant::INT;100likelihood = 0.2;101break;102case ARG_TYPE_SHORT | ARG_NUMBER_CLASS_BIT:103case ARG_TYPE_SHORT:104r_type = Variant::INT;105likelihood = 0.3;106break;107case ARG_TYPE_INT | ARG_NUMBER_CLASS_BIT:108case ARG_TYPE_INT:109r_type = Variant::INT;110likelihood = 1.0;111break;112case ARG_TYPE_LONG | ARG_NUMBER_CLASS_BIT:113case ARG_TYPE_LONG:114r_type = Variant::INT;115likelihood = 0.5;116break;117case ARG_TYPE_FLOAT | ARG_NUMBER_CLASS_BIT:118case ARG_TYPE_FLOAT:119r_type = Variant::FLOAT;120likelihood = 1.0;121break;122case ARG_TYPE_DOUBLE | ARG_NUMBER_CLASS_BIT:123case ARG_TYPE_DOUBLE:124r_type = Variant::FLOAT;125likelihood = 0.5;126break;127case ARG_TYPE_STRING:128case ARG_TYPE_CHARSEQUENCE:129r_type = Variant::STRING;130break;131case ARG_TYPE_CALLABLE:132r_type = Variant::CALLABLE;133break;134case ARG_TYPE_CLASS:135r_type = Variant::OBJECT;136break;137case ARG_ARRAY_BIT | ARG_TYPE_VOID:138r_type = Variant::NIL;139break;140case ARG_ARRAY_BIT | ARG_TYPE_BOOLEAN:141r_type = Variant::ARRAY;142break;143case ARG_ARRAY_BIT | ARG_TYPE_BYTE:144r_type = Variant::PACKED_BYTE_ARRAY;145likelihood = 1.0;146break;147case ARG_ARRAY_BIT | ARG_TYPE_CHAR:148r_type = Variant::PACKED_BYTE_ARRAY;149likelihood = 0.5;150break;151case ARG_ARRAY_BIT | ARG_TYPE_SHORT:152r_type = Variant::PACKED_INT32_ARRAY;153likelihood = 0.3;154break;155case ARG_ARRAY_BIT | ARG_TYPE_INT:156r_type = Variant::PACKED_INT32_ARRAY;157likelihood = 1.0;158break;159case ARG_ARRAY_BIT | ARG_TYPE_LONG:160r_type = Variant::PACKED_INT32_ARRAY;161likelihood = 0.5;162break;163case ARG_ARRAY_BIT | ARG_TYPE_FLOAT:164r_type = Variant::PACKED_FLOAT32_ARRAY;165likelihood = 1.0;166break;167case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE:168r_type = Variant::PACKED_FLOAT32_ARRAY;169likelihood = 0.5;170break;171case ARG_ARRAY_BIT | ARG_TYPE_STRING:172case ARG_ARRAY_BIT | ARG_TYPE_CHARSEQUENCE:173r_type = Variant::PACKED_STRING_ARRAY;174break;175case ARG_ARRAY_BIT | ARG_TYPE_CLASS:176case ARG_ARRAY_BIT | ARG_TYPE_CALLABLE:177r_type = Variant::ARRAY;178break;179}180}181182_FORCE_INLINE_ static bool _convert_object_to_variant(JNIEnv *env, jobject obj, Variant &var, uint32_t p_sig);183184bool _call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error, Variant &ret);185186friend class JavaClassWrapper;187friend class JavaObject;188String java_class_name;189String java_constructor_name;190HashMap<StringName, List<MethodInfo>> methods;191jclass _class;192#endif193194protected:195static void _bind_methods();196bool _get(const StringName &p_name, Variant &r_ret) const;197198public:199virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;200201String get_java_class_name() const;202TypedArray<Dictionary> get_java_method_list() const;203Ref<JavaClass> get_java_parent_class() const;204bool has_java_method(const StringName &p_method) const;205206#ifdef ANDROID_ENABLED207virtual String to_string() override;208#endif209210JavaClass();211~JavaClass();212};213214class JavaObject : public RefCounted {215GDCLASS(JavaObject, RefCounted);216217#ifdef ANDROID_ENABLED218Ref<JavaClass> base_class;219friend class JavaClass;220221jobject instance = nullptr;222#endif223224protected:225static void _bind_methods();226227public:228virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;229230Ref<JavaClass> get_java_class() const;231bool has_java_method(const StringName &p_method) const;232233#ifdef ANDROID_ENABLED234virtual String to_string() override;235236jobject get_instance() { return instance; }237238JavaObject();239JavaObject(const Ref<JavaClass> &p_base, jobject p_instance);240~JavaObject();241#endif242};243244class JavaClassWrapper : public Object {245GDCLASS(JavaClassWrapper, Object);246247#ifdef ANDROID_ENABLED248RBMap<String, Ref<JavaClass>> class_cache;249friend class JavaClass;250jmethodID Class_getConstructors;251jmethodID Class_getDeclaredMethods;252jmethodID Class_getFields;253jmethodID Class_getName;254jmethodID Class_getSuperclass;255jmethodID Constructor_getParameterTypes;256jmethodID Constructor_getModifiers;257jmethodID Method_getParameterTypes;258jmethodID Method_getReturnType;259jmethodID Method_getModifiers;260jmethodID Method_getName;261jmethodID Field_getName;262jmethodID Field_getModifiers;263jmethodID Field_get;264jmethodID Boolean_booleanValue;265jmethodID Byte_byteValue;266jmethodID Character_characterValue;267jmethodID Short_shortValue;268jmethodID Integer_integerValue;269jmethodID Long_longValue;270jmethodID Float_floatValue;271jmethodID Double_doubleValue;272273bool _get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, String &strsig);274#endif275276Ref<JavaObject> exception;277278Ref<JavaClass> _wrap(const String &p_class, bool p_allow_non_public_methods_access);279280static JavaClassWrapper *singleton;281282protected:283static void _bind_methods();284285public:286static JavaClassWrapper *get_singleton() { return singleton; }287288Ref<JavaClass> wrap(const String &p_class) {289return _wrap(p_class, false);290}291292Ref<JavaObject> get_exception() {293return exception;294}295296#ifdef ANDROID_ENABLED297Ref<JavaClass> wrap_jclass(jclass p_class, bool p_allow_private_methods_access = false);298#endif299JavaClassWrapper();300};301302303