mirror of https://github.com/axmolengine/axmol.git
Sync issue fixes from creator (#17041)
* Add EventDispatcher#hasEventListener (sync from creator) * Fix function wrapper using js object during its gc * Support more system languages * Direct log/error for better understanding problems & add sys.now * Synchronize Editbox APIs * Synchronize Scheduler.PRIORITY_NON_SYSTEM const * Upgrade web engine * Upgrade test cases * Manually bind EventDispatcher::addCustomEventListener to avoid memory issue * Manual bind EventListeners’ create to avoid memory issue * Fix compilation issue when COCOS_DEBUG = 2 * Unify function name of Texture2D::releaseTexture * Fix compilation issues and update web & bindings-generator * Fix lua compilation issue * Use %ld instead of %zd * Separate FinalizeHook for ref objects and non ref objects * Fix spine TrackEntry recursive conversion issue by using getter * Fix crash during Wrappers deallocation (possible to have leak) * Increase default JS heap to 32 mb * Update engine version * Add change log of web engine * Improve cc.formatStr * Fix chipmunk crash issues when using setDefaultCollisionHandler * Add change log for JSB and update web engine ref
This commit is contained in:
parent
bd0789e22c
commit
a715e3169f
31
CHANGELOG
31
CHANGELOG
|
@ -5,13 +5,14 @@ coocs2d-x-3.14 Dec 19 2016
|
|||
[NEW] Action: new actions: ResizeBy and ResizeTo
|
||||
[NEW] Button: can set title label
|
||||
[NEW] Can disable multi touch on Android
|
||||
[NEW] EventDispatcher: Add hasEventListener to check listener existance
|
||||
[NEW] EditBox: add horizontal text alignment
|
||||
[NEW] Sprite: support scale9 feature
|
||||
[NEW] Slider: add methods to get _slidBallNormalRenderer
|
||||
[NEW] Desktop: add a method to toggle between fullscreen and windowed
|
||||
[NEW] Desktop: add events for window resize, focus and unfocus
|
||||
[NEW] Mac: supports game controller
|
||||
[NEW] JSB: add perfromance.now()
|
||||
[NEW] JSB: add cc.sys.now() and perfromance.now(), the last one is more accurate
|
||||
[NEW] Lua: add cc.vec3 functions: add, sub and dot
|
||||
[NEW] Lua: use luajit 2.1.0-beta2
|
||||
|
||||
|
@ -25,6 +26,18 @@ coocs2d-x-3.14 Dec 19 2016
|
|||
[REFINE] Mac: system font enhancement
|
||||
[REFINE] Linux: build shared lib with -fPIC
|
||||
[REFINE] Android: use SharedPreferences.apply() to store data
|
||||
[REFINE] JSB: Increase default JS heap to 32 mb
|
||||
[REFINE] JSB: Support more system languages
|
||||
[REFINE] JSB: Direct log/error for better understantding problems
|
||||
[REFINE] JSB: Separate FinalizeHook for ref objects and non ref objects
|
||||
[REFINE] Web: Improve overall node construction performance
|
||||
[REFINE] Web: Improve overall loading process performance
|
||||
[REFINE] Web: Reduce overall memory usage
|
||||
[REFINE] Web: Made cc.LabelBMFont and cc.LabelAtlas support texture packing and auto batching
|
||||
[REFINE] Web: Reimplement a much faster ccui.Scale9Sprite
|
||||
[REFINE] Web: Reimplement a much faster cc.DrawNode WebGL renderer
|
||||
[REFINE] Web: Use stack to avoid recursive call in transform, onEnter, onExit etc, reduce call stack depth
|
||||
|
||||
|
||||
[FIX] AsstsManagerEx: project.manifest may be downloaded twice
|
||||
[FIX] AudioEngine: can not play large ogg file
|
||||
|
@ -74,11 +87,25 @@ coocs2d-x-3.14 Dec 19 2016
|
|||
[FIX] Linux: Application::openURL can not work
|
||||
[FIX] Desktop: crash upon exit when NotificationNode exists
|
||||
[FIX] Spine: color bug
|
||||
[FIX] Console: doesn't support `--ap` parameter
|
||||
[FIX] Lua: result of radian2angle is wrong
|
||||
[FIX] Lua: iskindof_ doesn't work correctly
|
||||
[FIX] Lua: new lua project crashes compiling with VS2015 release mode
|
||||
[FIX] JSB: `jsb.addRoot is not a function` error caused by cc.GLProgramState.setUniformCallback
|
||||
[FIX] Console: doesn't support `--ap` parameter
|
||||
[FIX] JSB: Fix spine TrackEntry conversion crash issue
|
||||
[FIX] JSB: Fix CallbackWrapper and FunctionWrapper crash during deallocation in new memory model
|
||||
[FIX] JSB: Fix event object memory issue by manually bind EventDispatcher::addCustomEventListener
|
||||
[FIX] JSB: Fix chipmunk crash issues when using setDefaultCollisionHandler
|
||||
[FIX] JSB: Fix compilation issues when COCOS_DEBUG = 2
|
||||
[FIX] JSB: Unify function name of Texture2D::releaseTexture
|
||||
[FIX] Web: Fix spine blend function inconsistency between web and jsb
|
||||
[FIX] Web: Fix particle system load from plist generated by x-studio365
|
||||
[FIX] Web: Fix doEnumerateRecursive(node, name, callback) always return undefined issue
|
||||
[FIX] Web: Change bright style on 'setEnabled' call of ccui.Widget
|
||||
[FIX] Web: Fix Editbox can't input in full screen mode
|
||||
[FIX] Web: Fix texture issue on some Android devices by always set vertexAttribPointer
|
||||
[FIX] Web: Made xhr ontimeout callback work on all browsers
|
||||
[FIX] Web: Fix clear color not normalized issue
|
||||
|
||||
cocos2d-x-3.13.1 Sep 13 2016
|
||||
|
||||
|
|
|
@ -365,7 +365,7 @@ void GLView::handleTouchesMove(int num, intptr_t ids[], float xs[], float ys[],
|
|||
continue;
|
||||
}
|
||||
|
||||
CCLOGINFO("Moving touches with id: %d, x=%f, y=%f, force=%f, maxFource=%f", id, x, y, force, maxForce);
|
||||
CCLOGINFO("Moving touches with id: %d, x=%f, y=%f, force=%f, maxFource=%f", (int)id, x, y, force, maxForce);
|
||||
Touch* touch = g_touches[iter->second];
|
||||
if (touch)
|
||||
{
|
||||
|
@ -417,7 +417,7 @@ void GLView::handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode, int num
|
|||
Touch* touch = g_touches[iter->second];
|
||||
if (touch)
|
||||
{
|
||||
CCLOGINFO("Ending touches with id: %d, x=%f, y=%f", id, x, y);
|
||||
CCLOGINFO("Ending touches with id: %d, x=%f, y=%f", (int)id, x, y);
|
||||
touch->setTouchInfo(iter->second, (x - _viewPortRect.origin.x) / _scaleX,
|
||||
(y - _viewPortRect.origin.y) / _scaleY);
|
||||
|
||||
|
|
|
@ -631,14 +631,14 @@ void ScriptingCore::createGlobalContext() {
|
|||
|
||||
// Removed from Spidermonkey 19.
|
||||
//JS_SetCStringsAreUTF8();
|
||||
_rt = JS_NewRuntime(8L * 1024L * 1024L);
|
||||
_rt = JS_NewRuntime(32L * 1024L * 1024L);
|
||||
JS_SetGCParameter(_rt, JSGC_MAX_BYTES, 0xffffffff);
|
||||
|
||||
JS_SetTrustedPrincipals(_rt, &shellTrustedPrincipals);
|
||||
JS_SetSecurityCallbacks(_rt, &securityCallbacks);
|
||||
JS_SetNativeStackQuota(_rt, JSB_MAX_STACK_QUOTA);
|
||||
|
||||
_cx = JS_NewContext(_rt, 8192);
|
||||
_cx = JS_NewContext(_rt, 32 * 1024);
|
||||
|
||||
// Removed in Firefox v27
|
||||
// JS_SetOptions(this->_cx, JSOPTION_TYPE_INFERENCE);
|
||||
|
@ -1438,7 +1438,7 @@ bool ScriptingCore::handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::Eve
|
|||
|
||||
for (const auto& touch : touches)
|
||||
{
|
||||
JS::RootedValue jsret(_cx, OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(_cx, touch, typeClassTouch, "cocos2d::Touch")));
|
||||
JS::RootedValue jsret(_cx, OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(_cx, touch, typeClassTouch)));
|
||||
if (!JS_SetElement(_cx, jsretArr, count, jsret))
|
||||
{
|
||||
break;
|
||||
|
@ -1451,7 +1451,7 @@ bool ScriptingCore::handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::Eve
|
|||
{
|
||||
jsval dataVal[2];
|
||||
dataVal[0] = OBJECT_TO_JSVAL(jsretArr);
|
||||
dataVal[1] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(_cx, event, typeClassEvent, "cocos2d::EventTouch"));
|
||||
dataVal[1] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(_cx, event, typeClassEvent));
|
||||
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), funcName.c_str(), 2, dataVal, jsvalRet);
|
||||
}
|
||||
|
||||
|
@ -1459,7 +1459,6 @@ bool ScriptingCore::handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::Eve
|
|||
{
|
||||
removeJSObject(_cx, touch);
|
||||
}
|
||||
|
||||
removeJSObject(_cx, event);
|
||||
|
||||
return ret;
|
||||
|
@ -1485,8 +1484,8 @@ bool ScriptingCore::handleTouchEvent(void* nativeObj, cocos2d::EventTouch::Event
|
|||
js_type_class_t *typeClassEvent = js_get_type_from_native<cocos2d::EventTouch>((cocos2d::EventTouch*)event);
|
||||
|
||||
jsval dataVal[2];
|
||||
dataVal[0] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(_cx, touch, typeClassTouch, "cocos2d::Touch"));
|
||||
dataVal[1] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(_cx, event, typeClassEvent, "cocos2d::EventTouch"));
|
||||
dataVal[0] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(_cx, touch, typeClassTouch));
|
||||
dataVal[1] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(_cx, event, typeClassEvent));
|
||||
|
||||
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), funcName.c_str(), 2, dataVal, jsvalRet);
|
||||
}
|
||||
|
@ -1514,7 +1513,7 @@ bool ScriptingCore::handleMouseEvent(void* nativeObj, cocos2d::EventMouse::Mouse
|
|||
if (p)
|
||||
{
|
||||
js_type_class_t *typeClass = js_get_type_from_native<cocos2d::EventMouse>((cocos2d::EventMouse*)event);
|
||||
jsval dataVal = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(_cx, event, typeClass, "cocos2d::EventMouse"));
|
||||
jsval dataVal = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(_cx, event, typeClass));
|
||||
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), funcName.c_str(), 1, &dataVal, jsvalRet);
|
||||
|
||||
removeJSObject(_cx, event);
|
||||
|
@ -1611,7 +1610,7 @@ bool ScriptingCore::handleKeyboardEvent(void* nativeObj, cocos2d::EventKeyboard:
|
|||
js_type_class_t *typeClass = js_get_type_from_native<cocos2d::EventKeyboard>((cocos2d::EventKeyboard*)event);
|
||||
jsval args[2] = {
|
||||
int32_to_jsval(_cx, (int32_t)keyCode),
|
||||
OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(_cx, event, typeClass, "cocos2d::EventKeyboard"))
|
||||
OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(_cx, event, typeClass))
|
||||
};
|
||||
|
||||
if (isPressed)
|
||||
|
@ -1662,7 +1661,7 @@ int ScriptingCore::executeCustomTouchesEvent(EventTouch::EventCode eventType,
|
|||
{
|
||||
js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Touch>(touch);
|
||||
|
||||
jsval jsret = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(this->_cx, touch, typeClass, "cocos2d::Touch"));
|
||||
jsval jsret = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(this->_cx, touch, typeClass));
|
||||
JS::RootedValue jsval(_cx, jsret);
|
||||
if (!JS_SetElement(this->_cx, jsretArr, count, jsval)) {
|
||||
break;
|
||||
|
@ -1690,7 +1689,7 @@ int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType, Touc
|
|||
std::string funcName = getTouchFuncName(eventType);
|
||||
|
||||
js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Touch>(touch);
|
||||
jsval jsTouch = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(this->_cx, touch, typeClass, "cocos2d::Touch"));
|
||||
jsval jsTouch = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(this->_cx, touch, typeClass));
|
||||
|
||||
executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), funcName.c_str(), 1, &jsTouch, &retval);
|
||||
|
||||
|
@ -1709,7 +1708,7 @@ int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType,
|
|||
std::string funcName = getTouchFuncName(eventType);
|
||||
|
||||
js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Touch>(touch);
|
||||
jsval jsTouch = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(this->_cx, touch, typeClass, "cocos2d::Touch"));
|
||||
jsval jsTouch = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(this->_cx, touch, typeClass));
|
||||
|
||||
executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), funcName.c_str(), 1, &jsTouch, retval);
|
||||
|
||||
|
@ -2308,12 +2307,16 @@ JSObject* jsb_create_weak_jsobject(JSContext *cx, void *native, js_type_class_t
|
|||
JS::RootedObject parent(cx, typeClass->parentProto.ref());
|
||||
JS::RootedObject jsObj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parent));
|
||||
auto proxy = jsb_new_proxy(native, jsObj);
|
||||
js_add_FinalizeHook(cx, jsObj, false);
|
||||
|
||||
#if ! CC_ENABLE_GC_FOR_NATIVE_OBJECTS
|
||||
JS::AddNamedObjectRoot(cx, &proxy->obj, debug);
|
||||
#else
|
||||
#if COCOS2D_DEBUG > 1
|
||||
CCLOG("++++++WEAK_REF++++++ Cpp(%s): %p - JS: %p", debug, native, jsObj.get());
|
||||
if (debug != nullptr)
|
||||
{
|
||||
CCLOG("++++++WEAK_REF++++++ Cpp(%s): %p - JS: %p", debug, native, jsObj.get());
|
||||
}
|
||||
#endif // COCOS2D_DEBUG
|
||||
#endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
|
||||
return jsObj;
|
||||
|
@ -2336,7 +2339,7 @@ JSObject* jsb_ref_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_ty
|
|||
js_proxy_t* newproxy = jsb_new_proxy(ref, jsObj);
|
||||
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
|
||||
ref->retain();
|
||||
js_add_FinalizeHook(cx, jsObj);
|
||||
js_add_FinalizeHook(cx, jsObj, true);
|
||||
#if COCOS2D_DEBUG > 1
|
||||
CCLOG("++++++RETAINED++++++ Cpp(%s): %p - JS: %p", debug, ref, jsObj.get());
|
||||
#endif // COCOS2D_DEBUG
|
||||
|
@ -2398,7 +2401,7 @@ void jsb_ref_init(JSContext* cx, JS::Heap<JSObject*> *obj, Ref* ref, const char*
|
|||
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
|
||||
(void)ref;
|
||||
JS::RootedObject jsObj(cx, *obj);
|
||||
js_add_FinalizeHook(cx, jsObj);
|
||||
js_add_FinalizeHook(cx, jsObj, true);
|
||||
// don't retain it, already retained
|
||||
#if COCOS2D_DEBUG > 1
|
||||
CCLOG("++++++RETAINED++++++ Cpp(%s): %p - JS: %p", debug, ref, jsObj.get());
|
||||
|
@ -2418,7 +2421,7 @@ void jsb_ref_autoreleased_init(JSContext* cx, JS::Heap<JSObject*> *obj, Ref* ref
|
|||
(void)obj;
|
||||
ref->retain();
|
||||
JS::RootedObject jsObj(cx, *obj);
|
||||
js_add_FinalizeHook(cx, jsObj);
|
||||
js_add_FinalizeHook(cx, jsObj, true);
|
||||
#else
|
||||
// don't autorelease it, since it is already autoreleased
|
||||
JS::AddNamedObjectRoot(cx, obj, debug);
|
||||
|
@ -2440,7 +2443,9 @@ void jsb_ref_rebind(JSContext* cx, JS::HandleObject jsobj, js_proxy_t *proxy, co
|
|||
// Rebind js obj with new action
|
||||
js_proxy_t* newProxy = jsb_new_proxy(newRef, jsobj);
|
||||
|
||||
#if !CC_ENABLE_GC_FOR_NATIVE_OBJECTS
|
||||
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
|
||||
CC_UNUSED_PARAM(newProxy);
|
||||
#else
|
||||
JS::AddNamedObjectRoot(cx, &newProxy->obj, debug);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include <memory>
|
||||
#include <chrono>
|
||||
|
||||
#define ENGINE_VERSION "Cocos2d-JS v3.13"
|
||||
#define ENGINE_VERSION "Cocos2d-JS v3.14"
|
||||
|
||||
void js_log(const char *format, ...);
|
||||
|
||||
|
@ -665,7 +665,7 @@ JSObject* jsb_ref_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_ty
|
|||
* 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_autoreleased_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=nullptr);
|
||||
|
||||
/**
|
||||
* It will try to get the associated JSObjct for the native object.
|
||||
|
@ -673,7 +673,7 @@ JSObject* jsb_ref_autoreleased_get_or_create_jsobject(JSContext *cx, cocos2d::Re
|
|||
* The reference created from JSObject to native object is weak because it won't retain it.
|
||||
* The behavior is exactly the same with 'jsb_ref_get_or_create_jsobject' when CC_ENABLE_GC_FOR_NATIVE_OBJECTS deactivated.
|
||||
*/
|
||||
CC_JS_DLL JSObject* jsb_get_or_create_weak_jsobject(JSContext *cx, void *native, js_type_class_t *typeClass, const char* debug);
|
||||
CC_JS_DLL JSObject* jsb_get_or_create_weak_jsobject(JSContext *cx, void *native, js_type_class_t *typeClass, const char* debug=nullptr);
|
||||
|
||||
/**
|
||||
* Register finalize hook and its owner as an entry in _js_hook_owner_map,
|
||||
|
|
|
@ -824,6 +824,7 @@ jsval cpSegmentQueryInfo_to_jsval(JSContext *cx, cpSegmentQueryInfo segmentQuery
|
|||
|
||||
return OBJECT_TO_JSVAL(object);
|
||||
}
|
||||
|
||||
#pragma mark - Collision Handler
|
||||
|
||||
struct collision_handler {
|
||||
|
@ -845,39 +846,72 @@ struct collision_handler {
|
|||
|
||||
unsigned int is_oo; // Objected oriented API ?
|
||||
UT_hash_handle hh;
|
||||
|
||||
bool is_default;
|
||||
|
||||
collision_handler()
|
||||
collision_handler ()
|
||||
{
|
||||
begin = nullptr;
|
||||
pre = nullptr;
|
||||
post = nullptr;
|
||||
separate = nullptr;
|
||||
jsthis = nullptr;
|
||||
is_default = false;
|
||||
}
|
||||
|
||||
~collision_handler ()
|
||||
{
|
||||
JS::RootedValue jsspace(cx, OBJECT_TO_JSVAL(jsthis));
|
||||
if (!is_default && jsspace.isObject())
|
||||
{
|
||||
JS::RootedValue callback(cx);
|
||||
callback.set(OBJECT_TO_JSVAL(begin));
|
||||
if (callback.isObject())
|
||||
{
|
||||
js_remove_object_reference(jsspace, callback);
|
||||
}
|
||||
callback.set(OBJECT_TO_JSVAL(pre));
|
||||
if (callback.isObject())
|
||||
{
|
||||
js_remove_object_reference(jsspace, callback);
|
||||
}
|
||||
callback.set(OBJECT_TO_JSVAL(post));
|
||||
if (callback.isObject())
|
||||
{
|
||||
js_remove_object_reference(jsspace, callback);
|
||||
}
|
||||
callback.set(OBJECT_TO_JSVAL(separate));
|
||||
if (callback.isObject())
|
||||
{
|
||||
js_remove_object_reference(jsspace, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Space must be set after set handles
|
||||
void setJSSpace(JS::HandleValue jsspace)
|
||||
{
|
||||
if (!jsspace.isNullOrUndefined())
|
||||
if (jsspace.isObject())
|
||||
{
|
||||
jsthis = jsspace.toObjectOrNull();
|
||||
JS::RootedValue callback(ScriptingCore::getInstance()->getGlobalContext());
|
||||
JS::RootedValue callback(cx);
|
||||
callback.set(OBJECT_TO_JSVAL(begin));
|
||||
if (!callback.isNullOrUndefined())
|
||||
if (callback.isObject())
|
||||
{
|
||||
js_add_object_reference(jsspace, callback);
|
||||
}
|
||||
callback.set(OBJECT_TO_JSVAL(pre));
|
||||
if (!callback.isNullOrUndefined())
|
||||
if (callback.isObject())
|
||||
{
|
||||
js_add_object_reference(jsspace, callback);
|
||||
}
|
||||
callback.set(OBJECT_TO_JSVAL(post));
|
||||
if (!callback.isNullOrUndefined())
|
||||
if (callback.isObject())
|
||||
{
|
||||
js_add_object_reference(jsspace, callback);
|
||||
}
|
||||
callback.set(OBJECT_TO_JSVAL(separate));
|
||||
if (!callback.isNullOrUndefined())
|
||||
if (callback.isObject())
|
||||
{
|
||||
js_add_object_reference(jsspace, callback);
|
||||
}
|
||||
|
@ -900,7 +934,12 @@ static unsigned long pair_ints( unsigned long A, unsigned long B )
|
|||
|
||||
static cpBool myCollisionBegin(cpArbiter *arb, cpSpace *space, void *data)
|
||||
{
|
||||
if (data == nullptr) {
|
||||
return cpTrue;
|
||||
}
|
||||
struct collision_handler *handler = (struct collision_handler*) data;
|
||||
|
||||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
|
||||
jsval args[2];
|
||||
if( handler->is_oo ) {
|
||||
|
@ -913,8 +952,6 @@ static cpBool myCollisionBegin(cpArbiter *arb, cpSpace *space, void *data)
|
|||
args[1] = opaque_to_jsval(handler->cx, space );
|
||||
}
|
||||
|
||||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
|
||||
JS::RootedValue rval(handler->cx);
|
||||
JS::RootedObject jsthis(handler->cx, handler->jsthis);
|
||||
JS::RootedValue jsbegin(handler->cx, OBJECT_TO_JSVAL(handler->begin));
|
||||
|
@ -930,7 +967,12 @@ static cpBool myCollisionBegin(cpArbiter *arb, cpSpace *space, void *data)
|
|||
|
||||
static cpBool myCollisionPre(cpArbiter *arb, cpSpace *space, void *data)
|
||||
{
|
||||
if (data == nullptr) {
|
||||
return cpTrue;
|
||||
}
|
||||
struct collision_handler *handler = (struct collision_handler*) data;
|
||||
|
||||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
|
||||
jsval args[2];
|
||||
if( handler->is_oo ) {
|
||||
|
@ -943,8 +985,6 @@ static cpBool myCollisionPre(cpArbiter *arb, cpSpace *space, void *data)
|
|||
args[1] = opaque_to_jsval( handler->cx, space );
|
||||
}
|
||||
|
||||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
|
||||
JS::RootedValue rval(handler->cx);
|
||||
JS::RootedObject jsthis(handler->cx, handler->jsthis);
|
||||
JS::RootedValue jspre(handler->cx, OBJECT_TO_JSVAL(handler->pre));
|
||||
|
@ -960,7 +1000,12 @@ static cpBool myCollisionPre(cpArbiter *arb, cpSpace *space, void *data)
|
|||
|
||||
static void myCollisionPost(cpArbiter *arb, cpSpace *space, void *data)
|
||||
{
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
struct collision_handler *handler = (struct collision_handler*) data;
|
||||
|
||||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
|
||||
jsval args[2];
|
||||
|
||||
|
@ -974,8 +1019,6 @@ static void myCollisionPost(cpArbiter *arb, cpSpace *space, void *data)
|
|||
args[1] = opaque_to_jsval( handler->cx, space );
|
||||
}
|
||||
|
||||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
|
||||
JS::RootedValue ignore(handler->cx);
|
||||
JS::RootedObject jsthis(handler->cx, handler->jsthis);
|
||||
JS::RootedValue jspost(handler->cx, OBJECT_TO_JSVAL(handler->post));
|
||||
|
@ -986,27 +1029,35 @@ static void myCollisionPost(cpArbiter *arb, cpSpace *space, void *data)
|
|||
static void myCollisionSeparate(cpArbiter *arb, cpSpace *space, void *data)
|
||||
{
|
||||
struct collision_handler *handler = (struct collision_handler*) data;
|
||||
if(! handler->cx || !handler->space)
|
||||
if (handler == nullptr || !handler->cx || !handler->space)
|
||||
return;
|
||||
|
||||
|
||||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
|
||||
JS::RootedValue jssep(handler->cx, OBJECT_TO_JSVAL(handler->separate));
|
||||
if (!jssep.isObject())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
jsval args[2];
|
||||
if( handler->is_oo ) {
|
||||
if (handler->is_oo)
|
||||
{
|
||||
JS::RootedObject arbiterProto(handler->cx, JSB_cpArbiter_object);
|
||||
JS::RootedObject spaceProto(handler->cx, JSB_cpSpace_object);
|
||||
args[0] = c_class_to_jsval(handler->cx, arb, arbiterProto, JSB_cpArbiter_class, "cpArbiter");
|
||||
args[1] = c_class_to_jsval(handler->cx, space, spaceProto, JSB_cpSpace_class, "cpArbiter");
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
args[0] = opaque_to_jsval( handler->cx, arb);
|
||||
args[1] = opaque_to_jsval( handler->cx, space );
|
||||
}
|
||||
|
||||
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
|
||||
|
||||
JS::RootedValue ignore(handler->cx);
|
||||
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");}
|
||||
JSB_PRECONDITION2(ok, handler->cx, , "Error calling collision callback: Separate");
|
||||
}
|
||||
|
||||
#pragma mark - cpSpace
|
||||
|
||||
|
@ -1015,22 +1066,33 @@ static void myCollisionSeparate(cpArbiter *arb, cpSpace *space, void *data)
|
|||
void JSB_cpSpace_finalize(JSFreeOp *fop, JSObject *jsthis)
|
||||
{
|
||||
struct jsb_c_proxy_s *proxy = jsb_get_c_proxy_for_jsobject(jsthis);
|
||||
if ( proxy ) {
|
||||
if ( proxy )
|
||||
{
|
||||
CCLOGINFO("jsbindings: finalizing JS object %p (cpSpace), handle: %p", jsthis, proxy->handle);
|
||||
|
||||
// space
|
||||
cpSpace *space = (cpSpace*) proxy->handle;
|
||||
|
||||
|
||||
// Remove collision handlers, since the user might have forgotten to manually remove them
|
||||
struct collision_handler *current = nullptr, *tmp = nullptr;
|
||||
HASH_ITER(hh, collision_handler_hash, current, tmp) {
|
||||
if( current->space == space ) {
|
||||
HASH_ITER(hh, collision_handler_hash, current, tmp)
|
||||
{
|
||||
if( current->space == space )
|
||||
{
|
||||
if (current->is_default)
|
||||
{
|
||||
cpCollisionHandler* defaultHandler = cpSpaceAddDefaultCollisionHandler(space);
|
||||
defaultHandler->userData = nullptr;
|
||||
defaultHandler->beginFunc = cpCollisionHandlerDoNothing.beginFunc;
|
||||
defaultHandler->preSolveFunc = cpCollisionHandlerDoNothing.preSolveFunc;
|
||||
defaultHandler->postSolveFunc = cpCollisionHandlerDoNothing.postSolveFunc;
|
||||
defaultHandler->separateFunc = cpCollisionHandlerDoNothing.separateFunc;
|
||||
}
|
||||
HASH_DEL(collision_handler_hash,current); /* delete; users advances to next */
|
||||
delete current; /* optional- if you want to free */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Free Space Children
|
||||
freeSpaceChildren(space);
|
||||
|
||||
|
@ -1064,13 +1126,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 = argvp->toObjectOrNull();
|
||||
handler->begin = argvp->isObject() ? argvp->toObjectOrNull() : nullptr;
|
||||
argvp++;
|
||||
handler->pre = argvp->toObjectOrNull();
|
||||
handler->pre = argvp->isObject() ? argvp->toObjectOrNull() : nullptr;
|
||||
argvp++;
|
||||
handler->post = argvp->toObjectOrNull();
|
||||
handler->post = argvp->isObject() ? argvp->toObjectOrNull() : nullptr;
|
||||
argvp++;
|
||||
handler->separate = argvp->toObjectOrNull();
|
||||
handler->separate = argvp->isObject() ? argvp->toObjectOrNull() : nullptr;
|
||||
argvp++;
|
||||
|
||||
JS::RootedValue spaceVal(cx, OBJECT_TO_JSVAL(jsspace));
|
||||
|
@ -1154,25 +1216,27 @@ bool JSB_cpSpace_setDefaultCollisionHandler(JSContext *cx, uint32_t argc, jsval
|
|||
|
||||
handler->typeA = 0;
|
||||
handler->typeB = 0;
|
||||
handler->begin = args.get(0).toObjectOrNull();
|
||||
handler->pre = args.get(1).toObjectOrNull();
|
||||
handler->post = args.get(2).toObjectOrNull();
|
||||
handler->separate = args.get(3).toObjectOrNull();
|
||||
handler->begin = args.get(0).isObject() ? args.get(0).toObjectOrNull() : nullptr;
|
||||
handler->pre = args.get(1).isObject() ? args.get(1).toObjectOrNull() : nullptr;
|
||||
handler->post = args.get(2).isObject() ? args.get(2).toObjectOrNull() : nullptr;
|
||||
handler->separate = args.get(3).isObject() ? args.get(3).toObjectOrNull() : nullptr;
|
||||
|
||||
JS::RootedValue spaceVal(cx, OBJECT_TO_JSVAL(jsthis));
|
||||
// Space must be set after set handles
|
||||
handler->setJSSpace(spaceVal);
|
||||
|
||||
// Object Oriented API ?
|
||||
handler->is_oo = 1;
|
||||
// Default handler shouldn't be removed
|
||||
handler->is_default = true;
|
||||
// owner of the collision handler
|
||||
handler->space = space;
|
||||
handler->cx = cx;
|
||||
|
||||
cpCollisionHandler* defaultHandler = cpSpaceAddDefaultCollisionHandler(space);
|
||||
defaultHandler->beginFunc = !handler->begin ? NULL : &myCollisionBegin;
|
||||
defaultHandler->preSolveFunc = !handler->pre ? NULL : &myCollisionPre;
|
||||
defaultHandler->postSolveFunc = !handler->post ? NULL : &myCollisionPost;
|
||||
defaultHandler->separateFunc = !handler->separate ? NULL : &myCollisionSeparate;
|
||||
defaultHandler->beginFunc = !handler->begin ? cpCollisionHandlerDoNothing.beginFunc : &myCollisionBegin;
|
||||
defaultHandler->preSolveFunc = !handler->pre ? cpCollisionHandlerDoNothing.preSolveFunc : &myCollisionPre;
|
||||
defaultHandler->postSolveFunc = !handler->post ? cpCollisionHandlerDoNothing.postSolveFunc : &myCollisionPost;
|
||||
defaultHandler->separateFunc = !handler->separate ? cpCollisionHandlerDoNothing.separateFunc : &myCollisionSeparate;
|
||||
defaultHandler->userData = handler;
|
||||
//
|
||||
// Already added ? If so, remove it.
|
||||
|
@ -2554,7 +2618,7 @@ static void unroot_jsobject_from_handle(void *handle)
|
|||
static void shapeFreeWrap(cpSpace *space, cpShape *shape, void *unused){
|
||||
cpSpaceRemoveShape(space, shape);
|
||||
unroot_jsobject_from_handle(shape);
|
||||
// cpShapeFree(shape);
|
||||
// cpShapeFree(shape);
|
||||
}
|
||||
|
||||
static void postShapeFree(cpShape *shape, cpSpace *space){
|
||||
|
@ -2564,7 +2628,7 @@ static void postShapeFree(cpShape *shape, cpSpace *space){
|
|||
static void constraintFreeWrap(cpSpace *space, cpConstraint *constraint, void *unused){
|
||||
cpSpaceRemoveConstraint(space, constraint);
|
||||
unroot_jsobject_from_handle(constraint);
|
||||
// cpConstraintFree(constraint);
|
||||
// cpConstraintFree(constraint);
|
||||
}
|
||||
|
||||
static void postConstraintFree(cpConstraint *constraint, cpSpace *space){
|
||||
|
@ -2574,7 +2638,7 @@ static void postConstraintFree(cpConstraint *constraint, cpSpace *space){
|
|||
static void bodyFreeWrap(cpSpace *space, cpBody *body, void *unused){
|
||||
cpSpaceRemoveBody(space, body);
|
||||
unroot_jsobject_from_handle(body);
|
||||
// cpBodyFree(body);
|
||||
// cpBodyFree(body);
|
||||
}
|
||||
|
||||
static void postBodyFree(cpBody *body, cpSpace *space){
|
||||
|
@ -2587,7 +2651,6 @@ void static freeSpaceChildren(cpSpace *space)
|
|||
// Must remove these BEFORE freeing the body or you will access dangling pointers.
|
||||
cpSpaceEachShape(space, (cpSpaceShapeIteratorFunc)postShapeFree, space);
|
||||
cpSpaceEachConstraint(space, (cpSpaceConstraintIteratorFunc)postConstraintFree, space);
|
||||
|
||||
cpSpaceEachBody(space, (cpSpaceBodyIteratorFunc)postBodyFree, space);
|
||||
}
|
||||
|
||||
|
@ -2620,4 +2683,4 @@ bool JSB_cpMomentForSegment(JSContext *cx, uint32_t argc, jsval *vp) {
|
|||
}
|
||||
|
||||
|
||||
#endif // JSB_INCLUDE_CHIPMUNK
|
||||
#endif // JSB_INCLUDE_CHIPMUNK
|
||||
|
|
|
@ -562,10 +562,19 @@ js_type_class_t *js_get_type_from_node(cocos2d::Node* native_obj)
|
|||
return js_get_type_from_native<cocos2d::Node>(native_obj);
|
||||
}
|
||||
|
||||
void js_add_FinalizeHook(JSContext *cx, JS::HandleObject target)
|
||||
void js_add_FinalizeHook(JSContext *cx, JS::HandleObject target, bool isRef)
|
||||
{
|
||||
JS::RootedObject proto(cx, jsb_FinalizeHook_prototype);
|
||||
JS::RootedObject hook(cx, JS_NewObject(cx, jsb_FinalizeHook_class, proto, JS::NullPtr()));
|
||||
JS::RootedObject hook(cx);
|
||||
if (isRef)
|
||||
{
|
||||
JS::RootedObject proto(cx, jsb_RefFinalizeHook_prototype);
|
||||
hook = JS_NewObject(cx, jsb_RefFinalizeHook_class, proto, JS::NullPtr());
|
||||
}
|
||||
else
|
||||
{
|
||||
JS::RootedObject proto(cx, jsb_ObjFinalizeHook_prototype);
|
||||
hook = JS_NewObject(cx, jsb_ObjFinalizeHook_class, proto, JS::NullPtr());
|
||||
}
|
||||
jsb_register_finalize_hook(hook.get(), target.get());
|
||||
JS::RootedValue hookVal(cx, OBJECT_TO_JSVAL(hook));
|
||||
JS_SetProperty(cx, target, "__hook", hookVal);
|
||||
|
@ -591,6 +600,7 @@ void js_add_object_reference(JS::HandleValue owner, JS::HandleValue target)
|
|||
ScriptingCore *engine = ScriptingCore::getInstance();
|
||||
JSContext *cx = engine->getGlobalContext();
|
||||
JS::RootedObject global(cx, engine->getGlobalObject());
|
||||
JSAutoCompartment(cx, global);
|
||||
JS::RootedObject jsbObj(cx);
|
||||
get_or_create_js_obj(cx, global, "jsb", &jsbObj);
|
||||
JS::RootedValue jsbVal(cx, OBJECT_TO_JSVAL(jsbObj));
|
||||
|
@ -615,10 +625,11 @@ void js_remove_object_reference(JS::HandleValue owner, JS::HandleValue target)
|
|||
}
|
||||
ScriptingCore *engine = ScriptingCore::getInstance();
|
||||
JSContext *cx = engine->getGlobalContext();
|
||||
JS::RootedObject global(cx, engine->getGlobalObject());
|
||||
JSAutoCompartment(cx, global);
|
||||
JS::RootedObject ownerObj(cx, owner.toObjectOrNull());
|
||||
JS::RootedObject targetObj(cx, target.toObjectOrNull());
|
||||
|
||||
JS::RootedObject global(cx, engine->getGlobalObject());
|
||||
|
||||
JS::RootedObject jsbObj(cx);
|
||||
get_or_create_js_obj(cx, global, "jsb", &jsbObj);
|
||||
JS::RootedValue jsbVal(cx, OBJECT_TO_JSVAL(jsbObj));
|
||||
|
@ -645,6 +656,7 @@ void js_add_object_root(JS::HandleValue target)
|
|||
ScriptingCore *engine = ScriptingCore::getInstance();
|
||||
JSContext *cx = engine->getGlobalContext();
|
||||
JS::RootedObject global(cx, engine->getGlobalObject());
|
||||
JSAutoCompartment(cx, global);
|
||||
JS::RootedObject jsbObj(cx);
|
||||
get_or_create_js_obj(cx, global, "jsb", &jsbObj);
|
||||
JS::RootedValue jsbVal(cx, OBJECT_TO_JSVAL(jsbObj));
|
||||
|
@ -673,6 +685,8 @@ void js_remove_object_root(JS::HandleValue target)
|
|||
}
|
||||
ScriptingCore *engine = ScriptingCore::getInstance();
|
||||
JSContext *cx = engine->getGlobalContext();
|
||||
JS::RootedObject global(cx, engine->getGlobalObject());
|
||||
JSAutoCompartment(cx, global);
|
||||
JS::RootedObject targetObj(cx, target.toObjectOrNull());
|
||||
js_proxy_t *pTarget = jsb_get_js_proxy(targetObj);
|
||||
if (!pTarget)
|
||||
|
@ -680,7 +694,6 @@ void js_remove_object_root(JS::HandleValue target)
|
|||
return;
|
||||
}
|
||||
|
||||
JS::RootedObject global(cx, engine->getGlobalObject());
|
||||
JS::RootedObject jsbObj(cx);
|
||||
get_or_create_js_obj(cx, global, "jsb", &jsbObj);
|
||||
JS::RootedValue jsbVal(cx, OBJECT_TO_JSVAL(jsbObj));
|
||||
|
@ -703,6 +716,7 @@ void js_remove_object_root(JS::HandleValue target)
|
|||
}
|
||||
|
||||
JSCallbackWrapper::JSCallbackWrapper()
|
||||
: _rooted(true)
|
||||
{
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
_jsCallback = JS::NullValue();
|
||||
|
@ -716,6 +730,7 @@ JSCallbackWrapper::JSCallbackWrapper()
|
|||
}
|
||||
|
||||
JSCallbackWrapper::JSCallbackWrapper(JS::HandleValue owner)
|
||||
: _rooted(true)
|
||||
{
|
||||
_owner = owner;
|
||||
_jsCallback = JS::NullValue();
|
||||
|
@ -727,7 +742,7 @@ JSCallbackWrapper::~JSCallbackWrapper()
|
|||
{
|
||||
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
|
||||
JS::RootedValue ownerVal(cx, _owner);
|
||||
if (!ownerVal.isNullOrUndefined())
|
||||
if (_rooted && !ownerVal.isNullOrUndefined())
|
||||
{
|
||||
JS::RootedValue target(cx, _jsCallback);
|
||||
if (!target.isNullOrUndefined())
|
||||
|
@ -1229,7 +1244,7 @@ void JSScheduleWrapper::dump()
|
|||
schedFunc_proxy_t *current_func, *tmp_func;
|
||||
int jsfuncTargetCount = 0;
|
||||
HASH_ITER(hh, _schedFunc_target_ht, current_func, tmp_func) {
|
||||
auto targets = current->targets;
|
||||
auto targets = current_func->targets;
|
||||
for (const auto& pObj : *targets)
|
||||
{
|
||||
CCLOG("js func ( %p ), native target[%d]=( %p )", current_func->jsfuncObj, jsfuncTargetCount, pObj);
|
||||
|
@ -1328,7 +1343,7 @@ bool js_CCNode_unschedule(JSContext *cx, uint32_t argc, jsval *vp)
|
|||
|
||||
auto targetArray = JSScheduleWrapper::getTargetForSchedule(args.get(0));
|
||||
if (targetArray) {
|
||||
CCLOGINFO("unschedule target number: %ld", static_cast<long>(targetArray->count()));
|
||||
CCLOGINFO("unschedule target number: %ld", static_cast<long>(targetArray->size()));
|
||||
|
||||
for (const auto& tmp : *targetArray)
|
||||
{
|
||||
|
@ -1707,7 +1722,7 @@ bool js_cocos2dx_CCNode_scheduleUpdate(JSContext *cx, uint32_t argc, jsval *vp)
|
|||
|
||||
if (!bFound)
|
||||
{
|
||||
tmpCobj = new (std::nothrow) JSScheduleWrapper(thisValue);
|
||||
tmpCobj = new (std::nothrow) JSScheduleWrapper(JS::NullHandleValue);
|
||||
tmpCobj->autorelease();
|
||||
tmpCobj->setJSCallbackThis(thisValue);
|
||||
tmpCobj->setJSCallbackFunc(jsUpdateFunc);
|
||||
|
@ -5876,15 +5891,17 @@ bool js_cocos2dx_ComponentJS_getScriptObject(JSContext *cx, uint32_t argc, jsval
|
|||
return false;
|
||||
}
|
||||
|
||||
JSClass *jsb_FinalizeHook_class;
|
||||
JSObject *jsb_FinalizeHook_prototype;
|
||||
JSClass *jsb_RefFinalizeHook_class;
|
||||
JSObject *jsb_RefFinalizeHook_prototype;
|
||||
JSClass *jsb_ObjFinalizeHook_class;
|
||||
JSObject *jsb_ObjFinalizeHook_prototype;
|
||||
|
||||
static bool jsb_FinalizeHook_constructor(JSContext *cx, uint32_t argc, jsval *vp)
|
||||
static bool jsb_RefFinalizeHook_constructor(JSContext *cx, uint32_t argc, jsval *vp)
|
||||
{
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
// Create new object
|
||||
JS::RootedObject proto(cx, jsb_FinalizeHook_prototype);
|
||||
JS::RootedObject obj(cx, JS_NewObject(cx, jsb_FinalizeHook_class, proto, JS::NullPtr()));
|
||||
JS::RootedObject proto(cx, jsb_RefFinalizeHook_prototype);
|
||||
JS::RootedObject obj(cx, JS_NewObject(cx, jsb_RefFinalizeHook_class, proto, JS::NullPtr()));
|
||||
// Register arguments[0] as owner
|
||||
if (!args.get(0).isNullOrUndefined())
|
||||
{
|
||||
|
@ -5893,7 +5910,7 @@ static bool jsb_FinalizeHook_constructor(JSContext *cx, uint32_t argc, jsval *vp
|
|||
args.rval().set(OBJECT_TO_JSVAL(obj));
|
||||
return true;
|
||||
}
|
||||
void jsb_FinalizeHook_finalize(JSFreeOp *fop, JSObject *obj)
|
||||
void jsb_RefFinalizeHook_finalize(JSFreeOp *fop, JSObject *obj)
|
||||
{
|
||||
ScriptingCore *sc = ScriptingCore::getInstance();
|
||||
JSContext *cx = sc->getGlobalContext();
|
||||
|
@ -5902,7 +5919,7 @@ void jsb_FinalizeHook_finalize(JSFreeOp *fop, JSObject *obj)
|
|||
if (ownerPtr)
|
||||
{
|
||||
JS::RootedObject owner(cx, ownerPtr);
|
||||
CCLOGINFO("jsbindings: finalizing JS object via Finalizehook %p", owner.get());
|
||||
CCLOGINFO("jsbindings: finalizing JS object via RefFinalizehook %p", owner.get());
|
||||
js_proxy_t* nproxy = nullptr;
|
||||
js_proxy_t* jsproxy = nullptr;
|
||||
jsproxy = jsb_get_js_proxy(owner);
|
||||
|
@ -5931,11 +5948,6 @@ void jsb_FinalizeHook_finalize(JSFreeOp *fop, JSObject *obj)
|
|||
CCLOG("------RELEASED------ Cpp: %p - JS: %p", refObj, ownerPtr);
|
||||
#endif // COCOS2D_DEBUG
|
||||
}
|
||||
#if COCOS2D_DEBUG > 1
|
||||
else {
|
||||
CCLOG("A non ref object have registered finalize hook: %p", nproxy->ptr);
|
||||
}
|
||||
#endif // COCOS2D_DEBUG
|
||||
sc->setFinalizing(nullptr);
|
||||
}
|
||||
#if COCOS2D_DEBUG > 1
|
||||
|
@ -5945,24 +5957,83 @@ void jsb_FinalizeHook_finalize(JSFreeOp *fop, JSObject *obj)
|
|||
#endif // COCOS2D_DEBUG
|
||||
}
|
||||
}
|
||||
static bool jsb_ObjFinalizeHook_constructor(JSContext *cx, uint32_t argc, jsval *vp)
|
||||
{
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
// Create new object
|
||||
JS::RootedObject proto(cx, jsb_ObjFinalizeHook_prototype);
|
||||
JS::RootedObject obj(cx, JS_NewObject(cx, jsb_ObjFinalizeHook_class, proto, JS::NullPtr()));
|
||||
// Register arguments[0] as owner
|
||||
if (!args.get(0).isNullOrUndefined())
|
||||
{
|
||||
jsb_register_finalize_hook(obj.get(), args.get(0).toObjectOrNull());
|
||||
}
|
||||
args.rval().set(OBJECT_TO_JSVAL(obj));
|
||||
return true;
|
||||
}
|
||||
void jsb_ObjFinalizeHook_finalize(JSFreeOp *fop, JSObject *obj)
|
||||
{
|
||||
ScriptingCore *sc = ScriptingCore::getInstance();
|
||||
JSContext *cx = sc->getGlobalContext();
|
||||
JS::RootedObject jsobj(cx, obj);
|
||||
JSObject *ownerPtr = jsb_get_and_remove_hook_owner(obj);
|
||||
if (ownerPtr)
|
||||
{
|
||||
JS::RootedObject owner(cx, ownerPtr);
|
||||
CCLOGINFO("jsbindings: finalizing JS object via ObjFinalizehook %p", owner.get());
|
||||
js_proxy_t* nproxy = nullptr;
|
||||
js_proxy_t* jsproxy = nullptr;
|
||||
jsproxy = jsb_get_js_proxy(owner);
|
||||
if (jsproxy)
|
||||
{
|
||||
sc->setFinalizing(ownerPtr);
|
||||
|
||||
nproxy = jsb_get_native_proxy(jsproxy->ptr);
|
||||
jsb_remove_proxy(nproxy, jsproxy);
|
||||
#if COCOS2D_DEBUG > 1
|
||||
CCLOG("------WEAK_REF------ Cpp: %p - JS: %p", nproxy->ptr, ownerPtr);
|
||||
#endif // COCOS2D_DEBUG
|
||||
sc->setFinalizing(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void jsb_register_FinalizeHook(JSContext *cx, JS::HandleObject global) {
|
||||
jsb_FinalizeHook_class = (JSClass *)calloc(1, sizeof(JSClass));
|
||||
jsb_FinalizeHook_class->name = "FinalizeHook";
|
||||
jsb_FinalizeHook_class->addProperty = JS_PropertyStub;
|
||||
jsb_FinalizeHook_class->delProperty = JS_DeletePropertyStub;
|
||||
jsb_FinalizeHook_class->getProperty = JS_PropertyStub;
|
||||
jsb_FinalizeHook_class->setProperty = JS_StrictPropertyStub;
|
||||
jsb_FinalizeHook_class->enumerate = JS_EnumerateStub;
|
||||
jsb_FinalizeHook_class->resolve = JS_ResolveStub;
|
||||
jsb_FinalizeHook_class->convert = JS_ConvertStub;
|
||||
jsb_FinalizeHook_class->finalize = jsb_FinalizeHook_finalize;
|
||||
jsb_FinalizeHook_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);
|
||||
void jsb_register_RefFinalizeHook(JSContext *cx, JS::HandleObject global) {
|
||||
jsb_RefFinalizeHook_class = (JSClass *)calloc(1, sizeof(JSClass));
|
||||
jsb_RefFinalizeHook_class->name = "RefFinalizeHook";
|
||||
jsb_RefFinalizeHook_class->addProperty = JS_PropertyStub;
|
||||
jsb_RefFinalizeHook_class->delProperty = JS_DeletePropertyStub;
|
||||
jsb_RefFinalizeHook_class->getProperty = JS_PropertyStub;
|
||||
jsb_RefFinalizeHook_class->setProperty = JS_StrictPropertyStub;
|
||||
jsb_RefFinalizeHook_class->enumerate = JS_EnumerateStub;
|
||||
jsb_RefFinalizeHook_class->resolve = JS_ResolveStub;
|
||||
jsb_RefFinalizeHook_class->convert = JS_ConvertStub;
|
||||
jsb_RefFinalizeHook_class->finalize = jsb_RefFinalizeHook_finalize;
|
||||
jsb_RefFinalizeHook_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);
|
||||
|
||||
jsb_FinalizeHook_prototype = JS_InitClass(cx, global,
|
||||
jsb_RefFinalizeHook_prototype = JS_InitClass(cx, global,
|
||||
JS::NullPtr(), // parent proto
|
||||
jsb_FinalizeHook_class,
|
||||
jsb_FinalizeHook_constructor, 0, // constructor
|
||||
jsb_RefFinalizeHook_class,
|
||||
jsb_RefFinalizeHook_constructor, 0, // constructor
|
||||
NULL, NULL, NULL, NULL);
|
||||
}
|
||||
void jsb_register_ObjFinalizeHook(JSContext *cx, JS::HandleObject global) {
|
||||
jsb_ObjFinalizeHook_class = (JSClass *)calloc(1, sizeof(JSClass));
|
||||
jsb_ObjFinalizeHook_class->name = "ObjFinalizeHook";
|
||||
jsb_ObjFinalizeHook_class->addProperty = JS_PropertyStub;
|
||||
jsb_ObjFinalizeHook_class->delProperty = JS_DeletePropertyStub;
|
||||
jsb_ObjFinalizeHook_class->getProperty = JS_PropertyStub;
|
||||
jsb_ObjFinalizeHook_class->setProperty = JS_StrictPropertyStub;
|
||||
jsb_ObjFinalizeHook_class->enumerate = JS_EnumerateStub;
|
||||
jsb_ObjFinalizeHook_class->resolve = JS_ResolveStub;
|
||||
jsb_ObjFinalizeHook_class->convert = JS_ConvertStub;
|
||||
jsb_ObjFinalizeHook_class->finalize = jsb_ObjFinalizeHook_finalize;
|
||||
jsb_ObjFinalizeHook_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);
|
||||
|
||||
jsb_ObjFinalizeHook_prototype = JS_InitClass(cx, global,
|
||||
JS::NullPtr(), // parent proto
|
||||
jsb_ObjFinalizeHook_class,
|
||||
jsb_ObjFinalizeHook_constructor, 0, // constructor
|
||||
NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
@ -5976,7 +6047,8 @@ void register_cocos2dx_js_core(JSContext* cx, JS::HandleObject global)
|
|||
get_or_create_js_obj(cx, global, "jsb", &jsbObj);
|
||||
|
||||
// Memory management related
|
||||
jsb_register_FinalizeHook(cx, jsbObj);
|
||||
jsb_register_RefFinalizeHook(cx, jsbObj);
|
||||
jsb_register_ObjFinalizeHook(cx, jsbObj);
|
||||
|
||||
js_register_cocos2dx_PolygonInfo(cx, jsbObj);
|
||||
js_register_cocos2dx_AutoPolygon(cx, jsbObj);
|
||||
|
|
|
@ -79,8 +79,10 @@ extern schedFunc_proxy_t *_schedFunc_target_ht;
|
|||
extern schedTarget_proxy_t *_schedObj_target_ht;
|
||||
extern callfuncTarget_proxy_t *_callfuncTarget_native_ht;
|
||||
|
||||
extern JSClass *jsb_FinalizeHook_class;
|
||||
extern JSObject *jsb_FinalizeHook_prototype;
|
||||
extern JSClass *jsb_RefFinalizeHook_class;
|
||||
extern JSObject *jsb_RefFinalizeHook_prototype;
|
||||
extern JSClass *jsb_ObjFinalizeHook_class;
|
||||
extern JSObject *jsb_ObjFinalizeHook_prototype;
|
||||
|
||||
/**
|
||||
* You don't need to manage the returned pointer. They live for the whole life of
|
||||
|
@ -142,7 +144,7 @@ JSObject* js_get_or_create_jsobject(JSContext *cx, typename std::enable_if<std::
|
|||
* In the finalize function, it mainly remove native/js proxys, release/delete the native object.
|
||||
* IMPORTANT: For Ref objects, please remember to retain the native object to correctly manage its reference count.
|
||||
*/
|
||||
void js_add_FinalizeHook(JSContext *cx, JS::HandleObject target);
|
||||
void js_add_FinalizeHook(JSContext *cx, JS::HandleObject target, bool isRef=true);
|
||||
|
||||
void js_add_object_reference(JS::HandleValue owner, JS::HandleValue target);
|
||||
void js_remove_object_reference(JS::HandleValue owner, JS::HandleValue target);
|
||||
|
@ -170,6 +172,7 @@ protected:
|
|||
JS::Heap<JS::Value> _jsCallback;
|
||||
JS::Heap<JS::Value> _jsThisObj;
|
||||
JS::Heap<JS::Value> _extraData;
|
||||
bool _rooted;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ class JSCCBAnimationWrapper: public JSCallbackWrapper
|
|||
{
|
||||
public:
|
||||
JSCCBAnimationWrapper(JS::HandleValue owner) : JSCallbackWrapper(owner) {}
|
||||
virtual ~JSCCBAnimationWrapper() {}
|
||||
|
||||
void animationCompleteCallback()
|
||||
{
|
||||
|
|
|
@ -107,6 +107,7 @@ const char* JSStringWrapper::get()
|
|||
// JSFunctionWrapper
|
||||
JSFunctionWrapper::JSFunctionWrapper(JSContext* cx, JS::HandleObject jsthis, JS::HandleValue fval)
|
||||
: _cx(cx)
|
||||
, _rooted(false)
|
||||
{
|
||||
_jsthis = jsthis;
|
||||
_fval = fval;
|
||||
|
@ -128,10 +129,12 @@ JSFunctionWrapper::JSFunctionWrapper(JSContext* cx, JS::HandleObject jsthis, JS:
|
|||
{
|
||||
js_add_object_reference(valRoot, funcVal);
|
||||
}
|
||||
_rooted = true;
|
||||
}
|
||||
}
|
||||
JSFunctionWrapper::JSFunctionWrapper(JSContext* cx, JS::HandleObject jsthis, JS::HandleValue fval, JS::HandleValue owner)
|
||||
: _cx(cx)
|
||||
, _rooted(false)
|
||||
{
|
||||
_jsthis = jsthis;
|
||||
_fval = fval;
|
||||
|
@ -154,7 +157,7 @@ JSFunctionWrapper::~JSFunctionWrapper()
|
|||
{
|
||||
JS::RootedValue ownerVal(_cx, _owner);
|
||||
|
||||
if (!ownerVal.isNullOrUndefined() && ScriptingCore::getInstance()->getFinalizing() != ownerVal.toObjectOrNull())
|
||||
if (_rooted && !ownerVal.isNullOrUndefined())
|
||||
{
|
||||
JS::RootedValue thisVal(_cx, OBJECT_TO_JSVAL(_jsthis));
|
||||
if (!thisVal.isNullOrUndefined())
|
||||
|
|
|
@ -85,6 +85,7 @@ private:
|
|||
JS::Heap<JSObject*> _jsthis;
|
||||
JS::Heap<JS::Value> _fval;
|
||||
JS::Heap<JS::Value> _owner;
|
||||
bool _rooted;
|
||||
private:
|
||||
CC_DISALLOW_COPY_AND_ASSIGN(JSFunctionWrapper);
|
||||
};
|
||||
|
|
|
@ -179,7 +179,7 @@ bool js_EventListenerAcceleration_create(JSContext *cx, uint32_t argc, jsval *vp
|
|||
largv[0] = ccacceleration_to_jsval(cx, *acc);
|
||||
if (event) {
|
||||
js_type_class_t *typeClassEvent = js_get_type_from_native<Event>(event);
|
||||
largv[1] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(cx, event, typeClassEvent, "cocos2d::EventAcceleration"));
|
||||
largv[1] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(cx, event, typeClassEvent));
|
||||
} else {
|
||||
largv[1] = JSVAL_NULL;
|
||||
};
|
||||
|
@ -246,7 +246,7 @@ bool js_EventListenerCustom_create(JSContext *cx, uint32_t argc, jsval *vp)
|
|||
jsval largv[1];
|
||||
if (event) {
|
||||
js_type_class_t *typeClassEvent = js_get_type_from_native<EventCustom>(event);
|
||||
largv[0] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(cx, event, typeClassEvent, "cocos2d::EventCustom"));
|
||||
largv[0] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(cx, event, typeClassEvent));
|
||||
} else {
|
||||
largv[0] = JSVAL_NULL;
|
||||
};
|
||||
|
@ -298,7 +298,7 @@ bool js_EventDispatcher_addCustomEventListener(JSContext *cx, uint32_t argc, jsv
|
|||
jsval largv[1];
|
||||
if (event) {
|
||||
js_type_class_t *typeClassEvent = js_get_type_from_native<EventCustom>(event);
|
||||
largv[0] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(cx, event, typeClassEvent, "cocos2d::EventCustom"));
|
||||
largv[0] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(cx, event, typeClassEvent));
|
||||
} else {
|
||||
largv[0] = JSVAL_NULL;
|
||||
};
|
||||
|
|
|
@ -400,7 +400,7 @@ JS_BINDED_CONSTRUCTOR_IMPL(MinXmlHttpRequest)
|
|||
js_proxy_t *p = jsb_new_proxy(req, obj);
|
||||
|
||||
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
|
||||
js_add_FinalizeHook(cx, obj);
|
||||
js_add_FinalizeHook(cx, obj, true);
|
||||
// don't retain it, already retained
|
||||
#if COCOS2D_DEBUG > 1
|
||||
CCLOG("++++++RETAINED++++++ Cpp(XMLHttpRequest): %p - JS: %p", req, obj.get());
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
|
||||
using namespace spine;
|
||||
|
||||
std::unordered_map<spTrackEntry*, jsval> _spTrackEntryMap;
|
||||
|
||||
jsval speventdata_to_jsval(JSContext* cx, spEventData& v)
|
||||
{
|
||||
JS::RootedObject tmp(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
|
||||
|
@ -279,45 +277,68 @@ jsval spanimation_to_jsval(JSContext* cx, spAnimation& v)
|
|||
return JSVAL_NULL;
|
||||
}
|
||||
|
||||
bool jsb_spine_TrackEntry_get_next(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp)
|
||||
{
|
||||
JS::RootedObject jsthis(cx, obj);
|
||||
js_proxy_t *proxy = jsb_get_js_proxy(jsthis);
|
||||
spTrackEntry* cobj = (spTrackEntry *)(proxy ? proxy->ptr : NULL);
|
||||
if (cobj) {
|
||||
JS::RootedValue jsret(cx, JS::NullValue());
|
||||
if (cobj->next)
|
||||
{
|
||||
jsret = sptrackentry_to_jsval(cx, *cobj->next);
|
||||
}
|
||||
vp.set(jsret);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
CCLOGERROR("jsb_spine_TrackEntry_get_next : Invalid Native Object");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool jsb_spine_TrackEntry_get_previous(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp)
|
||||
{
|
||||
JS::RootedObject jsthis(cx, obj);
|
||||
js_proxy_t *proxy = jsb_get_js_proxy(jsthis);
|
||||
spTrackEntry* cobj = (spTrackEntry *)(proxy ? proxy->ptr : NULL);
|
||||
if (cobj) {
|
||||
JS::RootedValue jsret(cx, JS::NullValue());
|
||||
if (cobj->previous)
|
||||
{
|
||||
jsret = sptrackentry_to_jsval(cx, *cobj->previous);
|
||||
}
|
||||
vp.set(jsret);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
CCLOGERROR("jsb_spine_TrackEntry_get_previous : Invalid Native Object");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
jsval sptrackentry_to_jsval(JSContext* cx, spTrackEntry& v)
|
||||
{
|
||||
JS::RootedObject tmp(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
|
||||
if (!tmp) return JSVAL_NULL;
|
||||
|
||||
JS::RootedValue nextVal(cx);
|
||||
if (v.next)
|
||||
js_proxy_t *proxy = jsb_get_native_proxy(&v);
|
||||
if (proxy)
|
||||
{
|
||||
auto nextPtr = v.next;
|
||||
auto entry = _spTrackEntryMap.find(nextPtr);
|
||||
if (entry == _spTrackEntryMap.end())
|
||||
{
|
||||
_spTrackEntryMap.emplace(nextPtr, nextVal.get());
|
||||
nextVal = sptrackentry_to_jsval(cx, *v.next);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextVal.set(entry->second);
|
||||
}
|
||||
JS::RootedObject entry(cx, proxy->obj);
|
||||
return OBJECT_TO_JSVAL(entry);
|
||||
}
|
||||
|
||||
JS::RootedValue previousVal(cx);
|
||||
if (v.previous)
|
||||
else
|
||||
{
|
||||
auto previousPtr = v.previous;
|
||||
auto entry = _spTrackEntryMap.find(previousPtr);
|
||||
if (entry == _spTrackEntryMap.end())
|
||||
{
|
||||
_spTrackEntryMap.emplace(previousPtr, previousVal.get());
|
||||
previousVal = sptrackentry_to_jsval(cx, *previousPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
previousVal.set(entry->second);
|
||||
}
|
||||
}
|
||||
|
||||
JS::RootedValue jsanimation(cx, spanimation_to_jsval(cx, *v.animation));
|
||||
bool ok = JS_DefineProperty(cx, tmp, "delay", v.delay, JSPROP_ENUMERATE | JSPROP_PERMANENT) &&
|
||||
JS::RootedObject tmp(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
|
||||
if (!tmp) return JSVAL_NULL;
|
||||
|
||||
jsb_new_proxy(&v, tmp);
|
||||
js_add_FinalizeHook(cx, tmp, false);
|
||||
|
||||
#if COCOS2D_DEBUG > 1
|
||||
CCLOG("++++++WEAK_REF++++++ Cpp(spine::TrackEntry): %p - JS: %p", &v, tmp.get());
|
||||
#endif // COCOS2D_DEBUG
|
||||
|
||||
JS::RootedValue jsanimation(cx, spanimation_to_jsval(cx, *v.animation));
|
||||
bool ok = JS_DefineProperty(cx, tmp, "delay", v.delay, JSPROP_ENUMERATE | JSPROP_PERMANENT) &&
|
||||
JS_DefineProperty(cx, tmp, "time", v.time, JSPROP_ENUMERATE | JSPROP_PERMANENT) &&
|
||||
JS_DefineProperty(cx, tmp, "lastTime", v.lastTime, JSPROP_ENUMERATE | JSPROP_PERMANENT) &&
|
||||
JS_DefineProperty(cx, tmp, "endTime", v.endTime, JSPROP_ENUMERATE | JSPROP_PERMANENT) &&
|
||||
|
@ -325,15 +346,16 @@ jsval sptrackentry_to_jsval(JSContext* cx, spTrackEntry& v)
|
|||
JS_DefineProperty(cx, tmp, "mixTime", v.mixTime, JSPROP_ENUMERATE | JSPROP_PERMANENT) &&
|
||||
JS_DefineProperty(cx, tmp, "mixDuration", v.mixDuration, JSPROP_ENUMERATE | JSPROP_PERMANENT) &&
|
||||
JS_DefineProperty(cx, tmp, "animation", jsanimation, JSPROP_ENUMERATE | JSPROP_PERMANENT) &&
|
||||
JS_DefineProperty(cx, tmp, "next", nextVal, JSPROP_ENUMERATE | JSPROP_PERMANENT) &&
|
||||
JS_DefineProperty(cx, tmp, "previous", previousVal, JSPROP_ENUMERATE | JSPROP_PERMANENT);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
return OBJECT_TO_JSVAL(tmp);
|
||||
JS_DefineProperty(cx, tmp, "next", JS::UndefinedHandleValue, JSPROP_ENUMERATE | JSPROP_PERMANENT, jsb_spine_TrackEntry_get_next) &&
|
||||
JS_DefineProperty(cx, tmp, "previous", JS::UndefinedHandleValue, JSPROP_ENUMERATE | JSPROP_PERMANENT, jsb_spine_TrackEntry_get_previous);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
return OBJECT_TO_JSVAL(tmp);
|
||||
}
|
||||
|
||||
return JSVAL_NULL;
|
||||
}
|
||||
|
||||
return JSVAL_NULL;
|
||||
}
|
||||
|
||||
bool jsb_cocos2dx_spine_findBone(JSContext *cx, uint32_t argc, jsval *vp)
|
||||
|
@ -481,7 +503,6 @@ bool jsb_cocos2dx_spine_getCurrent(JSContext *cx, uint32_t argc, jsval *vp)
|
|||
if (ret)
|
||||
{
|
||||
jsret = sptrackentry_to_jsval(cx, *ret);
|
||||
_spTrackEntryMap.clear();
|
||||
}
|
||||
} while (0);
|
||||
|
||||
|
@ -495,7 +516,6 @@ bool jsb_cocos2dx_spine_getCurrent(JSContext *cx, uint32_t argc, jsval *vp)
|
|||
if (ret)
|
||||
{
|
||||
jsret = sptrackentry_to_jsval(cx, *ret);
|
||||
_spTrackEntryMap.clear();
|
||||
}
|
||||
} while (0);
|
||||
|
||||
|
@ -532,7 +552,6 @@ bool jsb_cocos2dx_spine_setAnimation(JSContext *cx, uint32_t argc, jsval *vp)
|
|||
if (ret)
|
||||
{
|
||||
jsret = sptrackentry_to_jsval(cx, *ret);
|
||||
_spTrackEntryMap.clear();
|
||||
}
|
||||
} while(0);
|
||||
|
||||
|
@ -570,7 +589,6 @@ bool jsb_cocos2dx_spine_addAnimation(JSContext *cx, uint32_t argc, jsval *vp)
|
|||
if (ret)
|
||||
{
|
||||
jsret = sptrackentry_to_jsval(cx, *ret);
|
||||
_spTrackEntryMap.clear();
|
||||
}
|
||||
} while(0);
|
||||
|
||||
|
@ -596,7 +614,6 @@ bool jsb_cocos2dx_spine_addAnimation(JSContext *cx, uint32_t argc, jsval *vp)
|
|||
if (ret)
|
||||
{
|
||||
jsret = sptrackentry_to_jsval(cx, *ret);
|
||||
_spTrackEntryMap.clear();
|
||||
}
|
||||
} while(0);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ ccui.Widget.prototype._ctor
|
|||
= ccui.ScrollView.prototype._ctor
|
||||
= function(){
|
||||
this.init();
|
||||
}
|
||||
};
|
||||
|
||||
ccui.Button.prototype._ctor = function (normalImage, selectedImage, disableImage, texType) {
|
||||
if(texType !== undefined)
|
||||
|
@ -80,7 +80,7 @@ ccui.ImageView.prototype._ctor = function(imageFileName, texType){
|
|||
}
|
||||
else
|
||||
ccui.Widget.prototype.init.call(this);
|
||||
}
|
||||
};
|
||||
|
||||
ccui.LoadingBar.prototype._ctor = function(textureName, percentage){
|
||||
ccui.Widget.prototype.init.call(this);
|
||||
|
|
|
@ -737,35 +737,32 @@ cc.defineGetterSetter(cc.loader, "audioPath", function(){
|
|||
cc.formatStr = function(){
|
||||
var args = arguments;
|
||||
var l = args.length;
|
||||
if(l < 1)
|
||||
return "";
|
||||
if (l < 1) return '';
|
||||
var REGEXP_NUM_OR_STR = /(%d)|(%s)/;
|
||||
|
||||
var i = 1;
|
||||
var str = args[0];
|
||||
var needToFormat = true;
|
||||
if(typeof str === "object"){
|
||||
needToFormat = false;
|
||||
var hasSubstitution = typeof str === 'string' && REGEXP_NUM_OR_STR.test(str);
|
||||
if (hasSubstitution) {
|
||||
var REGEXP_STR = /%s/;
|
||||
for (; i < l; ++i) {
|
||||
var arg = args[i];
|
||||
var regExpToTest = typeof arg === 'number' ? REGEXP_NUM_OR_STR : REGEXP_STR;
|
||||
if (regExpToTest.test(str))
|
||||
str = str.replace(regExpToTest, arg);
|
||||
else
|
||||
str += ' ' + arg;
|
||||
}
|
||||
}
|
||||
for(var i = 1; i < l; ++i){
|
||||
var arg = args[i];
|
||||
if(needToFormat){
|
||||
while(true){
|
||||
var result = null;
|
||||
if(typeof arg === "number"){
|
||||
result = str.match(/(%d)|(%s)/);
|
||||
if(result){
|
||||
str = str.replace(/(%d)|(%s)/, arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = str.match(/%s/);
|
||||
if(result)
|
||||
str = str.replace(/%s/, arg);
|
||||
else
|
||||
str += " " + arg;
|
||||
break;
|
||||
else {
|
||||
if (l > 1) {
|
||||
for (; i < l; ++i) {
|
||||
str += ' ' + args[i];
|
||||
}
|
||||
}else
|
||||
str += " " + arg;
|
||||
}
|
||||
else {
|
||||
str = '' + str;
|
||||
}
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
// CCConfig.js
|
||||
//
|
||||
cc.ENGINE_VERSION = "Cocos2d-JS v3.13";
|
||||
cc.ENGINE_VERSION = "Cocos2d-JS v3.14";
|
||||
|
||||
cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL = 0;
|
||||
cc.DIRECTOR_STATS_POSITION = {x: 0, y: 0};
|
||||
|
|
|
@ -214,7 +214,7 @@ bool ControlSwitchSprite::initWithMaskSprite(
|
|||
return false;
|
||||
}
|
||||
|
||||
void ControlSwitchSprite::updateTweenAction(float value, const std::string& /*key*/)
|
||||
void ControlSwitchSprite::updateTweenAction(float value, const std::string& key)
|
||||
{
|
||||
CCLOGINFO("key = %s, value = %f", key.c_str(), value);
|
||||
setSliderXPosition(value);
|
||||
|
|
2
web
2
web
|
@ -1 +1 @@
|
|||
Subproject commit 640431814638f732a4b886182820cc8a88a75e87
|
||||
Subproject commit e5fe5bbf4f8e1016d58c56ee7079f38f38b2bfb1
|
Loading…
Reference in New Issue