• Runtimes
  • "Invalid skeleton JSON" with trial .json file and runtimes

  • Изменено
Related Discussions
...

I'm currently evaluating spine and have downloaded the spine trial which also comes with some exported image/skeleton/animation data. When trying to use the exported 'spineboy-ess.json' file from the latest 3.7 spine beta trial version with the latest spine-c runtimes I keep getting an "Invalid skeleton JSON" error when coding. The code I'm using is this (in C++ application):

    spAtlas* atlas = spAtlas_createFromFile("spineboy.atlas", 0);

RUNTIME_ASSERT(atlas != nullptr, "Atlas not loading properly!");

spSkeletonJson* json = spSkeletonJson_create(atlas);

spSkeletonData* skeletonData = spSkeletonJson_readSkeletonData(json, "spineboy-ess.json");

if (!skeletonData)
{
	LOG("%s\n", json->error);
	spSkeletonJson_dispose(json);
};

As you may have noticed the issue comes with the skeletonData being null (thus meaning the .json isn't loading properly). I have tried the 3.6 version of the runtimes as well to no avail. Is this an issue with the trial exported .json file? I attached it to this post as well.

I'm having troubles reproducing this. I've tried loading the spineboy-ess.json you attached in the spine-sfml demos as well as the spine-cocos2dx demos, using the 3.6 spine-runtimes and 3.7-beta spine-runtimes branch, but it loaded fine. Your code also looks fine. Could you debug into spSkeletonJson_readSkeleton and see where it fails?

FWIW, the examples in the Spine runtime repository and the ones shipped with Spine Trial/ESS/PRO/ENT are the same, so there shouldn't be any issue.

After debugging a bit, it seems the error is occuring within the 'Json_create(const char* value)' function:

/* Parse an object - create a new root, and populate. */
Json Json_create (const char value) {
Json c;
ep = 0;
if (!value) return 0; /
only place we check for NULL other than skip() /
c = Json_new();
if (!c) return 0; /
memory fail */

value = parse_value(c, skip(value));
if (!value) {
	Json_dispose(c);
	return 0;
} /* parse failure. ep is set. */

return c;

}

More specifically, when it hits 'parse_value(c, skip(value));' and dives into the parse_value function which eventually returns 0:

/* Parser core - when encountering text, process appropriately. /
static const char
parse_value (Json item, const char value) {
/* Referenced by Json_create(), parse_array(), and parse_object(). /
/
Always called with the result of skip(). /
#if SPINE_JSON_DEBUG /
Checked at entry to graph, Json_create, and after every parse_ call. /
if (!value) return 0; /
Fail on null. */
#endif

switch (*value) {
case 'n': {
	if (!strncmp(value + 1, "ull", 3)) {
		item->type = Json_NULL;
		return value + 4;
	}
	break;
}
case 'f': {
	if (!strncmp(value + 1, "alse", 4)) {
		item->type = Json_False;
		/* calloc prevents us needing item->type = Json_False or valueInt = 0 here */
		return value + 5;
	}
	break;
}
case 't': {
	if (!strncmp(value + 1, "rue", 3)) {
		item->type = Json_True;
		item->valueInt = 1;
		return value + 4;
	}
	break;
}
case '\"':
	return parse_string(item, value);
case '[':
	return parse_array(item, value);
case '{':
	return parse_object(item, value);
case '-': /* fallthrough */
case '0': /* fallthrough */
case '1': /* fallthrough */
case '2': /* fallthrough */
case '3': /* fallthrough */
case '4': /* fallthrough */
case '5': /* fallthrough */
case '6': /* fallthrough */
case '7': /* fallthrough */
case '8': /* fallthrough */
case '9':
	return parse_number(item, value);
default:
	break;
}

ep = value;
return 0; /* failure. */

}

So none of the switch cases are hit. When inspecting the const char* 'value' variable, its says it's holding the 'spineboy-ess.json' file name within it, so it's not like that variable is null or anything.

I recently changed parse_number, so that may be what is causing this. However, as I said, I can not reproduce this with the 3.6 and 3.7-beta branch using any of the Spine projects (including the JSON you provided). Any way for me to reproduce this, e.g. could you send your test project?

Well, I discovered the issue. on this line:

spSkeletonData* skeletonData = spSkeletonJson_readSkeletonData(json, "spineboy-ess.json");

I'm calling 'spSkeletonJson_readSkeletonData()' instead of 'spSkeletonJson_readSkeletonDataFile()'. I was only worried about calling the spSkeletonJson and not spSkeletonBinary, but didn't realize there were two very similar functions with spSkeletonJson.

Ahh, that's a sneaky gotcha!

Oh boy, sorry I didn't notice!

Yep, sure was sneaky.