Path: blob/master/platform/android/api/java_class_wrapper.h
10278 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 <android/log.h>37#include <jni.h>38#endif3940#ifdef ANDROID_ENABLED41class JavaObject;42#endif4344class JavaClass : public RefCounted {45GDCLASS(JavaClass, RefCounted);4647#ifdef ANDROID_ENABLED48enum ArgumentType {49ARG_TYPE_VOID,50ARG_TYPE_BOOLEAN,51ARG_TYPE_BYTE,52ARG_TYPE_CHAR,53ARG_TYPE_SHORT,54ARG_TYPE_INT,55ARG_TYPE_LONG,56ARG_TYPE_FLOAT,57ARG_TYPE_DOUBLE,58ARG_TYPE_STRING, //special case59ARG_TYPE_CHARSEQUENCE,60ARG_TYPE_CALLABLE,61ARG_TYPE_CLASS,62ARG_ARRAY_BIT = 1 << 16,63ARG_NUMBER_CLASS_BIT = 1 << 17,64ARG_TYPE_MASK = (1 << 16) - 165};6667RBMap<StringName, Variant> constant_map;6869struct MethodInfo {70bool _static = false;71bool _constructor = false;72Vector<uint32_t> param_types;73Vector<StringName> param_sigs;74uint32_t return_type = 0;75jmethodID method;76};7778_FORCE_INLINE_ static void _convert_to_variant_type(int p_sig, Variant::Type &r_type, float &likelihood) {79likelihood = 1.0;80r_type = Variant::NIL;8182switch (p_sig) {83case ARG_TYPE_VOID:84r_type = Variant::NIL;85break;86case ARG_TYPE_BOOLEAN | ARG_NUMBER_CLASS_BIT:87case ARG_TYPE_BOOLEAN:88r_type = Variant::BOOL;89break;90case ARG_TYPE_BYTE | ARG_NUMBER_CLASS_BIT:91case ARG_TYPE_BYTE:92r_type = Variant::INT;93likelihood = 0.1;94break;95case ARG_TYPE_CHAR | ARG_NUMBER_CLASS_BIT:96case ARG_TYPE_CHAR:97r_type = Variant::INT;98likelihood = 0.2;99break;100case ARG_TYPE_SHORT | ARG_NUMBER_CLASS_BIT:101case ARG_TYPE_SHORT:102r_type = Variant::INT;103likelihood = 0.3;104break;105case ARG_TYPE_INT | ARG_NUMBER_CLASS_BIT:106case ARG_TYPE_INT:107r_type = Variant::INT;108likelihood = 1.0;109break;110case ARG_TYPE_LONG | ARG_NUMBER_CLASS_BIT:111case ARG_TYPE_LONG:112r_type = Variant::INT;113likelihood = 0.5;114break;115case ARG_TYPE_FLOAT | ARG_NUMBER_CLASS_BIT:116case ARG_TYPE_FLOAT:117r_type = Variant::FLOAT;118likelihood = 1.0;119break;120case ARG_TYPE_DOUBLE | ARG_NUMBER_CLASS_BIT:121case ARG_TYPE_DOUBLE:122r_type = Variant::FLOAT;123likelihood = 0.5;124break;125case ARG_TYPE_STRING:126case ARG_TYPE_CHARSEQUENCE:127r_type = Variant::STRING;128break;129case ARG_TYPE_CALLABLE:130r_type = Variant::CALLABLE;131break;132case ARG_TYPE_CLASS:133r_type = Variant::OBJECT;134break;135case ARG_ARRAY_BIT | ARG_TYPE_VOID:136r_type = Variant::NIL;137break;138case ARG_ARRAY_BIT | ARG_TYPE_BOOLEAN:139r_type = Variant::ARRAY;140break;141case ARG_ARRAY_BIT | ARG_TYPE_BYTE:142r_type = Variant::PACKED_BYTE_ARRAY;143likelihood = 1.0;144break;145case ARG_ARRAY_BIT | ARG_TYPE_CHAR:146r_type = Variant::PACKED_BYTE_ARRAY;147likelihood = 0.5;148break;149case ARG_ARRAY_BIT | ARG_TYPE_SHORT:150r_type = Variant::PACKED_INT32_ARRAY;151likelihood = 0.3;152break;153case ARG_ARRAY_BIT | ARG_TYPE_INT:154r_type = Variant::PACKED_INT32_ARRAY;155likelihood = 1.0;156break;157case ARG_ARRAY_BIT | ARG_TYPE_LONG:158r_type = Variant::PACKED_INT32_ARRAY;159likelihood = 0.5;160break;161case ARG_ARRAY_BIT | ARG_TYPE_FLOAT:162r_type = Variant::PACKED_FLOAT32_ARRAY;163likelihood = 1.0;164break;165case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE:166r_type = Variant::PACKED_FLOAT32_ARRAY;167likelihood = 0.5;168break;169case ARG_ARRAY_BIT | ARG_TYPE_STRING:170case ARG_ARRAY_BIT | ARG_TYPE_CHARSEQUENCE:171r_type = Variant::PACKED_STRING_ARRAY;172break;173case ARG_ARRAY_BIT | ARG_TYPE_CLASS:174case ARG_ARRAY_BIT | ARG_TYPE_CALLABLE:175r_type = Variant::ARRAY;176break;177}178}179180_FORCE_INLINE_ static bool _convert_object_to_variant(JNIEnv *env, jobject obj, Variant &var, uint32_t p_sig);181182bool _call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error, Variant &ret);183184friend class JavaClassWrapper;185friend class JavaObject;186String java_class_name;187String java_constructor_name;188HashMap<StringName, List<MethodInfo>> methods;189jclass _class;190#endif191192protected:193static void _bind_methods();194bool _get(const StringName &p_name, Variant &r_ret) const;195196public:197virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;198199String get_java_class_name() const;200TypedArray<Dictionary> get_java_method_list() const;201Ref<JavaClass> get_java_parent_class() const;202203#ifdef ANDROID_ENABLED204virtual String to_string() override;205#endif206207JavaClass();208~JavaClass();209};210211class JavaObject : public RefCounted {212GDCLASS(JavaObject, RefCounted);213214#ifdef ANDROID_ENABLED215Ref<JavaClass> base_class;216friend class JavaClass;217218jobject instance = nullptr;219#endif220221protected:222static void _bind_methods();223224public:225virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;226227Ref<JavaClass> get_java_class() const;228229#ifdef ANDROID_ENABLED230virtual String to_string() override;231232jobject get_instance() { return instance; }233234JavaObject();235JavaObject(const Ref<JavaClass> &p_base, jobject p_instance);236~JavaObject();237#endif238};239240class JavaClassWrapper : public Object {241GDCLASS(JavaClassWrapper, Object);242243#ifdef ANDROID_ENABLED244RBMap<String, Ref<JavaClass>> class_cache;245friend class JavaClass;246jmethodID Class_getDeclaredConstructors;247jmethodID Class_getDeclaredMethods;248jmethodID Class_getFields;249jmethodID Class_getName;250jmethodID Class_getSuperclass;251jmethodID Constructor_getParameterTypes;252jmethodID Constructor_getModifiers;253jmethodID Method_getParameterTypes;254jmethodID Method_getReturnType;255jmethodID Method_getModifiers;256jmethodID Method_getName;257jmethodID Field_getName;258jmethodID Field_getModifiers;259jmethodID Field_get;260jmethodID Boolean_booleanValue;261jmethodID Byte_byteValue;262jmethodID Character_characterValue;263jmethodID Short_shortValue;264jmethodID Integer_integerValue;265jmethodID Long_longValue;266jmethodID Float_floatValue;267jmethodID Double_doubleValue;268269bool _get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, String &strsig);270#endif271272Ref<JavaObject> exception;273274Ref<JavaClass> _wrap(const String &p_class, bool p_allow_private_methods_access);275276static JavaClassWrapper *singleton;277278protected:279static void _bind_methods();280281public:282static JavaClassWrapper *get_singleton() { return singleton; }283284Ref<JavaClass> wrap(const String &p_class) {285return _wrap(p_class, false);286}287288Ref<JavaObject> get_exception() {289return exception;290}291292#ifdef ANDROID_ENABLED293Ref<JavaClass> wrap_jclass(jclass p_class, bool p_allow_private_methods_access = false);294#endif295JavaClassWrapper();296};297298299