Skip to content

Commit

Permalink
Performance improvement using SNAME, caches for find_bone find_slot, …
Browse files Browse the repository at this point in the history
…temporary string buffer support.
  • Loading branch information
jordo committed Aug 3, 2023
1 parent 8082dfc commit 0ce2ab6
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 76 deletions.
17 changes: 10 additions & 7 deletions spine-cpp/spine-cpp/include/spine/SpineString.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@
namespace spine {
class SP_API String : public SpineObject {
public:
String() : _length(0), _buffer(NULL) {
String() : _length(0), _buffer(NULL), _tofree(true) {
}

String(const char *chars, bool own = false) {
String(const char *chars, bool own = false, bool tofree = true) {
_tofree = tofree;
if (!chars) {
_length = 0;
_buffer = NULL;
Expand All @@ -63,6 +64,7 @@ namespace spine {
}

String(const String &other) {
_tofree = true;
if (!other._buffer) {
_length = 0;
_buffer = NULL;
Expand All @@ -87,7 +89,7 @@ namespace spine {

void own(const String &other) {
if (this == &other) return;
if (_buffer) {
if (_buffer && _tofree) {
SpineExtension::free(_buffer, __FILE__, __LINE__);
}
_length = other._length;
Expand All @@ -98,7 +100,7 @@ namespace spine {

void own(const char *chars) {
if (_buffer == chars) return;
if (_buffer) {
if (_buffer && _tofree) {
SpineExtension::free(_buffer, __FILE__, __LINE__);
}

Expand All @@ -118,7 +120,7 @@ namespace spine {

String &operator=(const String &other) {
if (this == &other) return *this;
if (_buffer) {
if (_buffer && _tofree) {
SpineExtension::free(_buffer, __FILE__, __LINE__);
}
if (!other._buffer) {
Expand All @@ -134,7 +136,7 @@ namespace spine {

String &operator=(const char *chars) {
if (_buffer == chars) return *this;
if (_buffer) {
if (_buffer && _tofree) {
SpineExtension::free(_buffer, __FILE__, __LINE__);
}
if (!chars) {
Expand Down Expand Up @@ -205,14 +207,15 @@ namespace spine {
}

~String() {
if (_buffer) {
if (_buffer && _tofree) {
SpineExtension::free(_buffer, __FILE__, __LINE__);
}
}

private:
mutable size_t _length;
mutable char *_buffer;
mutable bool _tofree;
};
}

Expand Down
8 changes: 4 additions & 4 deletions spine-godot/spine_godot/SpineAnimationTrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ void SpineAnimationTrack::_notification(int what) {
sprite = Object::cast_to<SpineSprite>(get_parent());
if (sprite)
#if VERSION_MAJOR > 3
sprite->connect("before_animation_state_update", callable_mp(this, &SpineAnimationTrack::update_animation_state));
sprite->connect(SNAME("before_animation_state_update"), callable_mp(this, &SpineAnimationTrack::update_animation_state));
#else
sprite->connect("before_animation_state_update", this, "update_animation_state");
sprite->connect(SNAME("before_animation_state_update"), this, SNAME("update_animation_state"));
#endif
NOTIFY_PROPERTY_LIST_CHANGED();
break;
Expand All @@ -100,9 +100,9 @@ void SpineAnimationTrack::_notification(int what) {
case NOTIFICATION_UNPARENTED: {
if (sprite) {
#if VERSION_MAJOR > 3
sprite->disconnect("before_animation_state_update", callable_mp(this, &SpineAnimationTrack::update_animation_state));
sprite->disconnect(SNAME("before_animation_state_update"), callable_mp(this, &SpineAnimationTrack::update_animation_state));
#else
sprite->disconnect("before_animation_state_update", this, "update_animation_state");
sprite->disconnect(SNAME("before_animation_state_update"), this, SNAME("update_animation_state"));
#endif
sprite = nullptr;
}
Expand Down
8 changes: 4 additions & 4 deletions spine-godot/spine_godot/SpineBoneNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ void SpineBoneNode::_notification(int what) {
SpineSprite *sprite = find_parent_sprite();
if (sprite) {
#if VERSION_MAJOR > 3
sprite->connect("world_transforms_changed", callable_mp(this, &SpineBoneNode::on_world_transforms_changed));
sprite->connect(SNAME("world_transforms_changed"), callable_mp(this, &SpineBoneNode::on_world_transforms_changed));
#else
sprite->connect("world_transforms_changed", this, "_on_world_transforms_changed");
sprite->connect(SNAME("world_transforms_changed"), this, SNAME("_on_world_transforms_changed"));
#endif
update_transform(sprite);
#if VERSION_MAJOR == 3
Expand All @@ -83,9 +83,9 @@ void SpineBoneNode::_notification(int what) {
SpineSprite *sprite = find_parent_sprite();
if (sprite) {
#if VERSION_MAJOR > 3
sprite->disconnect("world_transforms_changed", callable_mp(this, &SpineBoneNode::on_world_transforms_changed));
sprite->disconnect(SNAME("world_transforms_changed"), callable_mp(this, &SpineBoneNode::on_world_transforms_changed));
#else
sprite->disconnect("world_transforms_changed", this, "_on_world_transforms_changed");
sprite->disconnect(SNAME("world_transforms_changed"), this, SNAME("_on_world_transforms_changed"));
#endif
}
break;
Expand Down
12 changes: 8 additions & 4 deletions spine-godot/spine_godot/SpineCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
#define VARIANT_FLOAT Variant::REAL
#define GDREGISTER_CLASS(x) ClassDB::register_class<x>()
#define GEOMETRY2D Geometry
#ifndef SNAME
#define SNAME(m_arg) ([]() -> const StringName & { static StringName sname = _scs_create(m_arg); return sname; })()
#endif
#endif

#define SPINE_CHECK(obj, ret) \
Expand All @@ -65,6 +68,7 @@
}

#define SPINE_STRING(x) spine::String((x).utf8())
#define SPINE_STRING_TMP(x) spine::String((x).utf8(), true, false)

// Can't do template classes with Godot's object model :(
class SpineObjectWrapper : public REFCOUNTED {
Expand All @@ -81,9 +85,9 @@ class SpineObjectWrapper : public REFCOUNTED {
void spine_objects_invalidated() {
spine_object = nullptr;
#if VERSION_MAJOR > 3
spine_owner->disconnect("_internal_spine_objects_invalidated", callable_mp(this, &SpineObjectWrapper::spine_objects_invalidated));
spine_owner->disconnect(SNAME("_internal_spine_objects_invalidated"), callable_mp(this, &SpineObjectWrapper::spine_objects_invalidated));
#else
spine_owner->disconnect("_internal_spine_objects_invalidated", this, "_internal_spine_objects_invalidated");
spine_owner->disconnect(SNAME("_internal_spine_objects_invalidated"), this, SNAME("_internal_spine_objects_invalidated"));
#endif
}

Expand All @@ -108,9 +112,9 @@ class SpineObjectWrapper : public REFCOUNTED {
spine_owner = (Object *) _owner;
spine_object = _object;
#if VERSION_MAJOR > 3
spine_owner->connect("_internal_spine_objects_invalidated", callable_mp(this, &SpineObjectWrapper::spine_objects_invalidated));
spine_owner->connect(SNAME("_internal_spine_objects_invalidated"), callable_mp(this, &SpineObjectWrapper::spine_objects_invalidated));
#else
spine_owner->connect("_internal_spine_objects_invalidated", this, "_internal_spine_objects_invalidated");
spine_owner->connect(SNAME("_internal_spine_objects_invalidated"), this, SNAME("_internal_spine_objects_invalidated"));
#endif
}

Expand Down
20 changes: 10 additions & 10 deletions spine-godot/spine_godot/SpineEditorPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,18 +219,18 @@ void SpineEditorPropertyAnimationMixes::update_property() {
hbox->add_child(delete_button);
delete_button->set_text("Remove");
#if VERSION_MAJOR > 3
delete_button->connect("pressed", callable_mp(this, &SpineEditorPropertyAnimationMixes::delete_mix).bind(varray(i)));
delete_button->connect(SNAME("pressed"), callable_mp(this, &SpineEditorPropertyAnimationMixes::delete_mix).bind(varray(i)));
#else
delete_button->connect("pressed", this, "delete_mix", varray(i));
delete_button->connect(SNAME("pressed"), this, SNAME("delete_mix"), varray(i));
#endif
}

auto add_mix_button = memnew(Button);
add_mix_button->set_text("Add mix");
#if VERSION_MAJOR > 3
add_mix_button->connect("pressed", callable_mp(this, &SpineEditorPropertyAnimationMixes::add_mix));
add_mix_button->connect(SNAME("pressed"), callable_mp(this, &SpineEditorPropertyAnimationMixes::add_mix));
#else
add_mix_button->connect("pressed", this, "add_mix");
add_mix_button->connect(SNAME("pressed"), this, SNAME("add_mix"));
#endif
container->add_child(add_mix_button);

Expand Down Expand Up @@ -303,9 +303,9 @@ void SpineEditorPropertyAnimationMix::update_property() {
from_enum->set_object_and_property(mix, "from");
from_enum->update_property();
#if VERSION_MAJOR > 3
from_enum->connect("property_changed", callable_mp(this, &SpineEditorPropertyAnimationMix::data_changed));
from_enum->connect(SNAME("property_changed"), callable_mp(this, &SpineEditorPropertyAnimationMix::data_changed));
#else
from_enum->connect("property_changed", this, "data_changed");
from_enum->connect(SNAME("property_changed"), this, SNAME("data_changed"));
#endif
container->add_child(from_enum);

Expand All @@ -317,9 +317,9 @@ void SpineEditorPropertyAnimationMix::update_property() {
to_enum->set_object_and_property(mix, "to");
to_enum->update_property();
#if VERSION_MAJOR > 3
to_enum->connect("property_changed", callable_mp(this, &SpineEditorPropertyAnimationMix::data_changed));
to_enum->connect(SNAME("property_changed"), callable_mp(this, &SpineEditorPropertyAnimationMix::data_changed));
#else
to_enum->connect("property_changed", this, "data_changed");
to_enum->connect(SNAME("property_changed"), this, SNAME("data_changed"));
#endif
container->add_child(to_enum);

Expand All @@ -331,9 +331,9 @@ void SpineEditorPropertyAnimationMix::update_property() {
mix_float->set_object_and_property(mix, "mix");
mix_float->update_property();
#if VERSION_MAJOR > 3
mix_float->connect("property_changed", callable_mp(this, &SpineEditorPropertyAnimationMix::data_changed));
mix_float->connect(SNAME("property_changed"), callable_mp(this, &SpineEditorPropertyAnimationMix::data_changed));
#else
mix_float->connect("property_changed", this, "data_changed");
mix_float->connect(SNAME("property_changed"), this, SNAME("data_changed"));
#endif
container->add_child(mix_float);

Expand Down
24 changes: 16 additions & 8 deletions spine-godot/spine_godot/SpineSkeleton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,26 +113,34 @@ void SpineSkeleton::set_slots_to_setup_pose() {
Ref<SpineBone> SpineSkeleton::find_bone(const String &name) {
SPINE_CHECK(skeleton, nullptr)
if (EMPTY(name)) return nullptr;
auto bone = skeleton->findBone(SPINE_STRING(name));
auto bone = skeleton->findBone(SPINE_STRING_TMP(name));
if (!bone) return nullptr;
if (_cached_bones.count(bone) > 0 ) {
return _cached_bones[bone];
}
Ref<SpineBone> bone_ref(memnew(SpineBone));
bone_ref->set_spine_object(sprite, bone);
_cached_bones[bone] = bone_ref;
return bone_ref;
}

Ref<SpineSlot> SpineSkeleton::find_slot(const String &name) {
SPINE_CHECK(skeleton, nullptr)
if (EMPTY(name)) return nullptr;
auto slot = skeleton->findSlot(SPINE_STRING(name));
auto slot = skeleton->findSlot(SPINE_STRING_TMP(name));
if (!slot) return nullptr;
if (_cached_slots.count(slot) > 0 ) {
return _cached_slots[slot];
}
Ref<SpineSlot> slot_ref(memnew(SpineSlot));
slot_ref->set_spine_object(sprite, slot);
_cached_slots[slot] = slot_ref;
return slot_ref;
}

void SpineSkeleton::set_skin_by_name(const String &skin_name) {
SPINE_CHECK(skeleton, )
skeleton->setSkin(SPINE_STRING(skin_name));
skeleton->setSkin(SPINE_STRING_TMP(skin_name));
}

void SpineSkeleton::set_skin(Ref<SpineSkin> new_skin) {
Expand All @@ -144,7 +152,7 @@ void SpineSkeleton::set_skin(Ref<SpineSkin> new_skin) {

Ref<SpineAttachment> SpineSkeleton::get_attachment_by_slot_name(const String &slot_name, const String &attachment_name) {
SPINE_CHECK(skeleton, nullptr)
auto attachment = skeleton->getAttachment(SPINE_STRING(slot_name), SPINE_STRING(attachment_name));
auto attachment = skeleton->getAttachment(SPINE_STRING_TMP(slot_name), SPINE_STRING_TMP(attachment_name));
if (!attachment) return nullptr;
Ref<SpineAttachment> attachment_ref(memnew(SpineAttachment));
attachment_ref->set_spine_object(*sprite->get_skeleton_data_res(), attachment);
Expand All @@ -153,7 +161,7 @@ Ref<SpineAttachment> SpineSkeleton::get_attachment_by_slot_name(const String &sl

Ref<SpineAttachment> SpineSkeleton::get_attachment_by_slot_index(int slot_index, const String &attachment_name) {
SPINE_CHECK(skeleton, nullptr)
auto attachment = skeleton->getAttachment(slot_index, SPINE_STRING(attachment_name));
auto attachment = skeleton->getAttachment(slot_index, SPINE_STRING_TMP(attachment_name));
if (!attachment) return nullptr;
Ref<SpineAttachment> attachment_ref(memnew(SpineAttachment));
attachment_ref->set_spine_object(*sprite->get_skeleton_data_res(), attachment);
Expand All @@ -168,7 +176,7 @@ void SpineSkeleton::set_attachment(const String &slot_name, const String &attach
Ref<SpineIkConstraint> SpineSkeleton::find_ik_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr)
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton->findIkConstraint(SPINE_STRING(constraint_name));
auto constraint = skeleton->findIkConstraint(SPINE_STRING_TMP(constraint_name));
if (!constraint) return nullptr;
Ref<SpineIkConstraint> constraint_ref(memnew(SpineIkConstraint));
constraint_ref->set_spine_object(sprite, constraint);
Expand All @@ -178,7 +186,7 @@ Ref<SpineIkConstraint> SpineSkeleton::find_ik_constraint(const String &constrain
Ref<SpineTransformConstraint> SpineSkeleton::find_transform_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr)
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton->findTransformConstraint(SPINE_STRING(constraint_name));
auto constraint = skeleton->findTransformConstraint(SPINE_STRING_TMP(constraint_name));
if (!constraint) return nullptr;
Ref<SpineTransformConstraint> constraint_ref(memnew(SpineTransformConstraint));
constraint_ref->set_spine_object(sprite, constraint);
Expand All @@ -188,7 +196,7 @@ Ref<SpineTransformConstraint> SpineSkeleton::find_transform_constraint(const Str
Ref<SpinePathConstraint> SpineSkeleton::find_path_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr)
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton->findPathConstraint(SPINE_STRING(constraint_name));
auto constraint = skeleton->findPathConstraint(SPINE_STRING_TMP(constraint_name));
if (!constraint) return nullptr;
Ref<SpinePathConstraint> constraint_ref(memnew(SpinePathConstraint));
constraint_ref->set_spine_object(sprite, constraint);
Expand Down
5 changes: 5 additions & 0 deletions spine-godot/spine_godot/SpineSkeleton.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
#include "SpineTransformConstraint.h"
#include "SpinePathConstraint.h"

#include <unordered_map>

class SpineSprite;

class SpineSkeleton : public REFCOUNTED {
Expand Down Expand Up @@ -66,6 +68,9 @@ class SpineSkeleton : public REFCOUNTED {
spine::Vector<float> bounds_vertex_buffer;
Ref<SpineSkin> last_skin;

std::unordered_map<spine::Bone*, Ref<SpineBone>> _cached_bones;
std::unordered_map<spine::Slot*, Ref<SpineSlot>> _cached_slots;

public:
SpineSkeleton();
~SpineSkeleton() override;
Expand Down
Loading

0 comments on commit 0ce2ab6

Please sign in to comment.