11{% - macro render_method_call (method ) -%}
2- {% - if method .return_bridge == 'string' %}
3- final cString = bindings.{{ method.call_symbol }}(
2+ bindings.{{ method.call_symbol }}(
43{% - if method .needs_instance_handle %}
5- _nativeHandle{% if method .call_args |length > 0 %} ,{% endif %}
4+ _nativeHandle{% if method .call_args |length > 0 %} , {% endif %}
65{% - endif %}
76{% - for arg in method .call_args %}
8- {{ arg }}{% if not loop .last %} , {% endif %}
7+ {{ arg }}{% if not loop .last %} , {% endif %}
98{% - endfor %}
10- );
9+ )
10+ {% - endmacro -%}
11+
12+ {% - macro render_method_body (method ) -%}
13+ {% - if method .return_bridge == 'string' %}
14+ final cString = {{ render_method_call(method) }};
1115 if (cString == ffi.nullptr) return '';
1216 final value = cString.cast<pkgffi .Utf8 >().toDartString();
1317 bindings.{{ method.string_free_symbol }}(cString);
1418 return value;
19+ {% - elif method .return_bridge == 'enum' %}
20+ final nativeValue = {{ render_method_call(method) }};
21+ return {{ method.api_return_type }}.fromNativeValue(nativeValue);
22+ {% - elif method .return_bridge == 'struct' %}
23+ final nativeValue = {{ render_method_call(method) }};
24+ {% - if method .struct_free_symbol %}
25+ try {
26+ return {{ method.api_return_type }}.fromNative(nativeValue);
27+ } finally {
28+ final nativeValuePtr = pkgffi.malloc<{{ method.native_return_type }}>();
29+ nativeValuePtr.ref = nativeValue;
30+ bindings.{{ method.struct_free_symbol }}(nativeValuePtr);
31+ pkgffi.malloc.free(nativeValuePtr);
32+ }
33+ {% - else %}
34+ return {{ method.api_return_type }}.fromNative(nativeValue);
35+ {% - endif %}
1536{% - elif method .return_bridge == 'offset' %}
16- final nativeValue = bindings.{{ method.call_symbol }}(
17- {% - if method .needs_instance_handle %}
18- _nativeHandle{% if method .call_args |length > 0 %} ,{% endif %}
19- {% - endif %}
20- {% - for arg in method .call_args %}
21- {{ arg }}{% if not loop .last %} , {% endif %}
22- {% - endfor %}
23- );
37+ final nativeValue = {{ render_method_call(method) }};
2438 return ui.Offset(nativeValue.x, nativeValue.y);
2539{% - elif method .return_bridge == 'size' %}
26- final nativeValue = bindings.{{ method.call_symbol }}(
27- {% - if method .needs_instance_handle %}
28- _nativeHandle{% if method .call_args |length > 0 %} ,{% endif %}
29- {% - endif %}
30- {% - for arg in method .call_args %}
31- {{ arg }}{% if not loop .last %} , {% endif %}
32- {% - endfor %}
33- );
40+ final nativeValue = {{ render_method_call(method) }};
3441 return ui.Size(nativeValue.width, nativeValue.height);
3542{% - elif method .return_bridge == 'rect' %}
36- final nativeValue = bindings.{{ method.call_symbol }}(
37- {% - if method .needs_instance_handle %}
38- _nativeHandle{% if method .call_args |length > 0 %} ,{% endif %}
39- {% - endif %}
40- {% - for arg in method .call_args %}
41- {{ arg }}{% if not loop .last %} , {% endif %}
42- {% - endfor %}
43- );
43+ final nativeValue = {{ render_method_call(method) }};
4444 return ui.Rect.fromLTWH(nativeValue.x, nativeValue.y, nativeValue.width, nativeValue.height);
4545{% - elif method .return_bridge == 'void' %}
46- bindings.{{ method.call_symbol }}(
47- {% - if method .needs_instance_handle %}
48- _nativeHandle{% if method .call_args |length > 0 %} ,{% endif %}
49- {% - endif %}
50- {% - for arg in method .call_args %}
51- {{ arg }}{% if not loop .last %} , {% endif %}
52- {% - endfor %}
53- );
46+ {{ render_method_call(method) }};
5447{% - else %}
55- return bindings.{{ method.call_symbol }}(
56- {% - if method .needs_instance_handle %}
57- _nativeHandle{% if method .call_args |length > 0 %} ,{% endif %}
48+ return {{ render_method_call(method) }};
5849{% - endif %}
59- {% - for arg in method .call_args %}
60- {{ arg }}{% if not loop .last %} , {% endif %}
50+ {% - endmacro -%}
51+
52+ {% - macro render_callable (method ) -%}
53+ {% - for line in method .pre_call_lines %}
54+ {{ line }}
55+ {% - endfor %}
56+ {% - if method .post_call_lines %}
57+ try {
58+ {{ render_method_body(method) }}
59+ } finally {
60+ {% - for line in method .post_call_lines %}
61+ {{ line }}
6162{% - endfor %}
62- );
63+ }
64+ {% - else %}
65+ {{ render_method_body(method) }}
6366{% - endif %}
6467{% - endmacro -%}
6568
6669{% - macro render_class (item , mapping ) -%}
70+ {% - if item .is_singleton and not item .singleton_has_handle %}
71+ class {{ item.name }} with CNativeApiBindingsMixin {
72+ static final {{ item.name }} instance = {{ item.name }}._();
73+
74+ {{ item.name }}._();
75+
76+ {% - for method in item .methods %}
77+ {% - if not method .skip %}
78+ {% - if method .is_property %}
79+ {{ 'static ' if method.static else '' }}{{ method.api_return_type }} get {{ method.property_name }} {
80+ {{ render_callable(method) }}
81+ }
82+ {% - else %}
83+ {{ 'static ' if method.static else '' }}{{ method.api_return_type }} {{ method.api_name }}(
84+ {% - for param in method .params %}
85+ {{ param.api_type }} {{ param.name }}{% if not loop .last %} , {% endif %}
86+ {% - endfor %}
87+ ) {
88+ {{ render_callable(method) }}
89+ }
90+ {% - endif %}
91+
92+ {% - endif %}
93+ {% - endfor %}
94+ }
95+ {% - else %}
6796class {{ item.name }} with CNativeApiBindingsMixin implements NativeHandleWrapper<{{ item.handle_alias }}> {
6897 {% - if item .is_singleton %}
6998 static final {{ item.name }} instance = {{ item.name }}._();
@@ -74,9 +103,13 @@ class {{ item.name }} with CNativeApiBindingsMixin implements NativeHandleWrappe
74103 _nativeHandle = bindings.{{ item.singleton_symbol }}();
75104 }
76105 {% - else %}
77- final {{ item.handle_alias }} _nativeHandle;
106+ late final {{ item.handle_alias }} _nativeHandle;
107+ final bool _ownsHandle;
78108
79- {{ item.name }}(this._nativeHandle);
109+ {{ item.name }}([{{ item.handle_alias }}? nativeHandle])
110+ : _ownsHandle = nativeHandle == null {
111+ _nativeHandle = nativeHandle ?? bindings.{{ item.create_symbol }}();
112+ }
80113 {% - endif %}
81114
82115 @override
@@ -86,15 +119,15 @@ class {{ item.name }} with CNativeApiBindingsMixin implements NativeHandleWrappe
86119{% - if not method .skip %}
87120 {% - if method .is_property %}
88121 {{ 'static ' if method.static else '' }}{{ method.api_return_type }} get {{ method.property_name }} {
89- {{ render_method_call (method) }}
122+ {{ render_callable (method) }}
90123 }
91124 {% - else %}
92125 {{ 'static ' if method.static else '' }}{{ method.api_return_type }} {{ method.api_name }}(
93126 {% - for param in method .params %}
94127 {{ param.api_type }} {{ param.name }}{% if not loop .last %} , {% endif %}
95128 {% - endfor %}
96129 ) {
97- {{ render_method_call (method) }}
130+ {{ render_callable (method) }}
98131 }
99132 {% - endif %}
100133
@@ -103,7 +136,14 @@ class {{ item.name }} with CNativeApiBindingsMixin implements NativeHandleWrappe
103136
104137 @override
105138 void dispose() {
106- // Generated wrappers are non-owning by default.
139+ {% - if item .is_singleton %}
140+ // Singleton handles are managed by native code.
141+ {% - else %}
142+ if (_ownsHandle) {
143+ bindings.{{ item.destroy_symbol }}(_nativeHandle);
144+ }
145+ {% - endif %}
107146 }
108147}
148+ {% - endif %}
109149{% - endmacro -%}
0 commit comments