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
|
#ifndef Spine_Skin_h
|
||||||
#define Spine_Skin_h
|
#define Spine_Skin_h
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace Spine
|
namespace Spine
|
||||||
{
|
{
|
||||||
|
class Attachment;
|
||||||
|
class Skeleton;
|
||||||
|
|
||||||
|
class AttachmentKey;
|
||||||
|
|
||||||
/// Stores attachments by slot index and attachment name.
|
/// Stores attachments by slot index and attachment name.
|
||||||
/// See SkeletonData::getDefaultSkin, Skeleton::getSkin, and
|
/// See SkeletonData::getDefaultSkin, Skeleton::getSkin, and
|
||||||
/// http://esotericsoftware.com/spine-runtime-skins in the Spine Runtimes Guide.
|
/// http://esotericsoftware.com/spine-runtime-skins in the Spine Runtimes Guide.
|
||||||
class Skin
|
class Skin
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
public std::string Name { get { return name; } }
|
Skin(std::string name);
|
||||||
public Dictionary<AttachmentKeyTuple, Attachment> Attachments { get { return attachments; } }
|
|
||||||
|
|
||||||
public Skin (std::string name) {
|
/// Adds an attachment to the skin for the specified slot index and name.
|
||||||
if (name == null) throw new ArgumentNullException("name", "name cannot be null.");
|
/// If the name already exists for the slot, the previous value is replaced.
|
||||||
this.name = name;
|
void addAttachment(int slotIndex, std::string name, Attachment* 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.
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the attachment for the specified slot index and name, or null.
|
/// Returns the attachment for the specified slot index and name, or null.
|
||||||
/// <returns>May be null.</returns>
|
Attachment* getAttachment(int slotIndex, std::string name);
|
||||||
public Attachment GetAttachment (int slotIndex, std::string name) {
|
|
||||||
Attachment attachment;
|
|
||||||
attachments.TryGetValue(new AttachmentKeyTuple(slotIndex, name), out attachment);
|
|
||||||
return attachment;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finds the skin keys for a given slot. The results are added to the passed List(names).
|
/// Finds the skin keys for a given slot. The results are added to the passed vector 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 slotIndex The target slotIndex. To find the slot index, use Skeleton::findSlotIndex or SkeletonData::findSlotIndex
|
||||||
/// <param name="names">Found skin key names will be added to this list.</param>
|
/// @param names Found skin key names will be added to this vector.
|
||||||
public void FindNamesForSlot (int slotIndex, List<std::string> names) {
|
void findNamesForSlot(int slotIndex, std::vector<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 attachments for a given slot. The results are added to the passed List(Attachment).
|
/// 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 slotIndex The target slotIndex. To find the slot index, use Skeleton::findSlotIndex or SkeletonData::findSlotIndex
|
||||||
/// <param name="attachments">Found Attachments will be added to this list.</param>
|
/// @param attachments Found Attachments will be added to this vector.
|
||||||
public void FindAttachmentsForSlot (int slotIndex, List<Attachment> attachments) {
|
void findAttachmentsForSlot(int slotIndex, std::vector<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);
|
|
||||||
}
|
|
||||||
|
|
||||||
override public std::string ToString () {
|
const std::string& getName();
|
||||||
return name;
|
std::unordered_map<AttachmentKey, Attachment*>& getAttachments();
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
internal std::string name;
|
const std::string _name;
|
||||||
Dictionary<AttachmentKeyTuple, Attachment> attachments = new Dictionary<AttachmentKeyTuple, Attachment>(AttachmentKeyTupleComparer.Instance);
|
std::unordered_map<AttachmentKey, Attachment*> _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.
|
||||||
internal void AttachAll (Skeleton skeleton, Skin oldSkin) {
|
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 {
|
class AttachmentKey
|
||||||
public readonly int slotIndex;
|
{
|
||||||
public readonly std::string name;
|
public:
|
||||||
internal readonly int nameHashCode;
|
const int _slotIndex;
|
||||||
|
const std::string _name;
|
||||||
|
|
||||||
public AttachmentKeyTuple (int slotIndex, std::string name) {
|
AttachmentKey(int slotIndex, std::string name);
|
||||||
this.slotIndex = slotIndex;
|
|
||||||
this.name = name;
|
|
||||||
nameHashCode = this.name.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Avoids boxing in the dictionary.
|
bool operator==(const AttachmentKey &other) const;
|
||||||
class AttachmentKeyTupleComparer : IEqualityComparer<AttachmentKeyTuple> {
|
};
|
||||||
internal static readonly AttachmentKeyTupleComparer Instance = new AttachmentKeyTupleComparer();
|
|
||||||
|
|
||||||
bool IEqualityComparer<AttachmentKeyTuple>.Equals (AttachmentKeyTuple o1, AttachmentKeyTuple o2) {
|
friend std::ostream& operator <<(std::ostream& os, const Skin& ref);
|
||||||
return o1.slotIndex == o2.slotIndex && o1.nameHashCode == o2.nameHashCode && o1.name == o2.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
int IEqualityComparer<AttachmentKeyTuple>.GetHashCode (AttachmentKeyTuple o) {
|
namespace std
|
||||||
return o.slotIndex;
|
{
|
||||||
|
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.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <spine/Skin.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
namespace Spine
|
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