Refactored loading files.

This commit is contained in:
NathanSweet 2013-04-01 19:23:26 +02:00
parent ad67dae2e0
commit 6af401e888
16 changed files with 59 additions and 101 deletions

View File

@ -92,6 +92,12 @@ RegionAttachment* RegionAttachment_new (const char* name, AtlasRegion* region) {
/**/
char* _Util_readFile (const char* path, int* length) {
return _readFile(path, length);
}
/**/
int main (void) {
Atlas* atlas = Atlas_readAtlasFile("data/spineboy.atlas");
printf("First region name: %s, x: %d, y: %d\n", atlas->regions->name, atlas->regions->x, atlas->regions->y);

View File

@ -90,7 +90,7 @@ typedef struct {
AtlasRegion* regions;
} Atlas;
Atlas* Atlas_readAtlas (const char* data);
Atlas* Atlas_readAtlas (const char* data, unsigned long length);
Atlas* Atlas_readAtlasFile (const char* path);
void Atlas_free (Atlas* atlas);

View File

@ -54,7 +54,6 @@ struct Skeleton {
const void* const vtable;
};
Skeleton* Skeleton_new (SkeletonData* data);
void Skeleton_free (Skeleton* skeleton);
void Skeleton_updateWorldTransform (const Skeleton* skeleton);

View File

@ -76,7 +76,11 @@
/* Frees memory. Can be used on const. */
#define FREE(VALUE) free((void*)VALUE)
/* Allocates a new char[], assigns it to TO, and copies FROM to it. Can be used on const. */
#define MALLOC_STR(TO,FROM) strcpy(CONST_CAST(char*, TO) = (char*)malloc(strlen(FROM)), FROM)
#include <stdlib.h>
#include <string.h>
#include <spine/Skeleton.h>
#include <spine/RegionAttachment.h>
#include <spine/Animation.h>
@ -89,19 +93,21 @@ extern "C" {
#endif
/*
* Public API that must be implemented:
* Functions that must be implemented:
*/
Skeleton* Skeleton_new (SkeletonData* data);
RegionAttachment* RegionAttachment_new (const char* name, AtlasRegion* region);
AtlasPage* AtlasPage_new (const char* name);
char* _Util_readFile (const char* path, int* length);
/*
* Internal API available for extension:
*/
char* _readFile (const char* path, int* length);
typedef struct _SkeletonVtable {
void (*free) (Skeleton* skeleton);
} _SkeletonVtable;

View File

@ -26,7 +26,6 @@
#include <spine/Animation.h>
#include <math.h>
#include <spine/extension.h>
#include <spine/util.h>
Animation* Animation_new (int timelineCount) {
Animation* self = NEW(Animation);

View File

@ -26,7 +26,6 @@
#include <spine/Atlas.h>
#include <ctype.h>
#include <spine/extension.h>
#include <spine/util.h>
void _AtlasPage_init (AtlasPage* self, const char* name) {
CONST_CAST(_AtlasPageVtable*, self->vtable) = NEW(_AtlasPageVtable);
@ -73,24 +72,24 @@ static void trim (Str* str) {
}
/* Tokenize string without modification. Returns 0 on failure. */
static int readLine (const char* data, Str* str) {
static int readLine (const char* begin, const char* end, Str* str) {
static const char* nextStart;
if (data) {
nextStart = data;
if (begin) {
nextStart = begin;
return 1;
}
if (*nextStart == '\0') return 0;
if (nextStart == end) return 0;
str->begin = nextStart;
/* Find next delimiter. */
do {
nextStart++;
} while (*nextStart != '\0' && *nextStart != '\n');
} while (nextStart != end && *nextStart != '\n');
str->end = nextStart;
trim(str);
if (*nextStart != '\0') nextStart++;
if (nextStart != end) nextStart++;
return 1;
}
@ -108,17 +107,17 @@ static int beginPast (Str* str, char c) {
}
/* Returns 0 on failure. */
static int readValue (Str* str) {
readLine(0, str);
static int readValue (const char* end, Str* str) {
readLine(0, end, str);
if (!beginPast(str, ':')) return 0;
trim(str);
return 1;
}
/* Returns the number of tuple values read (2, 4, or 0 for failure). */
static int readTuple (Str tuple[]) {
static int readTuple (const char* end, Str tuple[]) {
Str str;
readLine(0, &str);
readLine(0, end, &str);
if (!beginPast(&str, ':')) return 0;
int i = 0;
for (i = 0; i < 3; ++i) {
@ -160,7 +159,7 @@ static int toInt (Str* str) {
return strtol(str->begin, (char**)&str->end, 10);
}
static Atlas* abort (Atlas* self) {
static Atlas* abortAtlas (Atlas* self) {
Atlas_free(self);
return 0;
}
@ -169,7 +168,9 @@ static const char* formatNames[] = {"Alpha", "Intensity", "LuminanceAlpha", "RGB
static const char* textureFilterNames[] = {"Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest",
"MipMapNearestLinear", "MipMapLinearLinear"};
Atlas* Atlas_readAtlas (const char* data) {
Atlas* Atlas_readAtlas (const char* begin, unsigned long length) {
const char* end = begin + length;
Atlas* self = NEW(Atlas);
AtlasPage *page = 0;
@ -177,8 +178,8 @@ Atlas* Atlas_readAtlas (const char* data) {
AtlasRegion *lastRegion = 0;
Str str;
Str tuple[4];
readLine(data, 0);
while (readLine(0, &str)) {
readLine(begin, 0, 0);
while (readLine(0, end, &str)) {
if (str.end - str.begin == 0) {
page = 0;
} else if (!page) {
@ -189,14 +190,14 @@ Atlas* Atlas_readAtlas (const char* data) {
self->pages = page;
lastPage = page;
if (!readValue(&str)) return abort(self);
if (!readValue(end, &str)) return abortAtlas(self);
page->format = (AtlasFormat)indexOf(formatNames, 7, &str);
if (!readTuple(tuple)) return abort(self);
if (!readTuple(end, tuple)) return abortAtlas(self);
page->minFilter = (AtlasFilter)indexOf(textureFilterNames, 7, tuple);
page->magFilter = (AtlasFilter)indexOf(textureFilterNames, 7, tuple + 1);
if (!readValue(&str)) return abort(self);
if (!readValue(end, &str)) return abortAtlas(self);
if (!equals(&str, "none")) {
page->uWrap = *str.begin == 'x' ? ATLAS_REPEAT : (*str.begin == 'y' ? ATLAS_CLAMPTOEDGE : ATLAS_REPEAT);
page->vWrap = *str.begin == 'x' ? ATLAS_CLAMPTOEDGE : (*str.begin == 'y' ? ATLAS_REPEAT : ATLAS_REPEAT);
@ -212,19 +213,19 @@ Atlas* Atlas_readAtlas (const char* data) {
region->page = page;
region->name = mallocString(&str);
if (!readValue(&str)) return abort(self);
if (!readValue(end, &str)) return abortAtlas(self);
region->rotate = equals(&str, "true");
if (readTuple(tuple) != 2) return abort(self);
if (readTuple(end, tuple) != 2) return abortAtlas(self);
region->x = toInt(tuple);
region->y = toInt(tuple + 1);
if (readTuple(tuple) != 2) return abort(self);
if (readTuple(end, tuple) != 2) return abortAtlas(self);
region->width = toInt(tuple);
region->height = toInt(tuple + 1);
int count;
if (!(count = readTuple(tuple))) return abort(self);
if (!(count = readTuple(end, tuple))) return abortAtlas(self);
if (count == 4) { /* split is optional */
region->splits = MALLOC(int, 4);
region->splits[0] = toInt(tuple);
@ -232,7 +233,7 @@ Atlas* Atlas_readAtlas (const char* data) {
region->splits[2] = toInt(tuple + 2);
region->splits[3] = toInt(tuple + 3);
if (!(count = readTuple(tuple))) return abort(self);
if (!(count = readTuple(end, tuple))) return abortAtlas(self);
if (count == 4) { /* pad is optional, but only present with splits */
region->pads = MALLOC(int, 4);
region->pads[0] = toInt(tuple);
@ -240,18 +241,18 @@ Atlas* Atlas_readAtlas (const char* data) {
region->pads[2] = toInt(tuple + 2);
region->pads[3] = toInt(tuple + 3);
if (!readTuple(tuple)) return abort(self);
if (!readTuple(end, tuple)) return abortAtlas(self);
}
}
region->originalWidth = toInt(tuple);
region->originalHeight = toInt(tuple + 1);
readTuple(tuple);
readTuple(end, tuple);
region->offsetX = (float)toInt(tuple);
region->offsetY = (float)toInt(tuple + 1);
if (!readValue(&str)) return abort(self);
if (!readValue(end, &str)) return abortAtlas(self);
region->index = toInt(&str);
}
}
@ -260,9 +261,10 @@ Atlas* Atlas_readAtlas (const char* data) {
}
Atlas* Atlas_readAtlasFile (const char* path) {
const char* data = readFile(path);
int length;
const char* data = _Util_readFile(path, &length);
if (!data) return 0;
Atlas* atlas = Atlas_readAtlas(data);
Atlas* atlas = Atlas_readAtlas(data, length);
FREE(data);
return atlas;
}

View File

@ -26,7 +26,6 @@
#include <spine/AtlasAttachmentLoader.h>
#include <stdio.h>
#include <spine/extension.h>
#include <spine/util.h>
void _AtlasAttachmentLoader_free (AttachmentLoader* self) {
_AttachmentLoader_deinit(self);

View File

@ -25,7 +25,6 @@
#include <spine/Attachment.h>
#include <spine/extension.h>
#include <spine/util.h>
#include <spine/Slot.h>
void _Attachment_init (Attachment* self, const char* name, AttachmentType type) {

View File

@ -25,7 +25,6 @@
#include <spine/AttachmentLoader.h>
#include <spine/extension.h>
#include <spine/util.h>
void _AttachmentLoader_init (AttachmentLoader* self) {
CONST_CAST(_AttachmentLoaderVtable*, self->vtable) = NEW(_AttachmentLoaderVtable);

View File

@ -25,7 +25,6 @@
#include <spine/BoneData.h>
#include <spine/extension.h>
#include <spine/util.h>
BoneData* BoneData_new (const char* name, BoneData* parent) {
BoneData* self = NEW(BoneData);

View File

@ -27,7 +27,7 @@
#include <math.h>
#include <stdio.h>
#include <ctype.h>
#include <spine/util.h>
#include <spine/extension.h>
static const char* ep;

View File

@ -28,7 +28,6 @@
#include <stdio.h>
#include <math.h>
#include <spine/extension.h>
#include <spine/util.h>
#include <spine/Json.h>
#include <spine/RegionAttachment.h>
#include <spine/AtlasAttachmentLoader.h>
@ -82,7 +81,8 @@ static float toColor (const char* value, int index) {
}
SkeletonData* SkeletonJson_readSkeletonDataFile (SkeletonJson* self, const char* path) {
const char* json = readFile(path);
int length;
const char* json = _Util_readFile(path, &length);
if (!json) {
_SkeletonJson_setError(self, 0, "Unable to read skeleton file: ", path);
return 0;
@ -240,13 +240,14 @@ SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* self, const char* jso
}
Animation* SkeletonJson_readAnimationFile (SkeletonJson* self, const char* path, const SkeletonData *skeletonData) {
const char* data = readFile(path);
if (!data) {
int length;
const char* json = _Util_readFile(path, &length);
if (!json) {
_SkeletonJson_setError(self, 0, "Unable to read animation file: ", path);
return 0;
}
Animation* animation = SkeletonJson_readAnimation(self, data, skeletonData);
FREE(data);
Animation* animation = SkeletonJson_readAnimation(self, json, skeletonData);
FREE(json);
return animation;
}

View File

@ -25,7 +25,6 @@
#include <spine/Skin.h>
#include <spine/extension.h>
#include <spine/util.h>
SkinEntry* _SkinEntry_new (int slotIndex, const char* name, Attachment* attachment) {
SkinEntry* self = NEW(SkinEntry);

View File

@ -25,7 +25,6 @@
#include <spine/SlotData.h>
#include <spine/extension.h>
#include <spine/util.h>
SlotData* SlotData_new (const char* name, BoneData* boneData) {
SlotData* self = NEW(SlotData);

View File

@ -23,21 +23,20 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#include <spine/util.h>
#include <spine/extension.h>
#include <stdio.h>
const char* readFile (const char* path) {
char* _readFile (const char* path, int* length) {
FILE *file = fopen(path, "rb");
if (!file) return 0;
fseek(file, 0, SEEK_END);
long length = ftell(file);
*length = ftell(file);
fseek(file, 0, SEEK_SET);
char* data = MALLOC(char, length + 1);
fread(data, 1, length, file);
char* data = MALLOC(char, *length);
fread(data, 1, *length, file);
fclose(file);
data[length] = '\0';
return data;
}

View File

@ -1,48 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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.
******************************************************************************/
#ifndef SPINE_UTIL_H_
#define SPINE_UTIL_H_
#include <string.h>
#include <spine/extension.h>
#ifdef __cplusplus
namespace spine {
extern "C" {
#endif
/* Allocates a new char[], assigns it to TO, and copies FROM to it. Can be used on const. */
#define MALLOC_STR(TO,FROM) strcpy(CONST_CAST(char*, TO) = (char*)malloc(strlen(FROM)), FROM)
/* Read file at specific path to a new char[]. Return value must be freed. */
const char* readFile (const char* path);
#ifdef __cplusplus
}
}
#endif
#endif /* SPINE_UTIL_H_ */