It's a simple way to avoid a ton of typing. It is also less error prone than copypasta. The naive alternative would be to type out:
if(has_x){
JS::RootedValue out_value(ctx);
JS_GetProperty(ctx, that, "x", &out_value);
vertex.x = out_value.toNumber();
}
if(has_y){
JS::RootedValue out_value(ctx);
JS_GetProperty(ctx, that, "y", &out_value);
vertex.y = out_value.toNumber();
}
if(has_u){
JS::RootedValue out_value(ctx);
JS_GetProperty(ctx, that, "u", &out_value);
if(!out_value.isNumber()){
return false;
}
vertex.u = out_value.toNumber();
}
if(has_v){
JS::RootedValue out_value(ctx);
JS_GetProperty(ctx, that, "v", &out_value);
if(!out_value.isNumber()){
return false;
}
vertex.v = out_value.toNumber();
}
if(has_color){
JS::RootedValue out_value(ctx);
JS_GetProperty(ctx, that, "color", &out_value);
if(!(out_value.isObject() && color_proto.instanceOf(ctx, out_value, nullptr))){
return false;
}
TS_Color *color = color_proto.unsafeUnwrap(out_value.toObjectOrNull());
vertex.color = TS_Color(color->red, color->green, color->blue, color->alpha);
}
I saw this kind of thing a lot in the Sphere source, and just sort of ignored it. It's something I kind of learned to appreciate at Mozilla.
I mean, I could do something with templates, but some times that just ends up being really complex. Sometimes the most readable, simplest way to do it is just a macro. I don't think this warrants anything more complex.
Anyways...
I've updated TurboSphere to use SpiderMonkey 40. Which meant a total of about 20 lines of changes, mostly to Sapphire and how it handles Group and Shape assignments. Compared to how V8's API changes, SpiderMonkey is extremely stable.
I also modified the Delay function to perform GC'ing, if more than 10 milliseconds of delay is requested, and if we have not GC'ed in the last second.
SM 40 also uses much less memory...we went from 40 MB running the test map down to 23 MB! I'm really impressed, that's much less than I thought. It's nice to have a JS engine that can actually manage its own memory for once.