Skip to content

Commit

Permalink
fix callback issue
Browse files Browse the repository at this point in the history
  • Loading branch information
AGulev committed Jan 30, 2024
1 parent 14f4d07 commit f9f1b32
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 23 deletions.
43 changes: 27 additions & 16 deletions defold-spine/src/comp_spine_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,10 +299,10 @@ namespace dmSpine

static void ClearCompletionCallback(SpineAnimationTrack* track)
{
if (track->m_AnimationInstance && track->m_AnimationCallbackRef)
if (track->m_AnimationInstance && track->m_CallbackInfo)
{
dmScript::UnrefInInstance(track->m_Context, track->m_AnimationCallbackRef+LUA_NOREF);
track->m_AnimationCallbackRef = 0;
DestroyCallback(track->m_CallbackInfo);
track->m_CallbackInfo = 0x0;
}
}

Expand Down Expand Up @@ -358,7 +358,7 @@ namespace dmSpine
track.m_AnimationInstance->mixDuration = blend_duration;
track.m_AnimationInstance->trackTime = dmMath::Clamp(offset, track.m_AnimationInstance->animationStart, track.m_AnimationInstance->animationEnd);

track.m_AnimationCallbackRef = 0;
track.m_CallbackInfo = 0x0;
dmMessage::ResetURL(&track.m_Listener);

return true;
Expand Down Expand Up @@ -418,10 +418,18 @@ namespace dmSpine
message.m_Playback = track.m_Playback;
message.m_Track = entry->trackIndex + 1;

dmGameObject::Result result = dmGameObject::PostDDF(&message, &sender, &receiver, track.m_AnimationCallbackRef, true);
if (result != dmGameObject::RESULT_OK)
if (track.m_CallbackInfo)
{
dmLogError("Could not send animation_done to listener: %d", result);
RunTrackCallback(track.m_CallbackInfo, dmGameSystemDDF::SpineAnimationDone::m_DDFDescriptor, (const char*)&message, &sender, true);
track.m_CallbackInfo = 0x0;
}
else
{
dmGameObject::Result result = dmGameObject::PostDDF(&message, &sender, &receiver, 0, true);
if (result != dmGameObject::RESULT_OK)
{
dmLogError("Could not send animation_done to listener: %d", result);
}
}
}

Expand Down Expand Up @@ -456,10 +464,17 @@ namespace dmSpine
message.m_Node.m_ContextTableRef = 0;
message.m_Track = entry->trackIndex + 1;

dmGameObject::Result result = dmGameObject::PostDDF(&message, &sender, &receiver, track.m_AnimationCallbackRef, false);
if (result != dmGameObject::RESULT_OK)
if (track.m_CallbackInfo)
{
dmLogError("Could not send animation event '%s' from animation '%s' to listener: %d", entry->animation->name, event->data->name, result);
RunTrackCallback(track.m_CallbackInfo, dmGameSystemDDF::SpineEvent::m_DDFDescriptor, (const char*)&message, &sender, false);
}
else
{
dmGameObject::Result result = dmGameObject::PostDDF(&message, &sender, &receiver, 0, false);
if (result != dmGameObject::RESULT_OK)
{
dmLogError("Could not send animation event '%s' from animation '%s' to listener: %d", entry->animation->name, event->data->name, result);
}
}
}

Expand Down Expand Up @@ -502,10 +517,6 @@ namespace dmSpine
{
// We only send the event if it's not looping (same behavior as before)
SendAnimationDone(component, state, entry, event);

// The animation has ended, so we won't send any more on this
track.m_AnimationCallbackRef = 0;
track.m_AnimationInstance = nullptr;
}

if (IsPingPong(track.m_Playback))
Expand Down Expand Up @@ -967,7 +978,7 @@ namespace dmSpine
component->m_ReHash = 1;
}

bool CompSpineModelPlayAnimation(SpineModelComponent* component, dmGameSystemDDF::SpinePlayAnimation* message, dmMessage::URL* sender, int callback_ref, lua_State* L)
bool CompSpineModelPlayAnimation(SpineModelComponent* component, dmGameSystemDDF::SpinePlayAnimation* message, dmMessage::URL* sender, void* callback_info, lua_State* L)
{
bool result = PlayAnimation(component, message->m_AnimationId, (dmGameObject::Playback)message->m_Playback, message->m_BlendDuration,
message->m_Offset, message->m_PlaybackRate, message->m_Track - 1);
Expand All @@ -976,7 +987,7 @@ namespace dmSpine
SpineAnimationTrack& track = component->m_AnimationTracks[message->m_Track - 1];
track.m_Listener = *sender;
track.m_Context = L;
track.m_AnimationCallbackRef = callback_ref;
track.m_CallbackInfo = callback_info;
}
return result;
}
Expand Down
8 changes: 6 additions & 2 deletions defold-spine/src/comp_spine_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ namespace dmSpine
dmGameObject::Playback m_Playback;
dmMessage::URL m_Listener;
lua_State* m_Context;
int m_AnimationCallbackRef;

void* m_CallbackInfo;
};

struct IKTarget
Expand Down Expand Up @@ -82,7 +83,7 @@ namespace dmSpine
};

// For scripting
bool CompSpineModelPlayAnimation(SpineModelComponent* component, dmGameSystemDDF::SpinePlayAnimation* message, dmMessage::URL* sender, int callback_ref, lua_State* L);
bool CompSpineModelPlayAnimation(SpineModelComponent* component, dmGameSystemDDF::SpinePlayAnimation* message, dmMessage::URL* sender, void* callback_info, lua_State* L);
bool CompSpineModelCancelAnimation(SpineModelComponent* component, dmGameSystemDDF::SpineCancelAnimation* message);

bool CompSpineModelSetConstant(SpineModelComponent* component, dmGameSystemDDF::SetConstant* message);
Expand All @@ -97,6 +98,9 @@ namespace dmSpine

bool CompSpineModelGetBone(SpineModelComponent* component, dmhash_t bone_name, dmhash_t* instance_id);

void DestroyCallback(void* callback_data);
void RunTrackCallback(void* callback_data, const dmDDF::Descriptor* desc, const char* data, const dmMessage::URL* sender, bool destroy_after_call);

}

#endif // DM_GAMESYS_COMP_SPINE_MODEL_H
47 changes: 42 additions & 5 deletions defold-spine/src/script_spine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,14 +306,12 @@ namespace dmSpine
lua_pop(L, 1);
}

int functionref = 0;
dmScript::LuaCallbackInfo* cbk = 0x0;
if (top > 4) // completed cb
{
if (lua_isfunction(L, 5))
{
lua_pushvalue(L, 5);
// NOTE: By convention m_FunctionRef is offset by LUA_NOREF, see message.h in dlib
functionref = dmScript::RefInInstance(L) - LUA_NOREF;
cbk = dmScript::CreateCallback(L, 5);
}
}

Expand All @@ -327,15 +325,54 @@ namespace dmSpine

dmMessage::URL sender;
dmScript::GetURL(L, &sender);
if (!CompSpineModelPlayAnimation(component, &msg, &sender, functionref, L))
if (!CompSpineModelPlayAnimation(component, &msg, &sender, cbk, L))
{
// destroy callback immediately if error happened
if (cbk)
{
dmScript::DestroyCallback(cbk);
}
char buffer[128];
dmLogError("Failed to run animation '%s' on component '%s'", lua_tostring(L, 2), dmScript::UrlToString(&receiver, buffer, sizeof(buffer)));
}

return 0;
}

void DestroyCallback(void* callback_data)
{
dmScript::LuaCallbackInfo* cbk = (dmScript::LuaCallbackInfo*)callback_data;
dmScript::DestroyCallback(cbk);
}

void RunTrackCallback(void* callback_data, const dmDDF::Descriptor* desc, const char* data, const dmMessage::URL* sender, bool destroy_after_call)
{
dmScript::LuaCallbackInfo* cbk = (dmScript::LuaCallbackInfo*)callback_data;
if (!dmScript::IsCallbackValid(cbk))
{
dmLogError("Spine models callback is invalid.");
return;
}
lua_State* L = dmScript::GetCallbackLuaContext(cbk);
DM_LUA_STACK_CHECK(L, 0);

if (!dmScript::SetupCallback(cbk))
{
dmLogError("Failed to setup spine animation callback");
return;
}
lua_pushstring(L, desc->m_Name);
dmScript::PushDDF(L, desc, data, false);
// dmScript::PushURL(L, sender); // function unavaliable in dmsdk
int ret = dmScript::PCall(L, 3, 0);
(void)ret;
dmScript::TeardownCallback(cbk);
if (destroy_after_call)
{
dmScript::DestroyCallback(cbk);
}
}

/*# cancel all animation on a spine model
* Cancels all running animations on a specified spine model component.
*
Expand Down

0 comments on commit f9f1b32

Please sign in to comment.