mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-15 11:31:37 +08:00
[cpp][flutter] Add setter to AnimationState for manual track entry disposal, add support for track entry and state listeners on dart side.
This commit is contained in:
parent
cde9519a00
commit
61560c9477
@ -45,7 +45,7 @@
|
||||
|
||||
namespace spine {
|
||||
enum EventType {
|
||||
EventType_Start,
|
||||
EventType_Start = 0,
|
||||
EventType_Interrupt,
|
||||
EventType_End,
|
||||
EventType_Complete,
|
||||
@ -429,6 +429,12 @@ namespace spine {
|
||||
|
||||
void enableQueue();
|
||||
|
||||
void setManualTrackEntryDisposal(bool inValue);
|
||||
|
||||
bool getManualTrackEntryDisposal();
|
||||
|
||||
void disposeTrackEntry(TrackEntry *entry);
|
||||
|
||||
private:
|
||||
static const int Subsequent = 0;
|
||||
static const int First = 1;
|
||||
@ -456,6 +462,8 @@ namespace spine {
|
||||
|
||||
float _timeScale;
|
||||
|
||||
bool _manualTrackEntryDisposal;
|
||||
|
||||
static Animation *getEmptyAnimation();
|
||||
|
||||
static void
|
||||
|
||||
@ -295,8 +295,7 @@ void EventQueue::drain() {
|
||||
else
|
||||
state._listenerObject->callback(&state, EventType_Dispose, trackEntry, NULL);
|
||||
|
||||
trackEntry->reset();
|
||||
_trackEntryPool.free(trackEntry);
|
||||
if (!_state.getManualTrackEntryDisposal()) _state.disposeTrackEntry(trackEntry);
|
||||
break;
|
||||
case EventType_Event:
|
||||
if (!trackEntry->_listenerObject)
|
||||
@ -320,7 +319,8 @@ AnimationState::AnimationState(AnimationStateData *data) : _data(data),
|
||||
_listener(dummyOnAnimationEventFunc),
|
||||
_listenerObject(NULL),
|
||||
_unkeyedState(0),
|
||||
_timeScale(1) {
|
||||
_timeScale(1),
|
||||
_manualTrackEntryDisposal(false) {
|
||||
}
|
||||
|
||||
AnimationState::~AnimationState() {
|
||||
@ -666,6 +666,19 @@ void AnimationState::enableQueue() {
|
||||
_queue->_drainDisabled = false;
|
||||
}
|
||||
|
||||
void AnimationState::setManualTrackEntryDisposal(bool inValue) {
|
||||
_manualTrackEntryDisposal = inValue;
|
||||
}
|
||||
|
||||
bool AnimationState::getManualTrackEntryDisposal() {
|
||||
return _manualTrackEntryDisposal;
|
||||
}
|
||||
|
||||
void AnimationState::disposeTrackEntry(TrackEntry *entry) {
|
||||
entry->reset();
|
||||
_trackEntryPool.free(entry);
|
||||
}
|
||||
|
||||
Animation *AnimationState::getEmptyAnimation() {
|
||||
static Vector<Timeline *> timelines;
|
||||
static Animation ret(String("<empty>"), timelines, 0);
|
||||
|
||||
@ -64,6 +64,7 @@ class AnimationStateEvents extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
reportLeaks();
|
||||
final controller = SpineWidgetController((controller) {
|
||||
for (final bone in controller.skeleton!.getBones()) {
|
||||
print(bone);
|
||||
@ -71,7 +72,12 @@ class AnimationStateEvents extends StatelessWidget {
|
||||
controller.skeleton?.setScaleX(0.5);
|
||||
controller.skeleton?.setScaleY(0.5);
|
||||
controller.skeleton?.setColor(Color(1, 1, 0, 1));
|
||||
final trackEntry = controller.animationState?.setAnimation(0, "walk", true);
|
||||
controller.animationState?.setAnimation(0, "walk", true)?.setListener((event) {
|
||||
print("Walk animation event ${event.type}");
|
||||
});
|
||||
controller.animationState?.addAnimation(0, "run", true, 2)?.setListener((event) {
|
||||
print("Run animation event ${event.type}");
|
||||
});
|
||||
});
|
||||
|
||||
return Scaffold(
|
||||
|
||||
@ -708,15 +708,48 @@ class TrackEntry {
|
||||
double getTrackComplete() {
|
||||
return _bindings.spine_track_entry_get_track_complete(_entry);
|
||||
}
|
||||
|
||||
void setListener(AnimationStateListener listener) {
|
||||
_state._setTrackEntryListener(_entry, listener);
|
||||
}
|
||||
}
|
||||
|
||||
enum EventType {
|
||||
Start,
|
||||
Interrupt,
|
||||
End,
|
||||
Complete,
|
||||
Dispose,
|
||||
Event
|
||||
}
|
||||
|
||||
class Event {
|
||||
final spine_event _event;
|
||||
|
||||
Event(this._event);
|
||||
}
|
||||
|
||||
class AnimationStateEvent {
|
||||
final EventType type;
|
||||
final TrackEntry entry;
|
||||
final Event? event;
|
||||
|
||||
AnimationStateEvent(this.type, this.entry, this.event);
|
||||
}
|
||||
|
||||
typedef AnimationStateListener = void Function(AnimationStateEvent event);
|
||||
|
||||
class AnimationState {
|
||||
final spine_animation_state _state;
|
||||
final spine_animation_state_events _events;
|
||||
final Map<spine_track_entry, AnimationStateListener> _trackEntryListeners;
|
||||
AnimationStateListener? _stateListener;
|
||||
|
||||
AnimationState(this._state, this._events);
|
||||
AnimationState(this._state, this._events): _trackEntryListeners = {};
|
||||
|
||||
// FIXME add listener methods
|
||||
void _setTrackEntryListener(spine_track_entry entry, AnimationStateListener listener) {
|
||||
_trackEntryListeners[entry] = listener;
|
||||
}
|
||||
|
||||
/// Increments the track entry times, setting queued animations as current if needed
|
||||
/// @param delta delta time
|
||||
@ -724,7 +757,43 @@ class AnimationState {
|
||||
_bindings.spine_animation_state_update(_state, delta);
|
||||
|
||||
final numEvents = _bindings.spine_animation_state_events_get_num_events(_events);
|
||||
print("events: $numEvents");
|
||||
if (numEvents > 0) {
|
||||
for (int i = 0; i < numEvents; i++) {
|
||||
late final EventType type;
|
||||
switch(_bindings.spine_animation_state_events_get_event_type(_events, i)) {
|
||||
case 0:
|
||||
type = EventType.Start;
|
||||
break;
|
||||
case 1:
|
||||
type = EventType.Interrupt;
|
||||
break;
|
||||
case 2:
|
||||
type = EventType.End;
|
||||
break;
|
||||
case 3:
|
||||
type = EventType.Complete;
|
||||
break;
|
||||
case 4:
|
||||
type = EventType.Dispose;
|
||||
break;
|
||||
case 5:
|
||||
type = EventType.Event;
|
||||
break;
|
||||
}
|
||||
final entry = _bindings.spine_animation_state_events_get_track_entry(_events, i);
|
||||
final nativeEvent = _bindings.spine_animation_state_events_get_event(_events, i);
|
||||
final event = AnimationStateEvent(type, TrackEntry(entry, this), nativeEvent.address == nullptr.address ? null : Event(nativeEvent));
|
||||
if (_trackEntryListeners.containsKey(entry)) {
|
||||
_trackEntryListeners[entry]?.call(event);
|
||||
}
|
||||
if (_stateListener != null) {
|
||||
_stateListener?.call(event);
|
||||
}
|
||||
if (type == EventType.Dispose) {
|
||||
_bindings.spine_animation_state_dispose_track_entry(_state, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
_bindings.spine_animation_state_events_reset(_events);
|
||||
}
|
||||
|
||||
|
||||
@ -205,6 +205,24 @@ class SpineFlutterBindings {
|
||||
late final _spine_animation_state_update = _spine_animation_state_updatePtr
|
||||
.asFunction<void Function(spine_animation_state, double)>();
|
||||
|
||||
void spine_animation_state_dispose_track_entry(
|
||||
spine_animation_state state,
|
||||
spine_track_entry entry,
|
||||
) {
|
||||
return _spine_animation_state_dispose_track_entry(
|
||||
state,
|
||||
entry,
|
||||
);
|
||||
}
|
||||
|
||||
late final _spine_animation_state_dispose_track_entryPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(spine_animation_state,
|
||||
spine_track_entry)>>('spine_animation_state_dispose_track_entry');
|
||||
late final _spine_animation_state_dispose_track_entry =
|
||||
_spine_animation_state_dispose_track_entryPtr.asFunction<
|
||||
void Function(spine_animation_state, spine_track_entry)>();
|
||||
|
||||
void spine_animation_state_apply(
|
||||
spine_animation_state state,
|
||||
spine_skeleton skeleton,
|
||||
|
||||
@ -125,6 +125,7 @@ FFI_PLUGIN_EXPORT spine_skeleton_drawable *spine_skeleton_drawable_create(spine_
|
||||
drawable->skeleton = new Skeleton((SkeletonData*)skeletonData);
|
||||
AnimationState *state = new AnimationState(new AnimationStateData((SkeletonData*)skeletonData));
|
||||
drawable->animationState = state;
|
||||
state->setManualTrackEntryDisposal(true);
|
||||
EventListener *listener = new EventListener();
|
||||
drawable->animationStateEvents = listener;
|
||||
state->setListener(listener);
|
||||
@ -276,6 +277,13 @@ FFI_PLUGIN_EXPORT void spine_animation_state_update(spine_animation_state state,
|
||||
_state->update(delta);
|
||||
}
|
||||
|
||||
FFI_PLUGIN_EXPORT void spine_animation_state_dispose_track_entry(spine_animation_state state, spine_track_entry entry) {
|
||||
if (state == nullptr) return;
|
||||
if (entry == nullptr) return;
|
||||
AnimationState *_state = (AnimationState*)state;
|
||||
_state->disposeTrackEntry((TrackEntry*)entry);
|
||||
}
|
||||
|
||||
FFI_PLUGIN_EXPORT void spine_animation_state_apply(spine_animation_state state, spine_skeleton skeleton) {
|
||||
if (state == nullptr) return;
|
||||
AnimationState *_state = (AnimationState*)state;
|
||||
@ -352,21 +360,21 @@ FFI_PLUGIN_EXPORT spine_event_type spine_animation_state_events_get_event_type(s
|
||||
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;
|
||||
if (index >= _events->events.size()) 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;
|
||||
if (index >= _events->events.size()) return nullptr;
|
||||
return (spine_track_entry)_events->events[index].entry;
|
||||
}
|
||||
|
||||
FFI_PLUGIN_EXPORT spine_event spine_animation_state_events_get_event(spine_animation_state_events events, int index) {
|
||||
if (events == nullptr) return nullptr;
|
||||
EventListener *_events = (EventListener*)events;
|
||||
if (_events->events.size() >= index) return nullptr;
|
||||
if (index >= _events->events.size()) return nullptr;
|
||||
return (spine_track_entry)_events->events[index].entry;
|
||||
}
|
||||
|
||||
|
||||
@ -123,6 +123,7 @@ FFI_PLUGIN_EXPORT spine_render_command *spine_skeleton_drawable_render(spine_ske
|
||||
FFI_PLUGIN_EXPORT void spine_skeleton_drawable_dispose(spine_skeleton_drawable *drawable);
|
||||
|
||||
FFI_PLUGIN_EXPORT void spine_animation_state_update(spine_animation_state state, float delta);
|
||||
FFI_PLUGIN_EXPORT void spine_animation_state_dispose_track_entry(spine_animation_state state, spine_track_entry entry);
|
||||
FFI_PLUGIN_EXPORT void spine_animation_state_apply(spine_animation_state state, spine_skeleton skeleton);
|
||||
FFI_PLUGIN_EXPORT void spine_animation_state_clear_tracks(spine_animation_state state);
|
||||
FFI_PLUGIN_EXPORT void spine_animation_state_clear_track(spine_animation_state state, int trackIndex);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user