mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 09:46:02 +08:00
[flutter] Scaffolding for animation state listener processing.
This commit is contained in:
parent
916193e57e
commit
cde9519a00
@ -47,6 +47,7 @@ class SimpleAnimation extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
reportLeaks();
|
||||||
final controller = SpineWidgetController((controller) => controller.animationState?.setAnimation(0, "walk", true));
|
final controller = SpineWidgetController((controller) => controller.animationState?.setAnimation(0, "walk", true));
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
|||||||
@ -444,8 +444,9 @@ enum MixBlend {
|
|||||||
|
|
||||||
class TrackEntry {
|
class TrackEntry {
|
||||||
final spine_track_entry _entry;
|
final spine_track_entry _entry;
|
||||||
|
final AnimationState _state;
|
||||||
|
|
||||||
TrackEntry(this._entry);
|
TrackEntry(this._entry, this._state);
|
||||||
|
|
||||||
/// The index of the track where this entry is either current or queued.
|
/// The index of the track where this entry is either current or queued.
|
||||||
int getTtrackIndex() {
|
int getTtrackIndex() {
|
||||||
@ -635,7 +636,7 @@ class TrackEntry {
|
|||||||
TrackEntry? getNext() {
|
TrackEntry? getNext() {
|
||||||
final next = _bindings.spine_track_entry_get_next(_entry);
|
final next = _bindings.spine_track_entry_get_next(_entry);
|
||||||
if (next.address == nullptr.address) return null;
|
if (next.address == nullptr.address) return null;
|
||||||
return TrackEntry(next);
|
return TrackEntry(next, this._state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if at least one loop has been completed.
|
/// Returns true if at least one loop has been completed.
|
||||||
@ -682,7 +683,7 @@ class TrackEntry {
|
|||||||
TrackEntry? getMixingFrom() {
|
TrackEntry? getMixingFrom() {
|
||||||
final from = _bindings.spine_track_entry_get_mixing_from(_entry);
|
final from = _bindings.spine_track_entry_get_mixing_from(_entry);
|
||||||
if (from.address == nullptr.address) return null;
|
if (from.address == nullptr.address) return null;
|
||||||
return TrackEntry(from);
|
return TrackEntry(from, this._state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The track entry for the next animation when mixing from this animation, or NULL if no mixing is currently occuring.
|
/// The track entry for the next animation when mixing from this animation, or NULL if no mixing is currently occuring.
|
||||||
@ -690,7 +691,7 @@ class TrackEntry {
|
|||||||
TrackEntry? getMixingTo() {
|
TrackEntry? getMixingTo() {
|
||||||
final to = _bindings.spine_track_entry_get_mixing_to(_entry);
|
final to = _bindings.spine_track_entry_get_mixing_to(_entry);
|
||||||
if (to.address == nullptr.address) return null;
|
if (to.address == nullptr.address) return null;
|
||||||
return TrackEntry(to);
|
return TrackEntry(to, this._state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the
|
/// Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the
|
||||||
@ -711,15 +712,20 @@ class TrackEntry {
|
|||||||
|
|
||||||
class AnimationState {
|
class AnimationState {
|
||||||
final spine_animation_state _state;
|
final spine_animation_state _state;
|
||||||
|
final spine_animation_state_events _events;
|
||||||
|
|
||||||
AnimationState(this._state);
|
AnimationState(this._state, this._events);
|
||||||
|
|
||||||
// FIXME add listener methods, get current
|
// FIXME add listener methods
|
||||||
|
|
||||||
/// Increments the track entry times, setting queued animations as current if needed
|
/// Increments the track entry times, setting queued animations as current if needed
|
||||||
/// @param delta delta time
|
/// @param delta delta time
|
||||||
void update(double delta) {
|
void update(double delta) {
|
||||||
_bindings.spine_animation_state_update(_state, delta);
|
_bindings.spine_animation_state_update(_state, delta);
|
||||||
|
|
||||||
|
final numEvents = _bindings.spine_animation_state_events_get_num_events(_events);
|
||||||
|
print("events: $numEvents");
|
||||||
|
_bindings.spine_animation_state_events_reset(_events);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the
|
/// Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the
|
||||||
@ -754,7 +760,7 @@ class AnimationState {
|
|||||||
final entry = _bindings.spine_animation_state_set_animation(_state, trackIndex, animation.cast(), loop ? -1 : 0);
|
final entry = _bindings.spine_animation_state_set_animation(_state, trackIndex, animation.cast(), loop ? -1 : 0);
|
||||||
calloc.free(animation);
|
calloc.free(animation);
|
||||||
if (entry.address == nullptr.address) throw Exception("Couldn't set animation $animationName");
|
if (entry.address == nullptr.address) throw Exception("Couldn't set animation $animationName");
|
||||||
return TrackEntry(entry);
|
return TrackEntry(entry, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds an animation to be played delay seconds after the current or last queued animation
|
/// Adds an animation to be played delay seconds after the current or last queued animation
|
||||||
@ -770,13 +776,13 @@ class AnimationState {
|
|||||||
final entry = _bindings.spine_animation_state_add_animation(_state, trackIndex, animation.cast(), loop ? -1 : 0, delay);
|
final entry = _bindings.spine_animation_state_add_animation(_state, trackIndex, animation.cast(), loop ? -1 : 0, delay);
|
||||||
calloc.free(animation);
|
calloc.free(animation);
|
||||||
if (entry.address == nullptr.address) throw Exception("Couldn't add animation $animationName");
|
if (entry.address == nullptr.address) throw Exception("Couldn't add animation $animationName");
|
||||||
return TrackEntry(entry);
|
return TrackEntry(entry, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets an empty animation for a track, discarding any queued animations, and mixes to it over the specified mix duration.
|
/// Sets an empty animation for a track, discarding any queued animations, and mixes to it over the specified mix duration.
|
||||||
TrackEntry setEmptyAnimation(int trackIndex, double mixDuration) {
|
TrackEntry setEmptyAnimation(int trackIndex, double mixDuration) {
|
||||||
final entry = _bindings.spine_animation_state_set_empty_animation(_state, trackIndex, mixDuration);
|
final entry = _bindings.spine_animation_state_set_empty_animation(_state, trackIndex, mixDuration);
|
||||||
return TrackEntry(entry);
|
return TrackEntry(entry, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds an empty animation to be played after the current or last queued animation for a track, and mixes to it over the
|
/// Adds an empty animation to be played after the current or last queued animation for a track, and mixes to it over the
|
||||||
@ -790,7 +796,13 @@ class AnimationState {
|
|||||||
/// duration of the previous track minus any mix duration plus the negative delay.
|
/// duration of the previous track minus any mix duration plus the negative delay.
|
||||||
TrackEntry addEmptyAnimation(int trackIndex, double mixDuration, double delay) {
|
TrackEntry addEmptyAnimation(int trackIndex, double mixDuration, double delay) {
|
||||||
final entry = _bindings.spine_animation_state_add_empty_animation(_state, trackIndex, mixDuration, delay);
|
final entry = _bindings.spine_animation_state_add_empty_animation(_state, trackIndex, mixDuration, delay);
|
||||||
return TrackEntry(entry);
|
return TrackEntry(entry, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackEntry? getCurrent(int trackIndex) {
|
||||||
|
final entry = _bindings.spine_animation_state_get_current(_state, trackIndex);
|
||||||
|
if (entry.address == nullptr.address) return null;
|
||||||
|
return TrackEntry(entry, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix duration.
|
/// Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix duration.
|
||||||
@ -813,20 +825,20 @@ class SkeletonDrawable {
|
|||||||
late final Pointer<spine_skeleton_drawable> _drawable;
|
late final Pointer<spine_skeleton_drawable> _drawable;
|
||||||
late final Skeleton skeleton;
|
late final Skeleton skeleton;
|
||||||
late final AnimationState animationState;
|
late final AnimationState animationState;
|
||||||
final bool _ownsData;
|
final bool _ownsAtlasAndSkeletonData;
|
||||||
bool _disposed;
|
bool _disposed;
|
||||||
|
|
||||||
SkeletonDrawable(this.atlas, this.skeletonData, this._ownsData): _disposed = false {
|
SkeletonDrawable(this.atlas, this.skeletonData, this._ownsAtlasAndSkeletonData): _disposed = false {
|
||||||
_drawable = _bindings.spine_skeleton_drawable_create(skeletonData._skeletonData);
|
_drawable = _bindings.spine_skeleton_drawable_create(skeletonData._skeletonData);
|
||||||
skeleton = Skeleton(_drawable.ref.skeleton);
|
skeleton = Skeleton(_drawable.ref.skeleton);
|
||||||
animationState = AnimationState(_drawable.ref.animationState);
|
animationState = AnimationState(_drawable.ref.animationState, _drawable.ref.animationStateEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(double delta) {
|
void update(double delta) {
|
||||||
if (_disposed) return;
|
if (_disposed) return;
|
||||||
_bindings.spine_animation_state_update(_drawable.ref.animationState, delta);
|
animationState.update(delta);
|
||||||
_bindings.spine_animation_state_apply(_drawable.ref.animationState, _drawable.ref.skeleton);
|
animationState.apply(skeleton);
|
||||||
_bindings.spine_skeleton_update_world_transform(_drawable.ref.skeleton);
|
skeleton.updateWorldTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<RenderCommand> render() {
|
List<RenderCommand> render() {
|
||||||
@ -844,7 +856,7 @@ class SkeletonDrawable {
|
|||||||
void dispose() {
|
void dispose() {
|
||||||
if (_disposed) return;
|
if (_disposed) return;
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
if (_ownsData) {
|
if (_ownsAtlasAndSkeletonData) {
|
||||||
atlas.dispose();
|
atlas.dispose();
|
||||||
skeletonData.dispose();
|
skeletonData.dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -374,6 +374,24 @@ class SpineFlutterBindings {
|
|||||||
_spine_animation_state_set_empty_animationsPtr
|
_spine_animation_state_set_empty_animationsPtr
|
||||||
.asFunction<void Function(spine_animation_state, double)>();
|
.asFunction<void Function(spine_animation_state, double)>();
|
||||||
|
|
||||||
|
spine_track_entry spine_animation_state_get_current(
|
||||||
|
spine_animation_state state,
|
||||||
|
int trackIndex,
|
||||||
|
) {
|
||||||
|
return _spine_animation_state_get_current(
|
||||||
|
state,
|
||||||
|
trackIndex,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _spine_animation_state_get_currentPtr = _lookup<
|
||||||
|
ffi.NativeFunction<
|
||||||
|
spine_track_entry Function(spine_animation_state,
|
||||||
|
ffi.Int32)>>('spine_animation_state_get_current');
|
||||||
|
late final _spine_animation_state_get_current =
|
||||||
|
_spine_animation_state_get_currentPtr
|
||||||
|
.asFunction<spine_track_entry Function(spine_animation_state, int)>();
|
||||||
|
|
||||||
double spine_animation_state_get_time_scale(
|
double spine_animation_state_get_time_scale(
|
||||||
spine_animation_state state,
|
spine_animation_state state,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@ -324,6 +324,12 @@ FFI_PLUGIN_EXPORT void spine_animation_state_set_empty_animations(spine_animatio
|
|||||||
_state->setEmptyAnimations(mixDuration);
|
_state->setEmptyAnimations(mixDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_get_current(spine_animation_state state, int trackIndex) {
|
||||||
|
if (state == nullptr) return nullptr;
|
||||||
|
AnimationState *_state = (AnimationState*)state;
|
||||||
|
return _state->getCurrent(trackIndex);
|
||||||
|
}
|
||||||
|
|
||||||
FFI_PLUGIN_EXPORT float spine_animation_state_get_time_scale(spine_animation_state state) {
|
FFI_PLUGIN_EXPORT float spine_animation_state_get_time_scale(spine_animation_state state) {
|
||||||
if (state == nullptr) return 0;
|
if (state == nullptr) return 0;
|
||||||
AnimationState *_state = (AnimationState*)state;
|
AnimationState *_state = (AnimationState*)state;
|
||||||
|
|||||||
@ -131,6 +131,7 @@ FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_add_animation(spine_an
|
|||||||
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_set_empty_animation(spine_animation_state state, int trackIndex, float mixDuration);
|
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_set_empty_animation(spine_animation_state state, int trackIndex, float mixDuration);
|
||||||
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_add_empty_animation(spine_animation_state state, int trackIndex, float mixDuration, float delay);
|
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_add_empty_animation(spine_animation_state state, int trackIndex, float mixDuration, float delay);
|
||||||
FFI_PLUGIN_EXPORT void spine_animation_state_set_empty_animations(spine_animation_state state, float mixDuration);
|
FFI_PLUGIN_EXPORT void spine_animation_state_set_empty_animations(spine_animation_state state, float mixDuration);
|
||||||
|
FFI_PLUGIN_EXPORT spine_track_entry spine_animation_state_get_current(spine_animation_state state, int trackIndex);
|
||||||
FFI_PLUGIN_EXPORT float spine_animation_state_get_time_scale(spine_animation_state state);
|
FFI_PLUGIN_EXPORT float spine_animation_state_get_time_scale(spine_animation_state state);
|
||||||
FFI_PLUGIN_EXPORT void spine_animation_state_set_time_scale(spine_animation_state state, float timeScale);
|
FFI_PLUGIN_EXPORT void spine_animation_state_set_time_scale(spine_animation_state state, float timeScale);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user