叶子的小屋
cocos2d-x中使用js[备忘]
2016-1-7 admin





static JSObject *jsb_Global_prototype;
static JSClass *jsb_Console_class;
static JSObject *jsb_Console_prototype;
class GlobalConsole
: public cocos2d::Ref
{
public:
GlobalConsole()
{
}
virtual ~GlobalConsole()
{
}
void init()
{
}
};
struct JSONSTRIFY_DATA{
std::string str;
JSContext* cx;
};
static bool js_JSONStringIfy_CallBack(const jschar *buf, uint32_t len, void *data){
JSONSTRIFY_DATA* pDat = (JSONSTRIFY_DATA*)data;
char* pStr = JS_EncodeString(pDat->cx, JS_NewUCStringCopyN(pDat->cx, buf, len));
pDat->str += pStr;
return true;
}
static bool js_Console_log(JSContext *cx, uint32_t argc, jsval *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
std::string output;
char buf[65];
for (uint32_t i = 0; i < argc; ++i){
JS::HandleValue val = args.get(i);
if (i > 0){
output += " ";
}
if (val.isBoolean()){
sprintf(buf, "%b", val.toBoolean());
output += buf;
}
else if (val.isDouble()){
sprintf(buf, "%f", (float)val.toDouble());
output += buf;
}
else if (val.isInt32()){
sprintf(buf, "%d", val.toInt32());
output += buf;
}
else if (val.isNull()){
output += "null";
}
else if (val.isUndefined()){
output += "undefined";
}
else if (val.isString()){
char* pStr = JS_EncodeString(cx, val.toString());
output += pStr;
}
else if (val.isObject()){
JS::RootedValue jsObject(cx,val);
//std::string autoJson;
JSONSTRIFY_DATA dat;
dat.cx = cx;
JS_Stringify(cx, &jsObject, JS::NullPtr(), JS::NullHandleValue, js_JSONStringIfy_CallBack, &dat);
if (dat.str.size() > 0){
output += dat.str;
}
else {
output += "{Object} ";
}
}
}
js_log(output.c_str());
args.rval().setUndefined();
return true;
}
static bool jsb_Console_constructor(JSContext *cx, uint32_t argc, jsval *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
bool ok = true;
GlobalConsole* cobj = new (std::nothrow) GlobalConsole();
cobj->init();
cobj->autorelease();
TypeTest<GlobalConsole> t;
js_type_class_t *typeClass = nullptr;
std::string typeName = t.s_name();
auto typeMapIter = _js_global_type_map.find(typeName);
CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!");
typeClass = typeMapIter->second;
CCASSERT(typeClass, "The value is null.");
// JSObject *obj = JS_NewObject(cx, typeClass->jsclass, typeClass->proto, typeClass->parentProto);
JS::RootedObject proto(cx, typeClass->proto.get());
JS::RootedObject parent(cx, typeClass->parentProto.get());
JS::RootedObject obj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parent));
args.rval().set(OBJECT_TO_JSVAL(obj));
// link the native object with the javascript object
js_proxy_t* p = jsb_new_proxy(cobj, obj);
AddNamedObjectRoot(cx, &p->obj, "js::console");
if (JS_HasProperty(cx, obj, "_ctor", &ok) && ok)
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), "_ctor", args);
return true;
}
static void js_Console_finalize(JSFreeOp *fop, JSObject *obj) {
CCLOGINFO("jsbindings: finalizing JS object %p (Module)", obj);
}
static void js_register_Global_Console(JSContext *cx, JS::HandleObject global)
{
jsb_Console_class = (JSClass *)calloc(1, sizeof(JSClass));
jsb_Console_class->name = "console";
jsb_Console_class->addProperty = JS_PropertyStub;
jsb_Console_class->delProperty = JS_DeletePropertyStub;
jsb_Console_class->getProperty = JS_PropertyStub;
jsb_Console_class->setProperty = JS_StrictPropertyStub;
jsb_Console_class->enumerate = JS_EnumerateStub;
jsb_Console_class->resolve = JS_ResolveStub;
jsb_Console_class->convert = JS_ConvertStub;
jsb_Console_class->finalize = js_Console_finalize;
jsb_Console_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);
static JSPropertySpec properties[] = {
JS_PSG("__nativeObj", js_is_native_obj, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_PS_END
};
static JSFunctionSpec funcs[] = {
JS_FN("log", js_Console_log, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_FN("warn", js_Console_log, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_FN("error", js_Console_log, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_FS_END
};
static JSFunctionSpec st_funcs[] = {
JS_FN("log", js_Console_log, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_FN("warn", js_Console_log, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_FN("error", js_Console_log, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_FS_END
};
jsb_Console_prototype = JS_InitClass(
cx, global,
JS::RootedObject(cx, jsb_Global_prototype),
jsb_Console_class,
jsb_Console_constructor, 0,
properties,
funcs,
NULL, // no static properties
st_funcs);
// make the class enumerable in the registered namespace
// bool found;
//FIXME: Removed in Firefox v27
// JS_SetPropertyAttributes(cx, global, "Effect3DOutline", JSPROP_ENUMERATE | JSPROP_READONLY, &found);
// add the proto and JSClass to the type->js info hash table
TypeTest<GlobalConsole> t;
js_type_class_t *p;
std::string typeName = t.s_name();
if (_js_global_type_map.find(typeName) == _js_global_type_map.end())
{
p = (js_type_class_t *)malloc(sizeof(js_type_class_t));
p->jsclass = jsb_Console_class;
p->proto = jsb_Console_prototype;
p->parentProto = jsb_Global_prototype;
_js_global_type_map.insert(std::make_pair(typeName, p));
}
}
void register_bindings(JSContext *cx, JS::HandleObject global)
{
JS::RootedObject ccobj(cx);
get_or_create_js_obj(cx, global, "js", &ccobj);
js_register_Global_Console(cx, global);
}
void run()
{
ScriptingCore* sc = ScriptingCore::getInstance();
sc->addRegisterCallback(register_bindings);
jsval ret = this->require(filename);
}