From 68f2e04495c3d8df5f3a9fb56e586f18ba99b029 Mon Sep 17 00:00:00 2001 From: badlogic Date: Tue, 12 Apr 2022 11:24:57 +0200 Subject: [PATCH] [godot] Clean-up SpineAnimation & SpineAnimationState, unify native object checks. --- spine-godot/spine_godot/SpineAnimation.cpp | 35 ++-- spine-godot/spine_godot/SpineAnimation.h | 7 +- .../spine_godot/SpineAnimationState.cpp | 152 +++++++++--------- spine-godot/spine_godot/SpineAnimationState.h | 41 ++--- spine-godot/spine_godot/common.h | 41 +++++ 5 files changed, 160 insertions(+), 116 deletions(-) create mode 100644 spine-godot/spine_godot/common.h diff --git a/spine-godot/spine_godot/SpineAnimation.cpp b/spine-godot/spine_godot/SpineAnimation.cpp index cef0e00e9..71fececf8 100644 --- a/spine-godot/spine_godot/SpineAnimation.cpp +++ b/spine-godot/spine_godot/SpineAnimation.cpp @@ -27,6 +27,7 @@ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +#include "common.h" #include "SpineAnimation.h" #include "SpineSkeleton.h" #include "SpineEvent.h" @@ -44,54 +45,60 @@ void SpineAnimation::_bind_methods() { ClassDB::bind_method(D_METHOD("has_timeline", "ids"), &SpineAnimation::has_timeline); } -SpineAnimation::SpineAnimation() : animation(NULL) { +SpineAnimation::SpineAnimation() : animation(nullptr) { } SpineAnimation::~SpineAnimation() { } String SpineAnimation::get_name() { + SPINE_CHECK(animation, "") return animation->getName().buffer(); } float SpineAnimation::get_duration() { + SPINE_CHECK(animation, 0) return animation->getDuration(); } void SpineAnimation::set_duration(float duration) { + SPINE_CHECK(animation,) animation->setDuration(duration); } -void SpineAnimation::apply(Ref skeleton, float lastTime, float time, bool loop, +void SpineAnimation::apply(Ref skeleton, float last_time, float time, bool loop, Array events, float alpha, SpineConstant::MixBlend blend, SpineConstant::MixDirection direction) { + SPINE_CHECK(animation,) spine::Vector spineEvents; - spineEvents.setSize(events.size(), nullptr); - for (size_t i = 0; i < events.size(); ++i) { - spineEvents[i] = ((Ref) (events[i]))->get_spine_object(); + animation->apply(*(skeleton->get_spine_object()), last_time, time, loop, &spineEvents, alpha, (spine::MixBlend) blend, (spine::MixDirection) direction); + for (int i = 0; i < spineEvents.size(); ++i) { + auto event_ref = memnew(SpineEvent); + event_ref->set_spine_object(spineEvents[i]); + events.append(event_ref); } - animation->apply(*(skeleton->get_spine_object()), lastTime, time, loop, &spineEvents, alpha, (spine::MixBlend) blend, (spine::MixDirection) direction); } Array SpineAnimation::get_timelines() { - auto &timelines = animation->getTimelines(); Array result; - result.resize(timelines.size()); + SPINE_CHECK(animation, result) + auto &timelines = animation->getTimelines(); + result.resize((int)timelines.size()); - for (size_t i = 0; i < result.size(); ++i) { - auto timeline = Ref(memnew(SpineTimeline)); - timeline->set_spine_object(timelines[i]); - result.set(i, timeline); + for (int i = 0; i < result.size(); ++i) { + auto timeline_ref = Ref(memnew(SpineTimeline)); + timeline_ref->set_spine_object(timelines[i]); + result.set(i, timeline_ref); } - return result; } bool SpineAnimation::has_timeline(Array ids) { + SPINE_CHECK(animation, false) spine::Vector property_ids; property_ids.setSize(ids.size(), 0); - for (size_t i = 0; i < property_ids.size(); ++i) { + for (int i = 0; i < property_ids.size(); ++i) { property_ids[i] = (int64_t) ids[i]; } return animation->hasTimeline(property_ids); diff --git a/spine-godot/spine_godot/SpineAnimation.h b/spine-godot/spine_godot/SpineAnimation.h index 25d908957..a6051b2ea 100644 --- a/spine-godot/spine_godot/SpineAnimation.h +++ b/spine-godot/spine_godot/SpineAnimation.h @@ -51,10 +51,11 @@ public: SpineAnimation(); ~SpineAnimation(); - inline void set_spine_object(spine::Animation *animation) { this->animation = animation; } - inline spine::Animation *get_spine_object() { return animation; } + void set_spine_object(spine::Animation *animation) { this->animation = animation; } + + spine::Animation *get_spine_object() { return animation; } - void apply(Ref skeleton, float lastTime, float time, bool loop, Array events, float alpha, SpineConstant::MixBlend blend, SpineConstant::MixDirection direction); + void apply(Ref skeleton, float last_time, float time, bool loop, Array events, float alpha, SpineConstant::MixBlend blend, SpineConstant::MixDirection direction); Array get_timelines(); diff --git a/spine-godot/spine_godot/SpineAnimationState.cpp b/spine-godot/spine_godot/SpineAnimationState.cpp index d73df1578..907f95734 100644 --- a/spine-godot/spine_godot/SpineAnimationState.cpp +++ b/spine-godot/spine_godot/SpineAnimationState.cpp @@ -27,23 +27,24 @@ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +#include "common.h" #include "SpineAnimationState.h" void SpineAnimationState::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_animation", "anim_name", "loop", "track_id"), &SpineAnimationState::set_animation, DEFVAL(true), DEFVAL(0)); ClassDB::bind_method(D_METHOD("update", "delta"), &SpineAnimationState::update, DEFVAL(0)); ClassDB::bind_method(D_METHOD("apply", "skeleton"), &SpineAnimationState::apply); ClassDB::bind_method(D_METHOD("clear_tracks"), &SpineAnimationState::clear_tracks); ClassDB::bind_method(D_METHOD("clear_track"), &SpineAnimationState::clear_track); - ClassDB::bind_method(D_METHOD("add_animation", "anim_name", "delay", "loop", "track_id"), &SpineAnimationState::add_animation, DEFVAL(0), DEFVAL(true), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("set_animation", "animation_name", "loop", "track_id"), &SpineAnimationState::set_animation, DEFVAL(true), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("add_animation", "animation_name", "delay", "loop", "track_id"), &SpineAnimationState::add_animation, DEFVAL(0), DEFVAL(true), DEFVAL(0)); ClassDB::bind_method(D_METHOD("set_empty_animation", "track_id", "mix_duration"), &SpineAnimationState::set_empty_animation); ClassDB::bind_method(D_METHOD("add_empty_animation", "track_id", "mix_duration", "delay"), &SpineAnimationState::add_empty_animation); ClassDB::bind_method(D_METHOD("set_empty_animations", "mix_duration"), &SpineAnimationState::set_empty_animations); + ClassDB::bind_method(D_METHOD("get_current", "track_id"), &SpineAnimationState::get_current); ClassDB::bind_method(D_METHOD("get_time_scale"), &SpineAnimationState::get_time_scale); ClassDB::bind_method(D_METHOD("set_time_scale", "time_scale"), &SpineAnimationState::set_time_scale); ClassDB::bind_method(D_METHOD("disable_queue"), &SpineAnimationState::disable_queue); ClassDB::bind_method(D_METHOD("enable_queue"), &SpineAnimationState::enable_queue); - ClassDB::bind_method(D_METHOD("get_current", "track_id"), &SpineAnimationState::get_current); } SpineAnimationState::SpineAnimationState() : animation_state(nullptr), skeleton_data_res(nullptr) { @@ -65,107 +66,98 @@ Ref SpineAnimationState::get_skeleton_data_res() cons return skeleton_data_res; } -#define CHECK_V \ - if (!animation_state) { \ - ERR_PRINT("The animation state is not loaded yet!"); \ - return; \ - } -#define CHECK_X(x) \ - if (!animation_state) { \ - ERR_PRINT("The animation state is not loaded yet!"); \ - return x; \ - } -#define S_T(x) (spine::String(x.utf8())) -Ref SpineAnimationState::set_animation(const String &anim_name, bool loop, uint64_t track) { - CHECK_X(nullptr); - auto skeleton_data = animation_state->getData()->getSkeletonData(); - auto anim = skeleton_data->findAnimation(anim_name.utf8().ptr()); - if (!anim) { - ERR_PRINT(String("Can not find animation: ") + anim_name); - return nullptr; - } - auto entry = animation_state->setAnimation(track, anim, loop); - Ref gd_entry(memnew(SpineTrackEntry)); - gd_entry->set_spine_object(entry); - return gd_entry; -} -Ref SpineAnimationState::add_animation(const String &anim_name, float delay, bool loop, uint64_t track) { - CHECK_X(nullptr); - auto skeleton_data = animation_state->getData()->getSkeletonData(); - auto anim = skeleton_data->findAnimation(anim_name.utf8().ptr()); - if (!anim) { - ERR_PRINT(String("Can not find animation: ") + anim_name); - return nullptr; - } - auto entry = animation_state->addAnimation(track, anim, loop, delay); - Ref gd_entry(memnew(SpineTrackEntry)); - gd_entry->set_spine_object(entry); - return gd_entry; -} - -Ref SpineAnimationState::set_empty_animation(uint64_t track_id, float mix_duration) { - CHECK_X(nullptr); - auto entry = animation_state->setEmptyAnimation(track_id, mix_duration); - Ref gd_entry(memnew(SpineTrackEntry)); - gd_entry->set_spine_object(entry); - return gd_entry; -} -Ref SpineAnimationState::add_empty_animation(uint64_t track_id, float mix_duration, float delay) { - CHECK_X(nullptr); - auto entry = animation_state->addEmptyAnimation(track_id, mix_duration, delay); - Ref gd_entry(memnew(SpineTrackEntry)); - gd_entry->set_spine_object(entry); - return gd_entry; -} -void SpineAnimationState::set_empty_animations(float mix_duration) { - CHECK_V; - animation_state->setEmptyAnimations(mix_duration); -} - void SpineAnimationState::update(float delta) { - CHECK_V; + SPINE_CHECK(animation_state,) animation_state->update(delta); } + bool SpineAnimationState::apply(Ref skeleton) { - CHECK_X(false); + SPINE_CHECK(animation_state, false) return animation_state->apply(*(skeleton->get_spine_object())); } void SpineAnimationState::clear_tracks() { - CHECK_V; + SPINE_CHECK(animation_state,) animation_state->clearTracks(); } + void SpineAnimationState::clear_track(uint64_t track_id) { - CHECK_V; + SPINE_CHECK(animation_state,) animation_state->clearTrack(track_id); } +Ref SpineAnimationState::set_animation(const String &animation_name, bool loop, uint64_t track) { + SPINE_CHECK(animation_state, nullptr) + auto skeleton_data = animation_state->getData()->getSkeletonData(); + auto animation = skeleton_data->findAnimation(animation_name.utf8().ptr()); + if (!animation) { + ERR_PRINT(String("Can not find animation: ") + animation_name); + return nullptr; + } + auto track_entry = animation_state->setAnimation(track, animation, loop); + Ref track_entry_ref(memnew(SpineTrackEntry)); + track_entry_ref->set_spine_object(track_entry); + return track_entry_ref; +} + +Ref SpineAnimationState::add_animation(const String &animation_name, float delay, bool loop, uint64_t track) { + SPINE_CHECK(animation_state, nullptr) + auto skeleton_data = animation_state->getData()->getSkeletonData(); + auto animation = skeleton_data->findAnimation(animation_name.utf8().ptr()); + if (!animation) { + ERR_PRINT(String("Can not find animation: ") + animation_name); + return nullptr; + } + auto track_entry = animation_state->addAnimation(track, animation, loop, delay); + Ref track_entry_ref(memnew(SpineTrackEntry)); + track_entry_ref->set_spine_object(track_entry); + return track_entry_ref; +} + +Ref SpineAnimationState::set_empty_animation(uint64_t track_id, float mix_duration) { + SPINE_CHECK(animation_state, nullptr) + auto track_entry = animation_state->setEmptyAnimation(track_id, mix_duration); + Ref track_entry_ref(memnew(SpineTrackEntry)); + track_entry_ref->set_spine_object(track_entry); + return track_entry_ref; +} +Ref SpineAnimationState::add_empty_animation(uint64_t track_id, float mix_duration, float delay) { + SPINE_CHECK(animation_state, nullptr) + auto track_entry = animation_state->addEmptyAnimation(track_id, mix_duration, delay); + Ref track_entry_ref(memnew(SpineTrackEntry)); + track_entry_ref->set_spine_object(track_entry); + return track_entry_ref; +} +void SpineAnimationState::set_empty_animations(float mix_duration) { + SPINE_CHECK(animation_state,) + animation_state->setEmptyAnimations(mix_duration); +} + +Ref SpineAnimationState::get_current(uint64_t track_index) { + SPINE_CHECK(animation_state, nullptr) + auto track_entry = animation_state->getCurrent(track_index); + if (!track_entry) return nullptr; + Ref track_entry_ref(memnew(SpineTrackEntry)); + track_entry_ref->set_spine_object(track_entry); + return track_entry_ref; +} + float SpineAnimationState::get_time_scale() { - CHECK_X(0); + SPINE_CHECK(animation_state, 0) return animation_state->getTimeScale(); } + void SpineAnimationState::set_time_scale(float time_scale) { - CHECK_V; + SPINE_CHECK(animation_state,) animation_state->setTimeScale(time_scale); } void SpineAnimationState::disable_queue() { - CHECK_V; + SPINE_CHECK(animation_state,) animation_state->disableQueue(); } + void SpineAnimationState::enable_queue() { - CHECK_V; + SPINE_CHECK(animation_state,) animation_state->enableQueue(); } - -Ref SpineAnimationState::get_current(uint64_t track_index) { - CHECK_X(nullptr); - Ref gd_entry(memnew(SpineTrackEntry)); - auto entry = animation_state->getCurrent(track_index); - if (entry == nullptr) return nullptr; - gd_entry->set_spine_object(entry); - return gd_entry; -} - -#undef CHECK_V -#undef CHECK_X diff --git a/spine-godot/spine_godot/SpineAnimationState.h b/spine-godot/spine_godot/SpineAnimationState.h index a8b4aebf4..1dc231b90 100644 --- a/spine-godot/spine_godot/SpineAnimationState.h +++ b/spine-godot/spine_godot/SpineAnimationState.h @@ -34,7 +34,7 @@ #include "SpineTrackEntry.h" class SpineAnimationState : public Reference { - GDCLASS(SpineAnimationState, Reference); + GDCLASS(SpineAnimationState, Reference) protected: static void _bind_methods(); @@ -46,28 +46,13 @@ private: public: SpineAnimationState(); ~SpineAnimationState(); + + spine::AnimationState *get_spine_object() { return animation_state; } void set_skeleton_data_res(Ref skeleton_data_res); + Ref get_skeleton_data_res() const; - inline void set_spine_object(spine::AnimationState *animation_state) { this->animation_state = animation_state; } - inline spine::AnimationState *get_spine_object() { return animation_state; } - - Ref set_animation(const String &anim_name, bool loop, uint64_t track_id); - - Ref add_animation(const String &anim_name, float delay, bool loop, uint64_t track_id); - - Ref set_empty_animation(uint64_t track_id, float mix_duration); - - Ref add_empty_animation(uint64_t track_id, float mix_duration, float delay); - void set_empty_animations(float mix_duration); - - float get_time_scale(); - void set_time_scale(float time_scale); - - void disable_queue(); - void enable_queue(); - void update(float delta); bool apply(Ref skeleton); @@ -76,7 +61,25 @@ public: void clear_track(uint64_t track_id); + Ref set_animation(const String &animation_name, bool loop, uint64_t track_id); + + Ref add_animation(const String &animation_name, float delay, bool loop, uint64_t track_id); + + Ref set_empty_animation(uint64_t track_id, float mix_duration); + + Ref add_empty_animation(uint64_t track_id, float mix_duration, float delay); + + void set_empty_animations(float mix_duration); + Ref get_current(uint64_t track_index); + + float get_time_scale(); + + void set_time_scale(float time_scale); + + void disable_queue(); + + void enable_queue(); }; #endif//GODOT_SPINEANIMATIONSTATE_H diff --git a/spine-godot/spine_godot/common.h b/spine-godot/spine_godot/common.h new file mode 100644 index 000000000..de6173e94 --- /dev/null +++ b/spine-godot/spine_godot/common.h @@ -0,0 +1,41 @@ +/****************************************************************************** +* Spine Runtimes License Agreement + * Last updated January 1, 2020. Replaces all prior versions. + * + * Copyright (c) 2013-2020, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, + * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef SPINE_COMMON_H +#define SPINE_COMMON_H + +#include "core/error_macros.h" + +#define SPINE_CHECK(obj, ret) \ + if (!(obj)) { \ + ERR_PRINT("Native Spine object not set."); \ + return ret; \ + } + +#endif \ No newline at end of file