From 92622246c1fead091fbb73678846e61db0d61068 Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Fri, 26 Apr 2013 20:03:28 +0200 Subject: [PATCH] AnimationState gets addAnimation methods for chaining animations. Tabs, not spaces! --- spine-c/include/spine/AnimationState.h | 12 ++- spine-c/src/spine/Animation.c | 2 +- spine-c/src/spine/AnimationState.c | 131 +++++++++++++++++++------ spine-c/src/spine/Atlas.c | 2 +- spine-c/src/spine/Attachment.c | 2 +- spine-c/src/spine/AttachmentLoader.c | 2 +- spine-c/src/spine/Skeleton.c | 2 +- spine-c/src/spine/Skin.c | 10 +- 8 files changed, 122 insertions(+), 41 deletions(-) diff --git a/spine-c/include/spine/AnimationState.h b/spine-c/include/spine/AnimationState.h index f904099cb..6880afc50 100644 --- a/spine-c/include/spine/AnimationState.h +++ b/spine-c/include/spine/AnimationState.h @@ -49,9 +49,17 @@ void AnimationState_update (AnimationState* self, float delta); void AnimationState_apply (AnimationState* self, struct Skeleton* skeleton); /* @param animationName May be 0. */ -void AnimationState_setAnimationByName (AnimationState* self, const char* animationName, int/**/loop); +void AnimationState_setAnimationByName (AnimationState* self, const char* animationName, int/*bool*/loop); /* @param animation May be 0. */ -void AnimationState_setAnimation (AnimationState* self, Animation* animation, int/**/loop); +void AnimationState_setAnimation (AnimationState* self, Animation* animation, int/*bool*/loop); + +/** @param animationName May be 0. + * @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */ +void AnimationState_addAnimationByName (AnimationState* self, const char* animationName, int/*bool*/loop, float delay); +/** @param animation May be 0. + * @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */ +void AnimationState_addAnimation (AnimationState* self, Animation* animation, int/*bool*/loop, float delay); + void AnimationState_clearAnimation (AnimationState* self); int/*bool*/AnimationState_isComplete (AnimationState* self); diff --git a/spine-c/src/spine/Animation.c b/spine-c/src/spine/Animation.c index 06bfbd90d..f5be9ecd5 100644 --- a/spine-c/src/spine/Animation.c +++ b/spine-c/src/spine/Animation.c @@ -474,7 +474,7 @@ void _AttachmentTimeline_dispose (Timeline* timeline) { for (i = 0; i < self->framesLength; ++i) FREE(self->attachmentNames[i]); FREE(self->attachmentNames); - FREE(self->frames); + FREE(self->frames); FREE(self); } diff --git a/spine-c/src/spine/AnimationState.c b/spine-c/src/spine/AnimationState.c index d095cb4f5..b2293f865 100644 --- a/spine-c/src/spine/AnimationState.c +++ b/spine-c/src/spine/AnimationState.c @@ -30,6 +30,14 @@ namespace spine { #endif +typedef struct _Entry _Entry; +struct _Entry { + Animation* animation; + int/*bool*/loop; + float delay; + _Entry* next; +}; + typedef struct { AnimationState super; Animation *previous; @@ -37,6 +45,7 @@ typedef struct { int/*bool*/previousLoop; float mixTime; float mixDuration; + _Entry* queue; } _Internal; AnimationState* AnimationState_create (AnimationStateData* data) { @@ -45,14 +54,105 @@ AnimationState* AnimationState_create (AnimationStateData* data) { return self; } +void _AnimationState_clearQueue (AnimationState* self) { + _Internal* internal = SUB_CAST(_Internal, self); + _Entry* entry = internal->queue; + while (entry) { + _Entry* nextEntry = entry->next; + FREE(entry); + entry = nextEntry; + } + internal->queue = 0; +} + void AnimationState_dispose (AnimationState* self) { + _AnimationState_clearQueue(self); FREE(self); } +#include + +void AnimationState_addAnimation (AnimationState* self, Animation* animation, int/*bool*/loop, float delay) { + _Entry* existingEntry; + Animation* previousAnimation; + + _Internal* internal = SUB_CAST(_Internal, self); + _Entry* entry = NEW(_Entry); + entry->animation = animation; + entry->loop = loop; + + existingEntry = internal->queue; + if (existingEntry) { + while (existingEntry->next) + existingEntry = existingEntry->next; + existingEntry->next = entry; + previousAnimation = existingEntry->animation; + } else { + internal->queue = entry; + previousAnimation = self->animation; + } + + if (delay <= 0) { + if (previousAnimation) + delay = self->animation->duration - AnimationStateData_getMix(self->data, self->animation, previousAnimation) + delay; + else + delay = 0; + } + entry->delay = delay; +} + +void AnimationState_addAnimationByName (AnimationState* self, const char* animationName, int/*bool*/loop, float delay) { + Animation* animation = animationName ? SkeletonData_findAnimation(self->data->skeletonData, animationName) : 0; + AnimationState_addAnimation(self, animation, loop, delay); +} + +void _AnimationState_setAnimation (AnimationState* self, Animation* newAnimation, int/*bool*/loop) { + _Internal* internal = SUB_CAST(_Internal, self); + internal->previous = 0; + if (newAnimation && self->animation && self->data) { + internal->mixDuration = AnimationStateData_getMix(self->data, self->animation, newAnimation); + if (internal->mixDuration > 0) { + internal->mixTime = 0; + internal->previous = self->animation; + internal->previousTime = self->time; + internal->previousLoop = self->loop; + } + } + CONST_CAST(Animation*, self->animation) = newAnimation; + self->loop = loop; + self->time = 0; +} + +void AnimationState_setAnimation (AnimationState* self, Animation* newAnimation, int/*bool*/loop) { + _AnimationState_clearQueue(self); + _AnimationState_setAnimation(self, newAnimation, loop); +} + +void AnimationState_setAnimationByName (AnimationState* self, const char* animationName, int/*bool*/loop) { + Animation* animation = animationName ? SkeletonData_findAnimation(self->data->skeletonData, animationName) : 0; + AnimationState_setAnimation(self, animation, loop); +} + +void AnimationState_clearAnimation (AnimationState* self) { + _Internal* internal = SUB_CAST(_Internal, self); + internal->previous = 0; + CONST_CAST(Animation*, self->animation) = 0; + _AnimationState_clearQueue(self); +} + void AnimationState_update (AnimationState* self, float delta) { + _Internal* internal = SUB_CAST(_Internal, self); + self->time += delta; - SUB_CAST(_Internal, self) ->previousTime += delta; - SUB_CAST(_Internal, self) ->mixTime += delta; + internal->previousTime += delta; + internal->mixTime += delta; + + if (internal->queue && self->time >= internal->queue->delay) { + _AnimationState_setAnimation(self, internal->queue->animation, internal->queue->loop); + _Entry* next = internal->queue->next; + FREE(internal->queue); + internal->queue = next; + } } void AnimationState_apply (AnimationState* self, Skeleton* skeleton) { @@ -73,33 +173,6 @@ void AnimationState_apply (AnimationState* self, Skeleton* skeleton) { Animation_apply(self->animation, skeleton, self->time, self->loop); } -void AnimationState_setAnimationByName (AnimationState* self, const char* animationName, int/**/loop) { - Animation* animation = SkeletonData_findAnimation(self->data->skeletonData, animationName); - AnimationState_setAnimation(self, animation, loop); -} - -void AnimationState_setAnimation (AnimationState* self, Animation* newAnimation, int/**/loop) { - _Internal* internal = SUB_CAST(_Internal, self); - internal->previous = 0; - if (newAnimation && self->animation && self->data) { - internal->mixDuration = AnimationStateData_getMix(self->data, self->animation, newAnimation); - if (internal->mixDuration > 0) { - internal->mixTime = 0; - internal->previous = self->animation; - internal->previousTime = self->time; - internal->previousLoop = self->loop; - } - } - CONST_CAST(Animation*, self->animation) = newAnimation; - self->loop = loop; - self->time = 0; -} - -void AnimationState_clearAnimation (AnimationState* self) { - SUB_CAST(_Internal, self) ->previous = 0; - CONST_CAST(Animation*, self->animation) = 0; -} - int/*bool*/AnimationState_isComplete (AnimationState* self) { return !self->animation || self->time >= self->animation->duration; } diff --git a/spine-c/src/spine/Atlas.c b/spine-c/src/spine/Atlas.c index 5b3059786..676f1481d 100644 --- a/spine-c/src/spine/Atlas.c +++ b/spine-c/src/spine/Atlas.c @@ -40,7 +40,7 @@ AtlasPage* AtlasPage_create (const char* name) { void AtlasPage_dispose (AtlasPage* self) { FREE(self->name); _AtlasPage_disposeTexture(self); - FREE(self); + FREE(self); } /**/ diff --git a/spine-c/src/spine/Attachment.c b/spine-c/src/spine/Attachment.c index d82097ed3..0b57fe583 100644 --- a/spine-c/src/spine/Attachment.c +++ b/spine-c/src/spine/Attachment.c @@ -52,7 +52,7 @@ void _Attachment_deinit (Attachment* self) { void Attachment_dispose (Attachment* self) { VTABLE(Attachment, self) ->dispose(self); - FREE(self); + FREE(self); } #ifdef __cplusplus diff --git a/spine-c/src/spine/AttachmentLoader.c b/spine-c/src/spine/AttachmentLoader.c index 5b17f7cfc..9af1505a1 100644 --- a/spine-c/src/spine/AttachmentLoader.c +++ b/spine-c/src/spine/AttachmentLoader.c @@ -52,7 +52,7 @@ void _AttachmentLoader_deinit (AttachmentLoader* self) { void AttachmentLoader_dispose (AttachmentLoader* self) { VTABLE(AttachmentLoader, self) ->dispose(self); - FREE(self); + FREE(self); } Attachment* AttachmentLoader_newAttachment (AttachmentLoader* self, Skin* skin, AttachmentType type, const char* name) { diff --git a/spine-c/src/spine/Skeleton.c b/spine-c/src/spine/Skeleton.c index 755b22825..6ccbb5f65 100644 --- a/spine-c/src/spine/Skeleton.c +++ b/spine-c/src/spine/Skeleton.c @@ -95,7 +95,7 @@ void Skeleton_dispose (Skeleton* self) { FREE(self->slots); FREE(self->drawOrder); - FREE(self); + FREE(self); } void Skeleton_updateWorldTransform (const Skeleton* self) { diff --git a/spine-c/src/spine/Skin.c b/spine-c/src/spine/Skin.c index 828958817..dace58cc9 100644 --- a/spine-c/src/spine/Skin.c +++ b/spine-c/src/spine/Skin.c @@ -66,11 +66,11 @@ Skin* Skin_create (const char* name) { } void Skin_dispose (Skin* self) { - _Entry* entry = SUB_CAST(_Internal, self)->entries; + _Entry* entry = SUB_CAST(_Internal, self) ->entries; while (entry) { - _Entry* nextEtry = entry->next; + _Entry* nextEntry = entry->next; _Entry_dispose(entry); - entry = nextEtry; + entry = nextEntry; } FREE(self->name); @@ -79,8 +79,8 @@ void Skin_dispose (Skin* self) { #include void Skin_addAttachment (Skin* self, int slotIndex, const char* name, Attachment* attachment) { _Entry* newEntry = _Entry_create(slotIndex, name, attachment); - newEntry->next = SUB_CAST(_Internal, self)->entries; - SUB_CAST(_Internal, self)->entries = newEntry; + newEntry->next = SUB_CAST(_Internal, self) ->entries; + SUB_CAST(_Internal, self) ->entries = newEntry; } Attachment* Skin_getAttachment (const Skin* self, int slotIndex, const char* name) {