Dev: add expiremental API with automatic #functionName resolving
This commit is contained in:
parent
cf0a3934b9
commit
fa93e4ed20
|
@ -9,94 +9,140 @@ import Foundation
|
||||||
import java_swift
|
import java_swift
|
||||||
|
|
||||||
public protocol JNIArgumentProtocol {
|
public protocol JNIArgumentProtocol {
|
||||||
func value() -> jvalue
|
func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue
|
||||||
|
func sig() -> String
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct jnull: JNIArgumentProtocol {
|
public struct jnull: JNIArgumentProtocol {
|
||||||
|
|
||||||
public func value() -> jvalue {
|
let className: String
|
||||||
|
|
||||||
|
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||||
return jvalue()
|
return jvalue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func sig() -> String {
|
||||||
|
return "L\(className);"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension jint: JNIArgumentProtocol {
|
extension jint: JNIArgumentProtocol {
|
||||||
|
|
||||||
public func value() -> jvalue {
|
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||||
return jvalue(i: self)
|
return jvalue(i: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func sig() -> String {
|
||||||
|
return "I"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension jbyte: JNIArgumentProtocol {
|
extension jbyte: JNIArgumentProtocol {
|
||||||
|
|
||||||
public func value() -> jvalue {
|
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||||
return jvalue(b: self)
|
return jvalue(b: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func sig() -> String {
|
||||||
|
return "B"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension jchar: JNIArgumentProtocol {
|
extension jchar: JNIArgumentProtocol {
|
||||||
|
|
||||||
public func value() -> jvalue {
|
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||||
return jvalue(c: self)
|
return jvalue(c: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func sig() -> String {
|
||||||
|
return "C"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension jshort: JNIArgumentProtocol {
|
extension jshort: JNIArgumentProtocol {
|
||||||
|
|
||||||
public func value() -> jvalue {
|
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||||
return jvalue(s: self)
|
return jvalue(s: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func sig() -> String {
|
||||||
|
return "S"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension jlong: JNIArgumentProtocol {
|
extension jlong: JNIArgumentProtocol {
|
||||||
|
|
||||||
public func value() -> jvalue {
|
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||||
return jvalue(j: self)
|
return jvalue(j: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func sig() -> String {
|
||||||
|
return "J"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension jboolean: JNIArgumentProtocol {
|
extension jboolean: JNIArgumentProtocol {
|
||||||
|
|
||||||
public func value() -> jvalue {
|
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||||
return jvalue(z: self)
|
return jvalue(z: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func sig() -> String {
|
||||||
|
return "Z"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension jfloat: JNIArgumentProtocol {
|
extension jfloat: JNIArgumentProtocol {
|
||||||
|
|
||||||
public func value() -> jvalue {
|
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||||
return jvalue(f: self)
|
return jvalue(f: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func sig() -> String {
|
||||||
|
return "F"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension jdouble: JNIArgumentProtocol {
|
extension jdouble: JNIArgumentProtocol {
|
||||||
|
|
||||||
public func value() -> jvalue {
|
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||||
return jvalue(d: self)
|
return jvalue(d: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func sig() -> String {
|
||||||
|
return "D"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension String: JNIArgumentProtocol {
|
||||||
|
|
||||||
|
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||||
|
return jvalue(l: self.localJavaObject(locals))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func sig() -> String {
|
||||||
|
return "Ljava/lang/String;"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension jobject: JNIArgumentProtocol {
|
extension jobject: JNIArgumentProtocol {
|
||||||
|
|
||||||
public func value() -> jvalue {
|
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||||
return jvalue(l: self)
|
return jvalue(l: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
public func sig() -> String {
|
||||||
|
return "L\(JNIObject.getJavaClassname(javaObject: self));"
|
||||||
// For backward compatibility
|
|
||||||
extension jvalue: JNIArgumentProtocol {
|
|
||||||
|
|
||||||
public func value() -> jvalue {
|
|
||||||
return self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,10 +88,6 @@ fileprivate let javaFieldLock = NSLock()
|
||||||
|
|
||||||
public extension JNICore {
|
public extension JNICore {
|
||||||
|
|
||||||
public var NULL: JNIArgumentProtocol {
|
|
||||||
return jnull()
|
|
||||||
}
|
|
||||||
|
|
||||||
public var TRUE: jboolean {
|
public var TRUE: jboolean {
|
||||||
return jboolean(JNI_TRUE)
|
return jboolean(JNI_TRUE)
|
||||||
}
|
}
|
||||||
|
@ -327,8 +323,12 @@ public extension JNICore {
|
||||||
|
|
||||||
private func checkArgumentAndWrap<Result>(args: [JNIArgumentProtocol], _ block: (_ argsPtr: UnsafePointer<jvalue>?) -> Result) -> Result {
|
private func checkArgumentAndWrap<Result>(args: [JNIArgumentProtocol], _ block: (_ argsPtr: UnsafePointer<jvalue>?) -> Result) -> Result {
|
||||||
if args.count > 0 {
|
if args.count > 0 {
|
||||||
var argsValues = args.map({ $0.value() })
|
var locals = [jobject]()
|
||||||
|
var argsValues = args.map({ $0.value(locals: &locals) })
|
||||||
return withUnsafePointer(to: &argsValues[0]) { argsPtr in
|
return withUnsafePointer(to: &argsValues[0]) { argsPtr in
|
||||||
|
defer {
|
||||||
|
_ = JNI.check(Void.self, &locals)
|
||||||
|
}
|
||||||
return block(argsPtr)
|
return block(argsPtr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,35 +8,73 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import java_swift
|
import java_swift
|
||||||
|
|
||||||
|
public class JNIObjectWithClass: JNIObject {
|
||||||
|
|
||||||
|
var privateClassName: String!
|
||||||
|
|
||||||
|
public required init(javaObject: jobject?) {
|
||||||
|
super.init(javaObject: javaObject)
|
||||||
|
privateClassName = JNIObject.getJavaClassname(javaObject: self.javaObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
public required init(javaObject: jobject?, className: String) {
|
||||||
|
super.init(javaObject: javaObject)
|
||||||
|
self.privateClassName = className
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public extension JNIObject {
|
public extension JNIObject {
|
||||||
|
|
||||||
|
public static func getJavaClassname(javaObject: jobject?) -> String {
|
||||||
|
let cls = JNI.api.GetObjectClass(JNI.env, javaObject)
|
||||||
|
let javaClassName = JNI.api.CallObjectMethodA(JNI.env, cls, ClassGetNameMethod, nil)
|
||||||
|
return String(javaObject: javaClassName).replacingOccurrences(of: ".", with: "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
public var className: String {
|
||||||
|
if let jniObject = self as? JNIObjectWithClass {
|
||||||
|
return jniObject.privateClassName
|
||||||
|
}
|
||||||
|
return JNIObject.getJavaClassname(javaObject: self.javaObject)
|
||||||
|
}
|
||||||
|
|
||||||
public func callVoidMethod(_ methodID: jmethodID, _ args: JNIArgumentProtocol..., locals: UnsafeMutablePointer<[jobject]>? = nil) {
|
public func callVoidMethod(_ methodID: jmethodID, _ args: JNIArgumentProtocol...) {
|
||||||
checkArgumentAndWrap(args: args, { argsPtr in
|
checkArgumentAndWrap(args: args, { argsPtr in
|
||||||
|
|
||||||
JNI.api.CallVoidMethodA(JNI.env, javaObject, methodID, argsPtr)
|
JNI.api.CallVoidMethodA(JNI.env, javaObject, methodID, argsPtr)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private func checkArgumentAndWrap<Result>(args: [JNIArgumentProtocol], _ block: (_ argsPtr: UnsafePointer<jvalue>?) -> Result, locals: UnsafeMutablePointer<[jobject]>? = nil) -> Result {
|
public func callStringMethod(method: String? = nil, functionName: String = #function, _ args: JNIArgumentProtocol...) -> String {
|
||||||
|
let methodName = method ?? String(functionName.split(separator: "(")[0])
|
||||||
|
return String(javaObject: self.internalcallObjectMethod(method: methodName, returnType: "Ljava/lang/String;", args))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func callObjectMethod(method: String? = nil, functionName: String = #function, returnType: String, _ args: JNIArgumentProtocol...) -> jobject? {
|
||||||
|
let methodName = method ?? String(functionName.split(separator: "(")[0])
|
||||||
|
return self.internalcallObjectMethod(method: methodName, returnType: returnType, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func internalcallObjectMethod(method: String, returnType: String, _ args: [JNIArgumentProtocol]) -> jobject? {
|
||||||
|
let sig = "(\(args.map({ $0.sig() }).joined()))\(returnType)"
|
||||||
|
let methodID = try! JNI.getJavaMethod(forClass: self.className, method: method, sig: sig)
|
||||||
|
return checkArgumentAndWrap(args: args, { argsPtr in
|
||||||
|
return JNI.api.CallObjectMethodA(JNI.env, javaObject, methodID, argsPtr)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private func checkArgumentAndWrap<Result>(args: [JNIArgumentProtocol], _ block: (_ argsPtr: UnsafePointer<jvalue>?) -> Result) -> Result {
|
||||||
if args.count > 0 {
|
if args.count > 0 {
|
||||||
var argsValues = args.map({ $0.value() })
|
var locals = [jobject]()
|
||||||
|
var argsValues = args.map({ $0.value(locals: &locals) })
|
||||||
return withUnsafePointer(to: &argsValues[0]) { argsPtr in
|
return withUnsafePointer(to: &argsValues[0]) { argsPtr in
|
||||||
defer {
|
defer {
|
||||||
if let locals = locals {
|
_ = JNI.check(Void.self, &locals)
|
||||||
_ = JNI.check(Void.self, locals)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return block(argsPtr)
|
return block(argsPtr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
defer {
|
|
||||||
if let locals = locals {
|
|
||||||
_ = JNI.check(Void.self, locals)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return block(nil)
|
return block(nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue