From 95c567ab035b0dd5b8090a8883a080cead593662 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Sat, 27 Aug 2022 14:51:45 +0200 Subject: [PATCH] [flutter] Warp skeleton, remove drawable.update on native side. --- spine-flutter/example/lib/main.dart | 22 +- spine-flutter/lib/spine_flutter.dart | 26 +- .../lib/spine_flutter_bindings_generated.dart | 879 +++++++++++++++++- spine-flutter/lib/spine_widget.dart | 1 + spine-flutter/src/spine_flutter.cpp | 348 ++++++- spine-flutter/src/spine_flutter.h | 113 ++- 6 files changed, 1300 insertions(+), 89 deletions(-) diff --git a/spine-flutter/example/lib/main.dart b/spine-flutter/example/lib/main.dart index 5179b484d..c00e71b44 100644 --- a/spine-flutter/example/lib/main.dart +++ b/spine-flutter/example/lib/main.dart @@ -35,11 +35,7 @@ class Spineboy extends StatelessWidget { @override Widget build(BuildContext context) { - final controller = SpineWidgetController((controller) { - final state = controller.animationState; - state?.setAnimation(0, "walk", false).setMixDuration(2); - state?.addEmptyAnimation(0, 0.2, 0); - }); + final controller = SpineWidgetController((controller) => controller.animationState?.setAnimation(0, "walk", true)); return Scaffold( appBar: AppBar(title: const Text('Spineboy')), @@ -50,6 +46,22 @@ class Spineboy extends StatelessWidget { } } +class AnimationStateEvents extends StatelessWidget { + const AnimationStateEvents({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final controller = SpineWidgetController((controller) { + final trackEntry = controller.animationState?.setAnimation(0, "walk", true); + }); + + return Scaffold( + appBar: AppBar(title: const Text('Spineboy')), + body: SpineWidget.asset("assets/spineboy-pro.skel", "assets/spineboy.atlas", controller), + ); + } +} + void main() { runApp(MaterialApp( title: "Spine Examples", diff --git a/spine-flutter/lib/spine_flutter.dart b/spine-flutter/lib/spine_flutter.dart index 5f4d9722d..78f9ae2ac 100644 --- a/spine-flutter/lib/spine_flutter.dart +++ b/spine-flutter/lib/spine_flutter.dart @@ -10,7 +10,7 @@ import 'package:http/http.dart' as http; import 'package:flutter/services.dart'; import 'spine_flutter_bindings_generated.dart'; export 'spine_widget.dart'; -import 'package:path/path.dart' as Path; +import 'package:path/path.dart' as path; int majorVersion() => _bindings.spine_major_version(); int minorVersion() => _bindings.spine_minor_version(); @@ -34,15 +34,15 @@ class Atlas { final Pointer error = atlas.ref.error.cast(); final message = error.toDartString(); _bindings.spine_atlas_dispose(atlas); - throw Exception("Couldn't load atlas: " + message); + throw Exception("Couldn't load atlas: $message"); } - final atlasDir = Path.dirname(atlasFileName); + final atlasDir = path.dirname(atlasFileName); List atlasPages = []; List atlasPagePaints = []; for (int i = 0; i < atlas.ref.numImagePaths; i++) { final Pointer atlasPageFile = atlas.ref.imagePaths[i].cast(); - final imagePath = Path.join(atlasDir, atlasPageFile.toDartString()); + final imagePath = path.join(atlasDir, atlasPageFile.toDartString()); var imageData = await loadFile(imagePath); final Codec codec = await instantiateImageCodec(imageData); final FrameInfo frameInfo = await codec.getNextFrame(); @@ -80,7 +80,7 @@ class Atlas { } class SkeletonData { - final Pointer _skeletonData; + final Pointer _skeletonData; bool _disposed; SkeletonData(this._skeletonData): _disposed = false; @@ -91,8 +91,8 @@ class SkeletonData { if (skeletonData.ref.error.address != nullptr.address) { final Pointer error = skeletonData.ref.error.cast(); final message = error.toDartString(); - _bindings.spine_skeleton_data_dispose(skeletonData); - throw Exception("Couldn't load skeleton data: " + message); + _bindings.spine_skeleton_data_result_dispose(skeletonData); + throw Exception("Couldn't load skeleton data: $message"); } return SkeletonData(skeletonData); } @@ -105,8 +105,8 @@ class SkeletonData { if (skeletonData.ref.error.address != nullptr.address) { final Pointer error = skeletonData.ref.error.cast(); final message = error.toDartString(); - _bindings.spine_skeleton_data_dispose(skeletonData); - throw Exception("Couldn't load skeleton data: " + message); + _bindings.spine_skeleton_data_result_dispose(skeletonData); + throw Exception("Couldn't load skeleton data: $message"); } return SkeletonData(skeletonData); } @@ -114,7 +114,7 @@ class SkeletonData { void dispose() { if (_disposed) return; _disposed = true; - _bindings.spine_skeleton_data_dispose(this._skeletonData); + _bindings.spine_skeleton_data_result_dispose(_skeletonData); } } @@ -515,14 +515,16 @@ class SkeletonDrawable { bool _disposed; SkeletonDrawable(this.atlas, this.skeletonData, this._ownsData): _disposed = false { - _drawable = _bindings.spine_skeleton_drawable_create(skeletonData._skeletonData); + _drawable = _bindings.spine_skeleton_drawable_create(skeletonData._skeletonData.ref.skeletonData.cast()); skeleton = Skeleton(_drawable.ref.skeleton); animationState = AnimationState(_drawable.ref.animationState); } void update(double delta) { if (_disposed) return; - _bindings.spine_skeleton_drawable_update(_drawable, delta); + _bindings.spine_animation_state_update(_drawable.ref.animationState, delta); + _bindings.spine_animation_state_apply(_drawable.ref.animationState, _drawable.ref.skeleton); + _bindings.spine_skeleton_update_world_transform(_drawable.ref.skeleton); } List render() { diff --git a/spine-flutter/lib/spine_flutter_bindings_generated.dart b/spine-flutter/lib/spine_flutter_bindings_generated.dart index dd0a0df85..4113d71dd 100644 --- a/spine-flutter/lib/spine_flutter_bindings_generated.dart +++ b/spine-flutter/lib/spine_flutter_bindings_generated.dart @@ -82,7 +82,7 @@ class SpineFlutterBindings { late final _spine_atlas_dispose = _spine_atlas_disposePtr .asFunction)>(); - ffi.Pointer spine_skeleton_data_load_json( + ffi.Pointer spine_skeleton_data_load_json( ffi.Pointer atlas, ffi.Pointer skeletonData, ) { @@ -94,14 +94,15 @@ class SpineFlutterBindings { late final _spine_skeleton_data_load_jsonPtr = _lookup< ffi.NativeFunction< - ffi.Pointer Function(ffi.Pointer, + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>>('spine_skeleton_data_load_json'); late final _spine_skeleton_data_load_json = _spine_skeleton_data_load_jsonPtr.asFunction< - ffi.Pointer Function( + ffi.Pointer Function( ffi.Pointer, ffi.Pointer)>(); - ffi.Pointer spine_skeleton_data_load_binary( + ffi.Pointer spine_skeleton_data_load_binary( ffi.Pointer atlas, ffi.Pointer skeletonData, int length, @@ -115,29 +116,30 @@ class SpineFlutterBindings { late final _spine_skeleton_data_load_binaryPtr = _lookup< ffi.NativeFunction< - ffi.Pointer Function( + ffi.Pointer Function( ffi.Pointer, ffi.Pointer, ffi.Int32)>>('spine_skeleton_data_load_binary'); late final _spine_skeleton_data_load_binary = _spine_skeleton_data_load_binaryPtr.asFunction< - ffi.Pointer Function( + ffi.Pointer Function( ffi.Pointer, ffi.Pointer, int)>(); - void spine_skeleton_data_dispose( - ffi.Pointer skeletonData, + void spine_skeleton_data_result_dispose( + ffi.Pointer skeletonData, ) { - return _spine_skeleton_data_dispose( + return _spine_skeleton_data_result_dispose( skeletonData, ); } - late final _spine_skeleton_data_disposePtr = _lookup< + late final _spine_skeleton_data_result_disposePtr = _lookup< ffi.NativeFunction< - ffi.Void Function(ffi.Pointer)>>( - 'spine_skeleton_data_dispose'); - late final _spine_skeleton_data_dispose = _spine_skeleton_data_disposePtr - .asFunction)>(); + ffi.Void Function(ffi.Pointer)>>( + 'spine_skeleton_data_result_dispose'); + late final _spine_skeleton_data_result_dispose = + _spine_skeleton_data_result_disposePtr + .asFunction)>(); ffi.Pointer spine_skeleton_drawable_create( ffi.Pointer skeletonData, @@ -157,24 +159,6 @@ class SpineFlutterBindings { ffi.Pointer Function( ffi.Pointer)>(); - void spine_skeleton_drawable_update( - ffi.Pointer drawable, - double deltaTime, - ) { - return _spine_skeleton_drawable_update( - drawable, - deltaTime, - ); - } - - late final _spine_skeleton_drawable_updatePtr = _lookup< - ffi.NativeFunction< - ffi.Void Function(ffi.Pointer, - ffi.Float)>>('spine_skeleton_drawable_update'); - late final _spine_skeleton_drawable_update = - _spine_skeleton_drawable_updatePtr.asFunction< - void Function(ffi.Pointer, double)>(); - ffi.Pointer spine_skeleton_drawable_render( ffi.Pointer drawable, ) { @@ -428,6 +412,90 @@ class SpineFlutterBindings { _spine_animation_state_set_time_scalePtr .asFunction(); + int spine_animation_state_events_get_num_events( + spine_animation_state_events events, + ) { + return _spine_animation_state_events_get_num_events( + events, + ); + } + + late final _spine_animation_state_events_get_num_eventsPtr = _lookup< + ffi.NativeFunction>( + 'spine_animation_state_events_get_num_events'); + late final _spine_animation_state_events_get_num_events = + _spine_animation_state_events_get_num_eventsPtr + .asFunction(); + + int spine_animation_state_events_get_event_type( + spine_animation_state_events events, + int index, + ) { + return _spine_animation_state_events_get_event_type( + events, + index, + ); + } + + late final _spine_animation_state_events_get_event_typePtr = _lookup< + ffi.NativeFunction< + ffi.Int32 Function(spine_animation_state_events, + ffi.Int32)>>('spine_animation_state_events_get_event_type'); + late final _spine_animation_state_events_get_event_type = + _spine_animation_state_events_get_event_typePtr + .asFunction(); + + spine_track_entry spine_animation_state_events_get_track_entry( + spine_animation_state_events events, + int index, + ) { + return _spine_animation_state_events_get_track_entry( + events, + index, + ); + } + + late final _spine_animation_state_events_get_track_entryPtr = _lookup< + ffi.NativeFunction< + spine_track_entry Function(spine_animation_state_events, + ffi.Int32)>>('spine_animation_state_events_get_track_entry'); + late final _spine_animation_state_events_get_track_entry = + _spine_animation_state_events_get_track_entryPtr.asFunction< + spine_track_entry Function(spine_animation_state_events, int)>(); + + spine_event spine_animation_state_events_get_event( + spine_animation_state_events events, + int index, + ) { + return _spine_animation_state_events_get_event( + events, + index, + ); + } + + late final _spine_animation_state_events_get_eventPtr = _lookup< + ffi.NativeFunction< + spine_event Function(spine_animation_state_events, + ffi.Int32)>>('spine_animation_state_events_get_event'); + late final _spine_animation_state_events_get_event = + _spine_animation_state_events_get_eventPtr.asFunction< + spine_event Function(spine_animation_state_events, int)>(); + + void spine_animation_state_events_reset( + spine_animation_state_events events, + ) { + return _spine_animation_state_events_reset( + events, + ); + } + + late final _spine_animation_state_events_resetPtr = _lookup< + ffi.NativeFunction>( + 'spine_animation_state_events_reset'); + late final _spine_animation_state_events_reset = + _spine_animation_state_events_resetPtr + .asFunction(); + int spine_track_entry_get_track_index( spine_track_entry entry, ) { @@ -1143,6 +1211,699 @@ class SpineFlutterBindings { late final _spine_track_entry_get_track_complete = _spine_track_entry_get_track_completePtr .asFunction(); + + void spine_skeleton_update_cache( + spine_skeleton skeleton, + ) { + return _spine_skeleton_update_cache( + skeleton, + ); + } + + late final _spine_skeleton_update_cachePtr = + _lookup>( + 'spine_skeleton_update_cache'); + late final _spine_skeleton_update_cache = _spine_skeleton_update_cachePtr + .asFunction(); + + void spine_skeleton_update_world_transform( + spine_skeleton skeleton, + ) { + return _spine_skeleton_update_world_transform( + skeleton, + ); + } + + late final _spine_skeleton_update_world_transformPtr = + _lookup>( + 'spine_skeleton_update_world_transform'); + late final _spine_skeleton_update_world_transform = + _spine_skeleton_update_world_transformPtr + .asFunction(); + + void spine_skeleton_update_world_transform_bone( + spine_skeleton skeleton, + ffi.Pointer parent, + ) { + return _spine_skeleton_update_world_transform_bone( + skeleton, + parent, + ); + } + + late final _spine_skeleton_update_world_transform_bonePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skeleton, ffi.Pointer)>>( + 'spine_skeleton_update_world_transform_bone'); + late final _spine_skeleton_update_world_transform_bone = + _spine_skeleton_update_world_transform_bonePtr + .asFunction)>(); + + void spine_skeleton_set_to_setup_pose( + spine_skeleton skeleton, + ) { + return _spine_skeleton_set_to_setup_pose( + skeleton, + ); + } + + late final _spine_skeleton_set_to_setup_posePtr = + _lookup>( + 'spine_skeleton_set_to_setup_pose'); + late final _spine_skeleton_set_to_setup_pose = + _spine_skeleton_set_to_setup_posePtr + .asFunction(); + + void spine_skeleton_set_bones_to_setup_pose( + spine_skeleton skeleton, + ) { + return _spine_skeleton_set_bones_to_setup_pose( + skeleton, + ); + } + + late final _spine_skeleton_set_bones_to_setup_posePtr = + _lookup>( + 'spine_skeleton_set_bones_to_setup_pose'); + late final _spine_skeleton_set_bones_to_setup_pose = + _spine_skeleton_set_bones_to_setup_posePtr + .asFunction(); + + void spine_skeleton_set_slots_to_setup_pose( + spine_skeleton skeleton, + ) { + return _spine_skeleton_set_slots_to_setup_pose( + skeleton, + ); + } + + late final _spine_skeleton_set_slots_to_setup_posePtr = + _lookup>( + 'spine_skeleton_set_slots_to_setup_pose'); + late final _spine_skeleton_set_slots_to_setup_pose = + _spine_skeleton_set_slots_to_setup_posePtr + .asFunction(); + + spine_bone spine_skeleton_find_bone( + spine_skeleton skeleton, + ffi.Pointer boneName, + ) { + return _spine_skeleton_find_bone( + skeleton, + boneName, + ); + } + + late final _spine_skeleton_find_bonePtr = _lookup< + ffi.NativeFunction< + spine_bone Function(spine_skeleton, + ffi.Pointer)>>('spine_skeleton_find_bone'); + late final _spine_skeleton_find_bone = _spine_skeleton_find_bonePtr + .asFunction)>(); + + spine_slot spine_skeleton_find_slot( + spine_skeleton skeleton, + ffi.Pointer slotName, + ) { + return _spine_skeleton_find_slot( + skeleton, + slotName, + ); + } + + late final _spine_skeleton_find_slotPtr = _lookup< + ffi.NativeFunction< + spine_slot Function(spine_skeleton, + ffi.Pointer)>>('spine_skeleton_find_slot'); + late final _spine_skeleton_find_slot = _spine_skeleton_find_slotPtr + .asFunction)>(); + + void spine_skeleton_set_skin_by_name( + spine_skeleton skeleton, + ffi.Pointer skinName, + ) { + return _spine_skeleton_set_skin_by_name( + skeleton, + skinName, + ); + } + + late final _spine_skeleton_set_skin_by_namePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skeleton, + ffi.Pointer)>>('spine_skeleton_set_skin_by_name'); + late final _spine_skeleton_set_skin_by_name = + _spine_skeleton_set_skin_by_namePtr + .asFunction)>(); + + void spine_skeleton_set_skin( + spine_skeleton skeleton, + spine_skin skin, + ) { + return _spine_skeleton_set_skin( + skeleton, + skin, + ); + } + + late final _spine_skeleton_set_skinPtr = _lookup< + ffi.NativeFunction>( + 'spine_skeleton_set_skin'); + late final _spine_skeleton_set_skin = _spine_skeleton_set_skinPtr + .asFunction(); + + spine_attachment spine_skeleton_get_attachment_by_name( + spine_skeleton skeleton, + ffi.Pointer slotName, + ffi.Pointer attachmentName, + ) { + return _spine_skeleton_get_attachment_by_name( + skeleton, + slotName, + attachmentName, + ); + } + + late final _spine_skeleton_get_attachment_by_namePtr = _lookup< + ffi.NativeFunction< + spine_attachment Function(spine_skeleton, ffi.Pointer, + ffi.Pointer)>>('spine_skeleton_get_attachment_by_name'); + late final _spine_skeleton_get_attachment_by_name = + _spine_skeleton_get_attachment_by_namePtr.asFunction< + spine_attachment Function( + spine_skeleton, ffi.Pointer, ffi.Pointer)>(); + + spine_attachment spine_skeleton_get_attachment( + spine_skeleton skeleton, + int slotIndex, + ffi.Pointer attachmentName, + ) { + return _spine_skeleton_get_attachment( + skeleton, + slotIndex, + attachmentName, + ); + } + + late final _spine_skeleton_get_attachmentPtr = _lookup< + ffi.NativeFunction< + spine_attachment Function(spine_skeleton, ffi.Int32, + ffi.Pointer)>>('spine_skeleton_get_attachment'); + late final _spine_skeleton_get_attachment = + _spine_skeleton_get_attachmentPtr.asFunction< + spine_attachment Function( + spine_skeleton, int, ffi.Pointer)>(); + + void spine_skeleton_set_attachment( + spine_skeleton skeleton, + ffi.Pointer slotName, + ffi.Pointer attachmentName, + ) { + return _spine_skeleton_set_attachment( + skeleton, + slotName, + attachmentName, + ); + } + + late final _spine_skeleton_set_attachmentPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skeleton, ffi.Pointer, + ffi.Pointer)>>('spine_skeleton_set_attachment'); + late final _spine_skeleton_set_attachment = + _spine_skeleton_set_attachmentPtr.asFunction< + void Function( + spine_skeleton, ffi.Pointer, ffi.Pointer)>(); + + spine_ik_constraint spine_skeleton_find_ik_constraint( + spine_skeleton skeleton, + ffi.Pointer constraintName, + ) { + return _spine_skeleton_find_ik_constraint( + skeleton, + constraintName, + ); + } + + late final _spine_skeleton_find_ik_constraintPtr = _lookup< + ffi.NativeFunction< + spine_ik_constraint Function(spine_skeleton, + ffi.Pointer)>>('spine_skeleton_find_ik_constraint'); + late final _spine_skeleton_find_ik_constraint = + _spine_skeleton_find_ik_constraintPtr.asFunction< + spine_ik_constraint Function( + spine_skeleton, ffi.Pointer)>(); + + spine_transform_constraint spine_skeleton_find_transform_constraint( + spine_skeleton skeleton, + ffi.Pointer constraintName, + ) { + return _spine_skeleton_find_transform_constraint( + skeleton, + constraintName, + ); + } + + late final _spine_skeleton_find_transform_constraintPtr = _lookup< + ffi.NativeFunction< + spine_transform_constraint Function( + spine_skeleton, ffi.Pointer)>>( + 'spine_skeleton_find_transform_constraint'); + late final _spine_skeleton_find_transform_constraint = + _spine_skeleton_find_transform_constraintPtr.asFunction< + spine_transform_constraint Function( + spine_skeleton, ffi.Pointer)>(); + + spine_path_constraint spine_skeleton_find_path_constraint( + spine_skeleton skeleton, + ffi.Pointer constraintName, + ) { + return _spine_skeleton_find_path_constraint( + skeleton, + constraintName, + ); + } + + late final _spine_skeleton_find_path_constraintPtr = _lookup< + ffi.NativeFunction< + spine_path_constraint Function(spine_skeleton, + ffi.Pointer)>>('spine_skeleton_find_path_constraint'); + late final _spine_skeleton_find_path_constraint = + _spine_skeleton_find_path_constraintPtr.asFunction< + spine_path_constraint Function( + spine_skeleton, ffi.Pointer)>(); + + spine_bounds spine_skeleton_get_bounds( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_bounds( + skeleton, + ); + } + + late final _spine_skeleton_get_boundsPtr = + _lookup>( + 'spine_skeleton_get_bounds'); + late final _spine_skeleton_get_bounds = _spine_skeleton_get_boundsPtr + .asFunction(); + + spine_bone spine_skeleton_get_root_bone( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_root_bone( + skeleton, + ); + } + + late final _spine_skeleton_get_root_bonePtr = + _lookup>( + 'spine_skeleton_get_root_bone'); + late final _spine_skeleton_get_root_bone = _spine_skeleton_get_root_bonePtr + .asFunction(); + + spine_skeleton_data spine_skeleton_get_data( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_data( + skeleton, + ); + } + + late final _spine_skeleton_get_dataPtr = + _lookup>( + 'spine_skeleton_get_data'); + late final _spine_skeleton_get_data = _spine_skeleton_get_dataPtr + .asFunction(); + + int spine_skeleton_get_num_bones( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_num_bones( + skeleton, + ); + } + + late final _spine_skeleton_get_num_bonesPtr = + _lookup>( + 'spine_skeleton_get_num_bones'); + late final _spine_skeleton_get_num_bones = _spine_skeleton_get_num_bonesPtr + .asFunction(); + + ffi.Pointer spine_skeleton_get_bones( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_bones( + skeleton, + ); + } + + late final _spine_skeleton_get_bonesPtr = _lookup< + ffi.NativeFunction Function(spine_skeleton)>>( + 'spine_skeleton_get_bones'); + late final _spine_skeleton_get_bones = _spine_skeleton_get_bonesPtr + .asFunction Function(spine_skeleton)>(); + + int spine_skeleton_get_num_slots( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_num_slots( + skeleton, + ); + } + + late final _spine_skeleton_get_num_slotsPtr = + _lookup>( + 'spine_skeleton_get_num_slots'); + late final _spine_skeleton_get_num_slots = _spine_skeleton_get_num_slotsPtr + .asFunction(); + + ffi.Pointer spine_skeleton_get_slots( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_slots( + skeleton, + ); + } + + late final _spine_skeleton_get_slotsPtr = _lookup< + ffi.NativeFunction Function(spine_skeleton)>>( + 'spine_skeleton_get_slots'); + late final _spine_skeleton_get_slots = _spine_skeleton_get_slotsPtr + .asFunction Function(spine_skeleton)>(); + + int spine_skeleton_get_num_draw_order( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_num_draw_order( + skeleton, + ); + } + + late final _spine_skeleton_get_num_draw_orderPtr = + _lookup>( + 'spine_skeleton_get_num_draw_order'); + late final _spine_skeleton_get_num_draw_order = + _spine_skeleton_get_num_draw_orderPtr + .asFunction(); + + ffi.Pointer spine_skeleton_get_draw_order( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_draw_order( + skeleton, + ); + } + + late final _spine_skeleton_get_draw_orderPtr = _lookup< + ffi.NativeFunction Function(spine_skeleton)>>( + 'spine_skeleton_get_draw_order'); + late final _spine_skeleton_get_draw_order = _spine_skeleton_get_draw_orderPtr + .asFunction Function(spine_skeleton)>(); + + int spine_skeleton_get_num_ik_constraints( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_num_ik_constraints( + skeleton, + ); + } + + late final _spine_skeleton_get_num_ik_constraintsPtr = + _lookup>( + 'spine_skeleton_get_num_ik_constraints'); + late final _spine_skeleton_get_num_ik_constraints = + _spine_skeleton_get_num_ik_constraintsPtr + .asFunction(); + + ffi.Pointer spine_skeleton_get_ik_constraints( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_ik_constraints( + skeleton, + ); + } + + late final _spine_skeleton_get_ik_constraintsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton)>>('spine_skeleton_get_ik_constraints'); + late final _spine_skeleton_get_ik_constraints = + _spine_skeleton_get_ik_constraintsPtr.asFunction< + ffi.Pointer Function(spine_skeleton)>(); + + int spine_skeleton_get_num_transform_constraints( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_num_transform_constraints( + skeleton, + ); + } + + late final _spine_skeleton_get_num_transform_constraintsPtr = + _lookup>( + 'spine_skeleton_get_num_transform_constraints'); + late final _spine_skeleton_get_num_transform_constraints = + _spine_skeleton_get_num_transform_constraintsPtr + .asFunction(); + + ffi.Pointer + spine_skeleton_get_transform_constraints( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_transform_constraints( + skeleton, + ); + } + + late final _spine_skeleton_get_transform_constraintsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton)>>('spine_skeleton_get_transform_constraints'); + late final _spine_skeleton_get_transform_constraints = + _spine_skeleton_get_transform_constraintsPtr.asFunction< + ffi.Pointer Function(spine_skeleton)>(); + + int spine_skeleton_get_num_path_constraints( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_num_path_constraints( + skeleton, + ); + } + + late final _spine_skeleton_get_num_path_constraintsPtr = + _lookup>( + 'spine_skeleton_get_num_path_constraints'); + late final _spine_skeleton_get_num_path_constraints = + _spine_skeleton_get_num_path_constraintsPtr + .asFunction(); + + ffi.Pointer spine_skeleton_get_path_constraints( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_path_constraints( + skeleton, + ); + } + + late final _spine_skeleton_get_path_constraintsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton)>>('spine_skeleton_get_path_constraints'); + late final _spine_skeleton_get_path_constraints = + _spine_skeleton_get_path_constraintsPtr.asFunction< + ffi.Pointer Function(spine_skeleton)>(); + + spine_skin spine_skeleton_get_skin( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_skin( + skeleton, + ); + } + + late final _spine_skeleton_get_skinPtr = + _lookup>( + 'spine_skeleton_get_skin'); + late final _spine_skeleton_get_skin = _spine_skeleton_get_skinPtr + .asFunction(); + + spine_color spine_skeleton_get_color( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_color( + skeleton, + ); + } + + late final _spine_skeleton_get_colorPtr = + _lookup>( + 'spine_skeleton_get_color'); + late final _spine_skeleton_get_color = _spine_skeleton_get_colorPtr + .asFunction(); + + void spine_skeleton_set_color( + spine_skeleton skeleton, + double r, + double g, + double b, + double a, + ) { + return _spine_skeleton_set_color( + skeleton, + r, + g, + b, + a, + ); + } + + late final _spine_skeleton_set_colorPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skeleton, ffi.Float, ffi.Float, ffi.Float, + ffi.Float)>>('spine_skeleton_set_color'); + late final _spine_skeleton_set_color = + _spine_skeleton_set_colorPtr.asFunction< + void Function(spine_skeleton, double, double, double, double)>(); + + void spine_skeleton_set_position( + spine_skeleton skeleton, + double x, + double y, + ) { + return _spine_skeleton_set_position( + skeleton, + x, + y, + ); + } + + late final _spine_skeleton_set_positionPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skeleton, ffi.Float, + ffi.Float)>>('spine_skeleton_set_position'); + late final _spine_skeleton_set_position = _spine_skeleton_set_positionPtr + .asFunction(); + + double spine_skeleton_get_x( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_x( + skeleton, + ); + } + + late final _spine_skeleton_get_xPtr = + _lookup>( + 'spine_skeleton_get_x'); + late final _spine_skeleton_get_x = + _spine_skeleton_get_xPtr.asFunction(); + + void spine_skeleton_set_x( + spine_skeleton skeleton, + double x, + ) { + return _spine_skeleton_set_x( + skeleton, + x, + ); + } + + late final _spine_skeleton_set_xPtr = + _lookup>( + 'spine_skeleton_set_x'); + late final _spine_skeleton_set_x = _spine_skeleton_set_xPtr + .asFunction(); + + double spine_skeleton_get_y( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_y( + skeleton, + ); + } + + late final _spine_skeleton_get_yPtr = + _lookup>( + 'spine_skeleton_get_y'); + late final _spine_skeleton_get_y = + _spine_skeleton_get_yPtr.asFunction(); + + void spine_skeleton_set_y( + spine_skeleton skeleton, + double y, + ) { + return _spine_skeleton_set_y( + skeleton, + y, + ); + } + + late final _spine_skeleton_set_yPtr = + _lookup>( + 'spine_skeleton_set_y'); + late final _spine_skeleton_set_y = _spine_skeleton_set_yPtr + .asFunction(); + + double spine_skeleton_get_scale_x( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_scale_x( + skeleton, + ); + } + + late final _spine_skeleton_get_scale_xPtr = + _lookup>( + 'spine_skeleton_get_scale_x'); + late final _spine_skeleton_get_scale_x = _spine_skeleton_get_scale_xPtr + .asFunction(); + + void spine_skeleton_set_scale_x( + spine_skeleton skeleton, + double scaleX, + ) { + return _spine_skeleton_set_scale_x( + skeleton, + scaleX, + ); + } + + late final _spine_skeleton_set_scale_xPtr = + _lookup>( + 'spine_skeleton_set_scale_x'); + late final _spine_skeleton_set_scale_x = _spine_skeleton_set_scale_xPtr + .asFunction(); + + double spine_skeleton_get_scale_y( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_scale_y( + skeleton, + ); + } + + late final _spine_skeleton_get_scale_yPtr = + _lookup>( + 'spine_skeleton_get_scale_y'); + late final _spine_skeleton_get_scale_y = _spine_skeleton_get_scale_yPtr + .asFunction(); + + void spine_skeleton_set_scale_y( + spine_skeleton skeleton, + double scaleY, + ) { + return _spine_skeleton_set_scale_y( + skeleton, + scaleY, + ); + } + + late final _spine_skeleton_set_scale_yPtr = + _lookup>( + 'spine_skeleton_set_scale_y'); + late final _spine_skeleton_set_scale_y = _spine_skeleton_set_scale_yPtr + .asFunction(); } class spine_atlas extends ffi.Struct { @@ -1156,12 +1917,14 @@ class spine_atlas extends ffi.Struct { external ffi.Pointer error; } -class spine_skeleton_data extends ffi.Struct { - external ffi.Pointer skeletonData; +class spine_skeleton_data_result extends ffi.Struct { + external spine_skeleton_data skeletonData; external ffi.Pointer error; } +typedef spine_skeleton_data = ffi.Pointer; + abstract class spine_blend_mode { static const int SPINE_BLEND_MODE_NORMAL = 0; static const int SPINE_BLEND_MODE_ADDITIVE = 1; @@ -1176,6 +1939,15 @@ abstract class spine_mix_blend { static const int SPINE_MIX_BLEND_ADD = 3; } +abstract class spine_event_type { + static const int SPINE_EVENT_TYPE_START = 0; + static const int SPINE_EVENT_TYPE_INTERRUPT = 1; + static const int SPINE_EVENT_TYPE_END = 2; + static const int SPINE_EVENT_TYPE_COMPLETE = 3; + static const int SPINE_EVENT_TYPE_DISPOSE = 4; + static const int SPINE_EVENT_TYPE_EVENT = 5; +} + class spine_render_command extends ffi.Struct { external ffi.Pointer positions; @@ -1200,11 +1972,41 @@ class spine_render_command extends ffi.Struct { external ffi.Pointer next; } +class spine_bounds extends ffi.Struct { + @ffi.Float() + external double x; + + @ffi.Float() + external double y; + + @ffi.Float() + external double width; + + @ffi.Float() + external double height; +} + +class spine_color extends ffi.Struct { + @ffi.Float() + external double r; + + @ffi.Float() + external double g; + + @ffi.Float() + external double b; + + @ffi.Float() + external double a; +} + class spine_skeleton_drawable extends ffi.Struct { external spine_skeleton skeleton; external spine_animation_state animationState; + external spine_animation_state_events animationStateEvents; + external ffi.Pointer clipping; external ffi.Pointer renderCommand; @@ -1212,5 +2014,14 @@ class spine_skeleton_drawable extends ffi.Struct { typedef spine_skeleton = ffi.Pointer; typedef spine_animation_state = ffi.Pointer; +typedef spine_animation_state_events = ffi.Pointer; typedef spine_track_entry = ffi.Pointer; +typedef spine_event = ffi.Pointer; typedef spine_animation = ffi.Pointer; +typedef spine_bone = ffi.Pointer; +typedef spine_slot = ffi.Pointer; +typedef spine_skin = ffi.Pointer; +typedef spine_attachment = ffi.Pointer; +typedef spine_ik_constraint = ffi.Pointer; +typedef spine_transform_constraint = ffi.Pointer; +typedef spine_path_constraint = ffi.Pointer; diff --git a/spine-flutter/lib/spine_widget.dart b/spine-flutter/lib/spine_widget.dart index b38041672..93ad69096 100644 --- a/spine-flutter/lib/spine_widget.dart +++ b/spine-flutter/lib/spine_widget.dart @@ -19,6 +19,7 @@ class SpineWidgetController { SpineWidgetController([this.onInitialized]); void _initialize(Atlas atlas, SkeletonData data, SkeletonDrawable drawable) { + if (initialized) throw Exception("SpineWidgetController already initialized. A controller can only be used with one widget."); _atlas = atlas; _data = data; _drawable = drawable; diff --git a/spine-flutter/src/spine_flutter.cpp b/spine-flutter/src/spine_flutter.cpp index 8c0826d88..5d3357ee6 100644 --- a/spine-flutter/src/spine_flutter.cpp +++ b/spine-flutter/src/spine_flutter.cpp @@ -5,6 +5,21 @@ using namespace spine; +struct AnimationStateEvent { + EventType type; + TrackEntry *entry; + Event* event; + AnimationStateEvent( EventType type, TrackEntry *entry, Event* event): type(type), entry(entry), event(event) {}; +}; + +struct EventListener: public AnimationStateListenerObject { + Vector events; + + void callback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) { + events.add(AnimationStateEvent(type, entry, event)); + } +}; + spine::SpineExtension *spine::getDefaultExtension() { return new spine::DebugExtension(new spine::DefaultSpineExtension()); } @@ -46,14 +61,14 @@ FFI_PLUGIN_EXPORT void spine_atlas_dispose(spine_atlas *atlas) { SpineExtension::free(atlas, __FILE__, __LINE__); } -FFI_PLUGIN_EXPORT spine_skeleton_data *spine_skeleton_data_load_json(spine_atlas *atlas, const char *skeletonData) { +FFI_PLUGIN_EXPORT spine_skeleton_data_result *spine_skeleton_data_load_json(spine_atlas *atlas, const char *skeletonData) { Bone::setYDown(true); if (!atlas) return nullptr; if (!atlas->atlas) return nullptr; if (!skeletonData) return nullptr; SkeletonJson json((Atlas*)atlas->atlas); SkeletonData *data = json.readSkeletonData(skeletonData); - spine_skeleton_data *result = SpineExtension::calloc(1, __FILE__, __LINE__); + spine_skeleton_data_result *result = SpineExtension::calloc(1, __FILE__, __LINE__); result->skeletonData = data; if (!json.getError().isEmpty()) { result->error = strdup(json.getError().buffer()); @@ -61,7 +76,7 @@ FFI_PLUGIN_EXPORT spine_skeleton_data *spine_skeleton_data_load_json(spine_atlas return result; } -FFI_PLUGIN_EXPORT spine_skeleton_data* spine_skeleton_data_load_binary(spine_atlas *atlas, const unsigned char *skeletonData, int32_t length) { +FFI_PLUGIN_EXPORT spine_skeleton_data_result* spine_skeleton_data_load_binary(spine_atlas *atlas, const unsigned char *skeletonData, int32_t length) { Bone::setYDown(true); if (!atlas) return nullptr; if (!atlas->atlas) return nullptr; @@ -69,7 +84,7 @@ FFI_PLUGIN_EXPORT spine_skeleton_data* spine_skeleton_data_load_binary(spine_atl if (length <= 0) return nullptr; SkeletonBinary binary((Atlas*)atlas->atlas); SkeletonData *data = binary.readSkeletonData(skeletonData, length); - spine_skeleton_data *result = SpineExtension::calloc(1, __FILE__, __LINE__); + spine_skeleton_data_result *result = SpineExtension::calloc(1, __FILE__, __LINE__); result->skeletonData = data; if (!binary.getError().isEmpty()) { result->error = strdup(binary.getError().buffer()); @@ -77,7 +92,7 @@ FFI_PLUGIN_EXPORT spine_skeleton_data* spine_skeleton_data_load_binary(spine_atl return result; } -FFI_PLUGIN_EXPORT void spine_skeleton_data_dispose(spine_skeleton_data *skeletonData) { +FFI_PLUGIN_EXPORT void spine_skeleton_data_result_dispose(spine_skeleton_data_result *skeletonData) { if (!skeletonData) return; if (skeletonData->skeletonData) delete (SkeletonData*)skeletonData->skeletonData; if (skeletonData->error) free(skeletonData->error); @@ -109,8 +124,12 @@ void spine_render_command_dispose(spine_render_command *cmd) { FFI_PLUGIN_EXPORT spine_skeleton_drawable *spine_skeleton_drawable_create(spine_skeleton_data *skeletonData) { spine_skeleton_drawable *drawable = SpineExtension::calloc(1, __FILE__, __LINE__); - drawable->skeleton = new Skeleton((SkeletonData*)skeletonData->skeletonData); - drawable->animationState = new AnimationState(new AnimationStateData((SkeletonData*)skeletonData->skeletonData)); + drawable->skeleton = new Skeleton((SkeletonData*)skeletonData); + AnimationState *state = new AnimationState(new AnimationStateData((SkeletonData*)skeletonData)); + drawable->animationState = state; + EventListener *listener = new EventListener(); + drawable->animationStateEvents = listener; + state->setListener(listener); drawable->clipping = new SkeletonClipping(); return drawable; } @@ -123,6 +142,7 @@ FFI_PLUGIN_EXPORT void spine_skeleton_drawable_dispose(spine_skeleton_drawable * delete state->getData(); delete (AnimationState*)state; } + if (drawable->animationStateEvents) delete (Vector*)(drawable->animationStateEvents); if (drawable->clipping) delete (SkeletonClipping*)drawable->clipping; while (drawable->renderCommand) { spine_render_command *cmd = drawable->renderCommand; @@ -132,19 +152,6 @@ FFI_PLUGIN_EXPORT void spine_skeleton_drawable_dispose(spine_skeleton_drawable * SpineExtension::free(drawable, __FILE__, __LINE__); } -FFI_PLUGIN_EXPORT void spine_skeleton_drawable_update(spine_skeleton_drawable *drawable, float deltaTime) { - if (!drawable) return; - if (!drawable->skeleton) return; - if (!drawable->animationState) return; - if (!drawable->clipping) return; - - Skeleton *skeleton = (Skeleton*)drawable->skeleton; - AnimationState *animationState = (AnimationState*)drawable->animationState; - animationState->update(deltaTime); - animationState->apply(*skeleton); - skeleton->updateWorldTransform(); -} - FFI_PLUGIN_EXPORT spine_render_command *spine_skeleton_drawable_render(spine_skeleton_drawable *drawable) { if (!drawable) return nullptr; if (!drawable->skeleton) return nullptr; @@ -331,6 +338,40 @@ FFI_PLUGIN_EXPORT void spine_animation_state_set_time_scale(spine_animation_stat _state->setTimeScale(timeScale); } +FFI_PLUGIN_EXPORT int spine_animation_state_events_get_num_events(spine_animation_state_events events) { + if (events == nullptr) return 0; + EventListener *_events = (EventListener*)events; + return _events->events.size(); +} + +FFI_PLUGIN_EXPORT spine_event_type spine_animation_state_events_get_event_type(spine_animation_state_events events, int index) { + if (events == nullptr) return SPINE_EVENT_TYPE_DISPOSE; + if (index < 0) return SPINE_EVENT_TYPE_DISPOSE; + EventListener *_events = (EventListener*)events; + if (_events->events.size() >= index) return SPINE_EVENT_TYPE_DISPOSE; + 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, int index) { + if (events == nullptr) return nullptr; + EventListener *_events = (EventListener*)events; + if (_events->events.size() >= index) 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, int index) { + if (events == nullptr) return nullptr; + EventListener *_events = (EventListener*)events; + if (_events->events.size() >= index) return nullptr; + return (spine_track_entry)_events->events[index].entry; +} + +FFI_PLUGIN_EXPORT void spine_animation_state_events_reset(spine_animation_state_events events) { + if (events == nullptr) return; + EventListener *_events = (EventListener*)events; + _events->events.clear(); +} + FFI_PLUGIN_EXPORT int spine_track_entry_get_track_index(spine_track_entry entry) { if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; @@ -605,4 +646,271 @@ FFI_PLUGIN_EXPORT float spine_track_entry_get_track_complete(spine_track_entry e if (entry == nullptr) return 0; TrackEntry *_entry = (TrackEntry*)entry; return _entry->getTrackComplete(); +} + +FFI_PLUGIN_EXPORT 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) { + 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) { + if (skeleton == nullptr) return; + if (parent == nullptr) return; + Skeleton *_skeleton = (Skeleton*)skeleton; + Bone *_bone = (Bone*)parent; + _skeleton->updateWorldTransform(_bone); +} + +FFI_PLUGIN_EXPORT 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) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton*)skeleton; + _skeleton->setBonesToSetupPose(); +} + +FFI_PLUGIN_EXPORT 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 char* boneName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->findBone(boneName); +} + +FFI_PLUGIN_EXPORT spine_slot spine_skeleton_find_slot(spine_skeleton skeleton, const char* slotName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->findSlot(slotName); +} + +FFI_PLUGIN_EXPORT void spine_skeleton_set_skin_by_name(spine_skeleton skeleton, const char* skinName) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton*)skeleton; + _skeleton->setSkin(skinName); +} + +FFI_PLUGIN_EXPORT 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 char* slotName, const char* attachmentName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->getAttachment(slotName, attachmentName); +} + +FFI_PLUGIN_EXPORT spine_attachment spine_skeleton_get_attachment(spine_skeleton skeleton, int slotIndex, const char* attachmentName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->getAttachment(slotIndex, attachmentName); +} + +FFI_PLUGIN_EXPORT void spine_skeleton_set_attachment(spine_skeleton skeleton, const char* slotName, const char* attachmentName) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->setAttachment(slotName, attachmentName); +} + +FFI_PLUGIN_EXPORT spine_ik_constraint spine_skeleton_find_ik_constraint(spine_skeleton skeleton, const char* constraintName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->findIkConstraint(constraintName); +} + +FFI_PLUGIN_EXPORT spine_transform_constraint spine_skeleton_find_transform_constraint(spine_skeleton skeleton, const char* constraintName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->findTransformConstraint(constraintName); +} + +FFI_PLUGIN_EXPORT spine_path_constraint spine_skeleton_find_path_constraint(spine_skeleton skeleton, const char* constraintName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->findPathConstraint(constraintName); +} + +FFI_PLUGIN_EXPORT spine_bounds spine_skeleton_get_bounds(spine_skeleton skeleton) { + spine_bounds bounds = {0, 0, 0, 0}; + if (skeleton == nullptr) return bounds; + Skeleton *_skeleton = (Skeleton*)skeleton; + Vector vertices; + _skeleton->getBounds(bounds.x, bounds.y, bounds.width, bounds.height, vertices); + return bounds; +} + +FFI_PLUGIN_EXPORT spine_bone spine_skeleton_get_root_bone(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->getRootBone(); +} + +FFI_PLUGIN_EXPORT spine_skeleton_data spine_skeleton_get_data(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->getData(); +} + +FFI_PLUGIN_EXPORT int spine_skeleton_get_num_bones(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->getBones().size(); +} + +FFI_PLUGIN_EXPORT spine_bone* spine_skeleton_get_bones(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return (void**)_skeleton->getBones().buffer(); +} + +FFI_PLUGIN_EXPORT int spine_skeleton_get_num_slots(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->getSlots().size(); +} + +FFI_PLUGIN_EXPORT spine_slot* spine_skeleton_get_slots(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return (void**)_skeleton->getSlots().buffer(); +} + +FFI_PLUGIN_EXPORT int spine_skeleton_get_num_draw_order(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->getDrawOrder().size(); +} + +FFI_PLUGIN_EXPORT spine_slot* spine_skeleton_get_draw_order(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return (void**)_skeleton->getDrawOrder().buffer(); +} + +FFI_PLUGIN_EXPORT int spine_skeleton_get_num_ik_constraints(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->getIkConstraints().size(); +} + +FFI_PLUGIN_EXPORT spine_ik_constraint* spine_skeleton_get_ik_constraints(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return (void**)_skeleton->getIkConstraints().buffer(); +} + +FFI_PLUGIN_EXPORT int spine_skeleton_get_num_transform_constraints(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->getTransformConstraints().size(); +} + +FFI_PLUGIN_EXPORT spine_transform_constraint* spine_skeleton_get_transform_constraints(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return (void**)_skeleton->getTransformConstraints().buffer(); +} + +FFI_PLUGIN_EXPORT int spine_skeleton_get_num_path_constraints(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->getPathConstraints().size(); +} + +FFI_PLUGIN_EXPORT spine_path_constraint* spine_skeleton_get_path_constraints(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return (void**)_skeleton->getPathConstraints().buffer(); +} + +FFI_PLUGIN_EXPORT spine_skin spine_skeleton_get_skin(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton*)skeleton; + return _skeleton->getSkin(); +} + +FFI_PLUGIN_EXPORT spine_color spine_skeleton_get_color(spine_skeleton skeleton) { + spine_color color = {0, 0, 0, 0}; + if (skeleton == nullptr) return color; + Skeleton *_skeleton = (Skeleton*)skeleton; + Color &c = _skeleton->getColor(); + color = { c.r, c.g, c.b, c.a }; + return color; +} + +FFI_PLUGIN_EXPORT 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) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton*)skeleton; + _skeleton->setPosition(x, y); +} + +FFI_PLUGIN_EXPORT 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) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton*)skeleton; + _skeleton->setX(x); +} + +FFI_PLUGIN_EXPORT 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) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton*)skeleton; + _skeleton->setY(y); +} + +FFI_PLUGIN_EXPORT 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) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton*)skeleton; + _skeleton->setScaleX(scaleX); +} + +FFI_PLUGIN_EXPORT 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) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton*)skeleton; + _skeleton->setScaleY(scaleY); } \ No newline at end of file diff --git a/spine-flutter/src/spine_flutter.h b/spine-flutter/src/spine_flutter.h index 4cdd65527..866ef9a2b 100644 --- a/spine-flutter/src/spine_flutter.h +++ b/spine-flutter/src/spine_flutter.h @@ -23,9 +23,20 @@ #endif #endif -FFI_PLUGIN_EXPORT int32_t spine_major_version(); -FFI_PLUGIN_EXPORT int32_t spine_minor_version(); -FFI_PLUGIN_EXPORT void spine_report_leaks(); +typedef void* spine_skeleton; +typedef void* spine_skeleton_data; +typedef void* spine_bone; +typedef void* spine_slot; +typedef void* spine_skin; +typedef void* spine_attachment; +typedef void* spine_ik_constraint; +typedef void* spine_transform_constraint; +typedef void* spine_path_constraint; +typedef void* spine_animation_state; +typedef void* spine_animation_state_events; +typedef void* spine_event; +typedef void* spine_track_entry; +typedef void* spine_animation; typedef struct spine_atlas { void *atlas; @@ -34,17 +45,10 @@ typedef struct spine_atlas { char *error; } spine_atlas; -FFI_PLUGIN_EXPORT spine_atlas* spine_atlas_load(const char *atlasData); -FFI_PLUGIN_EXPORT void spine_atlas_dispose(spine_atlas *atlas); - -typedef struct spine_skeleton_data { - void *skeletonData; +typedef struct spine_skeleton_data_result { + spine_skeleton_data skeletonData; char *error; -} spine_skeleton_data; - -FFI_PLUGIN_EXPORT spine_skeleton_data* spine_skeleton_data_load_json(spine_atlas *atlas, const char *skeletonData); -FFI_PLUGIN_EXPORT spine_skeleton_data* spine_skeleton_data_load_binary(spine_atlas *atlas, const unsigned char *skeletonData, int32_t length); -FFI_PLUGIN_EXPORT void spine_skeleton_data_dispose(spine_skeleton_data *skeletonData); +} spine_skeleton_data_result; typedef enum spine_blend_mode { SPINE_BLEND_MODE_NORMAL = 0, @@ -60,6 +64,15 @@ typedef enum spine_mix_blend { SPINE_MIX_BLEND_ADD } spine_mix_blend; +typedef enum spine_event_type { + SPINE_EVENT_TYPE_START = 0, + SPINE_EVENT_TYPE_INTERRUPT, + SPINE_EVENT_TYPE_END, + SPINE_EVENT_TYPE_COMPLETE, + SPINE_EVENT_TYPE_DISPOSE, + SPINE_EVENT_TYPE_EVENT +} spine_event_type; + typedef struct spine_render_command { float *positions; float *uvs; @@ -72,20 +85,34 @@ typedef struct spine_render_command { struct spine_render_command *next; } spine_render_command; -typedef void* spine_skeleton; -typedef void* spine_animation_state; -typedef void* spine_track_entry; -typedef void* spine_animation; +typedef struct spine_bounds { + float x, y, width, height; +} spine_bounds; + +typedef struct spine_color { + float r, g, b, a; +} spine_color; typedef struct spine_skeleton_drawable { spine_skeleton skeleton; spine_animation_state animationState; + spine_animation_state_events animationStateEvents; void *clipping; spine_render_command *renderCommand; } spine_skeleton_drawable; +FFI_PLUGIN_EXPORT int32_t spine_major_version(); +FFI_PLUGIN_EXPORT int32_t spine_minor_version(); +FFI_PLUGIN_EXPORT void spine_report_leaks(); + +FFI_PLUGIN_EXPORT spine_atlas* spine_atlas_load(const char *atlasData); +FFI_PLUGIN_EXPORT void spine_atlas_dispose(spine_atlas *atlas); + +FFI_PLUGIN_EXPORT spine_skeleton_data_result* spine_skeleton_data_load_json(spine_atlas *atlas, const char *skeletonData); +FFI_PLUGIN_EXPORT spine_skeleton_data_result* spine_skeleton_data_load_binary(spine_atlas *atlas, const unsigned char *skeletonData, int32_t length); +FFI_PLUGIN_EXPORT void spine_skeleton_data_result_dispose(spine_skeleton_data_result *skeletonData); + FFI_PLUGIN_EXPORT spine_skeleton_drawable *spine_skeleton_drawable_create(spine_skeleton_data *skeletonData); -FFI_PLUGIN_EXPORT void spine_skeleton_drawable_update(spine_skeleton_drawable *drawable, float deltaTime); FFI_PLUGIN_EXPORT spine_render_command *spine_skeleton_drawable_render(spine_skeleton_drawable *drawable); FFI_PLUGIN_EXPORT void spine_skeleton_drawable_dispose(spine_skeleton_drawable *drawable); @@ -101,6 +128,12 @@ FFI_PLUGIN_EXPORT void spine_animation_state_set_empty_animations(spine_animatio FFI_PLUGIN_EXPORT float spine_animation_state_get_time_scale(spine_animation_state state); FFI_PLUGIN_EXPORT void spine_animation_state_set_time_scale(spine_animation_state state, float timeScale); +FFI_PLUGIN_EXPORT int spine_animation_state_events_get_num_events(spine_animation_state_events events); +FFI_PLUGIN_EXPORT spine_event_type spine_animation_state_events_get_event_type(spine_animation_state_events events, int index); +FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_events_get_track_entry(spine_animation_state_events events, int index); +FFI_PLUGIN_EXPORT spine_event spine_animation_state_events_get_event(spine_animation_state_events events, int index); +FFI_PLUGIN_EXPORT void spine_animation_state_events_reset(spine_animation_state_events events); + FFI_PLUGIN_EXPORT int spine_track_entry_get_track_index(spine_track_entry entry); FFI_PLUGIN_EXPORT spine_animation spine_track_entry_get_animation(spine_track_entry entry); FFI_PLUGIN_EXPORT spine_track_entry spine_track_entry_get_previous(spine_track_entry entry); @@ -147,3 +180,47 @@ FFI_PLUGIN_EXPORT spine_track_entry spine_track_entry_get_mixing_from(spine_trac FFI_PLUGIN_EXPORT spine_track_entry spine_track_entry_get_mixing_to(spine_track_entry entry); FFI_PLUGIN_EXPORT void spine_track_entry_reset_rotation_directions(spine_track_entry entry); FFI_PLUGIN_EXPORT float spine_track_entry_get_track_complete(spine_track_entry entry); + +FFI_PLUGIN_EXPORT void spine_skeleton_update_cache(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT void spine_skeleton_update_world_transform(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT void spine_skeleton_update_world_transform_bone(spine_skeleton skeleton, spine_bone *parent); +FFI_PLUGIN_EXPORT void spine_skeleton_set_to_setup_pose(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT void spine_skeleton_set_bones_to_setup_pose(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT void spine_skeleton_set_slots_to_setup_pose(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT spine_bone spine_skeleton_find_bone(spine_skeleton skeleton, const char* boneName); +FFI_PLUGIN_EXPORT spine_slot spine_skeleton_find_slot(spine_skeleton skeleton, const char* slotName); +FFI_PLUGIN_EXPORT void spine_skeleton_set_skin_by_name(spine_skeleton skeleton, const char* skinName); +FFI_PLUGIN_EXPORT void spine_skeleton_set_skin(spine_skeleton skeleton, spine_skin skin); +FFI_PLUGIN_EXPORT spine_attachment spine_skeleton_get_attachment_by_name(spine_skeleton skeleton, const char* slotName, const char* attachmentName); +FFI_PLUGIN_EXPORT spine_attachment spine_skeleton_get_attachment(spine_skeleton skeleton, int slotIndex, const char* attachmentName); +FFI_PLUGIN_EXPORT void spine_skeleton_set_attachment(spine_skeleton skeleton, const char* slotName, const char* attachmentName); +FFI_PLUGIN_EXPORT spine_ik_constraint spine_skeleton_find_ik_constraint(spine_skeleton skeleton, const char* constraintName); +FFI_PLUGIN_EXPORT spine_transform_constraint spine_skeleton_find_transform_constraint(spine_skeleton skeleton, const char* constraintName); +FFI_PLUGIN_EXPORT spine_path_constraint spine_skeleton_find_path_constraint(spine_skeleton skeleton, const char* constraintName); +FFI_PLUGIN_EXPORT spine_bounds spine_skeleton_get_bounds(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT spine_bone spine_skeleton_get_root_bone(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT spine_skeleton_data spine_skeleton_get_data(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT int spine_skeleton_get_num_bones(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT spine_bone* spine_skeleton_get_bones(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT int spine_skeleton_get_num_slots(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT spine_slot* spine_skeleton_get_slots(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT int spine_skeleton_get_num_draw_order(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT spine_slot* spine_skeleton_get_draw_order(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT int spine_skeleton_get_num_ik_constraints(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT spine_ik_constraint* spine_skeleton_get_ik_constraints(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT int spine_skeleton_get_num_transform_constraints(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT spine_transform_constraint* spine_skeleton_get_transform_constraints(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT int spine_skeleton_get_num_path_constraints(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT spine_path_constraint* spine_skeleton_get_path_constraints(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT spine_skin spine_skeleton_get_skin(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT spine_color spine_skeleton_get_color(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT void spine_skeleton_set_color(spine_skeleton skeleton, float r, float g, float b, float a); +FFI_PLUGIN_EXPORT void spine_skeleton_set_position(spine_skeleton skeleton, float x, float y); +FFI_PLUGIN_EXPORT float spine_skeleton_get_x(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT void spine_skeleton_set_x(spine_skeleton skeleton, float x); +FFI_PLUGIN_EXPORT float spine_skeleton_get_y(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT void spine_skeleton_set_y(spine_skeleton skeleton, float y); +FFI_PLUGIN_EXPORT float spine_skeleton_get_scale_x(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT void spine_skeleton_set_scale_x(spine_skeleton skeleton, float scaleX); +FFI_PLUGIN_EXPORT float spine_skeleton_get_scale_y(spine_skeleton skeleton); +FFI_PLUGIN_EXPORT void spine_skeleton_set_scale_y(spine_skeleton skeleton, float scaleY); \ No newline at end of file