diff --git a/spine-c/spine-c/include/spine/Skin.h b/spine-c/spine-c/include/spine/Skin.h index 806cde877..3b3f8b249 100644 --- a/spine-c/spine-c/include/spine/Skin.h +++ b/spine-c/spine-c/include/spine/Skin.h @@ -38,6 +38,9 @@ extern "C" { #endif +/* Size of hashtable used in skin structure for fast attachment lookup. */ +#define SKIN_ENTRIES_HASH_TABLE_SIZE 100 + struct spSkeleton; typedef struct spSkin { @@ -59,9 +62,16 @@ struct _Entry { _Entry* next; }; +typedef struct _SkinHashTableEntry _SkinHashTableEntry; +struct _SkinHashTableEntry { + _Entry* entry; + _SkinHashTableEntry* next; /* list for elements with same hashes */ +}; + typedef struct { spSkin super; - _Entry* entries; + _Entry* entries; /* entries list stored for getting attachment name by attachment index */ + _SkinHashTableEntry* entriesHashTable[SKIN_ENTRIES_HASH_TABLE_SIZE]; /* hashtable for fast attachment lookup */ } _spSkin; SP_API spSkin* spSkin_create (const char* name); diff --git a/spine-c/spine-c/src/spine/Skin.c b/spine-c/spine-c/src/spine/Skin.c index 91f2d21fe..e222babbc 100644 --- a/spine-c/spine-c/src/spine/Skin.c +++ b/spine-c/spine-c/src/spine/Skin.c @@ -45,6 +45,16 @@ void _Entry_dispose (_Entry* self) { FREE(self); } +static _SkinHashTableEntry* _SkinHashTableEntry_create (_Entry* entry) { + _SkinHashTableEntry* self = NEW(_SkinHashTableEntry); + self->entry = entry; + return self; +} + +static void _SkinHashTableEntry_dispose (_SkinHashTableEntry* self) { + FREE(self); +} + /**/ spSkin* spSkin_create (const char* name) { @@ -55,12 +65,28 @@ spSkin* spSkin_create (const char* name) { void spSkin_dispose (spSkin* self) { _Entry* entry = SUB_CAST(_spSkin, self)->entries; + while (entry) { _Entry* nextEntry = entry->next; _Entry_dispose(entry); entry = nextEntry; } + { + _SkinHashTableEntry** currentHashtableEntry = SUB_CAST(_spSkin, self)->entriesHashTable; + int i; + + for (i = 0; i < SKIN_ENTRIES_HASH_TABLE_SIZE; ++i, ++currentHashtableEntry) { + _SkinHashTableEntry* hashtableEntry = *currentHashtableEntry; + + while (hashtableEntry) { + _SkinHashTableEntry* nextEntry = hashtableEntry->next; + _SkinHashTableEntry_dispose(hashtableEntry); + hashtableEntry = nextEntry; + } + } + } + FREE(self->name); FREE(self); } @@ -69,13 +95,21 @@ void spSkin_addAttachment (spSkin* self, int slotIndex, const char* name, spAtta _Entry* newEntry = _Entry_create(slotIndex, name, attachment); newEntry->next = SUB_CAST(_spSkin, self)->entries; SUB_CAST(_spSkin, self)->entries = newEntry; + + { + unsigned int hashTableIndex = (unsigned int)slotIndex % SKIN_ENTRIES_HASH_TABLE_SIZE; + + _SkinHashTableEntry* newHashEntry = _SkinHashTableEntry_create(newEntry); + newHashEntry->next = SUB_CAST(_spSkin, self)->entriesHashTable[hashTableIndex]; + SUB_CAST(_spSkin, self)->entriesHashTable[hashTableIndex] = newHashEntry; + } } spAttachment* spSkin_getAttachment (const spSkin* self, int slotIndex, const char* name) { - const _Entry* entry = SUB_CAST(_spSkin, self)->entries; - while (entry) { - if (entry->slotIndex == slotIndex && strcmp(entry->name, name) == 0) return entry->attachment; - entry = entry->next; + const _SkinHashTableEntry* hashEntry = SUB_CAST(_spSkin, self)->entriesHashTable[(unsigned int)slotIndex % SKIN_ENTRIES_HASH_TABLE_SIZE]; + while (hashEntry) { + if (hashEntry->entry->slotIndex == slotIndex && strcmp(hashEntry->entry->name, name) == 0) return hashEntry->entry->attachment; + hashEntry = hashEntry->next; } return 0; } diff --git a/spine-libgdx/LICENSE b/spine-libgdx/LICENSE index daceab94a..1f6d3bc57 100644 --- a/spine-libgdx/LICENSE +++ b/spine-libgdx/LICENSE @@ -1,6 +1,6 @@ Spine Runtimes Software License v2.5 -Copyright (c) 2013-2016, Esoteric Software +Copyright (c) 2013-2018, Esoteric Software All rights reserved. You are granted a perpetual, non-exclusive, non-sublicensable, and @@ -24,4 +24,4 @@ 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. \ No newline at end of file +POSSIBILITY OF SUCH DAMAGE. diff --git a/spine-ts/widget/src/Widget.ts b/spine-ts/widget/src/Widget.ts index 6a1dd172d..d5a477bbb 100644 --- a/spine-ts/widget/src/Widget.ts +++ b/spine-ts/widget/src/Widget.ts @@ -102,7 +102,7 @@ module spine { } else { for (let i = 0; i < config.atlasPages.length; i++) { if (config.atlasPagesContent && config.atlasPagesContent[i]) { - assets.loadTextureData(config.atlasPages[i], config.atlasPagesContent[0]); + assets.loadTextureData(config.atlasPages[i], config.atlasPagesContent[i]); } else { assets.loadTexture(config.atlasPages[i]); } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs index fa5cac11c..bd2dcaf62 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs @@ -1282,7 +1282,13 @@ namespace Spine.Unity { internal Material[] sharedMaterials = new Material[0]; public void Initialize () { - doubleBufferedMesh = new DoubleBuffered(); + if (doubleBufferedMesh != null) { + doubleBufferedMesh.GetNext().Clear(); + doubleBufferedMesh.GetNext().Clear(); + submeshMaterials.Clear(); + } else { + doubleBufferedMesh = new DoubleBuffered(); + } } public Material[] GetUpdatedSharedMaterialsArray () { @@ -1341,6 +1347,11 @@ namespace Spine.Unity { public Mesh mesh = SpineMesh.NewSkeletonMesh(); public SkeletonRendererInstruction instructionUsed = new SkeletonRendererInstruction(); + public void Clear () { + mesh.Clear(); + instructionUsed.Clear(); + } + public void Dispose () { if (mesh != null) { #if UNITY_EDITOR