mirror of https://github.com/axmolengine/axmol.git
Use JS::Heap instead of Mozilla::maybe to improve stability
This commit is contained in:
parent
55756cb043
commit
554523a201
|
@ -35,19 +35,21 @@ public:
|
|||
JSB_HeapValueWrapper(JSContext* cx, JS::HandleValue value)
|
||||
:_cx(cx)
|
||||
{
|
||||
_data.construct(cx, value);
|
||||
_data = value;
|
||||
js_add_object_root(value);
|
||||
}
|
||||
|
||||
|
||||
~JSB_HeapValueWrapper(){
|
||||
_data.destroyIfConstructed();
|
||||
JS::RootedValue value(_cx, _data);
|
||||
js_remove_object_root(value);
|
||||
}
|
||||
|
||||
jsval get(){
|
||||
return _data.ref();
|
||||
return _data;
|
||||
}
|
||||
private:
|
||||
JSContext* _cx;
|
||||
mozilla::Maybe<JS::PersistentRootedValue> _data;
|
||||
JS::Heap<JS::Value> _data;
|
||||
};
|
||||
|
||||
static bool js_cocos2dx_Sprite3D_createAsync(JSContext *cx, uint32_t argc, jsval *vp)
|
||||
|
@ -59,15 +61,18 @@ static bool js_cocos2dx_Sprite3D_createAsync(JSContext *cx, uint32_t argc, jsval
|
|||
jsval_to_std_string(cx, args.get(0), &modelPath);
|
||||
|
||||
std::function<void(Sprite3D*, void*)> callback;
|
||||
JS::RootedObject cb(cx, args.get(argc == 4 ? 2 : 3).toObjectOrNull());
|
||||
std::shared_ptr<JSFunctionWrapper> func(new JSFunctionWrapper(cx, cb, args.get(argc == 4 ? 1 : 2)));
|
||||
JS::RootedValue targetVal(cx, args.get(argc == 4 ? 2 : 3));
|
||||
JS::RootedObject target(cx, targetVal.toObjectOrNull());
|
||||
JS::RootedValue fval(cx, args.get(argc == 4 ? 1 : 2));
|
||||
std::shared_ptr<JSFunctionWrapper> func(new JSFunctionWrapper(cx, target, fval));
|
||||
auto lambda = [=](Sprite3D* larg0, void* larg1) -> void{
|
||||
|
||||
jsval largv[2];
|
||||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
largv[0] = OBJECT_TO_JSVAL(js_get_or_create_jsobject<Sprite3D>(cx, larg0));
|
||||
JSB_HeapValueWrapper* v = (JSB_HeapValueWrapper*)larg1;
|
||||
largv[1] = JS::RootedValue(cx, v->get());
|
||||
JS::RootedValue dataVal(cx, v->get());
|
||||
largv[1] = dataVal;
|
||||
|
||||
JS::RootedValue rval(cx);
|
||||
bool ok = func->invoke(2, largv, &rval);
|
||||
|
|
|
@ -159,12 +159,12 @@ bool JSB_CCPhysicsDebugNode_debugNodeForCPSpace__static(JSContext *cx, uint32_t
|
|||
JSB_PRECONDITION2(ok, cx, false, "Error processing arguments");
|
||||
|
||||
PhysicsDebugNode* ret = PhysicsDebugNode::create(arg0);
|
||||
jsval jsret;
|
||||
JS::RootedValue jsret(cx);
|
||||
if (ret) {
|
||||
js_type_class_t *typeClass = js_get_type_from_native<PhysicsDebugNode>(ret);
|
||||
JS::RootedValue jsret(cx, OBJECT_TO_JSVAL(jsb_ref_autoreleased_get_or_create_jsobject(cx, ret, typeClass, "cocos2d::extension::PhysicsDebugNode")));
|
||||
jsret.set(OBJECT_TO_JSVAL(jsb_ref_autoreleased_get_or_create_jsobject(cx, ret, typeClass, "cocos2d::extension::PhysicsDebugNode")));
|
||||
} else {
|
||||
jsret = JSVAL_NULL;
|
||||
jsret.set(JS::NullValue());
|
||||
}
|
||||
args.rval().set(jsret);
|
||||
|
||||
|
@ -321,12 +321,12 @@ bool JSPROXY_CCPhysicsSprite_spriteWithSpriteFrame__static(JSContext *cx, uint32
|
|||
}
|
||||
PhysicsSprite* ret = PhysicsSprite::createWithSpriteFrame(arg0);
|
||||
|
||||
jsval jsret;
|
||||
JS::RootedValue jsret(cx);
|
||||
if (ret) {
|
||||
js_type_class_t *typeClass = js_get_type_from_native<PhysicsSprite>(ret);
|
||||
JS::RootedValue jsret(cx, OBJECT_TO_JSVAL(jsb_ref_autoreleased_get_or_create_jsobject(cx, ret, typeClass, "cocos2d::extension::PhysicsSprite")));
|
||||
jsret.set(OBJECT_TO_JSVAL(jsb_ref_autoreleased_get_or_create_jsobject(cx, ret, typeClass, "cocos2d::extension::PhysicsSprite")));
|
||||
} else {
|
||||
jsret = JSVAL_NULL;
|
||||
jsret.set(JS::NullValue());
|
||||
}
|
||||
args.rval().set(jsret);
|
||||
return true;
|
||||
|
@ -619,11 +619,11 @@ struct collision_handler {
|
|||
cpCollisionType typeA;
|
||||
cpCollisionType typeB;
|
||||
|
||||
mozilla::Maybe<JS::RootedObject> begin;
|
||||
mozilla::Maybe<JS::RootedObject> pre;
|
||||
mozilla::Maybe<JS::RootedObject> post;
|
||||
mozilla::Maybe<JS::RootedObject> separate;
|
||||
mozilla::Maybe<JS::RootedObject> jsthis;
|
||||
JS::Heap<JSObject*> begin;
|
||||
JS::Heap<JSObject*> pre;
|
||||
JS::Heap<JSObject*> post;
|
||||
JS::Heap<JSObject*> separate;
|
||||
JS::Heap<JSObject*> jsthis;
|
||||
JSContext *cx;
|
||||
|
||||
// "owner" of the collision handler
|
||||
|
@ -637,36 +637,35 @@ struct collision_handler {
|
|||
|
||||
collision_handler()
|
||||
{
|
||||
JSContext *globalcx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
begin.construct(globalcx);
|
||||
pre.construct(globalcx);
|
||||
post.construct(globalcx);
|
||||
separate.construct(globalcx);
|
||||
jsthis.construct(globalcx);
|
||||
begin = nullptr;
|
||||
pre = nullptr;
|
||||
post = nullptr;
|
||||
separate = nullptr;
|
||||
jsthis = nullptr;
|
||||
}
|
||||
|
||||
void setJSSpace(JS::HandleValue jsspace)
|
||||
{
|
||||
if (!jsspace.isNullOrUndefined())
|
||||
{
|
||||
jsthis.ref() = jsspace.toObjectOrNull();
|
||||
jsthis = jsspace.toObjectOrNull();
|
||||
JS::RootedValue callback(ScriptingCore::getInstance()->getGlobalContext());
|
||||
callback.set(OBJECT_TO_JSVAL(begin.ref()));
|
||||
callback.set(OBJECT_TO_JSVAL(begin));
|
||||
if (!callback.isNullOrUndefined())
|
||||
{
|
||||
js_add_object_reference(jsspace, callback);
|
||||
}
|
||||
callback.set(OBJECT_TO_JSVAL(pre.ref()));
|
||||
callback.set(OBJECT_TO_JSVAL(pre));
|
||||
if (!callback.isNullOrUndefined())
|
||||
{
|
||||
js_add_object_reference(jsspace, callback);
|
||||
}
|
||||
callback.set(OBJECT_TO_JSVAL(post.ref()));
|
||||
callback.set(OBJECT_TO_JSVAL(post));
|
||||
if (!callback.isNullOrUndefined())
|
||||
{
|
||||
js_add_object_reference(jsspace, callback);
|
||||
}
|
||||
callback.set(OBJECT_TO_JSVAL(separate.ref()));
|
||||
callback.set(OBJECT_TO_JSVAL(separate));
|
||||
if (!callback.isNullOrUndefined())
|
||||
{
|
||||
js_add_object_reference(jsspace, callback);
|
||||
|
@ -706,8 +705,8 @@ static cpBool myCollisionBegin(cpArbiter *arb, cpSpace *space, void *data)
|
|||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
|
||||
JS::RootedValue rval(handler->cx);
|
||||
JS::RootedObject jsthis(handler->cx, handler->jsthis.ref());
|
||||
JS::RootedValue jsbegin(handler->cx, OBJECT_TO_JSVAL(handler->begin.ref()));
|
||||
JS::RootedObject jsthis(handler->cx, handler->jsthis);
|
||||
JS::RootedValue jsbegin(handler->cx, OBJECT_TO_JSVAL(handler->begin));
|
||||
bool ok = JS_CallFunctionValue(handler->cx, jsthis, jsbegin, JS::HandleValueArray::fromMarkedLocation(2, args), &rval);
|
||||
JSB_PRECONDITION2(ok, handler->cx, cpFalse, "Error calling collision callback: begin");
|
||||
|
||||
|
@ -736,8 +735,8 @@ static cpBool myCollisionPre(cpArbiter *arb, cpSpace *space, void *data)
|
|||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
|
||||
JS::RootedValue rval(handler->cx);
|
||||
JS::RootedObject jsthis(handler->cx, handler->jsthis.ref());
|
||||
JS::RootedValue jspre(handler->cx, OBJECT_TO_JSVAL(handler->pre.ref()));
|
||||
JS::RootedObject jsthis(handler->cx, handler->jsthis);
|
||||
JS::RootedValue jspre(handler->cx, OBJECT_TO_JSVAL(handler->pre));
|
||||
bool ok = JS_CallFunctionValue( handler->cx, jsthis, jspre, JS::HandleValueArray::fromMarkedLocation(2, args), &rval);
|
||||
JSB_PRECONDITION2(ok, handler->cx, false, "Error calling collision callback: pre");
|
||||
|
||||
|
@ -767,8 +766,8 @@ static void myCollisionPost(cpArbiter *arb, cpSpace *space, void *data)
|
|||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
|
||||
JS::RootedValue ignore(handler->cx);
|
||||
JS::RootedObject jsthis(handler->cx, handler->jsthis.ref());
|
||||
JS::RootedValue jspost(handler->cx, OBJECT_TO_JSVAL(handler->post.ref()));
|
||||
JS::RootedObject jsthis(handler->cx, handler->jsthis);
|
||||
JS::RootedValue jspost(handler->cx, OBJECT_TO_JSVAL(handler->post));
|
||||
bool ok = JS_CallFunctionValue( handler->cx, jsthis, jspost, JS::HandleValueArray::fromMarkedLocation(2, args), &ignore);
|
||||
JSB_PRECONDITION2(ok, handler->cx, , "Error calling collision callback: Post");
|
||||
}
|
||||
|
@ -793,8 +792,8 @@ static void myCollisionSeparate(cpArbiter *arb, cpSpace *space, void *data)
|
|||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
|
||||
JS::RootedValue ignore(handler->cx);
|
||||
JS::RootedObject jsthis(handler->cx, handler->jsthis.ref());
|
||||
JS::RootedValue jssep(handler->cx, OBJECT_TO_JSVAL(handler->separate.ref()));
|
||||
JS::RootedObject jsthis(handler->cx, handler->jsthis);
|
||||
JS::RootedValue jssep(handler->cx, OBJECT_TO_JSVAL(handler->separate));
|
||||
bool ok = JS_CallFunctionValue( handler->cx, jsthis, jssep, JS::HandleValueArray::fromMarkedLocation(2, args), &ignore);
|
||||
JSB_PRECONDITION2(ok, handler->cx, , "Error calling collision callback: Separate");}
|
||||
|
||||
|
@ -850,13 +849,13 @@ bool __jsb_cpSpace_addCollisionHandler(JSContext *cx, jsval *vp, jsval *argvp, J
|
|||
ok &= jsval_to_int(cx, jstypeA, (int32_t*) &handler->typeA );
|
||||
ok &= jsval_to_int(cx, jstypeB, (int32_t*) &handler->typeB );
|
||||
|
||||
handler->begin.ref() = argvp->toObjectOrNull();
|
||||
handler->begin = argvp->toObjectOrNull();
|
||||
argvp++;
|
||||
handler->pre.ref() = argvp->toObjectOrNull();
|
||||
handler->pre = argvp->toObjectOrNull();
|
||||
argvp++;
|
||||
handler->post.ref() = argvp->toObjectOrNull();
|
||||
handler->post = argvp->toObjectOrNull();
|
||||
argvp++;
|
||||
handler->separate.ref() = argvp->toObjectOrNull();
|
||||
handler->separate = argvp->toObjectOrNull();
|
||||
argvp++;
|
||||
|
||||
JS::RootedValue spaceVal(cx, OBJECT_TO_JSVAL(jsspace));
|
||||
|
@ -871,10 +870,10 @@ bool __jsb_cpSpace_addCollisionHandler(JSContext *cx, jsval *vp, jsval *argvp, J
|
|||
handler->cx = cx;
|
||||
|
||||
cpSpaceAddCollisionHandler(space, handler->typeA, handler->typeB,
|
||||
!handler->begin.ref() ? NULL : &myCollisionBegin,
|
||||
!handler->pre.ref() ? NULL : &myCollisionPre,
|
||||
!handler->post.ref() ? NULL : &myCollisionPost,
|
||||
!handler->separate.ref() ? NULL : &myCollisionSeparate,
|
||||
!handler->begin ? NULL : &myCollisionBegin,
|
||||
!handler->pre ? NULL : &myCollisionPre,
|
||||
!handler->post ? NULL : &myCollisionPost,
|
||||
!handler->separate ? NULL : &myCollisionSeparate,
|
||||
handler );
|
||||
|
||||
|
||||
|
@ -941,10 +940,10 @@ bool JSB_cpSpace_setDefaultCollisionHandler(JSContext *cx, uint32_t argc, jsval
|
|||
|
||||
handler->typeA = 0;
|
||||
handler->typeB = 0;
|
||||
handler->begin.ref() = args.get(0).toObjectOrNull();
|
||||
handler->pre.ref() = args.get(1).toObjectOrNull();
|
||||
handler->post.ref() = args.get(2).toObjectOrNull();
|
||||
handler->separate.ref() = args.get(3).toObjectOrNull();
|
||||
handler->begin = args.get(0).toObjectOrNull();
|
||||
handler->pre = args.get(1).toObjectOrNull();
|
||||
handler->post = args.get(2).toObjectOrNull();
|
||||
handler->separate = args.get(3).toObjectOrNull();
|
||||
|
||||
JS::RootedValue spaceVal(cx, OBJECT_TO_JSVAL(jsthis));
|
||||
handler->setJSSpace(spaceVal);
|
||||
|
@ -956,10 +955,10 @@ bool JSB_cpSpace_setDefaultCollisionHandler(JSContext *cx, uint32_t argc, jsval
|
|||
handler->cx = cx;
|
||||
|
||||
cpSpaceSetDefaultCollisionHandler(space,
|
||||
!handler->begin.ref() ? NULL : &myCollisionBegin,
|
||||
!handler->pre.ref() ? NULL : &myCollisionPre,
|
||||
!handler->post.ref() ? NULL : &myCollisionPost,
|
||||
!handler->separate.ref() ? NULL : &myCollisionSeparate,
|
||||
!handler->begin ? NULL : &myCollisionBegin,
|
||||
!handler->pre ? NULL : &myCollisionPre,
|
||||
!handler->post ? NULL : &myCollisionPost,
|
||||
!handler->separate ? NULL : &myCollisionSeparate,
|
||||
handler );
|
||||
|
||||
//
|
||||
|
|
|
@ -40,20 +40,21 @@ JSTouchDelegate::JSTouchDelegate()
|
|||
: _touchListenerAllAtOnce(nullptr)
|
||||
, _touchListenerOneByOne(nullptr)
|
||||
{
|
||||
auto cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
_obj.construct(cx);
|
||||
_obj = nullptr;
|
||||
}
|
||||
|
||||
JSTouchDelegate::~JSTouchDelegate()
|
||||
{
|
||||
CCLOGINFO("In the destructor of JSTouchDelegate.");
|
||||
JSContext *cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
JS::RootedValue objVal(cx, OBJECT_TO_JSVAL(_obj.ref()));
|
||||
if (!objVal.isNullOrUndefined())
|
||||
if (_obj)
|
||||
{
|
||||
js_remove_object_root(objVal);
|
||||
JSContext *cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
JS::RootedValue objVal(cx, OBJECT_TO_JSVAL(_obj));
|
||||
if (!objVal.isNullOrUndefined())
|
||||
{
|
||||
js_remove_object_root(objVal);
|
||||
}
|
||||
}
|
||||
_obj.destroyIfConstructed();
|
||||
}
|
||||
|
||||
void JSTouchDelegate::setDelegateForJSObject(JSObject* pJSObj, JSTouchDelegate* pDelegate)
|
||||
|
@ -84,13 +85,17 @@ void JSTouchDelegate::removeDelegateForJSObject(JSObject* pJSObj)
|
|||
void JSTouchDelegate::setJSObject(JS::HandleObject obj)
|
||||
{
|
||||
JSContext *cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
JS::RootedValue objVal(cx, OBJECT_TO_JSVAL(_obj.ref()));
|
||||
if (!objVal.isNullOrUndefined())
|
||||
JS::RootedValue objVal(cx);
|
||||
if (_obj)
|
||||
{
|
||||
js_remove_object_root(objVal);
|
||||
objVal.set(OBJECT_TO_JSVAL(_obj));
|
||||
if (!objVal.isNullOrUndefined())
|
||||
{
|
||||
js_remove_object_root(objVal);
|
||||
}
|
||||
}
|
||||
|
||||
_obj.ref() = obj;
|
||||
_obj = obj;
|
||||
|
||||
objVal.set(OBJECT_TO_JSVAL(obj));
|
||||
if (!objVal.isNullOrUndefined())
|
||||
|
@ -149,7 +154,8 @@ bool JSTouchDelegate::onTouchBegan(Touch *touch, Event *event)
|
|||
JS::RootedValue retval(cx);
|
||||
bool bRet = false;
|
||||
|
||||
ScriptingCore::getInstance()->executeCustomTouchEvent(EventTouch::EventCode::BEGAN, touch, _obj.ref(), &retval);
|
||||
JS::RootedObject obj(cx, _obj);
|
||||
ScriptingCore::getInstance()->executeCustomTouchEvent(EventTouch::EventCode::BEGAN, touch, obj, &retval);
|
||||
|
||||
if(retval.isBoolean())
|
||||
{
|
||||
|
@ -163,46 +169,51 @@ bool JSTouchDelegate::onTouchBegan(Touch *touch, Event *event)
|
|||
void JSTouchDelegate::onTouchMoved(Touch *touch, Event *event)
|
||||
{
|
||||
CC_UNUSED_PARAM(event);
|
||||
|
||||
ScriptingCore::getInstance()->executeCustomTouchEvent(EventTouch::EventCode::MOVED, touch, _obj.ref());
|
||||
JS::RootedObject obj(ScriptingCore::getInstance()->getGlobalContext(), _obj);
|
||||
ScriptingCore::getInstance()->executeCustomTouchEvent(EventTouch::EventCode::MOVED, touch, obj);
|
||||
}
|
||||
|
||||
void JSTouchDelegate::onTouchEnded(Touch *touch, Event *event)
|
||||
{
|
||||
CC_UNUSED_PARAM(event);
|
||||
|
||||
ScriptingCore::getInstance()->executeCustomTouchEvent(EventTouch::EventCode::ENDED, touch, _obj.ref());
|
||||
JS::RootedObject obj(ScriptingCore::getInstance()->getGlobalContext(), _obj);
|
||||
ScriptingCore::getInstance()->executeCustomTouchEvent(EventTouch::EventCode::ENDED, touch, obj);
|
||||
}
|
||||
|
||||
void JSTouchDelegate::onTouchCancelled(Touch *touch, Event *event)
|
||||
{
|
||||
CC_UNUSED_PARAM(event);
|
||||
ScriptingCore::getInstance()->executeCustomTouchEvent(EventTouch::EventCode::CANCELLED, touch, _obj.ref());
|
||||
JS::RootedObject obj(ScriptingCore::getInstance()->getGlobalContext(), _obj);
|
||||
ScriptingCore::getInstance()->executeCustomTouchEvent(EventTouch::EventCode::CANCELLED, touch, obj);
|
||||
}
|
||||
|
||||
// optional
|
||||
void JSTouchDelegate::onTouchesBegan(const std::vector<Touch*>& touches, Event *event)
|
||||
{
|
||||
CC_UNUSED_PARAM(event);
|
||||
ScriptingCore::getInstance()->executeCustomTouchesEvent(EventTouch::EventCode::BEGAN, touches, _obj.ref());
|
||||
JS::RootedObject obj(ScriptingCore::getInstance()->getGlobalContext(), _obj);
|
||||
ScriptingCore::getInstance()->executeCustomTouchesEvent(EventTouch::EventCode::BEGAN, touches, obj);
|
||||
}
|
||||
|
||||
void JSTouchDelegate::onTouchesMoved(const std::vector<Touch*>& touches, Event *event)
|
||||
{
|
||||
CC_UNUSED_PARAM(event);
|
||||
ScriptingCore::getInstance()->executeCustomTouchesEvent(EventTouch::EventCode::MOVED, touches, _obj.ref());
|
||||
JS::RootedObject obj(ScriptingCore::getInstance()->getGlobalContext(), _obj);
|
||||
ScriptingCore::getInstance()->executeCustomTouchesEvent(EventTouch::EventCode::MOVED, touches, obj);
|
||||
}
|
||||
|
||||
void JSTouchDelegate::onTouchesEnded(const std::vector<Touch*>& touches, Event *event)
|
||||
{
|
||||
CC_UNUSED_PARAM(event);
|
||||
ScriptingCore::getInstance()->executeCustomTouchesEvent(EventTouch::EventCode::ENDED, touches, _obj.ref());
|
||||
JS::RootedObject obj(ScriptingCore::getInstance()->getGlobalContext(), _obj);
|
||||
ScriptingCore::getInstance()->executeCustomTouchesEvent(EventTouch::EventCode::ENDED, touches, obj);
|
||||
}
|
||||
|
||||
void JSTouchDelegate::onTouchesCancelled(const std::vector<Touch*>& touches, Event *event)
|
||||
{
|
||||
CC_UNUSED_PARAM(event);
|
||||
ScriptingCore::getInstance()->executeCustomTouchesEvent(EventTouch::EventCode::CANCELLED, touches, _obj.ref());
|
||||
JS::RootedObject obj(ScriptingCore::getInstance()->getGlobalContext(), _obj);
|
||||
ScriptingCore::getInstance()->executeCustomTouchesEvent(EventTouch::EventCode::CANCELLED, touches, obj);
|
||||
}
|
||||
|
||||
// cc.EventTouch#getTouches
|
||||
|
@ -538,6 +549,7 @@ void js_add_FinalizeHook(JSContext *cx, JS::HandleObject target)
|
|||
JS::RootedObject proto(cx, jsb_FinalizeHook_prototype);
|
||||
JS::RootedObject hook(cx, JS_NewObject(cx, jsb_FinalizeHook_class, proto, JS::NullPtr()));
|
||||
jsb_register_finalize_hook(hook.get(), target.get());
|
||||
CCLOG("======= %p", hook.get());
|
||||
JS::RootedValue hookVal(cx, OBJECT_TO_JSVAL(hook));
|
||||
JS_SetProperty(cx, target, "__hook", hookVal);
|
||||
}
|
||||
|
@ -678,111 +690,116 @@ void js_remove_object_root(JS::HandleValue target)
|
|||
|
||||
JSCallbackWrapper::JSCallbackWrapper()
|
||||
{
|
||||
ScriptingCore *engine = ScriptingCore::getInstance();
|
||||
JSContext* cx = engine->getGlobalContext();
|
||||
_jsCallback.construct(cx, JS::NullHandleValue);
|
||||
_jsThisObj.construct(cx, JS::NullHandleValue);
|
||||
_extraData.construct(cx, JS::NullHandleValue);
|
||||
_owner.construct(cx, JS::NullHandleValue);
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
_jsCallback = JS::NullValue();
|
||||
_jsThisObj = JS::NullValue();
|
||||
_extraData = JS::NullValue();
|
||||
|
||||
JS::RootedObject root(cx);
|
||||
get_or_create_js_obj("jsb._root", &root);
|
||||
JS::RootedValue valRoot(cx, OBJECT_TO_JSVAL(root));
|
||||
_owner.ref() = valRoot;
|
||||
_owner = valRoot;
|
||||
}
|
||||
|
||||
JSCallbackWrapper::JSCallbackWrapper(JS::HandleValue owner)
|
||||
{
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
_owner.construct(cx, JS::NullHandleValue);
|
||||
_owner.ref() = owner;
|
||||
_jsCallback.construct(cx, JS::NullHandleValue);
|
||||
_jsThisObj.construct(cx, JS::NullHandleValue);
|
||||
_extraData.construct(cx, JS::NullHandleValue);
|
||||
_owner = owner;
|
||||
_jsCallback = JS::NullValue();
|
||||
_jsThisObj = JS::NullValue();
|
||||
_extraData = JS::NullValue();
|
||||
}
|
||||
|
||||
JSCallbackWrapper::~JSCallbackWrapper()
|
||||
{
|
||||
if (!_owner.ref().isNullOrUndefined())
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
JS::RootedValue ownerVal(cx, _owner);
|
||||
if (!ownerVal.isNullOrUndefined())
|
||||
{
|
||||
if (!_jsCallback.ref().isNullOrUndefined())
|
||||
JS::RootedValue target(cx, _jsCallback);
|
||||
if (!target.isNullOrUndefined())
|
||||
{
|
||||
js_remove_object_reference(_owner.ref(), _jsCallback.ref());
|
||||
js_remove_object_reference(ownerVal, target);
|
||||
}
|
||||
if (!_jsThisObj.ref().isNullOrUndefined())
|
||||
target.set(_jsThisObj);
|
||||
if (!target.isNullOrUndefined())
|
||||
{
|
||||
js_remove_object_reference(_owner.ref(), _jsThisObj.ref());
|
||||
js_remove_object_reference(ownerVal, target);
|
||||
}
|
||||
if (!_extraData.ref().isNullOrUndefined())
|
||||
target.set(_extraData);
|
||||
if (!target.isNullOrUndefined())
|
||||
{
|
||||
js_remove_object_reference(_owner.ref(), _extraData.ref());
|
||||
js_remove_object_reference(ownerVal, target);
|
||||
}
|
||||
}
|
||||
|
||||
_owner.destroyIfConstructed();
|
||||
_jsCallback.destroyIfConstructed();
|
||||
_jsThisObj.destroyIfConstructed();
|
||||
_extraData.destroyIfConstructed();
|
||||
}
|
||||
|
||||
void JSCallbackWrapper::setJSCallbackFunc(JS::HandleValue func) {
|
||||
if (!_owner.ref().isNullOrUndefined())
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
JS::RootedValue ownerVal(cx, _owner);
|
||||
if (!ownerVal.isNullOrUndefined())
|
||||
{
|
||||
if (!_jsCallback.ref().isNullOrUndefined())
|
||||
JS::RootedValue target(cx, _jsCallback);
|
||||
if (!target.isNullOrUndefined())
|
||||
{
|
||||
js_remove_object_reference(_owner.ref(), _jsCallback.ref());
|
||||
js_remove_object_reference(ownerVal, target);
|
||||
}
|
||||
js_add_object_reference(_owner.ref(), func);
|
||||
js_add_object_reference(ownerVal, func);
|
||||
}
|
||||
if (!func.isNullOrUndefined())
|
||||
{
|
||||
_jsCallback.ref() = func;
|
||||
_jsCallback = func;
|
||||
}
|
||||
}
|
||||
|
||||
void JSCallbackWrapper::setJSCallbackThis(JS::HandleValue thisObj) {
|
||||
if (!_owner.ref().isNullOrUndefined())
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
JS::RootedValue ownerVal(cx, _owner);
|
||||
if (!ownerVal.isNullOrUndefined())
|
||||
{
|
||||
if (!_jsThisObj.ref().isNullOrUndefined())
|
||||
JS::RootedValue target(cx, _jsThisObj);
|
||||
if (!target.isNullOrUndefined())
|
||||
{
|
||||
js_remove_object_reference(_owner.ref(), _jsThisObj.ref());
|
||||
js_remove_object_reference(ownerVal, target);
|
||||
}
|
||||
js_add_object_reference(_owner.ref(), thisObj);
|
||||
js_add_object_reference(ownerVal, thisObj);
|
||||
}
|
||||
if (!thisObj.isNullOrUndefined())
|
||||
{
|
||||
_jsThisObj.ref() = thisObj;
|
||||
_jsThisObj = thisObj;
|
||||
}
|
||||
}
|
||||
|
||||
void JSCallbackWrapper::setJSExtraData(JS::HandleValue data) {
|
||||
if (!_owner.ref().isNullOrUndefined())
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
JS::RootedValue ownerVal(cx, _owner);
|
||||
if (!ownerVal.isNullOrUndefined())
|
||||
{
|
||||
if (!_extraData.ref().isNullOrUndefined())
|
||||
JS::RootedValue target(cx, _extraData);
|
||||
if (!target.isNullOrUndefined())
|
||||
{
|
||||
js_remove_object_reference(_owner.ref(), _extraData.ref());
|
||||
js_remove_object_reference(ownerVal, target);
|
||||
}
|
||||
js_add_object_reference(_owner.ref(), data);
|
||||
js_add_object_reference(ownerVal, data);
|
||||
}
|
||||
if (!data.isNullOrUndefined())
|
||||
{
|
||||
_extraData.ref() = data;
|
||||
_extraData = data;
|
||||
}
|
||||
}
|
||||
|
||||
const jsval JSCallbackWrapper::getJSCallbackFunc() const
|
||||
{
|
||||
return _jsCallback.ref().get();
|
||||
return _jsCallback;
|
||||
}
|
||||
|
||||
const jsval JSCallbackWrapper::getJSCallbackThis() const
|
||||
{
|
||||
return _jsThisObj.ref().get();
|
||||
return _jsThisObj;
|
||||
}
|
||||
|
||||
const jsval JSCallbackWrapper::getJSExtraData() const
|
||||
{
|
||||
return _extraData.ref().get();
|
||||
return _extraData;
|
||||
}
|
||||
|
||||
// cc.CallFunc.create( func, this, [data])
|
||||
|
@ -923,8 +940,7 @@ JSScheduleWrapper::JSScheduleWrapper()
|
|||
, _priority(0)
|
||||
, _isUpdateSchedule(false)
|
||||
{
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
_pPureJSTarget.construct(cx);
|
||||
_pPureJSTarget = nullptr;
|
||||
}
|
||||
|
||||
JSScheduleWrapper::JSScheduleWrapper(JS::HandleValue owner)
|
||||
|
@ -933,13 +949,7 @@ JSScheduleWrapper::JSScheduleWrapper(JS::HandleValue owner)
|
|||
, _priority(0)
|
||||
, _isUpdateSchedule(false)
|
||||
{
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
_pPureJSTarget.construct(cx);
|
||||
}
|
||||
|
||||
JSScheduleWrapper::~JSScheduleWrapper()
|
||||
{
|
||||
_pPureJSTarget.destroyIfConstructed();
|
||||
_pPureJSTarget = nullptr;
|
||||
}
|
||||
|
||||
void JSScheduleWrapper::setTargetForSchedule(JS::HandleValue sched, JSScheduleWrapper *target) {
|
||||
|
@ -1260,12 +1270,12 @@ void JSScheduleWrapper::setTarget(Ref* pTarget)
|
|||
|
||||
void JSScheduleWrapper::setPureJSTarget(JS::HandleObject pPureJSTarget)
|
||||
{
|
||||
_pPureJSTarget.ref() = pPureJSTarget;
|
||||
_pPureJSTarget = pPureJSTarget;
|
||||
}
|
||||
|
||||
JSObject* JSScheduleWrapper::getPureJSTarget()
|
||||
{
|
||||
return _pPureJSTarget.ref().get();
|
||||
return _pPureJSTarget;
|
||||
}
|
||||
|
||||
void JSScheduleWrapper::setPriority(int priority)
|
||||
|
|
|
@ -138,10 +138,10 @@ public:
|
|||
const jsval getJSCallbackThis() const;
|
||||
const jsval getJSExtraData() const;
|
||||
protected:
|
||||
mozilla::Maybe<JS::RootedValue> _owner;
|
||||
mozilla::Maybe<JS::RootedValue> _jsCallback;
|
||||
mozilla::Maybe<JS::RootedValue> _jsThisObj;
|
||||
mozilla::Maybe<JS::RootedValue> _extraData;
|
||||
JS::Heap<JS::Value> _owner;
|
||||
JS::Heap<JS::Value> _jsCallback;
|
||||
JS::Heap<JS::Value> _jsThisObj;
|
||||
JS::Heap<JS::Value> _extraData;
|
||||
};
|
||||
|
||||
|
||||
|
@ -150,7 +150,6 @@ class JSScheduleWrapper: public JSCallbackWrapper {
|
|||
public:
|
||||
JSScheduleWrapper();
|
||||
JSScheduleWrapper(JS::HandleValue owner);
|
||||
virtual ~JSScheduleWrapper();
|
||||
|
||||
static void setTargetForSchedule(JS::HandleValue sched, JSScheduleWrapper *target);
|
||||
static cocos2d::__Array * getTargetForSchedule(JS::HandleValue sched);
|
||||
|
@ -186,7 +185,7 @@ public:
|
|||
|
||||
protected:
|
||||
Ref* _pTarget;
|
||||
mozilla::Maybe<JS::RootedObject> _pPureJSTarget;
|
||||
JS::Heap<JSObject*> _pPureJSTarget;
|
||||
int _priority;
|
||||
bool _isUpdateSchedule;
|
||||
};
|
||||
|
@ -225,7 +224,7 @@ public:
|
|||
void onTouchesCancelled(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event *event);
|
||||
|
||||
private:
|
||||
mozilla::Maybe<JS::RootedObject> _obj;
|
||||
JS::Heap<JSObject*> _obj;
|
||||
typedef std::unordered_map<JSObject*, JSTouchDelegate*> TouchDelegateMap;
|
||||
typedef std::pair<JSObject*, JSTouchDelegate*> TouchDelegatePair;
|
||||
static TouchDelegateMap sTouchDelegateMap;
|
||||
|
|
|
@ -39,13 +39,7 @@ class JSB_ScrollViewDelegate
|
|||
public:
|
||||
JSB_ScrollViewDelegate()
|
||||
{
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
_JSDelegate.construct(cx);
|
||||
}
|
||||
|
||||
virtual ~JSB_ScrollViewDelegate()
|
||||
{
|
||||
_JSDelegate.destroyIfConstructed();
|
||||
_JSDelegate = nullptr;
|
||||
}
|
||||
|
||||
virtual void scrollViewDidScroll(ScrollView* view) override
|
||||
|
@ -54,7 +48,7 @@ public:
|
|||
if (!p) return;
|
||||
|
||||
jsval arg = OBJECT_TO_JSVAL(p->obj);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate.ref()), "scrollViewDidScroll", 1, &arg);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate), "scrollViewDidScroll", 1, &arg);
|
||||
}
|
||||
|
||||
virtual void scrollViewDidZoom(ScrollView* view) override
|
||||
|
@ -63,15 +57,15 @@ public:
|
|||
if (!p) return;
|
||||
|
||||
jsval arg = OBJECT_TO_JSVAL(p->obj);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate.ref()), "scrollViewDidZoom", 1, &arg);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate), "scrollViewDidZoom", 1, &arg);
|
||||
}
|
||||
|
||||
void setJSDelegate(JS::HandleObject pJSDelegate)
|
||||
{
|
||||
_JSDelegate.ref() = pJSDelegate;
|
||||
_JSDelegate = pJSDelegate;
|
||||
}
|
||||
private:
|
||||
mozilla::Maybe<JS::RootedObject> _JSDelegate;
|
||||
JS::Heap<JSObject*> _JSDelegate;
|
||||
};
|
||||
|
||||
static bool js_cocos2dx_CCScrollView_setDelegate(JSContext *cx, uint32_t argc, jsval *vp)
|
||||
|
@ -114,13 +108,7 @@ class JSB_TableViewDelegate
|
|||
public:
|
||||
JSB_TableViewDelegate()
|
||||
{
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
_JSDelegate.construct(cx);
|
||||
}
|
||||
|
||||
virtual ~JSB_TableViewDelegate()
|
||||
{
|
||||
_JSDelegate.destroyIfConstructed();
|
||||
_JSDelegate = nullptr;
|
||||
}
|
||||
|
||||
virtual void scrollViewDidScroll(ScrollView* view) override
|
||||
|
@ -155,7 +143,7 @@ public:
|
|||
|
||||
void setJSDelegate(JS::HandleObject pJSDelegate)
|
||||
{
|
||||
_JSDelegate.ref() = pJSDelegate;
|
||||
_JSDelegate = pJSDelegate;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -165,7 +153,7 @@ private:
|
|||
if (!p) return;
|
||||
|
||||
jsval arg = OBJECT_TO_JSVAL(p->obj);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate.ref()), jsFunctionName.c_str(), 1, &arg);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate), jsFunctionName.c_str(), 1, &arg);
|
||||
}
|
||||
|
||||
void callJSDelegate(TableView* table, TableViewCell* cell, std::string jsFunctionName)
|
||||
|
@ -180,10 +168,10 @@ private:
|
|||
args[0] = OBJECT_TO_JSVAL(p->obj);
|
||||
args[1] = OBJECT_TO_JSVAL(pCellProxy->obj);
|
||||
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate.ref()), jsFunctionName.c_str(), 2, args);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate), jsFunctionName.c_str(), 2, args);
|
||||
}
|
||||
|
||||
mozilla::Maybe<JS::RootedObject> _JSDelegate;
|
||||
JS::Heap<JSObject*> _JSDelegate;
|
||||
};
|
||||
|
||||
static bool js_cocos2dx_CCTableView_setDelegate(JSContext *cx, uint32_t argc, jsval *vp)
|
||||
|
@ -231,13 +219,7 @@ class JSB_TableViewDataSource
|
|||
public:
|
||||
JSB_TableViewDataSource()
|
||||
{
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
_JSTableViewDataSource.construct(cx);
|
||||
}
|
||||
|
||||
virtual ~JSB_TableViewDataSource()
|
||||
{
|
||||
_JSTableViewDataSource.destroyIfConstructed();
|
||||
_JSTableViewDataSource = nullptr;
|
||||
}
|
||||
|
||||
virtual Size tableCellSizeForIndex(TableView *table, ssize_t idx) override
|
||||
|
@ -297,7 +279,7 @@ public:
|
|||
|
||||
void setTableViewDataSource(JS::HandleObject pJSSource)
|
||||
{
|
||||
_JSTableViewDataSource.ref() = pJSSource;
|
||||
_JSTableViewDataSource = pJSSource;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -312,7 +294,7 @@ private:
|
|||
JS::RootedValue temp_retval(cx);
|
||||
jsval dataVal = OBJECT_TO_JSVAL(p->obj);
|
||||
|
||||
JS::RootedObject obj(cx, _JSTableViewDataSource.ref());
|
||||
JS::RootedObject obj(cx, _JSTableViewDataSource);
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
|
||||
if (JS_HasProperty(cx, obj, jsFunctionName.c_str(), &hasAction) && hasAction)
|
||||
|
@ -345,7 +327,7 @@ private:
|
|||
dataVal[0] = OBJECT_TO_JSVAL(p->obj);
|
||||
dataVal[1] = ssize_to_jsval(cx,idx);
|
||||
|
||||
JS::RootedObject obj(cx, _JSTableViewDataSource.ref());
|
||||
JS::RootedObject obj(cx, _JSTableViewDataSource);
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
|
||||
if (JS_HasProperty(cx, obj, jsFunctionName.c_str(), &hasAction) && hasAction)
|
||||
|
@ -368,7 +350,7 @@ private:
|
|||
}
|
||||
|
||||
private:
|
||||
mozilla::Maybe<JS::RootedObject> _JSTableViewDataSource;
|
||||
JS::Heap<JSObject*> _JSTableViewDataSource;
|
||||
};
|
||||
|
||||
static bool js_cocos2dx_CCTableView_setDataSource(JSContext *cx, uint32_t argc, jsval *vp)
|
||||
|
@ -541,14 +523,12 @@ public:
|
|||
: _callback(nullptr),
|
||||
_type(Control::EventType::TOUCH_DOWN)
|
||||
{
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
_jsFunc.construct(cx);
|
||||
_jsFunc = nullptr;
|
||||
}
|
||||
|
||||
virtual ~JSB_ControlButtonTarget()
|
||||
{
|
||||
CCLOGINFO("In the destruction of JSB_ControlButtonTarget ...");
|
||||
_jsFunc.destroyIfConstructed();
|
||||
|
||||
if (_callback != nullptr)
|
||||
{
|
||||
|
@ -593,7 +573,7 @@ public:
|
|||
}
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
_callback = new (std::nothrow) JSFunctionWrapper(cx, jsTarget, jsFunc);
|
||||
_jsFunc.ref() = jsFunc.toObjectOrNull();
|
||||
_jsFunc = jsFunc.toObjectOrNull();
|
||||
}
|
||||
|
||||
void setEventType(Control::EventType type)
|
||||
|
@ -605,7 +585,7 @@ public:
|
|||
static std::multimap<JSObject*, JSB_ControlButtonTarget*> _jsNativeTargetMap;
|
||||
JSFunctionWrapper *_callback;
|
||||
Control::EventType _type;
|
||||
mozilla::Maybe<JS::RootedObject> _jsFunc;
|
||||
JS::Heap<JSObject*> _jsFunc;
|
||||
};
|
||||
|
||||
std::multimap<JSObject*, JSB_ControlButtonTarget*> JSB_ControlButtonTarget::_jsNativeTargetMap;
|
||||
|
@ -631,7 +611,7 @@ static bool js_cocos2dx_CCControl_addTargetWithActionForControlEvents(JSContext
|
|||
auto range = JSB_ControlButtonTarget::_jsNativeTargetMap.equal_range(jsDelegate);
|
||||
for (auto it = range.first; it != range.second; ++it)
|
||||
{
|
||||
if (it->second->_jsFunc.ref().get() == jsFunc && arg2 == it->second->_type)
|
||||
if (it->second->_jsFunc.get() == jsFunc && arg2 == it->second->_type)
|
||||
{
|
||||
// Return true directly.
|
||||
args.rval().setUndefined();
|
||||
|
@ -695,7 +675,7 @@ static bool js_cocos2dx_CCControl_removeTargetWithActionForControlEvents(JSConte
|
|||
auto range = JSB_ControlButtonTarget::_jsNativeTargetMap.equal_range(obj);
|
||||
for (auto it = range.first; it != range.second; ++it)
|
||||
{
|
||||
if (it->second->_jsFunc.ref().get() == jsFunc && arg2 == it->second->_type)
|
||||
if (it->second->_jsFunc.get() == jsFunc && arg2 == it->second->_type)
|
||||
{
|
||||
nativeTargetToRemoved = it->second;
|
||||
JSB_ControlButtonTarget::_jsNativeTargetMap.erase(it);
|
||||
|
@ -842,8 +822,8 @@ __JSDownloaderDelegator::__JSDownloaderDelegator(JSContext *cx, JS::HandleObject
|
|||
: _cx(cx)
|
||||
, _url(url)
|
||||
{
|
||||
_obj.construct(_cx, obj);
|
||||
_jsCallback.construct(_cx, callback);
|
||||
_obj = obj;
|
||||
_jsCallback = callback;
|
||||
|
||||
JS::RootedValue target(cx, OBJECT_TO_JSVAL(obj));
|
||||
if (!target.isNullOrUndefined())
|
||||
|
@ -859,19 +839,17 @@ __JSDownloaderDelegator::__JSDownloaderDelegator(JSContext *cx, JS::HandleObject
|
|||
|
||||
__JSDownloaderDelegator::~__JSDownloaderDelegator()
|
||||
{
|
||||
JS::RootedValue target(_cx, OBJECT_TO_JSVAL(_obj.ref()));
|
||||
JS::RootedValue target(_cx, OBJECT_TO_JSVAL(_obj));
|
||||
if (!target.isNullOrUndefined())
|
||||
{
|
||||
js_remove_object_root(target);
|
||||
}
|
||||
target.set(OBJECT_TO_JSVAL(_jsCallback.ref()));
|
||||
target.set(OBJECT_TO_JSVAL(_jsCallback));
|
||||
if (!target.isNullOrUndefined())
|
||||
{
|
||||
js_remove_object_root(target);
|
||||
}
|
||||
|
||||
_obj.destroyIfConstructed();
|
||||
_jsCallback.destroyIfConstructed();
|
||||
_downloader->onTaskError = (nullptr);
|
||||
_downloader->onDataTaskSuccess = (nullptr);
|
||||
}
|
||||
|
@ -948,7 +926,7 @@ void __JSDownloaderDelegator::onError()
|
|||
{
|
||||
Director::getInstance()->getScheduler()->performFunctionInCocosThread([this]
|
||||
{
|
||||
JS::RootedValue callback(_cx, OBJECT_TO_JSVAL(_jsCallback.ref()));
|
||||
JS::RootedValue callback(_cx, OBJECT_TO_JSVAL(_jsCallback));
|
||||
if (!callback.isNull()) {
|
||||
JS::RootedObject global(_cx, ScriptingCore::getInstance()->getGlobalObject());
|
||||
JSAutoCompartment ac(_cx, global);
|
||||
|
@ -982,7 +960,7 @@ void __JSDownloaderDelegator::onSuccess(Texture2D *tex)
|
|||
valArr[1] = JSVAL_NULL;
|
||||
}
|
||||
|
||||
JS::RootedValue callback(_cx, OBJECT_TO_JSVAL(_jsCallback.ref()));
|
||||
JS::RootedValue callback(_cx, OBJECT_TO_JSVAL(_jsCallback));
|
||||
if (!callback.isNull())
|
||||
{
|
||||
JS::RootedValue retval(_cx);
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "cocos/network/CCDownloader.h"
|
||||
#include "renderer/CCTexture2D.h"
|
||||
|
||||
|
@ -50,8 +49,8 @@ private:
|
|||
std::shared_ptr<cocos2d::network::Downloader> _downloader;
|
||||
std::string _url;
|
||||
JSContext *_cx;
|
||||
mozilla::Maybe<JS::RootedObject> _jsCallback;
|
||||
mozilla::Maybe<JS::RootedObject> _obj;
|
||||
JS::Heap<JSObject*> _jsCallback;
|
||||
JS::Heap<JSObject*> _obj;
|
||||
};
|
||||
|
||||
void register_all_cocos2dx_extension_manual(JSContext* cx, JS::HandleObject global);
|
||||
|
|
|
@ -87,71 +87,74 @@ const char* JSStringWrapper::get()
|
|||
JSFunctionWrapper::JSFunctionWrapper(JSContext* cx, JS::HandleObject jsthis, JS::HandleValue fval)
|
||||
: _cx(cx)
|
||||
{
|
||||
_jsthis.construct(cx, jsthis);
|
||||
_fval.construct(cx, fval);
|
||||
_owner.construct(cx, JS::NullHandleValue);
|
||||
_jsthis = jsthis;
|
||||
_fval = fval;
|
||||
|
||||
JS::RootedObject root(cx);
|
||||
get_or_create_js_obj("jsb._root", &root);
|
||||
JS::RootedValue valRoot(cx, OBJECT_TO_JSVAL(root));
|
||||
_owner.ref() = valRoot;
|
||||
_owner = valRoot;
|
||||
|
||||
if (!valRoot.isNullOrUndefined())
|
||||
{
|
||||
JS::RootedValue thisVal(cx, OBJECT_TO_JSVAL(_jsthis.ref()));
|
||||
JS::RootedValue thisVal(cx, OBJECT_TO_JSVAL(_jsthis));
|
||||
if (!thisVal.isNullOrUndefined())
|
||||
{
|
||||
js_add_object_reference(valRoot, thisVal);
|
||||
}
|
||||
if (!_fval.ref().isNullOrUndefined())
|
||||
JS::RootedValue funcVal(cx, _fval);
|
||||
if (!funcVal.isNullOrUndefined())
|
||||
{
|
||||
js_add_object_reference(valRoot, _fval.ref());
|
||||
js_add_object_reference(valRoot, funcVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
JSFunctionWrapper::JSFunctionWrapper(JSContext* cx, JS::HandleObject jsthis, JS::HandleValue fval, JS::HandleValue owner)
|
||||
: _cx(cx)
|
||||
{
|
||||
_jsthis.construct(cx, jsthis);
|
||||
_fval.construct(cx, fval);
|
||||
_owner.construct(cx, owner);
|
||||
_jsthis = jsthis;
|
||||
_fval = fval;
|
||||
_owner = owner;
|
||||
JS::RootedValue ownerVal(cx, owner);
|
||||
|
||||
JS::RootedValue thisVal(cx, OBJECT_TO_JSVAL(_jsthis.ref()));
|
||||
JS::RootedValue thisVal(cx, OBJECT_TO_JSVAL(jsthis));
|
||||
if (!thisVal.isNullOrUndefined())
|
||||
{
|
||||
js_add_object_reference(owner, thisVal);
|
||||
js_add_object_reference(ownerVal, thisVal);
|
||||
}
|
||||
if (!_fval.ref().isNullOrUndefined())
|
||||
JS::RootedValue funcVal(cx, _fval);
|
||||
if (!funcVal.isNullOrUndefined())
|
||||
{
|
||||
js_add_object_reference(owner, _fval.ref());
|
||||
js_add_object_reference(ownerVal, funcVal);
|
||||
}
|
||||
}
|
||||
|
||||
JSFunctionWrapper::~JSFunctionWrapper()
|
||||
{
|
||||
if (!_owner.ref().isNullOrUndefined())
|
||||
JS::RootedValue ownerVal(_cx, _owner);
|
||||
|
||||
if (!ownerVal.isNullOrUndefined())
|
||||
{
|
||||
JS::RootedValue thisVal(_cx, OBJECT_TO_JSVAL(_jsthis.ref()));
|
||||
JS::RootedValue thisVal(_cx, OBJECT_TO_JSVAL(_jsthis));
|
||||
if (!thisVal.isNullOrUndefined())
|
||||
{
|
||||
js_remove_object_reference(_owner.ref(), thisVal);
|
||||
js_remove_object_reference(ownerVal, thisVal);
|
||||
}
|
||||
if (!_fval.ref().isNullOrUndefined())
|
||||
JS::RootedValue funcVal(_cx, _fval);
|
||||
if (!funcVal.isNullOrUndefined())
|
||||
{
|
||||
js_remove_object_reference(_owner.ref(), _fval.ref());
|
||||
js_remove_object_reference(ownerVal, funcVal);
|
||||
}
|
||||
}
|
||||
|
||||
_jsthis.destroyIfConstructed();
|
||||
_fval.destroyIfConstructed();
|
||||
_owner.destroyIfConstructed();
|
||||
}
|
||||
|
||||
bool JSFunctionWrapper::invoke(unsigned int argc, jsval *argv, JS::MutableHandleValue rval)
|
||||
{
|
||||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
|
||||
return JS_CallFunctionValue(_cx, _jsthis.ref(), _fval.ref(), JS::HandleValueArray::fromMarkedLocation(argc, argv), rval);
|
||||
JS::RootedObject thisObj(_cx, _jsthis);
|
||||
JS::RootedValue fval(_cx, _fval);
|
||||
return JS_CallFunctionValue(_cx, thisObj, fval, JS::HandleValueArray::fromMarkedLocation(argc, argv), rval);
|
||||
}
|
||||
|
||||
static Color3B getColorFromJSObject(JSContext *cx, JS::HandleObject colorObject)
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "cocos2d.h"
|
||||
#include "spidermonkey_specifics.h"
|
||||
#include "js-BindingsExport.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
#define JSB_COMPATIBLE_WITH_COCOS2D_HTML5_BASIC_TYPES
|
||||
|
||||
|
@ -71,9 +70,9 @@ public:
|
|||
bool invoke(unsigned int argc, jsval *argv, JS::MutableHandleValue rval);
|
||||
private:
|
||||
JSContext *_cx;
|
||||
mozilla::Maybe<JS::RootedObject> _jsthis;
|
||||
mozilla::Maybe<JS::RootedValue> _fval;
|
||||
mozilla::Maybe<JS::RootedValue> _owner;
|
||||
JS::Heap<JSObject*> _jsthis;
|
||||
JS::Heap<JS::Value> _fval;
|
||||
JS::Heap<JS::Value> _owner;
|
||||
private:
|
||||
CC_DISALLOW_COPY_AND_ASSIGN(JSFunctionWrapper);
|
||||
};
|
||||
|
|
|
@ -215,8 +215,17 @@ void MinXmlHttpRequest::handle_requestResponse(cocos2d::network::HttpClient *sen
|
|||
_errorFlag = true;
|
||||
_status = 0;
|
||||
_statusText.clear();
|
||||
_notify(_onerrorCallback.ref());
|
||||
_notify(_onloadendCallback.ref());
|
||||
JS::RootedObject callback(_cx);
|
||||
if (_onerrorCallback)
|
||||
{
|
||||
callback.set(_onerrorCallback);
|
||||
_notify(callback);
|
||||
}
|
||||
if (_onloadendCallback)
|
||||
{
|
||||
callback.set(_onloadendCallback);
|
||||
_notify(callback);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -244,9 +253,22 @@ void MinXmlHttpRequest::handle_requestResponse(cocos2d::network::HttpClient *sen
|
|||
_data[_dataSize] = '\0';
|
||||
memcpy((void*)_data, (const void*)buffer->data(), _dataSize);
|
||||
|
||||
_notify(_onreadystateCallback.ref());
|
||||
_notify(_onloadCallback.ref());
|
||||
_notify(_onloadendCallback.ref());
|
||||
JS::RootedObject callback(_cx);
|
||||
if (_onreadystateCallback)
|
||||
{
|
||||
callback.set(_onreadystateCallback);
|
||||
_notify(callback);
|
||||
}
|
||||
if (_onloadCallback)
|
||||
{
|
||||
callback.set(_onloadCallback);
|
||||
_notify(callback);
|
||||
}
|
||||
if (_onloadendCallback)
|
||||
{
|
||||
callback.set(_onloadendCallback);
|
||||
_notify(callback);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Send out request and fire callback when done.
|
||||
|
@ -259,13 +281,19 @@ void MinXmlHttpRequest::_sendRequest(JSContext *cx)
|
|||
_httpRequest->release();
|
||||
}
|
||||
|
||||
MinXmlHttpRequest::MinXmlHttpRequest()
|
||||
: _url()
|
||||
{
|
||||
MinXmlHttpRequest(ScriptingCore::getInstance()->getGlobalContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor initializes cchttprequest and stuff
|
||||
*
|
||||
*/
|
||||
MinXmlHttpRequest::MinXmlHttpRequest()
|
||||
MinXmlHttpRequest::MinXmlHttpRequest(JSContext *cx)
|
||||
: _url()
|
||||
, _cx(ScriptingCore::getInstance()->getGlobalContext())
|
||||
, _cx(cx)
|
||||
, _meth()
|
||||
, _type()
|
||||
, _data(nullptr)
|
||||
|
@ -284,18 +312,16 @@ MinXmlHttpRequest::MinXmlHttpRequest()
|
|||
, _httpHeader()
|
||||
, _requestHeader()
|
||||
, _isAborted(false)
|
||||
, _onreadystateCallback(nullptr)
|
||||
, _onloadstartCallback(nullptr)
|
||||
, _onabortCallback(nullptr)
|
||||
, _onerrorCallback(nullptr)
|
||||
, _onloadCallback(nullptr)
|
||||
, _onloadendCallback(nullptr)
|
||||
, _ontimeoutCallback(nullptr)
|
||||
{
|
||||
_scheduler = cocos2d::Director::getInstance()->getScheduler();
|
||||
_scheduler->retain();
|
||||
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
_onreadystateCallback.construct(cx);
|
||||
_onloadstartCallback.construct(cx);
|
||||
_onabortCallback.construct(cx);
|
||||
_onerrorCallback.construct(cx);
|
||||
_onloadCallback.construct(cx);
|
||||
_onloadendCallback.construct(cx);
|
||||
_ontimeoutCallback.construct(cx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -304,13 +330,42 @@ MinXmlHttpRequest::MinXmlHttpRequest()
|
|||
*/
|
||||
MinXmlHttpRequest::~MinXmlHttpRequest()
|
||||
{
|
||||
_onreadystateCallback.destroyIfConstructed();
|
||||
_onloadstartCallback.destroyIfConstructed();
|
||||
_onloadendCallback.destroyIfConstructed();
|
||||
_onloadCallback.destroyIfConstructed();
|
||||
_onerrorCallback.destroyIfConstructed();
|
||||
_onabortCallback.destroyIfConstructed();
|
||||
_ontimeoutCallback.destroyIfConstructed();
|
||||
JS::RootedValue callback(_cx);
|
||||
if (_onreadystateCallback)
|
||||
{
|
||||
callback.set(OBJECT_TO_JSVAL(_onreadystateCallback));
|
||||
js_remove_object_root(callback);
|
||||
}
|
||||
if (_onloadstartCallback)
|
||||
{
|
||||
callback.set(OBJECT_TO_JSVAL(_onloadstartCallback));
|
||||
js_remove_object_root(callback);
|
||||
}
|
||||
if (_onabortCallback)
|
||||
{
|
||||
callback.set(OBJECT_TO_JSVAL(_onabortCallback));
|
||||
js_remove_object_root(callback);
|
||||
}
|
||||
if (_onerrorCallback)
|
||||
{
|
||||
callback.set(OBJECT_TO_JSVAL(_onerrorCallback));
|
||||
js_remove_object_root(callback);
|
||||
}
|
||||
if (_onloadCallback)
|
||||
{
|
||||
callback.set(OBJECT_TO_JSVAL(_onloadCallback));
|
||||
js_remove_object_root(callback);
|
||||
}
|
||||
if (_onloadendCallback)
|
||||
{
|
||||
callback.set(OBJECT_TO_JSVAL(_onloadendCallback));
|
||||
js_remove_object_root(callback);
|
||||
}
|
||||
if (_ontimeoutCallback)
|
||||
{
|
||||
callback.set(OBJECT_TO_JSVAL(_ontimeoutCallback));
|
||||
js_remove_object_root(callback);
|
||||
}
|
||||
|
||||
if (_httpRequest)
|
||||
{
|
||||
|
@ -335,7 +390,7 @@ JS_BINDED_CLASS_GLUE_IMPL(MinXmlHttpRequest);
|
|||
JS_BINDED_CONSTRUCTOR_IMPL(MinXmlHttpRequest)
|
||||
{
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
MinXmlHttpRequest* req = new (std::nothrow) MinXmlHttpRequest();
|
||||
MinXmlHttpRequest* req = new (std::nothrow) MinXmlHttpRequest(cx);
|
||||
|
||||
JS::RootedObject proto(cx, MinXmlHttpRequest::js_proto);
|
||||
JS::RootedObject parentProto(cx, MinXmlHttpRequest::js_parent);
|
||||
|
@ -378,9 +433,9 @@ JS_BINDED_CONSTRUCTOR_IMPL(MinXmlHttpRequest)
|
|||
*/
|
||||
#define GETTER_SETTER_FOR_CALLBACK_PROP(x,y) JS_BINDED_PROP_GET_IMPL(MinXmlHttpRequest, x)\
|
||||
{\
|
||||
if (y.ref())\
|
||||
if (y)\
|
||||
{\
|
||||
JS::RootedValue out(cx, OBJECT_TO_JSVAL(y.ref()));\
|
||||
JS::RootedValue out(cx, OBJECT_TO_JSVAL(y));\
|
||||
args.rval().set(out);\
|
||||
}\
|
||||
else\
|
||||
|
@ -394,12 +449,13 @@ JS_BINDED_PROP_SET_IMPL(MinXmlHttpRequest, x)\
|
|||
JS::RootedValue callback(cx, args.get(0));\
|
||||
if (!callback.isNullOrUndefined())\
|
||||
{\
|
||||
js_proxy_t *p = jsb_get_native_proxy(this);\
|
||||
if (p) {\
|
||||
JS::RootedObject thisObj(cx, p->obj);\
|
||||
JS_SetProperty(cx, thisObj, "y", callback);\
|
||||
if (y)\
|
||||
{\
|
||||
JS::RootedValue oldCallback(cx, OBJECT_TO_JSVAL(y));\
|
||||
js_remove_object_root(oldCallback);\
|
||||
}\
|
||||
y.ref() = callback.toObjectOrNull();\
|
||||
js_add_object_root(callback);\
|
||||
y = callback.toObjectOrNull();\
|
||||
}\
|
||||
return true;\
|
||||
}
|
||||
|
@ -775,7 +831,11 @@ JS_BINDED_FUNC_IMPL(MinXmlHttpRequest, send)
|
|||
|
||||
_setHttpRequestHeader();
|
||||
_sendRequest(cx);
|
||||
_notify(_onloadstartCallback.ref());
|
||||
if (_onloadstartCallback)
|
||||
{
|
||||
JS::RootedObject callback(cx, _onloadstartCallback);
|
||||
_notify(callback);
|
||||
}
|
||||
|
||||
//begin schedule for timeout
|
||||
if(_timeout > 0)
|
||||
|
@ -791,7 +851,11 @@ void MinXmlHttpRequest::update(float dt)
|
|||
_elapsedTime += dt;
|
||||
if(_elapsedTime * 1000 >= _timeout)
|
||||
{
|
||||
_notify(_ontimeoutCallback.ref());
|
||||
if (_ontimeoutCallback)
|
||||
{
|
||||
JS::RootedObject callback(_cx, _ontimeoutCallback);
|
||||
_notify(callback);
|
||||
}
|
||||
_elapsedTime = 0;
|
||||
_readyState = UNSENT;
|
||||
_scheduler->unscheduleAllForTarget(this);
|
||||
|
@ -813,7 +877,11 @@ JS_BINDED_FUNC_IMPL(MinXmlHttpRequest, abort)
|
|||
//3.Change the state to UNSENT.
|
||||
_readyState = UNSENT;
|
||||
|
||||
_notify(_onabortCallback.ref());
|
||||
if (_onabortCallback)
|
||||
{
|
||||
JS::RootedObject callback(cx, _onabortCallback);
|
||||
_notify(callback);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -946,15 +1014,14 @@ void MinXmlHttpRequest::_notify(JS::HandleObject callback)
|
|||
|
||||
if(p)
|
||||
{
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
|
||||
if (callback)
|
||||
{
|
||||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
JS::RootedObject obj(_cx, p->obj);
|
||||
JSAutoCompartment ac(_cx, obj);
|
||||
//JS_IsExceptionPending(cx) && JS_ReportPendingException(cx);
|
||||
JS::RootedValue fval(cx, OBJECT_TO_JSVAL(callback));
|
||||
JS::RootedValue out(cx);
|
||||
JS_CallFunctionValue(cx, JS::NullPtr(), fval, JS::HandleValueArray::empty(), &out);
|
||||
JS::RootedValue callbackVal(_cx, OBJECT_TO_JSVAL(callback));
|
||||
JS::RootedValue out(_cx);
|
||||
JS_CallFunctionValue(_cx, JS::NullPtr(), callbackVal, JS::HandleValueArray::empty(), &out);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
static const unsigned short DONE = 4;
|
||||
|
||||
MinXmlHttpRequest();
|
||||
MinXmlHttpRequest(JSContext *cx);
|
||||
~MinXmlHttpRequest();
|
||||
|
||||
JS_BINDED_CLASS_GLUE(MinXmlHttpRequest);
|
||||
|
@ -102,13 +103,13 @@ private:
|
|||
std::string _type;
|
||||
char* _data;
|
||||
uint32_t _dataSize;
|
||||
mozilla::Maybe<JS::RootedObject> _onloadstartCallback;
|
||||
mozilla::Maybe<JS::RootedObject> _onabortCallback;
|
||||
mozilla::Maybe<JS::RootedObject> _onerrorCallback;
|
||||
mozilla::Maybe<JS::RootedObject> _onloadCallback;
|
||||
mozilla::Maybe<JS::RootedObject> _onloadendCallback;
|
||||
mozilla::Maybe<JS::RootedObject> _ontimeoutCallback;
|
||||
mozilla::Maybe<JS::RootedObject> _onreadystateCallback;
|
||||
JS::Heap<JSObject*> _onloadstartCallback;
|
||||
JS::Heap<JSObject*> _onabortCallback;
|
||||
JS::Heap<JSObject*> _onerrorCallback;
|
||||
JS::Heap<JSObject*> _onloadCallback;
|
||||
JS::Heap<JSObject*> _onloadendCallback;
|
||||
JS::Heap<JSObject*> _ontimeoutCallback;
|
||||
JS::Heap<JSObject*> _onreadystateCallback;
|
||||
int _readyState;
|
||||
long _status;
|
||||
std::string _statusText;
|
||||
|
|
|
@ -116,13 +116,7 @@ class JSB_EditBoxDelegate
|
|||
public:
|
||||
JSB_EditBoxDelegate()
|
||||
{
|
||||
JSContext *cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
_JSDelegate.construct(cx, JS::NullHandleValue);
|
||||
}
|
||||
|
||||
virtual ~JSB_EditBoxDelegate()
|
||||
{
|
||||
_JSDelegate.destroyIfConstructed();
|
||||
_JSDelegate = JS::NullValue();
|
||||
}
|
||||
|
||||
virtual void editBoxEditingDidBegin(EditBox* editBox) override
|
||||
|
@ -131,7 +125,8 @@ public:
|
|||
if (!p) return;
|
||||
|
||||
jsval arg = OBJECT_TO_JSVAL(p->obj);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(_JSDelegate.ref().get(), "editBoxEditingDidBegin", 1, &arg);
|
||||
JS::RootedValue delegateVal(ScriptingCore::getInstance()->getGlobalContext(), _JSDelegate);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(delegateVal, "editBoxEditingDidBegin", 1, &arg);
|
||||
}
|
||||
|
||||
virtual void editBoxEditingDidEnd(EditBox* editBox) override
|
||||
|
@ -140,7 +135,8 @@ public:
|
|||
if (!p) return;
|
||||
|
||||
jsval arg = OBJECT_TO_JSVAL(p->obj);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(_JSDelegate.ref().get(), "editBoxEditingDidEnd", 1, &arg);
|
||||
JS::RootedValue delegateVal(ScriptingCore::getInstance()->getGlobalContext(), _JSDelegate);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(delegateVal, "editBoxEditingDidEnd", 1, &arg);
|
||||
}
|
||||
|
||||
virtual void editBoxTextChanged(EditBox* editBox, const std::string& text) override
|
||||
|
@ -148,12 +144,15 @@ public:
|
|||
js_proxy_t * p = jsb_get_native_proxy(editBox);
|
||||
if (!p) return;
|
||||
|
||||
JSContext *cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
|
||||
jsval dataVal[2];
|
||||
dataVal[0] = OBJECT_TO_JSVAL(p->obj);
|
||||
std::string arg1 = text;
|
||||
dataVal[1] = std_string_to_jsval(ScriptingCore::getInstance()->getGlobalContext(), arg1);
|
||||
dataVal[1] = std_string_to_jsval(cx, arg1);
|
||||
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(_JSDelegate.ref().get(), "editBoxTextChanged", 2, dataVal);
|
||||
JS::RootedValue delegateVal(cx, _JSDelegate);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(delegateVal, "editBoxTextChanged", 2, dataVal);
|
||||
}
|
||||
|
||||
virtual void editBoxReturn(EditBox* editBox) override
|
||||
|
@ -162,15 +161,16 @@ public:
|
|||
if (!p) return;
|
||||
|
||||
jsval arg = OBJECT_TO_JSVAL(p->obj);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(_JSDelegate.ref().get(), "editBoxReturn", 1, &arg);
|
||||
JS::RootedValue delegateVal(ScriptingCore::getInstance()->getGlobalContext(), _JSDelegate);
|
||||
ScriptingCore::getInstance()->executeFunctionWithOwner(delegateVal, "editBoxReturn", 1, &arg);
|
||||
}
|
||||
|
||||
void setJSDelegate(JS::HandleValue pJSDelegate)
|
||||
{
|
||||
_JSDelegate.ref() = pJSDelegate;
|
||||
_JSDelegate = pJSDelegate;
|
||||
}
|
||||
private:
|
||||
mozilla::Maybe<JS::RootedValue> _JSDelegate;
|
||||
JS::Heap<JS::Value> _JSDelegate;
|
||||
};
|
||||
|
||||
static bool js_cocos2dx_CCEditBox_setDelegate(JSContext *cx, uint32_t argc, jsval *vp)
|
||||
|
|
Loading…
Reference in New Issue