Merge pull request #14645 from ricardoquesada/js_fixes

Squashed commit of the following:
This commit is contained in:
Ricardo Quesada 2015-12-11 09:42:53 -08:00
commit 8878992a79
13 changed files with 440 additions and 227 deletions

View File

@ -64,8 +64,8 @@ static bool js_cocos2dx_Sprite3D_createAsync(JSContext *cx, uint32_t argc, jsval
auto lambda = [=](Sprite3D* larg0, void* larg1) -> void{ auto lambda = [=](Sprite3D* larg0, void* larg1) -> void{
jsval largv[2]; jsval largv[2];
js_proxy_t* proxy = js_get_or_create_proxy(cx, larg0); JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
largv[0] = proxy ? OBJECT_TO_JSVAL(proxy->obj) : JS::UndefinedValue(); largv[0] = OBJECT_TO_JSVAL(js_get_or_create_jsobject<Sprite3D>(cx, larg0));
JSB_HeapValueWrapper* v = (JSB_HeapValueWrapper*)larg1; JSB_HeapValueWrapper* v = (JSB_HeapValueWrapper*)larg1;
largv[1] = v->get(); largv[1] = v->get();
@ -280,8 +280,7 @@ bool js_cocos2dx_Terrain_create(JSContext *cx, uint32_t argc, jsval *vp)
ret = Terrain::create(arg0, arg1); ret = Terrain::create(arg0, arg1);
} }
js_proxy_t *jsProxy = js_get_or_create_proxy<Terrain>(cx, (Terrain*)ret); args.rval().set(OBJECT_TO_JSVAL(js_get_or_create_jsobject<Terrain>(cx, ret)));
args.rval().set(OBJECT_TO_JSVAL(jsProxy->obj));
return true; return true;
} }
JS_ReportError(cx, "wrong number of arguments"); JS_ReportError(cx, "wrong number of arguments");
@ -342,6 +341,42 @@ bool js_cocos2dx_Terrain_getHeightData(JSContext *cx, uint32_t argc, jsval *vp)
return false; return false;
} }
// this code cannot be automated since it must use
// get_or_create_jsobject instead of create_jsobject
// since Animation3D::create() might return an existing copy
// since it caches them
bool js_cocos2dx_3d_Animation3D_create(JSContext *cx, uint32_t argc, jsval *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
bool ok = true;
if (argc == 1) {
std::string arg0;
ok &= jsval_to_std_string(cx, args.get(0), &arg0);
JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_3d_Animation3D_create : Error processing arguments");
auto ret = cocos2d::Animation3D::create(arg0);
js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Animation3D>(ret);
JS::RootedObject jsret(cx, jsb_ref_autoreleased_get_or_create_jsobject(cx, ret, typeClass, "cocos2d::Animation3D"));
args.rval().set(OBJECT_TO_JSVAL(jsret));
return true;
}
if (argc == 2) {
std::string arg0;
std::string arg1;
ok &= jsval_to_std_string(cx, args.get(0), &arg0);
ok &= jsval_to_std_string(cx, args.get(1), &arg1);
JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_3d_Animation3D_create : Error processing arguments");
auto ret = cocos2d::Animation3D::create(arg0, arg1);
js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Animation3D>(ret);
JS::RootedObject jsret(cx, jsb_ref_autoreleased_get_or_create_jsobject(cx, ret, typeClass, "cocos2d::Animation3D"));
args.rval().set(OBJECT_TO_JSVAL(jsret));
return true;
}
JS_ReportError(cx, "js_cocos2dx_3d_Animation3D_create : wrong number of arguments");
return false;
}
void register_all_cocos2dx_3d_manual(JSContext *cx, JS::HandleObject global) void register_all_cocos2dx_3d_manual(JSContext *cx, JS::HandleObject global)
{ {
JS::RootedValue tmpVal(cx); JS::RootedValue tmpVal(cx);
@ -357,6 +392,10 @@ void register_all_cocos2dx_3d_manual(JSContext *cx, JS::HandleObject global)
tmpObj.set(tmpVal.toObjectOrNull()); tmpObj.set(tmpVal.toObjectOrNull());
JS_DefineFunction(cx, tmpObj, "create", js_cocos2dx_Terrain_create, 2, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(cx, tmpObj, "create", js_cocos2dx_Terrain_create, 2, JSPROP_READONLY | JSPROP_PERMANENT);
JS_GetProperty(cx, ccObj, "Animation3D", &tmpVal);
tmpObj.set(tmpVal.toObjectOrNull());
JS_DefineFunction(cx, tmpObj, "create", js_cocos2dx_3d_Animation3D_create, 2, JSPROP_READONLY | JSPROP_PERMANENT);
JS_GetProperty(cx, ccObj, "Bundle3D", &tmpVal); JS_GetProperty(cx, ccObj, "Bundle3D", &tmpVal);
tmpObj.set(tmpVal.toObjectOrNull()); tmpObj.set(tmpVal.toObjectOrNull());
JS_DefineFunction(cx, tmpObj, "getTrianglesList", js_cocos2dx_Bundle3D_getTrianglesList, 1, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(cx, tmpObj, "getTrianglesList", js_cocos2dx_Bundle3D_getTrianglesList, 1, JSPROP_READONLY | JSPROP_PERMANENT);

View File

@ -430,8 +430,9 @@ void registerDefaultClasses(JSContext* cx, JS::HandleObject global) {
JS_DefineFunction(cx, global, "__isObjectValid", ScriptingCore::isObjectValid, 1, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(cx, global, "__isObjectValid", ScriptingCore::isObjectValid, 1, JSPROP_READONLY | JSPROP_PERMANENT);
} }
static void sc_finalize(JSFreeOp *freeOp, JSObject *obj) { static void sc_finalize(JSFreeOp *freeOp, JSObject *obj)
CCLOGINFO("jsbindings: finalizing JS object %p (global class)", obj); {
CCLOG("jsbindings: finalizing JS object %p (global class)", obj);
} }
//static JSClass global_class = { //static JSClass global_class = {
@ -1181,10 +1182,17 @@ bool ScriptingCore::handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::Eve
// AddNamedObjectRoot(this->_cx, &jsretArr, "touchArray"); // AddNamedObjectRoot(this->_cx, &jsretArr, "touchArray");
int count = 0; int count = 0;
js_type_class_t *typeClassEvent = nullptr;
js_type_class_t *typeClassTouch = nullptr;
if (touches.size()>0)
typeClassTouch = js_get_type_from_native<cocos2d::Touch>(touches[0]);
typeClassEvent = js_get_type_from_native<cocos2d::Event>(event);
for (const auto& touch : touches) for (const auto& touch : touches)
{ {
JS::RootedValue jsret(_cx, OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::Touch>(this->_cx, touch))); JS::RootedValue jsret(_cx, OBJECT_TO_JSVAL(jsb_ref_get_or_create_jsobject(_cx, touch, typeClassTouch, "cocos2d::Touch")));
if (!JS_SetElement(this->_cx, jsretArr, count, jsret)) if (!JS_SetElement(this->_cx, jsretArr, count, jsret))
{ {
break; break;
@ -1192,19 +1200,14 @@ bool ScriptingCore::handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::Eve
++count; ++count;
} }
do js_proxy_t* p = jsb_get_native_proxy(nativeObj);
if (p)
{ {
js_proxy_t * p = jsb_get_native_proxy(nativeObj);
if (!p) break;
jsval dataVal[2]; jsval dataVal[2];
dataVal[0] = OBJECT_TO_JSVAL(jsretArr); dataVal[0] = OBJECT_TO_JSVAL(jsretArr);
dataVal[1] = OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::Event>(_cx, event)); dataVal[1] = OBJECT_TO_JSVAL(jsb_ref_get_or_create_jsobject(_cx, event, typeClassEvent, "cocos2d::Event"));
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), funcName.c_str(), 2, dataVal, jsvalRet); ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), funcName.c_str(), 2, dataVal, jsvalRet);
}
} while(false);
// JS_RemoveObjectRoot(this->_cx, &jsretArr); // JS_RemoveObjectRoot(this->_cx, &jsretArr);
@ -1231,37 +1234,18 @@ bool ScriptingCore::handleTouchEvent(void* nativeObj, cocos2d::EventTouch::Event
std::string funcName = getTouchFuncName(eventCode); std::string funcName = getTouchFuncName(eventCode);
bool ret = false; bool ret = false;
do js_proxy_t * p = jsb_get_native_proxy(nativeObj);
if (p)
{ {
js_proxy_t * p = jsb_get_native_proxy(nativeObj); js_type_class_t *typeClassTouch = js_get_type_from_native<cocos2d::Touch>(touch);
if (!p) break; js_type_class_t *typeClassEvent = js_get_type_from_native<cocos2d::Event>(event);
jsval dataVal[2]; jsval dataVal[2];
dataVal[0] = OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::Touch>(_cx, touch)); dataVal[0] = OBJECT_TO_JSVAL(jsb_ref_get_or_create_jsobject(_cx, touch, typeClassTouch, "cocos2d::Touch"));
dataVal[1] = OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::Event>(_cx, event)); dataVal[1] = OBJECT_TO_JSVAL(jsb_ref_get_or_create_jsobject(_cx, event, typeClassEvent, "cocos2d::Event"));
// if (jsvalRet != nullptr) ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), funcName.c_str(), 2, dataVal, jsvalRet);
// { }
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), funcName.c_str(), 2, dataVal, jsvalRet);
// }
// else
// {
// JS::RootedValue retval(_cx);
// executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), funcName.c_str(), 2, dataVal, &retval);
// if(retval.isNull())
// {
// ret = false;
// }
// else if(retval.isBoolean())
// {
// ret = retval.toBoolean();
// }
// else
// {
// ret = false;
// }
// }
} while(false);
removeJSObject(_cx, touch); removeJSObject(_cx, touch);
removeJSObject(_cx, event); removeJSObject(_cx, event);
@ -1282,37 +1266,15 @@ bool ScriptingCore::handleMouseEvent(void* nativeObj, cocos2d::EventMouse::Mouse
std::string funcName = getMouseFuncName(eventType); std::string funcName = getMouseFuncName(eventType);
bool ret = false; bool ret = false;
do js_proxy_t * p = jsb_get_native_proxy(nativeObj);
if (p)
{ {
js_proxy_t * p = jsb_get_native_proxy(nativeObj);
if (!p) break;
jsval dataVal[1]; jsval dataVal[1];
dataVal[0] = OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::Event>(_cx, event)); js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Event>(event);
dataVal[0] = OBJECT_TO_JSVAL(jsb_ref_get_or_create_jsobject(_cx, event, typeClass, "cocos2d::Event"));
// if (jsvalRet != nullptr) ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), funcName.c_str(), 1, dataVal, jsvalRet);
// { }
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), funcName.c_str(), 1, dataVal, jsvalRet);
// }
// else
// {
// JS::RootedValue retval(_cx);
// executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), funcName.c_str(), 1, dataVal, &retval);
// if(retval.isNull())
// {
// ret = false;
// }
// else if(retval.isBoolean())
// {
// ret = retval.toBoolean();
// }
// else
// {
// ret = false;
// }
// }
} while(false);
removeJSObject(_cx, event); removeJSObject(_cx, event);
return ret; return ret;
@ -1396,10 +1358,11 @@ bool ScriptingCore::handleKeybardEvent(void* nativeObj, cocos2d::EventKeyboard::
return false; return false;
bool ret = false; bool ret = false;
js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Event>(event);
jsval args[2] = { jsval args[2] = {
int32_to_jsval(_cx, (int32_t)keyCode), int32_to_jsval(_cx, (int32_t)keyCode),
OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::Event>(_cx, event)) OBJECT_TO_JSVAL(jsb_ref_get_or_create_jsobject(_cx, event, typeClass, "cocos2d::Event"))
}; };
if (isPressed) if (isPressed)
@ -1425,9 +1388,11 @@ bool ScriptingCore::handleFocusEvent(void* nativeObj, cocos2d::ui::Widget* widge
if (nullptr == p) if (nullptr == p)
return false; return false;
js_type_class_t *typeClass = js_get_type_from_native<cocos2d::ui::Widget>(widgetLoseFocus);
jsval args[2] = { jsval args[2] = {
OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::ui::Widget>(_cx, widgetLoseFocus)), OBJECT_TO_JSVAL(jsb_ref_get_or_create_jsobject(_cx, widgetLoseFocus, typeClass, "cocos2d::ui::Widget")),
OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::ui::Widget>(_cx, widgetGetFocus)) OBJECT_TO_JSVAL(jsb_ref_get_or_create_jsobject(_cx, widgetGetFocus, typeClass, "cocos2d::ui::Widget"))
}; };
bool ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), "onFocusChanged", 2, args); bool ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), "onFocusChanged", 2, args);
@ -1446,7 +1411,9 @@ int ScriptingCore::executeCustomTouchesEvent(EventTouch::EventCode eventType,
int count = 0; int count = 0;
for (auto& touch : touches) for (auto& touch : touches)
{ {
jsval jsret = OBJECT_TO_JSVAL(js_get_or_create_jsobject<Touch>(this->_cx, touch)); js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Touch>(touch);
jsval jsret = OBJECT_TO_JSVAL(jsb_ref_get_or_create_jsobject(this->_cx, touch, typeClass, "cocos2d::Touch"));
JS::RootedValue jsval(_cx, jsret); JS::RootedValue jsval(_cx, jsret);
if (!JS_SetElement(this->_cx, jsretArr, count, jsval)) { if (!JS_SetElement(this->_cx, jsretArr, count, jsval)) {
break; break;
@ -1467,20 +1434,20 @@ int ScriptingCore::executeCustomTouchesEvent(EventTouch::EventCode eventType,
} }
int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType, int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType, Touch *touch, JSObject *obj)
Touch *pTouch, JSObject *obj)
{ {
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
JS::RootedValue retval(_cx); JS::RootedValue retval(_cx);
std::string funcName = getTouchFuncName(eventType); std::string funcName = getTouchFuncName(eventType);
jsval jsTouch = OBJECT_TO_JSVAL(js_get_or_create_jsobject<Touch>(this->_cx, pTouch)); js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Touch>(touch);
jsval jsTouch = OBJECT_TO_JSVAL(jsb_ref_get_or_create_jsobject(this->_cx, touch, typeClass, "cocos2d::Touch"));
executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), funcName.c_str(), 1, &jsTouch, &retval); executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), funcName.c_str(), 1, &jsTouch, &retval);
// Remove touch object from global hash table and unroot it. // Remove touch object from global hash table and unroot it.
removeJSObject(this->_cx, pTouch); removeJSObject(this->_cx, touch);
return 1; return 1;
@ -1488,19 +1455,20 @@ int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType,
int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType, int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType,
Touch *pTouch, JSObject *obj, Touch *touch, JSObject *obj,
JS::MutableHandleValue retval) JS::MutableHandleValue retval)
{ {
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
std::string funcName = getTouchFuncName(eventType); std::string funcName = getTouchFuncName(eventType);
jsval jsTouch = OBJECT_TO_JSVAL(js_get_or_create_jsobject<Touch>(this->_cx, pTouch)); js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Touch>(touch);
jsval jsTouch = OBJECT_TO_JSVAL(jsb_ref_get_or_create_jsobject(this->_cx, touch, typeClass, "cocos2d::Touch"));
executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), funcName.c_str(), 1, &jsTouch, retval); executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), funcName.c_str(), 1, &jsTouch, retval);
// Remove touch object from global hash table and unroot it. // Remove touch object from global hash table and unroot it.
removeJSObject(this->_cx, pTouch); removeJSObject(this->_cx, touch);
return 1; return 1;
@ -1611,6 +1579,7 @@ void ScriptingCore::unrootObject(Ref* ref)
js_proxy_t* nproxy; js_proxy_t* nproxy;
js_proxy_t* jsproxy; js_proxy_t* jsproxy;
void *ptr = (void*)ref; void *ptr = (void*)ref;
nproxy = jsb_get_native_proxy(ptr); nproxy = jsb_get_native_proxy(ptr);
if (nproxy) { if (nproxy) {
JSContext *cx = getGlobalContext(); JSContext *cx = getGlobalContext();
@ -1621,7 +1590,7 @@ void ScriptingCore::unrootObject(Ref* ref)
jsproxy = jsb_get_js_proxy(handle); jsproxy = jsb_get_js_proxy(handle);
RemoveObjectRoot(cx, &jsproxy->obj); RemoveObjectRoot(cx, &jsproxy->obj);
CCLOG("Unrooting %p - %p: %s", ref, &jsproxy->obj, typeid(*ref).name()); CCLOG("Unrooting #2 %p - %p: %s", ref, &jsproxy->obj, typeid(*ref).name());
} }
} }
@ -2018,33 +1987,38 @@ JSObject* jsb_ref_autoreleased_create_jsobject(JSContext *cx, cocos2d::Ref *ref,
return js_obj; return js_obj;
} }
JSObject* jsb_ref_singleton_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug)
{
JS::RootedObject proto(cx, typeClass->proto.ref());
JS::RootedObject parent(cx, typeClass->parentProto.ref());
JS::RootedObject js_obj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parent));
js_proxy_t* newproxy = jsb_new_proxy(ref, js_obj);
jsb_ref_singleton_init(cx, &newproxy->obj, ref, debug);
return js_obj;
}
// get_or_create // get_or_create
JSObject* jsb_ref_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug) JSObject* jsb_ref_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug)
{ {
auto proxy = jsb_get_native_proxy(ref); auto proxy = jsb_get_native_proxy(ref);
if (proxy) if (proxy)
return proxy->obj; return proxy->obj;
// else
return jsb_ref_create_jsobject(cx, ref, typeClass, debug); // don't auto-release, don't retain.
JS::RootedObject proto(cx, typeClass->proto.ref());
JS::RootedObject parent(cx, typeClass->parentProto.ref());
JS::RootedObject js_obj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parent));
js_proxy_t* newproxy = jsb_new_proxy(ref, js_obj);
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
CC_UNUSED_PARAM(newproxy);
// don't retain it.
ref->_scriptOwned = true;
#else
// don't autorelease it
JS::AddNamedObjectRoot(cx, &newproxy->obj, debug);
#endif
return js_obj;
} }
JSObject* jsb_ref_singleton_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug) // get_or_create: REf is already autoreleased (or created)
JSObject* jsb_ref_autoreleased_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug)
{ {
auto proxy = jsb_get_native_proxy(ref); auto proxy = jsb_get_native_proxy(ref);
if (proxy) if (proxy)
return proxy->obj; return proxy->obj;
// else // else
return jsb_ref_singleton_create_jsobject(cx, ref, typeClass, debug); return jsb_ref_autoreleased_create_jsobject(cx, ref, typeClass, debug);
} }
// ref_init // ref_init
@ -2071,34 +2045,24 @@ void jsb_ref_autoreleased_init(JSContext* cx, JS::Heap<JSObject*> *obj, Ref* ref
(void)obj; (void)obj;
ref->_scriptOwned = true; ref->_scriptOwned = true;
// retain it, since the object is autoreleased // retain it, since the object is autoreleased
ret->retain(); ref->retain();
#else #else
// don't autorelease it, since it is already autoreleased // don't autorelease it, since it is already autoreleased
JS::AddNamedObjectRoot(cx, obj, debug); JS::AddNamedObjectRoot(cx, obj, debug);
#endif #endif
} }
void jsb_ref_singleton_init(JSContext* cx, JS::Heap<JSObject*> *obj, Ref* ref, const char* debug)
{
// CCLOG("jsb_ref_singleton_init: JSObject address = %p. %s", obj->get(), debug);
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
(void)cx;
(void)obj;
ref->_scriptOwned = true;
// don't retain it: it is a singleton
#else
// don't autorelease it: it is a singleton
JS::AddNamedObjectRoot(cx, obj, debug);
#endif
}
// finalize // finalize
void jsb_ref_finalize(JSFreeOp* fop, JSObject* obj) void jsb_ref_finalize(JSFreeOp* fop, JSObject* obj)
{ {
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
js_proxy_t* nproxy; js_proxy_t* nproxy;
js_proxy_t* jsproxy; js_proxy_t* jsproxy;
jsproxy = jsb_get_js_proxy(obj);
CCLOG("jsb_ref_finalize #1: JSObject address = %p", obj);
JS::RootedObject jsobj(fop->runtime(), obj);
jsproxy = jsb_get_js_proxy(jsobj);
if (jsproxy) if (jsproxy)
{ {
auto ref = static_cast<cocos2d::Ref*>(jsproxy->ptr); auto ref = static_cast<cocos2d::Ref*>(jsproxy->ptr);
@ -2106,7 +2070,7 @@ void jsb_ref_finalize(JSFreeOp* fop, JSObject* obj)
if (ref) if (ref)
{ {
CCLOG("jsb_ref_finalize: JSObject address = %p (%s)", obj, typeid(*ref).name()); CCLOG("jsb_ref_finalize #2: JSObject address = %p (%s)", obj, typeid(*ref).name());
jsb_remove_proxy(nproxy, jsproxy); jsb_remove_proxy(nproxy, jsproxy);
ref->release(); ref->release();

View File

@ -565,12 +565,6 @@ void jsb_ref_init(JSContext* cx, JS::Heap<JSObject*> *obj, cocos2d::Ref* ref, co
*/ */
void jsb_ref_autoreleased_init(JSContext* cx, JS::Heap<JSObject*> *obj, cocos2d::Ref* ref, const char* debug); void jsb_ref_autoreleased_init(JSContext* cx, JS::Heap<JSObject*> *obj, cocos2d::Ref* ref, const char* debug);
/**
* Generic initialization function for Singletons
* Similar to jsb_ref_init(), but call it to initialize singletons
*/
void jsb_ref_singleton_init(JSContext* cx, JS::Heap<JSObject*> *obj, cocos2d::Ref* ref, const char* debug);
/** /**
* Generic finalize used by objects that are subclass of Ref * Generic finalize used by objects that are subclass of Ref
*/ */
@ -595,23 +589,20 @@ JSObject* jsb_ref_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_clas
*/ */
JSObject* jsb_ref_autoreleased_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug); JSObject* jsb_ref_autoreleased_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug);
/**
* Creates a new JSObject of a certain type (typeClass) and creates a proxy associated with and the Singleton (ref)
* Similar to jsb_ref_create_jsobject(), but call it if you know that Ref is a Singleton
*/
JSObject* jsb_ref_singleton_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug);
/** /**
It will try to get the associated JSObjct for ref. It will try to get the associated JSObjct for ref.
If it can't find it, it will create a new one associating it to Ref If it can't find it, it will create a new one associating it to Ref.
Call this function for objects that were already created and initialized, when returning `getChild()`
*/ */
JSObject* jsb_ref_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug); JSObject* jsb_ref_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug);
/** /**
It will try to get the associated JSObjct for ref. It will try to get the associated JSObjct for ref.
If it can't find it, it will create a new one associating it to Ref If it can't find it, it will create a new one associating it to Ref
Call this function for objects that might return an already existing copy when you create them. For example, `Animation3D::create()`;
*/ */
JSObject* jsb_ref_singleton_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug); JSObject* jsb_ref_autoreleased_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug);
void removeJSObject(JSContext* cx, void* nativeObj); void removeJSObject(JSContext* cx, void* nativeObj);

View File

@ -203,10 +203,9 @@ bool js_cocos2dx_EventTouch_getTouches(JSContext *cx, uint32_t argc, jsval *vp)
JS::RootedValue arrElement(cx); JS::RootedValue arrElement(cx);
//First, check whether object is associated with js object. //First, check whether object is associated with js object.
js_proxy_t* jsproxy = js_get_or_create_proxy<cocos2d::Touch>(cx, touchObj); auto jsobj = js_get_or_create_jsobject<cocos2d::Touch>(cx, touchObj);
if (jsproxy) { if (jsobj)
arrElement = OBJECT_TO_JSVAL(jsproxy->obj); arrElement = OBJECT_TO_JSVAL(jsobj);
}
if (!JS_SetElement(cx, jsretArr, i, arrElement)) { if (!JS_SetElement(cx, jsretArr, i, arrElement)) {
break; break;
} }
@ -4558,8 +4557,7 @@ bool js_PlistParser_getInstance(JSContext *cx, unsigned argc, JS::Value *vp)
jsret = OBJECT_TO_JSVAL(p->obj); jsret = OBJECT_TO_JSVAL(p->obj);
} else { } else {
// create a new js obj of that class // create a new js obj of that class
js_proxy_t *proxy = js_get_or_create_proxy<SAXParser>(cx, parser); jsret = OBJECT_TO_JSVAL(js_get_or_create_jsobject<SAXParser>(cx, parser));
jsret = OBJECT_TO_JSVAL(proxy->obj);
} }
} else { } else {
jsret = JSVAL_NULL; jsret = JSVAL_NULL;
@ -4878,8 +4876,8 @@ bool js_cocos2dx_RenderTexture_saveToFile(JSContext *cx, uint32_t argc, jsval *v
jsval largv[2]; jsval largv[2];
do { do {
if (larg0) { if (larg0) {
js_proxy_t *jsProxy = js_get_or_create_proxy<cocos2d::RenderTexture>(cx, (cocos2d::RenderTexture*)larg0); JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
largv[0] = OBJECT_TO_JSVAL(jsProxy->obj); largv[0] = OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::RenderTexture>(cx, (cocos2d::RenderTexture*)larg0));
} else { } else {
largv[0] = JSVAL_NULL; largv[0] = JSVAL_NULL;
} }
@ -4949,8 +4947,8 @@ bool js_cocos2dx_RenderTexture_saveToFile(JSContext *cx, uint32_t argc, jsval *v
jsval largv[2]; jsval largv[2];
do { do {
if (larg0) { if (larg0) {
js_proxy_t *jsProxy = js_get_or_create_proxy<cocos2d::RenderTexture>(cx, (cocos2d::RenderTexture*)larg0); JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
largv[0] = OBJECT_TO_JSVAL(jsProxy->obj); largv[0] = OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::RenderTexture>(cx, (cocos2d::RenderTexture*)larg0));
} else { } else {
largv[0] = JSVAL_NULL; largv[0] = JSVAL_NULL;
} }
@ -5314,17 +5312,11 @@ bool js_cocos2dx_Scene_getPhysics3DWorld(JSContext *cx, uint32_t argc, jsval *vp
{ {
cocos2d::Physics3DWorld* ret = cobj->getPhysics3DWorld(); cocos2d::Physics3DWorld* ret = cobj->getPhysics3DWorld();
jsval jsret = JSVAL_NULL; jsval jsret = JSVAL_NULL;
do if (ret)
{ {
if (ret) js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Physics3DWorld>(ret);
{ jsret = OBJECT_TO_JSVAL(jsb_ref_get_or_create_jsobject(cx, ret, typeClass, "cocos2d::Physics3DWorld"));
js_proxy_t *jsProxy = js_get_or_create_proxy<cocos2d::Physics3DWorld>(cx, (cocos2d::Physics3DWorld*)ret); }
jsret = OBJECT_TO_JSVAL(jsProxy->obj);
} else
{
jsret = JSVAL_NULL;
}
} while (0);
args.rval().set(jsret); args.rval().set(jsret);
return true; return true;
} }
@ -5400,15 +5392,11 @@ bool js_cocos2dx_Scene_getNavMesh(JSContext *cx, uint32_t argc, jsval *vp)
if (argc == 0) { if (argc == 0) {
cocos2d::NavMesh* ret = cobj->getNavMesh(); cocos2d::NavMesh* ret = cobj->getNavMesh();
jsval jsret = JSVAL_NULL; jsval jsret = JSVAL_NULL;
do { if (ret)
if (ret) { {
js_proxy_t *jsProxy = js_get_or_create_proxy<cocos2d::NavMesh>(cx, (cocos2d::NavMesh*)ret); js_type_class_t *typeClass = js_get_type_from_native<cocos2d::NavMesh>(ret);
jsret = OBJECT_TO_JSVAL(jsProxy->obj); jsret = OBJECT_TO_JSVAL(jsb_ref_get_or_create_jsobject(cx, ret, typeClass, "cocos2d::NavMesh"));
} }
else {
jsret = JSVAL_NULL;
}
} while (0);
args.rval().set(jsret); args.rval().set(jsret);
return true; return true;
} }
@ -5657,14 +5645,9 @@ bool js_cocos2dx_AutoPolygon_generatePolygon(JSContext *cx, uint32_t argc, jsval
JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_AutoPolygon_generatePolygon : Error processing arguments"); JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_AutoPolygon_generatePolygon : Error processing arguments");
cocos2d::PolygonInfo* ret = new cocos2d::PolygonInfo(cocos2d::AutoPolygon::generatePolygon(arg0)); cocos2d::PolygonInfo* ret = new cocos2d::PolygonInfo(cocos2d::AutoPolygon::generatePolygon(arg0));
jsval jsret = JSVAL_NULL; jsval jsret = JSVAL_NULL;
do { if (ret) {
if (ret) { jsret = OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::PolygonInfo>(cx, ret));
js_proxy_t *jsProxy = js_get_or_create_proxy<cocos2d::PolygonInfo>(cx, ret); }
jsret = OBJECT_TO_JSVAL(jsProxy->obj);
} else {
jsret = JSVAL_NULL;
}
} while (0);
args.rval().set(jsret); args.rval().set(jsret);
return true; return true;
} }
@ -5676,14 +5659,9 @@ bool js_cocos2dx_AutoPolygon_generatePolygon(JSContext *cx, uint32_t argc, jsval
JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_AutoPolygon_generatePolygon : Error processing arguments"); JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_AutoPolygon_generatePolygon : Error processing arguments");
cocos2d::PolygonInfo* ret = new cocos2d::PolygonInfo(cocos2d::AutoPolygon::generatePolygon(arg0, arg1)); cocos2d::PolygonInfo* ret = new cocos2d::PolygonInfo(cocos2d::AutoPolygon::generatePolygon(arg0, arg1));
jsval jsret = JSVAL_NULL; jsval jsret = JSVAL_NULL;
do { if (ret) {
if (ret) { jsret = OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::PolygonInfo>(cx, ret));
js_proxy_t *jsProxy = js_get_or_create_proxy<cocos2d::PolygonInfo>(cx, ret); }
jsret = OBJECT_TO_JSVAL(jsProxy->obj);
} else {
jsret = JSVAL_NULL;
}
} while (0);
args.rval().set(jsret); args.rval().set(jsret);
return true; return true;
} }
@ -5697,14 +5675,9 @@ bool js_cocos2dx_AutoPolygon_generatePolygon(JSContext *cx, uint32_t argc, jsval
JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_AutoPolygon_generatePolygon : Error processing arguments"); JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_AutoPolygon_generatePolygon : Error processing arguments");
cocos2d::PolygonInfo* ret = new cocos2d::PolygonInfo(cocos2d::AutoPolygon::generatePolygon(arg0, arg1, arg2)); cocos2d::PolygonInfo* ret = new cocos2d::PolygonInfo(cocos2d::AutoPolygon::generatePolygon(arg0, arg1, arg2));
jsval jsret = JSVAL_NULL; jsval jsret = JSVAL_NULL;
do { if (ret) {
if (ret) { jsret = OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::PolygonInfo>(cx, ret));
js_proxy_t *jsProxy = js_get_or_create_proxy<cocos2d::PolygonInfo>(cx, ret); }
jsret = OBJECT_TO_JSVAL(jsProxy->obj);
} else {
jsret = JSVAL_NULL;
}
} while (0);
args.rval().set(jsret); args.rval().set(jsret);
return true; return true;
} }
@ -5720,14 +5693,9 @@ bool js_cocos2dx_AutoPolygon_generatePolygon(JSContext *cx, uint32_t argc, jsval
JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_AutoPolygon_generatePolygon : Error processing arguments"); JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_AutoPolygon_generatePolygon : Error processing arguments");
cocos2d::PolygonInfo* ret = new cocos2d::PolygonInfo(cocos2d::AutoPolygon::generatePolygon(arg0, arg1, arg2, arg3)); cocos2d::PolygonInfo* ret = new cocos2d::PolygonInfo(cocos2d::AutoPolygon::generatePolygon(arg0, arg1, arg2, arg3));
jsval jsret = JSVAL_NULL; jsval jsret = JSVAL_NULL;
do { if (ret) {
if (ret) { jsret = OBJECT_TO_JSVAL(js_get_or_create_jsobject<cocos2d::PolygonInfo>(cx, ret));
js_proxy_t *jsProxy = js_get_or_create_proxy<cocos2d::PolygonInfo>(cx, ret); }
jsret = OBJECT_TO_JSVAL(jsProxy->obj);
} else {
jsret = JSVAL_NULL;
}
} while (0);
args.rval().set(jsret); args.rval().set(jsret);
return true; return true;
} }

View File

@ -150,13 +150,8 @@ JSObject* js_get_or_create_jsobject(JSContext *cx, typename std::enable_if<!std:
template<class T> template<class T>
JSObject* js_get_or_create_jsobject(JSContext *cx, typename std::enable_if<std::is_base_of<cocos2d::Ref,T>::value,T>::type *native_obj) JSObject* js_get_or_create_jsobject(JSContext *cx, typename std::enable_if<std::is_base_of<cocos2d::Ref,T>::value,T>::type *native_obj)
{ {
js_proxy_t *proxy = jsb_get_native_proxy(native_obj);
if (proxy)
return proxy->obj;
// else
js_type_class_t* typeClass = js_get_type_from_native<T>(native_obj); js_type_class_t* typeClass = js_get_type_from_native<T>(native_obj);
return jsb_ref_autoreleased_create_jsobject(cx, native_obj, typeClass, typeid(*native_obj).name()); return jsb_ref_get_or_create_jsobject(cx, native_obj, typeClass, typeid(*native_obj).name());
} }
JS::Value anonEvaluate(JSContext *cx, JS::HandleObject thisObj, const char* string); JS::Value anonEvaluate(JSContext *cx, JS::HandleObject thisObj, const char* string);

View File

@ -1761,9 +1761,10 @@ jsval ccarray_to_jsval(JSContext* cx, __Array *arr)
JS::RootedValue arrElement(cx); JS::RootedValue arrElement(cx);
//First, check whether object is associated with js object. //First, check whether object is associated with js object.
js_proxy_t* jsproxy = js_get_or_create_proxy<cocos2d::Ref>(cx, obj); js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Ref>(obj);
if (jsproxy) { auto jsobj = jsb_ref_get_or_create_jsobject(cx, obj, typeClass, "cocos2d::Ref");
arrElement = OBJECT_TO_JSVAL(jsproxy->obj); if (jsobj) {
arrElement = OBJECT_TO_JSVAL(jsobj);
} }
else { else {
__String* strVal = NULL; __String* strVal = NULL;
@ -1812,9 +1813,10 @@ jsval ccdictionary_to_jsval(JSContext* cx, __Dictionary* dict)
JS::RootedValue dictElement(cx); JS::RootedValue dictElement(cx);
Ref* obj = pElement->getObject(); Ref* obj = pElement->getObject();
//First, check whether object is associated with js object. //First, check whether object is associated with js object.
js_proxy_t* jsproxy = js_get_or_create_proxy<cocos2d::Ref>(cx, obj); js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Ref>(obj);
if (jsproxy) { auto jsobj = jsb_ref_get_or_create_jsobject(cx, obj, typeClass, "cocos2d::Ref");
dictElement = OBJECT_TO_JSVAL(jsproxy->obj); if (jsobj) {
dictElement = OBJECT_TO_JSVAL(jsobj);
} }
else { else {
__String* strVal = NULL; __String* strVal = NULL;

View File

@ -563,19 +563,13 @@ cc.ActionInterval.prototype._ctor = function(d) {
}; };
cc.Sequence.prototype._ctor = function(tempArray) { cc.Sequence.prototype._ctor = function(tempArray) {
var paramArray = (tempArray instanceof Array) ? tempArray : arguments; var paramArray = (tempArray instanceof Array) ? tempArray : Array.prototype.slice.call(arguments);
var last = paramArray.length - 1; var last = paramArray.length - 1;
if ((last >= 0) && (paramArray[last] == null)) if ((last >= 0) && (paramArray[last] == null))
cc.log("parameters should not be ending with null in Javascript"); cc.log("parameters should not be ending with null in Javascript");
if (last >= 0) { if (last >= 0) {
var prev = paramArray[0]; this.init(paramArray);
for (var i = 1; i < last; i++) {
if (paramArray[i]) {
prev = cc.Sequence.create(prev, paramArray[i]);
}
}
this.initWithTwoActions(prev, paramArray[last]);
} }
}; };
@ -588,19 +582,13 @@ cc.RepeatForever.prototype._ctor = function(action) {
}; };
cc.Spawn.prototype._ctor = function(tempArray) { cc.Spawn.prototype._ctor = function(tempArray) {
var paramArray = (tempArray instanceof Array) ? tempArray : arguments; var paramArray = (tempArray instanceof Array) ? tempArray : Array.prototype.slice.call(arguments);
var last = paramArray.length - 1; var last = paramArray.length - 1;
if ((last >= 0) && (paramArray[last] == null)) if ((last >= 0) && (paramArray[last] == null))
cc.log("parameters should not be ending with null in Javascript"); cc.log("parameters should not be ending with null in Javascript");
if (last >= 0) { if (last >= 0) {
var prev = paramArray[0]; this.init(paramArray);
for (var i = 1; i < last; i++) {
if (paramArray[i]) {
prev = cc.Spawn.create(prev, paramArray[i]);
}
}
this.initWithTwoActions(prev, paramArray[last]);
} }
}; };
@ -1208,4 +1196,4 @@ cc.Menu.create = function(menuItems) {
return cc.Menu._create.apply(null, items); return cc.Menu._create.apply(null, items);
}; };
cc.TMXLayer.prototype.tileFlagsAt = cc.TMXLayer.prototype.getTileFlagsAt; cc.TMXLayer.prototype.tileFlagsAt = cc.TMXLayer.prototype.getTileFlagsAt;

View File

@ -33,6 +33,7 @@
"src/TouchesTest/TouchesTest.js", "src/TouchesTest/TouchesTest.js",
"src/SchedulerTest/SchedulerTest.js", "src/SchedulerTest/SchedulerTest.js",
"src/MenuTest/MenuTest.js", "src/MenuTest/MenuTest.js",
"src/MemoryModelTest/MemoryModelTest.js",
"src/ActionsTest/ActionsTest.js", "src/ActionsTest/ActionsTest.js",
"src/TileMapTest/TileMapTest.js", "src/TileMapTest/TileMapTest.js",
"src/TransitionsTest/TransitionsTest.js", "src/TransitionsTest/TransitionsTest.js",

View File

@ -0,0 +1,256 @@
/****************************************************************************
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2011-2012 cocos2d-x.org
Copyright (c) 2013-2014 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
var memoryModelTestSceneIdx = -1;
//------------------------------------------------------------------
//
// MemoryModelTestBase
//
//------------------------------------------------------------------
var MemoryModelTestBase = BaseTestLayer.extend({
_title:"",
_subtitle:"",
onRestartCallback:function (sender) {
var s = new MemoryModelTestScene();
s.addChild(restartMemoryModelTest());
director.runScene(s);
},
onNextCallback:function (sender) {
var s = new MemoryModelTestScene();
s.addChild(nextMemoryModelTest());
director.runScene(s);
},
onBackCallback:function (sender) {
var s = new MemoryModelTestScene();
s.addChild(previousMemoryModelTest());
director.runScene(s);
},
// automation
numberOfPendingTests:function() {
return ( (arrayOfMemoryModelTest.length-1) - memoryModelTestSceneIdx );
},
getTestNumber:function() {
return memoryModelTestSceneIdx;
}
});
//------------------------------------------------------------------
//
// Set property on sprite
//
//------------------------------------------------------------------
var SetPropertyMemoryModelTest = MemoryModelTestBase.extend({
_title:"Set Property Test",
_subtitle:"See console for possible errors",
ctor:function () {
this._super();
var sprite = new cc.Sprite(s_grossini_dance_atlas, cc.rect(0, 0, 85, 121));
var tag = 10;
this.addChild(sprite, 0, tag);
var x = winSize.width / 2;
var y = winSize.height / 2;
sprite.setPosition(x, y);
// add random property
sprite.randomProperty = "hello world";
sprite = this.getChildByTag(tag);
// should print "hello world"
this.log(sprite.randomProperty);
},
});
//------------------------------------------------------------------
//
// Using Ivar 1: from ctor to onEnter
//
//------------------------------------------------------------------
var Ivar1MemoryModelTest = MemoryModelTestBase.extend({
_title:"Using ivars to hold C++ objects",
_subtitle:"From ctor to onEnter",
ctor:function () {
this._super();
this.sprite = new cc.Sprite(s_grossini_dance_atlas, cc.rect(0, 0, 85, 121));
},
onEnter:function() {
this._super();
this.addChild(this.sprite);
var x = winSize.width / 2;
var y = winSize.height / 2;
this.sprite.setPosition(x, y);
},
});
//------------------------------------------------------------------
//
// Using Ivar 2: from ctor to update
//
//------------------------------------------------------------------
var Ivar2MemoryModelTest = MemoryModelTestBase.extend({
_title:"Using ivars to hold C++ objects",
_subtitle:"From ctor to update",
ctor:function () {
this._super();
this.sprite = new cc.Sprite(s_grossini_dance_atlas, cc.rect(0, 0, 85, 121));
this.scheduleOnce(this.showSprite, 0.5);
},
showSprite:function() {
this.addChild(this.sprite);
var x = winSize.width / 2;
var y = winSize.height / 2;
this.sprite.setPosition(x, y);
},
});
var MemoryModelTestScene = TestScene.extend({
runThisTest:function (num) {
memoryModelTestSceneIdx = (num || num == 0) ? (num - 1) : -1;
var layer = nextMemoryModelTest();
this.addChild(layer);
director.runScene(this);
}
});
//------------------------------------------------------------------
//
// Using Local vars
//
//------------------------------------------------------------------
var LocalVarMemoryModelTest = MemoryModelTestBase.extend({
_title:"Using local vars + GC",
_subtitle:"native objects should get destroyed",
ctor:function () {
this._super();
var sprite1 = new cc.Sprite(s_grossini_dance_atlas, cc.rect(0, 0, 85, 121));
var sprite2 = new cc.Sprite(s_grossini_dance_atlas, cc.rect(0, 0, 85, 121));
var sprite3 = new cc.Sprite(s_grossini_dance_atlas, cc.rect(0, 0, 85, 121));
var a = 10;
//cc.sys.dumpRoot();
cc.sys.garbageCollect();
cc.log(sprite1);
cc.log(sprite2);
cc.log(sprite3);
cc.log(a);
},
});
//------------------------------------------------------------------
//
// Using Local vars
//
//------------------------------------------------------------------
var RetainRootsMemoryModelTest = MemoryModelTestBase.extend({
_title:"retain must root",
_subtitle:"native objects should not get destroyed",
ctor:function () {
this._super();
var sprite = new cc.Sprite(s_grossini_dance_atlas, cc.rect(0, 0, 85, 121));
// addChild should root the sprite
this.addChild(sprite);
cc.sys.garbageCollect();
var x = winSize.width / 2;
var y = winSize.height / 2;
sprite.setPosition(x, y);
},
});
//------------------------------------------------------------------
//
// Testing Root/Unroot
//
//------------------------------------------------------------------
var RootUnrootMemoryModelTest = MemoryModelTestBase.extend({
_title:"root/unroot",
_subtitle:"rooting/unrooting with GC memory model",
ctor:function () {
this._super();
var sprite = new cc.Sprite(s_grossini_dance_atlas, cc.rect(0, 0, 85, 121));
// addChild should root the sprite
this.addChild(sprite);
// should unroot the sprite
this.removeChild(sprite)
cc.sys.garbageCollect();
},
});
//
// Entry point
//
var MemoryModelTestScene = TestScene.extend({
runThisTest:function (num) {
memoryModelTestSceneIdx = (num || num == 0) ? (num - 1) : -1;
var layer = nextMemoryModelTest();
this.addChild(layer);
director.runScene(this);
}
});
//
// Flow control
//
var arrayOfMemoryModelTest = [
SetPropertyMemoryModelTest,
Ivar1MemoryModelTest,
Ivar2MemoryModelTest,
LocalVarMemoryModelTest,
RetainRootsMemoryModelTest,
RootUnrootMemoryModelTest,
];
var nextMemoryModelTest = function () {
memoryModelTestSceneIdx++;
memoryModelTestSceneIdx = memoryModelTestSceneIdx % arrayOfMemoryModelTest.length;
return new arrayOfMemoryModelTest[memoryModelTestSceneIdx]();
};
var previousMemoryModelTest = function () {
memoryModelTestSceneIdx--;
if (memoryModelTestSceneIdx < 0)
memoryModelTestSceneIdx += arrayOfMemoryModelTest.length;
return new arrayOfMemoryModelTest[memoryModelTestSceneIdx]();
};
var restartMemoryModelTest = function () {
return new arrayOfMemoryModelTest[memoryModelTestSceneIdx]();
};

View File

@ -479,6 +479,15 @@ var testNames = [
return new MaterialSystemTestScene(); return new MaterialSystemTestScene();
} }
}, },
{
title:"Memory Model Test",
resource:g_menu,
platforms: PLATFORM_JSB,
linksrc:"src/MemoryModelTest/MemoryModelTest.js",
testScene:function () {
return new MemoryModelTestScene();
}
},
{ {
title:"Menu Test", title:"Menu Test",
resource:g_menu, resource:g_menu,

@ -1 +1 @@
Subproject commit b940871c1dfff94c0220364539dd9d0583995719 Subproject commit 26b56a42b7ea74ca7acb4003c7f98fe149741503

View File

@ -87,8 +87,8 @@ skip = Node::[^setPosition$ setGLServerState description getUserObject .*UserDat
Range::[*], Range::[*],
NotificationObserver::[*], NotificationObserver::[*],
Image::[initWithString initWithImageData], Image::[initWithString initWithImageData],
Sequence::[create init], Sequence::[create],
Spawn::[create init], Spawn::[create],
RotateTo::[calculateAngles], RotateTo::[calculateAngles],
GLProgram::[getProgram setUniformLocationWith(1|2|3|4)fv setUniformLocationWith(2|3|4)iv setUniformLocationWithMatrix(2|3|4)fv], GLProgram::[getProgram setUniformLocationWith(1|2|3|4)fv setUniformLocationWith(2|3|4)iv setUniformLocationWithMatrix(2|3|4)fv],
GLProgramState::[setUniformVec4 setVertexAttribPointer], GLProgramState::[setUniformVec4 setVertexAttribPointer],

View File

@ -43,7 +43,7 @@ skip = Skeleton3D::[create],
Sprite3D::[getAABB getMeshArrayByName createAsync], Sprite3D::[getAABB getMeshArrayByName createAsync],
Mesh::[create getMeshCommand getAABB getDefaultGLProgram getMeshVertexAttribute draw setTexture getTexture], Mesh::[create getMeshCommand getAABB getDefaultGLProgram getMeshVertexAttribute draw setTexture getTexture],
Sprite3DCache::[addSprite3DData getSpriteData], Sprite3DCache::[addSprite3DData getSpriteData],
Animation3D::[getBoneCurves], Animation3D::[create getBoneCurves],
Animate3D::[getKeyFrameUserInfo], Animate3D::[getKeyFrameUserInfo],
TextureCube::[setTexParameters], TextureCube::[setTexParameters],
Terrain::[getAABB getQuadTree create getHeightData], Terrain::[getAABB getQuadTree create getHeightData],