Stephen Gowen 8 anos atrás
pai
commit
08af18e86e

+ 50 - 69
spine-cpp/spine-cpp/include/spine/Skin.h

@@ -31,97 +31,78 @@
 #ifndef Spine_Skin_h
 #define Spine_Skin_h
 
+#include <string>
+#include <vector>
+#include <unordered_map>
+
 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<AttachmentKeyTuple, Attachment> Attachments { get { return attachments; } }
-        
-        public Skin (std::string name) {
-            if (name == null) throw new ArgumentNullException("name", "name cannot be null.");
-            this.name = name;
-        }
+        Skin(std::string 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.
-        /// <returns>May be null.</returns>
-        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).
-        /// <param name="slotIndex">The target slotIndex. To find the slot index, use <see cref="Spine.Skeleton.FindSlotIndex"/> or <see cref="Spine.SkeletonData.FindSlotIndex"/>
-        /// <param name="names">Found skin key names will be added to this list.</param>
-        public void FindNamesForSlot (int slotIndex, List<std::string> 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<std::string>& names);
         
         /// Finds the attachments for a given slot. The results are added to the passed List(Attachment).
-        /// <param name="slotIndex">The target slotIndex. To find the slot index, use <see cref="Spine.Skeleton.FindSlotIndex"/> or <see cref="Spine.SkeletonData.FindSlotIndex"/>
-        /// <param name="attachments">Found Attachments will be added to this list.</param>
-        public void FindAttachmentsForSlot (int slotIndex, List<Attachment> attachments) {
-            if (attachments == null) throw new ArgumentNullException("attachments", "attachments cannot be null.");
-            foreach (KeyValuePair<AttachmentKeyTuple, Attachment> 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<Attachment*>& attachments);
         
-        override public std::string ToString () {
-            return name;
-        }
+        const std::string& getName();
+        std::unordered_map<AttachmentKey, Attachment*>& getAttachments();
         
     private:
-        internal std::string name;
-        Dictionary<AttachmentKeyTuple, Attachment> attachments = new Dictionary<AttachmentKeyTuple, Attachment>(AttachmentKeyTupleComparer.Instance);
+        const std::string _name;
+        std::unordered_map<AttachmentKey, Attachment*> _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<AttachmentKeyTuple, Attachment> 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;
-                }
-            }
-        }
-        
-        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();
-            }
-        }
+        void attachAll(Skeleton& skeleton, Skin& oldSkin);
         
-        // Avoids boxing in the dictionary.
-        class AttachmentKeyTupleComparer : IEqualityComparer<AttachmentKeyTuple> {
-            internal static readonly AttachmentKeyTupleComparer Instance = new AttachmentKeyTupleComparer();
+        class AttachmentKey
+        {
+        public:
+            const int _slotIndex;
+            const std::string _name;
             
-            bool IEqualityComparer<AttachmentKeyTuple>.Equals (AttachmentKeyTuple o1, AttachmentKeyTuple o2) {
-                return o1.slotIndex == o2.slotIndex && o1.nameHashCode == o2.nameHashCode && o1.name == o2.name;
-            }
+            AttachmentKey(int slotIndex, std::string name);
             
-            int IEqualityComparer<AttachmentKeyTuple>.GetHashCode (AttachmentKeyTuple o) {
-                return o.slotIndex;
-            }
+            bool operator==(const AttachmentKey &other) const;
+        };
+        
+        friend std::ostream& operator <<(std::ostream& os, const Skin& ref);
+        
+        namespace std
+        {
+            template <>
+            struct hash<AttachmentKey>
+            {
+                size_t operator()(const AttachmentKey& val) const
+                {
+                    size_t h1 = hash<int>{}(val._slotIndex);
+                    size_t h2 = hash<string>{}(val._name);
+                    
+                    return h1 ^ (h2 << 1);
+                }
+            };
         }
     };
 }

+ 101 - 1
spine-cpp/spine-cpp/src/spine/Skin.cpp

@@ -28,7 +28,107 @@
 * POSSIBILITY OF SUCH DAMAGE.
 *****************************************************************************/
 
+#include <spine/Skin.h>
+
+#include <assert.h>
+
 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<AttachmentKey, Attachment*> 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<std::string>& 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<Attachment*>& attachments)
+    {
+        foreach (KeyValuePair<AttachmentKey, Attachment> entry in this.attachments)
+        if (entry.Key.slotIndex == slotIndex) attachments.Add(entry.Value);
+    }
+    
+    const std::string& Skin::getName()
+    {
+        //
+    }
+    
+    std::unordered_map<AttachmentKey, Attachment*>& Skin::getAttachments()
+    {
+        //
+    }
+    
+    void Skin::attachAll(Skeleton& skeleton, Skin& oldSkin)
+    {
+        foreach (KeyValuePair<AttachmentKey, Attachment> 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;
+    }
 }