-
Notifications
You must be signed in to change notification settings - Fork 233
/
ObjectTemplate.kt
100 lines (87 loc) · 3.43 KB
/
ObjectTemplate.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
{%- let obj = ci.get_object_definition(name).unwrap() %}
{%- if self.include_once_check("ObjectRuntime.kt") %}{% include "ObjectRuntime.kt" %}{% endif %}
{{- self.add_import("java.util.concurrent.atomic.AtomicLong") }}
{{- self.add_import("java.util.concurrent.atomic.AtomicBoolean") }}
public interface {{ type_name }}Interface {
{% for meth in obj.methods() -%}
{%- match meth.throws() -%}
{%- when Some with (throwable) %}
@Throws({{ throwable|exception_name }}::class)
{%- else -%}
{%- endmatch %}
fun {{ meth.name()|fn_name }}({% call kt::arg_list_decl(meth) %})
{%- match meth.return_type() -%}
{%- when Some with (return_type) %}: {{ return_type|type_name -}}
{%- else -%}
{%- endmatch %}
{% endfor %}
}
class {{ type_name }}(
pointer: Pointer
) : FFIObject(pointer), {{ type_name }}Interface {
{%- match obj.primary_constructor() %}
{%- when Some with (cons) %}
constructor({% call kt::arg_list_decl(cons) -%}) :
this({% call kt::to_ffi_call(cons) %})
{%- when None %}
{%- endmatch %}
/**
* Disconnect the object from the underlying Rust object.
*
* It can be called more than once, but once called, interacting with the object
* causes an `IllegalStateException`.
*
* Clients **must** call this method once done with the object, or cause a memory leak.
*/
override protected fun freeRustArcPtr() {
rustCall() { status ->
_UniFFILib.INSTANCE.{{ obj.ffi_object_free().name() }}(this.pointer, status)
}
}
{% for meth in obj.methods() -%}
{%- match meth.throws() -%}
{%- when Some with (throwable) %}
@Throws({{ throwable|exception_name }}::class)
{%- else -%}
{%- endmatch %}
{%- match meth.return_type() -%}
{%- when Some with (return_type) -%}
override fun {{ meth.name()|fn_name }}({% call kt::arg_list_protocol(meth) %}): {{ return_type|type_name }} =
callWithPointer {
{%- call kt::to_ffi_call_with_prefix("it", meth) %}
}.let {
{{ return_type|lift_fn }}(it)
}
{%- when None -%}
override fun {{ meth.name()|fn_name }}({% call kt::arg_list_protocol(meth) %}) =
callWithPointer {
{%- call kt::to_ffi_call_with_prefix("it", meth) %}
}
{% endmatch %}
{% endfor %}
{% if !obj.alternate_constructors().is_empty() -%}
companion object {
{% for cons in obj.alternate_constructors() -%}
fun {{ cons.name()|fn_name }}({% call kt::arg_list_decl(cons) %}): {{ type_name }} =
{{ type_name }}({% call kt::to_ffi_call(cons) %})
{% endfor %}
}
{% endif %}
}
public object {{ obj|ffi_converter_name }}: FfiConverter<{{ type_name }}, Pointer> {
override fun lower(value: {{ type_name }}): Pointer = value.callWithPointer { it }
override fun lift(value: Pointer): {{ type_name }} {
return {{ type_name }}(value)
}
override fun read(buf: ByteBuffer): {{ type_name }} {
// The Rust code always writes pointers as 8 bytes, and will
// fail to compile if they don't fit.
return lift(Pointer(buf.getLong()))
}
override fun allocationSize(value: {{ type_name }}) = 8
override fun write(value: {{ type_name }}, buf: ByteBuffer) {
// The Rust code always expects pointers written as 8 bytes,
// and will fail to compile if they don't fit.
buf.putLong(Pointer.nativeValue(lower(value)))
}
}