[flutter] Web support through WASM

Massive refactor, no more passing/returning structs by value and explicit initialization.
This commit is contained in:
Mario Zechner 2022-11-20 02:16:48 +01:00
parent 7ea45ed77b
commit 35a0aaf8dc
21 changed files with 2341 additions and 1328 deletions

View File

@ -0,0 +1,6 @@
package com.example.example
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}

View File

@ -6,6 +6,7 @@ import 'pause_play_animation.dart';
import 'skins.dart';
import 'dress_up.dart';
import 'ik_following.dart';
import 'package:spine_flutter/spine_flutter.dart';
class ExampleSelector extends StatelessWidget {
const ExampleSelector({super.key});
@ -98,7 +99,9 @@ class ExampleSelector extends StatelessWidget {
}
}
void main() {
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await initSpineFlutter();
runApp(const MaterialApp(
title: "Spine Examples",
home: ExampleSelector()

View File

@ -95,6 +95,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.1"
inject_js:
dependency: transitive
description:
name: inject_js
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.5"
lints:
dependency: transitive
description:
@ -212,6 +226,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
web_ffi:
dependency: transitive
description:
name: web_ffi
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.2"
sdks:
dart: ">=2.17.6 <3.0.0"
flutter: ">=2.11.0"

View File

@ -45,8 +45,6 @@ dependencies:
raw_image_provider: ^0.2.0
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="example">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>
<title>example</title>
<link rel="manifest" href="manifest.json">
<script>
// The value below is injected by flutter build, do not touch.
var serviceWorkerVersion = null;
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>
</head>
<body>
<script>
window.addEventListener('load', function(ev) {
// Download main.dart.js
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
}
}).then(function(engineInitializer) {
return engineInitializer.initializeEngine();
}).then(function(appRunner) {
return appRunner.runApp();
});
});
</script>
</body>
</html>

View File

@ -0,0 +1,35 @@
{
"name": "example",
"short_name": "example",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "A new Flutter project.",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "icons/Icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "icons/Icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}

View File

@ -0,0 +1 @@
export 'dart:ffi' if (dart.library.html) 'package:web_ffi/web_ffi.dart';

View File

@ -0,0 +1,87 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:convert';
import 'ffi_proxy.dart';
import 'dart:typed_data';
/// The contents of a native zero-terminated array of UTF-8 code units.
///
/// The Utf8 type itself has no functionality, it's only intended to be used
/// through a `Pointer<Utf8>` representing the entire array. This pointer is
/// the equivalent of a char pointer (`const char*`) in C code.
class Utf8 extends Opaque {}
/// Extension method for converting a`Pointer<Utf8>` to a [String].
extension Utf8Pointer on Pointer<Utf8> {
/// The number of UTF-8 code units in this zero-terminated UTF-8 string.
///
/// The UTF-8 code units of the strings are the non-zero code units up to the
/// first zero code unit.
int get length {
_ensureNotNullptr('length');
final codeUnits = cast<Uint8>();
return _length(codeUnits);
}
/// Converts this UTF-8 encoded string to a Dart string.
///
/// Decodes the UTF-8 code units of this zero-terminated byte array as
/// Unicode code points and creates a Dart string containing those code
/// points.
///
/// If [length] is provided, zero-termination is ignored and the result can
/// contain NUL characters.
///
/// If [length] is not provided, the returned string is the string up til
/// but not including the first NUL character.
String toDartString({int? length}) {
_ensureNotNullptr('toDartString');
final codeUnits = cast<Uint8>();
if (length != null) {
RangeError.checkNotNegative(length, 'length');
} else {
length = _length(codeUnits);
}
return utf8.decode(codeUnits.asTypedList(length));
}
static int _length(Pointer<Uint8> codeUnits) {
var length = 0;
while (codeUnits[length] != 0) {
length++;
}
return length;
}
void _ensureNotNullptr(String operation) {
if (this == nullptr) {
throw UnsupportedError(
"Operation '$operation' not allowed on a 'nullptr'.");
}
}
}
/// Extension method for converting a [String] to a `Pointer<Utf8>`.
extension StringUtf8Pointer on String {
/// Creates a zero-terminated [Utf8] code-unit array from this String.
///
/// If this [String] contains NUL characters, converting it back to a string
/// using [Utf8Pointer.toDartString] will truncate the result if a length is
/// not passed.
///
/// Unpaired surrogate code points in this [String] will be encoded as
/// replacement characters (U+FFFD, encoded as the bytes 0xEF 0xBF 0xBD) in
/// the UTF-8 encoded result. See [Utf8Encoder] for details on encoding.
///
/// Returns an [allocator]-allocated pointer to the result.
Pointer<Utf8> toNativeUtf8(Allocator allocator) {
final units = utf8.encode(this);
final Pointer<Uint8> result = allocator<Uint8>(units.length + 1);
final Uint8List nativeString = result.asTypedList(units.length + 1);
nativeString.setAll(0, units);
nativeString[units.length] = 0;
return result.cast();
}
}

View File

@ -0,0 +1,28 @@
import 'dart:io';
import 'dart:ffi';
import 'package:ffi/ffi.dart';
const String _libName = 'spine_flutter';
final DynamicLibrary _dylib = () {
if (Platform.isMacOS || Platform.isIOS) {
return DynamicLibrary.open('$_libName.framework/$_libName');
}
if (Platform.isAndroid || Platform.isLinux) {
return DynamicLibrary.open('lib$_libName.so');
}
if (Platform.isWindows) {
return DynamicLibrary.open('$_libName.dll');
}
throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}');
}();
class SpineFlutterFFI {
DynamicLibrary dylib;
Allocator allocator;
SpineFlutterFFI(this.dylib, this.allocator);
}
Future<SpineFlutterFFI> initSpineFlutterFFI() async {
return SpineFlutterFFI(_dylib, malloc);
}

View File

@ -0,0 +1,77 @@
import 'package:flutter/services.dart';
import 'package:inject_js/inject_js.dart' as js;
import 'package:spine_flutter/ffi_utf8.dart';
import 'package:web_ffi/web_ffi.dart';
import 'package:web_ffi/web_ffi_modules.dart';
import 'spine_flutter_bindings_generated.dart';
const String _basePath = 'packages/spine_flutter/assets';
Module? _module;
class SpineFlutterFFI {
final DynamicLibrary dylib;
final Allocator allocator;
SpineFlutterFFI(this.dylib, this.allocator);
}
Future<SpineFlutterFFI> initSpineFlutterFFI() async {
if (_module == null) {
Memory.init();
registerOpaqueType<Utf8>();
registerOpaqueType<spine_skeleton_wrapper>();
registerOpaqueType<spine_skeleton_data_wrapper>();
registerOpaqueType<spine_bone_wrapper>();
registerOpaqueType<spine_bone_data_wrapper>();
registerOpaqueType<spine_slot_wrapper>();
registerOpaqueType<spine_slot_data_wrapper>();
registerOpaqueType<spine_skin_wrapper>();
registerOpaqueType<spine_attachment_wrapper>();
registerOpaqueType<spine_region_attachment_wrapper>();
registerOpaqueType<spine_vertex_attachment_wrapper>();
registerOpaqueType<spine_mesh_attachment_wrapper>();
registerOpaqueType<spine_clipping_attachment_wrapper>();
registerOpaqueType<spine_bounding_box_attachment_wrapper>();
registerOpaqueType<spine_path_attachment_wrapper>();
registerOpaqueType<spine_point_attachment_wrapper>();
registerOpaqueType<spine_texture_region_wrapper>();
registerOpaqueType<spine_sequence_wrapper>();
registerOpaqueType<spine_constraint_wrapper>();
registerOpaqueType<spine_constraint_data_wrapper>();
registerOpaqueType<spine_ik_constraint_wrapper>();
registerOpaqueType<spine_ik_constraint_data_wrapper>();
registerOpaqueType<spine_transform_constraint_wrapper>();
registerOpaqueType<spine_transform_constraint_data_wrapper>();
registerOpaqueType<spine_path_constraint_wrapper>();
registerOpaqueType<spine_path_constraint_data_wrapper>();
registerOpaqueType<spine_animation_state_wrapper>();
registerOpaqueType<spine_animation_state_data_wrapper>();
registerOpaqueType<spine_animation_state_events_wrapper>();
registerOpaqueType<spine_event_wrapper>();
registerOpaqueType<spine_event_data_wrapper>();
registerOpaqueType<spine_track_entry_wrapper>();
registerOpaqueType<spine_animation_wrapper>();
registerOpaqueType<spine_atlas_wrapper>();
registerOpaqueType<spine_skeleton_data_result_wrapper>();
registerOpaqueType<spine_render_command_wrapper>();
registerOpaqueType<spine_bounds_wrapper>();
registerOpaqueType<spine_color_wrapper>();
registerOpaqueType<spine_vector_wrapper>();
registerOpaqueType<spine_skeleton_drawable_wrapper>();
registerOpaqueType<spine_skin_entry_wrapper>();
registerOpaqueType<spine_skin_entries_wrapper>();
await js.importLibrary('$_basePath/libspine_flutter.js');
String path = 'libspine_flutter.wasm';
Uint8List wasmBinaries = (await rootBundle.load(path)).buffer.asUint8List();
_module = await EmscriptenModule.compile(wasmBinaries, 'libspine_flutter');
}
Module? m = _module;
if (m != null) {
final dylib = DynamicLibrary.fromModule(m);
return SpineFlutterFFI(dylib, dylib.boundMemory);
} else {
throw Exception("Couldn't load libspine-flutter.js/.wasm");
}
}

View File

@ -1,18 +1,30 @@
import 'dart:convert' as convert;
import 'dart:ffi';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';
import 'package:ffi/ffi.dart';
import 'package:flutter/rendering.dart' as rendering;
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;
import 'spine_flutter_bindings_generated.dart';
import 'ffi_proxy.dart';
import 'ffi_utf8.dart';
export 'spine_widget.dart';
import 'init.dart' if (dart.library.html) 'init_web.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
late SpineFlutterBindings _bindings;
late Allocator _allocator;
Future<void> initSpineFlutter() async {
final ffi = await initSpineFlutterFFI();
_bindings = SpineFlutterBindings(ffi.dylib);
_allocator = ffi.allocator;
return;
}
int majorVersion() => _bindings.spine_major_version();
@ -46,7 +58,7 @@ class Vector2 {
}
class Atlas {
final Pointer<spine_atlas> _atlas;
final spine_atlas _atlas;
final List<Image> atlasPages;
final List<Paint> atlasPagePaints;
bool _disposed;
@ -56,11 +68,11 @@ class Atlas {
static Future<Atlas> _load(String atlasFileName, Future<Uint8List> Function(String name) loadFile) async {
final atlasBytes = await loadFile(atlasFileName);
final atlasData = convert.utf8.decode(atlasBytes);
final atlasDataNative = atlasData.toNativeUtf8();
final atlasDataNative = atlasData.toNativeUtf8(_allocator);
final atlas = _bindings.spine_atlas_load(atlasDataNative.cast());
malloc.free(atlasDataNative);
if (atlas.ref.error.address != nullptr.address) {
final Pointer<Utf8> error = atlas.ref.error.cast();
_allocator.free(atlasDataNative);
if (_bindings.spine_atlas_get_error(atlas).address != nullptr.address) {
final Pointer<Utf8> error = _bindings.spine_atlas_get_error(atlas).cast();
final message = error.toDartString();
_bindings.spine_atlas_dispose(atlas);
throw Exception("Couldn't load atlas: $message");
@ -69,8 +81,9 @@ class Atlas {
final atlasDir = path.dirname(atlasFileName);
List<Image> atlasPages = [];
List<Paint> atlasPagePaints = [];
for (int i = 0; i < atlas.ref.numImagePaths; i++) {
final Pointer<Utf8> atlasPageFile = atlas.ref.imagePaths[i].cast();
final numImagePaths = _bindings.spine_atlas_get_num_image_paths(atlas);
for (int i = 0; i < numImagePaths; i++) {
final Pointer<Utf8> atlasPageFile = _bindings.spine_atlas_get_image_path(atlas, i).cast();
final imagePath = path.join(atlasDir, atlasPageFile.toDartString());
var imageData = await loadFile(imagePath);
final Codec codec = await instantiateImageCodec(imageData);
@ -117,30 +130,34 @@ class SkeletonData {
SkeletonData._(this._data) : _disposed = false;
static SkeletonData fromJson(Atlas atlas, String json) {
final jsonNative = json.toNativeUtf8();
final jsonNative = json.toNativeUtf8(_allocator);
final result = _bindings.spine_skeleton_data_load_json(atlas._atlas, jsonNative.cast());
malloc.free(jsonNative);
if (result.error.address != nullptr.address) {
final Pointer<Utf8> error = result.error.cast();
_allocator.free(jsonNative);
if (_bindings.spine_skeleton_data_result_get_error(result).address != nullptr.address) {
final Pointer<Utf8> error = _bindings.spine_skeleton_data_result_get_error(result).cast();
final message = error.toDartString();
malloc.free(error);
_bindings.spine_skeleton_data_result_dispose(result);
throw Exception("Couldn't load skeleton data: $message");
}
return SkeletonData._(result.skeletonData);
var data = SkeletonData._(_bindings.spine_skeleton_data_result_get_data(result));
_bindings.spine_skeleton_data_result_dispose(result);
return data;
}
static SkeletonData fromBinary(Atlas atlas, Uint8List binary) {
final Pointer<Uint8> binaryNative = malloc.allocate(binary.lengthInBytes);
final Pointer<Uint8> binaryNative = _allocator.allocate(binary.lengthInBytes);
binaryNative.asTypedList(binary.lengthInBytes).setAll(0, binary);
final result = _bindings.spine_skeleton_data_load_binary(atlas._atlas, binaryNative.cast(), binary.lengthInBytes);
malloc.free(binaryNative);
if (result.error.address != nullptr.address) {
final Pointer<Utf8> error = result.error.cast();
_allocator.free(binaryNative);
if (_bindings.spine_skeleton_data_result_get_error(result).address != nullptr.address) {
final Pointer<Utf8> error = _bindings.spine_skeleton_data_result_get_error(result).cast();
final message = error.toDartString();
malloc.free(error);
_bindings.spine_skeleton_data_result_dispose(result);
throw Exception("Couldn't load skeleton data: $message");
}
return SkeletonData._(result.skeletonData);
var data = SkeletonData._(_bindings.spine_skeleton_data_result_get_data(result));
_bindings.spine_skeleton_data_result_dispose(result);
return data;
}
static Future<SkeletonData> fromAsset(AssetBundle assetBundle, Atlas atlas, String skeletonFile) async {
@ -169,18 +186,18 @@ class SkeletonData {
/// Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it multiple times.
BoneData? findBone(String name) {
final nativeName = name.toNativeUtf8();
final nativeName = name.toNativeUtf8(_allocator);
final bone = _bindings.spine_skeleton_data_find_bone(_data, nativeName.cast());
malloc.free(nativeName);
_allocator.free(nativeName);
if (bone.address == nullptr.address) return null;
return BoneData._(bone);
}
/// Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it multiple times.
SlotData? findSlot(String name) {
final nativeName = name.toNativeUtf8();
final nativeName = name.toNativeUtf8(_allocator);
final slot = _bindings.spine_skeleton_data_find_slot(_data, nativeName.cast());
malloc.free(nativeName);
_allocator.free(nativeName);
if (slot.address == nullptr.address) return null;
return SlotData._(slot);
}
@ -188,9 +205,9 @@ class SkeletonData {
/// Finds a skin by comparing each skin's name. It is more efficient to cache the results of this method than to call it
/// multiple times.
Skin? findSkin(String name) {
final nativeName = name.toNativeUtf8();
final nativeName = name.toNativeUtf8(_allocator);
final skin = _bindings.spine_skeleton_data_find_skin(_data, nativeName.cast());
malloc.free(nativeName);
_allocator.free(nativeName);
if (skin.address == nullptr.address) return null;
return Skin._(skin);
}
@ -198,9 +215,9 @@ class SkeletonData {
/// Finds an event by comparing each events's name. It is more efficient to cache the results of this method than to call it
/// multiple times.
EventData? findEvent(String name) {
final nativeName = name.toNativeUtf8();
final nativeName = name.toNativeUtf8(_allocator);
final event = _bindings.spine_skeleton_data_find_event(_data, nativeName.cast());
malloc.free(nativeName);
_allocator.free(nativeName);
if (event.address == nullptr.address) return null;
return EventData._(event);
}
@ -208,9 +225,9 @@ class SkeletonData {
/// Finds an animation by comparing each animation's name. It is more efficient to cache the results of this method than to
/// call it multiple times.
Animation? findAnimation(String name) {
final nativeName = name.toNativeUtf8();
final nativeName = name.toNativeUtf8(_allocator);
final animation = _bindings.spine_skeleton_data_find_animation(_data, nativeName.cast());
malloc.free(nativeName);
_allocator.free(nativeName);
if (animation.address == nullptr.address) return null;
return Animation._(animation);
}
@ -218,9 +235,9 @@ class SkeletonData {
/// Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method
/// than to call it multiple times.
IkConstraintData? findIkConstraint(String name) {
final nativeName = name.toNativeUtf8();
final nativeName = name.toNativeUtf8(_allocator);
final constraint = _bindings.spine_skeleton_data_find_ik_constraint(_data, nativeName.cast());
malloc.free(nativeName);
_allocator.free(nativeName);
if (constraint.address == nullptr.address) return null;
return IkConstraintData._(constraint);
}
@ -228,9 +245,9 @@ class SkeletonData {
/// Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of
/// this method than to call it multiple times.
TransformConstraintData? findTransformConstraint(String name) {
final nativeName = name.toNativeUtf8();
final nativeName = name.toNativeUtf8(_allocator);
final constraint = _bindings.spine_skeleton_data_find_transform_constraint(_data, nativeName.cast());
malloc.free(nativeName);
_allocator.free(nativeName);
if (constraint.address == nullptr.address) return null;
return TransformConstraintData._(constraint);
}
@ -238,9 +255,9 @@ class SkeletonData {
/// Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method
/// than to call it multiple times.
PathConstraintData? findPathConstraint(String name) {
final nativeName = name.toNativeUtf8();
final nativeName = name.toNativeUtf8(_allocator);
final constraint = _bindings.spine_skeleton_data_find_path_constraint(_data, nativeName.cast());
malloc.free(nativeName);
_allocator.free(nativeName);
if (constraint.address == nullptr.address) return null;
return PathConstraintData._(constraint);
}
@ -588,7 +605,11 @@ class BoneData {
Color getColor() {
final color = _bindings.spine_bone_data_get_color(_data);
return Color(color.r, color.g, color.b, color.a);
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color));
}
void setColor(double r, double g, double b, double a) {
@ -633,12 +654,16 @@ class Bone {
Vector2 worldToLocal(double worldX, double worldY) {
final local = _bindings.spine_bone_world_to_local(_bone, worldX, worldY);
return Vector2(local.x, local.y);
final result = Vector2(_bindings.spine_vector_get_x(local), _bindings.spine_vector_get_y(local));
_allocator.free(local);
return result;
}
Vector2 localToWorld(double localX, double localY) {
final world = _bindings.spine_bone_local_to_world(_bone, localX, localY);
return Vector2(world.x, world.y);
final result = Vector2(_bindings.spine_vector_get_x(world), _bindings.spine_vector_get_y(world));
_allocator.free(world);
return result;
}
double worldToLocalRotation(double worldRotation) {
@ -890,7 +915,11 @@ class SlotData {
Color getColor() {
final color = _bindings.spine_slot_data_get_color(_data);
return Color(color.r, color.g, color.b, color.a);
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color));
}
void setColor(double r, double g, double b, double a) {
@ -899,7 +928,11 @@ class SlotData {
Color getDarkColor() {
final color = _bindings.spine_slot_data_get_dark_color(_data);
return Color(color.r, color.g, color.b, color.a);
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color));
}
void setDarkColor(double r, double g, double b, double a) {
@ -920,9 +953,9 @@ class SlotData {
}
void setAttachmentName(String attachmentName) {
final nativeName = attachmentName.toNativeUtf8();
final nativeName = attachmentName.toNativeUtf8(_allocator);
_bindings.spine_slot_data_set_attachment_name(_data, nativeName.cast());
malloc.free(nativeName);
_allocator.free(nativeName);
}
BlendMode getBlendMode() {
@ -962,7 +995,11 @@ class Slot {
Color getColor() {
final color = _bindings.spine_slot_get_color(_slot);
return Color(color.r, color.g, color.b, color.a);
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color));
}
void setColor(Color color) {
@ -971,7 +1008,11 @@ class Slot {
Color getDarkColor() {
final color = _bindings.spine_slot_get_dark_color(_slot);
return Color(color.r, color.g, color.b, color.a);
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color));
}
void setDarkColor(Color color) {
@ -1118,11 +1159,11 @@ class Sequence {
}
String getPath(String basePath, int index) {
final nativeBasePath = basePath.toNativeUtf8();
final nativeBasePath = basePath.toNativeUtf8(_allocator);
final Pointer<Utf8> path = _bindings.spine_sequence_get_path(_sequence, nativeBasePath.cast(), index).cast();
final result = path.toDartString();
malloc.free(nativeBasePath);
malloc.free(path);
_allocator.free(nativeBasePath);
_allocator.free(path);
return result;
}
@ -1228,10 +1269,10 @@ class RegionAttachment extends Attachment<spine_region_attachment> {
RegionAttachment._(spine_region_attachment attachment) : super._(attachment);
List<double> computeWorldVertices(Slot slot) {
Pointer<Float> vertices = malloc.allocate(4 * 8).cast();
Pointer<Float> vertices = _allocator.allocate(4 * 8).cast();
_bindings.spine_region_attachment_compute_world_vertices(_attachment, slot._slot, vertices);
final result = vertices.asTypedList(8).toList();
malloc.free(vertices);
_allocator.free(vertices);
return result;
}
@ -1293,7 +1334,11 @@ class RegionAttachment extends Attachment<spine_region_attachment> {
Color getColor() {
final color = _bindings.spine_region_attachment_get_color(_attachment);
return Color(color.r, color.g, color.b, color.a);
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color));
}
void setColor(double r, double g, double b, double a) {
@ -1335,10 +1380,10 @@ class VertexAttachment<T extends Pointer> extends Attachment<T> {
List<double> computeWorldVertices(Slot slot) {
final worldVerticesLength = _bindings.spine_vertex_attachment_get_world_vertices_length(_attachment.cast());
Pointer<Float> vertices = malloc.allocate(4 * worldVerticesLength).cast();
Pointer<Float> vertices = _allocator.allocate(4 * worldVerticesLength).cast();
_bindings.spine_vertex_attachment_compute_world_vertices(_attachment.cast(), slot._slot, vertices);
final result = vertices.asTypedList(worldVerticesLength).toList();
malloc.free(vertices);
_allocator.free(vertices);
return result;
}
@ -1401,7 +1446,11 @@ class MeshAttachment extends VertexAttachment<spine_mesh_attachment> {
Color getColor() {
final color = _bindings.spine_mesh_attachment_get_color(_attachment);
return Color(color.r, color.g, color.b, color.a);
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color));
}
void setColor(double r, double g, double b, double a) {
@ -1473,7 +1522,11 @@ class ClippingAttachment extends VertexAttachment<spine_clipping_attachment> {
Color getColor() {
final color = _bindings.spine_clipping_attachment_get_color(_attachment);
return Color(color.r, color.g, color.b, color.a);
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color));
}
void setColor(double r, double g, double b, double a) {
@ -1486,7 +1539,11 @@ class BoundingBoxAttachment extends VertexAttachment<spine_bounding_box_attachme
Color getColor() {
final color = _bindings.spine_bounding_box_attachment_get_color(_attachment);
return Color(color.r, color.g, color.b, color.a);
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color));
}
void setColor(double r, double g, double b, double a) {
@ -1521,7 +1578,11 @@ class PathAttachment extends VertexAttachment<spine_path_attachment> {
Color getColor() {
final color = _bindings.spine_path_attachment_get_color(_attachment);
return Color(color.r, color.g, color.b, color.a);
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color));
}
void setColor(double r, double g, double b, double a) {
@ -1534,7 +1595,9 @@ class PointAttachment extends Attachment<spine_point_attachment> {
Vector2 computeWorldPosition(Bone bone) {
final position = _bindings.spine_point_attachment_compute_world_position(_attachment, bone._bone);
return Vector2(position.x, position.y);
final result = Vector2(_bindings.spine_vector_get_x(position), _bindings.spine_vector_get_y(position));
_allocator.free(position);
return result;
}
double computeWorldRotation(Bone bone) {
@ -1567,7 +1630,11 @@ class PointAttachment extends Attachment<spine_point_attachment> {
Color getColor() {
final color = _bindings.spine_point_attachment_get_color(_attachment);
return Color(color.r, color.g, color.b, color.a);
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color));
}
void setColor(double r, double g, double b, double a) {
@ -1590,9 +1657,9 @@ class Skin {
Skin._(this._skin) : _isCustomSkin = false;
Skin.new(String name) {
final nativeName = name.toNativeUtf8();
final nativeName = name.toNativeUtf8(_allocator);
_skin = _bindings.spine_skin_create(nativeName.cast());
malloc.free(nativeName);
_allocator.free(nativeName);
_isCustomSkin = true;
}
@ -1602,24 +1669,24 @@ class Skin {
}
void setAttachment(int slotIndex, String name, Attachment? attachment) {
final nativeName = name.toNativeUtf8();
final nativeName = name.toNativeUtf8(_allocator);
_bindings.spine_skin_set_attachment(
_skin, slotIndex, nativeName.cast(), attachment == null ? nullptr : attachment._attachment.cast());
malloc.free(nativeName);
_allocator.free(nativeName);
}
Attachment? getAttachment(int slotIndex, String name) {
final nativeName = name.toNativeUtf8();
final nativeName = name.toNativeUtf8(_allocator);
final attachment = _bindings.spine_skin_get_attachment(_skin, slotIndex, nativeName.cast());
malloc.free(nativeName);
_allocator.free(nativeName);
if (attachment.address == nullptr.address) return null;
return Attachment._toSubclass(attachment);
}
void removeAttachment(int slotIndex, String name) {
final nativeName = name.toNativeUtf8();
final nativeName = name.toNativeUtf8(_allocator);
_bindings.spine_skin_remove_attachment(_skin, slotIndex, nativeName.cast());
malloc.free(nativeName);
_allocator.free(nativeName);
}
String getName() {
@ -1634,12 +1701,12 @@ class Skin {
List<SkinEntry> getEntries() {
List<SkinEntry> result = [];
final entries = _bindings.spine_skin_get_entries(_skin);
int numEntries = entries.ref.numEntries;
int numEntries = _bindings.spine_skin_entries_get_num_entries(entries);
for (int i = 0; i < numEntries; i++) {
final entry = entries.ref.entries[i];
Pointer<Utf8> name = entry.name.cast();
result.add(SkinEntry(entry.slotIndex, name.toDartString(),
entry.attachment.address == nullptr.address ? null : Attachment._toSubclass(entry.attachment)));
final entry = _bindings.spine_skin_entries_get_entry(entries, i);
Pointer<Utf8> name = _bindings.spine_skin_entry_get_name(entry).cast();
result.add(SkinEntry(_bindings.spine_skin_entry_get_slot_index(entry), name.toDartString(),
_bindings.spine_skin_entry_get_attachment(entry).address == nullptr.address ? null : Attachment._toSubclass(_bindings.spine_skin_entry_get_attachment(entry))));
}
return result;
}
@ -2297,17 +2364,17 @@ class Skeleton {
}
Bone? findBone(String boneName) {
final nameNative = boneName.toNativeUtf8();
final nameNative = boneName.toNativeUtf8(_allocator);
final bone = _bindings.spine_skeleton_find_bone(_skeleton, nameNative.cast());
malloc.free(nameNative);
_allocator.free(nameNative);
if (bone.address == nullptr.address) return null;
return Bone._(bone);
}
Slot? findSlot(String slotName) {
final nameNative = slotName.toNativeUtf8();
final nameNative = slotName.toNativeUtf8(_allocator);
final slot = _bindings.spine_skeleton_find_slot(_skeleton, nameNative.cast());
malloc.free(nameNative);
_allocator.free(nameNative);
if (slot.address == nullptr.address) return null;
return Slot._(slot);
}
@ -2320,9 +2387,9 @@ class Skeleton {
/// skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin.
/// @param skinName May be NULL.
void setSkinByName(String skinName) {
final nameNative = skinName.toNativeUtf8();
final nameNative = skinName.toNativeUtf8(_allocator);
_bindings.spine_skeleton_set_skin_by_name(_skeleton, nameNative.cast());
malloc.free(nameNative);
_allocator.free(nameNative);
}
void setSkin(Skin skin) {
@ -2330,52 +2397,52 @@ class Skeleton {
}
Attachment? getAttachmentByName(String slotName, String attachmentName) {
final slotNameNative = slotName.toNativeUtf8();
final attachmentNameNative = attachmentName.toNativeUtf8();
final slotNameNative = slotName.toNativeUtf8(_allocator);
final attachmentNameNative = attachmentName.toNativeUtf8(_allocator);
final attachment =
_bindings.spine_skeleton_get_attachment_by_name(_skeleton, slotNameNative.cast(), attachmentNameNative.cast());
malloc.free(slotNameNative);
malloc.free(attachmentNameNative);
_allocator.free(slotNameNative);
_allocator.free(attachmentNameNative);
if (attachment.address == nullptr.address) return null;
return Attachment._toSubclass(attachment);
}
Attachment? getAttachment(int slotIndex, String attachmentName) {
final attachmentNameNative = attachmentName.toNativeUtf8();
final attachmentNameNative = attachmentName.toNativeUtf8(_allocator);
final attachment = _bindings.spine_skeleton_get_attachment(_skeleton, slotIndex, attachmentNameNative.cast());
malloc.free(attachmentNameNative);
_allocator.free(attachmentNameNative);
if (attachment.address == nullptr.address) return null;
return Attachment._toSubclass(attachment);
}
void setAttachment(String slotName, String attachmentName) {
final slotNameNative = slotName.toNativeUtf8();
final attachmentNameNative = attachmentName.toNativeUtf8();
final slotNameNative = slotName.toNativeUtf8(_allocator);
final attachmentNameNative = attachmentName.toNativeUtf8(_allocator);
_bindings.spine_skeleton_set_attachment(_skeleton, slotNameNative.cast(), attachmentNameNative.cast());
malloc.free(slotNameNative);
malloc.free(attachmentNameNative);
_allocator.free(slotNameNative);
_allocator.free(attachmentNameNative);
}
IkConstraint? findIkConstraint(String constraintName) {
final nameNative = constraintName.toNativeUtf8();
final nameNative = constraintName.toNativeUtf8(_allocator);
final constraint = _bindings.spine_skeleton_find_ik_constraint(_skeleton, nameNative.cast());
malloc.free(nameNative);
_allocator.free(nameNative);
if (constraint.address == nullptr.address) return null;
return IkConstraint._(constraint);
}
TransformConstraint? findTransformConstraint(String constraintName) {
final nameNative = constraintName.toNativeUtf8();
final nameNative = constraintName.toNativeUtf8(_allocator);
final constraint = _bindings.spine_skeleton_find_transform_constraint(_skeleton, nameNative.cast());
malloc.free(nameNative);
_allocator.free(nameNative);
if (constraint.address == nullptr.address) return null;
return TransformConstraint._(constraint);
}
PathConstraint? findPathConstraint(String constraintName) {
final nameNative = constraintName.toNativeUtf8();
final nameNative = constraintName.toNativeUtf8(_allocator);
final constraint = _bindings.spine_skeleton_find_path_constraint(_skeleton, nameNative.cast());
malloc.free(nameNative);
_allocator.free(nameNative);
if (constraint.address == nullptr.address) return null;
return PathConstraint._(constraint);
}
@ -2388,7 +2455,13 @@ class Skeleton {
/// @param outVertexBuffer Reference to hold a Vector of floats. This method will assign it with new floats as needed.
Bounds getBounds() {
final nativeBounds = _bindings.spine_skeleton_get_bounds(_skeleton);
return Bounds(nativeBounds.x, nativeBounds.y, nativeBounds.width, nativeBounds.height);
final bounds = Bounds(
_bindings.spine_bounds_get_x(nativeBounds),
_bindings.spine_bounds_get_y(nativeBounds),
_bindings.spine_bounds_get_width(nativeBounds),
_bindings.spine_bounds_get_height(nativeBounds));
_allocator.free(nativeBounds);
return bounds;
}
Bone? getRootBone() {
@ -2471,7 +2544,11 @@ class Skeleton {
Color getColor() {
final color = _bindings.spine_skeleton_get_color(_skeleton);
return Color(color.r, color.g, color.b, color.a);
return Color(
_bindings.spine_color_get_r(color),
_bindings.spine_color_get_g(color),
_bindings.spine_color_get_b(color),
_bindings.spine_color_get_a(color));
}
void setColor(Color color) {
@ -2848,9 +2925,9 @@ class EventData {
}
void setStringValue(String value) {
final nativeString = value.toNativeUtf8();
final nativeString = value.toNativeUtf8(_allocator);
_bindings.spine_event_data_set_string_value(_data, nativeString.cast());
malloc.free(nativeString);
_allocator.free(nativeString);
}
String getAudioPath() {
@ -2910,9 +2987,9 @@ class Event {
}
void setStringValue(String value) {
final nativeString = value.toNativeUtf8();
final nativeString = value.toNativeUtf8(_allocator);
_bindings.spine_event_set_string_value(_event, nativeString.cast());
malloc.free(nativeString);
_allocator.free(nativeString);
}
double getVolume() {
@ -2952,19 +3029,19 @@ class AnimationStateData {
}
void setMixByName(String fromName, String toName, double duration) {
final fromNative = fromName.toNativeUtf8();
final toNative = toName.toNativeUtf8();
final fromNative = fromName.toNativeUtf8(_allocator);
final toNative = toName.toNativeUtf8(_allocator);
_bindings.spine_animation_state_data_set_mix_by_name(_data, fromNative.cast(), toNative.cast(), duration);
malloc.free(fromNative);
malloc.free(toNative);
_allocator.free(fromNative);
_allocator.free(toNative);
}
double getMixByName(String fromName, String toName) {
final fromNative = fromName.toNativeUtf8();
final toNative = toName.toNativeUtf8();
final fromNative = fromName.toNativeUtf8(_allocator);
final toNative = toName.toNativeUtf8(_allocator);
final duration = _bindings.spine_animation_state_data_get_mix_by_name(_data, fromNative.cast(), toNative.cast());
malloc.free(fromNative);
malloc.free(toNative);
_allocator.free(fromNative);
_allocator.free(toNative);
return duration;
}
@ -3072,10 +3149,10 @@ class AnimationState {
/// A track entry to allow further customization of animation playback. References to the track entry must not be kept
/// after AnimationState.Dispose.
TrackEntry setAnimationByName(int trackIndex, String animationName, bool loop) {
final animation = animationName.toNativeUtf8();
final animation = animationName.toNativeUtf8(_allocator);
final entry =
_bindings.spine_animation_state_set_animation_by_name(_state, trackIndex, animation.cast(), loop ? -1 : 0);
malloc.free(animation);
_allocator.free(animation);
if (entry.address == nullptr.address) throw Exception("Couldn't set animation $animationName");
return TrackEntry._(entry, this);
}
@ -3096,10 +3173,10 @@ class AnimationState {
/// @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
/// after AnimationState.Dispose
TrackEntry addAnimationByName(int trackIndex, String animationName, bool loop, double delay) {
final animation = animationName.toNativeUtf8();
final animation = animationName.toNativeUtf8(_allocator);
final entry = _bindings.spine_animation_state_add_animation_by_name(
_state, trackIndex, animation.cast(), loop ? -1 : 0, delay);
malloc.free(animation);
_allocator.free(animation);
if (entry.address == nullptr.address) throw Exception("Couldn't add animation $animationName");
return TrackEntry._(entry, this);
}
@ -3167,7 +3244,7 @@ class AnimationState {
class SkeletonDrawable {
final Atlas atlas;
final SkeletonData skeletonData;
late final Pointer<spine_skeleton_drawable> _drawable;
late final spine_skeleton_drawable _drawable;
late final Skeleton skeleton;
late final AnimationStateData animationStateData;
late final AnimationState animationState;
@ -3176,12 +3253,11 @@ class SkeletonDrawable {
SkeletonDrawable(this.atlas, this.skeletonData, this._ownsAtlasAndSkeletonData) : _disposed = false {
_drawable = _bindings.spine_skeleton_drawable_create(skeletonData._data);
skeleton = Skeleton._(_drawable.ref.skeleton);
animationStateData = AnimationStateData._(_drawable.ref.animationStateData);
animationState = AnimationState._(_drawable.ref.animationState, _drawable.ref.animationStateEvents);
skeleton = Skeleton._(_bindings.spine_skeleton_drawable_get_skeleton(_drawable));
animationStateData = AnimationStateData._(_bindings.spine_skeleton_drawable_get_animation_state_data(_drawable));
animationState = AnimationState._(_bindings.spine_skeleton_drawable_get_animation_state(_drawable), _bindings.spine_skeleton_drawable_get_animation_state_events(_drawable));
}
static Future<SkeletonDrawable> fromAsset(String skeletonFile, String atlasFile) async {
var atlas = await Atlas.fromAsset(rootBundle, atlasFile);
var skeletonData = await SkeletonData.fromAsset(rootBundle, atlas, skeletonFile);
@ -3209,12 +3285,12 @@ class SkeletonDrawable {
List<RenderCommand> render() {
if (_disposed) return [];
Pointer<spine_render_command> nativeCmd = _bindings.spine_skeleton_drawable_render(_drawable);
spine_render_command nativeCmd = _bindings.spine_skeleton_drawable_render(_drawable);
List<RenderCommand> commands = [];
while (nativeCmd.address != nullptr.address) {
final atlasPage = atlas.atlasPages[nativeCmd.ref.atlasPage];
final atlasPage = atlas.atlasPages[_bindings.spine_render_command_get_atlas_page(nativeCmd)];
commands.add(RenderCommand._(nativeCmd, atlasPage.width.toDouble(), atlasPage.height.toDouble()));
nativeCmd = nativeCmd.ref.next;
nativeCmd = _bindings.spine_render_command_get_next(nativeCmd);
}
return commands;
}
@ -3242,40 +3318,38 @@ class RenderCommand {
late final Vertices vertices;
late final int atlasPageIndex;
RenderCommand._(Pointer<spine_render_command> nativeCmd, double pageWidth, double pageHeight) {
atlasPageIndex = nativeCmd.ref.atlasPage;
int numVertices = nativeCmd.ref.numVertices;
int numIndices = nativeCmd.ref.numIndices;
final positions = nativeCmd.ref.positions.asTypedList(numVertices * 2);
final uvs = nativeCmd.ref.uvs.asTypedList(numVertices * 2);
RenderCommand._(spine_render_command nativeCmd, double pageWidth, double pageHeight) {
atlasPageIndex = _bindings.spine_render_command_get_atlas_page(nativeCmd);
int numVertices = _bindings.spine_render_command_get_num_vertices(nativeCmd);
int numIndices = _bindings.spine_render_command_get_num_indices(nativeCmd);
final positions = _bindings.spine_render_command_get_positions(nativeCmd).asTypedList(numVertices * 2);
final uvs = _bindings.spine_render_command_get_uvs(nativeCmd).asTypedList(numVertices * 2);
for (int i = 0; i < numVertices * 2; i += 2) {
uvs[i] *= pageWidth;
uvs[i + 1] *= pageHeight;
}
// We pass the native data as views directly to Vertices.raw. According to the sources, the data
// is copied, so it doesn't matter that we free up the underlying memory on the next
// render call. See the implementation of Vertices.raw() here:
// https://github.com/flutter/engine/blob/5c60785b802ad2c8b8899608d949342d5c624952/lib/ui/painting/vertices.cc#L21
vertices = Vertices.raw(VertexMode.triangles, positions,
textureCoordinates: uvs,
colors: nativeCmd.ref.colors.asTypedList(numVertices),
indices: nativeCmd.ref.indices.asTypedList(numIndices));
}
}
final colors = _bindings.spine_render_command_get_colors(nativeCmd).asTypedList(numVertices);
final indices = _bindings.spine_render_command_get_indices(nativeCmd).asTypedList(numIndices);
const String _libName = 'spine_flutter';
final DynamicLibrary _dylib = () {
if (Platform.isMacOS || Platform.isIOS) {
return DynamicLibrary.open('$_libName.framework/$_libName');
if (!kIsWeb) {
// We pass the native data as views directly to Vertices.raw. According to the sources, the data
// is copied, so it doesn't matter that we free up the underlying memory on the next
// render call. See the implementation of Vertices.raw() here:
// https://github.com/flutter/engine/blob/5c60785b802ad2c8b8899608d949342d5c624952/lib/ui/painting/vertices.cc#L21
vertices = Vertices.raw(VertexMode.triangles, positions,
textureCoordinates: uvs,
colors: _bindings.spine_render_command_get_colors(nativeCmd).asTypedList(numVertices),
indices: _bindings.spine_render_command_get_indices(nativeCmd).asTypedList(numIndices));
} else {
// On the web, rendering is done through CanvasKit, which requires copies of the native data.
final positionsCopy = Float32List.fromList(positions);
final uvsCopy = Float32List.fromList(uvs);
final colorsCopy = Int32List.fromList(colors);
final indicesCopy = Uint16List.fromList(indices);
vertices = Vertices.raw(VertexMode.triangles, positionsCopy,
textureCoordinates: uvsCopy,
colors: colorsCopy,
indices: indicesCopy);
}
}
if (Platform.isAndroid || Platform.isLinux) {
return DynamicLibrary.open('lib$_libName.so');
}
if (Platform.isWindows) {
return DynamicLibrary.open('$_libName.dll');
}
throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}');
}();
final SpineFlutterBindings _bindings = SpineFlutterBindings(_dylib);
}

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,8 @@ dependencies:
sdk: flutter
plugin_platform_interface: ^2.0.2
ffi: ^2.0.1
web_ffi: ^0.7.2
inject_js: ^2.0.0
http: ^0.13.5
dev_dependencies:

View File

@ -0,0 +1,5 @@
#!/bin/sh
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
pushd $dir > /dev/null
emcc -Ispine-cpp/include --closure 1 -O3 -fno-rtti -fno-exceptions -s MAIN_MODULE=1 -s EXPORT_NAME=libspine_flutter -s MODULARIZE=1 spine_flutter.cpp `find spine-cpp/src -type f` -o ../lib/assets/libspine_flutter.js
popd

File diff suppressed because it is too large Load Diff

View File

@ -82,18 +82,17 @@ SPINE_OPAQUE_TYPE(spine_event)
SPINE_OPAQUE_TYPE(spine_event_data)
SPINE_OPAQUE_TYPE(spine_track_entry)
SPINE_OPAQUE_TYPE(spine_animation)
SPINE_OPAQUE_TYPE(spine_atlas)
SPINE_OPAQUE_TYPE(spine_skeleton_data_result)
SPINE_OPAQUE_TYPE(spine_render_command)
SPINE_OPAQUE_TYPE(spine_bounds)
SPINE_OPAQUE_TYPE(spine_color)
SPINE_OPAQUE_TYPE(spine_vector)
SPINE_OPAQUE_TYPE(spine_skeleton_drawable)
SPINE_OPAQUE_TYPE(spine_skin_entry)
SPINE_OPAQUE_TYPE(spine_skin_entries)
typedef struct spine_atlas {
void *atlas;
char **imagePaths;
int numImagePaths;
char *error;
} spine_atlas;
typedef struct spine_skeleton_data_result {
spine_skeleton_data skeletonData;
char *error;
} spine_skeleton_data_result;
typedef uint8_t utf8;
typedef enum spine_blend_mode {
SPINE_BLEND_MODE_NORMAL = 0,
@ -159,86 +158,61 @@ typedef enum spine_rotate_mode {
SPINE_ROTATE_MODE_CHAIN_SCALE
} spine_rotate_mode;
typedef struct spine_render_command {
float *positions;
float *uvs;
int32_t *colors;
int numVertices;
uint16_t *indices;
int numIndices;
int atlasPage;
spine_blend_mode blendMode;
struct spine_render_command *next;
} spine_render_command;
typedef struct spine_bounds {
float x, y, width, height;
} spine_bounds;
typedef struct spine_color {
float r, g, b, a;
} spine_color;
typedef struct spine_vector {
float x, y;
} spine_vector;
typedef struct spine_skeleton_drawable {
spine_skeleton skeleton;
spine_animation_state animationState;
spine_animation_state_data animationStateData;
spine_animation_state_events animationStateEvents;
void *clipping;
spine_render_command *renderCommand;
} spine_skeleton_drawable;
typedef struct spine_skin_entry {
int slotIndex;
const char* name;
spine_attachment attachment;
} spine_skin_entry;
typedef struct spine_skin_entries {
int numEntries;
spine_skin_entry* entries;
} spine_skin_entries;
FFI_PLUGIN_EXPORT int spine_major_version();
FFI_PLUGIN_EXPORT int spine_minor_version();
FFI_PLUGIN_EXPORT int32_t spine_major_version();
FFI_PLUGIN_EXPORT int32_t spine_minor_version();
FFI_PLUGIN_EXPORT void spine_report_leaks();
FFI_PLUGIN_EXPORT spine_atlas* spine_atlas_load(const char *atlasData);
FFI_PLUGIN_EXPORT void spine_atlas_dispose(spine_atlas *atlas);
FFI_PLUGIN_EXPORT float spine_color_get_r(spine_color color);
FFI_PLUGIN_EXPORT float spine_color_get_g(spine_color color);
FFI_PLUGIN_EXPORT float spine_color_get_b(spine_color color);
FFI_PLUGIN_EXPORT float spine_color_get_a(spine_color color);
FFI_PLUGIN_EXPORT spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas *atlas, const char *skeletonData);
FFI_PLUGIN_EXPORT spine_skeleton_data_result spine_skeleton_data_load_binary(spine_atlas *atlas, const unsigned char *skeletonData, int length);
FFI_PLUGIN_EXPORT spine_bone_data spine_skeleton_data_find_bone(spine_skeleton_data data, const char *name);
FFI_PLUGIN_EXPORT spine_slot_data spine_skeleton_data_find_slot(spine_skeleton_data data, const char *name);
FFI_PLUGIN_EXPORT spine_skin spine_skeleton_data_find_skin(spine_skeleton_data data, const char *name);
FFI_PLUGIN_EXPORT spine_event_data spine_skeleton_data_find_event(spine_skeleton_data data, const char *name);
FFI_PLUGIN_EXPORT spine_animation spine_skeleton_data_find_animation(spine_skeleton_data data, const char *name);
FFI_PLUGIN_EXPORT spine_ik_constraint_data spine_skeleton_data_find_ik_constraint(spine_skeleton_data data, const char *name);
FFI_PLUGIN_EXPORT spine_transform_constraint_data spine_skeleton_data_find_transform_constraint(spine_skeleton_data data, const char *name);
FFI_PLUGIN_EXPORT spine_path_constraint_data spine_skeleton_data_find_path_constraint(spine_skeleton_data data, const char *name);
FFI_PLUGIN_EXPORT const char* spine_skeleton_data_get_name(spine_skeleton_data data);
FFI_PLUGIN_EXPORT float spine_bounds_get_x(spine_bounds bounds);
FFI_PLUGIN_EXPORT float spine_bounds_get_y(spine_bounds bounds);
FFI_PLUGIN_EXPORT float spine_bounds_get_width(spine_bounds bounds);
FFI_PLUGIN_EXPORT float spine_bounds_get_height(spine_bounds bounds);
FFI_PLUGIN_EXPORT float spine_vector_get_x(spine_vector vector);
FFI_PLUGIN_EXPORT float spine_vector_get_y(spine_vector vector);
FFI_PLUGIN_EXPORT spine_atlas spine_atlas_load(const utf8 *atlasData);
FFI_PLUGIN_EXPORT int32_t spine_atlas_get_num_image_paths(spine_atlas atlas);
FFI_PLUGIN_EXPORT utf8 *spine_atlas_get_image_path(spine_atlas atlas, int32_t index);
FFI_PLUGIN_EXPORT utf8 *spine_atlas_get_error(spine_atlas atlas);
FFI_PLUGIN_EXPORT void spine_atlas_dispose(spine_atlas atlas);
FFI_PLUGIN_EXPORT spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, const utf8 *skeletonData);
FFI_PLUGIN_EXPORT spine_skeleton_data_result spine_skeleton_data_load_binary(spine_atlas atlas, const uint8_t *skeletonData, int32_t length);
FFI_PLUGIN_EXPORT utf8 *spine_skeleton_data_result_get_error(spine_skeleton_data_result result);
FFI_PLUGIN_EXPORT spine_skeleton_data spine_skeleton_data_result_get_data(spine_skeleton_data_result result);
FFI_PLUGIN_EXPORT void spine_skeleton_data_result_dispose(spine_skeleton_data_result result);
FFI_PLUGIN_EXPORT spine_bone_data spine_skeleton_data_find_bone(spine_skeleton_data data, const utf8 *name);
FFI_PLUGIN_EXPORT spine_slot_data spine_skeleton_data_find_slot(spine_skeleton_data data, const utf8 *name);
FFI_PLUGIN_EXPORT spine_skin spine_skeleton_data_find_skin(spine_skeleton_data data, const utf8 *name);
FFI_PLUGIN_EXPORT spine_event_data spine_skeleton_data_find_event(spine_skeleton_data data, const utf8 *name);
FFI_PLUGIN_EXPORT spine_animation spine_skeleton_data_find_animation(spine_skeleton_data data, const utf8 *name);
FFI_PLUGIN_EXPORT spine_ik_constraint_data spine_skeleton_data_find_ik_constraint(spine_skeleton_data data, const utf8 *name);
FFI_PLUGIN_EXPORT spine_transform_constraint_data spine_skeleton_data_find_transform_constraint(spine_skeleton_data data, const utf8 *name);
FFI_PLUGIN_EXPORT spine_path_constraint_data spine_skeleton_data_find_path_constraint(spine_skeleton_data data, const utf8 *name);
FFI_PLUGIN_EXPORT const utf8* spine_skeleton_data_get_name(spine_skeleton_data data);
// OMITTED setName()
FFI_PLUGIN_EXPORT int spine_skeleton_data_get_num_bones(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_bones(spine_skeleton_data data);
FFI_PLUGIN_EXPORT spine_bone_data* spine_skeleton_data_get_bones(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int spine_skeleton_data_get_num_slots(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_slots(spine_skeleton_data data);
FFI_PLUGIN_EXPORT spine_slot_data* spine_skeleton_data_get_slots(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int spine_skeleton_data_get_num_skins(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_skins(spine_skeleton_data data);
FFI_PLUGIN_EXPORT spine_skin* spine_skeleton_data_get_skins(spine_skeleton_data data);
FFI_PLUGIN_EXPORT spine_skin spine_skeleton_data_get_default_skin(spine_skeleton_data data);
FFI_PLUGIN_EXPORT void spine_skeleton_data_set_default_skin(spine_skeleton_data data, spine_skin skin);
FFI_PLUGIN_EXPORT int spine_skeleton_data_get_num_events(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_events(spine_skeleton_data data);
FFI_PLUGIN_EXPORT spine_event_data* spine_skeleton_data_get_events(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int spine_skeleton_data_get_num_animations(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_animations(spine_skeleton_data data);
FFI_PLUGIN_EXPORT spine_animation* spine_skeleton_data_get_animations(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int spine_skeleton_data_get_num_ik_constraints(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_ik_constraints(spine_skeleton_data data);
FFI_PLUGIN_EXPORT spine_ik_constraint_data* spine_skeleton_data_get_ik_constraints(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int spine_skeleton_data_get_num_transform_constraints(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_transform_constraints(spine_skeleton_data data);
FFI_PLUGIN_EXPORT spine_transform_constraint_data* spine_skeleton_data_get_transform_constraints(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int spine_skeleton_data_get_num_path_constraints(spine_skeleton_data data);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_path_constraints(spine_skeleton_data data);
FFI_PLUGIN_EXPORT spine_path_constraint_data* spine_skeleton_data_get_path_constraints(spine_skeleton_data data);
FFI_PLUGIN_EXPORT float spine_skeleton_data_get_x(spine_skeleton_data data);
FFI_PLUGIN_EXPORT void spine_skeleton_data_set_x(spine_skeleton_data data, float x);
@ -248,23 +222,37 @@ FFI_PLUGIN_EXPORT float spine_skeleton_data_get_width(spine_skeleton_data data);
FFI_PLUGIN_EXPORT void spine_skeleton_data_set_width(spine_skeleton_data data, float width);
FFI_PLUGIN_EXPORT float spine_skeleton_data_get_height(spine_skeleton_data data);
FFI_PLUGIN_EXPORT void spine_skeleton_data_set_height(spine_skeleton_data data, float height);
FFI_PLUGIN_EXPORT const char* spine_skeleton_data_get_version(spine_skeleton_data data);
FFI_PLUGIN_EXPORT const utf8 *spine_skeleton_data_get_version(spine_skeleton_data data);
// OMITTED setVersion()
FFI_PLUGIN_EXPORT const char* spine_skeleton_data_get_hash(spine_skeleton_data data);
FFI_PLUGIN_EXPORT const utf8 *spine_skeleton_data_get_hash(spine_skeleton_data data);
// OMITTED setHash()
FFI_PLUGIN_EXPORT const char* spine_skeleton_data_get_images_path(spine_skeleton_data data);
FFI_PLUGIN_EXPORT const utf8 *spine_skeleton_data_get_images_path(spine_skeleton_data data);
// OMITTED setImagesPath()
FFI_PLUGIN_EXPORT const char* spine_skeleton_data_get_audio_path(spine_skeleton_data data);
FFI_PLUGIN_EXPORT const utf8 *spine_skeleton_data_get_audio_path(spine_skeleton_data data);
// OMITTED setAudioPath()
FFI_PLUGIN_EXPORT float spine_skeleton_data_get_fps(spine_skeleton_data data);
// OMITTED setFps()
FFI_PLUGIN_EXPORT void spine_skeleton_data_dispose(spine_skeleton_data data);
FFI_PLUGIN_EXPORT spine_skeleton_drawable *spine_skeleton_drawable_create(spine_skeleton_data skeletonData);
FFI_PLUGIN_EXPORT spine_render_command *spine_skeleton_drawable_render(spine_skeleton_drawable *drawable);
FFI_PLUGIN_EXPORT void spine_skeleton_drawable_dispose(spine_skeleton_drawable *drawable);
FFI_PLUGIN_EXPORT spine_skeleton_drawable spine_skeleton_drawable_create(spine_skeleton_data skeletonData);
FFI_PLUGIN_EXPORT spine_render_command spine_skeleton_drawable_render(spine_skeleton_drawable drawable);
FFI_PLUGIN_EXPORT void spine_skeleton_drawable_dispose(spine_skeleton_drawable drawable);
FFI_PLUGIN_EXPORT spine_skeleton spine_skeleton_drawable_get_skeleton(spine_skeleton_drawable drawable);
FFI_PLUGIN_EXPORT spine_animation_state spine_skeleton_drawable_get_animation_state(spine_skeleton_drawable drawable);
FFI_PLUGIN_EXPORT spine_animation_state_data spine_skeleton_drawable_get_animation_state_data(spine_skeleton_drawable drawable);
FFI_PLUGIN_EXPORT spine_animation_state_events spine_skeleton_drawable_get_animation_state_events(spine_skeleton_drawable drawable);
FFI_PLUGIN_EXPORT const char* spine_animation_get_name(spine_animation animation);
FFI_PLUGIN_EXPORT float *spine_render_command_get_positions(spine_render_command command);
FFI_PLUGIN_EXPORT float *spine_render_command_get_uvs(spine_render_command command);
FFI_PLUGIN_EXPORT int32_t *spine_render_command_get_colors(spine_render_command command);
FFI_PLUGIN_EXPORT int32_t spine_render_command_get_num_vertices(spine_render_command command);
FFI_PLUGIN_EXPORT uint16_t *spine_render_command_get_indices(spine_render_command command);
FFI_PLUGIN_EXPORT int32_t spine_render_command_get_num_indices(spine_render_command command);
FFI_PLUGIN_EXPORT int32_t spine_render_command_get_atlas_page(spine_render_command command);
FFI_PLUGIN_EXPORT spine_blend_mode spine_render_command_get_blend_mode(spine_render_command command);
FFI_PLUGIN_EXPORT spine_render_command spine_render_command_get_next(spine_render_command command);
FFI_PLUGIN_EXPORT const utf8* spine_animation_get_name(spine_animation animation);
// OMITTED getTimelines()
// OMITTED hasTimeline()
FFI_PLUGIN_EXPORT float spine_animation_get_duration(spine_animation animation);
@ -275,23 +263,23 @@ FFI_PLUGIN_EXPORT float spine_animation_state_data_get_default_mix(spine_animati
FFI_PLUGIN_EXPORT void spine_animation_state_data_set_default_mix(spine_animation_state_data stateData, float defaultMix);
FFI_PLUGIN_EXPORT void spine_animation_state_data_set_mix(spine_animation_state_data stateData, spine_animation from, spine_animation to, float duration);
FFI_PLUGIN_EXPORT float spine_animation_state_data_get_mix(spine_animation_state_data stateData, spine_animation from, spine_animation to);
FFI_PLUGIN_EXPORT void spine_animation_state_data_set_mix_by_name(spine_animation_state_data stateData, const char* fromName, const char* toName, float duration);
FFI_PLUGIN_EXPORT float spine_animation_state_data_get_mix_by_name(spine_animation_state_data stateData, const char* fromName, const char* toName);
FFI_PLUGIN_EXPORT void spine_animation_state_data_set_mix_by_name(spine_animation_state_data stateData, const utf8* fromName, const utf8* toName, float duration);
FFI_PLUGIN_EXPORT float spine_animation_state_data_get_mix_by_name(spine_animation_state_data stateData, const utf8* fromName, const utf8* toName);
FFI_PLUGIN_EXPORT void spine_animation_state_data_clear(spine_animation_state_data stateData);
FFI_PLUGIN_EXPORT void spine_animation_state_update(spine_animation_state state, float delta);
FFI_PLUGIN_EXPORT void spine_animation_state_apply(spine_animation_state state, spine_skeleton skeleton);
FFI_PLUGIN_EXPORT void spine_animation_state_clear_tracks(spine_animation_state state);
FFI_PLUGIN_EXPORT void spine_animation_state_clear_track(spine_animation_state state, int trackIndex);
FFI_PLUGIN_EXPORT int spine_animation_state_get_num_tracks(spine_animation_state state);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_set_animation_by_name(spine_animation_state state, int trackIndex, const char* animationName, int loop);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_set_animation(spine_animation_state state, int trackIndex, spine_animation animation, int loop);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_add_animation_by_name(spine_animation_state state, int trackIndex, const char* animationName, int loop, float delay);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_add_animation(spine_animation_state state, int trackIndex, spine_animation animation, int loop, float delay);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_set_empty_animation(spine_animation_state state, int trackIndex, float mixDuration);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_add_empty_animation(spine_animation_state state, int trackIndex, float mixDuration, float delay);
FFI_PLUGIN_EXPORT void spine_animation_state_clear_track(spine_animation_state state, int32_t trackIndex);
FFI_PLUGIN_EXPORT int32_t spine_animation_state_get_num_tracks(spine_animation_state state);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_set_animation_by_name(spine_animation_state state, int32_t trackIndex, const utf8* animationName, int32_t loop);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_set_animation(spine_animation_state state, int32_t trackIndex, spine_animation animation, int32_t loop);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_add_animation_by_name(spine_animation_state state, int32_t trackIndex, const utf8* animationName, int32_t loop, float delay);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_add_animation(spine_animation_state state, int32_t trackIndex, spine_animation animation, int32_t loop, float delay);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_set_empty_animation(spine_animation_state state, int32_t trackIndex, float mixDuration);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_add_empty_animation(spine_animation_state state, int32_t trackIndex, float mixDuration, float delay);
FFI_PLUGIN_EXPORT void spine_animation_state_set_empty_animations(spine_animation_state state, float mixDuration);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_get_current(spine_animation_state state, int trackIndex);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_get_current(spine_animation_state state, int32_t trackIndex);
FFI_PLUGIN_EXPORT spine_animation_state_data spine_animation_state_get_data(spine_animation_state state);
FFI_PLUGIN_EXPORT float spine_animation_state_get_time_scale(spine_animation_state state);
FFI_PLUGIN_EXPORT void spine_animation_state_set_time_scale(spine_animation_state state, float timeScale);
@ -303,23 +291,23 @@ FFI_PLUGIN_EXPORT void spine_animation_state_set_time_scale(spine_animation_stat
// OMITTED getManualTrackEntryDisposal()
FFI_PLUGIN_EXPORT void spine_animation_state_dispose_track_entry(spine_animation_state state, spine_track_entry entry);
FFI_PLUGIN_EXPORT int spine_animation_state_events_get_num_events(spine_animation_state_events events);
FFI_PLUGIN_EXPORT spine_event_type spine_animation_state_events_get_event_type(spine_animation_state_events events, int index);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_events_get_track_entry(spine_animation_state_events events, int index);
FFI_PLUGIN_EXPORT spine_event spine_animation_state_events_get_event(spine_animation_state_events events, int index);
FFI_PLUGIN_EXPORT int32_t spine_animation_state_events_get_num_events(spine_animation_state_events events);
FFI_PLUGIN_EXPORT spine_event_type spine_animation_state_events_get_event_type(spine_animation_state_events events, int32_t index);
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_events_get_track_entry(spine_animation_state_events events, int32_t index);
FFI_PLUGIN_EXPORT spine_event spine_animation_state_events_get_event(spine_animation_state_events events, int32_t index);
FFI_PLUGIN_EXPORT void spine_animation_state_events_reset(spine_animation_state_events events);
FFI_PLUGIN_EXPORT int spine_track_entry_get_track_index(spine_track_entry entry);
FFI_PLUGIN_EXPORT int32_t spine_track_entry_get_track_index(spine_track_entry entry);
FFI_PLUGIN_EXPORT spine_animation spine_track_entry_get_animation(spine_track_entry entry);
FFI_PLUGIN_EXPORT spine_track_entry spine_track_entry_get_previous(spine_track_entry entry);
FFI_PLUGIN_EXPORT int spine_track_entry_get_loop(spine_track_entry entry);
FFI_PLUGIN_EXPORT void spine_track_entry_set_loop(spine_track_entry entry, int loop);
FFI_PLUGIN_EXPORT int spine_track_entry_get_hold_previous(spine_track_entry entry);
FFI_PLUGIN_EXPORT void spine_track_entry_set_hold_previous(spine_track_entry entry, int holdPrevious);
FFI_PLUGIN_EXPORT int spine_track_entry_get_reverse(spine_track_entry entry);
FFI_PLUGIN_EXPORT void spine_track_entry_set_reverse(spine_track_entry entry, int reverse);
FFI_PLUGIN_EXPORT int spine_track_entry_get_shortest_rotation(spine_track_entry entry);
FFI_PLUGIN_EXPORT void spine_track_entry_set_shortest_rotation(spine_track_entry entry, int shortestRotation);
FFI_PLUGIN_EXPORT int32_t spine_track_entry_get_loop(spine_track_entry entry);
FFI_PLUGIN_EXPORT void spine_track_entry_set_loop(spine_track_entry entry, int32_t loop);
FFI_PLUGIN_EXPORT int32_t spine_track_entry_get_hold_previous(spine_track_entry entry);
FFI_PLUGIN_EXPORT void spine_track_entry_set_hold_previous(spine_track_entry entry, int32_t holdPrevious);
FFI_PLUGIN_EXPORT int32_t spine_track_entry_get_reverse(spine_track_entry entry);
FFI_PLUGIN_EXPORT void spine_track_entry_set_reverse(spine_track_entry entry, int32_t reverse);
FFI_PLUGIN_EXPORT int32_t spine_track_entry_get_shortest_rotation(spine_track_entry entry);
FFI_PLUGIN_EXPORT void spine_track_entry_set_shortest_rotation(spine_track_entry entry, int32_t shortestRotation);
FFI_PLUGIN_EXPORT float spine_track_entry_get_delay(spine_track_entry entry);
FFI_PLUGIN_EXPORT void spine_track_entry_set_delay(spine_track_entry entry, float delay);
FFI_PLUGIN_EXPORT float spine_track_entry_get_track_time(spine_track_entry entry);
@ -344,7 +332,7 @@ FFI_PLUGIN_EXPORT void spine_track_entry_set_attachment_threshold(spine_track_en
FFI_PLUGIN_EXPORT float spine_track_entry_get_draw_order_threshold(spine_track_entry entry);
FFI_PLUGIN_EXPORT void spine_track_entry_set_draw_order_threshold(spine_track_entry entry, float drawOrderThreshold);
FFI_PLUGIN_EXPORT spine_track_entry spine_track_entry_get_next(spine_track_entry entry);
FFI_PLUGIN_EXPORT int spine_track_entry_is_complete(spine_track_entry entry);
FFI_PLUGIN_EXPORT int32_t spine_track_entry_is_complete(spine_track_entry entry);
FFI_PLUGIN_EXPORT float spine_track_entry_get_mix_time(spine_track_entry entry);
FFI_PLUGIN_EXPORT void spine_track_entry_set_mix_time(spine_track_entry entry, float mixTime);
FFI_PLUGIN_EXPORT float spine_track_entry_get_mix_duration(spine_track_entry entry);
@ -365,31 +353,31 @@ FFI_PLUGIN_EXPORT void spine_skeleton_update_world_transform_bone(spine_skeleton
FFI_PLUGIN_EXPORT void spine_skeleton_set_to_setup_pose(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT void spine_skeleton_set_bones_to_setup_pose(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT void spine_skeleton_set_slots_to_setup_pose(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT spine_bone spine_skeleton_find_bone(spine_skeleton skeleton, const char* boneName);
FFI_PLUGIN_EXPORT spine_slot spine_skeleton_find_slot(spine_skeleton skeleton, const char* slotName);
FFI_PLUGIN_EXPORT void spine_skeleton_set_skin_by_name(spine_skeleton skeleton, const char* skinName);
FFI_PLUGIN_EXPORT spine_bone spine_skeleton_find_bone(spine_skeleton skeleton, const utf8* boneName);
FFI_PLUGIN_EXPORT spine_slot spine_skeleton_find_slot(spine_skeleton skeleton, const utf8* slotName);
FFI_PLUGIN_EXPORT void spine_skeleton_set_skin_by_name(spine_skeleton skeleton, const utf8* skinName);
FFI_PLUGIN_EXPORT void spine_skeleton_set_skin(spine_skeleton skeleton, spine_skin skin);
FFI_PLUGIN_EXPORT spine_attachment spine_skeleton_get_attachment_by_name(spine_skeleton skeleton, const char* slotName, const char* attachmentName);
FFI_PLUGIN_EXPORT spine_attachment spine_skeleton_get_attachment(spine_skeleton skeleton, int slotIndex, const char* attachmentName);
FFI_PLUGIN_EXPORT void spine_skeleton_set_attachment(spine_skeleton skeleton, const char* slotName, const char* attachmentName);
FFI_PLUGIN_EXPORT spine_ik_constraint spine_skeleton_find_ik_constraint(spine_skeleton skeleton, const char* constraintName);
FFI_PLUGIN_EXPORT spine_transform_constraint spine_skeleton_find_transform_constraint(spine_skeleton skeleton, const char* constraintName);
FFI_PLUGIN_EXPORT spine_path_constraint spine_skeleton_find_path_constraint(spine_skeleton skeleton, const char* constraintName);
FFI_PLUGIN_EXPORT spine_attachment spine_skeleton_get_attachment_by_name(spine_skeleton skeleton, const utf8* slotName, const utf8* attachmentName);
FFI_PLUGIN_EXPORT spine_attachment spine_skeleton_get_attachment(spine_skeleton skeleton, int32_t slotIndex, const utf8* attachmentName);
FFI_PLUGIN_EXPORT void spine_skeleton_set_attachment(spine_skeleton skeleton, const utf8* slotName, const utf8* attachmentName);
FFI_PLUGIN_EXPORT spine_ik_constraint spine_skeleton_find_ik_constraint(spine_skeleton skeleton, const utf8* constraintName);
FFI_PLUGIN_EXPORT spine_transform_constraint spine_skeleton_find_transform_constraint(spine_skeleton skeleton, const utf8* constraintName);
FFI_PLUGIN_EXPORT spine_path_constraint spine_skeleton_find_path_constraint(spine_skeleton skeleton, const utf8* constraintName);
FFI_PLUGIN_EXPORT spine_bounds spine_skeleton_get_bounds(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT spine_bone spine_skeleton_get_root_bone(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT spine_skeleton_data spine_skeleton_get_data(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT int spine_skeleton_get_num_bones(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_get_num_bones(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT spine_bone* spine_skeleton_get_bones(spine_skeleton skeleton);
// OMITTED getUpdateCacheList()
FFI_PLUGIN_EXPORT int spine_skeleton_get_num_slots(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_get_num_slots(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT spine_slot* spine_skeleton_get_slots(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT int spine_skeleton_get_num_draw_order(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_get_num_draw_order(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT spine_slot* spine_skeleton_get_draw_order(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT int spine_skeleton_get_num_ik_constraints(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_get_num_ik_constraints(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT spine_ik_constraint* spine_skeleton_get_ik_constraints(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT int spine_skeleton_get_num_transform_constraints(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_get_num_transform_constraints(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT spine_transform_constraint* spine_skeleton_get_transform_constraints(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT int spine_skeleton_get_num_path_constraints(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT int32_t spine_skeleton_get_num_path_constraints(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT spine_path_constraint* spine_skeleton_get_path_constraints(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT spine_skin spine_skeleton_get_skin(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT spine_color spine_skeleton_get_color(spine_skeleton skeleton);
@ -404,14 +392,14 @@ FFI_PLUGIN_EXPORT void spine_skeleton_set_scale_x(spine_skeleton skeleton, float
FFI_PLUGIN_EXPORT float spine_skeleton_get_scale_y(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT void spine_skeleton_set_scale_y(spine_skeleton skeleton, float scaleY);
FFI_PLUGIN_EXPORT const char* spine_event_data_get_name(spine_event_data event);
FFI_PLUGIN_EXPORT int spine_event_data_get_int_value(spine_event_data event);
FFI_PLUGIN_EXPORT void spine_event_data_set_int_value(spine_event_data event, int value);
FFI_PLUGIN_EXPORT const utf8* spine_event_data_get_name(spine_event_data event);
FFI_PLUGIN_EXPORT int32_t spine_event_data_get_int_value(spine_event_data event);
FFI_PLUGIN_EXPORT void spine_event_data_set_int_value(spine_event_data event, int32_t value);
FFI_PLUGIN_EXPORT float spine_event_data_get_float_value(spine_event_data event);
FFI_PLUGIN_EXPORT void spine_event_data_set_float_value(spine_event_data event, float value);
FFI_PLUGIN_EXPORT const char* spine_event_data_get_string_value(spine_event_data event);
FFI_PLUGIN_EXPORT void spine_event_data_set_string_value(spine_event_data event, const char *value);
FFI_PLUGIN_EXPORT const char* spine_event_data_get_audio_path(spine_event_data event);
FFI_PLUGIN_EXPORT const utf8* spine_event_data_get_string_value(spine_event_data event);
FFI_PLUGIN_EXPORT void spine_event_data_set_string_value(spine_event_data event, const utf8 *value);
FFI_PLUGIN_EXPORT const utf8* spine_event_data_get_audio_path(spine_event_data event);
// OMITTED setAudioPath()
FFI_PLUGIN_EXPORT float spine_event_data_get_volume(spine_event_data event);
FFI_PLUGIN_EXPORT void spine_event_data_set_volume(spine_event_data event, float volume);
@ -420,28 +408,28 @@ FFI_PLUGIN_EXPORT void spine_event_data_set_balance(spine_event_data event, floa
FFI_PLUGIN_EXPORT spine_event_data spine_event_get_data(spine_event event);
FFI_PLUGIN_EXPORT float spine_event_get_time(spine_event event);
FFI_PLUGIN_EXPORT int spine_event_get_int_value(spine_event event);
FFI_PLUGIN_EXPORT void spine_event_set_int_value(spine_event event, int value);
FFI_PLUGIN_EXPORT int32_t spine_event_get_int_value(spine_event event);
FFI_PLUGIN_EXPORT void spine_event_set_int_value(spine_event event, int32_t value);
FFI_PLUGIN_EXPORT float spine_event_get_float_value(spine_event event);
FFI_PLUGIN_EXPORT void spine_event_set_float_value(spine_event event, float value);
FFI_PLUGIN_EXPORT const char* spine_event_get_string_value(spine_event event);
FFI_PLUGIN_EXPORT void spine_event_set_string_value(spine_event event, const char *value);
FFI_PLUGIN_EXPORT const utf8* spine_event_get_string_value(spine_event event);
FFI_PLUGIN_EXPORT void spine_event_set_string_value(spine_event event, const utf8 *value);
FFI_PLUGIN_EXPORT float spine_event_get_volume(spine_event event);
FFI_PLUGIN_EXPORT void spine_event_set_volume(spine_event event, float volume);
FFI_PLUGIN_EXPORT float spine_event_get_balance(spine_event event);
FFI_PLUGIN_EXPORT void spine_event_set_balance(spine_event event, float balance);
FFI_PLUGIN_EXPORT int spine_slot_data_get_index(spine_slot_data slot);
FFI_PLUGIN_EXPORT const char* spine_slot_data_get_name(spine_slot_data slot);
FFI_PLUGIN_EXPORT int32_t spine_slot_data_get_index(spine_slot_data slot);
FFI_PLUGIN_EXPORT const utf8* spine_slot_data_get_name(spine_slot_data slot);
FFI_PLUGIN_EXPORT spine_bone_data spine_slot_data_get_bone_data(spine_slot_data slot);
FFI_PLUGIN_EXPORT spine_color spine_slot_data_get_color(spine_slot_data slot);
FFI_PLUGIN_EXPORT void spine_slot_data_set_color(spine_slot_data slot, float r, float g, float b, float a);
FFI_PLUGIN_EXPORT spine_color spine_slot_data_get_dark_color(spine_slot_data slot);
FFI_PLUGIN_EXPORT void spine_slot_data_set_dark_color(spine_slot_data slot, float r, float g, float b, float a);
FFI_PLUGIN_EXPORT int spine_slot_data_has_dark_color(spine_slot_data slot);
FFI_PLUGIN_EXPORT void spine_slot_data_set_has_dark_color(spine_slot_data slot, int hasDarkColor);
FFI_PLUGIN_EXPORT const char* spine_slot_data_get_attachment_name(spine_slot_data slot);
FFI_PLUGIN_EXPORT void spine_slot_data_set_attachment_name(spine_slot_data slot, const char *attachmentName);
FFI_PLUGIN_EXPORT int32_t spine_slot_data_has_dark_color(spine_slot_data slot);
FFI_PLUGIN_EXPORT void spine_slot_data_set_has_dark_color(spine_slot_data slot, int32_t hasDarkColor);
FFI_PLUGIN_EXPORT const utf8* spine_slot_data_get_attachment_name(spine_slot_data slot);
FFI_PLUGIN_EXPORT void spine_slot_data_set_attachment_name(spine_slot_data slot, const utf8 *attachmentName);
FFI_PLUGIN_EXPORT spine_blend_mode spine_slot_data_get_blend_mode(spine_slot_data slot);
FFI_PLUGIN_EXPORT void spine_slot_data_set_blend_mode(spine_slot_data slot, spine_blend_mode blendMode);
@ -453,16 +441,16 @@ FFI_PLUGIN_EXPORT spine_color spine_slot_get_color(spine_slot slot);
FFI_PLUGIN_EXPORT void spine_slot_set_color(spine_slot slot, float r, float g, float b, float a);
FFI_PLUGIN_EXPORT spine_color spine_slot_get_dark_color(spine_slot slot);
FFI_PLUGIN_EXPORT void spine_slot_set_dark_color(spine_slot slot, float r, float g, float b, float a);
FFI_PLUGIN_EXPORT int spine_slot_has_dark_color(spine_slot slot);
FFI_PLUGIN_EXPORT int32_t spine_slot_has_dark_color(spine_slot slot);
FFI_PLUGIN_EXPORT spine_attachment spine_slot_get_attachment(spine_slot slot);
FFI_PLUGIN_EXPORT void spine_slot_set_attachment(spine_slot slot, spine_attachment attachment);
// OMITTED getDeform()
FFI_PLUGIN_EXPORT int spine_slot_get_sequence_index(spine_slot slot);
FFI_PLUGIN_EXPORT void spine_slot_set_sequence_index(spine_slot slot, int sequenceIndex);
FFI_PLUGIN_EXPORT int32_t spine_slot_get_sequence_index(spine_slot slot);
FFI_PLUGIN_EXPORT void spine_slot_set_sequence_index(spine_slot slot, int32_t sequenceIndex);
FFI_PLUGIN_EXPORT int spine_bone_data_get_index(spine_bone_data data);
FFI_PLUGIN_EXPORT const char* spine_bone_data_get_name(spine_bone_data data);
FFI_PLUGIN_EXPORT int32_t spine_bone_data_get_index(spine_bone_data data);
FFI_PLUGIN_EXPORT const utf8* spine_bone_data_get_name(spine_bone_data data);
FFI_PLUGIN_EXPORT spine_bone_data spine_bone_data_get_parent(spine_bone_data data);
FFI_PLUGIN_EXPORT float spine_bone_data_get_length(spine_bone_data data);
FFI_PLUGIN_EXPORT void spine_bone_data_set_length(spine_bone_data data, float length);
@ -482,13 +470,13 @@ FFI_PLUGIN_EXPORT float spine_bone_data_get_shear_y(spine_bone_data data);
FFI_PLUGIN_EXPORT void spine_bone_data_set_shear_y(spine_bone_data data, float shearY);
FFI_PLUGIN_EXPORT spine_transform_mode spine_bone_data_get_transform_mode(spine_bone_data data);
FFI_PLUGIN_EXPORT void spine_bone_data_set_transform_mode(spine_bone_data data, spine_transform_mode mode);
FFI_PLUGIN_EXPORT int spine_bone_data_is_skin_required(spine_bone_data data);
FFI_PLUGIN_EXPORT void spine_bone_data_set_is_skin_required(spine_bone_data data, int isSkinRequired);
FFI_PLUGIN_EXPORT int32_t spine_bone_data_is_skin_required(spine_bone_data data);
FFI_PLUGIN_EXPORT void spine_bone_data_set_is_skin_required(spine_bone_data data, int32_t isSkinRequired);
FFI_PLUGIN_EXPORT spine_color spine_bone_data_get_color(spine_bone_data data);
FFI_PLUGIN_EXPORT void spine_bone_data_set_color(spine_bone_data data, float r, float g, float b, float a);
FFI_PLUGIN_EXPORT void spine_bone_set_is_y_down(int yDown);
FFI_PLUGIN_EXPORT int spine_bone_get_is_y_down();
FFI_PLUGIN_EXPORT void spine_bone_set_is_y_down(int32_t yDown);
FFI_PLUGIN_EXPORT int32_t spine_bone_get_is_y_down();
FFI_PLUGIN_EXPORT void spine_bone_update(spine_bone bone);
FFI_PLUGIN_EXPORT void spine_bone_update_world_transform(spine_bone bone);
FFI_PLUGIN_EXPORT void spine_bone_update_world_transform_with(spine_bone bone, float x, float y, float rotation, float scaleX, float scaleY, float shearX, float shearY);
@ -503,7 +491,7 @@ FFI_PLUGIN_EXPORT float spine_bone_get_world_to_local_rotation_y(spine_bone bone
FFI_PLUGIN_EXPORT spine_bone_data spine_bone_get_data(spine_bone bone);
FFI_PLUGIN_EXPORT spine_skeleton spine_bone_get_skeleton(spine_bone bone);
FFI_PLUGIN_EXPORT spine_bone spine_bone_get_parent(spine_bone bone);
FFI_PLUGIN_EXPORT int spine_bone_get_num_children(spine_bone bone);
FFI_PLUGIN_EXPORT int32_t spine_bone_get_num_children(spine_bone bone);
FFI_PLUGIN_EXPORT spine_bone* spine_bone_get_children(spine_bone bone);
FFI_PLUGIN_EXPORT float spine_bone_get_x(spine_bone bone);
FFI_PLUGIN_EXPORT void spine_bone_set_x(spine_bone bone, float x);
@ -549,10 +537,10 @@ FFI_PLUGIN_EXPORT float spine_bone_get_world_rotation_x(spine_bone bone);
FFI_PLUGIN_EXPORT float spine_bone_get_world_rotation_y(spine_bone bone);
FFI_PLUGIN_EXPORT float spine_bone_get_world_scale_x(spine_bone bone);
FFI_PLUGIN_EXPORT float spine_bone_get_world_scale_y(spine_bone bone);
FFI_PLUGIN_EXPORT int spine_bone_get_is_active(spine_bone bone);
FFI_PLUGIN_EXPORT void spine_bone_set_is_active(spine_bone bone, int isActive);
FFI_PLUGIN_EXPORT int32_t spine_bone_get_is_active(spine_bone bone);
FFI_PLUGIN_EXPORT void spine_bone_set_is_active(spine_bone bone, int32_t isActive);
FFI_PLUGIN_EXPORT const char* spine_attachment_get_name(spine_attachment attachment);
FFI_PLUGIN_EXPORT const utf8* spine_attachment_get_name(spine_attachment attachment);
FFI_PLUGIN_EXPORT spine_attachment_type spine_attachment_get_type(spine_attachment attachment);
FFI_PLUGIN_EXPORT spine_attachment spine_attachment_copy(spine_attachment attachment);
FFI_PLUGIN_EXPORT void spine_attachment_dispose(spine_attachment attachment);
@ -586,40 +574,40 @@ FFI_PLUGIN_EXPORT float spine_region_attachment_get_height(spine_region_attachme
FFI_PLUGIN_EXPORT void spine_region_attachment_set_height(spine_region_attachment attachment, float height);
FFI_PLUGIN_EXPORT spine_color spine_region_attachment_get_color(spine_region_attachment attachment);
FFI_PLUGIN_EXPORT void spine_region_attachment_set_color(spine_region_attachment attachment, float r, float g, float b, float a);
FFI_PLUGIN_EXPORT const char *spine_region_attachment_get_path(spine_region_attachment attachment);
FFI_PLUGIN_EXPORT const utf8 *spine_region_attachment_get_path(spine_region_attachment attachment);
// OMITTED setPath()
FFI_PLUGIN_EXPORT spine_texture_region spine_region_attachment_get_region(spine_region_attachment attachment);
// OMITTED setRegion()
FFI_PLUGIN_EXPORT spine_sequence spine_region_attachment_get_sequence(spine_region_attachment attachment);
// OMITTED setSequence()
FFI_PLUGIN_EXPORT int spine_region_attachment_get_num_offset(spine_region_attachment attachment);
FFI_PLUGIN_EXPORT int32_t spine_region_attachment_get_num_offset(spine_region_attachment attachment);
FFI_PLUGIN_EXPORT float *spine_region_attachment_get_offset(spine_region_attachment attachment);
FFI_PLUGIN_EXPORT int spine_region_attachment_get_num_uvs(spine_region_attachment attachment);
FFI_PLUGIN_EXPORT int32_t spine_region_attachment_get_num_uvs(spine_region_attachment attachment);
FFI_PLUGIN_EXPORT float *spine_region_attachment_get_uvs(spine_region_attachment attachment);
FFI_PLUGIN_EXPORT int spine_vertex_attachment_get_world_vertices_length(spine_vertex_attachment attachment);
FFI_PLUGIN_EXPORT int32_t spine_vertex_attachment_get_world_vertices_length(spine_vertex_attachment attachment);
FFI_PLUGIN_EXPORT void spine_vertex_attachment_compute_world_vertices(spine_vertex_attachment attachment, spine_slot slot, float *worldVertices);
// OMITTED getId()
FFI_PLUGIN_EXPORT int spine_vertex_attachment_get_num_bones(spine_vertex_attachment attachment);
FFI_PLUGIN_EXPORT int32_t spine_vertex_attachment_get_num_bones(spine_vertex_attachment attachment);
FFI_PLUGIN_EXPORT int32_t *spine_vertex_attachment_get_bones(spine_vertex_attachment attachment);
FFI_PLUGIN_EXPORT int spine_vertex_attachment_get_num_vertices(spine_vertex_attachment attachment);
FFI_PLUGIN_EXPORT int32_t spine_vertex_attachment_get_num_vertices(spine_vertex_attachment attachment);
FFI_PLUGIN_EXPORT float *spine_vertex_attachment_get_vertices(spine_vertex_attachment attachment);
FFI_PLUGIN_EXPORT spine_attachment spine_vertex_attachment_get_timeline_attachment(spine_vertex_attachment timelineAttachment);
FFI_PLUGIN_EXPORT void spine_vertex_attachment_set_timeline_attachment(spine_vertex_attachment attachment, spine_attachment timelineAttachment);
// OMITTED copyTo()
FFI_PLUGIN_EXPORT void spine_mesh_attachment_update_region(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT int spine_mesh_attachment_get_hull_length(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT void spine_mesh_attachment_set_hull_length(spine_mesh_attachment attachment, int hullLength);
FFI_PLUGIN_EXPORT int spine_mesh_attachment_get_num_region_uvs(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT int32_t spine_mesh_attachment_get_hull_length(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT void spine_mesh_attachment_set_hull_length(spine_mesh_attachment attachment, int32_t hullLength);
FFI_PLUGIN_EXPORT int32_t spine_mesh_attachment_get_num_region_uvs(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT float *spine_mesh_attachment_get_region_uvs(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT int spine_mesh_attachment_get_num_uvs(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT int32_t spine_mesh_attachment_get_num_uvs(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT float *spine_mesh_attachment_get_uvs(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT int spine_mesh_attachment_get_num_triangles(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT int32_t spine_mesh_attachment_get_num_triangles(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT uint16_t *spine_mesh_attachment_get_triangles(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT spine_color spine_mesh_attachment_get_color(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT void spine_mesh_attachment_set_color(spine_mesh_attachment attachment, float r, float g, float b, float a);
FFI_PLUGIN_EXPORT const char *spine_mesh_attachment_get_path(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT const utf8 *spine_mesh_attachment_get_path(spine_mesh_attachment attachment);
// OMITTED setPath()
FFI_PLUGIN_EXPORT spine_texture_region spine_mesh_attachment_get_region(spine_mesh_attachment attachment);
// OMITTED setRegion()
@ -627,7 +615,7 @@ FFI_PLUGIN_EXPORT spine_sequence spine_mesh_attachment_get_sequence(spine_mesh_a
// OMITTED setSequence()
FFI_PLUGIN_EXPORT spine_mesh_attachment spine_mesh_attachment_get_parent_mesh(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT void spine_mesh_attachment_set_parent_mesh(spine_mesh_attachment attachment, spine_mesh_attachment parentMesh);
FFI_PLUGIN_EXPORT int spine_mesh_attachment_get_num_edges(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT int32_t spine_mesh_attachment_get_num_edges(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT uint16_t *spine_mesh_attachment_get_edges(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT float spine_mesh_attachment_get_width(spine_mesh_attachment attachment);
FFI_PLUGIN_EXPORT void spine_mesh_attachment_set_width(spine_mesh_attachment attachment, float width);
@ -643,77 +631,82 @@ FFI_PLUGIN_EXPORT void spine_clipping_attachment_set_color(spine_clipping_attach
FFI_PLUGIN_EXPORT spine_color spine_bounding_box_attachment_get_color(spine_bounding_box_attachment attachment);
FFI_PLUGIN_EXPORT void spine_bounding_box_attachment_set_color(spine_bounding_box_attachment attachment, float r, float g, float b, float a);
FFI_PLUGIN_EXPORT int spine_path_attachment_get_num_lengths(spine_path_attachment attachment);
FFI_PLUGIN_EXPORT int32_t spine_path_attachment_get_num_lengths(spine_path_attachment attachment);
FFI_PLUGIN_EXPORT float *spine_path_attachment_get_lengths(spine_path_attachment attachment);
FFI_PLUGIN_EXPORT int spine_path_attachment_get_is_closed(spine_path_attachment attachment);
FFI_PLUGIN_EXPORT void spine_path_attachment_set_is_closed(spine_path_attachment attachment, int isClosed);
FFI_PLUGIN_EXPORT int spine_path_attachment_get_is_constant_speed(spine_path_attachment attachment);
FFI_PLUGIN_EXPORT void spine_path_attachment_set_is_constant_speed(spine_path_attachment attachment, int isConstantSpeed);
FFI_PLUGIN_EXPORT int32_t spine_path_attachment_get_is_closed(spine_path_attachment attachment);
FFI_PLUGIN_EXPORT void spine_path_attachment_set_is_closed(spine_path_attachment attachment, int32_t isClosed);
FFI_PLUGIN_EXPORT int32_t spine_path_attachment_get_is_constant_speed(spine_path_attachment attachment);
FFI_PLUGIN_EXPORT void spine_path_attachment_set_is_constant_speed(spine_path_attachment attachment, int32_t isConstantSpeed);
FFI_PLUGIN_EXPORT spine_color spine_path_attachment_get_color(spine_path_attachment attachment);
FFI_PLUGIN_EXPORT void spine_path_attachment_set_color(spine_path_attachment attachment, float r, float g, float b, float a);
FFI_PLUGIN_EXPORT void spine_skin_set_attachment(spine_skin skin, int slotIndex, const char* name, spine_attachment attachment);
FFI_PLUGIN_EXPORT spine_attachment spine_skin_get_attachment(spine_skin skin, int slotIndex, const char* name);
FFI_PLUGIN_EXPORT void spine_skin_remove_attachment(spine_skin skin, int slotIndex, const char* name);
FFI_PLUGIN_EXPORT void spine_skin_set_attachment(spine_skin skin, int32_t slotIndex, const utf8* name, spine_attachment attachment);
FFI_PLUGIN_EXPORT spine_attachment spine_skin_get_attachment(spine_skin skin, int32_t slotIndex, const utf8* name);
FFI_PLUGIN_EXPORT void spine_skin_remove_attachment(spine_skin skin, int32_t slotIndex, const utf8* name);
// OMITTED findNamesForSlot()
// OMITTED findAttachmentsForSlot()
FFI_PLUGIN_EXPORT const char* spine_skin_get_name(spine_skin skin);
FFI_PLUGIN_EXPORT const utf8* spine_skin_get_name(spine_skin skin);
FFI_PLUGIN_EXPORT void spine_skin_add_skin(spine_skin skin, spine_skin other);
FFI_PLUGIN_EXPORT void spine_skin_copy_skin(spine_skin skin, spine_skin other);
FFI_PLUGIN_EXPORT spine_skin_entries *spine_skin_get_entries(spine_skin skin);
FFI_PLUGIN_EXPORT void spine_skin_entries_dispose(spine_skin_entries *entries);
FFI_PLUGIN_EXPORT int spine_skin_get_num_bones(spine_skin skin);
FFI_PLUGIN_EXPORT spine_skin_entries spine_skin_get_entries(spine_skin skin);
FFI_PLUGIN_EXPORT int32_t spine_skin_entries_get_num_entries(spine_skin_entries entries);
FFI_PLUGIN_EXPORT spine_skin_entry spine_skin_entries_get_entry(spine_skin_entries entries, int32_t index);
FFI_PLUGIN_EXPORT void spine_skin_entries_dispose(spine_skin_entries entries);
FFI_PLUGIN_EXPORT int32_t spine_skin_entry_get_slot_index(spine_skin_entry entry);
FFI_PLUGIN_EXPORT utf8 *spine_skin_entry_get_name(spine_skin_entry entry);
FFI_PLUGIN_EXPORT spine_attachment spine_skin_entry_get_attachment(spine_skin_entry entry);
FFI_PLUGIN_EXPORT int32_t spine_skin_get_num_bones(spine_skin skin);
FFI_PLUGIN_EXPORT spine_bone_data* spine_skin_get_bones(spine_skin skin);
FFI_PLUGIN_EXPORT int spine_skin_get_num_constraints(spine_skin skin);
FFI_PLUGIN_EXPORT int32_t spine_skin_get_num_constraints(spine_skin skin);
FFI_PLUGIN_EXPORT spine_constraint_data* spine_skin_get_constraints(spine_skin skin);
FFI_PLUGIN_EXPORT spine_skin spine_skin_create(const char* name);
FFI_PLUGIN_EXPORT spine_skin spine_skin_create(const utf8* name);
FFI_PLUGIN_EXPORT void spine_skin_dispose(spine_skin skin);
FFI_PLUGIN_EXPORT spine_constraint_type spine_constraint_data_get_type(spine_constraint_data data);
FFI_PLUGIN_EXPORT const char* spine_constraint_data_get_name(spine_constraint_data data);
FFI_PLUGIN_EXPORT const utf8* spine_constraint_data_get_name(spine_constraint_data data);
FFI_PLUGIN_EXPORT uint64_t spine_constraint_data_get_order(spine_constraint_data data);
FFI_PLUGIN_EXPORT void spine_constraint_data_set_order(spine_constraint_data data, uint64_t order);
FFI_PLUGIN_EXPORT int spine_constraint_data_get_is_skin_required(spine_constraint_data data);
FFI_PLUGIN_EXPORT void spine_constraint_data_set_is_skin_required(spine_constraint_data data, int isSkinRequired);
FFI_PLUGIN_EXPORT int32_t spine_constraint_data_get_is_skin_required(spine_constraint_data data);
FFI_PLUGIN_EXPORT void spine_constraint_data_set_is_skin_required(spine_constraint_data data, int32_t isSkinRequired);
FFI_PLUGIN_EXPORT int spine_ik_constraint_data_get_num_bones(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_data_get_num_bones(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT spine_bone_data* spine_ik_constraint_data_get_bones(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT spine_bone_data spine_ik_constraint_data_get_target(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_target(spine_ik_constraint_data data, spine_bone_data target);
FFI_PLUGIN_EXPORT int spine_ik_constraint_data_get_bend_direction(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_bend_direction(spine_ik_constraint_data data, int bendDirection);
FFI_PLUGIN_EXPORT int spine_ik_constraint_data_get_compress(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_compress(spine_ik_constraint_data data, int compress);
FFI_PLUGIN_EXPORT int spine_ik_constraint_data_get_stretch(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_stretch(spine_ik_constraint_data data, int stretch);
FFI_PLUGIN_EXPORT int spine_ik_constraint_data_get_uniform(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_uniform(spine_ik_constraint_data data, int uniform);
FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_data_get_bend_direction(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_bend_direction(spine_ik_constraint_data data, int32_t bendDirection);
FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_data_get_compress(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_compress(spine_ik_constraint_data data, int32_t compress);
FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_data_get_stretch(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_stretch(spine_ik_constraint_data data, int32_t stretch);
FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_data_get_uniform(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_uniform(spine_ik_constraint_data data, int32_t uniform);
FFI_PLUGIN_EXPORT float spine_ik_constraint_data_get_mix(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_mix(spine_ik_constraint_data data, float mix);
FFI_PLUGIN_EXPORT float spine_ik_constraint_data_get_softness(spine_ik_constraint_data data);
FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_softness(spine_ik_constraint_data data, float softness);
FFI_PLUGIN_EXPORT void spine_ik_constraint_update(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT int spine_ik_constraint_get_order(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_get_order(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT spine_ik_constraint_data spine_ik_constraint_get_data(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT int spine_ik_constraint_get_num_bones(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_get_num_bones(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT spine_bone* spine_ik_constraint_get_bones(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT spine_bone spine_ik_constraint_get_target(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT void spine_ik_constraint_set_target(spine_ik_constraint constraint, spine_bone target);
FFI_PLUGIN_EXPORT int spine_ik_constraint_get_bend_direction(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT void spine_ik_constraint_set_bend_direction(spine_ik_constraint constraint, int bendDirection);
FFI_PLUGIN_EXPORT int spine_ik_constraint_get_compress(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT void spine_ik_constraint_set_compress(spine_ik_constraint constraint, int compress);
FFI_PLUGIN_EXPORT int spine_ik_constraint_get_stretch(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT void spine_ik_constraint_set_stretch(spine_ik_constraint constraint, int stretch);
FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_get_bend_direction(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT void spine_ik_constraint_set_bend_direction(spine_ik_constraint constraint, int32_t bendDirection);
FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_get_compress(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT void spine_ik_constraint_set_compress(spine_ik_constraint constraint, int32_t compress);
FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_get_stretch(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT void spine_ik_constraint_set_stretch(spine_ik_constraint constraint, int32_t stretch);
FFI_PLUGIN_EXPORT float spine_ik_constraint_get_mix(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT void spine_ik_constraint_set_mix(spine_ik_constraint constraint, float mix);
FFI_PLUGIN_EXPORT float spine_ik_constraint_get_softness(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT void spine_ik_constraint_set_softness(spine_ik_constraint constraint, float softness);
FFI_PLUGIN_EXPORT int spine_ik_constraint_get_is_active(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT void spine_ik_constraint_set_is_active(spine_ik_constraint constraint, int isActive);
FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_get_is_active(spine_ik_constraint constraint);
FFI_PLUGIN_EXPORT void spine_ik_constraint_set_is_active(spine_ik_constraint constraint, int32_t isActive);
FFI_PLUGIN_EXPORT int spine_transform_constraint_data_get_num_bones(spine_transform_constraint_data data);
FFI_PLUGIN_EXPORT int32_t spine_transform_constraint_data_get_num_bones(spine_transform_constraint_data data);
FFI_PLUGIN_EXPORT spine_bone_data* spine_transform_constraint_data_get_bones(spine_transform_constraint_data data);
FFI_PLUGIN_EXPORT spine_bone_data spine_transform_constraint_data_get_target(spine_transform_constraint_data data);
FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_target(spine_transform_constraint_data data, spine_bone_data target);
@ -741,15 +734,15 @@ FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_offset_scale_y(spine
FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_offset_scale_y(spine_transform_constraint_data data, float offsetScaleY);
FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_offset_shear_y(spine_transform_constraint_data data);
FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_offset_shear_y(spine_transform_constraint_data data, float offsetShearY);
FFI_PLUGIN_EXPORT int spine_transform_constraint_data_get_is_relative(spine_transform_constraint_data data);
FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_is_relative(spine_transform_constraint_data data, int isRelative);
FFI_PLUGIN_EXPORT int spine_transform_constraint_data_get_is_local(spine_transform_constraint_data data);
FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_is_local(spine_transform_constraint_data data, int isLocal);
FFI_PLUGIN_EXPORT int32_t spine_transform_constraint_data_get_is_relative(spine_transform_constraint_data data);
FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_is_relative(spine_transform_constraint_data data, int32_t isRelative);
FFI_PLUGIN_EXPORT int32_t spine_transform_constraint_data_get_is_local(spine_transform_constraint_data data);
FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_is_local(spine_transform_constraint_data data, int32_t isLocal);
FFI_PLUGIN_EXPORT void spine_transform_constraint_update(spine_transform_constraint constraint);
FFI_PLUGIN_EXPORT int spine_transform_constraint_get_order(spine_transform_constraint constraint);
FFI_PLUGIN_EXPORT int32_t spine_transform_constraint_get_order(spine_transform_constraint constraint);
FFI_PLUGIN_EXPORT spine_transform_constraint_data spine_transform_constraint_get_data(spine_transform_constraint constraint);
FFI_PLUGIN_EXPORT int spine_transform_constraint_get_num_bones(spine_transform_constraint constraint);
FFI_PLUGIN_EXPORT int32_t spine_transform_constraint_get_num_bones(spine_transform_constraint constraint);
FFI_PLUGIN_EXPORT spine_bone* spine_transform_constraint_get_bones(spine_transform_constraint constraint);
FFI_PLUGIN_EXPORT spine_bone spine_transform_constraint_get_target(spine_transform_constraint constraint);
FFI_PLUGIN_EXPORT void spine_transform_constraint_set_target(spine_transform_constraint constraint, spine_bone target);
@ -766,9 +759,9 @@ FFI_PLUGIN_EXPORT void spine_transform_constraint_set_mix_scale_y(spine_transfor
FFI_PLUGIN_EXPORT float spine_transform_constraint_get_mix_shear_y(spine_transform_constraint constraint);
FFI_PLUGIN_EXPORT void spine_transform_constraint_set_mix_shear_y(spine_transform_constraint constraint, float mixShearY);
FFI_PLUGIN_EXPORT float spine_transform_constraint_get_is_active(spine_transform_constraint constraint);
FFI_PLUGIN_EXPORT void spine_transform_constraint_set_is_active(spine_transform_constraint constraint, int isActive);
FFI_PLUGIN_EXPORT void spine_transform_constraint_set_is_active(spine_transform_constraint constraint, int32_t isActive);
FFI_PLUGIN_EXPORT int spine_path_constraint_data_get_num_bones(spine_path_constraint_data data);
FFI_PLUGIN_EXPORT int32_t spine_path_constraint_data_get_num_bones(spine_path_constraint_data data);
FFI_PLUGIN_EXPORT spine_bone_data* spine_path_constraint_data_get_bones(spine_path_constraint_data data);
FFI_PLUGIN_EXPORT spine_slot_data spine_path_constraint_data_get_target(spine_path_constraint_data data);
FFI_PLUGIN_EXPORT void spine_path_constraint_data_set_target(spine_path_constraint_data data, spine_slot_data target);
@ -792,9 +785,9 @@ FFI_PLUGIN_EXPORT float spine_path_constraint_data_get_mix_y(spine_path_constrai
FFI_PLUGIN_EXPORT void spine_path_constraint_data_set_mix_y(spine_path_constraint_data data, float mixY);
FFI_PLUGIN_EXPORT void spine_path_constraint_update(spine_path_constraint constraint);
FFI_PLUGIN_EXPORT int spine_path_constraint_get_order(spine_path_constraint constraint);
FFI_PLUGIN_EXPORT int32_t spine_path_constraint_get_order(spine_path_constraint constraint);
FFI_PLUGIN_EXPORT spine_path_constraint_data spine_path_constraint_get_data(spine_path_constraint constraint);
FFI_PLUGIN_EXPORT int spine_path_constraint_get_num_bones(spine_path_constraint constraint);
FFI_PLUGIN_EXPORT int32_t spine_path_constraint_get_num_bones(spine_path_constraint constraint);
FFI_PLUGIN_EXPORT spine_bone* spine_path_constraint_get_bones(spine_path_constraint constraint);
FFI_PLUGIN_EXPORT spine_slot spine_path_constraint_get_target(spine_path_constraint constraint);
FFI_PLUGIN_EXPORT void spine_path_constraint_set_target(spine_path_constraint constraint, spine_slot target);
@ -808,21 +801,21 @@ FFI_PLUGIN_EXPORT float spine_path_constraint_get_mix_x(spine_path_constraint co
FFI_PLUGIN_EXPORT void spine_path_constraint_set_mix_x(spine_path_constraint constraint, float mixX);
FFI_PLUGIN_EXPORT float spine_path_constraint_get_mix_y(spine_path_constraint constraint);
FFI_PLUGIN_EXPORT void spine_path_constraint_set_mix_y(spine_path_constraint constraint, float mixY);
FFI_PLUGIN_EXPORT int spine_path_constraint_get_is_active(spine_path_constraint constraint);
FFI_PLUGIN_EXPORT void spine_path_constraint_set_is_active(spine_path_constraint constraint, int isActive);
FFI_PLUGIN_EXPORT int32_t spine_path_constraint_get_is_active(spine_path_constraint constraint);
FFI_PLUGIN_EXPORT void spine_path_constraint_set_is_active(spine_path_constraint constraint, int32_t isActive);
// OMITTED copy()
FFI_PLUGIN_EXPORT void spine_sequence_apply(spine_sequence sequence, spine_slot slot, spine_attachment attachment);
FFI_PLUGIN_EXPORT const char* spine_sequence_get_path(spine_sequence sequence, const char *basePath, int index);
FFI_PLUGIN_EXPORT int spine_sequence_get_id(spine_sequence sequence);
FFI_PLUGIN_EXPORT void spine_sequence_set_id(spine_sequence sequence, int id);
FFI_PLUGIN_EXPORT int spine_sequence_get_start(spine_sequence sequence);
FFI_PLUGIN_EXPORT void spine_sequence_set_start(spine_sequence sequence, int start);
FFI_PLUGIN_EXPORT int spine_sequence_get_digits(spine_sequence sequence);
FFI_PLUGIN_EXPORT void spine_sequence_set_digits(spine_sequence sequence, int digits);
FFI_PLUGIN_EXPORT int spine_sequence_get_setup_index(spine_sequence sequence);
FFI_PLUGIN_EXPORT void spine_sequence_set_setup_index(spine_sequence sequence, int setupIndex);
FFI_PLUGIN_EXPORT int spine_sequence_get_num_regions(spine_sequence sequence);
FFI_PLUGIN_EXPORT const utf8* spine_sequence_get_path(spine_sequence sequence, const utf8 *basePath, int32_t index);
FFI_PLUGIN_EXPORT int32_t spine_sequence_get_id(spine_sequence sequence);
FFI_PLUGIN_EXPORT void spine_sequence_set_id(spine_sequence sequence, int32_t id);
FFI_PLUGIN_EXPORT int32_t spine_sequence_get_start(spine_sequence sequence);
FFI_PLUGIN_EXPORT void spine_sequence_set_start(spine_sequence sequence, int32_t start);
FFI_PLUGIN_EXPORT int32_t spine_sequence_get_digits(spine_sequence sequence);
FFI_PLUGIN_EXPORT void spine_sequence_set_digits(spine_sequence sequence, int32_t digits);
FFI_PLUGIN_EXPORT int32_t spine_sequence_get_setup_index(spine_sequence sequence);
FFI_PLUGIN_EXPORT void spine_sequence_set_setup_index(spine_sequence sequence, int32_t setupIndex);
FFI_PLUGIN_EXPORT int32_t spine_sequence_get_num_regions(spine_sequence sequence);
FFI_PLUGIN_EXPORT spine_texture_region* spine_sequence_get_regions(spine_sequence sequence);
FFI_PLUGIN_EXPORT void* spine_texture_region_get_texture(spine_texture_region textureRegion);
@ -835,19 +828,19 @@ FFI_PLUGIN_EXPORT float spine_texture_region_get_u2(spine_texture_region texture
FFI_PLUGIN_EXPORT void spine_texture_region_set_u2(spine_texture_region textureRegion, float u2);
FFI_PLUGIN_EXPORT float spine_texture_region_get_v2(spine_texture_region textureRegion);
FFI_PLUGIN_EXPORT void spine_texture_region_set_v2(spine_texture_region textureRegion, float v2);
FFI_PLUGIN_EXPORT int spine_texture_region_get_degrees(spine_texture_region textureRegion);
FFI_PLUGIN_EXPORT void spine_texture_region_set_degrees(spine_texture_region textureRegion, int degrees);
FFI_PLUGIN_EXPORT int32_t spine_texture_region_get_degrees(spine_texture_region textureRegion);
FFI_PLUGIN_EXPORT void spine_texture_region_set_degrees(spine_texture_region textureRegion, int32_t degrees);
FFI_PLUGIN_EXPORT float spine_texture_region_get_offset_x(spine_texture_region textureRegion);
FFI_PLUGIN_EXPORT void spine_texture_region_set_offset_x(spine_texture_region textureRegion, float offsetX);
FFI_PLUGIN_EXPORT float spine_texture_region_get_offset_y(spine_texture_region textureRegion);
FFI_PLUGIN_EXPORT void spine_texture_region_set_offset_y(spine_texture_region textureRegion, float offsetY);
FFI_PLUGIN_EXPORT int spine_texture_region_get_width(spine_texture_region textureRegion);
FFI_PLUGIN_EXPORT void spine_texture_region_set_width(spine_texture_region textureRegion, int width);
FFI_PLUGIN_EXPORT int spine_texture_region_get_height(spine_texture_region textureRegion);
FFI_PLUGIN_EXPORT void spine_texture_region_set_height(spine_texture_region textureRegion, int height);
FFI_PLUGIN_EXPORT int spine_texture_region_get_original_width(spine_texture_region textureRegion);
FFI_PLUGIN_EXPORT void spine_texture_region_set_original_width(spine_texture_region textureRegion, int originalWidth);
FFI_PLUGIN_EXPORT int spine_texture_region_get_original_height(spine_texture_region textureRegion);
FFI_PLUGIN_EXPORT void spine_texture_region_set_original_height(spine_texture_region textureRegion, int originalHeight);
FFI_PLUGIN_EXPORT int32_t spine_texture_region_get_width(spine_texture_region textureRegion);
FFI_PLUGIN_EXPORT void spine_texture_region_set_width(spine_texture_region textureRegion, int32_t width);
FFI_PLUGIN_EXPORT int32_t spine_texture_region_get_height(spine_texture_region textureRegion);
FFI_PLUGIN_EXPORT void spine_texture_region_set_height(spine_texture_region textureRegion, int32_t height);
FFI_PLUGIN_EXPORT int32_t spine_texture_region_get_original_width(spine_texture_region textureRegion);
FFI_PLUGIN_EXPORT void spine_texture_region_set_original_width(spine_texture_region textureRegion, int32_t originalWidth);
FFI_PLUGIN_EXPORT int32_t spine_texture_region_get_original_height(spine_texture_region textureRegion);
FFI_PLUGIN_EXPORT void spine_texture_region_set_original_height(spine_texture_region textureRegion, int32_t originalHeight);
#endif