cocos2d-x中使用js[备忘]

2016-1-7 admin cocos2d


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);
}


标签: C++ cocos2d

发表评论:

Powered by emlog

浙ICP备17021512号 |浙公网安备 33010602008237号