Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions cocos/spine/skeleton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,6 @@ export class Skeleton extends UIRenderer {
* @engineInternal
*/
public _curFrame: AnimationFrame | null = null;
// Is need update skeltonData
protected _needUpdateSkeltonData = true;
protected _listener: TrackEntryListeners | null = null;

/**
Expand Down Expand Up @@ -328,6 +326,8 @@ export class Skeleton extends UIRenderer {
private _eventListenerID: number = -1;
private _slotTextures: Map<string, Texture2D> | null = null;

private _isRenderable: boolean = false;

constructor () {
super();
this._useVertexOpacity = true;
Expand Down Expand Up @@ -695,22 +695,18 @@ export class Skeleton extends UIRenderer {
*/
public onEnable (): void {
super.onEnable();
if (this._instance) {
this._instance.enable = true;
}
this._flushAssembler();
SkeletonSystem.getInstance().add(this);
this._isRenderable = true;
}
/**
* @en Be called when component state becomes disabled.
* @zh 组件状态变为禁用状态时调用。
*/
public onDisable (): void {
super.onDisable();
if (this._instance) {
this._instance.enable = false;
}
SkeletonSystem.getInstance().remove(this);
this._isRenderable = false;
}

public onDestroy (): void {
Expand Down Expand Up @@ -771,12 +767,14 @@ export class Skeleton extends UIRenderer {
this._skeleton = null!;
this._textures = [];
this._refreshInspector();
if (this._isRenderable) {
SkeletonSystem.getInstance().remove(this);
}
return;
}
if (this._instance) {
this._instance.dtRate = this._timeScale * timeScale;
}
this._needUpdateSkeltonData = false;
//const data = this.skeletonData?.getRuntimeData();
//if (!data) return;
//this.setSkeletonData(data);
Expand Down Expand Up @@ -858,6 +856,9 @@ export class Skeleton extends UIRenderer {
this._state = this._instance!.getAnimationState();
this._instance!.setPremultipliedAlpha(this._premultipliedAlpha);
}
if (this._isRenderable) {
SkeletonSystem.getInstance().add(this);
}
// Recreate render data and mark dirty
this._flushAssembler();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,11 @@ struct TrackEntryListeners {
};

void animationCallback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) {
(static_cast<SkeletonAnimation *>(state->getRendererObject()))->onAnimationStateEvent(entry, type, event);
(static_cast<SkeletonAnimation *>(state->getRendererObject()))->cacheAnimationEvent(entry, type, event);
}

void trackEntryCallback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) {
(static_cast<SkeletonAnimation *>(state->getRendererObject()))->onTrackEntryEvent(entry, type, event);
if (type == EventType_Dispose) {
if (entry->getRendererObject()) {
delete static_cast<TrackEntryListeners *>(entry->getRendererObject());
entry->setRendererObject(nullptr);
}
}
(static_cast<SkeletonAnimation *>(state->getRendererObject()))->cacheTrackEvent(entry, type, event);
}

static TrackEntryListeners *getListeners(TrackEntry *entry) {
Expand All @@ -72,6 +66,24 @@ void SkeletonAnimation::setGlobalTimeScale(float timeScale) {
GlobalTimeScale = timeScale;
}

void SkeletonAnimation::cacheAnimationEvent(spine::TrackEntry *entry, spine::EventType type, spine::Event *event) {
_vecAnimationEvents.push_back({type, entry, event});
}

void SkeletonAnimation::cacheTrackEvent(spine::TrackEntry *entry, spine::EventType type, spine::Event *event) {
_vecTrackEvents.push_back({type, entry, event});
}

void SkeletonAnimation::dispatchEvents() {
auto animationEvents = std::move(_vecAnimationEvents);
auto trackEvents = std::move(_vecTrackEvents);
for (const auto &info : animationEvents) {
onAnimationStateEvent(info.entry, info.type, info.event);
}
for (const auto &info : trackEvents) {
onTrackEntryEvent(info.entry, info.type, info.event);
}
}
SkeletonAnimation *SkeletonAnimation::create() {
auto *skeleton = new SkeletonAnimation();
return skeleton;
Expand Down Expand Up @@ -104,7 +116,10 @@ void SkeletonAnimation::initialize() {
_state->setListener(animationCallback);
}

SkeletonAnimation::SkeletonAnimation() = default;
SkeletonAnimation::SkeletonAnimation() {
_vecAnimationEvents.reserve(EventType::EventType_Event + 1);
_vecTrackEvents.reserve(EventType::EventType_Event + 1);
}

SkeletonAnimation::~SkeletonAnimation() {
_startListener = nullptr;
Expand Down Expand Up @@ -133,6 +148,7 @@ void SkeletonAnimation::update(float deltaTime) {
_skeleton->updateWorldTransform(Physics::Physics_Update);
#endif
}
dispatchEvents();
}

void SkeletonAnimation::setAnimationStateData(AnimationStateData *stateData) {
Expand Down Expand Up @@ -265,6 +281,8 @@ void SkeletonAnimation::onTrackEntryEvent(TrackEntry *entry, EventType type, Eve
break;
case EventType_Dispose:
if (listeners->disposeListener) listeners->disposeListener(entry);
delete static_cast<TrackEntryListeners *>(entry->getRendererObject());
entry->setRendererObject(nullptr);
break;
case EventType_Complete:
if (listeners->completeListener) listeners->completeListener(entry);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,15 @@
#pragma once
#include "spine-creator-support/SkeletonRenderer.h"
#include "spine/spine.h"
#include <vector>

namespace cc {

struct CacheEventInfo {
spine::EventType type{spine::EventType::EventType_Start};
spine::TrackEntry *entry{nullptr};
spine::Event *event{nullptr};
};
typedef std::function<void(spine::TrackEntry *entry)> StartListener;
typedef std::function<void(spine::TrackEntry *entry)> InterruptListener;
typedef std::function<void(spine::TrackEntry *entry)> EndListener;
Expand Down Expand Up @@ -82,6 +88,10 @@ class SkeletonAnimation : public cc::SkeletonRenderer {
virtual void onAnimationStateEvent(spine::TrackEntry *entry, spine::EventType type, spine::Event *event);
virtual void onTrackEntryEvent(spine::TrackEntry *entry, spine::EventType type, spine::Event *event);

void cacheAnimationEvent(spine::TrackEntry *entry, spine::EventType type, spine::Event *event);
void cacheTrackEvent(spine::TrackEntry *entry, spine::EventType type, spine::Event *event);
void dispatchEvents();

spine::AnimationState *getState() const;

SkeletonAnimation();
Expand All @@ -103,6 +113,8 @@ class SkeletonAnimation : public cc::SkeletonRenderer {

private:
typedef cc::SkeletonRenderer super;
std::vector<CacheEventInfo> _vecAnimationEvents;
std::vector<CacheEventInfo> _vecTrackEvents;
};

} // namespace cc
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,6 @@ EMSCRIPTEN_BINDINGS(spine) {
.constructor<>()
.property("isCache", &SpineSkeletonInstance::isCache)
.property("dtRate", &SpineSkeletonInstance::dtRate)
.property("enable", &SpineSkeletonInstance::enable)
.function("initSkeleton", &SpineSkeletonInstance::initSkeleton, allow_raw_pointers())
.function("setAnimation", &SpineSkeletonInstance::setAnimation, allow_raw_pointers())
.function("setSkin", &SpineSkeletonInstance::setSkin)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1359,7 +1359,6 @@ EMSCRIPTEN_BINDINGS(spine) {
.constructor<>()
.property("isCache", &SpineSkeletonInstance::isCache)
.property("dtRate", &SpineSkeletonInstance::dtRate)
.property("enable", &SpineSkeletonInstance::enable)
.function("initSkeleton", &SpineSkeletonInstance::initSkeleton, allow_raw_pointers())
.function("setAnimation", &SpineSkeletonInstance::setAnimation, allow_raw_pointers())
.function("setSkin", &SpineSkeletonInstance::setSkin)
Expand Down
40 changes: 36 additions & 4 deletions native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,24 @@ using namespace spine;

static void animationCallback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) {
SpineSkeletonInstance *instance = (static_cast<SpineSkeletonInstance *>(state->getRendererObject()));
instance->onAnimationStateEvent(entry, type, event);
if (instance) {
SpineEventInfo info;
info.entry = entry;
info.eventType = type;
info.event = event;
instance->animationEvents.add(info);
}
}

static void trackEntryCallback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) {
void* renderObj = state->getRendererObject();
if (renderObj) {
(static_cast<SpineSkeletonInstance *>(renderObj))->onTrackEntryEvent(entry, type, event);
SpineSkeletonInstance *instance = (static_cast<SpineSkeletonInstance *>(state->getRendererObject()));
if (instance) {
SpineEventInfo info;
info.entry = entry;
info.eventType = type;
info.event = event;
instance->trackEvents.add(info);

if (type == EventType_Dispose) {
if (entry->getRendererObject()) {
entry->setRendererObject(nullptr);
Expand All @@ -31,10 +42,14 @@ static void trackEntryCallback(AnimationState *state, EventType type, TrackEntry

SpineSkeletonInstance::SpineSkeletonInstance() {
_model = new SpineModel();
animationEvents.ensureCapacity(spine::EventType::EventType_Event + 1);
trackEvents.ensureCapacity(spine::EventType::EventType_Event + 1);
}

SpineSkeletonInstance::~SpineSkeletonInstance() {
_trackListenerSet.clear();
animationEvents.clear();
trackEvents.clear();
_skeletonData = nullptr;
if (_clipper) delete _clipper;
if (_animState) delete _animState;
Expand All @@ -48,6 +63,9 @@ void SpineSkeletonInstance::destroy() {
}

Skeleton *SpineSkeletonInstance::initSkeleton(SkeletonData *data) {
if (data == _skeletonData) {
return _skeleton;
}
if (_clipper) delete _clipper;
if (_animState) delete _animState;
if (_animStateData) delete _animStateData;
Expand Down Expand Up @@ -99,6 +117,20 @@ void SpineSkeletonInstance::updateAnimation(float dltTime) {
_skeleton->update(dltTime);
_animState->update(dltTime);
_animState->apply(*_skeleton);
//Cache animation events then call back to JS.
auto vecAnimationEvents = animationEvents;
animationEvents.clear();
//Cache track events then call back to JS.
auto vecTrackEvents = trackEvents;
trackEvents.clear();
for (int i = 0; i < vecAnimationEvents.size(); i++) {
auto& info = vecAnimationEvents[i];
onAnimationStateEvent(info.entry, info.eventType, info.event);
}
for (int i = 0; i < vecTrackEvents.size(); i++) {
auto& info = vecTrackEvents[i];
onTrackEntryEvent(info.entry, info.eventType, info.event);
}
}

SpineModel *SpineSkeletonInstance::updateRenderData() {
Expand Down
12 changes: 11 additions & 1 deletion native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
#include "mesh-type-define.h"
#include "spine-model.h"

namespace {
struct SpineEventInfo {
spine::TrackEntry* entry{nullptr};
spine::EventType eventType{spine::EventType::EventType_Start};
spine::Event *event{nullptr};
};
}
enum DEBUG_SHAPE_TYPE {
DEBUG_REGION = 0,
DEBUG_MESH = 1
Expand Down Expand Up @@ -59,8 +66,11 @@ class SpineSkeletonInstance {
void setSlotTexture(const spine::String &slotName, const spine::String& textureUuid);
void destroy();
bool isCache{false};
bool enable{true};
float dtRate{1.0F};

// Used internal for cache event
spine::Vector<SpineEventInfo> animationEvents;
spine::Vector<SpineEventInfo> trackEvents;
private:
void collectMeshData();

Expand Down
3 changes: 3 additions & 0 deletions native/tools/swig-config/spine_3_8.i
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ using namespace spine;
%ignore cc::SkeletonAnimation::createWithData;
%ignore cc::SkeletonAnimation::onTrackEntryEvent;
%ignore cc::SkeletonAnimation::onAnimationStateEvent;
%ignore cc::SkeletonAnimation::cacheAnimationEvent;
%ignore cc::SkeletonAnimation::cacheTrackEvent;
%ignore cc::SkeletonAnimation::dispatchEvents;
%ignore spine::TrackEntry::setListener;
%ignore spine::AnimationState::setListener;
%ignore spine::Attachment::getRTTI;
Expand Down
3 changes: 3 additions & 0 deletions native/tools/swig-config/spine_4_2.i
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ using namespace spine;
%ignore cc::SkeletonAnimation::createWithData;
%ignore cc::SkeletonAnimation::onTrackEntryEvent;
%ignore cc::SkeletonAnimation::onAnimationStateEvent;
%ignore cc::SkeletonAnimation::cacheAnimationEvent;
%ignore cc::SkeletonAnimation::cacheTrackEvent;
%ignore cc::SkeletonAnimation::dispatchEvents;
%ignore spine::TrackEntry::setListener;
%ignore spine::AnimationState::setListener;
%ignore spine::Attachment::getRTTI;
Expand Down
1 change: 0 additions & 1 deletion platforms/native/engine/jsb-spine-skeleton.js
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,6 @@ const cacheManager = require('./jsb-cache-manager');
this._nativeSkeleton._comp = null;
this._nativeSkeleton = null;
}
this._needUpdateSkeltonData = false;
};

const _onDestroy = skeleton.onDestroy;
Expand Down