From 934e3747247179d419bfc2b00e8c4c7c92df3c13 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Sun, 20 Nov 2022 22:18:39 +0100 Subject: [PATCH] [flutter] Add web_ffi fork, fix .wasm/.js size The fork is required as Emscripten produces a .wasm file that the upstream web_ffi can't parse correctly to extract exported symbols. --- spine-cpp/spine-cpp/src/spine/Extension.cpp | 4 + spine-flutter/README.md | 17 +- spine-flutter/example/pubspec.lock | 7 - spine-flutter/lib/ffi_proxy.dart | 2 +- spine-flutter/lib/init_web.dart | 4 +- spine-flutter/lib/web_ffi/ffi/extensions.dart | 284 ++++ spine-flutter/lib/web_ffi/ffi/types.dart | 326 +++++ .../web_ffi/internal/invoker_generated.dart | 1091 +++++++++++++++ .../lib/web_ffi/internal/marshaller.dart | 271 ++++ .../lib/web_ffi/internal/type_utils.dart | 62 + spine-flutter/lib/web_ffi/meta/meta.dart | 35 + .../modules/emscripten/emscripten_module.dart | 192 +++ .../emscripten/emscripten_module_stub.dart | 71 + .../lib/web_ffi/modules/exceptions.dart | 18 + spine-flutter/lib/web_ffi/modules/memory.dart | 116 ++ spine-flutter/lib/web_ffi/modules/module.dart | 114 ++ .../lib/web_ffi/modules/null_memory.dart | 20 + spine-flutter/lib/web_ffi/web_ffi.dart | 6 + spine-flutter/lib/web_ffi/web_ffi_meta.dart | 4 + .../lib/web_ffi/web_ffi_modules.dart | 12 + spine-flutter/pubspec.yaml | 3 +- spine-flutter/src/compile-wasm.sh | 12 +- spine-flutter/src/spine_flutter.cpp | 1228 +++++++++-------- 23 files changed, 3272 insertions(+), 627 deletions(-) create mode 100755 spine-flutter/lib/web_ffi/ffi/extensions.dart create mode 100755 spine-flutter/lib/web_ffi/ffi/types.dart create mode 100755 spine-flutter/lib/web_ffi/internal/invoker_generated.dart create mode 100755 spine-flutter/lib/web_ffi/internal/marshaller.dart create mode 100755 spine-flutter/lib/web_ffi/internal/type_utils.dart create mode 100755 spine-flutter/lib/web_ffi/meta/meta.dart create mode 100755 spine-flutter/lib/web_ffi/modules/emscripten/emscripten_module.dart create mode 100755 spine-flutter/lib/web_ffi/modules/emscripten/emscripten_module_stub.dart create mode 100755 spine-flutter/lib/web_ffi/modules/exceptions.dart create mode 100755 spine-flutter/lib/web_ffi/modules/memory.dart create mode 100755 spine-flutter/lib/web_ffi/modules/module.dart create mode 100755 spine-flutter/lib/web_ffi/modules/null_memory.dart create mode 100755 spine-flutter/lib/web_ffi/web_ffi.dart create mode 100755 spine-flutter/lib/web_ffi/web_ffi_meta.dart create mode 100755 spine-flutter/lib/web_ffi/web_ffi_modules.dart diff --git a/spine-cpp/spine-cpp/src/spine/Extension.cpp b/spine-cpp/spine-cpp/src/spine/Extension.cpp index acdc93a09..17a2539c9 100644 --- a/spine-cpp/spine-cpp/src/spine/Extension.cpp +++ b/spine-cpp/spine-cpp/src/spine/Extension.cpp @@ -104,6 +104,7 @@ void DefaultSpineExtension::_free(void *mem, const char *file, int line) { } char *DefaultSpineExtension::_readFile(const String &path, int *length) { +#ifndef __EMSCRIPTEN__ char *data; FILE *file = fopen(path.buffer(), "rb"); if (!file) return 0; @@ -117,6 +118,9 @@ char *DefaultSpineExtension::_readFile(const String &path, int *length) { fclose(file); return data; +#else + return nullptr; +#endif } DefaultSpineExtension::DefaultSpineExtension() : SpineExtension() { diff --git a/spine-flutter/README.md b/spine-flutter/README.md index aeb1f0a05..ba6284d27 100644 --- a/spine-flutter/README.md +++ b/spine-flutter/README.md @@ -14,6 +14,21 @@ In order to distribute your software containing the Spine Runtimes to others tha For the official legal terms governing the Spine Runtimes, please read the [Spine Runtimes License Agreement](http://esotericsoftware.com/spine-runtimes-license) and Section 2 of the [Spine Editor License Agreement](http://esotericsoftware.com/spine-editor-license#s2). +### Licensing web_ffi +spine-flutter includes a modified fork of [https://github.com/EPNW/web_ffi](web_ffi) by Eric Prokop und Nils Wieler Hard- und Softwareentwicklung GbR, which is licensed under the [BSD 2-Clause "Simplified" License](https://github.com/EPNW/web_ffi/blob/master/LICENSE). + +``` +Copyright 2021 Eric Prokop und Nils Wieler Hard- und Softwareentwicklung GbR + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +``` + ## Spine version spine-flutter works with data exported from Spine 4.1.xx. @@ -37,5 +52,3 @@ The example in this repository is directly depending on the spine-flutter source Once installed, run the `setup.sh` script in the `spine-flutter` folder. This will copy [spine-cpp](../spine-cpp) to the appropriate locations. You can then open `spine-flutter` in an IDE or editor of your choice that supports Flutter, like [IntelliJ IDEA/Android Studio](https://docs.flutter.dev/get-started/editor?tab=androidstudio) or [Visual Studio Code](https://docs.flutter.dev/get-started/editor?tab=vscode) to inspect and run the example. Alternatively, you can run the example from the [command line](https://docs.flutter.dev/get-started/test-drive?tab=terminal). - - \ No newline at end of file diff --git a/spine-flutter/example/pubspec.lock b/spine-flutter/example/pubspec.lock index 977fddeee..0e9b6f9f3 100644 --- a/spine-flutter/example/pubspec.lock +++ b/spine-flutter/example/pubspec.lock @@ -172,13 +172,6 @@ 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" diff --git a/spine-flutter/lib/ffi_proxy.dart b/spine-flutter/lib/ffi_proxy.dart index 5ff8e34e5..3e9771eef 100644 --- a/spine-flutter/lib/ffi_proxy.dart +++ b/spine-flutter/lib/ffi_proxy.dart @@ -1 +1 @@ -export 'dart:ffi' if (dart.library.html) 'package:web_ffi/web_ffi.dart'; \ No newline at end of file +export 'dart:ffi' if (dart.library.html) 'web_ffi/web_ffi.dart'; \ No newline at end of file diff --git a/spine-flutter/lib/init_web.dart b/spine-flutter/lib/init_web.dart index 102b2fe7d..9ad559b82 100644 --- a/spine-flutter/lib/init_web.dart +++ b/spine-flutter/lib/init_web.dart @@ -1,8 +1,8 @@ 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 'web_ffi/web_ffi.dart'; +import 'web_ffi/web_ffi_modules.dart'; import 'spine_flutter_bindings_generated.dart'; Module? _module; diff --git a/spine-flutter/lib/web_ffi/ffi/extensions.dart b/spine-flutter/lib/web_ffi/ffi/extensions.dart new file mode 100755 index 000000000..52b912fc4 --- /dev/null +++ b/spine-flutter/lib/web_ffi/ffi/extensions.dart @@ -0,0 +1,284 @@ +import 'dart:typed_data'; +import 'types.dart'; + +import '../modules/memory.dart'; +import '../modules/module.dart'; +import '../internal/marshaller.dart'; + +import '../web_ffi_meta.dart'; + +/// Extension on [Pointer] specialized for the type argument [NativeFunction]. +extension NativeFunctionPointer + on Pointer> { + /// Convert to Dart function, automatically marshalling the arguments and return value. + /// + /// There are several rules that apply for the return type of `DF`, see + /// the list of [allowed return types](https://github.com/EPNW/web_ffi/blob/master/return_types.md). + /// If marshalling failes, a [MarshallingException] is thrown. + /// + /// If this is called on a pointer that does not point to a function, + /// a [ArgumentError](https://api.dart.dev/stable/dart-core/ArgumentError-class.html) is thrown. + DF asFunction() { + WasmSymbol symbol = symbolByAddress(boundMemory, address); + if (symbol is FunctionDescription) { + return marshall(symbol.function, boundMemory); + } else { + throw ArgumentError( + 'No function at address $address was found (but a global symbol)!'); + } + } +} + +extension DynamicLibraryExtension on DynamicLibrary { + /// Helper that combines lookup and cast to a Dart function. + /// + /// This simply calles [DynamicLibrary.lookup] and [NativeFunctionPointer.asFunction] + /// internally, so see this two methods for additional insights. + F lookupFunction(String name) => + this.lookup>(name).asFunction(); +} + +/// Extension on [Allocator] to provide allocation with [NativeType]. +extension AllocatorAlloc on Allocator { + /// Allocates `sizeOf() * count` bytes of memory using [Allocator.allocate]. + /// + /// Since this calls [sizeOf] internally, an exception will be thrown if this + /// method is called with an @[unsized] type or before [Memory.init] was called. + Pointer call([int count = 1]) => + allocate(sizeOf() * count); +} + +/// Extension on [Pointer] specialized for the type argument [Float]. +extension FloatPointer on Pointer { + /// The float at address. + double get value => this[0]; + void set value(double value) => this[0] = value; + + /// Creates a typed list view backed by memory in the address space. + /// + /// The returned view will allow access to the memory range + /// from address to `address + size * length`. + Float32List asTypedList(int length) => + boundMemory.buffer.asFloat32List(address, length); + + /// The float at `address + size * index`. + double operator [](int index) => + viewSingle(index).getFloat32(0, Memory.endianess); + void operator []=(int index, double value) => + viewSingle(index).setFloat32(0, value, Memory.endianess); +} + +/// Extension on [Pointer] specialized for the type argument [Double]. +extension DoublePointer on Pointer { + /// The double at address. + double get value => this[0]; + void set value(double value) => this[0] = value; + + /// Creates a typed list view backed by memory in the address space. + /// + /// The returned view will allow access to the memory range + /// from address to `address + size * length`. + Float64List asTypedList(int length) => + boundMemory.buffer.asFloat64List(address, length); + + /// The double at `address + size * index`. + double operator [](int index) => + viewSingle(index).getFloat64(0, Memory.endianess); + void operator []=(int index, double value) => + viewSingle(index).setFloat64(0, value, Memory.endianess); +} + +/// Extension on [Pointer] specialized for the type argument [Int8]. +extension Int8Pointer on Pointer { + /// The 8-bit integer at `address`. + int get value => this[0]; + void set value(int value) => this[0] = value; + + /// Creates a typed list view backed by memory in the address space. + /// + /// The returned view will allow access to the memory range + /// from address to `address + size * length`. + Int8List asTypedList(int length) => + boundMemory.buffer.asInt8List(address, length); + + /// The 8-bit integer at `address + size * index`. + int operator [](int index) => viewSingle(index).getInt8(0); + void operator []=(int index, int value) => + viewSingle(index).setInt8(0, value); +} + +/// Extension on [Pointer] specialized for the type argument [Int16]. +extension Int16Pointer on Pointer { + /// The 16-bit integer at `address`. + int get value => this[0]; + void set value(int value) => this[0] = value; + + /// Creates a typed list view backed by memory in the address space. + /// + /// The returned view will allow access to the memory range + /// from address to `address + size * length`. + Int16List asTypedList(int length) => + boundMemory.buffer.asInt16List(address, length); + + /// The 16-bit integer at `address + size * index`. + int operator [](int index) => viewSingle(index).getInt16(0, Memory.endianess); + void operator []=(int index, int value) => + viewSingle(index).setInt16(0, value, Memory.endianess); +} + +/// Extension on [Pointer] specialized for the type argument [Int32]. +extension Int32Pointer on Pointer { + /// The 32-bit integer at `address`. + int get value => this[0]; + void set value(int value) => this[0] = value; + + /// Creates a typed list view backed by memory in the address space. + /// + /// The returned view will allow access to the memory range + /// from address to `address + size * length`. + Int32List asTypedList(int length) => + boundMemory.buffer.asInt32List(address, length); + + /// The 32-bit integer at `address + size * index`. + int operator [](int index) => viewSingle(index).getInt32(0, Memory.endianess); + void operator []=(int index, int value) => + viewSingle(index).setInt32(0, value, Memory.endianess); +} + +/// Extension on [Pointer] specialized for the type argument [Int64]. +extension Int64Pointer on Pointer { + /// The 64-bit integer at `address`. + int get value => this[0]; + void set value(int value) => this[0] = value; + + /// Creates a typed list view backed by memory in the address space. + /// + /// The returned view will allow access to the memory range + /// from address to `address + size * length`. + Int64List asTypedList(int length) => + boundMemory.buffer.asInt64List(address, length); + + /// The 64-bit integer at `address + size * index`. + int operator [](int index) => viewSingle(index).getInt64(0, Memory.endianess); + void operator []=(int index, int value) => + viewSingle(index).setInt64(0, value, Memory.endianess); +} + +/// Extension on [Pointer] specialized for the type argument [Uint8]. +extension Uint8Pointer on Pointer { + /// The 8-bit unsigned integer at `address`. + int get value => this[0]; + void set value(int value) => this[0] = value; + + /// Creates a typed list view backed by memory in the address space. + /// + /// The returned view will allow access to the memory range + /// from address to `address + size * length`. + Uint8List asTypedList(int length) => + boundMemory.buffer.asUint8List(address, length); + + /// The 8-bit unsigned integer at `address + size * index`. + int operator [](int index) => viewSingle(index).getUint8(0); + void operator []=(int index, int value) => + viewSingle(index).setUint8(0, value); +} + +/// Extension on [Pointer] specialized for the type argument [Uint16]. +extension Uint16Pointer on Pointer { + /// The 16-bit unsigned integer at `address`. + int get value => this[0]; + void set value(int value) => this[0] = value; + + /// Creates a typed list view backed by memory in the address space. + /// + /// The returned view will allow access to the memory range + /// from address to `address + size * length`. + Uint16List asTypedList(int length) => + boundMemory.buffer.asUint16List(address, length); + + /// The 16-bit unsigned integer at `address + size * index`. + int operator [](int index) => + viewSingle(index).getUint16(0, Memory.endianess); + void operator []=(int index, int value) => + viewSingle(index).setUint16(0, value, Memory.endianess); +} + +/// Extension on [Pointer] specialized for the type argument [Uint32]. +extension Uint32Pointer on Pointer { + /// The 32-bit unsigned integer at `address`. + int get value => this[0]; + void set value(int value) => this[0] = value; + + /// Creates a typed list view backed by memory in the address space. + /// + /// The returned view will allow access to the memory range + /// from address to `address + size * length`. + Uint32List asTypedList(int length) => + boundMemory.buffer.asUint32List(address, length); + + /// The 32-bit unsigned integer at `address + size * index`. + int operator [](int index) => + viewSingle(index).getUint32(0, Memory.endianess); + void operator []=(int index, int value) => + viewSingle(index).setUint32(0, value, Memory.endianess); +} + +/// Extension on [Pointer] specialized for the type argument [Uint64]. +extension Uint64Pointer on Pointer { + /// The 64-bit unsigned integer at `address`. + int get value => this[0]; + void set value(int value) => this[0] = value; + + /// Creates a typed list view backed by memory in the address space. + /// + /// The returned view will allow access to the memory range + /// from address to `address + size * length`. + Uint64List asTypedList(int length) => + boundMemory.buffer.asUint64List(address, length); + + /// The 64-bit unsigned integer at `address + size * index`. + int operator [](int index) => + viewSingle(index).getUint64(0, Memory.endianess); + void operator []=(int index, int value) => + viewSingle(index).setUint64(0, value, Memory.endianess); +} + +/// Extension on [Pointer] specialized for the type argument [IntPtr]. +extension IntPtrPointer on Pointer { + /// The 32-bit or 64-bit value at `address`. + int get value => this[0]; + void set value(int value) => this[0] = value; + + /// Returns `true` if the size of a pointer is 64-bit, `false` otherwise. + @extra + bool get is64Bit => size == 8; + + /// The 32-bit or 64-bit integer at `address + size * index`. + int operator [](int index) => is64Bit + ? viewSingle(index).getUint64(0, Memory.endianess) + : viewSingle(index).getUint32(0, Memory.endianess); + void operator []=(int index, int value) => is64Bit + ? viewSingle(index).setUint64(0, value, Memory.endianess) + : viewSingle(index).setUint32(0, value, Memory.endianess); +} + +/// Extension on [Pointer] specialized for the type argument [Pointer]. +extension PointerPointer on Pointer> { + /// The pointer at `address`. + Pointer get value => this[0]; + void set value(Pointer value) => this[0] = value; + + /// Returns `true` if the size of a pointer is 64-bit, `false` otherwise. + @extra + bool get is64Bit => size == 8; + + /// The pointer at `address + size * index`. + Pointer operator [](int index) => new Pointer.fromAddress( + is64Bit + ? viewSingle(index).getUint64(0, Memory.endianess) + : viewSingle(index).getUint32(0, Memory.endianess), + boundMemory); + void operator []=(int index, Pointer value) => is64Bit + ? viewSingle(index).setUint64(0, value.address, Memory.endianess) + : viewSingle(index).setUint32(0, value.address, Memory.endianess); +} diff --git a/spine-flutter/lib/web_ffi/ffi/types.dart b/spine-flutter/lib/web_ffi/ffi/types.dart new file mode 100755 index 000000000..248ecaa60 --- /dev/null +++ b/spine-flutter/lib/web_ffi/ffi/types.dart @@ -0,0 +1,326 @@ +import 'dart:typed_data'; +import 'package:meta/meta.dart'; + +import '../modules/module.dart'; +import '../modules/memory.dart'; +import '../modules/null_memory.dart'; + +import '../internal/type_utils.dart'; + +import '../web_ffi_meta.dart'; + +/// Represents a pointer into the native C memory corresponding to "NULL", +/// e.g. a pointer with address 0. +/// +/// You can compare any other pointer with this pointer using == to check +/// if it's also an nullpointer. +/// +/// Any other operation than comparing (e.g. calling [Pointer.cast]) +/// will result in exceptions. +final Pointer nullptr = new Pointer._null(); + +/// Number of bytes used by native type T. +/// +/// MUST NOT be called with types annoteted with @[unsized] or +/// before [Memory.init()] was called or else an exception will be thrown. +int sizeOf() { + int? size; + if (isPointerType()) { + size = sizeMap[IntPtr]; + } else { + size = sizeMap[T]; + } + if (size != null) { + return size; + } else { + throw new ArgumentError('The type $T is not known!'); + } +} + +bool _isUnsizedType() { + return isNativeFunctionType() || isVoidType(); +} + +/// [NativeType]'s subtypes represent a native type in C. +/// +/// [NativeType]'s subtypes (except [Pointer]) are not constructible +/// in the Dart code and serve purely as markers in type signatures. +@sealed +@notConstructible +class NativeType {} + +/// Represents a native 64 bit double in C. +/// +/// Double is not constructible in the Dart code and serves +/// purely as marker in type signatures. +@sealed +@notConstructible +class Double extends NativeType {} + +/// Represents a native 32 bit float in C. +/// +/// Float is not constructible in the Dart code and serves +/// purely as marker in type signatures. +@sealed +@notConstructible +class Float extends NativeType {} + +/// Represents a native signed 8 bit integer in C. +/// +/// Int8 is not constructible in the Dart code and serves +/// purely as marker in type signatures. +@sealed +@notConstructible +class Int8 extends NativeType {} + +/// Represents a native signed 16 bit integer in C. +/// +/// Int16 is not constructible in the Dart code and serves +/// purely as marker in type signatures. +@sealed +@notConstructible +class Int16 extends NativeType {} + +/// Represents a native signed 32 bit integer in C. +/// +/// Int32 is not constructible in the Dart code and serves +/// purely as marker in type signatures. +@sealed +@notConstructible +class Int32 extends NativeType {} + +/// Represents a native signed 64 bit integer in C. +/// +/// Int64 is not constructible in the Dart code and serves +/// purely as marker in type signatures. +@sealed +@notConstructible +class Int64 extends NativeType {} + +/// Represents a native unsigned 8 bit integer in C. +/// +/// Uint8 is not constructible in the Dart code and serves +/// purely as marker in type signatures. +@sealed +@notConstructible +class Uint8 extends NativeType {} + +/// Represents a native unsigned 16 bit integer in C. +/// +/// Uint16 is not constructible in the Dart code and serves +/// purely as marker in type signatures. +@sealed +@notConstructible +class Uint16 extends NativeType {} + +/// Represents a native unsigned 32 bit integer in C. +/// +/// Uint32 is not constructible in the Dart code and serves +/// purely as marker in type signatures. +@sealed +@notConstructible +class Uint32 extends NativeType {} + +/// Represents a native unsigned 64 bit integer in C. +/// +/// Uint64 is not constructible in the Dart code and serves +/// purely as marker in type signatures. +@sealed +@notConstructible +class Uint64 extends NativeType {} + +/// Represents a native pointer-sized integer in C. +/// +/// IntPtr is not constructible in the Dart code and serves +/// purely as marker in type signatures. +@sealed +@notConstructible +class IntPtr extends NativeType {} + +/// Represents a function type in C. +/// +/// NativeFunction is not constructible in the Dart code and serves +/// purely as marker in type signatures. +@sealed +@notConstructible +@unsized +class NativeFunction extends NativeType {} + +/// Opaque's subtypes represent opaque types in C. +/// +/// Classes that extend Opaque MUST NOT have a type argument! +/// +/// Opaque's subtypes are not constructible in the Dart code and serve +/// purely as markers in type signatures. +@noGeneric +@notConstructible +class Opaque extends NativeType {} + +/// Represents a void type in C. +/// +/// Void is not constructible in the Dart code and serves +/// purely as marker in type signatures. +@sealed +@notConstructible +@unsized +class Void extends NativeType {} + +/// Represents a pointer into the native C memory. Cannot be extended. +@sealed +class Pointer extends NativeType { + //static Pointer> fromFunction(Function f, + // [Object? exceptionalReturn]) => + // throw new UnimplementedError(); + + /// Access to the raw pointer value. + final int address; + + /// The [Memory] object this pointer is bound to. + /// + /// The `Memory` object backs this pointer, if the value of + /// this pointer is accessed. + @extra + final Memory boundMemory; + + /// How much memory in bytes the type this pointer points to occupies, + /// or `null` for @[unsized] types. + @extra + final int? size; + + factory Pointer._null() { + return new Pointer._(0, new NullMemory(), null); + } + + /// Constructs a pointer from an address. + /// + /// The optional parameter `bindTo` can be ommited, if and only if + /// [Memory.global] is set, which is then used as `Memory` to bind to. + factory Pointer.fromAddress(int ptr, [Memory? bindTo]) { + bindTo = Memory.global; + Memory m; + if (bindTo != null) { + m = bindTo; + } else { + throw new StateError( + 'No global memory set and no explcity memory to bind to given!'); + } + return new Pointer._(ptr, m, _isUnsizedType() ? null : sizeOf()); + } + + Pointer._(this.address, this.boundMemory, this.size); + + /// Casts this pointer to an other type. + Pointer cast() => new Pointer._( + address, boundMemory, _isUnsizedType() ? null : sizeOf()); + + /// Pointer arithmetic (takes element size into account). + /// + /// Throws an [UnsupportedError] if called on a pointer with an @[unsized] + /// type argument. + Pointer elementAt(int index) { + int? s = size; + if (s != null) { + return new Pointer._(address + index * s, boundMemory, s); + } else { + throw new UnsupportedError( + 'elementAt is not supported for unsized types!'); + } + } + + /// The hash code for a Pointer only depends on its address. + @override + int get hashCode => address; + + /// Two pointers are equal if their address is the same, independently + /// of their type argument and of the memory they are bound to. + @override + bool operator ==(Object other) => + (other is Pointer && other.address == address); + + /// Returns a view of a single element at [index] (takes element + /// size into account). + /// + /// Any modifications to the data will also alter the [Memory] object. + /// + /// Throws an [UnsupportedError] if called on a pointer with an @[unsized] + /// type argument. + @extra + ByteData viewSingle(int index) { + int? s = size; + if (s != null) { + return boundMemory.buffer.asByteData(address + index * s, s); + } else { + throw new UnsupportedError( + 'viewSingle is not supported for unsized types!'); + } + } +} + +/// Represents a dynamically loaded C library. +class DynamicLibrary { + @extra + final Memory boundMemory; + + /// Creates a new instance based on the given module. + /// + /// While for each [DynamicLibrary] a new [Memory] object is + /// created, the [Memory] objects share the backing memory if + /// they are created based on the same module. + /// + /// The [registerMode] parameter can be used to control if the + /// newly created [Memory] object should be registered as + /// [Memory.global]. + @extra + factory DynamicLibrary.fromModule(Module module, + [MemoryRegisterMode registerMode = + MemoryRegisterMode.onlyIfGlobalNotSet]) { + Memory memory = createMemory(module); + switch (registerMode) { + case MemoryRegisterMode.yes: + Memory.global = memory; + break; + case MemoryRegisterMode.no: + break; + case MemoryRegisterMode.onlyIfGlobalNotSet: + if (Memory.global == null) { + Memory.global = memory; + } + break; + } + return new DynamicLibrary._(memory); + } + + DynamicLibrary._(this.boundMemory); + + /// Looks up a symbol in the DynamicLibrary and returns its address in memory. + /// + /// Throws an [ArgumentError] if it fails to lookup the symbol. + /// + /// While this method checks if the underyling wasm symbol is a actually + /// a function when you lookup a [NativeFunction]``, it does not check if + /// the return type and parameters of `T` match the wasm function. + Pointer lookup(String name) { + WasmSymbol symbol = symbolByName(boundMemory, name); + if (isNativeFunctionType()) { + if (symbol is FunctionDescription) { + return new Pointer.fromAddress(symbol.tableIndex, boundMemory); + } else { + throw new ArgumentError( + 'Tried to look up $name as a function, but it seems it is NOT a function!'); + } + } else { + return new Pointer.fromAddress(symbol.address, boundMemory); + } + } +} + +/// Manages memory on the native heap. +abstract class Allocator { + /// Allocates byteCount bytes of memory on the native heap. + /// + /// The parameter `alignment` is ignored. + Pointer allocate(int byteCount, {int? alignment}); + + /// Releases memory allocated on the native heap. + void free(Pointer pointer); +} diff --git a/spine-flutter/lib/web_ffi/internal/invoker_generated.dart b/spine-flutter/lib/web_ffi/internal/invoker_generated.dart new file mode 100755 index 000000000..c13282fac --- /dev/null +++ b/spine-flutter/lib/web_ffi/internal/invoker_generated.dart @@ -0,0 +1,1091 @@ +import '../ffi/types.dart'; +import '../modules/memory.dart'; +import 'marshaller.dart' show execute; + +/// https://stackoverflow.com/questions/26122009/is-there-a-maximum-number-of-parameters-for-functions-in-c-with-the-gcc-resp-m +/// the C Standard 5.2.4.1 says: +/// 4095 characters in a logical source line +/// 127 parameters in one function definition +/// 127 arguments in one function call + +class OpaqueInvokeHelper extends InvokeHelper> { + OpaqueInvokeHelper(Function? base, Memory? memory) : super(base, memory); + + @override + InvokeHelper> copyWith(Function base, Memory memory) { + return new OpaqueInvokeHelper(base, memory); + } + + @override + Pointer run( + [dynamic arg0, + dynamic arg1, + dynamic arg2, + dynamic arg3, + dynamic arg4, + dynamic arg5, + dynamic arg6, + dynamic arg7, + dynamic arg8, + dynamic arg9, + dynamic arg10, + dynamic arg11, + dynamic arg12, + dynamic arg13, + dynamic arg14, + dynamic arg15, + dynamic arg16, + dynamic arg17, + dynamic arg18, + dynamic arg19, + dynamic arg20, + dynamic arg21, + dynamic arg22, + dynamic arg23, + dynamic arg24, + dynamic arg25, + dynamic arg26, + dynamic arg27, + dynamic arg28, + dynamic arg29, + dynamic arg30, + dynamic arg31, + dynamic arg32, + dynamic arg33, + dynamic arg34, + dynamic arg35, + dynamic arg36, + dynamic arg37, + dynamic arg38, + dynamic arg39, + dynamic arg40, + dynamic arg41, + dynamic arg42, + dynamic arg43, + dynamic arg44, + dynamic arg45, + dynamic arg46, + dynamic arg47, + dynamic arg48, + dynamic arg49, + dynamic arg50, + dynamic arg51, + dynamic arg52, + dynamic arg53, + dynamic arg54, + dynamic arg55, + dynamic arg56, + dynamic arg57, + dynamic arg58, + dynamic arg59, + dynamic arg60, + dynamic arg61, + dynamic arg62, + dynamic arg63, + dynamic arg64, + dynamic arg65, + dynamic arg66, + dynamic arg67, + dynamic arg68, + dynamic arg69, + dynamic arg70, + dynamic arg71, + dynamic arg72, + dynamic arg73, + dynamic arg74, + dynamic arg75, + dynamic arg76, + dynamic arg77, + dynamic arg78, + dynamic arg79, + dynamic arg80, + dynamic arg81, + dynamic arg82, + dynamic arg83, + dynamic arg84, + dynamic arg85, + dynamic arg86, + dynamic arg87, + dynamic arg88, + dynamic arg89, + dynamic arg90, + dynamic arg91, + dynamic arg92, + dynamic arg93, + dynamic arg94, + dynamic arg95, + dynamic arg96, + dynamic arg97, + dynamic arg98, + dynamic arg99, + dynamic arg100, + dynamic arg101, + dynamic arg102, + dynamic arg103, + dynamic arg104, + dynamic arg105, + dynamic arg106, + dynamic arg107, + dynamic arg108, + dynamic arg109, + dynamic arg110, + dynamic arg111, + dynamic arg112, + dynamic arg113, + dynamic arg114, + dynamic arg115, + dynamic arg116, + dynamic arg117, + dynamic arg118, + dynamic arg119, + dynamic arg120, + dynamic arg121, + dynamic arg122, + dynamic arg123, + dynamic arg124, + dynamic arg125, + dynamic arg126]) => + new InvokeHelper>(_base, _memory) + .run( + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20, + arg21, + arg22, + arg23, + arg24, + arg25, + arg26, + arg27, + arg28, + arg29, + arg30, + arg31, + arg32, + arg33, + arg34, + arg35, + arg36, + arg37, + arg38, + arg39, + arg40, + arg41, + arg42, + arg43, + arg44, + arg45, + arg46, + arg47, + arg48, + arg49, + arg50, + arg51, + arg52, + arg53, + arg54, + arg55, + arg56, + arg57, + arg58, + arg59, + arg60, + arg61, + arg62, + arg63, + arg64, + arg65, + arg66, + arg67, + arg68, + arg69, + arg70, + arg71, + arg72, + arg73, + arg74, + arg75, + arg76, + arg77, + arg78, + arg79, + arg80, + arg81, + arg82, + arg83, + arg84, + arg85, + arg86, + arg87, + arg88, + arg89, + arg90, + arg91, + arg92, + arg93, + arg94, + arg95, + arg96, + arg97, + arg98, + arg99, + arg100, + arg101, + arg102, + arg103, + arg104, + arg105, + arg106, + arg107, + arg108, + arg109, + arg110, + arg111, + arg112, + arg113, + arg114, + arg115, + arg116, + arg117, + arg118, + arg119, + arg120, + arg121, + arg122, + arg123, + arg124, + arg125, + arg126) + .cast(); +} + +class OpaqueInvokeHelperSquare + extends InvokeHelper>> { + OpaqueInvokeHelperSquare(Function? base, Memory? memory) + : super(base, memory); + + @override + InvokeHelper>> copyWith(Function base, Memory memory) { + return new OpaqueInvokeHelperSquare(base, memory); + } + + @override + Pointer> run( + [dynamic arg0, + dynamic arg1, + dynamic arg2, + dynamic arg3, + dynamic arg4, + dynamic arg5, + dynamic arg6, + dynamic arg7, + dynamic arg8, + dynamic arg9, + dynamic arg10, + dynamic arg11, + dynamic arg12, + dynamic arg13, + dynamic arg14, + dynamic arg15, + dynamic arg16, + dynamic arg17, + dynamic arg18, + dynamic arg19, + dynamic arg20, + dynamic arg21, + dynamic arg22, + dynamic arg23, + dynamic arg24, + dynamic arg25, + dynamic arg26, + dynamic arg27, + dynamic arg28, + dynamic arg29, + dynamic arg30, + dynamic arg31, + dynamic arg32, + dynamic arg33, + dynamic arg34, + dynamic arg35, + dynamic arg36, + dynamic arg37, + dynamic arg38, + dynamic arg39, + dynamic arg40, + dynamic arg41, + dynamic arg42, + dynamic arg43, + dynamic arg44, + dynamic arg45, + dynamic arg46, + dynamic arg47, + dynamic arg48, + dynamic arg49, + dynamic arg50, + dynamic arg51, + dynamic arg52, + dynamic arg53, + dynamic arg54, + dynamic arg55, + dynamic arg56, + dynamic arg57, + dynamic arg58, + dynamic arg59, + dynamic arg60, + dynamic arg61, + dynamic arg62, + dynamic arg63, + dynamic arg64, + dynamic arg65, + dynamic arg66, + dynamic arg67, + dynamic arg68, + dynamic arg69, + dynamic arg70, + dynamic arg71, + dynamic arg72, + dynamic arg73, + dynamic arg74, + dynamic arg75, + dynamic arg76, + dynamic arg77, + dynamic arg78, + dynamic arg79, + dynamic arg80, + dynamic arg81, + dynamic arg82, + dynamic arg83, + dynamic arg84, + dynamic arg85, + dynamic arg86, + dynamic arg87, + dynamic arg88, + dynamic arg89, + dynamic arg90, + dynamic arg91, + dynamic arg92, + dynamic arg93, + dynamic arg94, + dynamic arg95, + dynamic arg96, + dynamic arg97, + dynamic arg98, + dynamic arg99, + dynamic arg100, + dynamic arg101, + dynamic arg102, + dynamic arg103, + dynamic arg104, + dynamic arg105, + dynamic arg106, + dynamic arg107, + dynamic arg108, + dynamic arg109, + dynamic arg110, + dynamic arg111, + dynamic arg112, + dynamic arg113, + dynamic arg114, + dynamic arg115, + dynamic arg116, + dynamic arg117, + dynamic arg118, + dynamic arg119, + dynamic arg120, + dynamic arg121, + dynamic arg122, + dynamic arg123, + dynamic arg124, + dynamic arg125, + dynamic arg126]) => + new InvokeHelper>>(_base, _memory) + .run( + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20, + arg21, + arg22, + arg23, + arg24, + arg25, + arg26, + arg27, + arg28, + arg29, + arg30, + arg31, + arg32, + arg33, + arg34, + arg35, + arg36, + arg37, + arg38, + arg39, + arg40, + arg41, + arg42, + arg43, + arg44, + arg45, + arg46, + arg47, + arg48, + arg49, + arg50, + arg51, + arg52, + arg53, + arg54, + arg55, + arg56, + arg57, + arg58, + arg59, + arg60, + arg61, + arg62, + arg63, + arg64, + arg65, + arg66, + arg67, + arg68, + arg69, + arg70, + arg71, + arg72, + arg73, + arg74, + arg75, + arg76, + arg77, + arg78, + arg79, + arg80, + arg81, + arg82, + arg83, + arg84, + arg85, + arg86, + arg87, + arg88, + arg89, + arg90, + arg91, + arg92, + arg93, + arg94, + arg95, + arg96, + arg97, + arg98, + arg99, + arg100, + arg101, + arg102, + arg103, + arg104, + arg105, + arg106, + arg107, + arg108, + arg109, + arg110, + arg111, + arg112, + arg113, + arg114, + arg115, + arg116, + arg117, + arg118, + arg119, + arg120, + arg121, + arg122, + arg123, + arg124, + arg125, + arg126) + .cast>(); +} + +class InvokeHelper { + final Memory? _memory; + final Function? _base; + + const InvokeHelper(this._base, this._memory); + + InvokeHelper copyWith(Function base, Memory memory) { + return new InvokeHelper(base, memory); + } + + T run( + [dynamic arg0, + dynamic arg1, + dynamic arg2, + dynamic arg3, + dynamic arg4, + dynamic arg5, + dynamic arg6, + dynamic arg7, + dynamic arg8, + dynamic arg9, + dynamic arg10, + dynamic arg11, + dynamic arg12, + dynamic arg13, + dynamic arg14, + dynamic arg15, + dynamic arg16, + dynamic arg17, + dynamic arg18, + dynamic arg19, + dynamic arg20, + dynamic arg21, + dynamic arg22, + dynamic arg23, + dynamic arg24, + dynamic arg25, + dynamic arg26, + dynamic arg27, + dynamic arg28, + dynamic arg29, + dynamic arg30, + dynamic arg31, + dynamic arg32, + dynamic arg33, + dynamic arg34, + dynamic arg35, + dynamic arg36, + dynamic arg37, + dynamic arg38, + dynamic arg39, + dynamic arg40, + dynamic arg41, + dynamic arg42, + dynamic arg43, + dynamic arg44, + dynamic arg45, + dynamic arg46, + dynamic arg47, + dynamic arg48, + dynamic arg49, + dynamic arg50, + dynamic arg51, + dynamic arg52, + dynamic arg53, + dynamic arg54, + dynamic arg55, + dynamic arg56, + dynamic arg57, + dynamic arg58, + dynamic arg59, + dynamic arg60, + dynamic arg61, + dynamic arg62, + dynamic arg63, + dynamic arg64, + dynamic arg65, + dynamic arg66, + dynamic arg67, + dynamic arg68, + dynamic arg69, + dynamic arg70, + dynamic arg71, + dynamic arg72, + dynamic arg73, + dynamic arg74, + dynamic arg75, + dynamic arg76, + dynamic arg77, + dynamic arg78, + dynamic arg79, + dynamic arg80, + dynamic arg81, + dynamic arg82, + dynamic arg83, + dynamic arg84, + dynamic arg85, + dynamic arg86, + dynamic arg87, + dynamic arg88, + dynamic arg89, + dynamic arg90, + dynamic arg91, + dynamic arg92, + dynamic arg93, + dynamic arg94, + dynamic arg95, + dynamic arg96, + dynamic arg97, + dynamic arg98, + dynamic arg99, + dynamic arg100, + dynamic arg101, + dynamic arg102, + dynamic arg103, + dynamic arg104, + dynamic arg105, + dynamic arg106, + dynamic arg107, + dynamic arg108, + dynamic arg109, + dynamic arg110, + dynamic arg111, + dynamic arg112, + dynamic arg113, + dynamic arg114, + dynamic arg115, + dynamic arg116, + dynamic arg117, + dynamic arg118, + dynamic arg119, + dynamic arg120, + dynamic arg121, + dynamic arg122, + dynamic arg123, + dynamic arg124, + dynamic arg125, + dynamic arg126]) { + if (_base == null || _memory == null) { + throw StateError('Call copyWith first!'); + } + Function base = _base!; + Memory memory = _memory!; + List args = []; + if (arg0 != null) { + args.add(arg0); + if (arg1 != null) { + args.add(arg1); + if (arg2 != null) { + args.add(arg2); + if (arg3 != null) { + args.add(arg3); + if (arg4 != null) { + args.add(arg4); + if (arg5 != null) { + args.add(arg5); + if (arg6 != null) { + args.add(arg6); + if (arg7 != null) { + args.add(arg7); + if (arg8 != null) { + args.add(arg8); + if (arg9 != null) { + args.add(arg9); + if (arg10 != null) { + args.add(arg10); + if (arg11 != null) { + args.add(arg11); + if (arg12 != null) { + args.add(arg12); + if (arg13 != null) { + args.add(arg13); + if (arg14 != null) { + args.add(arg14); + if (arg15 != null) { + args.add(arg15); + if (arg16 != null) { + args.add(arg16); + if (arg17 != null) { + args.add(arg17); + if (arg18 != null) { + args.add(arg18); + if (arg19 != null) { + args.add(arg19); + if (arg20 != null) { + args.add(arg20); + if (arg21 != null) { + args.add(arg21); + if (arg22 != null) { + args.add(arg22); + if (arg23 != null) { + args.add(arg23); + if (arg24 != null) { + args.add(arg24); + if (arg25 != null) { + args.add(arg25); + if (arg26 != null) { + args.add(arg26); + if (arg27 != null) { + args.add(arg27); + if (arg28 != null) { + args.add(arg28); + if (arg29 != + null) { + args.add(arg29); + if (arg30 != + null) { + args.add( + arg30); + if (arg31 != + null) { + args.add( + arg31); + if (arg32 != + null) { + args.add( + arg32); + if (arg33 != + null) { + args.add( + arg33); + if (arg34 != + null) { + args.add( + arg34); + if (arg35 != + null) { + args.add(arg35); + if (arg36 != + null) { + args.add(arg36); + if (arg37 != null) { + args.add(arg37); + if (arg38 != null) { + args.add(arg38); + if (arg39 != null) { + args.add(arg39); + if (arg40 != null) { + args.add(arg40); + if (arg41 != null) { + args.add(arg41); + if (arg42 != null) { + args.add(arg42); + if (arg43 != null) { + args.add(arg43); + if (arg44 != null) { + args.add(arg44); + if (arg45 != null) { + args.add(arg45); + if (arg46 != null) { + args.add(arg46); + if (arg47 != null) { + args.add(arg47); + if (arg48 != null) { + args.add(arg48); + if (arg49 != null) { + args.add(arg49); + if (arg50 != null) { + args.add(arg50); + if (arg51 != null) { + args.add(arg51); + if (arg52 != null) { + args.add(arg52); + if (arg53 != null) { + args.add(arg53); + if (arg54 != null) { + args.add(arg54); + if (arg55 != null) { + args.add(arg55); + if (arg56 != null) { + args.add(arg56); + if (arg57 != null) { + args.add(arg57); + if (arg58 != null) { + args.add(arg58); + if (arg59 != null) { + args.add(arg59); + if (arg60 != null) { + args.add(arg60); + if (arg61 != null) { + args.add(arg61); + if (arg62 != null) { + args.add(arg62); + if (arg63 != null) { + args.add(arg63); + if (arg64 != null) { + args.add(arg64); + if (arg65 != null) { + args.add(arg65); + if (arg66 != null) { + args.add(arg66); + if (arg67 != null) { + args.add(arg67); + if (arg68 != null) { + args.add(arg68); + if (arg69 != null) { + args.add(arg69); + if (arg70 != null) { + args.add(arg70); + if (arg71 != null) { + args.add(arg71); + if (arg72 != null) { + args.add(arg72); + if (arg73 != null) { + args.add(arg73); + if (arg74 != null) { + args.add(arg74); + if (arg75 != null) { + args.add(arg75); + if (arg76 != null) { + args.add(arg76); + if (arg77 != null) { + args.add(arg77); + if (arg78 != null) { + args.add(arg78); + if (arg79 != null) { + args.add(arg79); + if (arg80 != null) { + args.add(arg80); + if (arg81 != null) { + args.add(arg81); + if (arg82 != null) { + args.add(arg82); + if (arg83 != null) { + args.add(arg83); + if (arg84 != null) { + args.add(arg84); + if (arg85 != null) { + args.add(arg85); + if (arg86 != null) { + args.add(arg86); + if (arg87 != null) { + args.add(arg87); + if (arg88 != null) { + args.add(arg88); + if (arg89 != null) { + args.add(arg89); + if (arg90 != null) { + args.add(arg90); + if (arg91 != null) { + args.add(arg91); + if (arg92 != null) { + args.add(arg92); + if (arg93 != null) { + args.add(arg93); + if (arg94 != null) { + args.add(arg94); + if (arg95 != null) { + args.add(arg95); + if (arg96 != null) { + args.add(arg96); + if (arg97 != null) { + args.add(arg97); + if (arg98 != null) { + args.add(arg98); + if (arg99 != null) { + args.add(arg99); + if (arg100 != null) { + args.add(arg100); + if (arg101 != null) { + args.add(arg101); + if (arg102 != null) { + args.add(arg102); + if (arg103 != null) { + args.add(arg103); + if (arg104 != null) { + args.add(arg104); + if (arg105 != null) { + args.add(arg105); + if (arg106 != null) { + args.add(arg106); + if (arg107 != null) { + args.add(arg107); + if (arg108 != null) { + args.add(arg108); + if (arg109 != null) { + args.add(arg109); + if (arg110 != null) { + args.add(arg110); + if (arg111 != null) { + args.add(arg111); + if (arg112 != null) { + args.add(arg112); + if (arg113 != null) { + args.add(arg113); + if (arg114 != null) { + args.add(arg114); + if (arg115 != null) { + args.add(arg115); + if (arg116 != null) { + args.add(arg116); + if (arg117 != null) { + args.add(arg117); + if (arg118 != null) { + args.add(arg118); + if (arg119 != null) { + args.add(arg119); + if (arg120 != null) { + args.add(arg120); + if (arg121 != null) { + args.add(arg121); + if (arg122 != null) { + args.add(arg122); + if (arg123 != null) { + args.add(arg123); + if (arg124 != null) { + args.add(arg124); + if (arg125 != null) { + args.add(arg125); + if (arg126 != null) { + args.add(arg126); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + return execute(base, args, memory); + } +} diff --git a/spine-flutter/lib/web_ffi/internal/marshaller.dart b/spine-flutter/lib/web_ffi/internal/marshaller.dart new file mode 100755 index 000000000..0b00b4058 --- /dev/null +++ b/spine-flutter/lib/web_ffi/internal/marshaller.dart @@ -0,0 +1,271 @@ +import 'package:meta/meta.dart'; + +import '../ffi/types.dart'; +import '../modules/exceptions.dart'; +import '../modules/memory.dart'; +import 'invoker_generated.dart'; +import 'type_utils.dart'; + +// Called from the invokers +T execute(Function base, List args, Memory memory) { + if (T == DartVoidType) { + Function.apply(base, args.map(_toJsType).toList()); + return null as T; + } else { + Object result = Function.apply(base, args.map(_toJsType).toList()); + return _toDartType(result, memory); + } +} + +DF marshall( + Function base, Memory memory) { + return _inferFromSignature(DF.toString()).copyWith(base, memory).run as DF; +} + +Object _toJsType(Object dartObject) { + if (dartObject is int || dartObject is double || dartObject is bool) { + return dartObject; + } else if (dartObject is Pointer) { + return dartObject.address; + } else { + throw new MarshallingException( + 'Could not convert dart type ${dartObject.runtimeType} to a JavaScript type!'); + } +} + +InvokeHelper _inferFromSignature(String signature) { + String returnType = signature.split('=>').last.trim(); + if (returnType.startsWith(pointerPointerPointerPrefix)) { + throw new MarshallingException( + 'Nesting pointers is only supported to a deepth of 2!' + + '\nThis means that you can write Pointer> but not Pointer>>, ...'); + } + InvokeHelper? h = _knownTypes[returnType]; + if (h != null) { + return h; + } else { + if (returnType.startsWith(pointerNativeFunctionPrefix)) { + throw new MarshallingException( + 'Using pointers to native functions as return type is only allowed if the type of the native function is dynamic!' + + '\nThis means that only Pointer> is allowed!'); + } else { + throw new MarshallingException( + 'Unknown type $returnType (infered from $signature), all marshallable types: ${listKnownTypes()}'); + } + } +} + +@visibleForTesting +List listKnownTypes() => + new List.of(_knownTypes.keys, growable: false); + +final Map _knownTypes = { + typeString(): new InvokeHelper(null, null), + typeString(): new InvokeHelper(null, null), + typeString(): new InvokeHelper(null, null), + typeString(): new InvokeHelper(null, null) +}; + +void registerNativeMarshallerType() { + _knownTypes[typeString>()] = + new InvokeHelper>(null, null); + _knownTypes[typeString>>()] = + new InvokeHelper>>(null, null); +} + +void registerNativeMarshallerOpaque() { + _knownTypes[typeString>()] = new OpaqueInvokeHelper(null, null); + _knownTypes[typeString>>()] = + new OpaqueInvokeHelperSquare(null, null); +} + +T _toDartType(Object o, Memory bind) { + if (T == int) { + if (o is int) { + return o as T; + } else { + throw new MarshallingException.typeMissmatch(T, o); + } + } else if (T == double) { + if (o is double) { + return o as T; + } else { + throw new MarshallingException.typeMissmatch(T, o); + } + } else if (T == bool) { + if (o is bool) { + return o as T; + } else { + throw new MarshallingException.typeMissmatch(T, o); + } + } else { + if (T == Pointer_Void) { + if (o is int) { + return new Pointer.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_IntPtr) { + if (o is int) { + return new Pointer.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Int8) { + if (o is int) { + return new Pointer.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Int16) { + if (o is int) { + return new Pointer.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Int32) { + if (o is int) { + return new Pointer.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Int64) { + if (o is int) { + return new Pointer.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Double) { + if (o is int) { + return new Pointer.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Uint8) { + if (o is int) { + return new Pointer.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Uint16) { + if (o is int) { + return new Pointer.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Uint32) { + if (o is int) { + return new Pointer.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Uint64) { + if (o is int) { + return new Pointer.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Float) { + if (o is int) { + return new Pointer.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Opaque) { + if (o is int) { + return new Pointer.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_NativeFunction_dynamic) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else { + if (T == Pointer_Pointer_Void) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Pointer_IntPtr) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Pointer_Int8) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Pointer_Int16) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Pointer_Int32) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Pointer_Int64) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Pointer_Double) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Pointer_Uint8) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Pointer_Uint16) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Pointer_Uint32) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Pointer_Uint64) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Pointer_Float) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else if (T == Pointer_Pointer_Opaque) { + if (o is int) { + return new Pointer>.fromAddress(o, bind) as T; + } else { + throw new MarshallingException.noAddress(o); + } + } else { + throw new MarshallingException( + 'Can not back-marshall to type $T (object type is ${o.runtimeType}'); + } + } + } +} diff --git a/spine-flutter/lib/web_ffi/internal/type_utils.dart b/spine-flutter/lib/web_ffi/internal/type_utils.dart new file mode 100755 index 000000000..38b38ffb9 --- /dev/null +++ b/spine-flutter/lib/web_ffi/internal/type_utils.dart @@ -0,0 +1,62 @@ +import '../ffi/types.dart'; + +/// Hacky workadround, see https://github.com/dart-lang/language/issues/123 +Type _extractType() => T; +String typeString() => _extractType().toString(); + +// Variable names begin with a capital letter on purpose (opposing dart conventions) to hilight that +// they are treated like types (which are written with a captial letter in dart). +final Type Pointer_IntPtr = _extractType>(); +final Type Pointer_Void = _extractType>(); +final Type Pointer_Int8 = _extractType>(); +final Type Pointer_Int16 = _extractType>(); +final Type Pointer_Int32 = _extractType>(); +final Type Pointer_Int64 = _extractType>(); +final Type Pointer_Double = _extractType>(); +final Type Pointer_Uint8 = _extractType>(); +final Type Pointer_Uint16 = _extractType>(); +final Type Pointer_Uint32 = _extractType>(); +final Type Pointer_Uint64 = _extractType>(); +final Type Pointer_Float = _extractType>(); +final Type Pointer_Opaque = _extractType>(); +final Type Pointer_Pointer_IntPtr = _extractType>>(); +final Type Pointer_Pointer_Void = _extractType>>(); +final Type Pointer_Pointer_Int8 = _extractType>>(); +final Type Pointer_Pointer_Int16 = _extractType>>(); +final Type Pointer_Pointer_Int32 = _extractType>>(); +final Type Pointer_Pointer_Int64 = _extractType>>(); +final Type Pointer_Pointer_Double = _extractType>>(); +final Type Pointer_Pointer_Uint8 = _extractType>>(); +final Type Pointer_Pointer_Uint16 = _extractType>>(); +final Type Pointer_Pointer_Uint32 = _extractType>>(); +final Type Pointer_Pointer_Uint64 = _extractType>>(); +final Type Pointer_Pointer_Float = _extractType>>(); +final Type Pointer_Pointer_Opaque = _extractType>>(); +final Type Pointer_NativeFunction_dynamic = + _extractType>>(); +final Type DartVoidType = _extractType(); +final Type FfiVoidType = _extractType(); + +final String _dynamicTypeString = typeString(); + +final String pointerPointerPointerPrefix = + typeString>>>() + .split(_dynamicTypeString) + .first; + +final String pointerNativeFunctionPrefix = + typeString>>() + .split(_dynamicTypeString) + .first; + +final String _nativeFunctionPrefix = + typeString>().split(_dynamicTypeString).first; +bool isNativeFunctionType() => + typeString().startsWith(_nativeFunctionPrefix); + +final String _pointerPrefix = + typeString>().split(_dynamicTypeString).first; +bool isPointerType() => + typeString().startsWith(_pointerPrefix); + +bool isVoidType() => _extractType() == FfiVoidType; diff --git a/spine-flutter/lib/web_ffi/meta/meta.dart b/spine-flutter/lib/web_ffi/meta/meta.dart new file mode 100755 index 000000000..d2329466e --- /dev/null +++ b/spine-flutter/lib/web_ffi/meta/meta.dart @@ -0,0 +1,35 @@ +class _Extra { + const _Extra(); +} + +/// A class, field or method annotated with extra is present in `web_ffi`, +/// but not in `dart:ffi`. +const _Extra extra = const _Extra(); + +class _NoGeneric { + const _NoGeneric(); +} + +/// If a class which is annotead with [noGeneric] is extended or implemented, +/// the derived class MUST NOT impose a type argument! +const _NoGeneric noGeneric = const _NoGeneric(); + +class _NotConstructible { + const _NotConstructible(); +} + +/// A [NativeType] annotated with unsized should not be instantiated. +/// +/// However, they are not marked as `abstract` to meet the dart:ffi API. +const _NotConstructible notConstructible = const _NotConstructible(); + +class _Unsized { + const _Unsized(); +} + +/// A [NativeType] annotated with unsized does not have a predefined size. +/// +/// Unsized [NativeType]s do not support [sizeOf] because their size is unknown, +/// so calling [sizeOf] with an @[unsized] [NativeType] will throw an exception. +/// Consequently, [Pointer.elementAt] is not available and will also throw an exception. +const _Unsized unsized = const _Unsized(); diff --git a/spine-flutter/lib/web_ffi/modules/emscripten/emscripten_module.dart b/spine-flutter/lib/web_ffi/modules/emscripten/emscripten_module.dart new file mode 100755 index 000000000..8b44ff1fa --- /dev/null +++ b/spine-flutter/lib/web_ffi/modules/emscripten/emscripten_module.dart @@ -0,0 +1,192 @@ +@JS() +library emscripten_module; + +import 'dart:typed_data'; +import 'package:js/js.dart'; +import 'package:js/js_util.dart'; +import '../module.dart'; +import '../../web_ffi_meta.dart'; + +@JS('globalThis') +external Object get _globalThis; + +@JS('Object.entries') +external List? _entries(Object? o); + +@JS() +@anonymous +class _EmscriptenModuleJs { + external Uint8List? get wasmBinary; + external Uint8List? get HEAPU8; + external Object? get asm; + + // Must have an unnamed factory constructor with named arguments. + external factory _EmscriptenModuleJs({Uint8List wasmBinary}); +} + +const String _github = r'https://github.com/EPNW/web_ffi'; +String _adu(WasmSymbol? original, WasmSymbol? tried) => + 'CRITICAL EXCEPTION! Address double use! This should never happen, please report this issue on github immediately at $_github' + + '\r\nOriginal: $original' + + '\r\nTried: $tried'; + +typedef int _Malloc(int size); +typedef void _Free(int address); + +FunctionDescription _fromWasmFunction(String name, Function func) { + String? s = getProperty(func, 'name'); + if (s != null) { + int? index = int.tryParse(s); + if (index != null) { + int? length = getProperty(func, 'length'); + if (length != null) { + return new FunctionDescription( + tableIndex: index, + name: name, + function: func, + argumentCount: length); + } else { + throw new ArgumentError('$name does not seem to be a function symbol!'); + } + } else { + throw new ArgumentError('$name does not seem to be a function symbol!'); + } + } else { + throw new ArgumentError('$name does not seem to be a function symbol!'); + } +} + +/// Documentation is in `emscripten_module_stub.dart`! +@extra +class EmscriptenModule extends Module { + static Function _moduleFunction(String moduleName) { + Function? moduleFunction = getProperty(_globalThis, moduleName); + if (moduleFunction != null) { + return moduleFunction; + } else { + throw StateError('Could not find a emscripten module named $moduleName'); + } + } + + /// Documentation is in `emscripten_module_stub.dart`! + static Future process(String moduleName) async { + Function moduleFunction = _moduleFunction(moduleName); + _EmscriptenModuleJs module = new _EmscriptenModuleJs(); + Object? o = moduleFunction(module); + if (o != null) { + await promiseToFuture(o); + return new EmscriptenModule._fromJs(module); + } else { + throw new StateError('Could not instantiate an emscripten module!'); + } + } + + /// Documentation is in `emscripten_module_stub.dart`! + static Future compile( + Uint8List wasmBinary, String moduleName) async { + Function moduleFunction = _moduleFunction(moduleName); + _EmscriptenModuleJs module = + new _EmscriptenModuleJs(wasmBinary: wasmBinary); + Object? o = moduleFunction(module); + if (o != null) { + await promiseToFuture(o); + return new EmscriptenModule._fromJs(module); + } else { + throw new StateError('Could not instantiate an emscripten module!'); + } + } + + final _EmscriptenModuleJs _emscriptenModuleJs; + final List _exports; + final _Malloc _malloc; + final _Free _free; + + @override + List get exports => _exports; + + EmscriptenModule._( + this._emscriptenModuleJs, this._exports, this._malloc, this._free); + + factory EmscriptenModule._fromJs(_EmscriptenModuleJs module) { + Object? asm = module.asm; + if (asm != null) { + Map knownAddresses = {}; + _Malloc? malloc; + _Free? free; + List exports = []; + List? entries = _entries(asm); + if (entries != null) { + for (dynamic entry in entries) { + if (entry is List) { + Object value = entry.last; + if (value is int) { + Global g = + new Global(address: value, name: entry.first as String); + if (knownAddresses.containsKey(value) && + knownAddresses[value] is! Global) { + throw new StateError(_adu(knownAddresses[value], g)); + } + knownAddresses[value] = g; + exports.add(g); + } else if (value is Function) { + FunctionDescription description = + _fromWasmFunction(entry.first as String, value); + // It might happen that there are two different c functions that do nothing else than calling the same underlying c function + // In this case, a compiler might substitute both functions with the underlying c function + // So we got two functions with different names at the same table index + // So it is actually ok if there are two things at the same address, as long as they are both functions + if (knownAddresses.containsKey(description.tableIndex) && + knownAddresses[description.tableIndex] + is! FunctionDescription) { + throw new StateError( + _adu(knownAddresses[description.tableIndex], description)); + } + knownAddresses[description.tableIndex] = description; + exports.add(description); + if (description.name == 'malloc') { + malloc = description.function as _Malloc; + } else if (description.name == 'free') { + free = description.function as _Free; + } + } + } else { + throw new StateError( + 'Unexpected entry in entries(Module[\'asm\'])!'); + } + } + if (malloc != null) { + if (free != null) { + return new EmscriptenModule._(module, exports, malloc, free); + } else { + throw new StateError('Module does not export the free function!'); + } + } else { + throw new StateError('Module does not export the malloc function!'); + } + } else { + throw new StateError( + 'JavaScript error: Could not access entries of Module[\'asm\']!'); + } + } else { + throw new StateError( + 'Could not access Module[\'asm\'], are your sure your module was compiled using emscripten?'); + } + } + + @override + void free(int pointer) => _free(pointer); + + @override + ByteBuffer get heap => _getHeap(); + ByteBuffer _getHeap() { + Uint8List? h = _emscriptenModuleJs.HEAPU8; + if (h != null) { + return h.buffer; + } else { + throw StateError('Unexpected memory error!'); + } + } + + @override + int malloc(int size) => _malloc(size); +} diff --git a/spine-flutter/lib/web_ffi/modules/emscripten/emscripten_module_stub.dart b/spine-flutter/lib/web_ffi/modules/emscripten/emscripten_module_stub.dart new file mode 100755 index 000000000..ce4123e9a --- /dev/null +++ b/spine-flutter/lib/web_ffi/modules/emscripten/emscripten_module_stub.dart @@ -0,0 +1,71 @@ +import 'dart:typed_data'; +import '../module.dart'; + +import '../../web_ffi_meta.dart'; + +/// Provides access to WebAssembly compiled with [emscripten](https://emscripten.org). +/// +/// WebAssembly compiled with emscripten comes with an `.wasm` +/// and an additional `.js` glue JavaScript file. The later is +/// required to be loaded on the page before calling any of this classes +/// functions. +/// +/// The WebAssembly must have been compiled with the `-s MODULARIZE=1` +/// and `-s EXPORT_NAME=` flags. Futhermore the `` +/// must contain all exported WebAssembly functions that should be usable from +/// dart, so using `-s MAIN_MODULE=1` might be advisable. +/// +/// For a detailed walkthrough on how to create and inject these files, +/// see the [example](https://github.com/EPNW/web_ffi/blob/master/example/README.md). +/// +/// On platforms where [dart:js](https://api.dart.dev/stable/dart-js/dart-js-library.html) +/// is not available, all methods throw [UnsupportedError]s. +@extra +class EmscriptenModule extends Module { + /// Connects to the JavaScript glue of the emscripten module. + /// + /// This happens in the following way: + /// First, a JavaScript property named `moduleName` of the global object + /// is accessed, which should contain a function. Then this function is + /// called and expected to return a JavaScript emscripten module. + /// + /// The JavaScript emscripten module is responsible for retriving the + /// WebAssembly and compile it accordingly. + /// + /// On platforms where [dart:js](https://api.dart.dev/stable/dart-js/dart-js-library.html) + /// is not available, an [UnsupportedError] is thrown. + static Future process(String moduleName) => + throw new UnsupportedError( + 'Emscripten operations are only allowed on the web (where dart:js is present)!'); + + /// Connects to the JavaScript glue of the emscripten module. + /// + /// Works like [process], except that the bytes of the WebAssembly + /// are passed to the JavaScript emscripten module, so it is + /// your responsibility to fetch it. + /// + /// On platforms where [dart:js](https://api.dart.dev/stable/dart-js/dart-js-library.html) + /// is not available, an [UnsupportedError] is thrown. + static Future compile( + Uint8List wasmBinary, String moduleName) => + throw new UnsupportedError( + 'Emscripten operations are only allowed on the web (where dart:js is present)!'); + + EmscriptenModule._(); + + @override + List get exports => throw new UnsupportedError( + 'Emscripten operations are only allowed on the web (where dart:js is present)!'); + + @override + void free(int pointer) => throw new UnsupportedError( + 'Emscripten operations are only allowed on the web (where dart:js is present)!'); + + @override + ByteBuffer get heap => throw new UnsupportedError( + 'Emscripten operations are only allowed on the web (where dart:js is present)!'); + + @override + int malloc(int size) => throw new UnsupportedError( + 'Emscripten operations are only allowed on the web (where dart:js is present)!'); +} diff --git a/spine-flutter/lib/web_ffi/modules/exceptions.dart b/spine-flutter/lib/web_ffi/modules/exceptions.dart new file mode 100755 index 000000000..d3cfbc91e --- /dev/null +++ b/spine-flutter/lib/web_ffi/modules/exceptions.dart @@ -0,0 +1,18 @@ +/// Occures if it's not possible to convert dart types to JavaScript types. +/// +/// This usually happens if a not allowed type is uses as a [NativeType]'s +/// type argument, or a not allowed return value of a [NativeFunction] is +/// used. +class MarshallingException implements Exception { + final dynamic message; + const MarshallingException([this.message]); + + MarshallingException.noAddress(Object o) + : this('Expected a address (int) but found ${o.runtimeType}'); + + MarshallingException.typeMissmatch(Type t, Object o) + : this('Expected a type of $t but object has type ${o.runtimeType}'); + + @override + String toString() => new Exception(message).toString(); +} diff --git a/spine-flutter/lib/web_ffi/modules/memory.dart b/spine-flutter/lib/web_ffi/modules/memory.dart new file mode 100755 index 000000000..7404d2b4d --- /dev/null +++ b/spine-flutter/lib/web_ffi/modules/memory.dart @@ -0,0 +1,116 @@ +import 'dart:typed_data'; +import 'package:meta/meta.dart'; + +import 'module.dart'; +import '../ffi/types.dart'; +import '../internal/marshaller.dart'; +import '../web_ffi_meta.dart'; + +final Map sizeMap = {}; + +/// Must be called with each type that extends Opaque before +/// attemtping to use that type. +@extra +void registerOpaqueType() { + sizeMap[T] = sizeOf(); + registerNativeMarshallerOpaque(); +} + +void _registerType(int size) { + sizeMap[T] = size; + registerNativeMarshallerType(); +} + +/// Represents the native heap. +@extra +class Memory implements Allocator { + /// The endianess of data stored. + /// + /// The WebAssembly speficiation defines little endianess, so this is a constant. + static const Endian endianess = Endian.little; + + /// Must be called before working with `web_ffi` to initalize all type sizes. + /// + /// The optional parameter [pointerSizeBytes] can be used to adjust the size + /// of pointers. It defaults to `4` since WebAssembly usually uses 32 bit pointers. + /// If you want to use wasm64, set [pointerSizeBytes] to `8` to denote 64 bit pointers. + static void init([int pointerSizeBytes = 4]) { + _registerType(4); + _registerType(8); + _registerType(1); + _registerType(1); + _registerType(2); + _registerType(2); + _registerType(4); + _registerType(4); + _registerType(8); + _registerType(8); + _registerType(pointerSizeBytes); + _registerType(pointerSizeBytes); + registerNativeMarshallerType(); + registerNativeMarshallerType>(); + } + + /// The default [Memory] object to use. + /// + /// This field is null until it is either manually set to a [Memory] object, + /// or automatically set by [DynamicLibrary.fromModule]. + /// + /// This is most notably used when creating a pointer using [Pointer.fromAddress] + /// with no explicite memory to bind to given. + static Memory? global; + + /// Can be used to directly access the memory of this object. + /// + /// The value of this field should not be stored in a state variable, + /// since the returned buffer may change over time. + @doNotStore + ByteBuffer get buffer => _module.heap; + + final Module _module; + final Map _symbolsByName; + final Map _symbolsByAddress; + + Memory._(this._module) + : _symbolsByAddress = new Map.fromEntries(_module.exports + .map>((WasmSymbol symbol) => + new MapEntry(symbol.address, symbol))), + _symbolsByName = new Map.fromEntries(_module.exports + .map>((WasmSymbol symbol) => + new MapEntry(symbol.name, symbol))); + + @override + Pointer allocate(int byteCount, {int? alignment}) { + return new Pointer.fromAddress(_module.malloc(byteCount), this); + } + + @override + void free(Pointer pointer) { + _module.free(pointer.address); + } +} + +Memory createMemory(Module module) => new Memory._(module); + +WasmSymbol symbolByAddress(Memory m, int address) { + WasmSymbol? s = m._symbolsByAddress[address]; + if (s != null) { + return s; + } else { + throw new ArgumentError('Could not find symbol at $address!'); + } +} + +WasmSymbol symbolByName(Memory m, String name) { + WasmSymbol? s = m._symbolsByName[name]; + if (s != null) { + return s; + } else { + throw new ArgumentError('Could not find symbol $name!'); + } +} + +/// Used on [DynamicLibrary] creation to control if the therby newly created +/// [Memory] object should be registered as [Memory.global]. +@extra +enum MemoryRegisterMode { yes, no, onlyIfGlobalNotSet } diff --git a/spine-flutter/lib/web_ffi/modules/module.dart b/spine-flutter/lib/web_ffi/modules/module.dart new file mode 100755 index 000000000..1e918d206 --- /dev/null +++ b/spine-flutter/lib/web_ffi/modules/module.dart @@ -0,0 +1,114 @@ +import 'dart:typed_data'; +import 'package:meta/meta.dart'; +import '../web_ffi_meta.dart'; + +/// Base class to interact with the WebAssembly. +/// +/// Currently, only [emscripten](https://emscripten.org) compiled WebAssembly is supported, +/// so the only concrete implementation if this class is [EmscriptenModule]. +/// +/// To support additional mechanisms/frameworks/compilers, create a subclass of +/// [Module]. +@extra +abstract class Module { + /// Provides access to the malloc function in WebAssembly. + /// + /// Allocates `size` bytes of memory and returns the corresponding + /// address. + /// + /// Memory allocated by this should be [free]d afterwards. + int malloc(int size); + + /// Provides access to the free function in WebAssembly. + /// + /// Frees the memory region at `pointer` that was previously + /// allocated with [malloc]. + void free(int pointer); + + /// Provides access to the [WebAssemblys memory](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory) buffer. + /// + /// The actual [ByteBuffer] object returned by this getter is allowed to change; + /// It should not be cached in a state variable and is thus annotated with @[doNotStore]. + @doNotStore + ByteBuffer get heap; + + /// A list containing everything exported by the underlying + /// [WebAssembly instance](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance). + List get exports; +} + +/// Describes something exported by the WebAssembly. +@extra +@sealed +abstract class WasmSymbol { + /// The address of the exported thing. + final int address; + + /// The name of the exported thing. + final String name; + + const WasmSymbol({required this.address, required this.name}); + + @override + int get hashCode => toString().hashCode; + + @override + String toString() => '[address=$address\tname=$name]'; +} + +/// A global is a symbol exported by the WebAssembly, +/// that is not a function. +@extra +@sealed +class Global extends WasmSymbol { + const Global({required int address, required String name}) + : super(address: address, name: name); + + @override + bool operator ==(dynamic other) { + if (other != null && other is Global) { + return name == other.name && address == other.address; + } else { + return false; + } + } +} + +/// Describes a function exported from WebAssembly. +@extra +@sealed +class FunctionDescription extends WasmSymbol { + /// The index of this function in the [WebAssembly table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table). + /// This is the same as its address. + int get tableIndex => address; + + /// The amount of arguments the underyling function has. + final int argumentCount; + + /// The actual function. + final Function function; + const FunctionDescription( + {required int tableIndex, + required String name, + required this.argumentCount, + required this.function}) + : super(address: tableIndex, name: name); + + @override + int get hashCode => '$name$argumentCount$tableIndex'.hashCode; + + @override + bool operator ==(dynamic other) { + if (other != null && other is FunctionDescription) { + return argumentCount == other.argumentCount && + name == other.name && + tableIndex == other.tableIndex; + } else { + return false; + } + } + + @override + String toString() => + '[tableIndex=$tableIndex\tname=$name\targumentCount=$argumentCount\tfunction=$function]'; +} diff --git a/spine-flutter/lib/web_ffi/modules/null_memory.dart b/spine-flutter/lib/web_ffi/modules/null_memory.dart new file mode 100755 index 000000000..d1655fecc --- /dev/null +++ b/spine-flutter/lib/web_ffi/modules/null_memory.dart @@ -0,0 +1,20 @@ +import 'dart:typed_data'; +import 'memory.dart'; +import '../ffi/types.dart'; + +class NullMemory implements Memory { + @override + Pointer allocate(int byteCount, {int? alignment}) { + throw new UnsupportedError( + 'Can not use the null memory to allocate space!'); + } + + @override + ByteBuffer get buffer => + throw new UnsupportedError('The null memory has no buffer!'); + + @override + void free(Pointer pointer) { + throw new UnsupportedError('Can not use the null memory to free pointers!'); + } +} diff --git a/spine-flutter/lib/web_ffi/web_ffi.dart b/spine-flutter/lib/web_ffi/web_ffi.dart new file mode 100755 index 000000000..bbf5fbee1 --- /dev/null +++ b/spine-flutter/lib/web_ffi/web_ffi.dart @@ -0,0 +1,6 @@ +/// Provides mechanisms to use a [dart:ffi 2.12.0](https://api.dart.dev/stable/2.12.0/dart-ffi/dart-ffi-library.html) like API on the web but using [dart:js](https://api.dart.dev/stable/dart-js/dart-js-library.html). +/// While some things are missing, new things were added, identifiable by the @[extra] annotation. +library web_ffi; + +export 'ffi/types.dart'; +export 'ffi/extensions.dart'; diff --git a/spine-flutter/lib/web_ffi/web_ffi_meta.dart b/spine-flutter/lib/web_ffi/web_ffi_meta.dart new file mode 100755 index 000000000..9491003c4 --- /dev/null +++ b/spine-flutter/lib/web_ffi/web_ffi_meta.dart @@ -0,0 +1,4 @@ +/// This library contains and explains the annotations for `web_ffi`. +library web_ffi_meta; + +export 'meta/meta.dart'; diff --git a/spine-flutter/lib/web_ffi/web_ffi_modules.dart b/spine-flutter/lib/web_ffi/web_ffi_modules.dart new file mode 100755 index 000000000..66880b6e3 --- /dev/null +++ b/spine-flutter/lib/web_ffi/web_ffi_modules.dart @@ -0,0 +1,12 @@ +/// Provides additional classes that are needed for web_ffi, +/// but are not present in [dart:ffi](https://api.dart.dev/stable/2.12.0/dart-ffi/dart-ffi-library.html). +library web_ffi_modules; + +export 'modules/exceptions.dart'; +export 'modules/module.dart'; +export 'modules/memory.dart' + show registerOpaqueType, Memory, MemoryRegisterMode; + +export 'modules/emscripten/emscripten_module_stub.dart' + if (dart.library.js) 'modules/emscripten/emscripten_module.dart' + show EmscriptenModule; diff --git a/spine-flutter/pubspec.yaml b/spine-flutter/pubspec.yaml index db3a78a3f..e7b4a39a3 100644 --- a/spine-flutter/pubspec.yaml +++ b/spine-flutter/pubspec.yaml @@ -12,8 +12,9 @@ dependencies: sdk: flutter plugin_platform_interface: ^2.0.2 ffi: ^2.0.1 - web_ffi: ^0.7.2 inject_js: ^2.0.0 + js: ^0.6.3 + meta: ^1.3.0 http: ^0.13.5 dev_dependencies: diff --git a/spine-flutter/src/compile-wasm.sh b/spine-flutter/src/compile-wasm.sh index ac09cc282..b32d2cf31 100755 --- a/spine-flutter/src/compile-wasm.sh +++ b/spine-flutter/src/compile-wasm.sh @@ -2,15 +2,21 @@ dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" pushd $dir > /dev/null mkdir -p ../lib/assets/ +# Need to use -O2, as -O3 applies the Closure compiler to native function names. +# The entries for exported functions in Module.asm will be scrambled so +# EmscriptenModule._fromJs() is unable to parse them and link them with original +# names set on the module, e.g. Module._spine_get_major_version. emcc \ -Ispine-cpp/include \ - --closure 1 -O3 -fno-rtti -fno-exceptions \ - -s MAIN_MODULE=1 \ + -O2 --closure 1 -fno-rtti -fno-exceptions -lc++abi -lc++ \ + -s STRICT=1 \ + -s LLD_REPORT_UNDEFINED \ -s MODULARIZE=1 \ -s ALLOW_MEMORY_GROWTH=1 \ -s ALLOW_TABLE_GROWTH \ -s MALLOC=emmalloc \ - -s ENVIRONMENT=web \ + -s EXPORT_ALL=1 \ + -s EXPORTED_FUNCTIONS='["_malloc", "_free"]' \ --no-entry \ -s EXPORT_NAME=libspine_flutter \ spine_flutter.cpp `find spine-cpp/src -type f` \ diff --git a/spine-flutter/src/spine_flutter.cpp b/spine-flutter/src/spine_flutter.cpp index e295eb987..3682f7d6a 100644 --- a/spine-flutter/src/spine_flutter.cpp +++ b/spine-flutter/src/spine_flutter.cpp @@ -32,6 +32,12 @@ #include #include +#ifdef __EMSCRIPTEN__ +#include +#else +#define EMSCRIPTEN_KEEPALIVE +#endif + using namespace spine; struct AnimationStateEvent { @@ -107,76 +113,76 @@ spine::SpineExtension *spine::getDefaultExtension() { return new spine::DebugExtension(new spine::DefaultSpineExtension()); } -FFI_PLUGIN_EXPORT int32_t spine_major_version() { +EMSCRIPTEN_KEEPALIVE int32_t spine_major_version() { return SPINE_MAJOR_VERSION; } -FFI_PLUGIN_EXPORT int32_t spine_minor_version() { +EMSCRIPTEN_KEEPALIVE int32_t spine_minor_version() { return SPINE_MINOR_VERSION; } -void spine_report_leaks() { +EMSCRIPTEN_KEEPALIVE void spine_report_leaks() { ((DebugExtension*)spine::SpineExtension::getInstance())->reportLeaks(); } // Color -FFI_PLUGIN_EXPORT float spine_color_get_r(spine_color color) { +EMSCRIPTEN_KEEPALIVE float spine_color_get_r(spine_color color) { if (!color) return 0; return ((Color*)color)->r; } -FFI_PLUGIN_EXPORT float spine_color_get_g(spine_color color) { +EMSCRIPTEN_KEEPALIVE float spine_color_get_g(spine_color color) { if (!color) return 0; return ((Color*)color)->g; } -FFI_PLUGIN_EXPORT float spine_color_get_b(spine_color color) { +EMSCRIPTEN_KEEPALIVE float spine_color_get_b(spine_color color) { if (!color) return 0; return ((Color*)color)->b; } -FFI_PLUGIN_EXPORT float spine_color_get_a(spine_color color) { +EMSCRIPTEN_KEEPALIVE float spine_color_get_a(spine_color color) { if (!color) return 0; return ((Color*)color)->a; } // Bounds -FFI_PLUGIN_EXPORT float spine_bounds_get_x(spine_bounds bounds) { +EMSCRIPTEN_KEEPALIVE float spine_bounds_get_x(spine_bounds bounds) { if (!bounds) return 0; return ((_spine_bounds*)bounds)->x; } -FFI_PLUGIN_EXPORT float spine_bounds_get_y(spine_bounds bounds) { +EMSCRIPTEN_KEEPALIVE float spine_bounds_get_y(spine_bounds bounds) { if (!bounds) return 0; return ((_spine_bounds*)bounds)->y; } -FFI_PLUGIN_EXPORT float spine_bounds_get_width(spine_bounds bounds) { +EMSCRIPTEN_KEEPALIVE float spine_bounds_get_width(spine_bounds bounds) { if (!bounds) return 0; return ((_spine_bounds*)bounds)->width; } -FFI_PLUGIN_EXPORT float spine_bounds_get_height(spine_bounds bounds) { +EMSCRIPTEN_KEEPALIVE float spine_bounds_get_height(spine_bounds bounds) { if (!bounds) return 0; return ((_spine_bounds*)bounds)->height; } // Vector -FFI_PLUGIN_EXPORT float spine_vector_get_x(spine_vector vector) { +EMSCRIPTEN_KEEPALIVE float spine_vector_get_x(spine_vector vector) { if (!vector) return 0; return ((_spine_vector*)vector)->x; } -FFI_PLUGIN_EXPORT float spine_vector_get_y(spine_vector vector) { +EMSCRIPTEN_KEEPALIVE float spine_vector_get_y(spine_vector vector) { if (!vector) return 0; return ((_spine_vector*)vector)->y; } // Atlas -FFI_PLUGIN_EXPORT spine_atlas spine_atlas_load(const utf8 *atlasData) { +EMSCRIPTEN_KEEPALIVE spine_atlas spine_atlas_load(const utf8 *atlasData) { if (!atlasData) return nullptr; int32_t length = (int32_t)strlen((char*)atlasData); auto atlas = new (__FILE__, __LINE__) Atlas((char*)atlasData, length, "", (TextureLoader*)nullptr, false); @@ -190,22 +196,22 @@ FFI_PLUGIN_EXPORT spine_atlas spine_atlas_load(const utf8 *atlasData) { return (spine_atlas)result; } -FFI_PLUGIN_EXPORT int32_t spine_atlas_get_num_image_paths(spine_atlas atlas) { +EMSCRIPTEN_KEEPALIVE int32_t spine_atlas_get_num_image_paths(spine_atlas atlas) { if (!atlas) return 0; return ((_spine_atlas*)atlas)->numImagePaths; } -FFI_PLUGIN_EXPORT utf8 *spine_atlas_get_image_path(spine_atlas atlas, int32_t index) { +EMSCRIPTEN_KEEPALIVE utf8 *spine_atlas_get_image_path(spine_atlas atlas, int32_t index) { if (!atlas) return nullptr; return ((_spine_atlas*)atlas)->imagePaths[index]; } -FFI_PLUGIN_EXPORT utf8 *spine_atlas_get_error(spine_atlas atlas) { +EMSCRIPTEN_KEEPALIVE utf8 *spine_atlas_get_error(spine_atlas atlas) { if (!atlas) return nullptr; return ((_spine_atlas*)atlas)->error; } -FFI_PLUGIN_EXPORT void spine_atlas_dispose(spine_atlas atlas) { +EMSCRIPTEN_KEEPALIVE void spine_atlas_dispose(spine_atlas atlas) { if (!atlas) return; _spine_atlas *_atlas = (_spine_atlas*)atlas; if (_atlas->atlas) delete (Atlas*)_atlas->atlas; @@ -219,7 +225,7 @@ FFI_PLUGIN_EXPORT void spine_atlas_dispose(spine_atlas atlas) { // SkeletonData -FFI_PLUGIN_EXPORT spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, const utf8 *skeletonData) { +EMSCRIPTEN_KEEPALIVE spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, const utf8 *skeletonData) { _spine_skeleton_data_result *result = SpineExtension::calloc<_spine_skeleton_data_result>(1, __FILE__, __LINE__); _spine_atlas *_atlas = (_spine_atlas*)atlas; Bone::setYDown(true); @@ -235,7 +241,7 @@ FFI_PLUGIN_EXPORT spine_skeleton_data_result spine_skeleton_data_load_json(spine return (spine_skeleton_data_result)result; } -FFI_PLUGIN_EXPORT spine_skeleton_data_result spine_skeleton_data_load_binary(spine_atlas atlas, const uint8_t *skeletonData, int32_t length) { +EMSCRIPTEN_KEEPALIVE spine_skeleton_data_result spine_skeleton_data_load_binary(spine_atlas atlas, const uint8_t *skeletonData, int32_t length) { _spine_skeleton_data_result *result = SpineExtension::calloc<_spine_skeleton_data_result>(1, __FILE__, __LINE__); _spine_atlas *_atlas = (_spine_atlas*)atlas; Bone::setYDown(true); @@ -252,263 +258,263 @@ FFI_PLUGIN_EXPORT spine_skeleton_data_result spine_skeleton_data_load_binary(spi return (spine_skeleton_data_result)result; } -FFI_PLUGIN_EXPORT utf8 *spine_skeleton_data_result_get_error(spine_skeleton_data_result result) { +EMSCRIPTEN_KEEPALIVE utf8 *spine_skeleton_data_result_get_error(spine_skeleton_data_result result) { if (!result) return nullptr; return ((_spine_skeleton_data_result*)result)->error; } -FFI_PLUGIN_EXPORT spine_skeleton_data spine_skeleton_data_result_get_data(spine_skeleton_data_result result) { +EMSCRIPTEN_KEEPALIVE spine_skeleton_data spine_skeleton_data_result_get_data(spine_skeleton_data_result result) { if (!result) return nullptr; return ((_spine_skeleton_data_result*)result)->skeletonData; } -FFI_PLUGIN_EXPORT void spine_skeleton_data_result_dispose(spine_skeleton_data_result result) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_data_result_dispose(spine_skeleton_data_result result) { if (!result) return; _spine_skeleton_data_result *_result = (_spine_skeleton_data_result*)result; if (_result->error) SpineExtension::free(_result->error, __FILE__, __LINE__); SpineExtension::free(_result, __FILE__, __LINE__); } -FFI_PLUGIN_EXPORT spine_bone_data spine_skeleton_data_find_bone(spine_skeleton_data data, const utf8 *name) { +EMSCRIPTEN_KEEPALIVE spine_bone_data spine_skeleton_data_find_bone(spine_skeleton_data data, const utf8 *name) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_bone_data)_data->findBone((char*)name); } -FFI_PLUGIN_EXPORT spine_slot_data spine_skeleton_data_find_slot(spine_skeleton_data data, const utf8 *name) { +EMSCRIPTEN_KEEPALIVE spine_slot_data spine_skeleton_data_find_slot(spine_skeleton_data data, const utf8 *name) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_slot_data)_data->findSlot((char*)name); } -FFI_PLUGIN_EXPORT spine_skin spine_skeleton_data_find_skin(spine_skeleton_data data, const utf8 *name) { +EMSCRIPTEN_KEEPALIVE spine_skin spine_skeleton_data_find_skin(spine_skeleton_data data, const utf8 *name) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_skin)_data->findSkin((char*)name); } -FFI_PLUGIN_EXPORT spine_event_data spine_skeleton_data_find_event(spine_skeleton_data data, const utf8 *name) { +EMSCRIPTEN_KEEPALIVE spine_event_data spine_skeleton_data_find_event(spine_skeleton_data data, const utf8 *name) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_event_data)_data->findEvent((char*)name); } -FFI_PLUGIN_EXPORT spine_animation spine_skeleton_data_find_animation(spine_skeleton_data data, const utf8 *name) { +EMSCRIPTEN_KEEPALIVE spine_animation spine_skeleton_data_find_animation(spine_skeleton_data data, const utf8 *name) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_animation)_data->findAnimation((char*)name); } -FFI_PLUGIN_EXPORT spine_ik_constraint_data spine_skeleton_data_find_ik_constraint(spine_skeleton_data data, const utf8 *name) { +EMSCRIPTEN_KEEPALIVE spine_ik_constraint_data spine_skeleton_data_find_ik_constraint(spine_skeleton_data data, const utf8 *name) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_ik_constraint_data)_data->findIkConstraint((char*)name); } -FFI_PLUGIN_EXPORT spine_transform_constraint_data spine_skeleton_data_find_transform_constraint(spine_skeleton_data data, const utf8 *name) { +EMSCRIPTEN_KEEPALIVE spine_transform_constraint_data spine_skeleton_data_find_transform_constraint(spine_skeleton_data data, const utf8 *name) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_transform_constraint_data)_data->findTransformConstraint((char*)name); } -FFI_PLUGIN_EXPORT spine_path_constraint_data spine_skeleton_data_find_path_constraint(spine_skeleton_data data, const utf8 *name) { +EMSCRIPTEN_KEEPALIVE spine_path_constraint_data spine_skeleton_data_find_path_constraint(spine_skeleton_data data, const utf8 *name) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_path_constraint_data)_data->findPathConstraint((char*)name); } -FFI_PLUGIN_EXPORT const utf8* spine_skeleton_data_get_name(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_skeleton_data_get_name(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (utf8*)_data->getName().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_bones(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_data_get_num_bones(spine_skeleton_data data) { if (data == nullptr) return 0; SkeletonData *_data = (SkeletonData*)data; return (int32_t)_data->getBones().size(); } -FFI_PLUGIN_EXPORT spine_bone_data* spine_skeleton_data_get_bones(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE spine_bone_data* spine_skeleton_data_get_bones(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_bone_data*)_data->getBones().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_slots(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_data_get_num_slots(spine_skeleton_data data) { if (data == nullptr) return 0; SkeletonData *_data = (SkeletonData*)data; return (int32_t)_data->getSlots().size(); } -FFI_PLUGIN_EXPORT spine_slot_data* spine_skeleton_data_get_slots(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE spine_slot_data* spine_skeleton_data_get_slots(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_slot_data*)_data->getSlots().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_skins(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_data_get_num_skins(spine_skeleton_data data) { if (data == nullptr) return 0; SkeletonData *_data = (SkeletonData*)data; return (int32_t)_data->getSkins().size(); } -FFI_PLUGIN_EXPORT spine_skin* spine_skeleton_data_get_skins(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE spine_skin* spine_skeleton_data_get_skins(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_skin*)_data->getSkins().buffer(); } -FFI_PLUGIN_EXPORT spine_skin spine_skeleton_data_get_default_skin(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE spine_skin spine_skeleton_data_get_default_skin(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_skin)_data->getDefaultSkin(); } -FFI_PLUGIN_EXPORT void spine_skeleton_data_set_default_skin(spine_skeleton_data data, spine_skin skin) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_data_set_default_skin(spine_skeleton_data data, spine_skin skin) { if (data == nullptr) return; SkeletonData *_data = (SkeletonData*)data; _data->setDefaultSkin((Skin*)skin); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_events(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_data_get_num_events(spine_skeleton_data data) { if (data == nullptr) return 0; SkeletonData *_data = (SkeletonData*)data; return (int32_t)_data->getEvents().size(); } -FFI_PLUGIN_EXPORT spine_event_data* spine_skeleton_data_get_events(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE spine_event_data* spine_skeleton_data_get_events(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_event_data*)_data->getEvents().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_animations(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_data_get_num_animations(spine_skeleton_data data) { if (data == nullptr) return 0; SkeletonData *_data = (SkeletonData*)data; return (int32_t)_data->getAnimations().size(); } -FFI_PLUGIN_EXPORT spine_animation* spine_skeleton_data_get_animations(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE spine_animation* spine_skeleton_data_get_animations(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_animation*)_data->getAnimations().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_ik_constraints(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_data_get_num_ik_constraints(spine_skeleton_data data) { if (data == nullptr) return 0; SkeletonData *_data = (SkeletonData*)data; return (int32_t)_data->getIkConstraints().size(); } -FFI_PLUGIN_EXPORT spine_ik_constraint_data* spine_skeleton_data_get_ik_constraints(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE spine_ik_constraint_data* spine_skeleton_data_get_ik_constraints(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_ik_constraint_data*)_data->getIkConstraints().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_transform_constraints(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_data_get_num_transform_constraints(spine_skeleton_data data) { if (data == nullptr) return 0; SkeletonData *_data = (SkeletonData*)data; return (int32_t)_data->getTransformConstraints().size(); } -FFI_PLUGIN_EXPORT spine_transform_constraint_data* spine_skeleton_data_get_transform_constraints(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE spine_transform_constraint_data* spine_skeleton_data_get_transform_constraints(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_transform_constraint_data*)_data->getTransformConstraints().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_data_get_num_path_constraints(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_data_get_num_path_constraints(spine_skeleton_data data) { if (data == nullptr) return 0; SkeletonData *_data = (SkeletonData*)data; return (int32_t)_data->getPathConstraints().size(); } -FFI_PLUGIN_EXPORT spine_path_constraint_data* spine_skeleton_data_get_path_constraints(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE spine_path_constraint_data* spine_skeleton_data_get_path_constraints(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (spine_path_constraint_data*)_data->getPathConstraints().buffer(); } -FFI_PLUGIN_EXPORT float spine_skeleton_data_get_x(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE float spine_skeleton_data_get_x(spine_skeleton_data data) { if (data == nullptr) return 0; SkeletonData *_data = (SkeletonData*)data; return _data->getX(); } -FFI_PLUGIN_EXPORT void spine_skeleton_data_set_x(spine_skeleton_data data, float x) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_data_set_x(spine_skeleton_data data, float x) { if (data == nullptr) return; SkeletonData *_data = (SkeletonData*)data; _data->setX(x); } -FFI_PLUGIN_EXPORT float spine_skeleton_data_get_y(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE float spine_skeleton_data_get_y(spine_skeleton_data data) { if (data == nullptr) return 0; SkeletonData *_data = (SkeletonData*)data; return _data->getY(); } -FFI_PLUGIN_EXPORT void spine_skeleton_data_set_y(spine_skeleton_data data, float y) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_data_set_y(spine_skeleton_data data, float y) { if (data == nullptr) return; SkeletonData *_data = (SkeletonData*)data; _data->setY(y); } -FFI_PLUGIN_EXPORT float spine_skeleton_data_get_width(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE float spine_skeleton_data_get_width(spine_skeleton_data data) { if (data == nullptr) return 0; SkeletonData *_data = (SkeletonData*)data; return _data->getWidth(); } -FFI_PLUGIN_EXPORT void spine_skeleton_data_set_width(spine_skeleton_data data, float width) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_data_set_width(spine_skeleton_data data, float width) { if (data == nullptr) return; SkeletonData *_data = (SkeletonData*)data; _data->setWidth(width); } -FFI_PLUGIN_EXPORT float spine_skeleton_data_get_height(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE float spine_skeleton_data_get_height(spine_skeleton_data data) { if (data == nullptr) return 0; SkeletonData *_data = (SkeletonData*)data; return _data->getHeight(); } -FFI_PLUGIN_EXPORT void spine_skeleton_data_set_height(spine_skeleton_data data, float height) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_data_set_height(spine_skeleton_data data, float height) { if (data == nullptr) return; SkeletonData *_data = (SkeletonData*)data; _data->setHeight(height); } -FFI_PLUGIN_EXPORT const utf8* spine_skeleton_data_get_version(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_skeleton_data_get_version(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (utf8*)_data->getVersion().buffer(); } -FFI_PLUGIN_EXPORT const utf8* spine_skeleton_data_get_hash(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_skeleton_data_get_hash(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (utf8*)_data->getHash().buffer(); } -FFI_PLUGIN_EXPORT const utf8* spine_skeleton_data_get_images_path(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_skeleton_data_get_images_path(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (utf8*)_data->getImagesPath().buffer(); } -FFI_PLUGIN_EXPORT const utf8* spine_skeleton_data_get_audio_path(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_skeleton_data_get_audio_path(spine_skeleton_data data) { if (data == nullptr) return nullptr; SkeletonData *_data = (SkeletonData*)data; return (utf8*)_data->getAudioPath().buffer(); } -FFI_PLUGIN_EXPORT float spine_skeleton_data_get_fps(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE float spine_skeleton_data_get_fps(spine_skeleton_data data) { if (data == nullptr) return 0; SkeletonData *_data = (SkeletonData*)data; return _data->getFps(); } -FFI_PLUGIN_EXPORT void spine_skeleton_data_dispose(spine_skeleton_data data) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_data_dispose(spine_skeleton_data data) { if (!data) return; delete (SkeletonData*)data; } @@ -539,7 +545,7 @@ void spine_render_command_dispose(_spine_render_command *cmd) { // SkeletonDrawable -FFI_PLUGIN_EXPORT spine_skeleton_drawable spine_skeleton_drawable_create(spine_skeleton_data skeletonData) { +EMSCRIPTEN_KEEPALIVE spine_skeleton_drawable spine_skeleton_drawable_create(spine_skeleton_data skeletonData) { _spine_skeleton_drawable *drawable = SpineExtension::calloc<_spine_skeleton_drawable>(1, __FILE__, __LINE__); drawable->skeleton = (spine_skeleton)new (__FILE__, __LINE__) Skeleton((SkeletonData*)skeletonData); AnimationStateData *stateData = new (__FILE__, __LINE__) AnimationStateData((SkeletonData*)skeletonData); @@ -554,7 +560,7 @@ FFI_PLUGIN_EXPORT spine_skeleton_drawable spine_skeleton_drawable_create(spine_s return (spine_skeleton_drawable)drawable; } -FFI_PLUGIN_EXPORT void spine_skeleton_drawable_dispose(spine_skeleton_drawable drawable) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_drawable_dispose(spine_skeleton_drawable drawable) { _spine_skeleton_drawable *_drawable = (_spine_skeleton_drawable*)drawable; if (!_drawable) return; if (_drawable->skeleton) delete (Skeleton*)_drawable->skeleton; @@ -570,7 +576,7 @@ FFI_PLUGIN_EXPORT void spine_skeleton_drawable_dispose(spine_skeleton_drawable d SpineExtension::free(drawable, __FILE__, __LINE__); } -FFI_PLUGIN_EXPORT spine_render_command spine_skeleton_drawable_render(spine_skeleton_drawable drawable) { +EMSCRIPTEN_KEEPALIVE spine_render_command spine_skeleton_drawable_render(spine_skeleton_drawable drawable) { _spine_skeleton_drawable *_drawable = (_spine_skeleton_drawable*)drawable; if (!_drawable) return nullptr; if (!_drawable->skeleton) return nullptr; @@ -691,127 +697,127 @@ FFI_PLUGIN_EXPORT spine_render_command spine_skeleton_drawable_render(spine_skel return (spine_render_command)_drawable->renderCommand; } -FFI_PLUGIN_EXPORT spine_skeleton spine_skeleton_drawable_get_skeleton(spine_skeleton_drawable drawable) { +EMSCRIPTEN_KEEPALIVE spine_skeleton spine_skeleton_drawable_get_skeleton(spine_skeleton_drawable drawable) { if (!drawable) return nullptr; return ((_spine_skeleton_drawable*)drawable)->skeleton; } -FFI_PLUGIN_EXPORT spine_animation_state spine_skeleton_drawable_get_animation_state(spine_skeleton_drawable drawable) { +EMSCRIPTEN_KEEPALIVE spine_animation_state spine_skeleton_drawable_get_animation_state(spine_skeleton_drawable drawable) { if (!drawable) return nullptr; return ((_spine_skeleton_drawable*)drawable)->animationState; } -FFI_PLUGIN_EXPORT spine_animation_state_data spine_skeleton_drawable_get_animation_state_data(spine_skeleton_drawable drawable) { +EMSCRIPTEN_KEEPALIVE spine_animation_state_data spine_skeleton_drawable_get_animation_state_data(spine_skeleton_drawable drawable) { if (!drawable) return nullptr; return ((_spine_skeleton_drawable*)drawable)->animationStateData; } -FFI_PLUGIN_EXPORT spine_animation_state_events spine_skeleton_drawable_get_animation_state_events(spine_skeleton_drawable drawable) { +EMSCRIPTEN_KEEPALIVE spine_animation_state_events spine_skeleton_drawable_get_animation_state_events(spine_skeleton_drawable drawable) { if (!drawable) return nullptr; return ((_spine_skeleton_drawable*)drawable)->animationStateEvents; } // Render command -FFI_PLUGIN_EXPORT float *spine_render_command_get_positions(spine_render_command command) { +EMSCRIPTEN_KEEPALIVE float *spine_render_command_get_positions(spine_render_command command) { if (!command) return nullptr; return ((_spine_render_command*)command)->positions; } -FFI_PLUGIN_EXPORT float *spine_render_command_get_uvs(spine_render_command command) { +EMSCRIPTEN_KEEPALIVE float *spine_render_command_get_uvs(spine_render_command command) { if (!command) return nullptr; return ((_spine_render_command*)command)->uvs; } -FFI_PLUGIN_EXPORT int32_t *spine_render_command_get_colors(spine_render_command command) { +EMSCRIPTEN_KEEPALIVE int32_t *spine_render_command_get_colors(spine_render_command command) { if (!command) return nullptr; return ((_spine_render_command*)command)->colors; } -FFI_PLUGIN_EXPORT int32_t spine_render_command_get_num_vertices(spine_render_command command) { +EMSCRIPTEN_KEEPALIVE int32_t spine_render_command_get_num_vertices(spine_render_command command) { if (!command) return 0; return ((_spine_render_command*)command)->numVertices; } -FFI_PLUGIN_EXPORT uint16_t *spine_render_command_get_indices(spine_render_command command) { +EMSCRIPTEN_KEEPALIVE uint16_t *spine_render_command_get_indices(spine_render_command command) { if (!command) return nullptr; return ((_spine_render_command*)command)->indices; } -FFI_PLUGIN_EXPORT int32_t spine_render_command_get_num_indices(spine_render_command command) { +EMSCRIPTEN_KEEPALIVE int32_t spine_render_command_get_num_indices(spine_render_command command) { if (!command) return 0; return ((_spine_render_command*)command)->numIndices; } -FFI_PLUGIN_EXPORT int32_t spine_render_command_get_atlas_page(spine_render_command command) { +EMSCRIPTEN_KEEPALIVE int32_t spine_render_command_get_atlas_page(spine_render_command command) { if (!command) return 0; return ((_spine_render_command*)command)->atlasPage; } -FFI_PLUGIN_EXPORT spine_blend_mode spine_render_command_get_blend_mode(spine_render_command command) { +EMSCRIPTEN_KEEPALIVE spine_blend_mode spine_render_command_get_blend_mode(spine_render_command command) { if (!command) return SPINE_BLEND_MODE_NORMAL; return ((_spine_render_command*)command)->blendMode; } -FFI_PLUGIN_EXPORT spine_render_command spine_render_command_get_next(spine_render_command command) { +EMSCRIPTEN_KEEPALIVE spine_render_command spine_render_command_get_next(spine_render_command command) { if (!command) return nullptr; return (spine_render_command)((_spine_render_command*)command)->next; } // Animation -FFI_PLUGIN_EXPORT const utf8* spine_animation_get_name(spine_animation animation) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_animation_get_name(spine_animation animation) { if (animation == nullptr) return nullptr; Animation *_animation = (Animation*)animation; return (utf8*)_animation->getName().buffer(); } -FFI_PLUGIN_EXPORT float spine_animation_get_duration(spine_animation animation) { +EMSCRIPTEN_KEEPALIVE float spine_animation_get_duration(spine_animation animation) { if (animation == nullptr) return 0; Animation *_animation = (Animation*)animation; return _animation->getDuration(); } // AnimationStateData -FFI_PLUGIN_EXPORT spine_skeleton_data spine_animation_state_data_get_skeleton_data(spine_animation_state_data stateData) { +EMSCRIPTEN_KEEPALIVE spine_skeleton_data spine_animation_state_data_get_skeleton_data(spine_animation_state_data stateData) { if (stateData == nullptr) return nullptr; AnimationStateData* _stateData = (AnimationStateData*)stateData; return (spine_skeleton_data)_stateData->getSkeletonData(); } -FFI_PLUGIN_EXPORT float spine_animation_state_data_get_default_mix(spine_animation_state_data stateData) { +EMSCRIPTEN_KEEPALIVE float spine_animation_state_data_get_default_mix(spine_animation_state_data stateData) { if (stateData == nullptr) return 0; AnimationStateData* _stateData = (AnimationStateData*)stateData; return _stateData->getDefaultMix(); } -FFI_PLUGIN_EXPORT void spine_animation_state_data_set_default_mix(spine_animation_state_data stateData, float defaultMix) { +EMSCRIPTEN_KEEPALIVE void spine_animation_state_data_set_default_mix(spine_animation_state_data stateData, float defaultMix) { if (stateData == nullptr) return; AnimationStateData* _stateData = (AnimationStateData*)stateData; _stateData->setDefaultMix(defaultMix); } -FFI_PLUGIN_EXPORT void spine_animation_state_data_set_mix(spine_animation_state_data stateData, spine_animation from, spine_animation to, float duration) { +EMSCRIPTEN_KEEPALIVE void spine_animation_state_data_set_mix(spine_animation_state_data stateData, spine_animation from, spine_animation to, float duration) { if (stateData == nullptr) return; if (from == nullptr || to == nullptr) return; AnimationStateData* _stateData = (AnimationStateData*)stateData; _stateData->setMix((Animation*)from, (Animation*)to, duration); } -FFI_PLUGIN_EXPORT float spine_animation_state_data_get_mix(spine_animation_state_data stateData, spine_animation from, spine_animation to) { +EMSCRIPTEN_KEEPALIVE float spine_animation_state_data_get_mix(spine_animation_state_data stateData, spine_animation from, spine_animation to) { if (stateData == nullptr) return 0; if (from == nullptr || to == nullptr) return 0; AnimationStateData* _stateData = (AnimationStateData*)stateData; return _stateData->getMix((Animation*)from, (Animation*)to); } -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) { +EMSCRIPTEN_KEEPALIVE void spine_animation_state_data_set_mix_by_name(spine_animation_state_data stateData, const utf8* fromName, const utf8* toName, float duration) { if (stateData == nullptr) return; if (fromName == nullptr || toName == nullptr) return; AnimationStateData* _stateData = (AnimationStateData*)stateData; _stateData->setMix((char*)fromName, (char*)toName, duration); } -FFI_PLUGIN_EXPORT float spine_animation_state_data_get_mix_by_name(spine_animation_state_data stateData, const utf8* fromName, const utf8* toName) { +EMSCRIPTEN_KEEPALIVE float spine_animation_state_data_get_mix_by_name(spine_animation_state_data stateData, const utf8* fromName, const utf8* toName) { if (stateData == nullptr) return 0; AnimationStateData* _stateData = (AnimationStateData*)stateData; Animation* from = _stateData->getSkeletonData()->findAnimation((char*)fromName); @@ -820,123 +826,123 @@ FFI_PLUGIN_EXPORT float spine_animation_state_data_get_mix_by_name(spine_animati return _stateData->getMix(from, to); } -FFI_PLUGIN_EXPORT void spine_animation_state_data_clear(spine_animation_state_data stateData) { +EMSCRIPTEN_KEEPALIVE void spine_animation_state_data_clear(spine_animation_state_data stateData) { if (stateData == nullptr) return ; AnimationStateData* _stateData = (AnimationStateData*)stateData; _stateData->clear(); } // AnimationState -FFI_PLUGIN_EXPORT void spine_animation_state_update(spine_animation_state state, float delta) { +EMSCRIPTEN_KEEPALIVE void spine_animation_state_update(spine_animation_state state, float delta) { if (state == nullptr) return; AnimationState *_state = (AnimationState*)state; _state->update(delta); } -FFI_PLUGIN_EXPORT void spine_animation_state_dispose_track_entry(spine_animation_state state, spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE void spine_animation_state_dispose_track_entry(spine_animation_state state, spine_track_entry entry) { if (state == nullptr) return; if (entry == nullptr) return; AnimationState *_state = (AnimationState*)state; _state->disposeTrackEntry((TrackEntry*)entry); } -FFI_PLUGIN_EXPORT void spine_animation_state_apply(spine_animation_state state, spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE void spine_animation_state_apply(spine_animation_state state, spine_skeleton skeleton) { if (state == nullptr) return; AnimationState *_state = (AnimationState*)state; _state->apply(*(Skeleton*)skeleton); } -FFI_PLUGIN_EXPORT void spine_animation_state_clear_tracks(spine_animation_state state) { +EMSCRIPTEN_KEEPALIVE void spine_animation_state_clear_tracks(spine_animation_state state) { if (state == nullptr) return; AnimationState *_state = (AnimationState*)state; _state->clearTracks(); } -FFI_PLUGIN_EXPORT int32_t spine_animation_state_get_num_tracks(spine_animation_state state) { +EMSCRIPTEN_KEEPALIVE int32_t spine_animation_state_get_num_tracks(spine_animation_state state) { if (state == nullptr) return 0; AnimationState *_state = (AnimationState*)state; return (int32_t) _state->getTracks().size(); } -FFI_PLUGIN_EXPORT void spine_animation_state_clear_track(spine_animation_state state, int32_t trackIndex) { +EMSCRIPTEN_KEEPALIVE void spine_animation_state_clear_track(spine_animation_state state, int32_t trackIndex) { if (state == nullptr) return; AnimationState *_state = (AnimationState*)state; _state->clearTrack(trackIndex); } -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) { +EMSCRIPTEN_KEEPALIVE spine_track_entry spine_animation_state_set_animation_by_name(spine_animation_state state, int32_t trackIndex, const utf8* animationName, int32_t loop) { if (state == nullptr) return nullptr; AnimationState *_state = (AnimationState*)state; return (spine_track_entry)_state->setAnimation(trackIndex, (char*)animationName, 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) { +EMSCRIPTEN_KEEPALIVE spine_track_entry spine_animation_state_set_animation(spine_animation_state state, int32_t trackIndex, spine_animation animation, int32_t loop) { if (state == nullptr) return nullptr; AnimationState *_state = (AnimationState*)state; return (spine_track_entry)_state->setAnimation(trackIndex, (Animation*)animation, 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) { +EMSCRIPTEN_KEEPALIVE 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) { if (state == nullptr) return nullptr; AnimationState *_state = (AnimationState*)state; return (spine_track_entry)_state->addAnimation(trackIndex, (char*)animationName, loop, 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) { +EMSCRIPTEN_KEEPALIVE spine_track_entry spine_animation_state_add_animation(spine_animation_state state, int32_t trackIndex, spine_animation animation, int32_t loop, float delay) { if (state == nullptr) return nullptr; AnimationState *_state = (AnimationState*)state; return (spine_track_entry)_state->addAnimation(trackIndex, (Animation*)animation, loop, delay); } -FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_set_empty_animation(spine_animation_state state, int32_t trackIndex, float mixDuration) { +EMSCRIPTEN_KEEPALIVE spine_track_entry spine_animation_state_set_empty_animation(spine_animation_state state, int32_t trackIndex, float mixDuration) { if (state == nullptr) return nullptr; AnimationState *_state = (AnimationState*)state; return (spine_track_entry)_state->setEmptyAnimation(trackIndex, mixDuration); } -FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_add_empty_animation(spine_animation_state state, int32_t trackIndex, float mixDuration, float delay) { +EMSCRIPTEN_KEEPALIVE spine_track_entry spine_animation_state_add_empty_animation(spine_animation_state state, int32_t trackIndex, float mixDuration, float delay) { if (state == nullptr) return nullptr; AnimationState *_state = (AnimationState*)state; return (spine_track_entry)_state->addEmptyAnimation(trackIndex, mixDuration, delay); } -FFI_PLUGIN_EXPORT void spine_animation_state_set_empty_animations(spine_animation_state state, float mixDuration) { +EMSCRIPTEN_KEEPALIVE void spine_animation_state_set_empty_animations(spine_animation_state state, float mixDuration) { if (state == nullptr) return; AnimationState *_state = (AnimationState*)state; _state->setEmptyAnimations(mixDuration); } -FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_get_current(spine_animation_state state, int32_t trackIndex) { +EMSCRIPTEN_KEEPALIVE spine_track_entry spine_animation_state_get_current(spine_animation_state state, int32_t trackIndex) { if (state == nullptr) return nullptr; AnimationState *_state = (AnimationState*)state; return (spine_track_entry)_state->getCurrent(trackIndex); } -FFI_PLUGIN_EXPORT spine_animation_state_data spine_animation_state_get_data(spine_animation_state state) { +EMSCRIPTEN_KEEPALIVE spine_animation_state_data spine_animation_state_get_data(spine_animation_state state) { if (state == nullptr) return nullptr; AnimationState *_state = (AnimationState*)state; return (spine_animation_state_data)_state->getData(); } -FFI_PLUGIN_EXPORT float spine_animation_state_get_time_scale(spine_animation_state state) { +EMSCRIPTEN_KEEPALIVE float spine_animation_state_get_time_scale(spine_animation_state state) { if (state == nullptr) return 0; AnimationState *_state = (AnimationState*)state; return _state->getTimeScale(); } -FFI_PLUGIN_EXPORT void spine_animation_state_set_time_scale(spine_animation_state state, float timeScale) { +EMSCRIPTEN_KEEPALIVE void spine_animation_state_set_time_scale(spine_animation_state state, float timeScale) { if (state == nullptr) return; AnimationState *_state = (AnimationState*)state; _state->setTimeScale(timeScale); } -FFI_PLUGIN_EXPORT int32_t spine_animation_state_events_get_num_events(spine_animation_state_events events) { +EMSCRIPTEN_KEEPALIVE int32_t spine_animation_state_events_get_num_events(spine_animation_state_events events) { if (events == nullptr) return 0; EventListener *_events = (EventListener*)events; return (int32_t)_events->events.size(); } -FFI_PLUGIN_EXPORT spine_event_type spine_animation_state_events_get_event_type(spine_animation_state_events events, int32_t index) { +EMSCRIPTEN_KEEPALIVE spine_event_type spine_animation_state_events_get_event_type(spine_animation_state_events events, int32_t index) { if (events == nullptr) return SPINE_EVENT_TYPE_DISPOSE; if (index < 0) return SPINE_EVENT_TYPE_DISPOSE; EventListener *_events = (EventListener*)events; @@ -944,21 +950,21 @@ FFI_PLUGIN_EXPORT spine_event_type spine_animation_state_events_get_event_type(s return (spine_event_type)_events->events[index].type; } -FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_events_get_track_entry(spine_animation_state_events events, int32_t index) { +EMSCRIPTEN_KEEPALIVE spine_track_entry spine_animation_state_events_get_track_entry(spine_animation_state_events events, int32_t index) { if (events == nullptr) return nullptr; EventListener *_events = (EventListener*)events; if (index >= _events->events.size()) return nullptr; return (spine_track_entry)_events->events[index].entry; } -FFI_PLUGIN_EXPORT spine_event spine_animation_state_events_get_event(spine_animation_state_events events, int32_t index) { +EMSCRIPTEN_KEEPALIVE spine_event spine_animation_state_events_get_event(spine_animation_state_events events, int32_t index) { if (events == nullptr) return nullptr; EventListener *_events = (EventListener*)events; if (index >= _events->events.size()) return nullptr; return (spine_event)_events->events[index].event; } -FFI_PLUGIN_EXPORT void spine_animation_state_events_reset(spine_animation_state_events events) { +EMSCRIPTEN_KEEPALIVE void spine_animation_state_events_reset(spine_animation_state_events events) { if (events == nullptr) return; EventListener *_events = (EventListener*)events; _events->events.clear(); @@ -966,277 +972,277 @@ FFI_PLUGIN_EXPORT void spine_animation_state_events_reset(spine_animation_state_ // TrackEntry -FFI_PLUGIN_EXPORT int32_t spine_track_entry_get_track_index(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE int32_t spine_track_entry_get_track_index(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getTrackIndex(); } -FFI_PLUGIN_EXPORT spine_animation spine_track_entry_get_animation(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE spine_animation spine_track_entry_get_animation(spine_track_entry entry) { if (entry == nullptr) return nullptr; TrackEntry *_entry = (TrackEntry*)entry; return (spine_animation)_entry->getAnimation(); } -FFI_PLUGIN_EXPORT spine_track_entry spine_track_entry_get_previous(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE spine_track_entry spine_track_entry_get_previous(spine_track_entry entry) { if (entry == nullptr) return nullptr; TrackEntry *_entry = (TrackEntry*)entry; return (spine_track_entry)_entry->getPrevious(); } -FFI_PLUGIN_EXPORT int32_t spine_track_entry_get_loop(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE int32_t spine_track_entry_get_loop(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getLoop() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_track_entry_set_loop(spine_track_entry entry, int32_t loop) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_loop(spine_track_entry entry, int32_t loop) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setLoop(loop); } -FFI_PLUGIN_EXPORT int32_t spine_track_entry_get_hold_previous(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE int32_t spine_track_entry_get_hold_previous(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getHoldPrevious() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_track_entry_set_hold_previous(spine_track_entry entry, int32_t holdPrevious) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_hold_previous(spine_track_entry entry, int32_t holdPrevious) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setHoldPrevious(holdPrevious); } -FFI_PLUGIN_EXPORT int32_t spine_track_entry_get_reverse(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE int32_t spine_track_entry_get_reverse(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getReverse() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_track_entry_set_reverse(spine_track_entry entry, int32_t reverse) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_reverse(spine_track_entry entry, int32_t reverse) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setReverse(reverse); } -FFI_PLUGIN_EXPORT int32_t spine_track_entry_get_shortest_rotation(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE int32_t spine_track_entry_get_shortest_rotation(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getShortestRotation() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_track_entry_set_shortest_rotation(spine_track_entry entry, int32_t shortestRotation) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_shortest_rotation(spine_track_entry entry, int32_t shortestRotation) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setShortestRotation(shortestRotation); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_delay(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_delay(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getDelay(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_delay(spine_track_entry entry, float delay) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_delay(spine_track_entry entry, float delay) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setDelay(delay); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_track_time(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_track_time(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getTrackTime(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_track_time(spine_track_entry entry, float trackTime) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_track_time(spine_track_entry entry, float trackTime) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setTrackTime(trackTime); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_track_end(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_track_end(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getTrackEnd(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_track_end(spine_track_entry entry, float trackEnd) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_track_end(spine_track_entry entry, float trackEnd) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setTrackEnd(trackEnd); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_animation_start(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_animation_start(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getAnimationStart(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_animation_start(spine_track_entry entry, float animationStart) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_animation_start(spine_track_entry entry, float animationStart) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setAnimationStart(animationStart); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_animation_end(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_animation_end(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getAnimationEnd(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_animation_end(spine_track_entry entry, float animationEnd) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_animation_end(spine_track_entry entry, float animationEnd) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setAnimationEnd(animationEnd); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_animation_last(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_animation_last(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getAnimationLast(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_animation_last(spine_track_entry entry, float animationLast) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_animation_last(spine_track_entry entry, float animationLast) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setAnimationLast(animationLast); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_animation_time(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_animation_time(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getAnimationTime(); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_time_scale(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_time_scale(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getTimeScale(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_time_scale(spine_track_entry entry, float timeScale) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_time_scale(spine_track_entry entry, float timeScale) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setTimeScale(timeScale); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_alpha(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_alpha(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getAlpha(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_alpha(spine_track_entry entry, float alpha) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_alpha(spine_track_entry entry, float alpha) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setAlpha(alpha); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_event_threshold(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_event_threshold(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getEventThreshold(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_event_threshold(spine_track_entry entry, float eventThreshold) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_event_threshold(spine_track_entry entry, float eventThreshold) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setEventThreshold(eventThreshold); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_attachment_threshold(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_attachment_threshold(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getAttachmentThreshold(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_attachment_threshold(spine_track_entry entry, float attachmentThreshold) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_attachment_threshold(spine_track_entry entry, float attachmentThreshold) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setAttachmentThreshold(attachmentThreshold); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_draw_order_threshold(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_draw_order_threshold(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getDrawOrderThreshold(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_draw_order_threshold(spine_track_entry entry, float drawOrderThreshold) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_draw_order_threshold(spine_track_entry entry, float drawOrderThreshold) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setDrawOrderThreshold(drawOrderThreshold); } -FFI_PLUGIN_EXPORT spine_track_entry spine_track_entry_get_next(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE spine_track_entry spine_track_entry_get_next(spine_track_entry entry) { if (entry == nullptr) return nullptr; TrackEntry *_entry = (TrackEntry*)entry; return (spine_track_entry)_entry->getNext(); } -FFI_PLUGIN_EXPORT int32_t spine_track_entry_is_complete(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE int32_t spine_track_entry_is_complete(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->isComplete() ? -1 : 0; } -FFI_PLUGIN_EXPORT float spine_track_entry_get_mix_time(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_mix_time(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getMixTime(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_mix_time(spine_track_entry entry, float mixTime) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_mix_time(spine_track_entry entry, float mixTime) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setMixTime(mixTime); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_mix_duration(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_mix_duration(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getMixDuration(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_mix_duration(spine_track_entry entry, float mixDuration) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_mix_duration(spine_track_entry entry, float mixDuration) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setMixDuration(mixDuration); } -FFI_PLUGIN_EXPORT spine_mix_blend spine_track_entry_get_mix_blend(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE spine_mix_blend spine_track_entry_get_mix_blend(spine_track_entry entry) { if (entry == nullptr) return SPINE_MIX_BLEND_SETUP; TrackEntry *_entry = (TrackEntry*)entry; return (spine_mix_blend)_entry->getMixBlend(); } -FFI_PLUGIN_EXPORT void spine_track_entry_set_mix_blend(spine_track_entry entry, spine_mix_blend mixBlend) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_set_mix_blend(spine_track_entry entry, spine_mix_blend mixBlend) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->setMixBlend((MixBlend)mixBlend); } -FFI_PLUGIN_EXPORT spine_track_entry spine_track_entry_get_mixing_from(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE spine_track_entry spine_track_entry_get_mixing_from(spine_track_entry entry) { if (entry == nullptr) return nullptr; TrackEntry *_entry = (TrackEntry*)entry; return (spine_track_entry)_entry->getMixingFrom(); } -FFI_PLUGIN_EXPORT spine_track_entry spine_track_entry_get_mixing_to(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE spine_track_entry spine_track_entry_get_mixing_to(spine_track_entry entry) { if (entry == nullptr) return nullptr; TrackEntry *_entry = (TrackEntry*)entry; return (spine_track_entry)_entry->getMixingTo(); } -FFI_PLUGIN_EXPORT void spine_track_entry_reset_rotation_directions(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE void spine_track_entry_reset_rotation_directions(spine_track_entry entry) { if (entry == nullptr) return; TrackEntry *_entry = (TrackEntry*)entry; _entry->resetRotationDirections(); } -FFI_PLUGIN_EXPORT float spine_track_entry_get_track_complete(spine_track_entry entry) { +EMSCRIPTEN_KEEPALIVE float spine_track_entry_get_track_complete(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getTrackComplete(); @@ -1244,19 +1250,19 @@ FFI_PLUGIN_EXPORT float spine_track_entry_get_track_complete(spine_track_entry e // Skeleton -FFI_PLUGIN_EXPORT void spine_skeleton_update_cache(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_update_cache(spine_skeleton skeleton) { if (skeleton == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; _skeleton->updateCache(); } -FFI_PLUGIN_EXPORT void spine_skeleton_update_world_transform(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_update_world_transform(spine_skeleton skeleton) { if (skeleton == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; _skeleton->updateWorldTransform(); } -FFI_PLUGIN_EXPORT void spine_skeleton_update_world_transform_bone(spine_skeleton skeleton, spine_bone parent) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_update_world_transform_bone(spine_skeleton skeleton, spine_bone parent) { if (skeleton == nullptr) return; if (parent == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; @@ -1264,86 +1270,86 @@ FFI_PLUGIN_EXPORT void spine_skeleton_update_world_transform_bone(spine_skeleton _skeleton->updateWorldTransform(_bone); } -FFI_PLUGIN_EXPORT void spine_skeleton_set_to_setup_pose(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_set_to_setup_pose(spine_skeleton skeleton) { if (skeleton == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; _skeleton->setToSetupPose(); } -FFI_PLUGIN_EXPORT void spine_skeleton_set_bones_to_setup_pose(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_set_bones_to_setup_pose(spine_skeleton skeleton) { if (skeleton == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; _skeleton->setBonesToSetupPose(); } -FFI_PLUGIN_EXPORT void spine_skeleton_set_slots_to_setup_pose(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_set_slots_to_setup_pose(spine_skeleton skeleton) { if (skeleton == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; _skeleton->setSlotsToSetupPose(); } -FFI_PLUGIN_EXPORT spine_bone spine_skeleton_find_bone(spine_skeleton skeleton, const utf8* boneName) { +EMSCRIPTEN_KEEPALIVE spine_bone spine_skeleton_find_bone(spine_skeleton skeleton, const utf8* boneName) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_bone)_skeleton->findBone((char*)boneName); } -FFI_PLUGIN_EXPORT spine_slot spine_skeleton_find_slot(spine_skeleton skeleton, const utf8* slotName) { +EMSCRIPTEN_KEEPALIVE spine_slot spine_skeleton_find_slot(spine_skeleton skeleton, const utf8* slotName) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_slot)_skeleton->findSlot((char*)slotName); } -FFI_PLUGIN_EXPORT void spine_skeleton_set_skin_by_name(spine_skeleton skeleton, const utf8* skinName) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_set_skin_by_name(spine_skeleton skeleton, const utf8* skinName) { if (skeleton == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; _skeleton->setSkin((char*)skinName); } -FFI_PLUGIN_EXPORT void spine_skeleton_set_skin(spine_skeleton skeleton, spine_skin skin) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_set_skin(spine_skeleton skeleton, spine_skin skin) { if (skeleton == nullptr) return; if (skin == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; _skeleton->setSkin((Skin*)skin); } -FFI_PLUGIN_EXPORT spine_attachment spine_skeleton_get_attachment_by_name(spine_skeleton skeleton, const utf8* slotName, const utf8* attachmentName) { +EMSCRIPTEN_KEEPALIVE spine_attachment spine_skeleton_get_attachment_by_name(spine_skeleton skeleton, const utf8* slotName, const utf8* attachmentName) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_attachment)_skeleton->getAttachment((char*)slotName, (char*)attachmentName); } -FFI_PLUGIN_EXPORT spine_attachment spine_skeleton_get_attachment(spine_skeleton skeleton, int32_t slotIndex, const utf8* attachmentName) { +EMSCRIPTEN_KEEPALIVE spine_attachment spine_skeleton_get_attachment(spine_skeleton skeleton, int32_t slotIndex, const utf8* attachmentName) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_attachment)_skeleton->getAttachment(slotIndex, (char*)attachmentName); } -FFI_PLUGIN_EXPORT void spine_skeleton_set_attachment(spine_skeleton skeleton, const utf8* slotName, const utf8* attachmentName) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_set_attachment(spine_skeleton skeleton, const utf8* slotName, const utf8* attachmentName) { if (skeleton == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; return _skeleton->setAttachment((char*)slotName, (char*)attachmentName); } -FFI_PLUGIN_EXPORT spine_ik_constraint spine_skeleton_find_ik_constraint(spine_skeleton skeleton, const utf8* constraintName) { +EMSCRIPTEN_KEEPALIVE spine_ik_constraint spine_skeleton_find_ik_constraint(spine_skeleton skeleton, const utf8* constraintName) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_ik_constraint)_skeleton->findIkConstraint((char*)constraintName); } -FFI_PLUGIN_EXPORT spine_transform_constraint spine_skeleton_find_transform_constraint(spine_skeleton skeleton, const utf8* constraintName) { +EMSCRIPTEN_KEEPALIVE spine_transform_constraint spine_skeleton_find_transform_constraint(spine_skeleton skeleton, const utf8* constraintName) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_transform_constraint)_skeleton->findTransformConstraint((char*)constraintName); } -FFI_PLUGIN_EXPORT spine_path_constraint spine_skeleton_find_path_constraint(spine_skeleton skeleton, const utf8* constraintName) { +EMSCRIPTEN_KEEPALIVE spine_path_constraint spine_skeleton_find_path_constraint(spine_skeleton skeleton, const utf8* constraintName) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_path_constraint)_skeleton->findPathConstraint((char*)constraintName); } -FFI_PLUGIN_EXPORT spine_bounds spine_skeleton_get_bounds(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE spine_bounds spine_skeleton_get_bounds(spine_skeleton skeleton) { _spine_bounds *bounds = SpineExtension::calloc<_spine_bounds>(1, __FILE__, __LINE__); if (skeleton == nullptr) return (spine_bounds)bounds; Skeleton *_skeleton = (Skeleton*)skeleton; @@ -1352,157 +1358,157 @@ FFI_PLUGIN_EXPORT spine_bounds spine_skeleton_get_bounds(spine_skeleton skeleton return (spine_bounds)bounds; } -FFI_PLUGIN_EXPORT spine_bone spine_skeleton_get_root_bone(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE spine_bone spine_skeleton_get_root_bone(spine_skeleton skeleton) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_bone)_skeleton->getRootBone(); } -FFI_PLUGIN_EXPORT spine_skeleton_data spine_skeleton_get_data(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE spine_skeleton_data spine_skeleton_get_data(spine_skeleton skeleton) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_skeleton_data)_skeleton->getData(); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_get_num_bones(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_get_num_bones(spine_skeleton skeleton) { if (skeleton == nullptr) return 0; Skeleton *_skeleton = (Skeleton*)skeleton; return (int32_t)_skeleton->getBones().size(); } -FFI_PLUGIN_EXPORT spine_bone* spine_skeleton_get_bones(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE spine_bone* spine_skeleton_get_bones(spine_skeleton skeleton) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_bone*)_skeleton->getBones().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_get_num_slots(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_get_num_slots(spine_skeleton skeleton) { if (skeleton == nullptr) return 0; Skeleton *_skeleton = (Skeleton*)skeleton; return (int32_t)_skeleton->getSlots().size(); } -FFI_PLUGIN_EXPORT spine_slot* spine_skeleton_get_slots(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE spine_slot* spine_skeleton_get_slots(spine_skeleton skeleton) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_slot*)_skeleton->getSlots().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_get_num_draw_order(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_get_num_draw_order(spine_skeleton skeleton) { if (skeleton == nullptr) return 0; Skeleton *_skeleton = (Skeleton*)skeleton; return (int32_t)_skeleton->getDrawOrder().size(); } -FFI_PLUGIN_EXPORT spine_slot* spine_skeleton_get_draw_order(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE spine_slot* spine_skeleton_get_draw_order(spine_skeleton skeleton) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_slot*)_skeleton->getDrawOrder().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_get_num_ik_constraints(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_get_num_ik_constraints(spine_skeleton skeleton) { if (skeleton == nullptr) return 0; Skeleton *_skeleton = (Skeleton*)skeleton; return (int32_t)_skeleton->getIkConstraints().size(); } -FFI_PLUGIN_EXPORT spine_ik_constraint* spine_skeleton_get_ik_constraints(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE spine_ik_constraint* spine_skeleton_get_ik_constraints(spine_skeleton skeleton) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_ik_constraint*)_skeleton->getIkConstraints().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_get_num_transform_constraints(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_get_num_transform_constraints(spine_skeleton skeleton) { if (skeleton == nullptr) return 0; Skeleton *_skeleton = (Skeleton*)skeleton; return (int32_t)_skeleton->getTransformConstraints().size(); } -FFI_PLUGIN_EXPORT spine_transform_constraint* spine_skeleton_get_transform_constraints(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE spine_transform_constraint* spine_skeleton_get_transform_constraints(spine_skeleton skeleton) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_transform_constraint*)_skeleton->getTransformConstraints().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_skeleton_get_num_path_constraints(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skeleton_get_num_path_constraints(spine_skeleton skeleton) { if (skeleton == nullptr) return 0; Skeleton *_skeleton = (Skeleton*)skeleton; return (int32_t)_skeleton->getPathConstraints().size(); } -FFI_PLUGIN_EXPORT spine_path_constraint* spine_skeleton_get_path_constraints(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE spine_path_constraint* spine_skeleton_get_path_constraints(spine_skeleton skeleton) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_path_constraint*)_skeleton->getPathConstraints().buffer(); } -FFI_PLUGIN_EXPORT spine_skin spine_skeleton_get_skin(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE spine_skin spine_skeleton_get_skin(spine_skeleton skeleton) { if (skeleton == nullptr) return nullptr; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_skin)_skeleton->getSkin(); } -FFI_PLUGIN_EXPORT spine_color spine_skeleton_get_color(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE spine_color spine_skeleton_get_color(spine_skeleton skeleton) { if (skeleton == nullptr) return (spine_color)&NULL_COLOR; Skeleton *_skeleton = (Skeleton*)skeleton; return (spine_color)&_skeleton->getColor(); } -FFI_PLUGIN_EXPORT void spine_skeleton_set_color(spine_skeleton skeleton, float r, float g, float b, float a) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_set_color(spine_skeleton skeleton, float r, float g, float b, float a) { if (skeleton == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; _skeleton->getColor().set(r, g, b, a); } -FFI_PLUGIN_EXPORT void spine_skeleton_set_position(spine_skeleton skeleton, float x, float y) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_set_position(spine_skeleton skeleton, float x, float y) { if (skeleton == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; _skeleton->setPosition(x, y); } -FFI_PLUGIN_EXPORT float spine_skeleton_get_x(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE float spine_skeleton_get_x(spine_skeleton skeleton) { if (skeleton == nullptr) return 0; Skeleton *_skeleton = (Skeleton*)skeleton; return _skeleton->getX(); } -FFI_PLUGIN_EXPORT void spine_skeleton_set_x(spine_skeleton skeleton, float x) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_set_x(spine_skeleton skeleton, float x) { if (skeleton == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; _skeleton->setX(x); } -FFI_PLUGIN_EXPORT float spine_skeleton_get_y(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE float spine_skeleton_get_y(spine_skeleton skeleton) { if (skeleton == nullptr) return 0; Skeleton *_skeleton = (Skeleton*)skeleton; return _skeleton->getY(); } -FFI_PLUGIN_EXPORT void spine_skeleton_set_y(spine_skeleton skeleton, float y) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_set_y(spine_skeleton skeleton, float y) { if (skeleton == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; _skeleton->setY(y); } -FFI_PLUGIN_EXPORT float spine_skeleton_get_scale_x(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE float spine_skeleton_get_scale_x(spine_skeleton skeleton) { if (skeleton == nullptr) return 0; Skeleton *_skeleton = (Skeleton*)skeleton; return _skeleton->getScaleX(); } -FFI_PLUGIN_EXPORT void spine_skeleton_set_scale_x(spine_skeleton skeleton, float scaleX) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_set_scale_x(spine_skeleton skeleton, float scaleX) { if (skeleton == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; _skeleton->setScaleX(scaleX); } -FFI_PLUGIN_EXPORT float spine_skeleton_get_scale_y(spine_skeleton skeleton) { +EMSCRIPTEN_KEEPALIVE float spine_skeleton_get_scale_y(spine_skeleton skeleton) { if (skeleton == nullptr) return 0; Skeleton *_skeleton = (Skeleton*)skeleton; return _skeleton->getScaleY(); } -FFI_PLUGIN_EXPORT void spine_skeleton_set_scale_y(spine_skeleton skeleton, float scaleY) { +EMSCRIPTEN_KEEPALIVE void spine_skeleton_set_scale_y(spine_skeleton skeleton, float scaleY) { if (skeleton == nullptr) return; Skeleton *_skeleton = (Skeleton*)skeleton; _skeleton->setScaleY(scaleY); @@ -1510,73 +1516,73 @@ FFI_PLUGIN_EXPORT void spine_skeleton_set_scale_y(spine_skeleton skeleton, float // EventData -FFI_PLUGIN_EXPORT const utf8* spine_event_data_get_name(spine_event_data event) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_event_data_get_name(spine_event_data event) { if (event == nullptr) return nullptr; EventData *_event = (EventData*)event; return (utf8*)_event->getName().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_event_data_get_int_value(spine_event_data event) { +EMSCRIPTEN_KEEPALIVE int32_t spine_event_data_get_int_value(spine_event_data event) { if (event == nullptr) return 0; EventData *_event = (EventData*)event; return _event->getIntValue(); } -FFI_PLUGIN_EXPORT void spine_event_data_set_int_value(spine_event_data event, int32_t value) { +EMSCRIPTEN_KEEPALIVE void spine_event_data_set_int_value(spine_event_data event, int32_t value) { if (event == nullptr) return; EventData *_event = (EventData*)event; _event->setIntValue(value); } -FFI_PLUGIN_EXPORT float spine_event_data_get_float_value(spine_event_data event) { +EMSCRIPTEN_KEEPALIVE float spine_event_data_get_float_value(spine_event_data event) { if (event == nullptr) return 0; EventData *_event = (EventData*)event; return _event->getFloatValue(); } -FFI_PLUGIN_EXPORT void spine_event_data_set_float_value(spine_event_data event, float value) { +EMSCRIPTEN_KEEPALIVE void spine_event_data_set_float_value(spine_event_data event, float value) { if (event == nullptr) return; EventData *_event = (EventData*)event; _event->setFloatValue(value); } -FFI_PLUGIN_EXPORT const utf8* spine_event_data_get_string_value(spine_event_data event) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_event_data_get_string_value(spine_event_data event) { if (event == nullptr) return nullptr; EventData *_event = (EventData*)event; return (utf8*)_event->getStringValue().buffer(); } -FFI_PLUGIN_EXPORT void spine_event_data_set_string_value(spine_event_data event, const utf8 *value) { +EMSCRIPTEN_KEEPALIVE void spine_event_data_set_string_value(spine_event_data event, const utf8 *value) { if (event == nullptr) return; EventData *_event = (EventData*)event; _event->setStringValue((char*)value); } -FFI_PLUGIN_EXPORT const utf8* spine_event_data_get_audio_path(spine_event_data event) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_event_data_get_audio_path(spine_event_data event) { if (event == nullptr) return nullptr; EventData *_event = (EventData*)event; return (utf8*)_event->getAudioPath().buffer(); } -FFI_PLUGIN_EXPORT float spine_event_data_get_volume(spine_event_data event) { +EMSCRIPTEN_KEEPALIVE float spine_event_data_get_volume(spine_event_data event) { if (event == nullptr) return 0; EventData *_event = (EventData*)event; return _event->getVolume(); } -FFI_PLUGIN_EXPORT void spine_event_data_set_volume(spine_event_data event, float volume) { +EMSCRIPTEN_KEEPALIVE void spine_event_data_set_volume(spine_event_data event, float volume) { if (event == nullptr) return; EventData *_event = (EventData*)event; _event->setVolume(volume); } -FFI_PLUGIN_EXPORT float spine_event_data_get_balance(spine_event_data event) { +EMSCRIPTEN_KEEPALIVE float spine_event_data_get_balance(spine_event_data event) { if (event == nullptr) return 0; EventData *_event = (EventData*)event; return _event->getBalance(); } -FFI_PLUGIN_EXPORT void spine_event_data_set_balance(spine_event_data event, float balance) { +EMSCRIPTEN_KEEPALIVE void spine_event_data_set_balance(spine_event_data event, float balance) { if (event == nullptr) return; EventData *_event = (EventData*)event; _event->setBalance(balance); @@ -1584,415 +1590,415 @@ FFI_PLUGIN_EXPORT void spine_event_data_set_balance(spine_event_data event, floa // Event -FFI_PLUGIN_EXPORT spine_event_data spine_event_get_data(spine_event event) { +EMSCRIPTEN_KEEPALIVE spine_event_data spine_event_get_data(spine_event event) { if (event == nullptr) return nullptr; Event *_event = (Event*)event; return (spine_event_data)&_event->getData(); } -FFI_PLUGIN_EXPORT float spine_event_get_time(spine_event event) { +EMSCRIPTEN_KEEPALIVE float spine_event_get_time(spine_event event) { if (event == nullptr) return 0; Event *_event = (Event*)event; return _event->getTime(); } -FFI_PLUGIN_EXPORT int32_t spine_event_get_int_value(spine_event event) { +EMSCRIPTEN_KEEPALIVE int32_t spine_event_get_int_value(spine_event event) { if (event == nullptr) return 0; Event *_event = (Event*)event; return _event->getIntValue(); } -FFI_PLUGIN_EXPORT void spine_event_set_int_value(spine_event event, int32_t value) { +EMSCRIPTEN_KEEPALIVE void spine_event_set_int_value(spine_event event, int32_t value) { if (event == nullptr) return; Event *_event = (Event*)event; _event->setIntValue(value); } -FFI_PLUGIN_EXPORT float spine_event_get_float_value(spine_event event) { +EMSCRIPTEN_KEEPALIVE float spine_event_get_float_value(spine_event event) { if (event == nullptr) return 0; Event *_event = (Event*)event; return _event->getFloatValue(); } -FFI_PLUGIN_EXPORT void spine_event_set_float_value(spine_event event, float value) { +EMSCRIPTEN_KEEPALIVE void spine_event_set_float_value(spine_event event, float value) { if (event == nullptr) return; Event *_event = (Event*)event; _event->setFloatValue(value); } -FFI_PLUGIN_EXPORT const utf8* spine_event_get_string_value(spine_event event) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_event_get_string_value(spine_event event) { if (event == nullptr) return nullptr; Event *_event = (Event*)event; return (utf8*)_event->getStringValue().buffer(); } -FFI_PLUGIN_EXPORT void spine_event_set_string_value(spine_event event, const utf8 *value) { +EMSCRIPTEN_KEEPALIVE void spine_event_set_string_value(spine_event event, const utf8 *value) { if (event == nullptr) return; Event *_event = (Event*)event; _event->setStringValue((char*)value); } -FFI_PLUGIN_EXPORT float spine_event_get_volume(spine_event event) { +EMSCRIPTEN_KEEPALIVE float spine_event_get_volume(spine_event event) { if (event == nullptr) return 0; Event *_event = (Event*)event; return _event->getVolume(); } -FFI_PLUGIN_EXPORT void spine_event_set_volume(spine_event event, float volume) { +EMSCRIPTEN_KEEPALIVE void spine_event_set_volume(spine_event event, float volume) { if (event == nullptr) return; Event *_event = (Event*)event; _event->setVolume(volume); } -FFI_PLUGIN_EXPORT float spine_event_get_balance(spine_event event) { +EMSCRIPTEN_KEEPALIVE float spine_event_get_balance(spine_event event) { if (event == nullptr) return 0; Event *_event = (Event*)event; return _event->getBalance(); } -FFI_PLUGIN_EXPORT void spine_event_set_balance(spine_event event, float balance) { +EMSCRIPTEN_KEEPALIVE void spine_event_set_balance(spine_event event, float balance) { if (event == nullptr) return; Event *_event = (Event*)event; _event->setBalance(balance); } // SlotData -FFI_PLUGIN_EXPORT int32_t spine_slot_data_get_index(spine_slot_data slot) { +EMSCRIPTEN_KEEPALIVE int32_t spine_slot_data_get_index(spine_slot_data slot) { if (slot == nullptr) return 0; SlotData *_slot = (SlotData*)slot; return _slot->getIndex(); } -FFI_PLUGIN_EXPORT const utf8* spine_slot_data_get_name(spine_slot_data slot) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_slot_data_get_name(spine_slot_data slot) { if (slot == nullptr) return nullptr; SlotData *_slot = (SlotData*)slot; return (utf8*)_slot->getName().buffer(); } -FFI_PLUGIN_EXPORT spine_bone_data spine_slot_data_get_bone_data(spine_slot_data slot) { +EMSCRIPTEN_KEEPALIVE spine_bone_data spine_slot_data_get_bone_data(spine_slot_data slot) { if (slot == nullptr) return nullptr; SlotData *_slot = (SlotData*)slot; return (spine_bone_data)&_slot->getBoneData(); } -FFI_PLUGIN_EXPORT spine_color spine_slot_data_get_color(spine_slot_data slot) { +EMSCRIPTEN_KEEPALIVE spine_color spine_slot_data_get_color(spine_slot_data slot) { if (slot == nullptr) return (spine_color)&NULL_COLOR; SlotData *_slot = (SlotData*)slot; return (spine_color)&_slot->getColor(); } -FFI_PLUGIN_EXPORT void spine_slot_data_set_color(spine_slot_data slot, float r, float g, float b, float a) { +EMSCRIPTEN_KEEPALIVE void spine_slot_data_set_color(spine_slot_data slot, float r, float g, float b, float a) { if (slot == nullptr) return; SlotData *_slot = (SlotData*)slot; _slot->getColor().set(r, g, b, a); } -FFI_PLUGIN_EXPORT spine_color spine_slot_data_get_dark_color(spine_slot_data slot) { +EMSCRIPTEN_KEEPALIVE spine_color spine_slot_data_get_dark_color(spine_slot_data slot) { if (slot == nullptr) return (spine_color)&NULL_COLOR; SlotData *_slot = (SlotData*)slot; return (spine_color)&_slot->getDarkColor(); } -FFI_PLUGIN_EXPORT void spine_slot_data_set_dark_color(spine_slot_data slot, float r, float g, float b, float a) { +EMSCRIPTEN_KEEPALIVE void spine_slot_data_set_dark_color(spine_slot_data slot, float r, float g, float b, float a) { if (slot == nullptr) return; SlotData *_slot = (SlotData*)slot; _slot->getDarkColor().set(r, g, b, a); } -FFI_PLUGIN_EXPORT int32_t spine_slot_data_has_dark_color(spine_slot_data slot) { +EMSCRIPTEN_KEEPALIVE int32_t spine_slot_data_has_dark_color(spine_slot_data slot) { if (slot == nullptr) return 0; SlotData *_slot = (SlotData*)slot; return _slot->hasDarkColor() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_slot_data_set_has_dark_color(spine_slot_data slot, int32_t hasDarkColor) { +EMSCRIPTEN_KEEPALIVE void spine_slot_data_set_has_dark_color(spine_slot_data slot, int32_t hasDarkColor) { if (slot == nullptr) return; SlotData *_slot = (SlotData*)slot; _slot->setHasDarkColor(hasDarkColor); } -FFI_PLUGIN_EXPORT const utf8* spine_slot_data_get_attachment_name(spine_slot_data slot) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_slot_data_get_attachment_name(spine_slot_data slot) { if (slot == nullptr) return nullptr; SlotData *_slot = (SlotData*)slot; return (utf8*)_slot->getAttachmentName().buffer(); } -FFI_PLUGIN_EXPORT void spine_slot_data_set_attachment_name(spine_slot_data slot, const utf8 *attachmentName) { +EMSCRIPTEN_KEEPALIVE void spine_slot_data_set_attachment_name(spine_slot_data slot, const utf8 *attachmentName) { if (slot == nullptr) return; SlotData *_slot = (SlotData*)slot; _slot->setAttachmentName((char*)attachmentName); } -FFI_PLUGIN_EXPORT spine_blend_mode spine_slot_data_get_blend_mode(spine_slot_data slot) { +EMSCRIPTEN_KEEPALIVE spine_blend_mode spine_slot_data_get_blend_mode(spine_slot_data slot) { if (slot == nullptr) return SPINE_BLEND_MODE_NORMAL; SlotData *_slot = (SlotData*)slot; return (spine_blend_mode)_slot->getBlendMode(); } // Slot -FFI_PLUGIN_EXPORT void spine_slot_set_to_setup_pose(spine_slot slot) { +EMSCRIPTEN_KEEPALIVE void spine_slot_set_to_setup_pose(spine_slot slot) { if (slot == nullptr) return; Slot *_slot = (Slot*)slot; _slot->setToSetupPose(); } -FFI_PLUGIN_EXPORT spine_slot_data spine_slot_get_data(spine_slot slot) { +EMSCRIPTEN_KEEPALIVE spine_slot_data spine_slot_get_data(spine_slot slot) { if (slot == nullptr) return nullptr; Slot *_slot = (Slot*)slot; return (spine_slot_data)&_slot->getData(); } -FFI_PLUGIN_EXPORT spine_bone spine_slot_get_bone(spine_slot slot) { +EMSCRIPTEN_KEEPALIVE spine_bone spine_slot_get_bone(spine_slot slot) { if (slot == nullptr) return nullptr; Slot *_slot = (Slot*)slot; return (spine_bone)&_slot->getBone(); } -FFI_PLUGIN_EXPORT spine_skeleton spine_slot_get_skeleton(spine_slot slot) { +EMSCRIPTEN_KEEPALIVE spine_skeleton spine_slot_get_skeleton(spine_slot slot) { if (slot == nullptr) return nullptr; Slot *_slot = (Slot*)slot; return (spine_skeleton)&_slot->getSkeleton(); } -FFI_PLUGIN_EXPORT spine_color spine_slot_get_color(spine_slot slot) { +EMSCRIPTEN_KEEPALIVE spine_color spine_slot_get_color(spine_slot slot) { if (slot == nullptr) return (spine_color)&NULL_COLOR; Slot *_slot = (Slot*)slot; return (spine_color)&_slot->getColor(); } -FFI_PLUGIN_EXPORT void spine_slot_set_color(spine_slot slot, float r, float g, float b, float a) { +EMSCRIPTEN_KEEPALIVE void spine_slot_set_color(spine_slot slot, float r, float g, float b, float a) { if (slot == nullptr) return; Slot *_slot = (Slot*)slot; _slot->getColor().set(r, g, b, a); } -FFI_PLUGIN_EXPORT spine_color spine_slot_get_dark_color(spine_slot slot) { +EMSCRIPTEN_KEEPALIVE spine_color spine_slot_get_dark_color(spine_slot slot) { if (slot == nullptr) return (spine_color)&NULL_COLOR; Slot *_slot = (Slot*)slot; return (spine_color)&_slot->getDarkColor(); } -FFI_PLUGIN_EXPORT void spine_slot_set_dark_color(spine_slot slot, float r, float g, float b, float a) { +EMSCRIPTEN_KEEPALIVE void spine_slot_set_dark_color(spine_slot slot, float r, float g, float b, float a) { if (slot == nullptr) return; Slot *_slot = (Slot*)slot; _slot->getDarkColor().set(r, g, b, a); } -FFI_PLUGIN_EXPORT int32_t spine_slot_has_dark_color(spine_slot slot) { +EMSCRIPTEN_KEEPALIVE int32_t spine_slot_has_dark_color(spine_slot slot) { if (slot == nullptr) return 0; Slot *_slot = (Slot*)slot; return _slot->hasDarkColor() ? -1 : 0; } -FFI_PLUGIN_EXPORT spine_attachment spine_slot_get_attachment(spine_slot slot) { +EMSCRIPTEN_KEEPALIVE spine_attachment spine_slot_get_attachment(spine_slot slot) { if (slot == nullptr) return nullptr; Slot *_slot = (Slot*)slot; return (spine_attachment)_slot->getAttachment(); } -FFI_PLUGIN_EXPORT void spine_slot_set_attachment(spine_slot slot, spine_attachment attachment) { +EMSCRIPTEN_KEEPALIVE void spine_slot_set_attachment(spine_slot slot, spine_attachment attachment) { if (slot == nullptr) return; Slot *_slot = (Slot*)slot; _slot->setAttachment((Attachment*)attachment); } -FFI_PLUGIN_EXPORT int32_t spine_slot_get_sequence_index(spine_slot slot) { +EMSCRIPTEN_KEEPALIVE int32_t spine_slot_get_sequence_index(spine_slot slot) { if (slot == nullptr) return 0; Slot *_slot = (Slot*)slot; return _slot->getSequenceIndex(); } -FFI_PLUGIN_EXPORT void spine_slot_set_sequence_index(spine_slot slot, int32_t sequenceIndex) { +EMSCRIPTEN_KEEPALIVE void spine_slot_set_sequence_index(spine_slot slot, int32_t sequenceIndex) { if (slot == nullptr) return; Slot *_slot = (Slot*)slot; _slot->setSequenceIndex(sequenceIndex); } // BoneData -FFI_PLUGIN_EXPORT int32_t spine_bone_data_get_index(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_bone_data_get_index(spine_bone_data data) { if (data == nullptr) return 0; BoneData *_data = (BoneData*)data; return _data->getIndex(); } -FFI_PLUGIN_EXPORT const utf8* spine_bone_data_get_name(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_bone_data_get_name(spine_bone_data data) { if (data == nullptr) return nullptr; BoneData *_data = (BoneData*)data; return (utf8*)_data->getName().buffer(); } -FFI_PLUGIN_EXPORT spine_bone_data spine_bone_data_get_parent(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE spine_bone_data spine_bone_data_get_parent(spine_bone_data data) { if (data == nullptr) return nullptr; BoneData *_data = (BoneData*)data; return (spine_bone_data)_data->getParent(); } -FFI_PLUGIN_EXPORT float spine_bone_data_get_length(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE float spine_bone_data_get_length(spine_bone_data data) { if (data == nullptr) return 0; BoneData *_data = (BoneData*)data; return _data->getLength(); } -FFI_PLUGIN_EXPORT void spine_bone_data_set_length(spine_bone_data data, float length) { +EMSCRIPTEN_KEEPALIVE void spine_bone_data_set_length(spine_bone_data data, float length) { if (data == nullptr) return; BoneData *_data = (BoneData*)data; _data->setLength(length); } -FFI_PLUGIN_EXPORT float spine_bone_data_get_x(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE float spine_bone_data_get_x(spine_bone_data data) { if (data == nullptr) return 0; BoneData *_data = (BoneData*)data; return _data->getX(); } -FFI_PLUGIN_EXPORT void spine_bone_data_set_x(spine_bone_data data, float x) { +EMSCRIPTEN_KEEPALIVE void spine_bone_data_set_x(spine_bone_data data, float x) { if (data == nullptr) return; BoneData *_data = (BoneData*)data; _data->setX(x); } -FFI_PLUGIN_EXPORT float spine_bone_data_get_y(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE float spine_bone_data_get_y(spine_bone_data data) { if (data == nullptr) return 0; BoneData *_data = (BoneData*)data; return _data->getY(); } -FFI_PLUGIN_EXPORT void spine_bone_data_set_y(spine_bone_data data, float y) { +EMSCRIPTEN_KEEPALIVE void spine_bone_data_set_y(spine_bone_data data, float y) { if (data == nullptr) return; BoneData *_data = (BoneData*)data; _data->setY(y); } -FFI_PLUGIN_EXPORT float spine_bone_data_get_rotation(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE float spine_bone_data_get_rotation(spine_bone_data data) { if (data == nullptr) return 0; BoneData *_data = (BoneData*)data; return _data->getRotation(); } -FFI_PLUGIN_EXPORT void spine_bone_data_set_rotation(spine_bone_data data, float rotation) { +EMSCRIPTEN_KEEPALIVE void spine_bone_data_set_rotation(spine_bone_data data, float rotation) { if (data == nullptr) return; BoneData *_data = (BoneData*)data; _data->setRotation(rotation); } -FFI_PLUGIN_EXPORT float spine_bone_data_get_scale_x(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE float spine_bone_data_get_scale_x(spine_bone_data data) { if (data == nullptr) return 0; BoneData *_data = (BoneData*)data; return _data->getScaleX(); } -FFI_PLUGIN_EXPORT void spine_bone_data_set_scale_x(spine_bone_data data, float scaleX) { +EMSCRIPTEN_KEEPALIVE void spine_bone_data_set_scale_x(spine_bone_data data, float scaleX) { if (data == nullptr) return; BoneData *_data = (BoneData*)data; _data->setScaleX(scaleX); } -FFI_PLUGIN_EXPORT float spine_bone_data_get_scale_y(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE float spine_bone_data_get_scale_y(spine_bone_data data) { if (data == nullptr) return 0; BoneData *_data = (BoneData*)data; return _data->getScaleY(); } -FFI_PLUGIN_EXPORT void spine_bone_data_set_scale_y(spine_bone_data data, float scaleY) { +EMSCRIPTEN_KEEPALIVE void spine_bone_data_set_scale_y(spine_bone_data data, float scaleY) { if (data == nullptr) return; BoneData *_data = (BoneData*)data; _data->setScaleY(scaleY); } -FFI_PLUGIN_EXPORT float spine_bone_data_get_shear_x(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE float spine_bone_data_get_shear_x(spine_bone_data data) { if (data == nullptr) return 0; BoneData *_data = (BoneData*)data; return _data->getShearX(); } -FFI_PLUGIN_EXPORT void spine_bone_data_set_shear_x(spine_bone_data data, float shearX) { +EMSCRIPTEN_KEEPALIVE void spine_bone_data_set_shear_x(spine_bone_data data, float shearX) { if (data == nullptr) return; BoneData *_data = (BoneData*)data; _data->setShearX(shearX); } -FFI_PLUGIN_EXPORT float spine_bone_data_get_shear_y(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE float spine_bone_data_get_shear_y(spine_bone_data data) { if (data == nullptr) return 0; BoneData *_data = (BoneData*)data; return _data->getShearY(); } -FFI_PLUGIN_EXPORT void spine_bone_data_set_shear_y(spine_bone_data data, float y) { +EMSCRIPTEN_KEEPALIVE void spine_bone_data_set_shear_y(spine_bone_data data, float y) { if (data == nullptr) return; BoneData *_data = (BoneData*)data; _data->setShearY(y); } -FFI_PLUGIN_EXPORT spine_transform_mode spine_bone_data_get_transform_mode(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE spine_transform_mode spine_bone_data_get_transform_mode(spine_bone_data data) { if (data == nullptr) return SPINE_TRANSFORM_MODE_NORMAL; BoneData *_data = (BoneData*)data; return (spine_transform_mode)_data->getTransformMode(); } -FFI_PLUGIN_EXPORT void spine_bone_data_set_transform_mode(spine_bone_data data, spine_transform_mode mode) { +EMSCRIPTEN_KEEPALIVE void spine_bone_data_set_transform_mode(spine_bone_data data, spine_transform_mode mode) { if (data == nullptr) return; BoneData *_data = (BoneData*)data; _data->setTransformMode((TransformMode)mode); } -FFI_PLUGIN_EXPORT int32_t spine_bone_data_is_skin_required(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_bone_data_is_skin_required(spine_bone_data data) { if (data == nullptr) return 0; BoneData *_data = (BoneData*)data; return _data->isSkinRequired() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_bone_data_set_is_skin_required(spine_bone_data data, int32_t isSkinRequired) { +EMSCRIPTEN_KEEPALIVE void spine_bone_data_set_is_skin_required(spine_bone_data data, int32_t isSkinRequired) { if (data == nullptr) return; BoneData *_data = (BoneData*)data; _data->setSkinRequired(isSkinRequired); } -FFI_PLUGIN_EXPORT spine_color spine_bone_data_get_color(spine_bone_data data) { +EMSCRIPTEN_KEEPALIVE spine_color spine_bone_data_get_color(spine_bone_data data) { if (data == nullptr) return (spine_color)&NULL_COLOR; BoneData *_data = (BoneData*)data; return (spine_color)&_data->getColor(); } -FFI_PLUGIN_EXPORT void spine_bone_data_set_color(spine_bone_data data, float r, float g, float b, float a) { +EMSCRIPTEN_KEEPALIVE void spine_bone_data_set_color(spine_bone_data data, float r, float g, float b, float a) { if (data == nullptr) return; BoneData *_data = (BoneData*)data; _data->getColor().set(r, g, b, a); } // Bone -FFI_PLUGIN_EXPORT void spine_bone_set_is_y_down(int32_t yDown) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_is_y_down(int32_t yDown) { Bone::setYDown(yDown); } -FFI_PLUGIN_EXPORT int32_t spine_bone_get_is_y_down() { +EMSCRIPTEN_KEEPALIVE int32_t spine_bone_get_is_y_down() { return Bone::isYDown() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_bone_update(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE void spine_bone_update(spine_bone bone) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->update(); } -FFI_PLUGIN_EXPORT void spine_bone_update_world_transform(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE void spine_bone_update_world_transform(spine_bone bone) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->updateWorldTransform(); } -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) { +EMSCRIPTEN_KEEPALIVE void spine_bone_update_world_transform_with(spine_bone bone, float x, float y, float rotation, float scaleX, float scaleY, float shearX, float shearY) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->updateWorldTransform(x, y, rotation, scaleX, scaleY, shearX, shearY); } -FFI_PLUGIN_EXPORT void spine_bone_set_to_setup_pose(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_to_setup_pose(spine_bone bone) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setToSetupPose(); } -FFI_PLUGIN_EXPORT spine_vector spine_bone_world_to_local(spine_bone bone, float worldX, float worldY) { +EMSCRIPTEN_KEEPALIVE spine_vector spine_bone_world_to_local(spine_bone bone, float worldX, float worldY) { _spine_vector *coords = SpineExtension::calloc<_spine_vector>(1, __FILE__, __LINE__); if (bone == nullptr) return (spine_vector)coords; Bone *_bone = (Bone*)bone; @@ -2000,7 +2006,7 @@ FFI_PLUGIN_EXPORT spine_vector spine_bone_world_to_local(spine_bone bone, float return (spine_vector)coords; } -FFI_PLUGIN_EXPORT spine_vector spine_bone_local_to_world(spine_bone bone, float localX, float localY) { +EMSCRIPTEN_KEEPALIVE spine_vector spine_bone_local_to_world(spine_bone bone, float localX, float localY) { _spine_vector *coords = SpineExtension::calloc<_spine_vector>(1, __FILE__, __LINE__); if (bone == nullptr) return (spine_vector)coords; Bone *_bone = (Bone*)bone; @@ -2008,350 +2014,350 @@ FFI_PLUGIN_EXPORT spine_vector spine_bone_local_to_world(spine_bone bone, float return (spine_vector)coords; } -FFI_PLUGIN_EXPORT float spine_bone_world_to_local_rotation(spine_bone bone, float worldRotation) { +EMSCRIPTEN_KEEPALIVE float spine_bone_world_to_local_rotation(spine_bone bone, float worldRotation) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->worldToLocalRotation(worldRotation); } -FFI_PLUGIN_EXPORT float spine_bone_local_to_world_rotation(spine_bone bone, float localRotation) { +EMSCRIPTEN_KEEPALIVE float spine_bone_local_to_world_rotation(spine_bone bone, float localRotation) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->localToWorldRotation(localRotation); } -FFI_PLUGIN_EXPORT void spine_bone_rotate_world(spine_bone bone, float degrees) { +EMSCRIPTEN_KEEPALIVE void spine_bone_rotate_world(spine_bone bone, float degrees) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->rotateWorld(degrees); } -FFI_PLUGIN_EXPORT float spine_bone_get_world_to_local_rotation_x(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_world_to_local_rotation_x(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getWorldToLocalRotationX(); } -FFI_PLUGIN_EXPORT float spine_bone_get_world_to_local_rotation_y(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_world_to_local_rotation_y(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getWorldToLocalRotationY(); } -FFI_PLUGIN_EXPORT spine_bone_data spine_bone_get_data(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE spine_bone_data spine_bone_get_data(spine_bone bone) { if (bone == nullptr) return nullptr; Bone *_bone = (Bone*)bone; return (spine_bone_data)&_bone->getData(); } -FFI_PLUGIN_EXPORT spine_skeleton spine_bone_get_skeleton(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE spine_skeleton spine_bone_get_skeleton(spine_bone bone) { if (bone == nullptr) return nullptr; Bone *_bone = (Bone*)bone; return (spine_skeleton)&_bone->getSkeleton(); } -FFI_PLUGIN_EXPORT spine_bone spine_bone_get_parent(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE spine_bone spine_bone_get_parent(spine_bone bone) { if (bone == nullptr) return nullptr; Bone *_bone = (Bone*)bone; return (spine_bone)_bone->getParent(); } -FFI_PLUGIN_EXPORT int32_t spine_bone_get_num_children(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE int32_t spine_bone_get_num_children(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return (int32_t)_bone->getChildren().size(); } -FFI_PLUGIN_EXPORT spine_bone* spine_bone_get_children(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE spine_bone* spine_bone_get_children(spine_bone bone) { if (bone == nullptr) return nullptr; Bone *_bone = (Bone*)bone; return (spine_bone*)_bone->getChildren().buffer(); } -FFI_PLUGIN_EXPORT float spine_bone_get_x(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_x(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getX(); } -FFI_PLUGIN_EXPORT void spine_bone_set_x(spine_bone bone, float x) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_x(spine_bone bone, float x) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setX(x); } -FFI_PLUGIN_EXPORT float spine_bone_get_y(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_y(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getY(); } -FFI_PLUGIN_EXPORT void spine_bone_set_y(spine_bone bone, float y) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_y(spine_bone bone, float y) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setY(y); } -FFI_PLUGIN_EXPORT float spine_bone_get_rotation(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_rotation(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getRotation(); } -FFI_PLUGIN_EXPORT void spine_bone_set_rotation(spine_bone bone, float rotation) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_rotation(spine_bone bone, float rotation) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setRotation(rotation); } -FFI_PLUGIN_EXPORT float spine_bone_get_scale_x(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_scale_x(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getScaleX(); } -FFI_PLUGIN_EXPORT void spine_bone_set_scale_x(spine_bone bone, float scaleX) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_scale_x(spine_bone bone, float scaleX) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setScaleX(scaleX); } -FFI_PLUGIN_EXPORT float spine_bone_get_scale_y(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_scale_y(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getScaleY(); } -FFI_PLUGIN_EXPORT void spine_bone_set_scale_y(spine_bone bone, float scaleY) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_scale_y(spine_bone bone, float scaleY) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setScaleY(scaleY); } -FFI_PLUGIN_EXPORT float spine_bone_get_shear_x(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_shear_x(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getShearX(); } -FFI_PLUGIN_EXPORT void spine_bone_set_shear_x(spine_bone bone, float shearX) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_shear_x(spine_bone bone, float shearX) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setShearX(shearX); } -FFI_PLUGIN_EXPORT float spine_bone_get_shear_y(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_shear_y(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getShearY(); } -FFI_PLUGIN_EXPORT void spine_bone_set_shear_y(spine_bone bone, float shearY) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_shear_y(spine_bone bone, float shearY) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setShearY(shearY); } -FFI_PLUGIN_EXPORT float spine_bone_get_applied_rotation(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_applied_rotation(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getAppliedRotation(); } -FFI_PLUGIN_EXPORT void spine_bone_set_applied_rotation(spine_bone bone, float rotation) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_applied_rotation(spine_bone bone, float rotation) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setAppliedRotation(rotation); } -FFI_PLUGIN_EXPORT float spine_bone_get_a_x(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_a_x(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getAX(); } -FFI_PLUGIN_EXPORT void spine_bone_set_a_x(spine_bone bone, float x) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_a_x(spine_bone bone, float x) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setAX(x); } -FFI_PLUGIN_EXPORT float spine_bone_get_a_y(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_a_y(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getAY(); } -FFI_PLUGIN_EXPORT void spine_bone_set_a_y(spine_bone bone, float y) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_a_y(spine_bone bone, float y) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setAY(y); } -FFI_PLUGIN_EXPORT float spine_bone_get_a_scale_x(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_a_scale_x(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getAScaleX(); } -FFI_PLUGIN_EXPORT void spine_bone_set_a_scale_x(spine_bone bone, float scaleX) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_a_scale_x(spine_bone bone, float scaleX) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setAScaleX(scaleX); } -FFI_PLUGIN_EXPORT float spine_bone_get_a_scale_y(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_a_scale_y(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getAScaleY(); } -FFI_PLUGIN_EXPORT void spine_bone_set_a_scale_y(spine_bone bone, float scaleY) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_a_scale_y(spine_bone bone, float scaleY) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setAScaleY(scaleY); } -FFI_PLUGIN_EXPORT float spine_bone_get_a_shear_x(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_a_shear_x(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getAShearX(); } -FFI_PLUGIN_EXPORT void spine_bone_set_a_shear_x(spine_bone bone, float shearX) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_a_shear_x(spine_bone bone, float shearX) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setAShearX(shearX); } -FFI_PLUGIN_EXPORT float spine_bone_get_a_shear_y(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_a_shear_y(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getAShearY(); } -FFI_PLUGIN_EXPORT void spine_bone_set_shear_a_y(spine_bone bone, float shearY) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_shear_a_y(spine_bone bone, float shearY) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setAShearY(shearY); } -FFI_PLUGIN_EXPORT float spine_bone_get_a(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_a(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getA(); } -FFI_PLUGIN_EXPORT void spine_bone_set_a(spine_bone bone, float a) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_a(spine_bone bone, float a) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setA(a); } -FFI_PLUGIN_EXPORT float spine_bone_get_b(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_b(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getB(); } -FFI_PLUGIN_EXPORT void spine_bone_set_b(spine_bone bone, float b) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_b(spine_bone bone, float b) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setB(b); } -FFI_PLUGIN_EXPORT float spine_bone_get_c(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_c(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getC(); } -FFI_PLUGIN_EXPORT void spine_bone_set_c(spine_bone bone, float c) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_c(spine_bone bone, float c) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setC(c); } -FFI_PLUGIN_EXPORT float spine_bone_get_d(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_d(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getD(); } -FFI_PLUGIN_EXPORT void spine_bone_set_d(spine_bone bone, float d) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_d(spine_bone bone, float d) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setD(d); } -FFI_PLUGIN_EXPORT float spine_bone_get_world_x(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_world_x(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getWorldX(); } -FFI_PLUGIN_EXPORT void spine_bone_set_world_x(spine_bone bone, float worldX) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_world_x(spine_bone bone, float worldX) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setWorldX(worldX); } -FFI_PLUGIN_EXPORT float spine_bone_get_world_y(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_world_y(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getWorldY(); } -FFI_PLUGIN_EXPORT void spine_bone_set_world_y(spine_bone bone, float worldY) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_world_y(spine_bone bone, float worldY) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setWorldY(worldY); } -FFI_PLUGIN_EXPORT float spine_bone_get_world_rotation_x(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_world_rotation_x(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getWorldRotationX(); } -FFI_PLUGIN_EXPORT float spine_bone_get_world_rotation_y(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_world_rotation_y(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getWorldToLocalRotationY(); } -FFI_PLUGIN_EXPORT float spine_bone_get_world_scale_x(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_world_scale_x(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getWorldScaleX(); } -FFI_PLUGIN_EXPORT float spine_bone_get_world_scale_y(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_bone_get_world_scale_y(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->getWorldScaleY(); } -FFI_PLUGIN_EXPORT int32_t spine_bone_get_is_active(spine_bone bone) { +EMSCRIPTEN_KEEPALIVE int32_t spine_bone_get_is_active(spine_bone bone) { if (bone == nullptr) return 0; Bone *_bone = (Bone*)bone; return _bone->isActive() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_bone_set_is_active(spine_bone bone, int32_t isActive) { +EMSCRIPTEN_KEEPALIVE void spine_bone_set_is_active(spine_bone bone, int32_t isActive) { if (bone == nullptr) return; Bone *_bone = (Bone*)bone; _bone->setActive(isActive); } // Attachment -FFI_PLUGIN_EXPORT const utf8* spine_attachment_get_name(spine_attachment attachment) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_attachment_get_name(spine_attachment attachment) { if (attachment == nullptr) return nullptr; Attachment *_attachment = (Attachment*)attachment; return (utf8*)_attachment->getName().buffer(); } -FFI_PLUGIN_EXPORT spine_attachment_type spine_attachment_get_type(spine_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_attachment_type spine_attachment_get_type(spine_attachment attachment) { if (attachment == nullptr) return SPINE_ATTACHMENT_REGION; Attachment *_attachment = (Attachment*)attachment; if (_attachment->getRTTI().isExactly(RegionAttachment::rtti)) { @@ -2371,20 +2377,20 @@ FFI_PLUGIN_EXPORT spine_attachment_type spine_attachment_get_type(spine_attachme } } -FFI_PLUGIN_EXPORT spine_attachment spine_attachment_copy(spine_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_attachment spine_attachment_copy(spine_attachment attachment) { if (attachment == nullptr) return nullptr; Attachment *_attachment = (Attachment*)attachment; return (spine_attachment)_attachment->copy(); } -FFI_PLUGIN_EXPORT void spine_attachment_dispose(spine_attachment attachment) { +EMSCRIPTEN_KEEPALIVE void spine_attachment_dispose(spine_attachment attachment) { if (attachment == nullptr) return; Attachment *_attachment = (Attachment*)attachment; delete _attachment; } // PointAttachment -FFI_PLUGIN_EXPORT spine_vector spine_point_attachment_compute_world_position(spine_point_attachment attachment, spine_bone bone) { +EMSCRIPTEN_KEEPALIVE spine_vector spine_point_attachment_compute_world_position(spine_point_attachment attachment, spine_bone bone) { _spine_vector *result = SpineExtension::calloc<_spine_vector>(1, __FILE__, __LINE__); if (attachment == nullptr) return (spine_vector)result; PointAttachment *_attachment = (PointAttachment*)attachment; @@ -2392,521 +2398,521 @@ FFI_PLUGIN_EXPORT spine_vector spine_point_attachment_compute_world_position(spi return (spine_vector)result; } -FFI_PLUGIN_EXPORT float spine_point_attachment_compute_world_rotation(spine_point_attachment attachment, spine_bone bone) { +EMSCRIPTEN_KEEPALIVE float spine_point_attachment_compute_world_rotation(spine_point_attachment attachment, spine_bone bone) { if (attachment == nullptr) return 0; PointAttachment *_attachment = (PointAttachment*)attachment; return _attachment->computeWorldRotation(*(Bone*)bone); } -FFI_PLUGIN_EXPORT float spine_point_attachment_get_x(spine_point_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float spine_point_attachment_get_x(spine_point_attachment attachment) { if (attachment == nullptr) return 0; PointAttachment *_attachment = (PointAttachment*)attachment; return _attachment->getX(); } -FFI_PLUGIN_EXPORT void spine_point_attachment_set_x(spine_point_attachment attachment, float x) { +EMSCRIPTEN_KEEPALIVE void spine_point_attachment_set_x(spine_point_attachment attachment, float x) { if (attachment == nullptr) return; PointAttachment *_attachment = (PointAttachment*)attachment; _attachment->setX(x); } -FFI_PLUGIN_EXPORT float spine_point_attachment_get_y(spine_point_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float spine_point_attachment_get_y(spine_point_attachment attachment) { if (attachment == nullptr) return 0; PointAttachment *_attachment = (PointAttachment*)attachment; return _attachment->getY(); } -FFI_PLUGIN_EXPORT void spine_point_attachment_set_y(spine_point_attachment attachment, float y) { +EMSCRIPTEN_KEEPALIVE void spine_point_attachment_set_y(spine_point_attachment attachment, float y) { if (attachment == nullptr) return; PointAttachment *_attachment = (PointAttachment*)attachment; _attachment->setY(y); } -FFI_PLUGIN_EXPORT float spine_point_attachment_get_rotation(spine_point_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float spine_point_attachment_get_rotation(spine_point_attachment attachment) { if (attachment == nullptr) return 0; PointAttachment *_attachment = (PointAttachment*)attachment; return _attachment->getRotation(); } -FFI_PLUGIN_EXPORT void spine_point_attachment_set_rotation(spine_point_attachment attachment, float rotation) { +EMSCRIPTEN_KEEPALIVE void spine_point_attachment_set_rotation(spine_point_attachment attachment, float rotation) { if (attachment == nullptr) return; PointAttachment *_attachment = (PointAttachment*)attachment; _attachment->setRotation(rotation); } -FFI_PLUGIN_EXPORT spine_color spine_point_attachment_get_color(spine_point_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_color spine_point_attachment_get_color(spine_point_attachment attachment) { if (attachment == nullptr) return (spine_color)&NULL_COLOR; PointAttachment *_attachment = (PointAttachment*)attachment; return (spine_color)&_attachment->getColor(); } -FFI_PLUGIN_EXPORT void spine_point_attachment_set_color(spine_point_attachment attachment, float r, float g, float b, float a) { +EMSCRIPTEN_KEEPALIVE void spine_point_attachment_set_color(spine_point_attachment attachment, float r, float g, float b, float a) { if (attachment == nullptr) return; PointAttachment *_attachment = (PointAttachment*)attachment; _attachment->getColor().set(r, g, b, a); } // RegionAttachment -FFI_PLUGIN_EXPORT void spine_region_attachment_update_region(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE void spine_region_attachment_update_region(spine_region_attachment attachment) { if (attachment == nullptr) return; RegionAttachment *_attachment = (RegionAttachment*)attachment; _attachment->updateRegion(); } -FFI_PLUGIN_EXPORT void spine_region_attachment_compute_world_vertices(spine_region_attachment attachment, spine_slot slot, float *worldVertices) { +EMSCRIPTEN_KEEPALIVE void spine_region_attachment_compute_world_vertices(spine_region_attachment attachment, spine_slot slot, float *worldVertices) { if (attachment == nullptr) return; RegionAttachment *_attachment = (RegionAttachment*)attachment; _attachment->computeWorldVertices(*(Slot*)slot, worldVertices, 0); } -FFI_PLUGIN_EXPORT float spine_region_attachment_get_x(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float spine_region_attachment_get_x(spine_region_attachment attachment) { if (attachment == nullptr) return 0; RegionAttachment *_attachment = (RegionAttachment*)attachment; return _attachment->getX(); } -FFI_PLUGIN_EXPORT void spine_region_attachment_set_x(spine_region_attachment attachment, float x) { +EMSCRIPTEN_KEEPALIVE void spine_region_attachment_set_x(spine_region_attachment attachment, float x) { if (attachment == nullptr) return; RegionAttachment *_attachment = (RegionAttachment*)attachment; _attachment->setX(x); } -FFI_PLUGIN_EXPORT float spine_region_attachment_get_y(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float spine_region_attachment_get_y(spine_region_attachment attachment) { if (attachment == nullptr) return 0; RegionAttachment *_attachment = (RegionAttachment*)attachment; return _attachment->getY(); } -FFI_PLUGIN_EXPORT void spine_region_attachment_set_y(spine_region_attachment attachment, float y) { +EMSCRIPTEN_KEEPALIVE void spine_region_attachment_set_y(spine_region_attachment attachment, float y) { if (attachment == nullptr) return; RegionAttachment *_attachment = (RegionAttachment*)attachment; _attachment->setY(y); } -FFI_PLUGIN_EXPORT float spine_region_attachment_get_rotation(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float spine_region_attachment_get_rotation(spine_region_attachment attachment) { if (attachment == nullptr) return 0; RegionAttachment *_attachment = (RegionAttachment*)attachment; return _attachment->getRotation(); } -FFI_PLUGIN_EXPORT void spine_region_attachment_set_rotation(spine_region_attachment attachment, float rotation) { +EMSCRIPTEN_KEEPALIVE void spine_region_attachment_set_rotation(spine_region_attachment attachment, float rotation) { if (attachment == nullptr) return; RegionAttachment *_attachment = (RegionAttachment*)attachment; _attachment->setRotation(rotation); } -FFI_PLUGIN_EXPORT float spine_region_attachment_get_scale_x(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float spine_region_attachment_get_scale_x(spine_region_attachment attachment) { if (attachment == nullptr) return 0; RegionAttachment *_attachment = (RegionAttachment*)attachment; return _attachment->getScaleX(); } -FFI_PLUGIN_EXPORT void spine_region_attachment_set_scale_x(spine_region_attachment attachment, float scaleX) { +EMSCRIPTEN_KEEPALIVE void spine_region_attachment_set_scale_x(spine_region_attachment attachment, float scaleX) { if (attachment == nullptr) return; RegionAttachment *_attachment = (RegionAttachment*)attachment; _attachment->setScaleX(scaleX); } -FFI_PLUGIN_EXPORT float spine_region_attachment_get_scale_y(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float spine_region_attachment_get_scale_y(spine_region_attachment attachment) { if (attachment == nullptr) return 0; RegionAttachment *_attachment = (RegionAttachment*)attachment; return _attachment->getScaleY(); } -FFI_PLUGIN_EXPORT void spine_region_attachment_set_scale_y(spine_region_attachment attachment, float scaleY) { +EMSCRIPTEN_KEEPALIVE void spine_region_attachment_set_scale_y(spine_region_attachment attachment, float scaleY) { if (attachment == nullptr) return; RegionAttachment *_attachment = (RegionAttachment*)attachment; _attachment->setScaleY(scaleY); } -FFI_PLUGIN_EXPORT float spine_region_attachment_get_width(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float spine_region_attachment_get_width(spine_region_attachment attachment) { if (attachment == nullptr) return 0; RegionAttachment *_attachment = (RegionAttachment*)attachment; return _attachment->getWidth(); } -FFI_PLUGIN_EXPORT void spine_region_attachment_set_width(spine_region_attachment attachment, float width) { +EMSCRIPTEN_KEEPALIVE void spine_region_attachment_set_width(spine_region_attachment attachment, float width) { if (attachment == nullptr) return; RegionAttachment *_attachment = (RegionAttachment*)attachment; _attachment->setWidth(width); } -FFI_PLUGIN_EXPORT float spine_region_attachment_get_height(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float spine_region_attachment_get_height(spine_region_attachment attachment) { if (attachment == nullptr) return 0; RegionAttachment *_attachment = (RegionAttachment*)attachment; return _attachment->getHeight(); } -FFI_PLUGIN_EXPORT void spine_region_attachment_set_height(spine_region_attachment attachment, float height) { +EMSCRIPTEN_KEEPALIVE void spine_region_attachment_set_height(spine_region_attachment attachment, float height) { if (attachment == nullptr) return; RegionAttachment *_attachment = (RegionAttachment*)attachment; _attachment->setHeight(height); } -FFI_PLUGIN_EXPORT spine_color spine_region_attachment_get_color(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_color spine_region_attachment_get_color(spine_region_attachment attachment) { if (attachment == nullptr) return (spine_color)&NULL_COLOR; RegionAttachment *_attachment = (RegionAttachment*)attachment; return (spine_color)&_attachment->getColor(); } -FFI_PLUGIN_EXPORT void spine_region_attachment_set_color(spine_region_attachment attachment, float r, float g, float b, float a) { +EMSCRIPTEN_KEEPALIVE void spine_region_attachment_set_color(spine_region_attachment attachment, float r, float g, float b, float a) { if (attachment == nullptr) return; RegionAttachment *_attachment = (RegionAttachment*)attachment; _attachment->getColor().set(r, g, b, a); } -FFI_PLUGIN_EXPORT const utf8 *spine_region_attachment_get_path(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE const utf8 *spine_region_attachment_get_path(spine_region_attachment attachment) { if (attachment == nullptr) return nullptr; RegionAttachment *_attachment = (RegionAttachment*)attachment; return (utf8*)_attachment->getPath().buffer(); } -FFI_PLUGIN_EXPORT spine_texture_region spine_region_attachment_get_region(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_texture_region spine_region_attachment_get_region(spine_region_attachment attachment) { if (attachment == nullptr) return nullptr; RegionAttachment *_attachment = (RegionAttachment*)attachment; return (spine_texture_region)_attachment->getRegion(); } -FFI_PLUGIN_EXPORT spine_sequence spine_region_attachment_get_sequence(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_sequence spine_region_attachment_get_sequence(spine_region_attachment attachment) { if (attachment == nullptr) return nullptr; RegionAttachment *_attachment = (RegionAttachment*)attachment; return (spine_sequence)_attachment->getSequence(); } -FFI_PLUGIN_EXPORT int32_t spine_region_attachment_get_num_offset(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t spine_region_attachment_get_num_offset(spine_region_attachment attachment) { if (attachment == nullptr) return 0; RegionAttachment *_attachment = (RegionAttachment*)attachment; return (int32_t)_attachment->getOffset().size(); } -FFI_PLUGIN_EXPORT float *spine_region_attachment_get_offset(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float *spine_region_attachment_get_offset(spine_region_attachment attachment) { if (attachment == nullptr) return nullptr; RegionAttachment *_attachment = (RegionAttachment*)attachment; return _attachment->getOffset().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_region_attachment_get_num_uvs(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t spine_region_attachment_get_num_uvs(spine_region_attachment attachment) { if (attachment == nullptr) return 0; RegionAttachment *_attachment = (RegionAttachment*)attachment; return (int32_t)_attachment->getUVs().size(); } -FFI_PLUGIN_EXPORT float *spine_region_attachment_get_uvs(spine_region_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float *spine_region_attachment_get_uvs(spine_region_attachment attachment) { if (attachment == nullptr) return nullptr; RegionAttachment *_attachment = (RegionAttachment*)attachment; return _attachment->getUVs().buffer(); } // VertexAttachment -FFI_PLUGIN_EXPORT int32_t spine_vertex_attachment_get_world_vertices_length(spine_vertex_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t spine_vertex_attachment_get_world_vertices_length(spine_vertex_attachment attachment) { if (attachment == nullptr) return 0; VertexAttachment *_attachment = (VertexAttachment*)attachment; return (int32_t)_attachment->getWorldVerticesLength(); } -FFI_PLUGIN_EXPORT void spine_vertex_attachment_compute_world_vertices(spine_vertex_attachment attachment, spine_slot slot, float *worldVertices) { +EMSCRIPTEN_KEEPALIVE void spine_vertex_attachment_compute_world_vertices(spine_vertex_attachment attachment, spine_slot slot, float *worldVertices) { if (attachment == nullptr) return; VertexAttachment *_attachment = (VertexAttachment*)attachment; _attachment->computeWorldVertices(*(Slot*)slot, worldVertices); } -FFI_PLUGIN_EXPORT int32_t spine_vertex_attachment_get_num_bones(spine_vertex_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t spine_vertex_attachment_get_num_bones(spine_vertex_attachment attachment) { if (attachment == nullptr) return 0; VertexAttachment *_attachment = (VertexAttachment*)attachment; return (int32_t)_attachment->getBones().size(); } -FFI_PLUGIN_EXPORT int32_t *spine_vertex_attachment_get_bones(spine_vertex_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t *spine_vertex_attachment_get_bones(spine_vertex_attachment attachment) { if (attachment == nullptr) return nullptr; VertexAttachment *_attachment = (VertexAttachment*)attachment; return _attachment->getBones().buffer(); } // VertexAttachment -FFI_PLUGIN_EXPORT int32_t spine_vertex_attachment_get_num_vertices(spine_vertex_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t spine_vertex_attachment_get_num_vertices(spine_vertex_attachment attachment) { if (attachment == nullptr) return 0; VertexAttachment *_attachment = (VertexAttachment*)attachment; return (int32_t)_attachment->getVertices().size(); } -FFI_PLUGIN_EXPORT float *spine_vertex_attachment_get_vertices(spine_vertex_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float *spine_vertex_attachment_get_vertices(spine_vertex_attachment attachment) { if (attachment == nullptr) return nullptr; VertexAttachment *_attachment = (VertexAttachment*)attachment; return _attachment->getVertices().buffer(); } -FFI_PLUGIN_EXPORT spine_attachment spine_vertex_attachment_get_timeline_attachment(spine_vertex_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_attachment spine_vertex_attachment_get_timeline_attachment(spine_vertex_attachment attachment) { if (attachment == nullptr) return nullptr; VertexAttachment *_attachment = (VertexAttachment*)attachment; return (spine_attachment)_attachment->getTimelineAttachment(); } -FFI_PLUGIN_EXPORT void spine_vertex_attachment_set_timeline_attachment(spine_vertex_attachment attachment, spine_attachment timelineAttachment) { +EMSCRIPTEN_KEEPALIVE void spine_vertex_attachment_set_timeline_attachment(spine_vertex_attachment attachment, spine_attachment timelineAttachment) { if (attachment == nullptr) return; VertexAttachment *_attachment = (VertexAttachment*)attachment; _attachment->setTimelineAttachment((Attachment*)timelineAttachment); } // MeshAttachment -FFI_PLUGIN_EXPORT void spine_mesh_attachment_update_region(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE void spine_mesh_attachment_update_region(spine_mesh_attachment attachment) { if (attachment == nullptr) return; MeshAttachment *_attachment = (MeshAttachment*)attachment; _attachment->updateRegion(); } -FFI_PLUGIN_EXPORT int32_t spine_mesh_attachment_get_hull_length(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t spine_mesh_attachment_get_hull_length(spine_mesh_attachment attachment) { if (attachment == nullptr) return 0; MeshAttachment *_attachment = (MeshAttachment*)attachment; return _attachment->getHullLength(); } -FFI_PLUGIN_EXPORT void spine_mesh_attachment_set_hull_length(spine_mesh_attachment attachment, int32_t hullLength) { +EMSCRIPTEN_KEEPALIVE void spine_mesh_attachment_set_hull_length(spine_mesh_attachment attachment, int32_t hullLength) { if (attachment == nullptr) return; MeshAttachment *_attachment = (MeshAttachment*)attachment; _attachment->setHullLength(hullLength); } -FFI_PLUGIN_EXPORT int32_t spine_mesh_attachment_get_num_region_uvs(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t spine_mesh_attachment_get_num_region_uvs(spine_mesh_attachment attachment) { if (attachment == nullptr) return 0; MeshAttachment *_attachment = (MeshAttachment*)attachment; return (int32_t)_attachment->getRegionUVs().size(); } -FFI_PLUGIN_EXPORT float *spine_mesh_attachment_get_region_uvs(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float *spine_mesh_attachment_get_region_uvs(spine_mesh_attachment attachment) { if (attachment == nullptr) return nullptr; MeshAttachment *_attachment = (MeshAttachment*)attachment; return _attachment->getRegionUVs().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_mesh_attachment_get_num_uvs(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t spine_mesh_attachment_get_num_uvs(spine_mesh_attachment attachment) { if (attachment == nullptr) return 0; MeshAttachment *_attachment = (MeshAttachment*)attachment; return (int32_t)_attachment->getUVs().size(); } -FFI_PLUGIN_EXPORT float *spine_mesh_attachment_get_uvs(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float *spine_mesh_attachment_get_uvs(spine_mesh_attachment attachment) { if (attachment == nullptr) return 0; MeshAttachment *_attachment = (MeshAttachment*)attachment; return _attachment->getUVs().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_mesh_attachment_get_num_triangles(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t spine_mesh_attachment_get_num_triangles(spine_mesh_attachment attachment) { if (attachment == nullptr) return 0; MeshAttachment *_attachment = (MeshAttachment*)attachment; return (int32_t)_attachment->getTriangles().size(); } -FFI_PLUGIN_EXPORT uint16_t *spine_mesh_attachment_get_triangles(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE uint16_t *spine_mesh_attachment_get_triangles(spine_mesh_attachment attachment) { if (attachment == nullptr) return nullptr; MeshAttachment *_attachment = (MeshAttachment*)attachment; return _attachment->getTriangles().buffer(); } -FFI_PLUGIN_EXPORT spine_color spine_mesh_attachment_get_color(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_color spine_mesh_attachment_get_color(spine_mesh_attachment attachment) { if (attachment == nullptr) return (spine_color)&NULL_COLOR; MeshAttachment *_attachment = (MeshAttachment*)attachment; return (spine_color)&_attachment->getColor(); } -FFI_PLUGIN_EXPORT void spine_mesh_attachment_set_color(spine_mesh_attachment attachment, float r, float g, float b, float a) { +EMSCRIPTEN_KEEPALIVE void spine_mesh_attachment_set_color(spine_mesh_attachment attachment, float r, float g, float b, float a) { if (attachment == nullptr) return; MeshAttachment *_attachment = (MeshAttachment*)attachment; _attachment->getColor().set(r, g, b, a); } -FFI_PLUGIN_EXPORT const utf8 *spine_mesh_attachment_get_path(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE const utf8 *spine_mesh_attachment_get_path(spine_mesh_attachment attachment) { if (attachment == nullptr) return nullptr; MeshAttachment *_attachment = (MeshAttachment*)attachment; return (utf8*)_attachment->getPath().buffer(); } -FFI_PLUGIN_EXPORT spine_texture_region spine_mesh_attachment_get_region(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_texture_region spine_mesh_attachment_get_region(spine_mesh_attachment attachment) { if (attachment == nullptr) return nullptr; MeshAttachment *_attachment = (MeshAttachment*)attachment; return (spine_texture_region)_attachment->getRegion(); } -FFI_PLUGIN_EXPORT spine_sequence spine_mesh_attachment_get_sequence(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_sequence spine_mesh_attachment_get_sequence(spine_mesh_attachment attachment) { if (attachment == nullptr) return nullptr; MeshAttachment *_attachment = (MeshAttachment*)attachment; return (spine_sequence)_attachment->getSequence(); } -FFI_PLUGIN_EXPORT spine_mesh_attachment spine_mesh_attachment_get_parent_mesh(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_mesh_attachment spine_mesh_attachment_get_parent_mesh(spine_mesh_attachment attachment) { if (attachment == nullptr) return nullptr; MeshAttachment *_attachment = (MeshAttachment*)attachment; return (spine_mesh_attachment)_attachment->getParentMesh(); } -FFI_PLUGIN_EXPORT void spine_mesh_attachment_set_parent_mesh(spine_mesh_attachment attachment, spine_mesh_attachment parentMesh) { +EMSCRIPTEN_KEEPALIVE void spine_mesh_attachment_set_parent_mesh(spine_mesh_attachment attachment, spine_mesh_attachment parentMesh) { if (attachment == nullptr) return; MeshAttachment *_attachment = (MeshAttachment*)attachment; _attachment->setParentMesh((MeshAttachment*)parentMesh); } -FFI_PLUGIN_EXPORT int32_t spine_mesh_attachment_get_num_edges(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t spine_mesh_attachment_get_num_edges(spine_mesh_attachment attachment) { if (attachment == nullptr) return 0; MeshAttachment *_attachment = (MeshAttachment*)attachment; return (int32_t)_attachment->getEdges().size(); } -FFI_PLUGIN_EXPORT unsigned short *spine_mesh_attachment_get_edges(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE unsigned short *spine_mesh_attachment_get_edges(spine_mesh_attachment attachment) { if (attachment == nullptr) return nullptr; MeshAttachment *_attachment = (MeshAttachment*)attachment; return _attachment->getEdges().buffer(); } -FFI_PLUGIN_EXPORT float spine_mesh_attachment_get_width(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float spine_mesh_attachment_get_width(spine_mesh_attachment attachment) { if (attachment == nullptr) return 0; MeshAttachment *_attachment = (MeshAttachment*)attachment; return _attachment->getWidth(); } -FFI_PLUGIN_EXPORT void spine_mesh_attachment_set_width(spine_mesh_attachment attachment, float width) { +EMSCRIPTEN_KEEPALIVE void spine_mesh_attachment_set_width(spine_mesh_attachment attachment, float width) { if (attachment == nullptr) return; MeshAttachment *_attachment = (MeshAttachment*)attachment; _attachment->setWidth(width); } -FFI_PLUGIN_EXPORT float spine_mesh_attachment_get_height(spine_mesh_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float spine_mesh_attachment_get_height(spine_mesh_attachment attachment) { if (attachment == nullptr) return 0; MeshAttachment *_attachment = (MeshAttachment*)attachment; return _attachment->getHeight(); } -FFI_PLUGIN_EXPORT void spine_mesh_attachment_set_height(spine_mesh_attachment attachment, float height) { +EMSCRIPTEN_KEEPALIVE void spine_mesh_attachment_set_height(spine_mesh_attachment attachment, float height) { if (attachment == nullptr) return; MeshAttachment *_attachment = (MeshAttachment*)attachment; _attachment->setHeight(height); } // ClippingAttachment -FFI_PLUGIN_EXPORT spine_slot_data spine_clipping_attachment_get_end_slot(spine_clipping_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_slot_data spine_clipping_attachment_get_end_slot(spine_clipping_attachment attachment) { if (attachment == nullptr) return nullptr; ClippingAttachment *_attachment = (ClippingAttachment*)attachment; return (spine_slot_data)_attachment->getEndSlot(); } -FFI_PLUGIN_EXPORT void spine_clipping_attachment_set_end_slot(spine_clipping_attachment attachment, spine_slot_data endSlot) { +EMSCRIPTEN_KEEPALIVE void spine_clipping_attachment_set_end_slot(spine_clipping_attachment attachment, spine_slot_data endSlot) { if (attachment == nullptr) return; ClippingAttachment *_attachment = (ClippingAttachment*)attachment; _attachment->setEndSlot((SlotData*)endSlot); } -FFI_PLUGIN_EXPORT spine_color spine_clipping_attachment_get_color(spine_clipping_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_color spine_clipping_attachment_get_color(spine_clipping_attachment attachment) { if (attachment == nullptr) return (spine_color)&NULL_COLOR; ClippingAttachment *_attachment = (ClippingAttachment*)attachment; return (spine_color)&_attachment->getColor(); } -FFI_PLUGIN_EXPORT void spine_clipping_attachment_set_color(spine_clipping_attachment attachment, float r, float g, float b, float a) { +EMSCRIPTEN_KEEPALIVE void spine_clipping_attachment_set_color(spine_clipping_attachment attachment, float r, float g, float b, float a) { if (attachment == nullptr) return; ClippingAttachment *_attachment = (ClippingAttachment*)attachment; _attachment->getColor().set(r, g, b, a); } // BoundingBoxAttachment -FFI_PLUGIN_EXPORT spine_color spine_bounding_box_attachment_get_color(spine_bounding_box_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_color spine_bounding_box_attachment_get_color(spine_bounding_box_attachment attachment) { if (attachment == nullptr) return (spine_color)&NULL_COLOR; BoundingBoxAttachment *_attachment = (BoundingBoxAttachment*)attachment; return (spine_color)&_attachment->getColor(); } -FFI_PLUGIN_EXPORT void spine_bounding_box_attachment_set_color(spine_bounding_box_attachment attachment, float r, float g, float b, float a) { +EMSCRIPTEN_KEEPALIVE void spine_bounding_box_attachment_set_color(spine_bounding_box_attachment attachment, float r, float g, float b, float a) { if (attachment == nullptr) return; BoundingBoxAttachment *_attachment = (BoundingBoxAttachment*)attachment; _attachment->getColor().set(r, g, b, a); } // PathAttachment -FFI_PLUGIN_EXPORT int32_t spine_path_attachment_get_num_lengths(spine_path_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t spine_path_attachment_get_num_lengths(spine_path_attachment attachment) { if (attachment == nullptr) return 0; PathAttachment *_attachment = (PathAttachment*)attachment; return (int32_t)_attachment->getLengths().size(); } -FFI_PLUGIN_EXPORT float *spine_path_attachment_get_lengths(spine_path_attachment attachment) { +EMSCRIPTEN_KEEPALIVE float *spine_path_attachment_get_lengths(spine_path_attachment attachment) { if (attachment == nullptr) return nullptr; PathAttachment *_attachment = (PathAttachment*)attachment; return _attachment->getLengths().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_path_attachment_get_is_closed(spine_path_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t spine_path_attachment_get_is_closed(spine_path_attachment attachment) { if (attachment == nullptr) return 0; PathAttachment *_attachment = (PathAttachment*)attachment; return _attachment->isClosed() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_path_attachment_set_is_closed(spine_path_attachment attachment, int32_t isClosed) { +EMSCRIPTEN_KEEPALIVE void spine_path_attachment_set_is_closed(spine_path_attachment attachment, int32_t isClosed) { if (attachment == nullptr) return; PathAttachment *_attachment = (PathAttachment*)attachment; _attachment->setClosed(isClosed); } -FFI_PLUGIN_EXPORT int32_t spine_path_attachment_get_is_constant_speed(spine_path_attachment attachment) { +EMSCRIPTEN_KEEPALIVE int32_t spine_path_attachment_get_is_constant_speed(spine_path_attachment attachment) { if (attachment == nullptr) return 0; PathAttachment *_attachment = (PathAttachment*)attachment; return _attachment->isConstantSpeed() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_path_attachment_set_is_constant_speed(spine_path_attachment attachment, int32_t isConstantSpeed) { +EMSCRIPTEN_KEEPALIVE void spine_path_attachment_set_is_constant_speed(spine_path_attachment attachment, int32_t isConstantSpeed) { if (attachment == nullptr) return; PathAttachment *_attachment = (PathAttachment*)attachment; _attachment->setConstantSpeed(isConstantSpeed); } -FFI_PLUGIN_EXPORT spine_color spine_path_attachment_get_color(spine_path_attachment attachment) { +EMSCRIPTEN_KEEPALIVE spine_color spine_path_attachment_get_color(spine_path_attachment attachment) { if (attachment == nullptr) return (spine_color)&NULL_COLOR; PathAttachment *_attachment = (PathAttachment*)attachment; return (spine_color)&_attachment->getColor(); } -FFI_PLUGIN_EXPORT void spine_path_attachment_set_color(spine_path_attachment attachment, float r, float g, float b, float a) { +EMSCRIPTEN_KEEPALIVE void spine_path_attachment_set_color(spine_path_attachment attachment, float r, float g, float b, float a) { if (attachment == nullptr) return; PathAttachment *_attachment = (PathAttachment*)attachment; _attachment->getColor().set(r, g, b, a); } // Skin -FFI_PLUGIN_EXPORT void spine_skin_set_attachment(spine_skin skin, int32_t slotIndex, const utf8* name, spine_attachment attachment) { +EMSCRIPTEN_KEEPALIVE void spine_skin_set_attachment(spine_skin skin, int32_t slotIndex, const utf8* name, spine_attachment attachment) { if (skin == nullptr) return; Skin *_skin = (Skin*)skin; _skin->setAttachment(slotIndex, (char*)name, (Attachment*)attachment); } -FFI_PLUGIN_EXPORT spine_attachment spine_skin_get_attachment(spine_skin skin, int32_t slotIndex, const utf8* name) { +EMSCRIPTEN_KEEPALIVE spine_attachment spine_skin_get_attachment(spine_skin skin, int32_t slotIndex, const utf8* name) { if (skin == nullptr) return nullptr; Skin *_skin = (Skin*)skin; return (spine_attachment)_skin->getAttachment(slotIndex, (char*)name); } -FFI_PLUGIN_EXPORT void spine_skin_remove_attachment(spine_skin skin, int32_t slotIndex, const utf8* name) { +EMSCRIPTEN_KEEPALIVE void spine_skin_remove_attachment(spine_skin skin, int32_t slotIndex, const utf8* name) { if (skin == nullptr) return; Skin *_skin = (Skin*)skin; _skin->removeAttachment(slotIndex, (char*)name); } -FFI_PLUGIN_EXPORT const utf8* spine_skin_get_name(spine_skin skin) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_skin_get_name(spine_skin skin) { if (skin == nullptr) return nullptr; Skin *_skin = (Skin*)skin; return (utf8*)_skin->getName().buffer(); } -FFI_PLUGIN_EXPORT void spine_skin_add_skin(spine_skin skin, spine_skin other) { +EMSCRIPTEN_KEEPALIVE void spine_skin_add_skin(spine_skin skin, spine_skin other) { if (skin == nullptr) return; if (other == nullptr) return; Skin *_skin = (Skin*)skin; _skin->addSkin((Skin*)other); } -FFI_PLUGIN_EXPORT void spine_skin_copy_skin(spine_skin skin, spine_skin other) { +EMSCRIPTEN_KEEPALIVE void spine_skin_copy_skin(spine_skin skin, spine_skin other) { if (skin == nullptr) return; if (other == nullptr) return; Skin *_skin = (Skin*)skin; _skin->copySkin((Skin*)other); } -FFI_PLUGIN_EXPORT spine_skin_entries spine_skin_get_entries(spine_skin skin) { +EMSCRIPTEN_KEEPALIVE spine_skin_entries spine_skin_get_entries(spine_skin skin) { if (skin == nullptr) return nullptr; Skin *_skin = (Skin*)skin; _spine_skin_entries *entries = SpineExtension::getInstance()->calloc<_spine_skin_entries>(1, __FILE__, __LINE__); @@ -2926,74 +2932,74 @@ FFI_PLUGIN_EXPORT spine_skin_entries spine_skin_get_entries(spine_skin skin) { return (spine_skin_entries)entries; } -FFI_PLUGIN_EXPORT int32_t spine_skin_entries_get_num_entries(spine_skin_entries entries) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skin_entries_get_num_entries(spine_skin_entries entries) { if (!entries) return 0; return ((_spine_skin_entries*)entries)->numEntries; } -FFI_PLUGIN_EXPORT spine_skin_entry spine_skin_entries_get_entry(spine_skin_entries entries, int32_t index) { +EMSCRIPTEN_KEEPALIVE spine_skin_entry spine_skin_entries_get_entry(spine_skin_entries entries, int32_t index) { if (!entries) return 0; return (spine_skin_entry)&((_spine_skin_entries*)entries)->entries[index]; } -FFI_PLUGIN_EXPORT void spine_skin_entries_dispose(spine_skin_entries entries) { +EMSCRIPTEN_KEEPALIVE void spine_skin_entries_dispose(spine_skin_entries entries) { if (entries == nullptr) return; SpineExtension::getInstance()->free(((_spine_skin_entries*)entries)->entries, __FILE__, __LINE__); SpineExtension::getInstance()->free(entries, __FILE__, __LINE__); } -FFI_PLUGIN_EXPORT int32_t spine_skin_entry_get_slot_index(spine_skin_entry entry) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skin_entry_get_slot_index(spine_skin_entry entry) { if (!entry) return 0; return ((_spine_skin_entry*)entry)->slotIndex; } -FFI_PLUGIN_EXPORT utf8 *spine_skin_entry_get_name(spine_skin_entry entry) { +EMSCRIPTEN_KEEPALIVE utf8 *spine_skin_entry_get_name(spine_skin_entry entry) { if (!entry) return nullptr; return ((_spine_skin_entry*)entry)->name; } -FFI_PLUGIN_EXPORT spine_attachment spine_skin_entry_get_attachment(spine_skin_entry entry) { +EMSCRIPTEN_KEEPALIVE spine_attachment spine_skin_entry_get_attachment(spine_skin_entry entry) { if (!entry) return nullptr; return ((_spine_skin_entry*)entry)->attachment; } -FFI_PLUGIN_EXPORT int32_t spine_skin_get_num_bones(spine_skin skin) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skin_get_num_bones(spine_skin skin) { if (skin == nullptr) return 0; Skin *_skin = (Skin*)skin; return (int32_t)_skin->getBones().size(); } -FFI_PLUGIN_EXPORT spine_bone_data* spine_skin_get_bones(spine_skin skin) { +EMSCRIPTEN_KEEPALIVE spine_bone_data* spine_skin_get_bones(spine_skin skin) { if (skin == nullptr) return nullptr; Skin *_skin = (Skin*)skin; return (spine_bone_data*)_skin->getBones().buffer(); } -FFI_PLUGIN_EXPORT int32_t spine_skin_get_num_constraints(spine_skin skin) { +EMSCRIPTEN_KEEPALIVE int32_t spine_skin_get_num_constraints(spine_skin skin) { if (skin == nullptr) return 0; Skin *_skin = (Skin*)skin; return (int32_t)_skin->getConstraints().size(); } -FFI_PLUGIN_EXPORT spine_constraint_data* spine_skin_get_constraints(spine_skin skin) { +EMSCRIPTEN_KEEPALIVE spine_constraint_data* spine_skin_get_constraints(spine_skin skin) { if (skin == nullptr) return nullptr; Skin *_skin = (Skin*)skin; return (spine_constraint_data*)_skin->getConstraints().buffer(); } -FFI_PLUGIN_EXPORT spine_skin spine_skin_create(const utf8* name) { +EMSCRIPTEN_KEEPALIVE spine_skin spine_skin_create(const utf8* name) { if (name == nullptr) return nullptr; return (spine_skin)new (__FILE__, __LINE__) Skin((char*)name); } -FFI_PLUGIN_EXPORT void spine_skin_dispose(spine_skin skin) { +EMSCRIPTEN_KEEPALIVE void spine_skin_dispose(spine_skin skin) { if (skin == nullptr) return; Skin *_skin = (Skin*)skin; delete _skin; } // ConstraintData -FFI_PLUGIN_EXPORT spine_constraint_type spine_constraint_data_get_type(spine_constraint_data data) { +EMSCRIPTEN_KEEPALIVE spine_constraint_type spine_constraint_data_get_type(spine_constraint_data data) { if (data == nullptr) return SPINE_CONSTRAINT_IK; ConstraintData *_data = (ConstraintData*)data; if (_data->getRTTI().isExactly(IkConstraintData::rtti)) { @@ -3007,1021 +3013,1021 @@ FFI_PLUGIN_EXPORT spine_constraint_type spine_constraint_data_get_type(spine_con } } -FFI_PLUGIN_EXPORT const utf8* spine_constraint_data_get_name(spine_constraint_data data) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_constraint_data_get_name(spine_constraint_data data) { if (data == nullptr) return nullptr; ConstraintData *_data = (ConstraintData*)data; return (utf8*)_data->getName().buffer(); } -FFI_PLUGIN_EXPORT uint64_t spine_constraint_data_get_order(spine_constraint_data data) { +EMSCRIPTEN_KEEPALIVE uint64_t spine_constraint_data_get_order(spine_constraint_data data) { if (data == nullptr) return 0; ConstraintData *_data = (ConstraintData*)data; return (uint64_t)_data->getOrder(); } -FFI_PLUGIN_EXPORT void spine_constraint_data_set_order(spine_constraint_data data, uint64_t order) { +EMSCRIPTEN_KEEPALIVE void spine_constraint_data_set_order(spine_constraint_data data, uint64_t order) { if (data == nullptr) return; ConstraintData *_data = (ConstraintData*)data; _data->setOrder((size_t)order); } -FFI_PLUGIN_EXPORT int32_t spine_constraint_data_get_is_skin_required(spine_constraint_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_constraint_data_get_is_skin_required(spine_constraint_data data) { if (data == nullptr) return 0; ConstraintData *_data = (ConstraintData*)data; return _data->isSkinRequired() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_constraint_data_set_is_skin_required(spine_constraint_data data, int32_t isSkinRequired) { +EMSCRIPTEN_KEEPALIVE void spine_constraint_data_set_is_skin_required(spine_constraint_data data, int32_t isSkinRequired) { if (data == nullptr) return; ConstraintData *_data = (ConstraintData*)data; _data->setSkinRequired(isSkinRequired); } // IkConstraintData -FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_data_get_num_bones(spine_ik_constraint_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_ik_constraint_data_get_num_bones(spine_ik_constraint_data data) { if (data == nullptr) return 0; IkConstraintData *_data = (IkConstraintData*)data; return (int32_t)_data->getBones().size(); } -FFI_PLUGIN_EXPORT spine_bone_data* spine_ik_constraint_data_get_bones(spine_ik_constraint_data data) { +EMSCRIPTEN_KEEPALIVE spine_bone_data* spine_ik_constraint_data_get_bones(spine_ik_constraint_data data) { if (data == nullptr) return nullptr; IkConstraintData *_data = (IkConstraintData*)data; return (spine_bone_data*)_data->getBones().buffer(); } -FFI_PLUGIN_EXPORT spine_bone_data spine_ik_constraint_data_get_target(spine_ik_constraint_data data) { +EMSCRIPTEN_KEEPALIVE spine_bone_data spine_ik_constraint_data_get_target(spine_ik_constraint_data data) { if (data == nullptr) return nullptr; IkConstraintData *_data = (IkConstraintData*)data; return (spine_bone_data)_data->getTarget(); } -FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_target(spine_ik_constraint_data data, spine_bone_data target) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_data_set_target(spine_ik_constraint_data data, spine_bone_data target) { if (data == nullptr) return; IkConstraintData *_data = (IkConstraintData*)data; _data->setTarget((BoneData*)target); } -FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_data_get_bend_direction(spine_ik_constraint_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_ik_constraint_data_get_bend_direction(spine_ik_constraint_data data) { if (data == nullptr) return 1; IkConstraintData *_data = (IkConstraintData*)data; return _data->getBendDirection(); } -FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_bend_direction(spine_ik_constraint_data data, int32_t bendDirection) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_data_set_bend_direction(spine_ik_constraint_data data, int32_t bendDirection) { if (data == nullptr) return; IkConstraintData *_data = (IkConstraintData*)data; _data->setBendDirection(bendDirection); } -FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_data_get_compress(spine_ik_constraint_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_ik_constraint_data_get_compress(spine_ik_constraint_data data) { if (data == nullptr) return 0; IkConstraintData *_data = (IkConstraintData*)data; return _data->getCompress() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_compress(spine_ik_constraint_data data, int32_t compress) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_data_set_compress(spine_ik_constraint_data data, int32_t compress) { if (data == nullptr) return; IkConstraintData *_data = (IkConstraintData*)data; _data->setCompress(compress); } -FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_data_get_stretch(spine_ik_constraint_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_ik_constraint_data_get_stretch(spine_ik_constraint_data data) { if (data == nullptr) return 0; IkConstraintData *_data = (IkConstraintData*)data; return _data->getStretch() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_stretch(spine_ik_constraint_data data, int32_t stretch) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_data_set_stretch(spine_ik_constraint_data data, int32_t stretch) { if (data == nullptr) return; IkConstraintData *_data = (IkConstraintData*)data; _data->setStretch(stretch); } -FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_data_get_uniform(spine_ik_constraint_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_ik_constraint_data_get_uniform(spine_ik_constraint_data data) { if (data == nullptr) return 0; IkConstraintData *_data = (IkConstraintData*)data; return _data->getUniform() ? -1 : 0; } -FFI_PLUGIN_EXPORT float spine_ik_constraint_data_get_mix(spine_ik_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_ik_constraint_data_get_mix(spine_ik_constraint_data data) { if (data == nullptr) return 0; IkConstraintData *_data = (IkConstraintData*)data; return _data->getMix(); } -FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_mix(spine_ik_constraint_data data, float mix) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_data_set_mix(spine_ik_constraint_data data, float mix) { if (data == nullptr) return; IkConstraintData *_data = (IkConstraintData*)data; _data->setMix(mix); } -FFI_PLUGIN_EXPORT float spine_ik_constraint_data_get_softness(spine_ik_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_ik_constraint_data_get_softness(spine_ik_constraint_data data) { if (data == nullptr) return 0; IkConstraintData *_data = (IkConstraintData*)data; return _data->getSoftness(); } -FFI_PLUGIN_EXPORT void spine_ik_constraint_data_set_softness(spine_ik_constraint_data data, float softness) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_data_set_softness(spine_ik_constraint_data data, float softness) { if (data == nullptr) return; IkConstraintData *_data = (IkConstraintData*)data; _data->setSoftness(softness); } // IKConstraint -FFI_PLUGIN_EXPORT void spine_ik_constraint_update(spine_ik_constraint constraint) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_update(spine_ik_constraint constraint) { if (constraint == nullptr) return; IkConstraint *_constraint = (IkConstraint*)constraint; _constraint->update(); } -FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_get_order(spine_ik_constraint constraint) { +EMSCRIPTEN_KEEPALIVE int32_t spine_ik_constraint_get_order(spine_ik_constraint constraint) { if (constraint == nullptr) return 0; IkConstraint *_constraint = (IkConstraint*)constraint; return _constraint->getOrder(); } -FFI_PLUGIN_EXPORT spine_ik_constraint_data spine_ik_constraint_get_data(spine_ik_constraint constraint) { +EMSCRIPTEN_KEEPALIVE spine_ik_constraint_data spine_ik_constraint_get_data(spine_ik_constraint constraint) { if (constraint == nullptr) return nullptr; IkConstraint *_constraint = (IkConstraint*)constraint; return (spine_ik_constraint_data)&_constraint->getData(); } -FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_get_num_bones(spine_ik_constraint constraint) { +EMSCRIPTEN_KEEPALIVE int32_t spine_ik_constraint_get_num_bones(spine_ik_constraint constraint) { if (constraint == nullptr) return 0; IkConstraint *_constraint = (IkConstraint*)constraint; return (int32_t)_constraint->getBones().size(); } -FFI_PLUGIN_EXPORT spine_bone* spine_ik_constraint_get_bones(spine_ik_constraint constraint) { +EMSCRIPTEN_KEEPALIVE spine_bone* spine_ik_constraint_get_bones(spine_ik_constraint constraint) { if (constraint == nullptr) return nullptr; IkConstraint *_constraint = (IkConstraint*)constraint; return (spine_bone*)_constraint->getBones().buffer(); } -FFI_PLUGIN_EXPORT spine_bone spine_ik_constraint_get_target(spine_ik_constraint constraint) { +EMSCRIPTEN_KEEPALIVE spine_bone spine_ik_constraint_get_target(spine_ik_constraint constraint) { if (constraint == nullptr) return nullptr; IkConstraint *_constraint = (IkConstraint*)constraint; return (spine_bone)_constraint->getTarget(); } -FFI_PLUGIN_EXPORT void spine_ik_constraint_set_target(spine_ik_constraint constraint, spine_bone target) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_set_target(spine_ik_constraint constraint, spine_bone target) { if (constraint == nullptr) return; IkConstraint *_constraint = (IkConstraint*)constraint; _constraint->setTarget((Bone*)target); } -FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_get_bend_direction(spine_ik_constraint constraint) { +EMSCRIPTEN_KEEPALIVE int32_t spine_ik_constraint_get_bend_direction(spine_ik_constraint constraint) { if (constraint == nullptr) return 1; IkConstraint *_constraint = (IkConstraint*)constraint; return _constraint->getBendDirection(); } -FFI_PLUGIN_EXPORT void spine_ik_constraint_set_bend_direction(spine_ik_constraint constraint, int32_t bendDirection) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_set_bend_direction(spine_ik_constraint constraint, int32_t bendDirection) { if (constraint == nullptr) return; IkConstraint *_constraint = (IkConstraint*)constraint; _constraint->setBendDirection(bendDirection); } -FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_get_compress(spine_ik_constraint constraint) { +EMSCRIPTEN_KEEPALIVE int32_t spine_ik_constraint_get_compress(spine_ik_constraint constraint) { if (constraint == nullptr) return 0; IkConstraint *_constraint = (IkConstraint*)constraint; return _constraint->getCompress() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_ik_constraint_set_compress(spine_ik_constraint constraint, int32_t compress) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_set_compress(spine_ik_constraint constraint, int32_t compress) { if (constraint == nullptr) return; IkConstraint *_constraint = (IkConstraint*)constraint; _constraint->setCompress(compress); } -FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_get_stretch(spine_ik_constraint constraint) { +EMSCRIPTEN_KEEPALIVE int32_t spine_ik_constraint_get_stretch(spine_ik_constraint constraint) { if (constraint == nullptr) return 0; IkConstraint *_constraint = (IkConstraint*)constraint; return _constraint->getStretch() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_ik_constraint_set_stretch(spine_ik_constraint constraint, int32_t stretch) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_set_stretch(spine_ik_constraint constraint, int32_t stretch) { if (constraint == nullptr) return; IkConstraint *_constraint = (IkConstraint*)constraint; _constraint->setStretch(stretch); } -FFI_PLUGIN_EXPORT float spine_ik_constraint_get_mix(spine_ik_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_ik_constraint_get_mix(spine_ik_constraint constraint) { if (constraint == nullptr) return 0; IkConstraint *_constraint = (IkConstraint*)constraint; return _constraint->getMix(); } -FFI_PLUGIN_EXPORT void spine_ik_constraint_set_mix(spine_ik_constraint constraint, float mix) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_set_mix(spine_ik_constraint constraint, float mix) { if (constraint == nullptr) return; IkConstraint *_constraint = (IkConstraint*)constraint; _constraint->setMix(mix); } -FFI_PLUGIN_EXPORT float spine_ik_constraint_get_softness(spine_ik_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_ik_constraint_get_softness(spine_ik_constraint constraint) { if (constraint == nullptr) return 0; IkConstraint *_constraint = (IkConstraint*)constraint; return _constraint->getSoftness(); } -FFI_PLUGIN_EXPORT void spine_ik_constraint_set_softness(spine_ik_constraint constraint, float softness) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_set_softness(spine_ik_constraint constraint, float softness) { if (constraint == nullptr) return; IkConstraint *_constraint = (IkConstraint*)constraint; _constraint->setSoftness(softness); } -FFI_PLUGIN_EXPORT int32_t spine_ik_constraint_get_is_active(spine_ik_constraint constraint) { +EMSCRIPTEN_KEEPALIVE int32_t spine_ik_constraint_get_is_active(spine_ik_constraint constraint) { if (constraint == nullptr) return 0; IkConstraint *_constraint = (IkConstraint*)constraint; return _constraint->isActive() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_ik_constraint_set_is_active(spine_ik_constraint constraint, int32_t isActive) { +EMSCRIPTEN_KEEPALIVE void spine_ik_constraint_set_is_active(spine_ik_constraint constraint, int32_t isActive) { if (constraint == nullptr) return; IkConstraint *_constraint = (IkConstraint*)constraint; _constraint->setActive(isActive); } // TransformConstraintData -FFI_PLUGIN_EXPORT int32_t spine_transform_constraint_data_get_num_bones(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_transform_constraint_data_get_num_bones(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return (int32_t)_data->getBones().size(); } -FFI_PLUGIN_EXPORT spine_bone_data* spine_transform_constraint_data_get_bones(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE spine_bone_data* spine_transform_constraint_data_get_bones(spine_transform_constraint_data data) { if (data == nullptr) return nullptr; TransformConstraintData *_data = (TransformConstraintData*)data; return (spine_bone_data*)_data->getBones().buffer(); } -FFI_PLUGIN_EXPORT spine_bone_data spine_transform_constraint_data_get_target(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE spine_bone_data spine_transform_constraint_data_get_target(spine_transform_constraint_data data) { if (data == nullptr) return nullptr; TransformConstraintData *_data = (TransformConstraintData*)data; return (spine_bone_data)_data->getTarget(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_target(spine_transform_constraint_data data, spine_bone_data target) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_target(spine_transform_constraint_data data, spine_bone_data target) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setTarget((BoneData*)target); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_mix_rotate(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_data_get_mix_rotate(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->getMixRotate(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_mix_rotate(spine_transform_constraint_data data, float mixRotate) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_mix_rotate(spine_transform_constraint_data data, float mixRotate) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setMixRotate(mixRotate); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_mix_x(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_data_get_mix_x(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->getMixX(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_mix_x(spine_transform_constraint_data data, float mixX) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_mix_x(spine_transform_constraint_data data, float mixX) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setMixX(mixX); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_mix_y(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_data_get_mix_y(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->getMixY(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_mix_y(spine_transform_constraint_data data, float mixY) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_mix_y(spine_transform_constraint_data data, float mixY) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setMixY(mixY); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_mix_scale_x(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_data_get_mix_scale_x(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->getMixScaleX(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_mix_scale_x(spine_transform_constraint_data data, float mixScaleX) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_mix_scale_x(spine_transform_constraint_data data, float mixScaleX) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setMixScaleX(mixScaleX); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_mix_scale_y(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_data_get_mix_scale_y(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->getMixScaleY(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_mix_scale_y(spine_transform_constraint_data data, float mixScaleY) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_mix_scale_y(spine_transform_constraint_data data, float mixScaleY) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setMixScaleY(mixScaleY); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_mix_shear_y(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_data_get_mix_shear_y(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->getMixShearY(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_mix_shear_y(spine_transform_constraint_data data, float mixShearY) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_mix_shear_y(spine_transform_constraint_data data, float mixShearY) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setMixShearY(mixShearY); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_offset_rotation(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_data_get_offset_rotation(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->getOffsetRotation(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_offset_rotation(spine_transform_constraint_data data, float offsetRotation) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_offset_rotation(spine_transform_constraint_data data, float offsetRotation) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setOffsetRotation(offsetRotation); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_offset_x(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_data_get_offset_x(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->getOffsetX(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_offset_x(spine_transform_constraint_data data, float offsetX) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_offset_x(spine_transform_constraint_data data, float offsetX) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setOffsetX(offsetX); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_offset_y(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_data_get_offset_y(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->getOffsetY(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_offset_y(spine_transform_constraint_data data, float offsetY) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_offset_y(spine_transform_constraint_data data, float offsetY) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setOffsetY(offsetY); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_offset_scale_x(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_data_get_offset_scale_x(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->getOffsetScaleX(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_offset_scale_x(spine_transform_constraint_data data, float offsetScaleX) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_offset_scale_x(spine_transform_constraint_data data, float offsetScaleX) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setOffsetScaleX(offsetScaleX); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_offset_scale_y(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_data_get_offset_scale_y(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->getOffsetScaleY(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_offset_scale_y(spine_transform_constraint_data data, float offsetScaleY) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_offset_scale_y(spine_transform_constraint_data data, float offsetScaleY) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setOffsetScaleY(offsetScaleY); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_data_get_offset_shear_y(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_data_get_offset_shear_y(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->getOffsetShearY(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_offset_shear_y(spine_transform_constraint_data data, float offsetShearY) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_offset_shear_y(spine_transform_constraint_data data, float offsetShearY) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setOffsetShearY(offsetShearY); } -FFI_PLUGIN_EXPORT int32_t spine_transform_constraint_data_get_is_relative(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_transform_constraint_data_get_is_relative(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->isRelative() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_is_relative(spine_transform_constraint_data data, int32_t isRelative) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_is_relative(spine_transform_constraint_data data, int32_t isRelative) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setRelative(isRelative); } -FFI_PLUGIN_EXPORT int32_t spine_transform_constraint_data_get_is_local(spine_transform_constraint_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_transform_constraint_data_get_is_local(spine_transform_constraint_data data) { if (data == nullptr) return 0; TransformConstraintData *_data = (TransformConstraintData*)data; return _data->isLocal() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_transform_constraint_data_set_is_local(spine_transform_constraint_data data, int32_t isLocal) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_data_set_is_local(spine_transform_constraint_data data, int32_t isLocal) { if (data == nullptr) return; TransformConstraintData *_data = (TransformConstraintData*)data; _data->setLocal(isLocal); } // TransformConstraint -FFI_PLUGIN_EXPORT void spine_transform_constraint_update(spine_transform_constraint constraint) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_update(spine_transform_constraint constraint) { if (constraint == nullptr) return; TransformConstraint *_constraint = (TransformConstraint*)constraint; _constraint->update(); } -FFI_PLUGIN_EXPORT int32_t spine_transform_constraint_get_order(spine_transform_constraint constraint) { +EMSCRIPTEN_KEEPALIVE int32_t spine_transform_constraint_get_order(spine_transform_constraint constraint) { if (constraint == nullptr) return 0; TransformConstraint *_constraint = (TransformConstraint*)constraint; return _constraint->getOrder(); } -FFI_PLUGIN_EXPORT spine_transform_constraint_data spine_transform_constraint_get_data(spine_transform_constraint constraint) { +EMSCRIPTEN_KEEPALIVE spine_transform_constraint_data spine_transform_constraint_get_data(spine_transform_constraint constraint) { if (constraint == nullptr) return nullptr; TransformConstraint *_constraint = (TransformConstraint*)constraint; return (spine_transform_constraint_data)&_constraint->getData(); } -FFI_PLUGIN_EXPORT int32_t spine_transform_constraint_get_num_bones(spine_transform_constraint constraint) { +EMSCRIPTEN_KEEPALIVE int32_t spine_transform_constraint_get_num_bones(spine_transform_constraint constraint) { if (constraint == nullptr) return 0; TransformConstraint *_constraint = (TransformConstraint*)constraint; return (int32_t)_constraint->getBones().size(); } -FFI_PLUGIN_EXPORT spine_bone* spine_transform_constraint_get_bones(spine_transform_constraint constraint) { +EMSCRIPTEN_KEEPALIVE spine_bone* spine_transform_constraint_get_bones(spine_transform_constraint constraint) { if (constraint == nullptr) return nullptr; TransformConstraint *_constraint = (TransformConstraint*)constraint; return (spine_bone*)_constraint->getBones().buffer(); } -FFI_PLUGIN_EXPORT spine_bone spine_transform_constraint_get_target(spine_transform_constraint constraint) { +EMSCRIPTEN_KEEPALIVE spine_bone spine_transform_constraint_get_target(spine_transform_constraint constraint) { if (constraint == nullptr) return nullptr; TransformConstraint *_constraint = (TransformConstraint*)constraint; return (spine_bone)_constraint->getTarget(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_set_target(spine_transform_constraint constraint, spine_bone target) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_set_target(spine_transform_constraint constraint, spine_bone target) { if (constraint == nullptr) return; TransformConstraint *_constraint = (TransformConstraint*)constraint; _constraint->setTarget((Bone*)target); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_get_mix_rotate(spine_transform_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_get_mix_rotate(spine_transform_constraint constraint) { if (constraint == nullptr) return 0; TransformConstraint *_constraint = (TransformConstraint*)constraint; return _constraint->getMixRotate(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_set_mix_rotate(spine_transform_constraint constraint, float mixRotate) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_set_mix_rotate(spine_transform_constraint constraint, float mixRotate) { if (constraint == nullptr) return; TransformConstraint *_constraint = (TransformConstraint*)constraint; _constraint->setMixRotate(mixRotate); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_get_mix_x(spine_transform_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_get_mix_x(spine_transform_constraint constraint) { if (constraint == nullptr) return 0; TransformConstraint *_constraint = (TransformConstraint*)constraint; return _constraint->getMixX(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_set_mix_x(spine_transform_constraint constraint, float mixX) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_set_mix_x(spine_transform_constraint constraint, float mixX) { if (constraint == nullptr) return; TransformConstraint *_constraint = (TransformConstraint*)constraint; _constraint->setMixX(mixX); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_get_mix_y(spine_transform_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_get_mix_y(spine_transform_constraint constraint) { if (constraint == nullptr) return 0; TransformConstraint *_constraint = (TransformConstraint*)constraint; return _constraint->getMixY(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_set_mix_y(spine_transform_constraint constraint, float mixY) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_set_mix_y(spine_transform_constraint constraint, float mixY) { if (constraint == nullptr) return; TransformConstraint *_constraint = (TransformConstraint*)constraint; _constraint->setMixY(mixY); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_get_mix_scale_x(spine_transform_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_get_mix_scale_x(spine_transform_constraint constraint) { if (constraint == nullptr) return 0; TransformConstraint *_constraint = (TransformConstraint*)constraint; return _constraint->getMixScaleX(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_set_mix_scale_x(spine_transform_constraint constraint, float mixScaleX) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_set_mix_scale_x(spine_transform_constraint constraint, float mixScaleX) { if (constraint == nullptr) return; TransformConstraint *_constraint = (TransformConstraint*)constraint; _constraint->setMixScaleX(mixScaleX); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_get_mix_scale_y(spine_transform_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_get_mix_scale_y(spine_transform_constraint constraint) { if (constraint == nullptr) return 0; TransformConstraint *_constraint = (TransformConstraint*)constraint; return _constraint->getMixScaleY(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_set_mix_scale_y(spine_transform_constraint constraint, float mixScaleY) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_set_mix_scale_y(spine_transform_constraint constraint, float mixScaleY) { if (constraint == nullptr) return; TransformConstraint *_constraint = (TransformConstraint*)constraint; _constraint->setMixScaleY(mixScaleY); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_get_mix_shear_y(spine_transform_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_get_mix_shear_y(spine_transform_constraint constraint) { if (constraint == nullptr) return 0; TransformConstraint *_constraint = (TransformConstraint*)constraint; return _constraint->getMixShearY(); } -FFI_PLUGIN_EXPORT void spine_transform_constraint_set_mix_shear_y(spine_transform_constraint constraint, float mixShearY) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_set_mix_shear_y(spine_transform_constraint constraint, float mixShearY) { if (constraint == nullptr) return; TransformConstraint *_constraint = (TransformConstraint*)constraint; _constraint->setMixShearY(mixShearY); } -FFI_PLUGIN_EXPORT float spine_transform_constraint_get_is_active(spine_transform_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_transform_constraint_get_is_active(spine_transform_constraint constraint) { if (constraint == nullptr) return 0; TransformConstraint *_constraint = (TransformConstraint*)constraint; return _constraint->isActive() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_transform_constraint_set_is_active(spine_transform_constraint constraint, int32_t isActive) { +EMSCRIPTEN_KEEPALIVE void spine_transform_constraint_set_is_active(spine_transform_constraint constraint, int32_t isActive) { if (constraint == nullptr) return; TransformConstraint *_constraint = (TransformConstraint*)constraint; _constraint->setActive(isActive); } // PathConstraintData -FFI_PLUGIN_EXPORT int32_t spine_path_constraint_data_get_num_bones(spine_path_constraint_data data) { +EMSCRIPTEN_KEEPALIVE int32_t spine_path_constraint_data_get_num_bones(spine_path_constraint_data data) { if (data == nullptr) return 0; PathConstraintData *_data = (PathConstraintData*)data; return (int32_t)_data->getBones().size(); } -FFI_PLUGIN_EXPORT spine_bone_data* spine_path_constraint_data_get_bones(spine_path_constraint_data data) { +EMSCRIPTEN_KEEPALIVE spine_bone_data* spine_path_constraint_data_get_bones(spine_path_constraint_data data) { if (data == nullptr) return nullptr; PathConstraintData *_data = (PathConstraintData*)data; return (spine_bone_data*)_data->getBones().buffer(); } -FFI_PLUGIN_EXPORT spine_slot_data spine_path_constraint_data_get_target(spine_path_constraint_data data) { +EMSCRIPTEN_KEEPALIVE spine_slot_data spine_path_constraint_data_get_target(spine_path_constraint_data data) { if (data == nullptr) return nullptr; PathConstraintData *_data = (PathConstraintData*)data; return (spine_slot_data)_data->getTarget(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_data_set_target(spine_path_constraint_data data, spine_slot_data target) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_data_set_target(spine_path_constraint_data data, spine_slot_data target) { if (data == nullptr) return; PathConstraintData *_data = (PathConstraintData*)data; _data->setTarget((SlotData*)target); } -FFI_PLUGIN_EXPORT spine_position_mode spine_path_constraint_data_get_position_mode(spine_path_constraint_data data) { +EMSCRIPTEN_KEEPALIVE spine_position_mode spine_path_constraint_data_get_position_mode(spine_path_constraint_data data) { if (data == nullptr) return SPINE_POSITION_MODE_FIXED; PathConstraintData *_data = (PathConstraintData*)data; return (spine_position_mode)_data->getPositionMode(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_data_set_position_mode(spine_path_constraint_data data, spine_position_mode positionMode) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_data_set_position_mode(spine_path_constraint_data data, spine_position_mode positionMode) { if (data == nullptr) return; PathConstraintData *_data = (PathConstraintData*)data; _data->setPositionMode((PositionMode)positionMode); } -FFI_PLUGIN_EXPORT spine_spacing_mode spine_path_constraint_data_get_spacing_mode(spine_path_constraint_data data) { +EMSCRIPTEN_KEEPALIVE spine_spacing_mode spine_path_constraint_data_get_spacing_mode(spine_path_constraint_data data) { if (data == nullptr) return SPINE_SPACING_MODE_LENGTH; PathConstraintData *_data = (PathConstraintData*)data; return (spine_spacing_mode)_data->getSpacingMode(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_data_set_spacing_mode(spine_path_constraint_data data, spine_spacing_mode spacingMode) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_data_set_spacing_mode(spine_path_constraint_data data, spine_spacing_mode spacingMode) { if (data == nullptr) return; PathConstraintData *_data = (PathConstraintData*)data; _data->setSpacingMode((SpacingMode)spacingMode); } -FFI_PLUGIN_EXPORT spine_rotate_mode spine_path_constraint_data_get_rotate_mode(spine_path_constraint_data data) { +EMSCRIPTEN_KEEPALIVE spine_rotate_mode spine_path_constraint_data_get_rotate_mode(spine_path_constraint_data data) { if (data == nullptr) return SPINE_ROTATE_MODE_TANGENT; PathConstraintData *_data = (PathConstraintData*)data; return (spine_rotate_mode)_data->getRotateMode(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_data_set_rotate_mode(spine_path_constraint_data data, spine_rotate_mode rotateMode) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_data_set_rotate_mode(spine_path_constraint_data data, spine_rotate_mode rotateMode) { if (data == nullptr) return; PathConstraintData *_data = (PathConstraintData*)data; _data->setRotateMode((RotateMode)rotateMode); } -FFI_PLUGIN_EXPORT float spine_path_constraint_data_get_offset_rotation(spine_path_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_path_constraint_data_get_offset_rotation(spine_path_constraint_data data) { if (data == nullptr) return 0; PathConstraintData *_data = (PathConstraintData*)data; return _data->getOffsetRotation(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_data_set_offset_rotation(spine_path_constraint_data data, float offsetRotation) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_data_set_offset_rotation(spine_path_constraint_data data, float offsetRotation) { if (data == nullptr) return; PathConstraintData *_data = (PathConstraintData*)data; _data->setOffsetRotation(offsetRotation); } -FFI_PLUGIN_EXPORT float spine_path_constraint_data_get_position(spine_path_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_path_constraint_data_get_position(spine_path_constraint_data data) { if (data == nullptr) return 0; PathConstraintData *_data = (PathConstraintData*)data; return _data->getPosition(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_data_set_position(spine_path_constraint_data data, float position) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_data_set_position(spine_path_constraint_data data, float position) { if (data == nullptr) return; PathConstraintData *_data = (PathConstraintData*)data; _data->setPosition(position); } -FFI_PLUGIN_EXPORT float spine_path_constraint_data_get_spacing(spine_path_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_path_constraint_data_get_spacing(spine_path_constraint_data data) { if (data == nullptr) return 0; PathConstraintData *_data = (PathConstraintData*)data; return _data->getSpacing(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_data_set_spacing(spine_path_constraint_data data, float spacing) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_data_set_spacing(spine_path_constraint_data data, float spacing) { if (data == nullptr) return; PathConstraintData *_data = (PathConstraintData*)data; _data->setSpacing(spacing); } -FFI_PLUGIN_EXPORT float spine_path_constraint_data_get_mix_rotate(spine_path_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_path_constraint_data_get_mix_rotate(spine_path_constraint_data data) { if (data == nullptr) return 0; PathConstraintData *_data = (PathConstraintData*)data; return _data->getMixRotate(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_data_set_mix_rotate(spine_path_constraint_data data, float mixRotate) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_data_set_mix_rotate(spine_path_constraint_data data, float mixRotate) { if (data == nullptr) return; PathConstraintData *_data = (PathConstraintData*)data; _data->setMixRotate(mixRotate); } -FFI_PLUGIN_EXPORT float spine_path_constraint_data_get_mix_x(spine_path_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_path_constraint_data_get_mix_x(spine_path_constraint_data data) { if (data == nullptr) return 0; PathConstraintData *_data = (PathConstraintData*)data; return _data->getMixX(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_data_set_mix_x(spine_path_constraint_data data, float mixX) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_data_set_mix_x(spine_path_constraint_data data, float mixX) { if (data == nullptr) return; PathConstraintData *_data = (PathConstraintData*)data; _data->setMixX(mixX); } -FFI_PLUGIN_EXPORT float spine_path_constraint_data_get_mix_y(spine_path_constraint_data data) { +EMSCRIPTEN_KEEPALIVE float spine_path_constraint_data_get_mix_y(spine_path_constraint_data data) { if (data == nullptr) return 0; PathConstraintData *_data = (PathConstraintData*)data; return _data->getMixY(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_data_set_mix_y(spine_path_constraint_data data, float mixY) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_data_set_mix_y(spine_path_constraint_data data, float mixY) { if (data == nullptr) return; PathConstraintData *_data = (PathConstraintData*)data; _data->setMixY(mixY); } // PathConstraint -FFI_PLUGIN_EXPORT void spine_path_constraint_update(spine_path_constraint constraint) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_update(spine_path_constraint constraint) { if (constraint == nullptr) return; PathConstraint *_constraint = (PathConstraint*)constraint; _constraint->update(); } -FFI_PLUGIN_EXPORT int32_t spine_path_constraint_get_order(spine_path_constraint constraint) { +EMSCRIPTEN_KEEPALIVE int32_t spine_path_constraint_get_order(spine_path_constraint constraint) { if (constraint == nullptr) return 0; PathConstraint *_constraint = (PathConstraint*)constraint; return _constraint->getOrder(); } -FFI_PLUGIN_EXPORT spine_path_constraint_data spine_path_constraint_get_data(spine_path_constraint constraint) { +EMSCRIPTEN_KEEPALIVE spine_path_constraint_data spine_path_constraint_get_data(spine_path_constraint constraint) { if (constraint == nullptr) return nullptr; PathConstraint *_constraint = (PathConstraint*)constraint; return (spine_path_constraint_data)&_constraint->getData(); } -FFI_PLUGIN_EXPORT int32_t spine_path_constraint_get_num_bones(spine_path_constraint constraint) { +EMSCRIPTEN_KEEPALIVE int32_t spine_path_constraint_get_num_bones(spine_path_constraint constraint) { if (constraint == nullptr) return 0; PathConstraint *_constraint = (PathConstraint*)constraint; return (int32_t)_constraint->getBones().size(); } -FFI_PLUGIN_EXPORT spine_bone* spine_path_constraint_get_bones(spine_path_constraint constraint) { +EMSCRIPTEN_KEEPALIVE spine_bone* spine_path_constraint_get_bones(spine_path_constraint constraint) { if (constraint == nullptr) return nullptr; PathConstraint *_constraint = (PathConstraint*)constraint; return (spine_bone*)_constraint->getBones().buffer(); } -FFI_PLUGIN_EXPORT spine_slot spine_path_constraint_get_target(spine_path_constraint constraint) { +EMSCRIPTEN_KEEPALIVE spine_slot spine_path_constraint_get_target(spine_path_constraint constraint) { if (constraint == nullptr) return nullptr; PathConstraint *_constraint = (PathConstraint*)constraint; return (spine_slot)_constraint->getTarget(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_set_target(spine_path_constraint constraint, spine_slot target) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_set_target(spine_path_constraint constraint, spine_slot target) { if (constraint == nullptr) return; PathConstraint *_constraint = (PathConstraint*)constraint; _constraint->setTarget((Slot*)target); } -FFI_PLUGIN_EXPORT float spine_path_constraint_get_position(spine_path_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_path_constraint_get_position(spine_path_constraint constraint) { if (constraint == nullptr) return 0; PathConstraint *_constraint = (PathConstraint*)constraint; return _constraint->getPosition(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_set_position(spine_path_constraint constraint, float position) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_set_position(spine_path_constraint constraint, float position) { if (constraint == nullptr) return; PathConstraint *_constraint = (PathConstraint*)constraint; _constraint->setPosition(position); } -FFI_PLUGIN_EXPORT float spine_path_constraint_get_spacing(spine_path_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_path_constraint_get_spacing(spine_path_constraint constraint) { if (constraint == nullptr) return 0; PathConstraint *_constraint = (PathConstraint*)constraint; return _constraint->getSpacing(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_set_spacing(spine_path_constraint constraint, float spacing) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_set_spacing(spine_path_constraint constraint, float spacing) { if (constraint == nullptr) return; PathConstraint *_constraint = (PathConstraint*)constraint; _constraint->setSpacing(spacing); } -FFI_PLUGIN_EXPORT float spine_path_constraint_get_mix_rotate(spine_path_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_path_constraint_get_mix_rotate(spine_path_constraint constraint) { if (constraint == nullptr) return 0; PathConstraint *_constraint = (PathConstraint*)constraint; return _constraint->getMixRotate(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_set_mix_rotate(spine_path_constraint constraint, float mixRotate) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_set_mix_rotate(spine_path_constraint constraint, float mixRotate) { if (constraint == nullptr) return; PathConstraint *_constraint = (PathConstraint*)constraint; _constraint->setMixRotate(mixRotate); } -FFI_PLUGIN_EXPORT float spine_path_constraint_get_mix_x(spine_path_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_path_constraint_get_mix_x(spine_path_constraint constraint) { if (constraint == nullptr) return 0; PathConstraint *_constraint = (PathConstraint*)constraint; return _constraint->getMixX(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_set_mix_x(spine_path_constraint constraint, float mixX) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_set_mix_x(spine_path_constraint constraint, float mixX) { if (constraint == nullptr) return; PathConstraint *_constraint = (PathConstraint*)constraint; _constraint->setMixX(mixX); } -FFI_PLUGIN_EXPORT float spine_path_constraint_get_mix_y(spine_path_constraint constraint) { +EMSCRIPTEN_KEEPALIVE float spine_path_constraint_get_mix_y(spine_path_constraint constraint) { if (constraint == nullptr) return 0; PathConstraint *_constraint = (PathConstraint*)constraint; return _constraint->getMixY(); } -FFI_PLUGIN_EXPORT void spine_path_constraint_set_mix_y(spine_path_constraint constraint, float mixY) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_set_mix_y(spine_path_constraint constraint, float mixY) { if (constraint == nullptr) return; PathConstraint *_constraint = (PathConstraint*)constraint; _constraint->setMixY(mixY); } -FFI_PLUGIN_EXPORT int32_t spine_path_constraint_get_is_active(spine_path_constraint constraint) { +EMSCRIPTEN_KEEPALIVE int32_t spine_path_constraint_get_is_active(spine_path_constraint constraint) { if (constraint == nullptr) return 0; PathConstraint *_constraint = (PathConstraint*)constraint; return _constraint->isActive() ? -1 : 0; } -FFI_PLUGIN_EXPORT void spine_path_constraint_set_is_active(spine_path_constraint constraint, int32_t isActive) { +EMSCRIPTEN_KEEPALIVE void spine_path_constraint_set_is_active(spine_path_constraint constraint, int32_t isActive) { if (constraint == nullptr) return; PathConstraint *_constraint = (PathConstraint*)constraint; _constraint->setActive(isActive); } // Sequence -FFI_PLUGIN_EXPORT void spine_sequence_apply(spine_sequence sequence, spine_slot slot, spine_attachment attachment) { +EMSCRIPTEN_KEEPALIVE void spine_sequence_apply(spine_sequence sequence, spine_slot slot, spine_attachment attachment) { if (sequence == nullptr) return; Sequence *_sequence = (Sequence*)sequence; _sequence->apply((Slot*)slot, (Attachment*)attachment); } -FFI_PLUGIN_EXPORT const utf8* spine_sequence_get_path(spine_sequence sequence, const utf8 *basePath, int32_t index) { +EMSCRIPTEN_KEEPALIVE const utf8* spine_sequence_get_path(spine_sequence sequence, const utf8 *basePath, int32_t index) { if (sequence == nullptr) return nullptr; Sequence *_sequence = (Sequence*)sequence; return (utf8*)strdup(_sequence->getPath((char*)basePath, index).buffer()); } -FFI_PLUGIN_EXPORT int32_t spine_sequence_get_id(spine_sequence sequence) { +EMSCRIPTEN_KEEPALIVE int32_t spine_sequence_get_id(spine_sequence sequence) { if (sequence == nullptr) return 0; Sequence *_sequence = (Sequence *) sequence; return _sequence->getId(); } -FFI_PLUGIN_EXPORT void spine_sequence_set_id(spine_sequence sequence, int32_t id) { +EMSCRIPTEN_KEEPALIVE void spine_sequence_set_id(spine_sequence sequence, int32_t id) { if (sequence == nullptr) return; Sequence *_sequence = (Sequence *) sequence; _sequence->setId(id); } -FFI_PLUGIN_EXPORT int32_t spine_sequence_get_start(spine_sequence sequence) { +EMSCRIPTEN_KEEPALIVE int32_t spine_sequence_get_start(spine_sequence sequence) { if (sequence == nullptr) return 0; Sequence *_sequence = (Sequence *) sequence; return _sequence->getStart(); } -FFI_PLUGIN_EXPORT void spine_sequence_set_start(spine_sequence sequence, int32_t start) { +EMSCRIPTEN_KEEPALIVE void spine_sequence_set_start(spine_sequence sequence, int32_t start) { if (sequence == nullptr) return; Sequence *_sequence = (Sequence *) sequence; _sequence->setStart(start); } -FFI_PLUGIN_EXPORT int32_t spine_sequence_get_digits(spine_sequence sequence) { +EMSCRIPTEN_KEEPALIVE int32_t spine_sequence_get_digits(spine_sequence sequence) { if (sequence == nullptr) return 0; Sequence *_sequence = (Sequence *) sequence; return _sequence->getDigits(); } -FFI_PLUGIN_EXPORT void spine_sequence_set_digits(spine_sequence sequence, int32_t digits) { +EMSCRIPTEN_KEEPALIVE void spine_sequence_set_digits(spine_sequence sequence, int32_t digits) { if (sequence == nullptr) return; Sequence *_sequence = (Sequence *) sequence; _sequence->setDigits(digits); } -FFI_PLUGIN_EXPORT int32_t spine_sequence_get_setup_index(spine_sequence sequence) { +EMSCRIPTEN_KEEPALIVE int32_t spine_sequence_get_setup_index(spine_sequence sequence) { if (sequence == nullptr) return 0; Sequence *_sequence = (Sequence *) sequence; return _sequence->getSetupIndex(); } -FFI_PLUGIN_EXPORT void spine_sequence_set_setup_index(spine_sequence sequence, int32_t setupIndex) { +EMSCRIPTEN_KEEPALIVE void spine_sequence_set_setup_index(spine_sequence sequence, int32_t setupIndex) { if (sequence == nullptr) return; Sequence *_sequence = (Sequence *) sequence; _sequence->setSetupIndex(setupIndex); } -FFI_PLUGIN_EXPORT int32_t spine_sequence_get_num_regions(spine_sequence sequence) { +EMSCRIPTEN_KEEPALIVE int32_t spine_sequence_get_num_regions(spine_sequence sequence) { if (sequence == nullptr) return 0; Sequence *_sequence = (Sequence *) sequence; return (int32_t)_sequence->getRegions().size(); } -FFI_PLUGIN_EXPORT spine_texture_region* spine_sequence_get_regions(spine_sequence sequence) { +EMSCRIPTEN_KEEPALIVE spine_texture_region* spine_sequence_get_regions(spine_sequence sequence) { if (sequence == nullptr) return nullptr; Sequence *_sequence = (Sequence *) sequence; return (spine_texture_region*)_sequence->getRegions().buffer(); } // TextureRegion -FFI_PLUGIN_EXPORT void* spine_texture_region_get_texture(spine_texture_region textureRegion) { +EMSCRIPTEN_KEEPALIVE void* spine_texture_region_get_texture(spine_texture_region textureRegion) { if (textureRegion == nullptr) return nullptr; TextureRegion *_region = (TextureRegion*)textureRegion; return _region->rendererObject; } -FFI_PLUGIN_EXPORT void spine_texture_region_set_texture(spine_texture_region textureRegion, void *texture) { +EMSCRIPTEN_KEEPALIVE void spine_texture_region_set_texture(spine_texture_region textureRegion, void *texture) { if (textureRegion == nullptr) return; TextureRegion *_region = (TextureRegion*)textureRegion; _region->rendererObject = texture; } -FFI_PLUGIN_EXPORT float spine_texture_region_get_u(spine_texture_region textureRegion) { +EMSCRIPTEN_KEEPALIVE float spine_texture_region_get_u(spine_texture_region textureRegion) { if (textureRegion == nullptr) return 0; TextureRegion *_region = (TextureRegion*)textureRegion; return _region->u; } -FFI_PLUGIN_EXPORT void spine_texture_region_set_u(spine_texture_region textureRegion, float u) { +EMSCRIPTEN_KEEPALIVE void spine_texture_region_set_u(spine_texture_region textureRegion, float u) { if (textureRegion == nullptr) return; TextureRegion *_region = (TextureRegion*)textureRegion; _region->u = u; } -FFI_PLUGIN_EXPORT float spine_texture_region_get_v(spine_texture_region textureRegion) { +EMSCRIPTEN_KEEPALIVE float spine_texture_region_get_v(spine_texture_region textureRegion) { if (textureRegion == nullptr) return 0; TextureRegion *_region = (TextureRegion*)textureRegion; return _region->v; } -FFI_PLUGIN_EXPORT void spine_texture_region_set_v(spine_texture_region textureRegion, float v) { +EMSCRIPTEN_KEEPALIVE void spine_texture_region_set_v(spine_texture_region textureRegion, float v) { if (textureRegion == nullptr) return; TextureRegion *_region = (TextureRegion*)textureRegion; _region->v = v; } -FFI_PLUGIN_EXPORT float spine_texture_region_get_u2(spine_texture_region textureRegion) { +EMSCRIPTEN_KEEPALIVE float spine_texture_region_get_u2(spine_texture_region textureRegion) { if (textureRegion == nullptr) return 0; TextureRegion *_region = (TextureRegion*)textureRegion; return _region->u2; } -FFI_PLUGIN_EXPORT void spine_texture_region_set_u2(spine_texture_region textureRegion, float u2) { +EMSCRIPTEN_KEEPALIVE void spine_texture_region_set_u2(spine_texture_region textureRegion, float u2) { if (textureRegion == nullptr) return; TextureRegion *_region = (TextureRegion*)textureRegion; _region->u2 = u2; } -FFI_PLUGIN_EXPORT float spine_texture_region_get_v2(spine_texture_region textureRegion) { +EMSCRIPTEN_KEEPALIVE float spine_texture_region_get_v2(spine_texture_region textureRegion) { if (textureRegion == nullptr) return 0; TextureRegion *_region = (TextureRegion*)textureRegion; return _region->v2; } -FFI_PLUGIN_EXPORT void spine_texture_region_set_v2(spine_texture_region textureRegion, float v2) { +EMSCRIPTEN_KEEPALIVE void spine_texture_region_set_v2(spine_texture_region textureRegion, float v2) { if (textureRegion == nullptr) return; TextureRegion *_region = (TextureRegion*)textureRegion; _region->v2 = v2; } -FFI_PLUGIN_EXPORT int32_t spine_texture_region_get_degrees(spine_texture_region textureRegion) { +EMSCRIPTEN_KEEPALIVE int32_t spine_texture_region_get_degrees(spine_texture_region textureRegion) { if (textureRegion == nullptr) return 0; TextureRegion *_region = (TextureRegion*)textureRegion; return _region->degrees; } -FFI_PLUGIN_EXPORT void spine_texture_region_set_degrees(spine_texture_region textureRegion, int32_t degrees) { +EMSCRIPTEN_KEEPALIVE void spine_texture_region_set_degrees(spine_texture_region textureRegion, int32_t degrees) { if (textureRegion == nullptr) return; TextureRegion *_region = (TextureRegion*)textureRegion; _region->degrees = degrees; } -FFI_PLUGIN_EXPORT float spine_texture_region_get_offset_x(spine_texture_region textureRegion) { +EMSCRIPTEN_KEEPALIVE float spine_texture_region_get_offset_x(spine_texture_region textureRegion) { if (textureRegion == nullptr) return 0; TextureRegion *_region = (TextureRegion*)textureRegion; return _region->offsetX; } -FFI_PLUGIN_EXPORT void spine_texture_region_set_offset_x(spine_texture_region textureRegion, float offsetX) { +EMSCRIPTEN_KEEPALIVE void spine_texture_region_set_offset_x(spine_texture_region textureRegion, float offsetX) { if (textureRegion == nullptr) return; TextureRegion *_region = (TextureRegion*)textureRegion; _region->offsetX = offsetX; } -FFI_PLUGIN_EXPORT float spine_texture_region_get_offset_y(spine_texture_region textureRegion) { +EMSCRIPTEN_KEEPALIVE float spine_texture_region_get_offset_y(spine_texture_region textureRegion) { if (textureRegion == nullptr) return 0; TextureRegion *_region = (TextureRegion*)textureRegion; return _region->offsetY; } -FFI_PLUGIN_EXPORT void spine_texture_region_set_offset_y(spine_texture_region textureRegion, float offsetY) { +EMSCRIPTEN_KEEPALIVE void spine_texture_region_set_offset_y(spine_texture_region textureRegion, float offsetY) { if (textureRegion == nullptr) return; TextureRegion *_region = (TextureRegion*)textureRegion; _region->offsetY = offsetY; } -FFI_PLUGIN_EXPORT int32_t spine_texture_region_get_width(spine_texture_region textureRegion) { +EMSCRIPTEN_KEEPALIVE int32_t spine_texture_region_get_width(spine_texture_region textureRegion) { if (textureRegion == nullptr) return 0; TextureRegion *_region = (TextureRegion*)textureRegion; return _region->width; } -FFI_PLUGIN_EXPORT void spine_texture_region_set_width(spine_texture_region textureRegion, int32_t width) { +EMSCRIPTEN_KEEPALIVE void spine_texture_region_set_width(spine_texture_region textureRegion, int32_t width) { if (textureRegion == nullptr) return; TextureRegion *_region = (TextureRegion*)textureRegion; _region->width = width; } -FFI_PLUGIN_EXPORT int32_t spine_texture_region_get_height(spine_texture_region textureRegion) { +EMSCRIPTEN_KEEPALIVE int32_t spine_texture_region_get_height(spine_texture_region textureRegion) { if (textureRegion == nullptr) return 0; TextureRegion *_region = (TextureRegion*)textureRegion; return _region->height; } -FFI_PLUGIN_EXPORT void spine_texture_region_set_height(spine_texture_region textureRegion, int32_t height) { +EMSCRIPTEN_KEEPALIVE void spine_texture_region_set_height(spine_texture_region textureRegion, int32_t height) { if (textureRegion == nullptr) return; TextureRegion *_region = (TextureRegion*)textureRegion; _region->height = height; } -FFI_PLUGIN_EXPORT int32_t spine_texture_region_get_original_width(spine_texture_region textureRegion) { +EMSCRIPTEN_KEEPALIVE int32_t spine_texture_region_get_original_width(spine_texture_region textureRegion) { if (textureRegion == nullptr) return 0; TextureRegion *_region = (TextureRegion*)textureRegion; return _region->originalWidth; } -FFI_PLUGIN_EXPORT void spine_texture_region_set_original_width(spine_texture_region textureRegion, int32_t originalWidth) { +EMSCRIPTEN_KEEPALIVE void spine_texture_region_set_original_width(spine_texture_region textureRegion, int32_t originalWidth) { if (textureRegion == nullptr) return; TextureRegion *_region = (TextureRegion*)textureRegion; _region->originalWidth = originalWidth; } -FFI_PLUGIN_EXPORT int32_t spine_texture_region_get_original_height(spine_texture_region textureRegion) { +EMSCRIPTEN_KEEPALIVE int32_t spine_texture_region_get_original_height(spine_texture_region textureRegion) { if (textureRegion == nullptr) return 0; TextureRegion *_region = (TextureRegion*)textureRegion; return _region->originalHeight; } -FFI_PLUGIN_EXPORT void spine_texture_region_set_original_height(spine_texture_region textureRegion, int32_t originalHeight) { +EMSCRIPTEN_KEEPALIVE void spine_texture_region_set_original_height(spine_texture_region textureRegion, int32_t originalHeight) { if (textureRegion == nullptr) return; TextureRegion *_region = (TextureRegion*)textureRegion; _region->originalHeight = originalHeight;