mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 17:56:04 +08:00
wip
This commit is contained in:
parent
d173aa7e7d
commit
08af18e86e
@ -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; } }
|
||||
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.
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
}
|
||||
void attachAll(Skeleton& skeleton, Skin& oldSkin);
|
||||
|
||||
public struct AttachmentKeyTuple {
|
||||
public readonly int slotIndex;
|
||||
public readonly std::string name;
|
||||
internal readonly int nameHashCode;
|
||||
class AttachmentKey
|
||||
{
|
||||
public:
|
||||
const int _slotIndex;
|
||||
const std::string _name;
|
||||
|
||||
public AttachmentKeyTuple (int slotIndex, std::string name) {
|
||||
this.slotIndex = slotIndex;
|
||||
this.name = name;
|
||||
nameHashCode = this.name.GetHashCode();
|
||||
}
|
||||
}
|
||||
AttachmentKey(int slotIndex, std::string name);
|
||||
|
||||
// Avoids boxing in the dictionary.
|
||||
class AttachmentKeyTupleComparer : IEqualityComparer<AttachmentKeyTuple> {
|
||||
internal static readonly AttachmentKeyTupleComparer Instance = new AttachmentKeyTupleComparer();
|
||||
bool operator==(const AttachmentKey &other) const;
|
||||
};
|
||||
|
||||
bool IEqualityComparer<AttachmentKeyTuple>.Equals (AttachmentKeyTuple o1, AttachmentKeyTuple o2) {
|
||||
return o1.slotIndex == o2.slotIndex && o1.nameHashCode == o2.nameHashCode && o1.name == o2.name;
|
||||
}
|
||||
friend std::ostream& operator <<(std::ostream& os, const Skin& ref);
|
||||
|
||||
int IEqualityComparer<AttachmentKeyTuple>.GetHashCode (AttachmentKeyTuple o) {
|
||||
return o.slotIndex;
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user