mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-20 17:26:01 +08:00
Merge branch '3.8' into 3.9-beta
This commit is contained in:
commit
312f7a8828
@ -183,6 +183,7 @@
|
||||
* Renamed `Slot.AttachmentVertices` to `Slot.Deform`.
|
||||
* Changed the `.json` curve format and added more assumptions for omitted values, reducing the average size of JSON exports.
|
||||
* Renamed `Skin.AddAttachment()` to `Skin.SetAttachment()`.
|
||||
* Removed `FindAttachmentsForSlot(int slotIndex, List<Attachment> attachments)` and `FindNamesForSlot (int slotIndex, List<string> names)` and replaced it with `Skin.GetAttachments(int slotIndex, List<SkinEntry> attachments)` which returns the combined `SkinEntry` object holding both name and attachment.
|
||||
* Removed `VertexAttachment.ApplyDeform()` and replaced it with `VertexAttachment.DeformAttachment`. The attachment set on this field is used to decide if a `DeformTimeline` should be applied to the attachment active on the slot to which the timeline is applied.
|
||||
* Removed `inheritDeform` field, getter, and setter from `MeshAttachment`.
|
||||
* Changed `.skel` binary format, added a string table. References to strings in the data resolve to this string table, reducing storage size of binary files considerably.
|
||||
@ -194,7 +195,7 @@
|
||||
* Added skin-specific bones and constraints which are only updated if the skeleton's current skin contains them.
|
||||
* Improved Skin API to make it easier to handle mix-and-match use cases.
|
||||
* Added `Skin.GetAttachments()`. Returns all attachments in the skin.
|
||||
* Added `Skin.GetAttachments(int slotIndex, List<SkinEntry> attachments)`. Returns all attachements in the skin for the given slot index.
|
||||
* Added `Skin.GetAttachments(int slotIndex, List<SkinEntry> attachments)`. Returns all attachements in the skin for the given slot index. This method replaces `FindAttachmentsForSlot` and `FindNamesForSlot`.
|
||||
* Added `Skin.AddSkin(Skin skin)`. Adds all attachments, bones, and skins from the specified skin to this skin.
|
||||
* Added `Skin.CopySkin(Skin skin)`. Adds all attachments, bones, and skins from the specified skin to this skin. `VertexAttachment` are shallowly copied and will retain any parent mesh relationship. All other attachment types are deep copied.
|
||||
* Added `Attachment.Copy()` to all attachment type implementations. This lets you deep copy an attachment to modify it independently from the original, i.e. when programmatically changing texture coordinates or mesh vertices.
|
||||
|
||||
@ -1071,6 +1071,7 @@ void AnimationState::computeNotLast(TrackEntry *entry) {
|
||||
AttachmentTimeline *timeline = static_cast<AttachmentTimeline *>(timelines[i]);
|
||||
if (!_propertyIDs.contains(timeline->getSlotIndex())) {
|
||||
_propertyIDs.add(timeline->getSlotIndex());
|
||||
} else {
|
||||
timelineMode[i] |= NotLast;
|
||||
}
|
||||
}
|
||||
|
||||
631
spine-csharp/src/Collections/OrderedDictionary.cs
Normal file
631
spine-csharp/src/Collections/OrderedDictionary.cs
Normal file
@ -0,0 +1,631 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated May 1, 2019. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
/******************************************************************************
|
||||
* Thanks to Travis Parks
|
||||
* https://github.com/jehugaleahsa/truncon.collections.OrderedDictionary
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace Spine.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a dictionary that tracks the order that items were added.
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">The type of the dictionary keys.</typeparam>
|
||||
/// <typeparam name="TValue">The type of the dictionary values.</typeparam>
|
||||
/// <remarks>
|
||||
/// This dictionary makes it possible to get the index of a key and a key based on an index.
|
||||
/// It can be costly to find the index of a key because it must be searched for linearly.
|
||||
/// It can be costly to insert a key/value pair because other key's indexes must be adjusted.
|
||||
/// It can be costly to remove a key/value pair because other keys' indexes must be adjusted.
|
||||
/// </remarks>
|
||||
[DebuggerDisplay("Count = {Count}")]
|
||||
[DebuggerTypeProxy(typeof(OrderedDictionaryDebugView<,>))]
|
||||
public sealed class OrderedDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IList<KeyValuePair<TKey, TValue>>
|
||||
{
|
||||
private readonly Dictionary<TKey, int> dictionary;
|
||||
private readonly List<TKey> keys;
|
||||
private readonly List<TValue> values;
|
||||
private int version;
|
||||
|
||||
private const string CollectionModifiedMessage = "Collection was modified; enumeration operation may not execute.";
|
||||
private const string EditReadOnlyListMessage = "An attempt was made to edit a read-only list.";
|
||||
private const string IndexOutOfRangeMessage = "The index is negative or outside the bounds of the collection.";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an OrderedDictionary.
|
||||
/// </summary>
|
||||
public OrderedDictionary ()
|
||||
: this(0, null) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an OrderedDictionary.
|
||||
/// </summary>
|
||||
/// <param name="capacity">The initial capacity of the dictionary.</param>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">The capacity is less than zero.</exception>
|
||||
public OrderedDictionary (int capacity)
|
||||
: this(capacity, null) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an OrderedDictionary.
|
||||
/// </summary>
|
||||
/// <param name="comparer">The equality comparer to use to compare keys.</param>
|
||||
public OrderedDictionary (IEqualityComparer<TKey> comparer)
|
||||
: this(0, comparer) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an OrderedDictionary.
|
||||
/// </summary>
|
||||
/// <param name="capacity">The initial capacity of the dictionary.</param>
|
||||
/// <param name="comparer">The equality comparer to use to compare keys.</param>
|
||||
public OrderedDictionary (int capacity, IEqualityComparer<TKey> comparer) {
|
||||
dictionary = new Dictionary<TKey, int>(capacity, comparer ?? EqualityComparer<TKey>.Default);
|
||||
keys = new List<TKey>(capacity);
|
||||
values = new List<TValue>(capacity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the equality comparer used to compare keys.
|
||||
/// </summary>
|
||||
public IEqualityComparer<TKey> Comparer {
|
||||
get {
|
||||
return dictionary.Comparer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given key/value pair to the dictionary.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to add to the dictionary.</param>
|
||||
/// <param name="value">The value to associated with the key.</param>
|
||||
/// <exception cref="System.ArgumentException">The given key already exists in the dictionary.</exception>
|
||||
/// <exception cref="System.ArgumentNullException">The key is null.</exception>
|
||||
public void Add (TKey key, TValue value) {
|
||||
dictionary.Add(key, values.Count);
|
||||
keys.Add(key);
|
||||
values.Add(value);
|
||||
++version;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts the given key/value pair at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index to insert the key/value pair.</param>
|
||||
/// <param name="key">The key to insert.</param>
|
||||
/// <param name="value">The value to insert.</param>
|
||||
/// <exception cref="System.ArgumentException">The given key already exists in the dictionary.</exception>
|
||||
/// <exception cref="System.ArgumentNullException">The key is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">The index is negative -or- larger than the size of the dictionary.</exception>
|
||||
public void Insert (int index, TKey key, TValue value) {
|
||||
if (index < 0 || index > values.Count) {
|
||||
throw new ArgumentOutOfRangeException("index", index, IndexOutOfRangeMessage);
|
||||
}
|
||||
dictionary.Add(key, index);
|
||||
for (int keyIndex = index; keyIndex != keys.Count; ++keyIndex) {
|
||||
var otherKey = keys[keyIndex];
|
||||
dictionary[otherKey] += 1;
|
||||
}
|
||||
keys.Insert(index, key);
|
||||
values.Insert(index, value);
|
||||
++version;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given key exists in the dictionary.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to look for.</param>
|
||||
/// <returns>True if the key exists in the dictionary; otherwise, false.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">The key is null.</exception>
|
||||
public bool ContainsKey (TKey key) {
|
||||
return dictionary.ContainsKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key at the given index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the key to get.</param>
|
||||
/// <returns>The key at the given index.</returns>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">The index is negative -or- larger than the number of keys.</exception>
|
||||
public TKey GetKey (int index) {
|
||||
return keys[index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index of the given key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to get the index of.</param>
|
||||
/// <returns>The index of the key in the dictionary -or- -1 if the key is not found.</returns>
|
||||
/// <remarks>The operation runs in O(n).</remarks>
|
||||
public int IndexOf (TKey key) {
|
||||
int index;
|
||||
if (dictionary.TryGetValue(key, out index)) {
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the keys in the dictionary in the order they were added.
|
||||
/// </summary>
|
||||
public KeyCollection Keys {
|
||||
get {
|
||||
return new KeyCollection(this.dictionary);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the key/value pair with the given key from the dictionary.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the pair to remove.</param>
|
||||
/// <returns>True if the key was found and the pair removed; otherwise, false.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">The key is null.</exception>
|
||||
public bool Remove (TKey key) {
|
||||
int index;
|
||||
if (dictionary.TryGetValue(key, out index)) {
|
||||
RemoveAt(index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the key/value pair at the given index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the key/value pair to remove.</param>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">The index is negative -or- larger than the size of the dictionary.</exception>
|
||||
public void RemoveAt (int index) {
|
||||
var key = keys[index];
|
||||
for (int keyIndex = index + 1; keyIndex < keys.Count; ++keyIndex) {
|
||||
var otherKey = keys[keyIndex];
|
||||
dictionary[otherKey] -= 1;
|
||||
}
|
||||
dictionary.Remove(key);
|
||||
keys.RemoveAt(index);
|
||||
values.RemoveAt(index);
|
||||
++version;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get the value associated with the given key. If the key is not found,
|
||||
/// default(TValue) value is stored in the value.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to get the value for.</param>
|
||||
/// <param name="value">The value used to hold the results.</param>
|
||||
/// <returns>True if the key was found; otherwise, false.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">The key is null.</exception>
|
||||
public bool TryGetValue (TKey key, out TValue value) {
|
||||
int index;
|
||||
if (dictionary.TryGetValue(key, out index)) {
|
||||
value = values[index];
|
||||
return true;
|
||||
}
|
||||
value = default(TValue);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values in the dictionary.
|
||||
/// </summary>
|
||||
public ValueCollection Values {
|
||||
get {
|
||||
return new ValueCollection(values);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at the given index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the value to get.</param>
|
||||
/// <returns>The value at the given index.</returns>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">The index is negative -or- beyond the length of the dictionary.</exception>
|
||||
public TValue this[int index] {
|
||||
get {
|
||||
return values[index];
|
||||
}
|
||||
|
||||
set {
|
||||
values[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value associated with the given key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to get the associated value by or to associate with the value.</param>
|
||||
/// <returns>The value associated with the given key.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">The key is null.</exception>
|
||||
/// <exception cref="System.Collections.Generic.KeyNotFoundException">The key is not in the dictionary.</exception>
|
||||
public TValue this[TKey key] {
|
||||
get {
|
||||
return values[dictionary[key]];
|
||||
}
|
||||
set {
|
||||
int index;
|
||||
if (dictionary.TryGetValue(key, out index)) {
|
||||
values[index] = value;
|
||||
}
|
||||
else {
|
||||
Add(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all key/value pairs from the dictionary.
|
||||
/// </summary>
|
||||
public void Clear () {
|
||||
dictionary.Clear();
|
||||
keys.Clear();
|
||||
values.Clear();
|
||||
++version;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of key/value pairs in the dictionary.
|
||||
/// </summary>
|
||||
public int Count {
|
||||
get {
|
||||
return dictionary.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key/value pairs in the dictionary in the order they were added.
|
||||
/// </summary>
|
||||
/// <returns>An enumerator over the key/value pairs in the dictionary.</returns>
|
||||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator () {
|
||||
int startVersion = version;
|
||||
for (int index = 0; index != keys.Count; ++index) {
|
||||
var key = keys[index];
|
||||
var value = values[index];
|
||||
yield return new KeyValuePair<TKey, TValue>(key, value);
|
||||
if (version != startVersion) {
|
||||
throw new InvalidOperationException(CollectionModifiedMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int IList<KeyValuePair<TKey, TValue>>.IndexOf (KeyValuePair<TKey, TValue> item) {
|
||||
int index;
|
||||
if (dictionary.TryGetValue(item.Key, out index) && Equals(values[index], item.Value)) {
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void IList<KeyValuePair<TKey, TValue>>.Insert (int index, KeyValuePair<TKey, TValue> item) {
|
||||
Insert(index, item.Key, item.Value);
|
||||
}
|
||||
|
||||
KeyValuePair<TKey, TValue> IList<KeyValuePair<TKey, TValue>>.this[int index] {
|
||||
get {
|
||||
TKey key = keys[index];
|
||||
TValue value = values[index];
|
||||
return new KeyValuePair<TKey, TValue>(key, value);
|
||||
}
|
||||
set {
|
||||
TKey key = keys[index];
|
||||
if (dictionary.Comparer.Equals(key, value.Key)) {
|
||||
dictionary[value.Key] = index;
|
||||
}
|
||||
else {
|
||||
dictionary.Add(value.Key, index); // will throw if key already exists
|
||||
dictionary.Remove(key);
|
||||
}
|
||||
keys[index] = value.Key;
|
||||
values[index] = value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
ICollection<TKey> IDictionary<TKey, TValue>.Keys {
|
||||
get {
|
||||
return Keys;
|
||||
}
|
||||
}
|
||||
|
||||
ICollection<TValue> IDictionary<TKey, TValue>.Values {
|
||||
get {
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.Add (KeyValuePair<TKey, TValue> item) {
|
||||
Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Contains (KeyValuePair<TKey, TValue> item) {
|
||||
int index;
|
||||
if (dictionary.TryGetValue(item.Key, out index) && Equals(values[index], item.Value)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo (KeyValuePair<TKey, TValue>[] array, int arrayIndex) {
|
||||
if (array == null) {
|
||||
throw new ArgumentNullException("array");
|
||||
}
|
||||
if (arrayIndex < 0) {
|
||||
throw new ArgumentOutOfRangeException("arrayIndex", arrayIndex, IndexOutOfRangeMessage);
|
||||
}
|
||||
for (int index = 0; index != keys.Count && arrayIndex < array.Length; ++index, ++arrayIndex) {
|
||||
var key = keys[index];
|
||||
var value = values[index];
|
||||
array[arrayIndex] = new KeyValuePair<TKey, TValue>(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly {
|
||||
get {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Remove (KeyValuePair<TKey, TValue> item) {
|
||||
ICollection<KeyValuePair<TKey, TValue>> self = this;
|
||||
if (self.Contains(item)) {
|
||||
return Remove(item.Key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator () {
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the keys in an OrderDictionary.
|
||||
/// </summary>
|
||||
public sealed class KeyCollection : ICollection<TKey>
|
||||
{
|
||||
private readonly Dictionary<TKey, int> dictionary;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a KeyCollection.
|
||||
/// </summary>
|
||||
/// <param name="dictionary">The OrderedDictionary whose keys to wrap.</param>
|
||||
/// <exception cref="System.ArgumentNullException">The dictionary is null.</exception>
|
||||
internal KeyCollection (Dictionary<TKey, int> dictionary) {
|
||||
this.dictionary = dictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the keys from the OrderedDictionary to the given array, starting at the given index.
|
||||
/// </summary>
|
||||
/// <param name="array">The array to copy the keys to.</param>
|
||||
/// <param name="arrayIndex">The index into the array to start copying the keys.</param>
|
||||
/// <exception cref="System.ArgumentNullException">The array is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">The arrayIndex is negative.</exception>
|
||||
/// <exception cref="System.ArgumentException">The array, starting at the given index, is not large enough to contain all the keys.</exception>
|
||||
public void CopyTo (TKey[] array, int arrayIndex) {
|
||||
dictionary.Keys.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of keys in the OrderedDictionary.
|
||||
/// </summary>
|
||||
public int Count {
|
||||
get {
|
||||
return dictionary.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an enumerator over the keys in the OrderedDictionary.
|
||||
/// </summary>
|
||||
/// <returns>The enumerator.</returns>
|
||||
public IEnumerator<TKey> GetEnumerator () {
|
||||
return dictionary.Keys.GetEnumerator();
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
bool ICollection<TKey>.Contains (TKey item) {
|
||||
return dictionary.ContainsKey(item);
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void ICollection<TKey>.Add (TKey item) {
|
||||
throw new NotSupportedException(EditReadOnlyListMessage);
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void ICollection<TKey>.Clear () {
|
||||
throw new NotSupportedException(EditReadOnlyListMessage);
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
bool ICollection<TKey>.IsReadOnly {
|
||||
get {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
bool ICollection<TKey>.Remove (TKey item) {
|
||||
throw new NotSupportedException(EditReadOnlyListMessage);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator () {
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the keys in an OrderDictionary.
|
||||
/// </summary>
|
||||
public sealed class ValueCollection : ICollection<TValue>
|
||||
{
|
||||
private readonly List<TValue> values;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a ValueCollection.
|
||||
/// </summary>
|
||||
/// <param name="values">The OrderedDictionary whose keys to wrap.</param>
|
||||
/// <exception cref="System.ArgumentNullException">The dictionary is null.</exception>
|
||||
internal ValueCollection (List<TValue> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the values from the OrderedDictionary to the given array, starting at the given index.
|
||||
/// </summary>
|
||||
/// <param name="array">The array to copy the values to.</param>
|
||||
/// <param name="arrayIndex">The index into the array to start copying the values.</param>
|
||||
/// <exception cref="System.ArgumentNullException">The array is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">The arrayIndex is negative.</exception>
|
||||
/// <exception cref="System.ArgumentException">The array, starting at the given index, is not large enough to contain all the values.</exception>
|
||||
public void CopyTo (TValue[] array, int arrayIndex) {
|
||||
values.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of values in the OrderedDictionary.
|
||||
/// </summary>
|
||||
public int Count {
|
||||
get {
|
||||
return values.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an enumerator over the values in the OrderedDictionary.
|
||||
/// </summary>
|
||||
/// <returns>The enumerator.</returns>
|
||||
public IEnumerator<TValue> GetEnumerator () {
|
||||
return values.GetEnumerator();
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
bool ICollection<TValue>.Contains (TValue item) {
|
||||
return values.Contains(item);
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void ICollection<TValue>.Add (TValue item) {
|
||||
throw new NotSupportedException(EditReadOnlyListMessage);
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void ICollection<TValue>.Clear () {
|
||||
throw new NotSupportedException(EditReadOnlyListMessage);
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
bool ICollection<TValue>.IsReadOnly {
|
||||
get {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
bool ICollection<TValue>.Remove (TValue item) {
|
||||
throw new NotSupportedException(EditReadOnlyListMessage);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator () {
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class OrderedDictionaryDebugView<TKey, TValue>
|
||||
{
|
||||
private readonly OrderedDictionary<TKey, TValue> dictionary;
|
||||
|
||||
public OrderedDictionaryDebugView (OrderedDictionary<TKey, TValue> dictionary) {
|
||||
this.dictionary = dictionary;
|
||||
}
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public KeyValuePair<TKey, TValue>[] Items {
|
||||
get {
|
||||
return dictionary.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides extensions methods for constructing instances of <see cref="OrderedDictionary{TKey, TValue}"/>.
|
||||
/// </summary>
|
||||
public static class CollectionExtensions
|
||||
{
|
||||
#region ToOrderedDictionary
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new OrderedDictionary from the given collection, using the key selector to extract the key.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The type of the items in the collection.</typeparam>
|
||||
/// <typeparam name="TKey">The type of the key.</typeparam>
|
||||
/// <param name="source">The items to created the OrderedDictionary from.</param>
|
||||
/// <param name="keySelector">A delegate that can extract a key from an item in the collection.</param>
|
||||
/// <returns>An OrderedDictionary mapping the extracted keys to their values.</returns>
|
||||
public static OrderedDictionary<TKey, TSource> ToOrderedDictionary<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) {
|
||||
return ToOrderedDictionary(source, keySelector, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new OrderedDictionary from the given collection, using the key selector to extract the key.
|
||||
/// The key comparer is passed to the OrderedDictionary for comparing the extracted keys.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The type of the items in the collection.</typeparam>
|
||||
/// <typeparam name="TKey">The type of the key.</typeparam>
|
||||
/// <param name="source">The items to created the OrderedDictionary from.</param>
|
||||
/// <param name="keySelector">A delegate that can extract a key from an item in the collection.</param>
|
||||
/// <param name="comparer">The key equality comparer to use to compare keys in the dictionary.</param>
|
||||
/// <returns>An OrderedDictionary mapping the extracted keys to their values.</returns>
|
||||
public static OrderedDictionary<TKey, TSource> ToOrderedDictionary<TSource, TKey> (
|
||||
this IEnumerable<TSource> source,
|
||||
Func<TSource, TKey> keySelector,
|
||||
IEqualityComparer<TKey> comparer) {
|
||||
if (source == null) {
|
||||
throw new ArgumentNullException("source");
|
||||
}
|
||||
if (keySelector == null) {
|
||||
throw new ArgumentNullException("keySelector");
|
||||
}
|
||||
var dictionary = new OrderedDictionary<TKey, TSource>(comparer);
|
||||
foreach (TSource item in source) {
|
||||
TKey key = keySelector(item);
|
||||
dictionary.Add(key, item);
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -328,7 +328,7 @@ namespace Spine {
|
||||
if (defaultSkin) {
|
||||
slotCount = input.ReadInt(true);
|
||||
if (slotCount == 0) return null;
|
||||
skin = new Skin("default"));
|
||||
skin = new Skin("default");
|
||||
} else {
|
||||
skin = new Skin(input.ReadStringRef());
|
||||
Object[] bones = skin.bones.Resize(input.ReadInt(true)).Items;
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using Spine.Collections;
|
||||
|
||||
namespace Spine {
|
||||
/// <summary>Stores attachments by slot index and attachment name.
|
||||
@ -39,12 +39,12 @@ namespace Spine {
|
||||
/// </summary>
|
||||
public class Skin {
|
||||
internal string name;
|
||||
private OrderedDictionary attachments = new OrderedDictionary(SkinEntryComparer.Instance); // contains <SkinEntry, Attachment>
|
||||
private OrderedDictionary<SkinEntry, Attachment> attachments = new OrderedDictionary<SkinEntry, Attachment>(SkinEntryComparer.Instance);
|
||||
internal readonly ExposedList<BoneData> bones = new ExposedList<BoneData>();
|
||||
internal readonly ExposedList<ConstraintData> constraints = new ExposedList<ConstraintData>();
|
||||
|
||||
public string Name { get { return name; } }
|
||||
public OrderedDictionary Attachments { get { return attachments; } }
|
||||
public OrderedDictionary<SkinEntry, Attachment> Attachments { get { return attachments; } }
|
||||
public ExposedList<BoneData> Bones { get { return bones; } }
|
||||
public ExposedList<ConstraintData> Constraints { get { return constraints; } }
|
||||
|
||||
@ -94,8 +94,9 @@ namespace Spine {
|
||||
/// <returns>May be null.</returns>
|
||||
public Attachment GetAttachment (int slotIndex, string name) {
|
||||
var lookup = new SkinEntry(slotIndex, name, null);
|
||||
var obj = attachments[lookup];
|
||||
return (obj == null) ? null : (Attachment)obj;
|
||||
Attachment attachment = null;
|
||||
bool containsKey = attachments.TryGetValue(lookup, out attachment);
|
||||
return containsKey ? attachment : null;
|
||||
}
|
||||
|
||||
/// <summary> Removes the attachment in the skin for the specified slot index and name, if any.</summary>
|
||||
@ -106,11 +107,8 @@ namespace Spine {
|
||||
}
|
||||
|
||||
///<summary>Returns all attachments contained in this skin.</summary>
|
||||
public List<SkinEntry> GetAttachments () {
|
||||
List<SkinEntry> entries = new List<SkinEntry>();
|
||||
foreach (SkinEntry entry in this.attachments.Keys)
|
||||
entries.Add(entry);
|
||||
return entries;
|
||||
public ICollection<SkinEntry> GetAttachments () {
|
||||
return this.attachments.Keys;
|
||||
}
|
||||
|
||||
/// <summary>Returns all attachments in this skin for the specified slot index.</summary>
|
||||
@ -178,19 +176,16 @@ namespace Spine {
|
||||
}
|
||||
|
||||
// Avoids boxing in the dictionary and is necessary to omit entry.attachment in the comparison.
|
||||
class SkinEntryComparer : IEqualityComparer {
|
||||
class SkinEntryComparer : IEqualityComparer<SkinEntry> {
|
||||
internal static readonly SkinEntryComparer Instance = new SkinEntryComparer();
|
||||
|
||||
bool IEqualityComparer.Equals (object o1, object o2) {
|
||||
var e1 = (SkinEntry)o1;
|
||||
var e2 = (SkinEntry)o2;
|
||||
bool IEqualityComparer<SkinEntry>.Equals (SkinEntry e1, SkinEntry e2) {
|
||||
if (e1.SlotIndex != e2.SlotIndex) return false;
|
||||
if (!string.Equals(e1.Name, e2.Name, StringComparison.Ordinal)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int IEqualityComparer.GetHashCode (object o) {
|
||||
var e = (SkinEntry)o;
|
||||
int IEqualityComparer<SkinEntry>.GetHashCode (SkinEntry e) {
|
||||
return e.Name.GetHashCode() + e.SlotIndex * 37;
|
||||
}
|
||||
}
|
||||
|
||||
@ -484,49 +484,32 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
}
|
||||
|
||||
var slotAttachments = new List<Attachment>();
|
||||
var slotAttachmentNames = new List<string>();
|
||||
var defaultSkinAttachmentNames = new List<string>();
|
||||
var slotAttachments = new List<Skin.SkinEntry>();
|
||||
var defaultSkinAttachments = new List<Skin.SkinEntry>();
|
||||
var slotsItems = preview.Skeleton.Slots.Items;
|
||||
for (int i = preview.Skeleton.Slots.Count - 1; i >= 0; i--) {
|
||||
Slot slot = slotsItems[i];
|
||||
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(slot.Data.Name, Icons.slot));
|
||||
if (showAttachments) {
|
||||
slotAttachments.Clear();
|
||||
slotAttachmentNames.Clear();
|
||||
defaultSkinAttachmentNames.Clear();
|
||||
defaultSkinAttachments.Clear();
|
||||
|
||||
using (new SpineInspectorUtility.IndentScope()) {
|
||||
{
|
||||
var skinEntries = new List<Skin.SkinEntry>();
|
||||
skin.GetAttachments(i, skinEntries);
|
||||
foreach (var entry in skinEntries) {
|
||||
slotAttachments.Add(entry.Attachment);
|
||||
slotAttachmentNames.Add(entry.Name);
|
||||
}
|
||||
|
||||
skin.GetAttachments(i, slotAttachments);
|
||||
if (skin != defaultSkin) {
|
||||
skinEntries.Clear();
|
||||
defaultSkin.GetAttachments(i, skinEntries);
|
||||
foreach (var entry in skinEntries) {
|
||||
slotAttachments.Add(entry.Attachment);
|
||||
slotAttachmentNames.Add(entry.Name);
|
||||
defaultSkinAttachmentNames.Add(entry.Name);
|
||||
}
|
||||
|
||||
defaultSkin.GetAttachments(i, slotAttachments);
|
||||
defaultSkin.GetAttachments(i, defaultSkinAttachments);
|
||||
} else {
|
||||
skinEntries.Clear();
|
||||
defaultSkin.GetAttachments(i, skinEntries);
|
||||
foreach (var entry in skinEntries) {
|
||||
defaultSkinAttachmentNames.Add(entry.Name);
|
||||
}
|
||||
defaultSkin.GetAttachments(i, defaultSkinAttachments);
|
||||
}
|
||||
}
|
||||
|
||||
for (int a = 0; a < slotAttachments.Count; a++) {
|
||||
Attachment attachment = slotAttachments[a];
|
||||
string attachmentName = slotAttachmentNames[a];
|
||||
bool attachmentIsFromSkin = !defaultSkinAttachmentNames.Contains(attachmentName);
|
||||
var skinEntry = slotAttachments[a];
|
||||
Attachment attachment = skinEntry.Attachment;
|
||||
string attachmentName = skinEntry.Name;
|
||||
bool attachmentIsFromSkin = !defaultSkinAttachments.Contains(skinEntry);
|
||||
|
||||
Texture2D attachmentTypeIcon = Icons.GetAttachmentIcon(attachment);
|
||||
bool initialState = slot.Attachment == attachment;
|
||||
|
||||
@ -111,7 +111,7 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
|
||||
static void DrawPointsInSkin (Skin skin, Skeleton skeleton, Transform transform) {
|
||||
foreach (DictionaryEntry skinEntry in skin.Attachments) {
|
||||
foreach (var skinEntry in skin.Attachments) {
|
||||
var attachment = skinEntry.Value as PointAttachment;
|
||||
if (attachment != null) {
|
||||
var skinKey = (Skin.SkinEntry)skinEntry.Key;
|
||||
|
||||
@ -80,17 +80,13 @@ namespace Spine.Unity.Editor {
|
||||
for(int i = 0; i < slotCount; i++){
|
||||
Slot slot = skeletonUtility.skeletonRenderer.skeleton.Slots.Items[i];
|
||||
if (slot.Bone == utilityBone.bone) {
|
||||
var slotAttachments = new List<Attachment>();
|
||||
var skinEntries = new List<Skin.SkinEntry>();
|
||||
var slotAttachments = new List<Skin.SkinEntry>();
|
||||
int slotIndex = skeleton.FindSlotIndex(slot.Data.Name);
|
||||
skin.GetAttachments(slotIndex, skinEntries);
|
||||
foreach (var entry in skinEntries) {
|
||||
slotAttachments.Add(entry.Attachment);
|
||||
}
|
||||
skin.GetAttachments(slotIndex, slotAttachments);
|
||||
|
||||
var boundingBoxes = new List<BoundingBoxAttachment>();
|
||||
foreach (var att in slotAttachments) {
|
||||
var boundingBoxAttachment = att as BoundingBoxAttachment;
|
||||
var boundingBoxAttachment = att.Attachment as BoundingBoxAttachment;
|
||||
if (boundingBoxAttachment != null)
|
||||
boundingBoxes.Add(boundingBoxAttachment);
|
||||
}
|
||||
|
||||
@ -39,14 +39,6 @@
|
||||
#define NEW_PREFAB_SYSTEM
|
||||
#endif
|
||||
|
||||
#if UNITY_2018 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEWHIERARCHYWINDOWCALLBACKS
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFERENCES_SETTINGS_PROVIDER
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -43,10 +43,6 @@
|
||||
#define NEWHIERARCHYWINDOWCALLBACKS
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFERENCES_SETTINGS_PROVIDER
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -35,18 +35,6 @@
|
||||
#define NEWPLAYMODECALLBACKS
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFAB_SYSTEM
|
||||
#endif
|
||||
|
||||
#if UNITY_2018 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEWHIERARCHYWINDOWCALLBACKS
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFERENCES_SETTINGS_PROVIDER
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -31,22 +31,6 @@
|
||||
|
||||
#define SPINE_SKELETONMECANIM
|
||||
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
#define NEWPLAYMODECALLBACKS
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFAB_SYSTEM
|
||||
#endif
|
||||
|
||||
#if UNITY_2018 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEWHIERARCHYWINDOWCALLBACKS
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFERENCES_SETTINGS_PROVIDER
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -31,22 +31,6 @@
|
||||
|
||||
#define SPINE_SKELETONMECANIM
|
||||
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
#define NEWPLAYMODECALLBACKS
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFAB_SYSTEM
|
||||
#endif
|
||||
|
||||
#if UNITY_2018 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEWHIERARCHYWINDOWCALLBACKS
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFERENCES_SETTINGS_PROVIDER
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -39,10 +39,6 @@
|
||||
#define NEW_PREFAB_SYSTEM
|
||||
#endif
|
||||
|
||||
#if UNITY_2018 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEWHIERARCHYWINDOWCALLBACKS
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFERENCES_SETTINGS_PROVIDER
|
||||
#endif
|
||||
@ -139,6 +135,9 @@ namespace Spine.Unity.Editor {
|
||||
const string AUTO_RELOAD_SCENESKELETONS_KEY = "SPINE_AUTO_RELOAD_SCENESKELETONS";
|
||||
public static bool autoReloadSceneSkeletons = SpinePreferences.DEFAULT_AUTO_RELOAD_SCENESKELETONS;
|
||||
|
||||
const string MECANIM_EVENT_INCLUDE_FOLDERNAME_KEY = "SPINE_MECANIM_EVENT_INCLUDE_FOLDERNAME";
|
||||
public static bool mecanimEventIncludeFolderName = SpinePreferences.DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME;
|
||||
|
||||
static bool preferencesLoaded = false;
|
||||
|
||||
public static void Load () {
|
||||
@ -152,6 +151,7 @@ namespace Spine.Unity.Editor {
|
||||
showHierarchyIcons = EditorPrefs.GetBool(SHOW_HIERARCHY_ICONS_KEY, SpinePreferences.DEFAULT_SHOW_HIERARCHY_ICONS);
|
||||
setTextureImporterSettings = EditorPrefs.GetBool(SET_TEXTUREIMPORTER_SETTINGS_KEY, SpinePreferences.DEFAULT_SET_TEXTUREIMPORTER_SETTINGS);
|
||||
autoReloadSceneSkeletons = EditorPrefs.GetBool(AUTO_RELOAD_SCENESKELETONS_KEY, SpinePreferences.DEFAULT_AUTO_RELOAD_SCENESKELETONS);
|
||||
mecanimEventIncludeFolderName = EditorPrefs.GetBool(MECANIM_EVENT_INCLUDE_FOLDERNAME_KEY, SpinePreferences.DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME);
|
||||
atlasTxtImportWarning = EditorPrefs.GetBool(ATLASTXT_WARNING_KEY, SpinePreferences.DEFAULT_ATLASTXT_WARNING);
|
||||
textureImporterWarning = EditorPrefs.GetBool(TEXTUREIMPORTER_WARNING_KEY, SpinePreferences.DEFAULT_TEXTUREIMPORTER_WARNING);
|
||||
|
||||
@ -168,6 +168,7 @@ namespace Spine.Unity.Editor {
|
||||
newPreferences.showHierarchyIcons = EditorPrefs.GetBool(SHOW_HIERARCHY_ICONS_KEY, SpinePreferences.DEFAULT_SHOW_HIERARCHY_ICONS);
|
||||
newPreferences.setTextureImporterSettings = EditorPrefs.GetBool(SET_TEXTUREIMPORTER_SETTINGS_KEY, SpinePreferences.DEFAULT_SET_TEXTUREIMPORTER_SETTINGS);
|
||||
newPreferences.autoReloadSceneSkeletons = EditorPrefs.GetBool(AUTO_RELOAD_SCENESKELETONS_KEY, SpinePreferences.DEFAULT_AUTO_RELOAD_SCENESKELETONS);
|
||||
newPreferences.mecanimEventIncludeFolderName = EditorPrefs.GetBool(MECANIM_EVENT_INCLUDE_FOLDERNAME_KEY, SpinePreferences.DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME);
|
||||
newPreferences.atlasTxtImportWarning = EditorPrefs.GetBool(ATLASTXT_WARNING_KEY, SpinePreferences.DEFAULT_ATLASTXT_WARNING);
|
||||
newPreferences.textureImporterWarning = EditorPrefs.GetBool(TEXTUREIMPORTER_WARNING_KEY, SpinePreferences.DEFAULT_TEXTUREIMPORTER_WARNING);
|
||||
}
|
||||
@ -180,6 +181,7 @@ namespace Spine.Unity.Editor {
|
||||
EditorPrefs.SetBool(SHOW_HIERARCHY_ICONS_KEY, preferences.showHierarchyIcons);
|
||||
EditorPrefs.SetBool(SET_TEXTUREIMPORTER_SETTINGS_KEY, preferences.setTextureImporterSettings);
|
||||
EditorPrefs.SetBool(AUTO_RELOAD_SCENESKELETONS_KEY, preferences.autoReloadSceneSkeletons);
|
||||
EditorPrefs.SetBool(MECANIM_EVENT_INCLUDE_FOLDERNAME_KEY, preferences.mecanimEventIncludeFolderName);
|
||||
EditorPrefs.SetBool(ATLASTXT_WARNING_KEY, preferences.atlasTxtImportWarning);
|
||||
EditorPrefs.SetBool(TEXTUREIMPORTER_WARNING_KEY, preferences.textureImporterWarning);
|
||||
}
|
||||
@ -236,6 +238,12 @@ namespace Spine.Unity.Editor {
|
||||
SpineEditorUtilities.BoolPrefsField(ref defaultInstantiateLoop, DEFAULT_INSTANTIATE_LOOP_KEY, new GUIContent("Default Loop", "Spawn Spine GameObjects with loop enabled."));
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Mecanim Bake Settings", EditorStyles.boldLabel);
|
||||
{
|
||||
SpineEditorUtilities.BoolPrefsField(ref mecanimEventIncludeFolderName, MECANIM_EVENT_INCLUDE_FOLDERNAME_KEY, new GUIContent("Include Folder Name in Event", "When enabled, Mecanim events will call methods named 'FolderNameEventName', when disabled it will call 'EventName'."));
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel);
|
||||
{
|
||||
|
||||
@ -38,10 +38,6 @@
|
||||
#define NEWPLAYMODECALLBACKS
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFAB_SYSTEM
|
||||
#endif
|
||||
|
||||
#if UNITY_2018 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEWHIERARCHYWINDOWCALLBACKS
|
||||
#endif
|
||||
|
||||
@ -31,22 +31,6 @@
|
||||
|
||||
#define SPINE_SKELETONMECANIM
|
||||
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
#define NEWPLAYMODECALLBACKS
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFAB_SYSTEM
|
||||
#endif
|
||||
|
||||
#if UNITY_2018 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEWHIERARCHYWINDOWCALLBACKS
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFERENCES_SETTINGS_PROVIDER
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -339,28 +339,14 @@ namespace Spine.Unity.Editor {
|
||||
slotTransform.parent = prefabRoot.transform;
|
||||
slotTable.Add(slotData.Name, slotTransform);
|
||||
|
||||
List<Attachment> attachments = new List<Attachment>();
|
||||
List<string> attachmentNames = new List<string>();
|
||||
|
||||
var skinEntries = new List<Skin.SkinEntry>();
|
||||
skin.GetAttachments(slotIndex, skinEntries);
|
||||
foreach (var entry in skinEntries) {
|
||||
attachments.Add(entry.Attachment);
|
||||
attachmentNames.Add(entry.Name);
|
||||
}
|
||||
|
||||
if (skin != skeletonData.DefaultSkin) {
|
||||
skinEntries.Clear();
|
||||
if (skin != skeletonData.DefaultSkin)
|
||||
skeletonData.DefaultSkin.GetAttachments(slotIndex, skinEntries);
|
||||
foreach (var entry in skinEntries) {
|
||||
attachments.Add(entry.Attachment);
|
||||
attachmentNames.Add(entry.Name);
|
||||
}
|
||||
}
|
||||
|
||||
for (int a = 0; a < attachments.Count; a++) {
|
||||
var attachment = attachments[a];
|
||||
string attachmentName = attachmentNames[a];
|
||||
for (int a = 0; a < skinEntries.Count; a++) {
|
||||
var attachment = skinEntries[a].Attachment;
|
||||
string attachmentName = skinEntries[a].Name;
|
||||
string attachmentMeshName = "[" + slotData.Name + "] " + attachmentName;
|
||||
Vector3 offset = Vector3.zero;
|
||||
float rotation = 0;
|
||||
@ -1315,9 +1301,14 @@ namespace Spine.Unity.Editor {
|
||||
var animEvents = new List<AnimationEvent>();
|
||||
for (int i = 0, n = frames.Length; i < n; i++) {
|
||||
var spineEvent = events[i];
|
||||
string eventName = spineEvent.Data.Name;
|
||||
if (SpineEditorUtilities.Preferences.mecanimEventIncludeFolderName)
|
||||
eventName = eventName.Replace("/", ""); // calls method FolderNameEventName()
|
||||
else
|
||||
eventName = eventName.Substring(eventName.LastIndexOf('/') + 1); // calls method EventName()
|
||||
var unityAnimationEvent = new AnimationEvent {
|
||||
time = frames[i],
|
||||
functionName = spineEvent.Data.Name,
|
||||
functionName = eventName,
|
||||
messageOptions = eventOptions
|
||||
};
|
||||
|
||||
|
||||
@ -84,7 +84,7 @@ namespace Spine.Unity.Editor {
|
||||
[SpineBone(dataField:"skeletonRenderer")]
|
||||
public string boneName;
|
||||
|
||||
readonly Dictionary<Slot, List<Attachment>> attachmentTable = new Dictionary<Slot, List<Attachment>>();
|
||||
readonly Dictionary<Slot, List<Skin.SkinEntry>> attachmentTable = new Dictionary<Slot, List<Skin.SkinEntry>>();
|
||||
|
||||
static bool staticLostValues = true;
|
||||
|
||||
@ -338,7 +338,7 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
|
||||
int baseIndent = EditorGUI.indentLevel;
|
||||
foreach (KeyValuePair<Slot, List<Attachment>> pair in attachmentTable) {
|
||||
foreach (KeyValuePair<Slot, List<Skin.SkinEntry>> pair in attachmentTable) {
|
||||
Slot slot = pair.Key;
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
@ -352,7 +352,8 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var attachment in pair.Value) {
|
||||
foreach (var skinEntry in pair.Value) {
|
||||
var attachment = skinEntry.Attachment;
|
||||
GUI.contentColor = slot.Attachment == attachment ? Color.white : Color.grey;
|
||||
EditorGUI.indentLevel = baseIndent + 2;
|
||||
var icon = Icons.GetAttachmentIcon(attachment);
|
||||
@ -577,21 +578,12 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
attachmentTable.Clear();
|
||||
for (int i = skeleton.Slots.Count - 1; i >= 0; i--) {
|
||||
var attachments = new List<Attachment>();
|
||||
var attachments = new List<Skin.SkinEntry>();
|
||||
attachmentTable.Add(skeleton.Slots.Items[i], attachments);
|
||||
// Add skin attachments.
|
||||
var skinEntries = new List<Skin.SkinEntry>();
|
||||
skin.GetAttachments(i, skinEntries);
|
||||
foreach (var entry in skinEntries) {
|
||||
attachments.Add(entry.Attachment);
|
||||
}
|
||||
if (notDefaultSkin) { // Add default skin attachments.
|
||||
skinEntries.Clear();
|
||||
defaultSkin.GetAttachments(i, skinEntries);
|
||||
foreach (var entry in skinEntries) {
|
||||
attachments.Add(entry.Attachment);
|
||||
}
|
||||
}
|
||||
skin.GetAttachments(i, attachments);
|
||||
if (notDefaultSkin) // Add default skin attachments.
|
||||
defaultSkin.GetAttachments(i, attachments);
|
||||
}
|
||||
|
||||
activeSkin = skeleton.Skin;
|
||||
|
||||
@ -89,6 +89,9 @@ namespace Spine.Unity.Editor {
|
||||
internal const float DEFAULT_SCENE_ICONS_SCALE = 1f;
|
||||
public const string SCENE_ICONS_SCALE_KEY = "SPINE_SCENE_ICONS_SCALE";
|
||||
|
||||
public const bool DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME = true;
|
||||
public bool mecanimEventIncludeFolderName = DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME;
|
||||
|
||||
#if NEW_PREFERENCES_SETTINGS_PROVIDER
|
||||
public static void Load () {
|
||||
SpineHandles.handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, DEFAULT_SCENE_ICONS_SCALE);
|
||||
@ -155,6 +158,12 @@ namespace Spine.Unity.Editor {
|
||||
EditorGUILayout.PropertyField(settings.FindProperty("defaultInstantiateLoop"), new GUIContent("Default Loop", "Spawn Spine GameObjects with loop enabled."));
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Mecanim Bake Settings", EditorStyles.boldLabel);
|
||||
{
|
||||
EditorGUILayout.PropertyField(settings.FindProperty("mecanimEventIncludeFolderName"), new GUIContent("Include Folder Name in Event", "When enabled, Mecanim events will call methods named 'FolderNameEventName', when disabled it will call 'EventName'."));
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel);
|
||||
{
|
||||
|
||||
@ -333,9 +333,9 @@ namespace Spine.Unity.AttachmentTools {
|
||||
var originalRegions = new List<AtlasRegion>();
|
||||
int newRegionIndex = 0;
|
||||
|
||||
foreach (DictionaryEntry skinEntry in skinAttachments) {
|
||||
var originalKey = (Skin.SkinEntry)skinEntry.Key;
|
||||
var originalAttachment = (Attachment)skinEntry.Value;
|
||||
foreach (var skinEntry in skinAttachments) {
|
||||
var originalKey = skinEntry.Key;
|
||||
var originalAttachment = skinEntry.Value;
|
||||
|
||||
Attachment newAttachment;
|
||||
if (IsRenderable(originalAttachment)) {
|
||||
|
||||
@ -74,7 +74,7 @@ namespace Spine.Unity.AttachmentTools {
|
||||
var newSkin = new Skin(original.name + " clone");
|
||||
var newSkinAttachments = newSkin.Attachments;
|
||||
|
||||
foreach (DictionaryEntry a in original.Attachments)
|
||||
foreach (var a in original.Attachments)
|
||||
newSkinAttachments[a.Key] = a.Value;
|
||||
|
||||
return newSkin;
|
||||
@ -129,21 +129,21 @@ namespace Spine.Unity.AttachmentTools {
|
||||
|
||||
if (cloneAttachments) {
|
||||
if (overwrite) {
|
||||
foreach (DictionaryEntry e in sourceAttachments)
|
||||
destinationAttachments[e.Key] = ((Attachment)e.Value).GetCopy(cloneMeshesAsLinked);
|
||||
foreach (var e in sourceAttachments)
|
||||
destinationAttachments[e.Key] = e.Value.GetCopy(cloneMeshesAsLinked);
|
||||
} else {
|
||||
foreach (DictionaryEntry e in sourceAttachments) {
|
||||
if (destinationAttachments.Contains(e.Key)) continue;
|
||||
destinationAttachments.Add(e.Key, ((Attachment)e.Value).GetCopy(cloneMeshesAsLinked));
|
||||
foreach (var e in sourceAttachments) {
|
||||
if (destinationAttachments.ContainsKey(e.Key)) continue;
|
||||
destinationAttachments.Add(e.Key, e.Value.GetCopy(cloneMeshesAsLinked));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (overwrite) {
|
||||
foreach (DictionaryEntry e in sourceAttachments)
|
||||
foreach (var e in sourceAttachments)
|
||||
destinationAttachments[e.Key] = e.Value;
|
||||
} else {
|
||||
foreach (DictionaryEntry e in sourceAttachments) {
|
||||
if (destinationAttachments.Contains(e.Key)) continue;
|
||||
foreach (var e in sourceAttachments) {
|
||||
if (destinationAttachments.ContainsKey(e.Key)) continue;
|
||||
destinationAttachments.Add(e.Key, e.Value);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user