mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-01 13:19:08 +08:00
[flutter] clean-up of ffi related code
This commit is contained in:
parent
d059ac01fd
commit
c9d7e687a9
@ -502,7 +502,8 @@ export class DartWriter {
|
|||||||
const lines: string[] = [];
|
const lines: string[] = [];
|
||||||
|
|
||||||
lines.push('');
|
lines.push('');
|
||||||
lines.push("import '../ffi_proxy.dart';");
|
lines.push("import 'package:universal_ffi/ffi.dart';");
|
||||||
|
lines.push(`import 'package:universal_ffi/ffi_utils.dart';`);
|
||||||
|
|
||||||
lines.push("import 'spine_dart_bindings_generated.dart';");
|
lines.push("import 'spine_dart_bindings_generated.dart';");
|
||||||
lines.push("import '../spine_bindings.dart';");
|
lines.push("import '../spine_bindings.dart';");
|
||||||
@ -703,7 +704,8 @@ ${declaration} {`;
|
|||||||
|
|
||||||
lines.push(this.generateHeader());
|
lines.push(this.generateHeader());
|
||||||
lines.push('');
|
lines.push('');
|
||||||
lines.push("import '../ffi_proxy.dart';");
|
lines.push(`import 'package:universal_ffi/ffi.dart';`);
|
||||||
|
lines.push(`import 'package:universal_ffi/ffi_utils.dart';`);
|
||||||
lines.push("import 'spine_dart_bindings_generated.dart';");
|
lines.push("import 'spine_dart_bindings_generated.dart';");
|
||||||
lines.push("import '../spine_bindings.dart';");
|
lines.push("import '../spine_bindings.dart';");
|
||||||
lines.push("import '../native_array.dart';");
|
lines.push("import '../native_array.dart';");
|
||||||
@ -1608,13 +1610,10 @@ ${declaration} {`;
|
|||||||
lines.push('');
|
lines.push('');
|
||||||
lines.push('// AUTO GENERATED FILE, DO NOT EDIT.');
|
lines.push('// AUTO GENERATED FILE, DO NOT EDIT.');
|
||||||
lines.push('');
|
lines.push('');
|
||||||
lines.push('// ignore_for_file: type_argument_not_matching_bounds');
|
lines.push(`import 'package:universal_ffi/ffi.dart';`);
|
||||||
lines.push(`import 'package:flutter/services.dart';`);
|
|
||||||
lines.push(`import 'package:wasm_ffi/ffi.dart';`);
|
|
||||||
lines.push('');
|
lines.push('');
|
||||||
lines.push(`import 'generated/spine_dart_bindings_generated.dart';`);
|
lines.push(`import 'generated/spine_dart_bindings_generated.dart';`);
|
||||||
lines.push('');
|
lines.push('');
|
||||||
lines.push('// Export this so malloc_web.dart can access it');
|
|
||||||
lines.push('DynamicLibrary? dylibInstance;');
|
lines.push('DynamicLibrary? dylibInstance;');
|
||||||
lines.push('');
|
lines.push('');
|
||||||
lines.push('class SpineDartFFI {');
|
lines.push('class SpineDartFFI {');
|
||||||
|
|||||||
@ -29,10 +29,10 @@ async function generateFFIBindings(spineCDir: string): Promise<void> {
|
|||||||
throw new Error('Failed to generate bindings');
|
throw new Error('Failed to generate bindings');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace dart:ffi import with ffi_proxy.dart
|
// Replace dart:ffi import with universal_ffi
|
||||||
console.log('Replacing dart:ffi import with ffi_proxy.dart...');
|
console.log('Replacing dart:ffi import with universal_ffi...');
|
||||||
let content = fs.readFileSync(bindingsPath, 'utf8');
|
let content = fs.readFileSync(bindingsPath, 'utf8');
|
||||||
content = content.replace("import 'dart:ffi' as ffi;", "import '../ffi_proxy.dart' as ffi;");
|
content = content.replace("import 'dart:ffi' as ffi;", "import 'package:universal_ffi/ffi.dart' as ffi;");
|
||||||
|
|
||||||
// For web_ffi compatibility, we need to convert wrapper structs to Opaque
|
// For web_ffi compatibility, we need to convert wrapper structs to Opaque
|
||||||
console.log('Converting wrapper structs to Opaque for web_ffi compatibility...');
|
console.log('Converting wrapper structs to Opaque for web_ffi compatibility...');
|
||||||
|
|||||||
@ -194,6 +194,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.3.2"
|
||||||
|
universal_ffi:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: universal_ffi
|
||||||
|
sha256: "8f0e28bab34709e94541ff8c39d86294b686a6cc112561dd2aa071d4a4179609"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.3"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -1,911 +0,0 @@
|
|||||||
# Dart FFI Wrapper Generator
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
A TypeScript-based code generator that extends the existing `spine-c/codegen` system to automatically generate clean, type-safe Dart wrapper classes over the raw FFI bindings. This eliminates the need for manual wrapper implementation while providing a native Dart API experience.
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
```
|
|
||||||
spine-cpp (C++ source)
|
|
||||||
↓ (existing type-extractor.ts)
|
|
||||||
spine-cpp-types.json (type definitions)
|
|
||||||
↓ (existing ir-generator.ts + c-writer.ts)
|
|
||||||
spine-c (C bindings: .h/.c files)
|
|
||||||
↓ (ffigen via generate_bindings.sh)
|
|
||||||
spine_flutter_bindings_generated.dart (raw FFI)
|
|
||||||
↓ (NEW: dart-generator.ts)
|
|
||||||
spine_flutter.dart (clean Dart API)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Key Insights
|
|
||||||
|
|
||||||
### 1. Derivation vs Parsing
|
|
||||||
Instead of parsing the generated FFI bindings, we **derive** what ffigen produces using the same C type information that generates the headers. This works because ffigen follows predictable transformation rules:
|
|
||||||
|
|
||||||
### 2. Predictable Disposal Pattern
|
|
||||||
All C types follow a consistent disposal pattern (`spine_type_name` → `spine_type_name_dispose`), so we can derive disposal function names automatically instead of storing them.
|
|
||||||
|
|
||||||
### 3. Array Properties vs Regular Getters
|
|
||||||
C functions that return `spine_array_*` types become special **Array<T> properties** in Dart, requiring different generation logic than primitive getters.
|
|
||||||
|
|
||||||
### FFigen Transformation Rules
|
|
||||||
|
|
||||||
| C Code | Generated Dart FFI |
|
|
||||||
|--------|-------------------|
|
|
||||||
| `SPINE_C_API float spine_animation_get_duration(spine_animation self);` | `double spine_animation_get_duration(Pointer<spine_animation_wrapper> self)` |
|
|
||||||
| `SPINE_C_API void spine_animation_dispose(spine_animation self);` | `void spine_animation_dispose(Pointer<spine_animation_wrapper> self)` |
|
|
||||||
| `typedef enum { BLEND_NORMAL, BLEND_ADDITIVE } spine_blend_mode;` | `enum spine_blend_mode { BLEND_NORMAL(0), BLEND_ADDITIVE(1) }` |
|
|
||||||
| `SPINE_OPAQUE_TYPE(spine_animation)` | `typedef struct spine_animation_wrapper { char _dummy; } spine_animation_wrapper; typedef spine_animation_wrapper *spine_animation;` |
|
|
||||||
| `spine_array_timeline spine_animation_get_timelines(spine_animation self);` | `Pointer<spine_array_timeline_wrapper> spine_animation_get_timelines(Pointer<spine_animation_wrapper> self)` → **Array<Timeline> property** |
|
|
||||||
|
|
||||||
## Generator Components
|
|
||||||
|
|
||||||
### 1. Type Mapping System (`dart-types.ts`)
|
|
||||||
|
|
||||||
Defines the structure for Dart wrapper types:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
interface DartClass {
|
|
||||||
name: string; // "Animation"
|
|
||||||
cName: string; // "spine_animation"
|
|
||||||
nativeType: string; // "Pointer<spine_animation_wrapper>"
|
|
||||||
constructors: DartConstructor[];
|
|
||||||
methods: DartMethod[];
|
|
||||||
getters: DartGetter[];
|
|
||||||
setters: DartSetter[];
|
|
||||||
arrays: DartArrayGetter[]; // Properties that return Array<T> (e.g., animation.timelines)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DartMethod {
|
|
||||||
name: string; // "apply"
|
|
||||||
cFunctionName: string; // "spine_animation_apply"
|
|
||||||
returnType: DartType;
|
|
||||||
parameters: DartParameter[];
|
|
||||||
isStatic?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DartGetter {
|
|
||||||
name: string; // "duration"
|
|
||||||
cFunctionName: string; // "spine_animation_get_duration"
|
|
||||||
returnType: DartType;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DartSetter {
|
|
||||||
name: string; // "duration"
|
|
||||||
cFunctionName: string; // "spine_animation_set_duration"
|
|
||||||
parameterType: DartType;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DartArrayGetter {
|
|
||||||
name: string; // "timelines" (Dart property name)
|
|
||||||
elementType: string; // "Timeline" (element type inside Array<T>)
|
|
||||||
cArrayType: string; // "spine_array_timeline" (C array type returned)
|
|
||||||
cGetterName: string; // "spine_animation_get_timelines" (C function to call)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DartConstructor {
|
|
||||||
cFunctionName: string; // "spine_animation_create"
|
|
||||||
parameters: DartParameter[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DartParameter {
|
|
||||||
name: string;
|
|
||||||
type: DartType;
|
|
||||||
cType: string; // Original C type for conversion
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DartType {
|
|
||||||
dart: string; // "double", "String", "Animation"
|
|
||||||
isNullable?: boolean;
|
|
||||||
isNative?: boolean; // true for primitives, false for wrapper classes
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DartEnum {
|
|
||||||
name: string; // "BlendMode"
|
|
||||||
cName: string; // "spine_blend_mode"
|
|
||||||
values: DartEnumValue[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DartEnumValue {
|
|
||||||
name: string; // "normal"
|
|
||||||
cName: string; // "SPINE_BLEND_MODE_NORMAL"
|
|
||||||
value: number;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Type Mapping Rules (`dart-type-mapper.ts`)
|
|
||||||
|
|
||||||
Converts C types to Dart types:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
class DartTypeMapper {
|
|
||||||
// Maps C types to Dart types
|
|
||||||
private static readonly TYPE_MAP: Record<string, DartType> = {
|
|
||||||
'float': { dart: 'double', isNative: true },
|
|
||||||
'double': { dart: 'double', isNative: true },
|
|
||||||
'int': { dart: 'int', isNative: true },
|
|
||||||
'bool': { dart: 'bool', isNative: true },
|
|
||||||
'char*': { dart: 'String', isNative: true },
|
|
||||||
'const char*': { dart: 'String', isNative: true },
|
|
||||||
'void': { dart: 'void', isNative: true },
|
|
||||||
'spine_skeleton': { dart: 'Skeleton', isNative: false },
|
|
||||||
'spine_animation': { dart: 'Animation', isNative: false },
|
|
||||||
// ... more mappings
|
|
||||||
};
|
|
||||||
|
|
||||||
static mapCTypeToDart(cType: string): DartType {
|
|
||||||
// Handle pointers
|
|
||||||
if (cType.endsWith('*')) {
|
|
||||||
const baseType = cType.slice(0, -1).trim();
|
|
||||||
const mapped = this.TYPE_MAP[baseType];
|
|
||||||
return mapped ? { ...mapped, isNullable: true } : this.mapSpineType(baseType);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle direct mappings
|
|
||||||
return this.TYPE_MAP[cType] || this.mapSpineType(cType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static mapSpineType(cType: string): DartType {
|
|
||||||
if (cType.startsWith('spine_')) {
|
|
||||||
// spine_animation -> Animation
|
|
||||||
const dartName = toPascalCase(cType.replace('spine_', ''));
|
|
||||||
return { dart: dartName, isNative: false };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default to dynamic for unknown types
|
|
||||||
return { dart: 'dynamic', isNative: false };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Naming Convention Utilities (`dart-naming.ts`)
|
|
||||||
|
|
||||||
Handles C to Dart naming conversions:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
export function toPascalCase(snakeCase: string): string {
|
|
||||||
return snakeCase
|
|
||||||
.split('_')
|
|
||||||
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
||||||
.join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toCamelCase(snakeCase: string): string {
|
|
||||||
const pascal = toPascalCase(snakeCase);
|
|
||||||
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function extractMethodName(cFunctionName: string, className: string): string {
|
|
||||||
// spine_animation_get_duration -> getDuration
|
|
||||||
// spine_animation_set_duration -> setDuration
|
|
||||||
// spine_animation_apply -> apply
|
|
||||||
|
|
||||||
const prefix = `spine_${toSnakeCase(className)}_`;
|
|
||||||
if (!cFunctionName.startsWith(prefix)) {
|
|
||||||
throw new Error(`Function ${cFunctionName} doesn't match expected prefix ${prefix}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const methodPart = cFunctionName.slice(prefix.length);
|
|
||||||
return toCamelCase(methodPart);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isGetter(methodName: string): boolean {
|
|
||||||
return methodName.startsWith('get_');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isSetter(methodName: string): boolean {
|
|
||||||
return methodName.startsWith('set_');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function extractPropertyName(methodName: string): string {
|
|
||||||
// get_duration -> duration
|
|
||||||
// set_duration -> duration
|
|
||||||
if (methodName.startsWith('get_') || methodName.startsWith('set_')) {
|
|
||||||
return methodName.slice(4);
|
|
||||||
}
|
|
||||||
return methodName;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Dart Code Generator (`dart-writer.ts`)
|
|
||||||
|
|
||||||
Generates the actual Dart wrapper files:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
export class DartWriter {
|
|
||||||
constructor(private outputDir: string, private bindingsImport: string) {}
|
|
||||||
|
|
||||||
async writeClass(dartClass: DartClass): Promise<void> {
|
|
||||||
const lines: string[] = [];
|
|
||||||
|
|
||||||
// File header
|
|
||||||
lines.push("// AUTO GENERATED FILE, DO NOT EDIT.");
|
|
||||||
lines.push("// Generated by spine-c dart-wrapper generator");
|
|
||||||
lines.push("");
|
|
||||||
lines.push(`import '${this.bindingsImport}';`);
|
|
||||||
lines.push("import 'dart:ffi';");
|
|
||||||
lines.push("import 'array.dart';");
|
|
||||||
lines.push("");
|
|
||||||
|
|
||||||
// Class declaration
|
|
||||||
lines.push(`class ${dartClass.name} {`);
|
|
||||||
lines.push(` final ${dartClass.nativeType} _ptr;`);
|
|
||||||
lines.push(` final SpineFlutterBindings _bindings;`);
|
|
||||||
lines.push("");
|
|
||||||
|
|
||||||
// Private constructor
|
|
||||||
lines.push(` ${dartClass.name}._(this._ptr, this._bindings);`);
|
|
||||||
lines.push("");
|
|
||||||
|
|
||||||
// Public constructors
|
|
||||||
for (const constructor of dartClass.constructors) {
|
|
||||||
lines.push(this.writeConstructor(dartClass, constructor));
|
|
||||||
lines.push("");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
for (const getter of dartClass.getters) {
|
|
||||||
lines.push(this.writeGetter(getter));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setters
|
|
||||||
for (const setter of dartClass.setters) {
|
|
||||||
lines.push(this.writeSetter(setter));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Array getters
|
|
||||||
for (const arrayGetter of dartClass.arrays) {
|
|
||||||
lines.push(this.writeArrayGetter(arrayGetter));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Methods
|
|
||||||
for (const method of dartClass.methods) {
|
|
||||||
lines.push(this.writeMethod(method));
|
|
||||||
lines.push("");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disposal method (derived from class name)
|
|
||||||
lines.push(` void dispose() => _bindings.${dartClass.cName}_dispose(_ptr);`);
|
|
||||||
|
|
||||||
lines.push("}");
|
|
||||||
|
|
||||||
// Write to file
|
|
||||||
const fileName = `${toSnakeCase(dartClass.name)}.dart`;
|
|
||||||
const filePath = path.join(this.outputDir, fileName);
|
|
||||||
await fs.writeFile(filePath, lines.join('\n'));
|
|
||||||
}
|
|
||||||
|
|
||||||
private writeConstructor(dartClass: DartClass, constructor: DartConstructor): string {
|
|
||||||
const params = constructor.parameters.map(p =>
|
|
||||||
`${p.type.dart} ${p.name}`
|
|
||||||
).join(', ');
|
|
||||||
|
|
||||||
const args = constructor.parameters.map(p =>
|
|
||||||
this.convertDartToC(p.name, p.type, p.cType)
|
|
||||||
).join(', ');
|
|
||||||
|
|
||||||
return [
|
|
||||||
` factory ${dartClass.name}.create(SpineFlutterBindings bindings${params ? ', ' + params : ''}) {`,
|
|
||||||
` final ptr = bindings.${constructor.cFunctionName}(${args});`,
|
|
||||||
` return ${dartClass.name}._(ptr, bindings);`,
|
|
||||||
` }`
|
|
||||||
].join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
private writeGetter(getter: DartGetter): string {
|
|
||||||
if (getter.returnType.isNative) {
|
|
||||||
return ` ${getter.returnType.dart} get ${getter.name} => _bindings.${getter.cFunctionName}(_ptr);`;
|
|
||||||
} else {
|
|
||||||
return [
|
|
||||||
` ${getter.returnType.dart} get ${getter.name} {`,
|
|
||||||
` final ptr = _bindings.${getter.cFunctionName}(_ptr);`,
|
|
||||||
` return ${getter.returnType.dart}._(ptr, _bindings);`,
|
|
||||||
` }`
|
|
||||||
].join('\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private writeSetter(setter: DartSetter): string {
|
|
||||||
const conversion = this.convertDartToC('value', setter.parameterType, '');
|
|
||||||
return ` set ${setter.name}(${setter.parameterType.dart} value) => _bindings.${setter.cFunctionName}(_ptr, ${conversion});`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private writeArrayGetter(arrayGetter: DartArrayGetter): string {
|
|
||||||
return [
|
|
||||||
` Array<${arrayGetter.elementType}> get ${arrayGetter.name} {`,
|
|
||||||
` final array = _bindings.${arrayGetter.cGetterName}(_ptr);`,
|
|
||||||
` return Array.create<${arrayGetter.elementType}>(array, _bindings, ${arrayGetter.elementType}._);`,
|
|
||||||
` }`
|
|
||||||
].join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
private writeMethod(method: DartMethod): string {
|
|
||||||
const params = method.parameters.map(p =>
|
|
||||||
`${p.type.dart} ${p.name}`
|
|
||||||
).join(', ');
|
|
||||||
|
|
||||||
const args = ['_ptr', ...method.parameters.map(p =>
|
|
||||||
this.convertDartToC(p.name, p.type, p.cType)
|
|
||||||
)].join(', ');
|
|
||||||
|
|
||||||
if (method.returnType.dart === 'void') {
|
|
||||||
return [
|
|
||||||
` void ${method.name}(${params}) {`,
|
|
||||||
` _bindings.${method.cFunctionName}(${args});`,
|
|
||||||
` }`
|
|
||||||
].join('\n');
|
|
||||||
} else if (method.returnType.isNative) {
|
|
||||||
return [
|
|
||||||
` ${method.returnType.dart} ${method.name}(${params}) {`,
|
|
||||||
` return _bindings.${method.cFunctionName}(${args});`,
|
|
||||||
` }`
|
|
||||||
].join('\n');
|
|
||||||
} else {
|
|
||||||
return [
|
|
||||||
` ${method.returnType.dart} ${method.name}(${params}) {`,
|
|
||||||
` final ptr = _bindings.${method.cFunctionName}(${args});`,
|
|
||||||
` return ${method.returnType.dart}._(ptr, _bindings);`,
|
|
||||||
` }`
|
|
||||||
].join('\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private convertDartToC(dartValue: string, dartType: DartType, cType: string): string {
|
|
||||||
if (dartType.isNative) {
|
|
||||||
// Handle string conversion
|
|
||||||
if (dartType.dart === 'String') {
|
|
||||||
return `${dartValue}.toNativeUtf8().cast<Char>()`;
|
|
||||||
}
|
|
||||||
return dartValue;
|
|
||||||
} else {
|
|
||||||
// Wrapper class - extract the pointer
|
|
||||||
return `${dartValue}._ptr`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Generic Array Implementation (`dart-array-writer.ts`)
|
|
||||||
|
|
||||||
Generates a single reusable Array class:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
export class DartArrayWriter {
|
|
||||||
async writeArrayClass(outputDir: string): Promise<void> {
|
|
||||||
const content = `
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
|
||||||
// Generated by spine-c dart-wrapper generator
|
|
||||||
|
|
||||||
import 'dart:collection';
|
|
||||||
import 'dart:ffi';
|
|
||||||
import 'spine_flutter_bindings_generated.dart';
|
|
||||||
|
|
||||||
class Array<T> extends ListBase<T> {
|
|
||||||
final Pointer _nativeArray;
|
|
||||||
final SpineFlutterBindings _bindings;
|
|
||||||
final T Function(Pointer) _elementFactory;
|
|
||||||
final String _arrayTypeName;
|
|
||||||
|
|
||||||
Array._(
|
|
||||||
this._nativeArray,
|
|
||||||
this._bindings,
|
|
||||||
this._elementFactory,
|
|
||||||
this._arrayTypeName,
|
|
||||||
);
|
|
||||||
|
|
||||||
static Array<T> create<T>(
|
|
||||||
Pointer nativeArray,
|
|
||||||
SpineFlutterBindings bindings,
|
|
||||||
T Function(Pointer) elementFactory,
|
|
||||||
) {
|
|
||||||
final typeName = T.toString().toLowerCase();
|
|
||||||
return Array._(nativeArray, bindings, elementFactory, 'spine_array_\$typeName');
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get length {
|
|
||||||
// Use dynamic function lookup based on type
|
|
||||||
switch (_arrayTypeName) {
|
|
||||||
case 'spine_array_timeline':
|
|
||||||
return _bindings.spine_array_timeline_get_size(_nativeArray.cast());
|
|
||||||
case 'spine_array_bone_data':
|
|
||||||
return _bindings.spine_array_bone_data_get_size(_nativeArray.cast());
|
|
||||||
case 'spine_array_slot_data':
|
|
||||||
return _bindings.spine_array_slot_data_get_size(_nativeArray.cast());
|
|
||||||
// Add more cases as needed
|
|
||||||
default:
|
|
||||||
throw UnsupportedError('Unknown array type: \$_arrayTypeName');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
T operator [](int index) {
|
|
||||||
if (index < 0 || index >= length) {
|
|
||||||
throw RangeError.index(index, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer elementPtr;
|
|
||||||
switch (_arrayTypeName) {
|
|
||||||
case 'spine_array_timeline':
|
|
||||||
elementPtr = _bindings.spine_array_timeline_get(_nativeArray.cast(), index);
|
|
||||||
break;
|
|
||||||
case 'spine_array_bone_data':
|
|
||||||
elementPtr = _bindings.spine_array_bone_data_get(_nativeArray.cast(), index);
|
|
||||||
break;
|
|
||||||
case 'spine_array_slot_data':
|
|
||||||
elementPtr = _bindings.spine_array_slot_data_get(_nativeArray.cast(), index);
|
|
||||||
break;
|
|
||||||
// Add more cases as needed
|
|
||||||
default:
|
|
||||||
throw UnsupportedError('Unknown array type: \$_arrayTypeName');
|
|
||||||
}
|
|
||||||
|
|
||||||
return _elementFactory(elementPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void operator []=(int index, T value) {
|
|
||||||
throw UnsupportedError('Array is read-only');
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
set length(int newLength) {
|
|
||||||
throw UnsupportedError('Array is read-only');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const filePath = path.join(outputDir, 'array.dart');
|
|
||||||
await fs.writeFile(filePath, content.trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. Enum Generator (`dart-enum-writer.ts`)
|
|
||||||
|
|
||||||
Generates Dart enum wrappers:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
export class DartEnumWriter {
|
|
||||||
async writeEnum(dartEnum: DartEnum, outputDir: string): Promise<void> {
|
|
||||||
const lines: string[] = [];
|
|
||||||
|
|
||||||
// File header
|
|
||||||
lines.push("// AUTO GENERATED FILE, DO NOT EDIT.");
|
|
||||||
lines.push("// Generated by spine-c dart-wrapper generator");
|
|
||||||
lines.push("");
|
|
||||||
|
|
||||||
// Enum declaration
|
|
||||||
lines.push(`enum ${dartEnum.name} {`);
|
|
||||||
|
|
||||||
// Enum values
|
|
||||||
for (let i = 0; i < dartEnum.values.length; i++) {
|
|
||||||
const value = dartEnum.values[i];
|
|
||||||
const comma = i < dartEnum.values.length - 1 ? ',' : '';
|
|
||||||
lines.push(` ${value.name}(${value.value})${comma}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
lines.push("");
|
|
||||||
lines.push(" const ${dartEnum.name}(this.value);");
|
|
||||||
lines.push(" final int value;");
|
|
||||||
lines.push("");
|
|
||||||
|
|
||||||
// From native conversion
|
|
||||||
lines.push(` static ${dartEnum.name} fromNative(int value) {`);
|
|
||||||
lines.push(" switch (value) {");
|
|
||||||
for (const value of dartEnum.values) {
|
|
||||||
lines.push(` case ${value.value}: return ${dartEnum.name}.${value.name};`);
|
|
||||||
}
|
|
||||||
lines.push(` default: throw ArgumentError('Unknown ${dartEnum.name} value: \$value');`);
|
|
||||||
lines.push(" }");
|
|
||||||
lines.push(" }");
|
|
||||||
lines.push("}");
|
|
||||||
|
|
||||||
// Write to file
|
|
||||||
const fileName = `${toSnakeCase(dartEnum.name)}.dart`;
|
|
||||||
const filePath = path.join(outputDir, fileName);
|
|
||||||
await fs.writeFile(filePath, lines.join('\n'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7. Main Generator Orchestrator (`dart-generator.ts`)
|
|
||||||
|
|
||||||
Coordinates the entire generation process:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { CClassOrStruct, CEnum, CArrayType } from './c-types';
|
|
||||||
import { DartClass, DartEnum } from './dart-types';
|
|
||||||
import { DartTypeMapper } from './dart-type-mapper';
|
|
||||||
import { DartWriter } from './dart-writer';
|
|
||||||
import { DartEnumWriter } from './dart-enum-writer';
|
|
||||||
import { DartArrayWriter } from './dart-array-writer';
|
|
||||||
import { extractMethodName, isGetter, isSetter, extractPropertyName } from './dart-naming';
|
|
||||||
|
|
||||||
export class DartGenerator {
|
|
||||||
private typeMapper = new DartTypeMapper();
|
|
||||||
private writer: DartWriter;
|
|
||||||
private enumWriter = new DartEnumWriter();
|
|
||||||
private arrayWriter = new DartArrayWriter();
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private cTypes: CClassOrStruct[],
|
|
||||||
private cEnums: CEnum[],
|
|
||||||
private cArrayTypes: CArrayType[],
|
|
||||||
private outputDir: string,
|
|
||||||
private bindingsImport: string = 'spine_flutter_bindings_generated.dart'
|
|
||||||
) {
|
|
||||||
this.writer = new DartWriter(outputDir, bindingsImport);
|
|
||||||
}
|
|
||||||
|
|
||||||
async generateAll(): Promise<void> {
|
|
||||||
// Ensure output directory exists
|
|
||||||
await fs.mkdir(this.outputDir, { recursive: true });
|
|
||||||
|
|
||||||
console.log(`Generating ${this.cTypes.length} Dart wrapper classes...`);
|
|
||||||
|
|
||||||
// Generate wrapper classes
|
|
||||||
for (const cType of this.cTypes) {
|
|
||||||
const dartClass = this.convertCTypeToDartClass(cType);
|
|
||||||
await this.writer.writeClass(dartClass);
|
|
||||||
console.log(`Generated: ${dartClass.name}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Generating ${this.cEnums.length} Dart enums...`);
|
|
||||||
|
|
||||||
// Generate enums
|
|
||||||
for (const cEnum of this.cEnums) {
|
|
||||||
const dartEnum = this.convertCEnumToDartEnum(cEnum);
|
|
||||||
await this.enumWriter.writeEnum(dartEnum, this.outputDir);
|
|
||||||
console.log(`Generated enum: ${dartEnum.name}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate generic Array class
|
|
||||||
await this.arrayWriter.writeArrayClass(this.outputDir);
|
|
||||||
console.log('Generated: Array<T>');
|
|
||||||
|
|
||||||
console.log('Dart wrapper generation complete!');
|
|
||||||
}
|
|
||||||
|
|
||||||
private convertCTypeToDartClass(cType: CClassOrStruct): DartClass {
|
|
||||||
const className = toPascalCase(cType.name.replace('spine_', ''));
|
|
||||||
|
|
||||||
// Separate getters, setters, and regular methods
|
|
||||||
const getters: DartGetter[] = [];
|
|
||||||
const setters: DartSetter[] = [];
|
|
||||||
const methods: DartMethod[] = [];
|
|
||||||
const constructors: DartConstructor[] = [];
|
|
||||||
const arrays: DartArrayGetter[] = [];
|
|
||||||
|
|
||||||
for (const method of cType.methods) {
|
|
||||||
const methodName = extractMethodName(method.name, cType.name);
|
|
||||||
|
|
||||||
if (method.name.includes('_create')) {
|
|
||||||
// Constructor
|
|
||||||
constructors.push({
|
|
||||||
cFunctionName: method.name,
|
|
||||||
parameters: method.parameters.slice(0, -1).map(p => ({
|
|
||||||
name: p.name,
|
|
||||||
type: this.typeMapper.mapCTypeToDart(p.type),
|
|
||||||
cType: p.type
|
|
||||||
}))
|
|
||||||
});
|
|
||||||
} else if (isGetter(methodName)) {
|
|
||||||
// Getter
|
|
||||||
const propertyName = extractPropertyName(methodName);
|
|
||||||
const returnType = this.typeMapper.mapCTypeToDart(method.returnType);
|
|
||||||
|
|
||||||
// Check if this is an array getter
|
|
||||||
if (method.returnType.startsWith('spine_array_')) {
|
|
||||||
const elementType = this.extractArrayElementType(method.returnType);
|
|
||||||
arrays.push({
|
|
||||||
name: propertyName,
|
|
||||||
elementType,
|
|
||||||
cArrayType: method.returnType,
|
|
||||||
cGetterName: method.name
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
getters.push({
|
|
||||||
name: propertyName,
|
|
||||||
cFunctionName: method.name,
|
|
||||||
returnType
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (isSetter(methodName)) {
|
|
||||||
// Setter
|
|
||||||
const propertyName = extractPropertyName(methodName);
|
|
||||||
const paramType = this.typeMapper.mapCTypeToDart(method.parameters[1].type);
|
|
||||||
setters.push({
|
|
||||||
name: propertyName,
|
|
||||||
cFunctionName: method.name,
|
|
||||||
parameterType: paramType
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Regular method
|
|
||||||
methods.push({
|
|
||||||
name: methodName,
|
|
||||||
cFunctionName: method.name,
|
|
||||||
returnType: this.typeMapper.mapCTypeToDart(method.returnType),
|
|
||||||
parameters: method.parameters.slice(1).map(p => ({
|
|
||||||
name: p.name,
|
|
||||||
type: this.typeMapper.mapCTypeToDart(p.type),
|
|
||||||
cType: p.type
|
|
||||||
}))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: className,
|
|
||||||
cName: cType.name,
|
|
||||||
nativeType: `Pointer<${cType.name}_wrapper>`,
|
|
||||||
constructors,
|
|
||||||
methods,
|
|
||||||
getters,
|
|
||||||
setters,
|
|
||||||
arrays
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private convertCEnumToDartEnum(cEnum: CEnum): DartEnum {
|
|
||||||
return {
|
|
||||||
name: toPascalCase(cEnum.name.replace('spine_', '')),
|
|
||||||
cName: cEnum.name,
|
|
||||||
values: cEnum.values.map(value => ({
|
|
||||||
name: toCamelCase(value.name.replace(/^SPINE_.*?_/, '')),
|
|
||||||
cName: value.name,
|
|
||||||
value: value.value
|
|
||||||
}))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private extractArrayElementType(arrayType: string): string {
|
|
||||||
// spine_array_timeline -> Timeline
|
|
||||||
// spine_array_bone_data -> BoneData
|
|
||||||
const match = arrayType.match(/spine_array_(.+)/);
|
|
||||||
if (!match) throw new Error(`Invalid array type: ${arrayType}`);
|
|
||||||
|
|
||||||
return toPascalCase(match[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8. Integration with Existing Codegen (`index.ts` modifications)
|
|
||||||
|
|
||||||
Extend the existing main function:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Add to existing imports
|
|
||||||
import { DartGenerator } from './dart-generator';
|
|
||||||
|
|
||||||
// Add to existing main() function after C generation
|
|
||||||
async function main() {
|
|
||||||
// ... existing C generation code ...
|
|
||||||
|
|
||||||
// Write all C files to disk
|
|
||||||
const cWriter = new CWriter(path.join(__dirname, '../../src/generated'));
|
|
||||||
await cWriter.writeAll(cTypes, cEnums, cArrayTypes);
|
|
||||||
|
|
||||||
console.log('C code generation complete!');
|
|
||||||
|
|
||||||
// NEW: Generate Dart wrappers
|
|
||||||
const dartOutputDir = path.join(__dirname, '../../../lib/src/generated');
|
|
||||||
const dartGenerator = new DartGenerator(
|
|
||||||
cTypes,
|
|
||||||
cEnums,
|
|
||||||
cArrayTypes,
|
|
||||||
dartOutputDir
|
|
||||||
);
|
|
||||||
|
|
||||||
await dartGenerator.generateAll();
|
|
||||||
|
|
||||||
console.log('All code generation complete!');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Generated Output Structure
|
|
||||||
|
|
||||||
After running the generator, the output structure will be:
|
|
||||||
|
|
||||||
```
|
|
||||||
lib/
|
|
||||||
├── spine_flutter.dart # Main export file
|
|
||||||
├── spine_flutter_bindings_generated.dart # Raw FFI bindings (from ffigen)
|
|
||||||
└── src/
|
|
||||||
└── generated/
|
|
||||||
├── array.dart # Generic Array<T> implementation
|
|
||||||
├── animation.dart # Animation wrapper class
|
|
||||||
├── skeleton.dart # Skeleton wrapper class
|
|
||||||
├── bone_data.dart # BoneData wrapper class
|
|
||||||
├── blend_mode.dart # BlendMode enum
|
|
||||||
└── ... # More generated classes and enums
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage Examples
|
|
||||||
|
|
||||||
### Before (Manual FFI Usage)
|
|
||||||
```dart
|
|
||||||
// Raw FFI - error-prone and verbose
|
|
||||||
final skeletonDataPtr = bindings.spine_skeleton_data_create_from_file('skeleton.json'.toNativeUtf8().cast());
|
|
||||||
final bonesArrayPtr = bindings.spine_skeleton_data_get_bones(skeletonDataPtr);
|
|
||||||
final numBones = bindings.spine_skeleton_data_get_num_bones(skeletonDataPtr);
|
|
||||||
|
|
||||||
for (int i = 0; i < numBones; i++) {
|
|
||||||
final bonePtr = bindings.spine_array_bone_data_get(bonesArrayPtr, i);
|
|
||||||
final namePtr = bindings.spine_bone_data_get_name(bonePtr);
|
|
||||||
final name = namePtr.cast<Utf8>().toDartString();
|
|
||||||
print('Bone: $name');
|
|
||||||
}
|
|
||||||
|
|
||||||
bindings.spine_skeleton_data_dispose(skeletonDataPtr);
|
|
||||||
```
|
|
||||||
|
|
||||||
### After (Generated Wrapper Usage)
|
|
||||||
```dart
|
|
||||||
// Clean, type-safe API
|
|
||||||
final skeletonData = SkeletonData.fromFile(bindings, 'skeleton.json');
|
|
||||||
final bones = skeletonData.bones; // Array<BoneData>
|
|
||||||
|
|
||||||
for (final bone in bones) { // Natural Dart iteration
|
|
||||||
print('Bone: ${bone.name}'); // Direct property access
|
|
||||||
}
|
|
||||||
|
|
||||||
skeletonData.dispose(); // Clean disposal
|
|
||||||
```
|
|
||||||
|
|
||||||
### Advanced Usage
|
|
||||||
```dart
|
|
||||||
// Complex operations made simple
|
|
||||||
final skeleton = Skeleton.create(bindings, skeletonData);
|
|
||||||
final animState = AnimationState.create(bindings, animStateData);
|
|
||||||
|
|
||||||
// Arrays work like native Dart Lists
|
|
||||||
final animations = skeleton.data.animations;
|
|
||||||
final firstAnim = animations[0];
|
|
||||||
final animCount = animations.length;
|
|
||||||
|
|
||||||
// Functional programming support
|
|
||||||
final animNames = animations.map((a) => a.name).toList();
|
|
||||||
final longAnims = animations.where((a) => a.duration > 5.0).toList();
|
|
||||||
|
|
||||||
// Enum usage
|
|
||||||
skeleton.setSkin('goblin');
|
|
||||||
animState.setAnimation(0, firstAnim, true);
|
|
||||||
animState.setMixByName('idle', 'walk', 0.2);
|
|
||||||
|
|
||||||
// Chaining operations
|
|
||||||
skeleton.data.bones
|
|
||||||
.where((bone) => bone.parent != null)
|
|
||||||
.forEach((bone) => print('Child bone: ${bone.name}'));
|
|
||||||
```
|
|
||||||
|
|
||||||
## Build Integration
|
|
||||||
|
|
||||||
### 1. Update `generate_bindings.sh`
|
|
||||||
|
|
||||||
Add Dart wrapper generation to the existing script:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# ... existing FFI generation code ...
|
|
||||||
|
|
||||||
# Generate Dart wrappers
|
|
||||||
echo "Generating Dart wrapper classes..."
|
|
||||||
cd src/spine-c/codegen
|
|
||||||
npm run generate-dart
|
|
||||||
|
|
||||||
echo "✅ All code generation completed!"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Add npm script to `spine-c/codegen/package.json`
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"build": "tsc",
|
|
||||||
"generate": "npm run build && node dist/index.js",
|
|
||||||
"generate-dart": "npm run build && node dist/index.js --dart-only",
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Update `pubspec.yaml` dependencies
|
|
||||||
|
|
||||||
The generated code will require:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
dependencies:
|
|
||||||
flutter:
|
|
||||||
sdk: flutter
|
|
||||||
ffi: ^2.1.0
|
|
||||||
# ... existing dependencies
|
|
||||||
```
|
|
||||||
|
|
||||||
## Benefits
|
|
||||||
|
|
||||||
### 1. **Developer Experience**
|
|
||||||
- **Type Safety**: Compile-time checking prevents FFI pointer errors
|
|
||||||
- **IDE Support**: Full autocomplete, documentation, and refactoring
|
|
||||||
- **Familiar API**: Uses standard Dart patterns (getters, setters, Lists)
|
|
||||||
- **Memory Safety**: Automatic lifetime management with dispose patterns
|
|
||||||
|
|
||||||
### 2. **Performance**
|
|
||||||
- **Zero Copy**: Arrays provide lazy access to native data
|
|
||||||
- **Minimal Overhead**: Thin wrappers over FFI calls
|
|
||||||
- **Batch Operations**: Array operations can be optimized in native code
|
|
||||||
|
|
||||||
### 3. **Maintainability**
|
|
||||||
- **Automatic Updates**: Changes to C++ API automatically flow through
|
|
||||||
- **Consistent Patterns**: All classes follow the same conventions
|
|
||||||
- **Documentation**: Generated code includes comprehensive docs
|
|
||||||
- **Testing**: Type-safe API makes unit testing straightforward
|
|
||||||
|
|
||||||
### 4. **Reliability**
|
|
||||||
- **No Manual Coding**: Eliminates human error in wrapper implementation
|
|
||||||
- **Validated Generation**: Uses proven C type information
|
|
||||||
- **Comprehensive Coverage**: Every C function gets a Dart wrapper
|
|
||||||
|
|
||||||
## Implementation Timeline
|
|
||||||
|
|
||||||
### Phase 1: Core Infrastructure (1-2 weeks)
|
|
||||||
- [ ] Set up TypeScript generator project structure
|
|
||||||
- [ ] Implement basic type mapping system
|
|
||||||
- [ ] Create simple class generator for basic types
|
|
||||||
- [ ] Test with a few example classes (Animation, Skeleton)
|
|
||||||
|
|
||||||
### Phase 2: Array Support (1 week)
|
|
||||||
- [ ] Implement generic Array<T> class
|
|
||||||
- [ ] Add array detection and generation logic
|
|
||||||
- [ ] Test array functionality with timeline/bone arrays
|
|
||||||
|
|
||||||
### Phase 3: Enum Support (3-5 days)
|
|
||||||
- [ ] Add enum detection and generation
|
|
||||||
- [ ] Implement enum value mapping
|
|
||||||
- [ ] Test with BlendMode and other enums
|
|
||||||
|
|
||||||
### Phase 4: Advanced Features (1 week)
|
|
||||||
- [ ] Add constructor detection and generation
|
|
||||||
- [ ] Implement property getter/setter pairing
|
|
||||||
- [ ] Add disposal pattern detection
|
|
||||||
- [ ] Memory management best practices
|
|
||||||
|
|
||||||
### Phase 5: Integration & Polish (3-5 days)
|
|
||||||
- [ ] Integrate with existing build pipeline
|
|
||||||
- [ ] Add comprehensive documentation
|
|
||||||
- [ ] Create migration guide from manual FFI
|
|
||||||
- [ ] Performance testing and optimization
|
|
||||||
|
|
||||||
### Phase 6: Testing & Validation (1 week)
|
|
||||||
- [ ] Unit tests for all generated wrappers
|
|
||||||
- [ ] Integration tests with actual Spine files
|
|
||||||
- [ ] Performance benchmarks vs raw FFI
|
|
||||||
- [ ] Documentation and examples
|
|
||||||
|
|
||||||
**Total Estimated Time: 4-6 weeks**
|
|
||||||
|
|
||||||
## Future Enhancements
|
|
||||||
|
|
||||||
### 1. **Advanced Memory Management**
|
|
||||||
- Automatic disposal when objects go out of scope
|
|
||||||
- Reference counting for shared objects
|
|
||||||
- Memory leak detection in debug mode
|
|
||||||
|
|
||||||
### 2. **Performance Optimizations**
|
|
||||||
- Cached property access
|
|
||||||
- Batch array operations
|
|
||||||
- Native collection implementations
|
|
||||||
|
|
||||||
### 3. **Developer Tools**
|
|
||||||
- Debug visualizations for Spine objects
|
|
||||||
- Memory usage monitoring
|
|
||||||
- Performance profiling integration
|
|
||||||
|
|
||||||
### 4. **API Enhancements**
|
|
||||||
- Async/Future support for long operations
|
|
||||||
- Stream-based event handling
|
|
||||||
- Reactive programming patterns
|
|
||||||
|
|
||||||
This comprehensive generator will transform the Spine Flutter experience from low-level FFI manipulation to a clean, type-safe, and performant Dart API that feels native to the Flutter ecosystem.
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
///
|
|
||||||
/// Spine Runtimes License Agreement
|
|
||||||
/// Last updated April 5, 2025. Replaces all prior versions.
|
|
||||||
///
|
|
||||||
/// Copyright (c) 2013-2025, Esoteric Software LLC
|
|
||||||
///
|
|
||||||
/// Integration of the Spine Runtimes into software or otherwise creating
|
|
||||||
/// derivative works of the Spine Runtimes is permitted under the terms and
|
|
||||||
/// conditions of Section 2 of the Spine Editor License Agreement:
|
|
||||||
/// http://esotericsoftware.com/spine-editor-license
|
|
||||||
///
|
|
||||||
/// Otherwise, it is permitted to integrate the Spine Runtimes into software
|
|
||||||
/// or otherwise create derivative works of the Spine Runtimes (collectively,
|
|
||||||
/// "Products"), provided that each user of the Products must obtain their own
|
|
||||||
/// Spine Editor license and redistribution of the Products in any form must
|
|
||||||
/// include this license and copyright notice.
|
|
||||||
///
|
|
||||||
/// THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
|
||||||
/// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
/// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
|
||||||
/// BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) 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
|
|
||||||
/// THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
///
|
|
||||||
|
|
||||||
export 'dart:ffi' if (dart.library.html) 'package:wasm_ffi/ffi.dart';
|
|
||||||
|
|
||||||
export 'package:ffi/ffi.dart' if (dart.library.html) 'package:wasm_ffi/ffi_utils.dart';
|
|
||||||
// Only export our custom malloc on native platforms
|
|
||||||
export 'malloc_native.dart' if (dart.library.io) 'malloc_native.dart';
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'ffi_proxy.dart';
|
|
||||||
|
|
||||||
/// The contents of a native zero-terminated array of UTF-8 code units.
|
|
||||||
///
|
|
||||||
/// The Utf8 type itself has no functionality, it's only intended to be used
|
|
||||||
/// through a `Pointer<Utf8>` representing the entire array. This pointer is
|
|
||||||
/// the equivalent of a char pointer (`const char*`) in C code.
|
|
||||||
final class Utf8 extends Opaque {}
|
|
||||||
|
|
||||||
/// Extension method for converting a`Pointer<Utf8>` to a [String].
|
|
||||||
extension Utf8Pointer on Pointer<Utf8> {
|
|
||||||
/// The number of UTF-8 code units in this zero-terminated UTF-8 string.
|
|
||||||
///
|
|
||||||
/// The UTF-8 code units of the strings are the non-zero code units up to the
|
|
||||||
/// first zero code unit.
|
|
||||||
int get length {
|
|
||||||
_ensureNotNullptr('length');
|
|
||||||
final codeUnits = cast<Uint8>();
|
|
||||||
return _length(codeUnits);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts this UTF-8 encoded string to a Dart string.
|
|
||||||
///
|
|
||||||
/// Decodes the UTF-8 code units of this zero-terminated byte array as
|
|
||||||
/// Unicode code points and creates a Dart string containing those code
|
|
||||||
/// points.
|
|
||||||
///
|
|
||||||
/// If [length] is provided, zero-termination is ignored and the result can
|
|
||||||
/// contain NUL characters.
|
|
||||||
///
|
|
||||||
/// If [length] is not provided, the returned string is the string up til
|
|
||||||
/// but not including the first NUL character.
|
|
||||||
String toDartString({int? length}) {
|
|
||||||
_ensureNotNullptr('toDartString');
|
|
||||||
final codeUnits = cast<Uint8>();
|
|
||||||
if (length != null) {
|
|
||||||
RangeError.checkNotNegative(length, 'length');
|
|
||||||
} else {
|
|
||||||
length = _length(codeUnits);
|
|
||||||
}
|
|
||||||
return utf8.decode(codeUnits.asTypedList(length));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _length(Pointer<Uint8> codeUnits) {
|
|
||||||
var length = 0;
|
|
||||||
while (codeUnits[length] != 0) {
|
|
||||||
length++;
|
|
||||||
}
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _ensureNotNullptr(String operation) {
|
|
||||||
if (this == nullptr) {
|
|
||||||
throw UnsupportedError("Operation '$operation' not allowed on a 'nullptr'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extension method for converting a [String] to a `Pointer<Utf8>`.
|
|
||||||
extension StringUtf8Pointer on String {
|
|
||||||
/// Creates a zero-terminated [Utf8] code-unit array from this String.
|
|
||||||
///
|
|
||||||
/// If this [String] contains NUL characters, converting it back to a string
|
|
||||||
/// using [Utf8Pointer.toDartString] will truncate the result if a length is
|
|
||||||
/// not passed.
|
|
||||||
///
|
|
||||||
/// Unpaired surrogate code points in this [String] will be encoded as
|
|
||||||
/// replacement characters (U+FFFD, encoded as the bytes 0xEF 0xBF 0xBD) in
|
|
||||||
/// the UTF-8 encoded result. See [Utf8Encoder] for details on encoding.
|
|
||||||
///
|
|
||||||
/// Returns an [allocator]-allocated pointer to the result.
|
|
||||||
Pointer<Utf8> toNativeUtf8({Allocator allocator = malloc}) {
|
|
||||||
final units = utf8.encode(this);
|
|
||||||
final Pointer<Uint8> result = allocator<Uint8>(units.length + 1);
|
|
||||||
final Uint8List nativeString = result.asTypedList(units.length + 1);
|
|
||||||
nativeString.setAll(0, units);
|
|
||||||
nativeString[units.length] = 0;
|
|
||||||
return result.cast();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'curve_timeline1.dart';
|
import 'curve_timeline1.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'animation.dart';
|
import 'animation.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'animation.dart';
|
import 'animation.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import '../native_array.dart';
|
import '../native_array.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'atlas.dart';
|
import 'atlas.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'format.dart';
|
import 'format.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'bounding_box_attachment.dart';
|
import 'bounding_box_attachment.dart';
|
||||||
import 'clipping_attachment.dart';
|
import 'clipping_attachment.dart';
|
||||||
import 'mesh_attachment.dart';
|
import 'mesh_attachment.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'slot_timeline.dart';
|
import 'slot_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'bone_local.dart';
|
import 'bone_local.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'inherit.dart';
|
import 'inherit.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'bone_timeline.dart';
|
import 'bone_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'bone_timeline.dart';
|
import 'bone_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'color.dart';
|
import 'color.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'color.dart';
|
import 'color.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
import 'constraint_data.dart';
|
import 'constraint_data.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
import 'constraint.dart';
|
import 'constraint.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'constraint_timeline.dart';
|
import 'constraint_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'curve_timeline.dart';
|
import 'curve_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'event_data.dart';
|
import 'event_data.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'event.dart';
|
import 'event.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'from_property.dart';
|
import 'from_property.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'from_property.dart';
|
import 'from_property.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'from_property.dart';
|
import 'from_property.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'from_property.dart';
|
import 'from_property.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'from_property.dart';
|
import 'from_property.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'from_property.dart';
|
import 'from_property.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'constraint_timeline.dart';
|
import 'constraint_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'bone_timeline.dart';
|
import 'bone_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
|
||||||
/// LinkedMesh wrapper
|
/// LinkedMesh wrapper
|
||||||
abstract class LinkedMesh {
|
abstract class LinkedMesh {
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'constraint_timeline.dart';
|
import 'constraint_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'constraint_timeline1.dart';
|
import 'constraint_timeline1.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'constraint_timeline1.dart';
|
import 'constraint_timeline1.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'physics_constraint_timeline.dart';
|
import 'physics_constraint_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'rtti.dart';
|
import 'rtti.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'physics_constraint_timeline.dart';
|
import 'physics_constraint_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'physics_constraint_timeline.dart';
|
import 'physics_constraint_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'physics_constraint_timeline.dart';
|
import 'physics_constraint_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'physics_constraint_timeline.dart';
|
import 'physics_constraint_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'constraint_timeline.dart';
|
import 'constraint_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'physics_constraint_timeline.dart';
|
import 'physics_constraint_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'constraint_timeline.dart';
|
import 'constraint_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'physics_constraint_timeline.dart';
|
import 'physics_constraint_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'attachment.dart';
|
import 'attachment.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
|
||||||
/// Posed wrapper
|
/// Posed wrapper
|
||||||
abstract class Posed {
|
abstract class Posed {
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'blend_mode.dart';
|
import 'blend_mode.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'slot_curve_timeline.dart';
|
import 'slot_curve_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'slot_curve_timeline.dart';
|
import 'slot_curve_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'slot_curve_timeline.dart';
|
import 'slot_curve_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'slot_curve_timeline.dart';
|
import 'slot_curve_timeline.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'bone_timeline1.dart';
|
import 'bone_timeline1.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'bone_timeline2.dart';
|
import 'bone_timeline2.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'bone_timeline1.dart';
|
import 'bone_timeline1.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'bone_timeline1.dart';
|
import 'bone_timeline1.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'attachment.dart';
|
import 'attachment.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'bone_timeline2.dart';
|
import 'bone_timeline2.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'bone_timeline1.dart';
|
import 'bone_timeline1.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'bone_timeline1.dart';
|
import 'bone_timeline1.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'atlas.dart';
|
import 'atlas.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'arrays.dart';
|
import 'arrays.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'animation.dart';
|
import 'animation.dart';
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
|
|
||||||
import '../ffi_proxy.dart';
|
import 'package:universal_ffi/ffi.dart';
|
||||||
|
import 'package:universal_ffi/ffi_utils.dart';
|
||||||
import 'spine_dart_bindings_generated.dart';
|
import 'spine_dart_bindings_generated.dart';
|
||||||
import '../spine_bindings.dart';
|
import '../spine_bindings.dart';
|
||||||
import 'atlas.dart';
|
import 'atlas.dart';
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user