Skip to content

Commit

Permalink
[c] Optimized attachment lookup in skin. See #1117. (#1118)
Browse files Browse the repository at this point in the history
* [c] Optimized attachment lookup in skin. See #1117.

* [c] Optimized attachment lookup in skin. See #1117. Changes according to suggestions in PR #1118.
  • Loading branch information
ievgenmukhin authored and badlogic committed Jun 7, 2018
1 parent 35703db commit cab8127
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
12 changes: 11 additions & 1 deletion spine-c/spine-c/include/spine/Skin.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);
Expand Down
42 changes: 38 additions & 4 deletions spine-c/spine-c/src/spine/Skin.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}
Expand All @@ -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;
}
Expand Down

0 comments on commit cab8127

Please sign in to comment.