[cpp] Fixed up Skin and internal hashmap like structure.

This commit is contained in:
badlogic 2018-04-18 14:25:56 +02:00
parent bceee601ad
commit 6c29e8c2e9
8 changed files with 128 additions and 83 deletions

View File

@ -92,7 +92,7 @@ struct TestData {
void testLoading() { void testLoading() {
Vector<TestData> testData; Vector<TestData> testData;
testData.add(TestData("testdata/coin/coin-pro.json", "testdata/coin/coin-pro.skel", "testdata/coin/coin.atlas")); /*testData.add(TestData("testdata/coin/coin-pro.json", "testdata/coin/coin-pro.skel", "testdata/coin/coin.atlas"));
testData.add(TestData("testdata/goblins/goblins-pro.json", "testdata/goblins/goblins-pro.skel", testData.add(TestData("testdata/goblins/goblins-pro.json", "testdata/goblins/goblins-pro.skel",
"testdata/goblins/goblins.atlas")); "testdata/goblins/goblins.atlas"));
testData.add(TestData("testdata/raptor/raptor-pro.json", "testdata/raptor/raptor-pro.skel", testData.add(TestData("testdata/raptor/raptor-pro.json", "testdata/raptor/raptor-pro.skel",
@ -100,7 +100,7 @@ void testLoading() {
testData.add(TestData("testdata/spineboy/spineboy-pro.json", "testdata/spineboy/spineboy-pro.skel", testData.add(TestData("testdata/spineboy/spineboy-pro.json", "testdata/spineboy/spineboy-pro.skel",
"testdata/spineboy/spineboy.atlas")); "testdata/spineboy/spineboy.atlas"));
testData.add(TestData("testdata/stretchyman/stretchyman-pro.json", "testdata/stretchyman/stretchyman-pro.skel", testData.add(TestData("testdata/stretchyman/stretchyman-pro.json", "testdata/stretchyman/stretchyman-pro.skel",
"testdata/stretchyman/stretchyman.atlas")); "testdata/stretchyman/stretchyman.atlas"));*/
testData.add(TestData("testdata/tank/tank-pro.json", "testdata/tank/tank-pro.skel", "testdata/tank/tank.atlas")); testData.add(TestData("testdata/tank/tank-pro.json", "testdata/tank/tank-pro.skel", "testdata/tank/tank.atlas"));
for (size_t i = 0; i < testData.size(); i++) { for (size_t i = 0; i < testData.size(); i++) {

View File

@ -42,11 +42,11 @@ public:
clamp(); clamp();
} }
inline Color &set(float r, float g, float b, float a) { inline Color &set(float _r, float _g, float _b, float _a) {
r = r; this->r = _r;
g = g; this->g = _g;
b = b; this->b = _b;
a = a; this->a = _a;
clamp(); clamp();
return *this; return *this;
} }
@ -60,11 +60,11 @@ public:
return *this; return *this;
} }
inline Color &add(float r, float g, float b, float a) { inline Color &add(float _r, float _g, float _b, float _a) {
r += r; this->r += _r;
g += g; this->g += _g;
b += b; this->b += _b;
a += a; this->a += _a;
clamp(); clamp();
return *this; return *this;
} }

View File

@ -34,7 +34,6 @@
#include <spine/Extension.h> #include <spine/Extension.h>
#include <spine/Vector.h> #include <spine/Vector.h>
#include <spine/SpineObject.h> #include <spine/SpineObject.h>
#include <spine/String.h>
namespace Spine { namespace Spine {
template<typename K, typename V> template<typename K, typename V>

View File

@ -97,6 +97,8 @@ struct Interpolation {
virtual float interpolate(float start, float end, float a) { virtual float interpolate(float start, float end, float a) {
return start + (end - start) * apply(a); return start + (end - start) * apply(a);
} }
virtual ~Interpolation() {};
}; };
struct PowInterpolation: public Interpolation { struct PowInterpolation: public Interpolation {

View File

@ -31,7 +31,6 @@
#ifndef Spine_Skin_h #ifndef Spine_Skin_h
#define Spine_Skin_h #define Spine_Skin_h
#include <spine/HashMap.h>
#include <spine/Vector.h> #include <spine/Vector.h>
#include <spine/String.h> #include <spine/String.h>
@ -47,34 +46,70 @@ class Skin : public SpineObject {
friend class Skeleton; friend class Skeleton;
public: public:
class AttachmentKey : public SpineObject { class AttachmentMap : public SpineObject {
friend class Skin;
public: public:
int _slotIndex; struct Entry {
String _name; int _slotIndex;
String _name;
Attachment *_attachment;
explicit AttachmentKey(int slotIndex = 0, const String &name = 0); Entry(int slotIndex, const String &name, Attachment *attachment) :
_slotIndex(slotIndex),
_name(name),
_attachment(attachment) {
}
};
// Used in Skin::getAttachment to avoid allocation of temporary string class Entries {
explicit AttachmentKey(int slotIndex, const char* name); friend class AttachmentMap;
AttachmentKey(const AttachmentKey &other) { public:
this->_slotIndex = other._slotIndex; bool hasNext() {
this->_name = other._name; while(true) {
} if (_slotIndex >= (int) _buckets.size()) return false;
if (_bucketIndex >= (int) _buckets[_slotIndex].size()) {
_bucketIndex = 0;
++_slotIndex;
continue;
};
return true;
}
}
bool operator==(const AttachmentKey &other) const; Entry &next() {
Entry &result = _buckets[_slotIndex][_bucketIndex];
++_bucketIndex;
return result;
}
int getSlotIndex() { protected:
return _slotIndex; Entries(Vector< Vector<Entry> > &buckets) : _buckets(buckets), _slotIndex(0), _bucketIndex(0) {
} }
String& getName() { private:
return _name; Vector< Vector<Entry> > &_buckets;
} int _slotIndex;
}; int _bucketIndex;
};
struct HashAttachmentKey : public SpineObject { void put(int slotIndex, const String &attachmentName, Attachment *attachment);
std::size_t operator()(const Spine::Skin::AttachmentKey &val) const;
Attachment *get(int slotIndex, const String &attachmentName);
void remove(int slotIndex, const String &attachmentName);
Entries getEntries();
protected:
AttachmentMap();
private:
int findInBucket(Vector <Entry> &, const String &attachmentName);
Vector <Vector<Entry> > _buckets;
}; };
explicit Skin(const String &name); explicit Skin(const String &name);
@ -100,11 +135,11 @@ public:
const String &getName(); const String &getName();
HashMap<AttachmentKey, Attachment *> &getAttachments(); AttachmentMap::Entries getAttachments();
private: private:
const String _name; const String _name;
HashMap<AttachmentKey, Attachment *> _attachments; AttachmentMap _attachments;
/// Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached. /// Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached.
void attachAll(Skeleton &skeleton, Skin &oldSkin); void attachAll(Skeleton &skeleton, Skin &oldSkin);

View File

@ -225,7 +225,7 @@ private:
buffer->~T(); buffer->~T();
} }
Vector &operator=(const Vector &inVector) {}; // Vector &operator=(const Vector &inVector) {};
}; };
} }

View File

@ -602,13 +602,12 @@ void Skeleton::sortTransformConstraint(TransformConstraint *constraint) {
} }
void Skeleton::sortPathConstraintAttachment(Skin *skin, int slotIndex, Bone &slotBone) { void Skeleton::sortPathConstraintAttachment(Skin *skin, int slotIndex, Bone &slotBone) {
HashMap<Skin::AttachmentKey, Attachment *> &attachments = skin->getAttachments(); Skin::AttachmentMap::Entries attachments = skin->getAttachments();
for (HashMap<Skin::AttachmentKey, Attachment *>::Entries entries = attachments.getEntries(); entries.hasNext();) { while (attachments.hasNext()) {
HashMap<Skin::AttachmentKey, Attachment *>::Pair pair = entries.next(); Skin::AttachmentMap::Entry entry = attachments.next();
Skin::AttachmentKey &key = pair.key; if (entry._slotIndex == slotIndex) {
if (key._slotIndex == slotIndex) { Attachment *value = entry._attachment;
Attachment *value = pair.value;
sortPathConstraintAttachment(value, slotBone); sortPathConstraintAttachment(value, slotBone);
} }
} }

View File

@ -39,70 +39,80 @@
using namespace Spine; using namespace Spine;
Skin::AttachmentKey::AttachmentKey(int slotIndex, const char* name) : Skin::AttachmentMap::AttachmentMap() {
_slotIndex(slotIndex),
_name(name, true) {
} }
Skin::AttachmentKey::AttachmentKey(int slotIndex, const String &name) : void Skin::AttachmentMap::put(int slotIndex, const String &attachmentName, Attachment *attachment) {
_slotIndex(slotIndex), if (slotIndex >= _buckets.size())
_name(name) { _buckets.setSize(slotIndex + 1, Vector<Entry>());
Vector<Entry> &bucket = _buckets[slotIndex];
int existing = findInBucket(bucket, attachmentName);
if (existing >= 0) {
bucket[existing]._attachment = attachment;
} else {
bucket.add(Entry(slotIndex, attachmentName, attachment));
}
} }
bool Skin::AttachmentKey::operator==(const AttachmentKey &other) const { Attachment *Skin::AttachmentMap::get(int slotIndex, const String &attachmentName) {
return _slotIndex == other._slotIndex && _name == other._name; if (slotIndex >= _buckets.size()) return NULL;
int existing = findInBucket(_buckets[slotIndex], attachmentName);
return existing >= 0 ? _buckets[slotIndex][existing]._attachment : NULL;
} }
std::size_t Skin::HashAttachmentKey::operator()(const Spine::Skin::AttachmentKey &val) const { void Skin::AttachmentMap::remove(int slotIndex, const String &attachmentName) {
std::size_t h1 = val._slotIndex; if (slotIndex >= _buckets.size()) return;
return h1; int existing = findInBucket(_buckets[slotIndex], attachmentName);
if (existing >= 0) _buckets[slotIndex].removeAt(existing);
} }
Skin::Skin(const String &name) : _name(name) { int Skin::AttachmentMap::findInBucket(Vector<Entry> &bucket, const String &attachmentName) {
for (size_t i = 0; i < bucket.size(); i++)
if (bucket[i]._name == attachmentName) return i;
return -1;
}
Skin::AttachmentMap::Entries Skin::AttachmentMap::getEntries() {
return Skin::AttachmentMap::Entries(_buckets);
}
Skin::Skin(const String &name) : _name(name), _attachments() {
assert(_name.length() > 0); assert(_name.length() > 0);
} }
Skin::~Skin() { Skin::~Skin() {
HashMap<AttachmentKey, Attachment *>::Entries entries = _attachments.getEntries(); Skin::AttachmentMap::Entries entries = _attachments.getEntries();
while (entries.hasNext()) { while (entries.hasNext()) {
HashMap<AttachmentKey, Attachment *>::Pair pair = entries.next(); Skin::AttachmentMap::Entry entry = entries.next();
delete pair.value; delete entry._attachment;
} }
} }
void Skin::addAttachment(int slotIndex, const String &name, Attachment *attachment) { void Skin::addAttachment(int slotIndex, const String &name, Attachment *attachment) {
assert(attachment); assert(attachment);
_attachments.put(AttachmentKey(slotIndex, name), attachment); _attachments.put(slotIndex, name, attachment);
} }
Attachment *Skin::getAttachment(int slotIndex, const String &name) { Attachment *Skin::getAttachment(int slotIndex, const String &name) {
AttachmentKey key(slotIndex, name.buffer()); return _attachments.get(slotIndex, name);
if (_attachments.containsKey(key)) {
Attachment *attachment = _attachments[key];
key.getName().unown();
return attachment;
} else {
key.getName().unown();
return NULL;
}
} }
void Skin::findNamesForSlot(int slotIndex, Vector<String> &names) { void Skin::findNamesForSlot(int slotIndex, Vector<String> &names) {
HashMap<AttachmentKey, Attachment *>::Entries entries = _attachments.getEntries(); Skin::AttachmentMap::Entries entries = _attachments.getEntries();
while (entries.hasNext()) { while (entries.hasNext()) {
HashMap<AttachmentKey, Attachment *>::Pair pair = entries.next(); Skin::AttachmentMap::Entry &entry = entries.next();
if (pair.key._slotIndex == slotIndex) { if (entry._slotIndex == slotIndex) {
names.add(pair.key._name); names.add(entry._name);
} }
} }
} }
void Skin::findAttachmentsForSlot(int slotIndex, Vector<Attachment *> &attachments) { void Skin::findAttachmentsForSlot(int slotIndex, Vector<Attachment *> &attachments) {
HashMap<AttachmentKey, Attachment *>::Entries entries = _attachments.getEntries(); Skin::AttachmentMap::Entries entries = _attachments.getEntries();
while (entries.hasNext()) { while (entries.hasNext()) {
HashMap<AttachmentKey, Attachment *>::Pair pair = entries.next(); Skin::AttachmentMap::Entry &entry = entries.next();
if (pair.key._slotIndex == slotIndex) { if (entry._slotIndex == slotIndex) {
attachments.add(pair.value); attachments.add(entry._attachment);
} }
} }
} }
@ -111,21 +121,21 @@ const String &Skin::getName() {
return _name; return _name;
} }
HashMap<Skin::AttachmentKey, Attachment *> &Skin::getAttachments() { Skin::AttachmentMap::Entries Skin::getAttachments() {
return _attachments; return _attachments.getEntries();
} }
void Skin::attachAll(Skeleton &skeleton, Skin &oldSkin) { void Skin::attachAll(Skeleton &skeleton, Skin &oldSkin) {
Vector<Slot *> &slots = skeleton.getSlots(); Vector<Slot *> &slots = skeleton.getSlots();
HashMap<AttachmentKey, Attachment *>::Entries entries = oldSkin.getAttachments().getEntries(); Skin::AttachmentMap::Entries entries = oldSkin.getAttachments();
while (entries.hasNext()) { while (entries.hasNext()) {
HashMap<AttachmentKey, Attachment *>::Pair pair = entries.next(); Skin::AttachmentMap::Entry &entry = entries.next();
int slotIndex = pair.key._slotIndex; int slotIndex = entry._slotIndex;
Slot *slot = slots[slotIndex]; Slot *slot = slots[slotIndex];
if (slot->getAttachment() == pair.value) { if (slot->getAttachment() == entry._attachment) {
Attachment *attachment = NULL; Attachment *attachment = NULL;
if ((attachment = getAttachment(slotIndex, pair.key._name))) { if ((attachment = getAttachment(slotIndex, entry._name))) {
slot->setAttachment(attachment); slot->setAttachment(attachment);
} }
} }