From 08af18e86efa00080f2c27df2c809d40b21d3c14 Mon Sep 17 00:00:00 2001 From: Stephen Gowen Date: Tue, 3 Oct 2017 18:47:25 -0400 Subject: [PATCH] wip --- spine-cpp/spine-cpp/include/spine/Skin.h | 123 ++++++++++------------- spine-cpp/spine-cpp/src/spine/Skin.cpp | 102 ++++++++++++++++++- 2 files changed, 153 insertions(+), 72 deletions(-) diff --git a/spine-cpp/spine-cpp/include/spine/Skin.h b/spine-cpp/spine-cpp/include/spine/Skin.h index 1c6386964..910e2585e 100644 --- a/spine-cpp/spine-cpp/include/spine/Skin.h +++ b/spine-cpp/spine-cpp/include/spine/Skin.h @@ -31,97 +31,78 @@ #ifndef Spine_Skin_h #define Spine_Skin_h +#include +#include +#include + namespace Spine { + class Attachment; + class Skeleton; + + class AttachmentKey; + /// Stores attachments by slot index and attachment name. /// See SkeletonData::getDefaultSkin, Skeleton::getSkin, and /// http://esotericsoftware.com/spine-runtime-skins in the Spine Runtimes Guide. class Skin { public: - public std::string Name { get { return name; } } - public Dictionary Attachments { get { return attachments; } } + Skin(std::string name); - public Skin (std::string name) { - if (name == null) throw new ArgumentNullException("name", "name cannot be null."); - this.name = name; - } - - /// Adds an attachment to the skin for the specified slot index and name. If the name already exists for the slot, the previous value is replaced. - public void AddAttachment (int slotIndex, std::string name, Attachment attachment) { - if (attachment == null) throw new ArgumentNullException("attachment", "attachment cannot be null."); - attachments[new AttachmentKeyTuple(slotIndex, name)] = attachment; - } + /// Adds an attachment to the skin for the specified slot index and name. + /// If the name already exists for the slot, the previous value is replaced. + void addAttachment(int slotIndex, std::string name, Attachment* attachment); /// Returns the attachment for the specified slot index and name, or null. - /// May be null. - public Attachment GetAttachment (int slotIndex, std::string name) { - Attachment attachment; - attachments.TryGetValue(new AttachmentKeyTuple(slotIndex, name), out attachment); - return attachment; - } + Attachment* getAttachment(int slotIndex, std::string name); - /// Finds the skin keys for a given slot. The results are added to the passed List(names). - /// The target slotIndex. To find the slot index, use or - /// Found skin key names will be added to this list. - public void FindNamesForSlot (int slotIndex, List names) { - if (names == null) throw new ArgumentNullException("names", "names cannot be null."); - foreach (AttachmentKeyTuple key in attachments.Keys) - if (key.slotIndex == slotIndex) names.Add(key.name); - } + /// Finds the skin keys for a given slot. The results are added to the passed vector names. + /// @param slotIndex The target slotIndex. To find the slot index, use Skeleton::findSlotIndex or SkeletonData::findSlotIndex + /// @param names Found skin key names will be added to this vector. + void findNamesForSlot(int slotIndex, std::vector& names); /// Finds the attachments for a given slot. The results are added to the passed List(Attachment). - /// The target slotIndex. To find the slot index, use or - /// Found Attachments will be added to this list. - public void FindAttachmentsForSlot (int slotIndex, List attachments) { - if (attachments == null) throw new ArgumentNullException("attachments", "attachments cannot be null."); - foreach (KeyValuePair entry in this.attachments) - if (entry.Key.slotIndex == slotIndex) attachments.Add(entry.Value); - } + /// @param slotIndex The target slotIndex. To find the slot index, use Skeleton::findSlotIndex or SkeletonData::findSlotIndex + /// @param attachments Found Attachments will be added to this vector. + void findAttachmentsForSlot(int slotIndex, std::vector& attachments); - override public std::string ToString () { - return name; - } + const std::string& getName(); + std::unordered_map& getAttachments(); private: - internal std::string name; - Dictionary attachments = new Dictionary(AttachmentKeyTupleComparer.Instance); + const std::string _name; + std::unordered_map _attachments; /// Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached. - internal void AttachAll (Skeleton skeleton, Skin oldSkin) { - foreach (KeyValuePair entry in oldSkin.attachments) { - int slotIndex = entry.Key.slotIndex; - Slot slot = skeleton.slots.Items[slotIndex]; - if (slot.Attachment == entry.Value) { - Attachment attachment = GetAttachment(slotIndex, entry.Key.name); - if (attachment != null) slot.Attachment = attachment; + void attachAll(Skeleton& skeleton, Skin& oldSkin); + + class AttachmentKey + { + public: + const int _slotIndex; + const std::string _name; + + AttachmentKey(int slotIndex, std::string name); + + bool operator==(const AttachmentKey &other) const; + }; + + friend std::ostream& operator <<(std::ostream& os, const Skin& ref); + + namespace std + { + template <> + struct hash + { + size_t operator()(const AttachmentKey& val) const + { + size_t h1 = hash{}(val._slotIndex); + size_t h2 = hash{}(val._name); + + return h1 ^ (h2 << 1); } - } - } - - public struct AttachmentKeyTuple { - public readonly int slotIndex; - public readonly std::string name; - internal readonly int nameHashCode; - - public AttachmentKeyTuple (int slotIndex, std::string name) { - this.slotIndex = slotIndex; - this.name = name; - nameHashCode = this.name.GetHashCode(); - } - } - - // Avoids boxing in the dictionary. - class AttachmentKeyTupleComparer : IEqualityComparer { - internal static readonly AttachmentKeyTupleComparer Instance = new AttachmentKeyTupleComparer(); - - bool IEqualityComparer.Equals (AttachmentKeyTuple o1, AttachmentKeyTuple o2) { - return o1.slotIndex == o2.slotIndex && o1.nameHashCode == o2.nameHashCode && o1.name == o2.name; - } - - int IEqualityComparer.GetHashCode (AttachmentKeyTuple o) { - return o.slotIndex; - } + }; } }; } diff --git a/spine-cpp/spine-cpp/src/spine/Skin.cpp b/spine-cpp/spine-cpp/src/spine/Skin.cpp index bb4d2ccfe..8ee4f916a 100644 --- a/spine-cpp/spine-cpp/src/spine/Skin.cpp +++ b/spine-cpp/spine-cpp/src/spine/Skin.cpp @@ -28,7 +28,107 @@ * POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +#include + +#include + namespace Spine { - // TODO + Skin::Skin(std::string name) : _name(name) + { + assert(_name.length() > 0); + } + + void Skin::addAttachment(int slotIndex, std::string name, Attachment* attachment) + { + assert(attachment); + + _attachments[AttachmentKey(slotIndex, name)] = attachment; + } + + /// Returns the attachment for the specified slot index and name, or null. + Attachment* Skin::getAttachment(int slotIndex, std::string name) + { + std::iterator q = _attachments.find(AttachmentKey(slotIndex, name)); + + Attachment* ret = nullptr; + + if (q != _attachments.end()) + { + ret = q->second; + } + + return ret; + } + + struct sum + { + sum(int * t):total(t){}; + int * total; + + void operator()(AttachmentKey key) + { + *total+=element; + } + }; + + /// Finds the skin keys for a given slot. The results are added to the passed vector names. + /// @param slotIndex The target slotIndex. To find the slot index, use Skeleton::findSlotIndex or SkeletonData::findSlotIndex + /// @param names Found skin key names will be added to this vector. + void Skin::findNamesForSlot(int slotIndex, std::vector& names) + { + foreach (AttachmentKey key in attachments.Keys) + if (key.slotIndex == slotIndex) names.Add(key.name); + } + + /// Finds the attachments for a given slot. The results are added to the passed List(Attachment). + /// @param slotIndex The target slotIndex. To find the slot index, use Skeleton::findSlotIndex or SkeletonData::findSlotIndex + /// @param attachments Found Attachments will be added to this vector. + void Skin::findAttachmentsForSlot(int slotIndex, std::vector& attachments) + { + foreach (KeyValuePair entry in this.attachments) + if (entry.Key.slotIndex == slotIndex) attachments.Add(entry.Value); + } + + const std::string& Skin::getName() + { + // + } + + std::unordered_map& Skin::getAttachments() + { + // + } + + void Skin::attachAll(Skeleton& skeleton, Skin& oldSkin) + { + foreach (KeyValuePair entry in oldSkin.attachments) + { + int slotIndex = entry.Key.slotIndex; + Slot slot = skeleton.slots.Items[slotIndex]; + if (slot.Attachment == entry.Value) { + Attachment attachment = GetAttachment(slotIndex, entry.Key.name); + if (attachment != null) slot.Attachment = attachment; + } + } + } + + AttachmentKey::AttachmentKey(int slotIndex, std::string name) : + _slotIndex(slotIndex), + _name(name) + { + // Empty + } + + bool AttachmentKey::operator==(const AttachmentKey &other) const + { + return _slotIndex == other._slotIndex && _name == other._name; + } + + std::ostream& operator <<(std::ostream& os, const Skin& ref) + { + os << ref.getName(); + + return os; + } }