Skip to content

Commit a8a9c8e

Browse files
committed
Merge pull request cocos2d#14694 from ricardoquesada/v3_10_js_fixes
ccvector_to / ccmap_to converted to new API
2 parents 1bbb633 + eb8e755 commit a8a9c8e

9 files changed

+92
-113
lines changed

cocos/base/CCRef.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Ref::Ref()
6565

6666
Ref::~Ref()
6767
{
68-
#if CC_ENABLE_SCRIPT_BINDING
68+
#if CC_ENABLE_SCRIPT_BINDING && not CC_ENABLE_GC_FOR_NATIVE_OBJECTS
6969
// if the object is referenced by Lua engine, remove it
7070
if (_luaID)
7171
{
@@ -100,11 +100,7 @@ void Ref::retain()
100100
if (scriptMgr && scriptMgr->getScriptType() == kScriptTypeJavascript)
101101
{
102102
_referenceCountAtRootTime = _referenceCount-1;
103-
104-
CCLOG("retain + root: %p (%s) rc=%d rcrt=%d", this, typeid(*this).name(), _referenceCount, _referenceCountAtRootTime);
105-
106103
scriptMgr->rootObject(this);
107-
_rooted = true;
108104
}
109105
}
110106
#endif // CC_ENABLE_SCRIPT_BINDING
@@ -116,13 +112,12 @@ void Ref::release()
116112
--_referenceCount;
117113

118114
#if CC_ENABLE_SCRIPT_BINDING && CC_ENABLE_GC_FOR_NATIVE_OBJECTS
119-
if (_scriptOwned && _rooted && _referenceCount==_referenceCountAtRootTime)
115+
if (_scriptOwned && _rooted && _referenceCount==/*_referenceCountAtRootTime*/ 1)
120116
{
121117
auto scriptMgr = ScriptEngineManager::getInstance()->getScriptEngine();
122118
if (scriptMgr && scriptMgr->getScriptType() == kScriptTypeJavascript)
123119
{
124120
scriptMgr->unrootObject(this);
125-
_rooted = false;
126121
}
127122
}
128123
#endif // CC_ENABLE_SCRIPT_BINDING

cocos/scripting/js-bindings/manual/ScriptingCore.cpp

Lines changed: 71 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -212,18 +212,30 @@ static std::string getMouseFuncName(EventMouse::MouseEventType eventType)
212212
return funcName;
213213
}
214214

215-
void removeJSObject(JSContext* cx, void* nativeObj)
215+
static void removeJSObject(JSContext* cx, cocos2d::Ref* nativeObj)
216216
{
217217
js_proxy_t* nproxy;
218218
js_proxy_t* jsproxy;
219219

220220
nproxy = jsb_get_native_proxy(nativeObj);
221-
if (nproxy) {
222-
JS::RootedObject jsobj(cx, nproxy->obj);
223-
jsproxy = jsb_get_js_proxy(jsobj);
224-
RemoveObjectRoot(cx, &jsproxy->obj);
221+
if (nproxy)
222+
{
223+
jsproxy = jsb_get_js_proxy(nproxy->obj);
224+
JS::RemoveObjectRoot(cx, &jsproxy->obj);
225+
226+
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
227+
nativeObj->_rooted = false;
228+
229+
// FIXME BUG TODO: remove this line... but if I do so
230+
// another misterious bug appears
225231
jsb_remove_proxy(nproxy, jsproxy);
232+
#else
233+
// only remove when not using GC,
234+
// otherwise finalize won't be able to find the proxy
235+
jsb_remove_proxy(nproxy, jsproxy);
236+
#endif
226237
}
238+
else CCLOG("removeJSObject: BUG: cannot find native object = %p", nativeObj);
227239
}
228240

229241
void ScriptingCore::executeJSFunctionWithThisObj(JS::HandleValue thisObj, JS::HandleValue callback)
@@ -874,15 +886,16 @@ void ScriptingCore::removeScriptObjectByObject(Ref* pObj)
874886
nproxy = jsb_get_native_proxy(ptr);
875887
if (nproxy)
876888
{
877-
JSContext *cx = ScriptingCore::getInstance()->getGlobalContext();
878-
JS::RootedObject jsobj(cx, nproxy->obj);
879-
jsproxy = jsb_get_js_proxy(jsobj);
889+
JSContext *cx = getGlobalContext();
890+
jsproxy = jsb_get_js_proxy(nproxy->obj);
880891
if (jsproxy)
881892
{
882893
RemoveObjectRoot(cx, &jsproxy->obj);
883894
jsb_remove_proxy(nproxy, jsproxy);
884895
}
896+
// else CCLOG("removeScriptObjectByObject. BUG: jsproxy not found = %p", nproxy);
885897
}
898+
// else CCLOG("removeScriptObjectByObject. BUG: nproxy not found = %p", nproxy);
886899
}
887900

888901

@@ -1185,7 +1198,6 @@ bool ScriptingCore::handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::Eve
11851198

11861199
JS::RootedObject jsretArr(_cx, JS_NewArrayObject(this->_cx, 0));
11871200

1188-
// AddNamedObjectRoot(this->_cx, &jsretArr, "touchArray");
11891201
int count = 0;
11901202

11911203
js_type_class_t *typeClassEvent = nullptr;
@@ -1214,8 +1226,6 @@ bool ScriptingCore::handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::Eve
12141226
ret = executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), funcName.c_str(), 2, dataVal, jsvalRet);
12151227
}
12161228

1217-
// JS_RemoveObjectRoot(this->_cx, &jsretArr);
1218-
12191229
for (auto& touch : touches)
12201230
{
12211231
removeJSObject(this->_cx, touch);
@@ -1570,11 +1580,9 @@ void ScriptingCore::rootObject(Ref* ref)
15701580
JSContext *cx = getGlobalContext();
15711581
jsproxy = jsb_get_js_proxy(nproxy->obj);
15721582
JS::AddNamedObjectRoot(cx, &jsproxy->obj, typeid(*ref).name());
1583+
ref->_rooted = true;
15731584
}
1574-
else
1575-
{
1576-
CCLOG("BUG in rootObject");
1577-
}
1585+
else CCLOG("rootObject: BUG. native not found: %p", ref);
15781586
}
15791587

15801588
void ScriptingCore::unrootObject(Ref* ref)
@@ -1588,11 +1596,9 @@ void ScriptingCore::unrootObject(Ref* ref)
15881596
JSContext *cx = getGlobalContext();
15891597
jsproxy = jsb_get_js_proxy(nproxy->obj);
15901598
JS::RemoveObjectRoot(cx, &jsproxy->obj);
1599+
ref->_rooted = false;
15911600
}
1592-
else
1593-
{
1594-
CCLOG("BUG in unrootObject");
1595-
}
1601+
else CCLOG("unrootObject: BUG. native not found: %p", ref);
15961602
}
15971603

15981604
#pragma mark - Debug
@@ -1922,44 +1928,59 @@ js_proxy_t* jsb_new_proxy(void* nativeObj, JS::HandleObject jsObj)
19221928
{
19231929
js_proxy_t* p = nullptr;
19241930
JSObject* ptr = jsObj.get();
1925-
do {
1926-
p = (js_proxy_t *)malloc(sizeof(js_proxy_t));
1927-
assert(p);
1928-
js_proxy_t* nativeObjJsObjtmp = NULL;
1929-
HASH_FIND_PTR(_native_js_global_ht, &nativeObj, nativeObjJsObjtmp);
1930-
assert(!nativeObjJsObjtmp);
1931-
p->ptr = nativeObj;
1932-
p->obj = ptr;
1933-
HASH_ADD_PTR(_native_js_global_ht, ptr, p);
1934-
p = (js_proxy_t *)malloc(sizeof(js_proxy_t));
1935-
assert(p);
1936-
nativeObjJsObjtmp = NULL;
1937-
HASH_FIND_PTR(_js_native_global_ht, &ptr, nativeObjJsObjtmp);
1938-
assert(!nativeObjJsObjtmp);
1939-
p->ptr = nativeObj;
1940-
p->obj = ptr;
1941-
HASH_ADD_PTR(_js_native_global_ht, obj, p);
1942-
} while(0);
1931+
1932+
// native to JS index
1933+
p = (js_proxy_t *)malloc(sizeof(js_proxy_t));
1934+
assert(p);
1935+
js_proxy_t* nativeObjJsObjtmp = NULL;
1936+
HASH_FIND_PTR(_native_js_global_ht, &nativeObj, nativeObjJsObjtmp);
1937+
assert(!nativeObjJsObjtmp);
1938+
p->ptr = nativeObj;
1939+
p->obj = ptr;
1940+
HASH_ADD_PTR(_native_js_global_ht, ptr, p);
1941+
1942+
// JS to native Index
1943+
p = (js_proxy_t *)malloc(sizeof(js_proxy_t));
1944+
assert(p);
1945+
nativeObjJsObjtmp = NULL;
1946+
HASH_FIND_PTR(_js_native_global_ht, &ptr, nativeObjJsObjtmp);
1947+
assert(!nativeObjJsObjtmp);
1948+
p->ptr = nativeObj;
1949+
p->obj = ptr;
1950+
HASH_ADD_PTR(_js_native_global_ht, obj, p);
1951+
19431952
return p;
19441953
}
19451954

19461955
js_proxy_t* jsb_get_native_proxy(void* nativeObj)
19471956
{
19481957
js_proxy_t* p = nullptr;
1949-
JS_GET_PROXY(p, nativeObj);
1958+
HASH_FIND_PTR(_native_js_global_ht, &nativeObj, p);
19501959
return p;
19511960
}
19521961

19531962
js_proxy_t* jsb_get_js_proxy(JSObject* jsObj)
19541963
{
19551964
js_proxy_t* p = nullptr;
1956-
JS_GET_NATIVE_PROXY(p, jsObj);
1965+
HASH_FIND_PTR(_js_native_global_ht, &jsObj, p);
19571966
return p;
19581967
}
19591968

19601969
void jsb_remove_proxy(js_proxy_t* nativeProxy, js_proxy_t* jsProxy)
19611970
{
1962-
JS_REMOVE_PROXY(nativeProxy, jsProxy);
1971+
if (nativeProxy)
1972+
{
1973+
HASH_DEL(_native_js_global_ht, nativeProxy);
1974+
free(nativeProxy);
1975+
}
1976+
else CCLOG("jsb_remove_proxy: BUG: nativeProxy is null");
1977+
1978+
if (jsProxy)
1979+
{
1980+
HASH_DEL(_js_native_global_ht, jsProxy);
1981+
free(jsProxy);
1982+
}
1983+
else CCLOG("jsb_remove_proxy: BUG: jsProxy is null");
19631984
}
19641985

19651986
//
@@ -2001,7 +2022,10 @@ JSObject* jsb_ref_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_ty
20012022
js_proxy_t* newproxy = jsb_new_proxy(ref, js_obj);
20022023
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
20032024
CC_UNUSED_PARAM(newproxy);
2004-
// don't retain it.
2025+
2026+
// retain first copy, and before "owning" to prevent it
2027+
// from calling "rootObject"
2028+
ref->retain();
20052029
ref->_scriptOwned = true;
20062030
#else
20072031
// don't autorelease it
@@ -2029,7 +2053,7 @@ void jsb_ref_init(JSContext* cx, JS::Heap<JSObject*> *obj, Ref* ref, const char*
20292053
(void)cx;
20302054
(void)obj;
20312055
ref->_scriptOwned = true;
2032-
// don't retain it.
2056+
// don't retain it, already retained
20332057
#else
20342058
// autorelease it
20352059
ref->autorelease();
@@ -2043,9 +2067,10 @@ void jsb_ref_autoreleased_init(JSContext* cx, JS::Heap<JSObject*> *obj, Ref* ref
20432067
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
20442068
(void)cx;
20452069
(void)obj;
2046-
ref->_scriptOwned = true;
2047-
// retain it, since the object is autoreleased
2070+
// retain first copy, and before "owning" to prevent it
2071+
// from calling "rootObject"
20482072
ref->retain();
2073+
ref->_scriptOwned = true;
20492074
#else
20502075
// don't autorelease it, since it is already autoreleased
20512076
JS::AddNamedObjectRoot(cx, obj, debug);
@@ -2059,8 +2084,7 @@ void jsb_ref_finalize(JSFreeOp* fop, JSObject* obj)
20592084
js_proxy_t* nproxy;
20602085
js_proxy_t* jsproxy;
20612086

2062-
JS::RootedObject jsobj(fop->runtime(), obj);
2063-
jsproxy = jsb_get_js_proxy(jsobj);
2087+
jsproxy = jsb_get_js_proxy(obj);
20642088
if (jsproxy)
20652089
{
20662090
auto ref = static_cast<cocos2d::Ref*>(jsproxy->ptr);
@@ -2074,6 +2098,7 @@ void jsb_ref_finalize(JSFreeOp* fop, JSObject* obj)
20742098
else
20752099
jsb_remove_proxy(nullptr, jsproxy);
20762100
}
2101+
else CCLOG("jsb_ref_finalize: BUG: proxy not found for %p", obj);
20772102
#else
20782103
// CCLOG("jsb_ref_finalize: JSObject address = %p", obj);
20792104
#endif

cocos/scripting/js-bindings/manual/ScriptingCore.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,4 @@ JSObject* jsb_ref_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_ty
618618
*/
619619
JSObject* jsb_ref_autoreleased_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_type_class_t *typeClass, const char* debug);
620620

621-
622-
void removeJSObject(JSContext* cx, void* nativeObj);
623-
624621
#endif /* __SCRIPTING_CORE_H__ */

cocos/scripting/js-bindings/manual/cocos2d_specifics.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,7 @@ inline js_type_class_t *js_get_type_from_native(T* native_obj) {
8787
*/
8888
template<class T>
8989
inline js_proxy_t *js_get_or_create_proxy(JSContext *cx, T *native_obj) {
90-
js_proxy_t *proxy;
91-
HASH_FIND_PTR(_native_js_global_ht, &native_obj, proxy);
90+
js_proxy_t *proxy = jsb_get_native_proxy(native_obj);
9291
if (!proxy) {
9392
js_type_class_t *typeProxy = js_get_type_from_native<T>(native_obj);
9493
// Return NULL if can't find its type rather than making an assert.

cocos/scripting/js-bindings/manual/extension/jsb_cocos2dx_extension_manual.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,8 +557,7 @@ class JSB_ControlButtonTarget : public Ref
557557

558558
virtual void onEvent(Ref *controlButton, Control::EventType event)
559559
{
560-
js_proxy_t * p;
561-
JS_GET_PROXY(p, controlButton);
560+
js_proxy_t* p = jsb_get_native_proxy(controlButton);
562561
if (!p)
563562
{
564563
log("Failed to get proxy for control button");

cocos/scripting/js-bindings/manual/js_bindings_opengl.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,10 @@ void GLNode::onDraw(Mat4 &transform, uint32_t flags)
3535
JSContext *cx = ScriptingCore::getInstance()->getGlobalContext();
3636

3737
js_type_class_t *typeClass = js_get_type_from_native<cocos2d::GLNode>(this);
38-
auto j = jsb_ref_get_or_create_jsobject(cx, this, typeClass, "cocos2d::GLNode");
38+
JS::RootedObject jsObj(cx, jsb_ref_get_or_create_jsobject(cx, this, typeClass, "cocos2d::GLNode"));
3939

40-
if (j)
40+
if (jsObj.get())
4141
{
42-
JS::RootedObject jsObj(cx, j);
43-
4442
bool found = false;
4543
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
4644

cocos/scripting/js-bindings/manual/js_manual_conversions.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,12 @@ jsval meshVertexAttrib_to_jsval(JSContext* cx, const cocos2d::MeshVertexAttrib&
280280
jsval uniform_to_jsval(JSContext* cx, const cocos2d::Uniform* uniform);
281281
jsval resourcedata_to_jsval(JSContext* cx, const cocos2d::ResourceData& v);
282282

283-
template<class T>
284-
js_proxy_t *js_get_or_create_proxy(JSContext *cx, T *native_obj);
285283

284+
// forward declaration
285+
template <class T>
286+
js_type_class_t *js_get_type_from_native(T* native_obj);
287+
288+
// Ref version of ccvector_to_jsval
286289
template <class T>
287290
jsval ccvector_to_jsval(JSContext* cx, const cocos2d::Vector<T>& v)
288291
{
@@ -294,9 +297,10 @@ jsval ccvector_to_jsval(JSContext* cx, const cocos2d::Vector<T>& v)
294297
JS::RootedValue arrElement(cx);
295298

296299
//First, check whether object is associated with js object.
297-
js_proxy_t* jsproxy = js_get_or_create_proxy(cx, obj);
298-
if (jsproxy) {
299-
arrElement = OBJECT_TO_JSVAL(jsproxy->obj);
300+
js_type_class_t *typeClass = js_get_type_from_native(obj);
301+
JS::RootedObject jsobject(cx, jsb_ref_get_or_create_jsobject(cx, obj, typeClass, typeid(*obj).name()));
302+
if (jsobject.get()) {
303+
arrElement = OBJECT_TO_JSVAL(jsobject);
300304
}
301305

302306
if (!JS_SetElement(cx, jsretArr, i, arrElement)) {
@@ -322,9 +326,11 @@ jsval ccmap_string_key_to_jsval(JSContext* cx, const cocos2d::Map<std::string, T
322326
T obj = iter->second;
323327

324328
//First, check whether object is associated with js object.
325-
js_proxy_t* jsproxy = js_get_or_create_proxy(cx, obj);
326-
if (jsproxy) {
327-
element = OBJECT_TO_JSVAL(jsproxy->obj);
329+
js_type_class_t *typeClass = js_get_type_from_native(obj);
330+
JS::RootedObject jsobject(cx, jsb_ref_get_or_create_jsobject(cx, obj, typeClass, typeid(*obj).name()));
331+
332+
if (jsobject.get()) {
333+
element = OBJECT_TO_JSVAL(jsobject);
328334
}
329335

330336
if (!key.empty())

cocos/scripting/js-bindings/manual/network/jsb_socketio.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,7 @@ bool js_cocos2dx_SocketIO_connect(JSContext* cx, uint32_t argc, jsval* vp)
164164
if (ret)
165165
{
166166
// link the native object with the javascript object
167-
js_proxy_t *p;
168-
HASH_FIND_PTR(_native_js_global_ht, &ret, p);
167+
js_proxy_t *p = jsb_get_native_proxy(ret);
169168
if(!p)
170169
{
171170
//previous connection not found, create a new one

0 commit comments

Comments
 (0)