Fix ComponentJS proxy management issue in JSB

This commit is contained in:
pandamicro 2015-12-15 11:48:44 +08:00
parent ca45f9f69d
commit 64276bd664
4 changed files with 67 additions and 19 deletions

View File

@ -5770,6 +5770,41 @@ void js_register_cocos2dx_AutoPolygon(JSContext *cx, JS::HandleObject global) {
jsb_register_class<cocos2d::AutoPolygon>(cx, jsb_cocos2d_AutoPolygon_class, proto, JS::NullPtr()); jsb_register_class<cocos2d::AutoPolygon>(cx, jsb_cocos2d_AutoPolygon_class, proto, JS::NullPtr());
} }
// ComponentJS controls the native js proxy itself, must be bound manually
bool js_cocos2dx_ComponentJS_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_ComponentJS_create : Error processing arguments");
auto ret = cocos2d::ComponentJS::create(arg0);
JS::RootedObject jsret(cx, static_cast<JSObject*>(ret->getScriptObject()));
args.rval().set(OBJECT_TO_JSVAL(jsret));
return true;
}
JS_ReportError(cx, "js_cocos2dx_ComponentJS_create : wrong number of arguments");
return false;
}
static bool js_cocos2dx_ComponentJS_ctor(JSContext *cx, uint32_t argc, jsval *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::RootedObject obj(cx, args.thisv().toObjectOrNull());
bool ok = true;
std::string arg0;
ok &= jsval_to_std_string(cx, args.get(0), &arg0);
JSB_PRECONDITION2(ok, cx, false, "js_cocos2d_ComponentJS_ctor : Error processing arguments");
cocos2d::ComponentJS *nobj = new (std::nothrow) cocos2d::ComponentJS(arg0);
// autorelease it
nobj->autorelease();
bool isFound = false;
if (JS_HasProperty(cx, obj, "_ctor", &isFound) && isFound)
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), "_ctor", args);
args.rval().setUndefined();
return true;
}
bool js_cocos2dx_ComponentJS_getScriptObject(JSContext *cx, uint32_t argc, jsval *vp) bool js_cocos2dx_ComponentJS_getScriptObject(JSContext *cx, uint32_t argc, jsval *vp)
{ {
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
@ -6034,8 +6069,12 @@ void register_cocos2dx_js_core(JSContext* cx, JS::HandleObject global)
tmpObj.set(jsb_cocos2d_ClippingNode_prototype); tmpObj.set(jsb_cocos2d_ClippingNode_prototype);
JS_DefineFunction(cx, tmpObj, "init", js_cocos2dx_ClippingNode_init, 0, JSPROP_ENUMERATE | JSPROP_PERMANENT); JS_DefineFunction(cx, tmpObj, "init", js_cocos2dx_ClippingNode_init, 0, JSPROP_ENUMERATE | JSPROP_PERMANENT);
JS_GetProperty(cx, ccObj, "ComponentJS", &tmpVal);
tmpObj = tmpVal.toObjectOrNull();
JS_DefineFunction(cx, tmpObj, "create", js_cocos2dx_ComponentJS_create, 1, JSPROP_READONLY | JSPROP_PERMANENT);
tmpObj.set(jsb_cocos2d_ComponentJS_prototype); tmpObj.set(jsb_cocos2d_ComponentJS_prototype);
JS_DefineFunction(cx, tmpObj, "getScriptObject", js_cocos2dx_ComponentJS_getScriptObject, 0, JSPROP_ENUMERATE | JSPROP_PERMANENT); JS_DefineFunction(cx, tmpObj, "getScriptObject", js_cocos2dx_ComponentJS_getScriptObject, 0, JSPROP_ENUMERATE | JSPROP_PERMANENT);
JS_DefineFunction(cx, tmpObj, "ctor", js_cocos2dx_ComponentJS_ctor, 1, JSPROP_ENUMERATE | JSPROP_PERMANENT);
JS_DefineFunction(cx, ccObj, "glEnableVertexAttribs", js_cocos2dx_ccGLEnableVertexAttribs, 1, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(cx, ccObj, "glEnableVertexAttribs", js_cocos2dx_ccGLEnableVertexAttribs, 1, JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(cx, ccObj, "pAdd", js_cocos2dx_ccpAdd, 1, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(cx, ccObj, "pAdd", js_cocos2dx_ccpAdd, 1, JSPROP_READONLY | JSPROP_PERMANENT);

View File

@ -66,25 +66,15 @@ ComponentJS::ComponentJS(const std::string& scriptFileName)
JS::RootedValue protoValue(cx); JS::RootedValue protoValue(cx);
JS_GetProperty(cx, classObj, "prototype", &protoValue); JS_GetProperty(cx, classObj, "prototype", &protoValue);
TypeTest<ComponentJS> t;
js_type_class_t *typeClass = nullptr;
std::string typeName = t.s_name();
auto typeMapIter = _js_global_type_map.find(typeName);
CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!");
typeClass = typeMapIter->second;
mozilla::Maybe<JS::PersistentRootedObject> *jsObj = new mozilla::Maybe<JS::PersistentRootedObject>(); mozilla::Maybe<JS::PersistentRootedObject> *jsObj = new mozilla::Maybe<JS::PersistentRootedObject>();
js_type_class_t *typeClass = js_get_type_from_native<cocos2d::ComponentJS>(this);
JS::RootedObject proto(cx, protoValue.toObjectOrNull()); JS::RootedObject proto(cx, protoValue.toObjectOrNull());
JS::RootedObject parent(cx, typeClass->proto.ref()); JS::RootedObject parent(cx, typeClass->proto.ref());
jsObj->construct(cx); jsObj->construct(cx);
JS::RootedObject obj(cx, JS_NewObject(cx, theClass, proto, parent)); JS::RootedObject obj(cx, JS_NewObject(cx, theClass, proto, parent));
jsObj->ref() = obj; jsObj->ref() = obj;
// Unbind current proxy binding
js_proxy_t* jsproxy = js_get_or_create_proxy<ComponentJS>(cx, this);
JS::RemoveObjectRoot(cx, &jsproxy->obj);
jsb_remove_proxy(jsb_get_native_proxy(this), jsproxy);
// link the native object with the javascript object // link the native object with the javascript object
jsb_new_proxy(this, jsObj->ref()); jsb_new_proxy(this, jsObj->ref());
@ -95,6 +85,17 @@ ComponentJS::ComponentJS(const std::string& scriptFileName)
ComponentJS::~ComponentJS() ComponentJS::~ComponentJS()
{ {
mozilla::Maybe<JS::PersistentRootedObject>* jsObj = static_cast<mozilla::Maybe<JS::PersistentRootedObject>*>(_jsObj); mozilla::Maybe<JS::PersistentRootedObject>* jsObj = static_cast<mozilla::Maybe<JS::PersistentRootedObject>*>(_jsObj);
if (jsObj && !jsObj->empty())
{
// Remove proxy
js_proxy_t* jsproxy = jsb_get_js_proxy(jsObj->ref());
if (jsproxy)
{
js_proxy_t* nproxy = jsb_get_native_proxy(jsproxy->ptr);
jsb_remove_proxy(nproxy, jsproxy);
}
}
// Delete rooted object
if (jsObj != nullptr) if (jsObj != nullptr)
{ {
delete jsObj; delete jsObj;
@ -104,7 +105,14 @@ ComponentJS::~ComponentJS()
void* ComponentJS::getScriptObject() const void* ComponentJS::getScriptObject() const
{ {
mozilla::Maybe<JS::PersistentRootedObject>* jsObj = static_cast<mozilla::Maybe<JS::PersistentRootedObject>*>(_jsObj); mozilla::Maybe<JS::PersistentRootedObject>* jsObj = static_cast<mozilla::Maybe<JS::PersistentRootedObject>*>(_jsObj);
return jsObj->ref().get(); if (jsObj && !jsObj->empty())
{
return jsObj->ref().get();
}
else
{
return nullptr;
}
} }
void ComponentJS::update(float delta) void ComponentJS::update(float delta)

View File

@ -2771,29 +2771,30 @@ cc.GLProgram.prototype.setUniformLocationWithMatrix2fv = function(){
var tempArray = Array.prototype.slice.call(arguments); var tempArray = Array.prototype.slice.call(arguments);
tempArray = Array.prototype.concat.call(tempArray, 2); tempArray = Array.prototype.concat.call(tempArray, 2);
this.setUniformLocationWithMatrixfvUnion.apply(this, tempArray); this.setUniformLocationWithMatrixfvUnion.apply(this, tempArray);
} };
cc.GLProgram.prototype.setUniformLocationWithMatrix3fv = function(){ cc.GLProgram.prototype.setUniformLocationWithMatrix3fv = function(){
var tempArray = Array.prototype.slice.call(arguments); var tempArray = Array.prototype.slice.call(arguments);
tempArray = Array.prototype.concat.call(tempArray, 3); tempArray = Array.prototype.concat.call(tempArray, 3);
this.setUniformLocationWithMatrixfvUnion.apply(this, tempArray); this.setUniformLocationWithMatrixfvUnion.apply(this, tempArray);
} };
cc.GLProgram.prototype.setUniformLocationWithMatrix4fv = function(){ cc.GLProgram.prototype.setUniformLocationWithMatrix4fv = function(){
var tempArray = Array.prototype.slice.call(arguments); var tempArray = Array.prototype.slice.call(arguments);
tempArray = Array.prototype.concat.call(tempArray, 4); tempArray = Array.prototype.concat.call(tempArray, 4);
this.setUniformLocationWithMatrixfvUnion.apply(this, tempArray); this.setUniformLocationWithMatrixfvUnion.apply(this, tempArray);
} };
// //
// Script Component // Script Component
// //
cc._ComponentJS = cc.ComponentJS; cc._ComponentJS = cc.ComponentJS;
cc._ComponentJS.extend = cc.Class.extend;
cc.ComponentJS = function (filename) { cc.ComponentJS = function (filename) {
var comp = cc._ComponentJS.create(filename); var comp = cc._ComponentJS.create(filename);
var res = comp.getScriptObject(); var res = comp.getScriptObject();
return res; return res;
} };
cc.ComponentJS.extend = function (prop) { cc.ComponentJS.extend = function (prop) {
return cc._ComponentJS.extend(prop); return cc._ComponentJS.extend(prop);
}; };

View File

@ -31,7 +31,7 @@ replace_headers = CCComponentJS.h::component/CCComponentJS.h
classes = New.* Sprite SpriteBatchNode SpriteFrame SpriteFrameCache Scene Node.* Director Layer.* Menu.* Touch .*Action.* Move.* Rotate.* Blink.* Tint.* Sequence Repeat.* Fade.* Ease.* Scale.* Transition.* Spawn ReverseTime Animate AnimationFrame Animation AnimationCache Flip.* Delay.* Skew.* Jump.* Place.* Show.* Progress.* PointArray ToggleVisibility.* RemoveSelf Hide Particle.* Label.* Atlas.* TextureCache.* Texture2D Cardinal.* CatmullRom.* ParallaxNode TileMap.* TMX.* CallFunc CallFuncN RenderTexture GridAction Grid3DAction Grid3D TiledGrid3D GridBase$ .+Grid Shaky3D Waves3D FlipX3D FlipY3D Lens3D Ripple3D PageTurn3D ShakyTiles3D ShatteredTiles3D WavesTiles3D JumpTiles3D Speed ActionManager Set SimpleAudioEngine Scheduler Orbit.* Follow.* Bezier.* CardinalSpline.* Camera.* DrawNode Liquid$ Waves$ ShuffleTiles$ TurnOffTiles$ Split.* Twirl$ FileUtils$ GLProgram GLProgramCache Application ClippingNode MotionStreak TextFieldTTF GLViewProtocol GLView Component ComponentContainer __NodeRGBA __LayerRGBA SAXParser Event(?!.*(Physics).*).* Device Configuration ProtectedNode GLProgramState Image .*Light$ AsyncTaskPool Properties Material Technique RenderState Pass ComponentJS classes = New.* Sprite SpriteBatchNode SpriteFrame SpriteFrameCache Scene Node.* Director Layer.* Menu.* Touch .*Action.* Move.* Rotate.* Blink.* Tint.* Sequence Repeat.* Fade.* Ease.* Scale.* Transition.* Spawn ReverseTime Animate AnimationFrame Animation AnimationCache Flip.* Delay.* Skew.* Jump.* Place.* Show.* Progress.* PointArray ToggleVisibility.* RemoveSelf Hide Particle.* Label.* Atlas.* TextureCache.* Texture2D Cardinal.* CatmullRom.* ParallaxNode TileMap.* TMX.* CallFunc CallFuncN RenderTexture GridAction Grid3DAction Grid3D TiledGrid3D GridBase$ .+Grid Shaky3D Waves3D FlipX3D FlipY3D Lens3D Ripple3D PageTurn3D ShakyTiles3D ShatteredTiles3D WavesTiles3D JumpTiles3D Speed ActionManager Set SimpleAudioEngine Scheduler Orbit.* Follow.* Bezier.* CardinalSpline.* Camera.* DrawNode Liquid$ Waves$ ShuffleTiles$ TurnOffTiles$ Split.* Twirl$ FileUtils$ GLProgram GLProgramCache Application ClippingNode MotionStreak TextFieldTTF GLViewProtocol GLView Component ComponentContainer __NodeRGBA __LayerRGBA SAXParser Event(?!.*(Physics).*).* Device Configuration ProtectedNode GLProgramState Image .*Light$ AsyncTaskPool Properties Material Technique RenderState Pass ComponentJS
classes_need_extend = Node __NodeRGBA Layer.* Sprite SpriteBatchNode SpriteFrame Menu MenuItem.* Scene DrawNode Component .*Action.* GridBase Grid3D TiledGrid3D MotionStreak ParticleBatchNode ParticleSystem TextFieldTTF RenderTexture TileMapAtlas TMXLayer TMXTiledMap TMXMapInfo TransitionScene ProgressTimer ParallaxNode Label.* GLProgram Move.* Rotate.* Blink.* Tint.* Sequence Repeat.* Fade.* Ease.* Scale.* Transition.* Spawn ReverseTime Animate AnimationFrame Animation AnimationCache Flip.* Delay.* Skew.* Jump.* Place.* Show.* Progress.* Orbit.* Follow.* Bezier.* Hide CallFunc CallFuncN ComponentJS classes_need_extend = Node __NodeRGBA Layer.* Sprite SpriteBatchNode SpriteFrame Menu MenuItem.* Scene DrawNode Component .*Action.* GridBase Grid3D TiledGrid3D MotionStreak ParticleBatchNode ParticleSystem TextFieldTTF RenderTexture TileMapAtlas TMXLayer TMXTiledMap TMXMapInfo TransitionScene ProgressTimer ParallaxNode Label.* GLProgram Move.* Rotate.* Blink.* Tint.* Sequence Repeat.* Fade.* Ease.* Scale.* Transition.* Spawn ReverseTime Animate AnimationFrame Animation AnimationCache Flip.* Delay.* Skew.* Jump.* Place.* Show.* Progress.* Orbit.* Follow.* Bezier.* Hide CallFunc CallFuncN
# what should we skip? in the format ClassName::[function function] # what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also # ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
@ -140,7 +140,7 @@ skip = Node::[^setPosition$ setGLServerState description getUserObject .*UserDat
Camera::[unproject isVisibleInFrustum], Camera::[unproject isVisibleInFrustum],
ClippingNode::[init], ClippingNode::[init],
RenderState::[setStateBlock], RenderState::[setStateBlock],
ComponentJS::[getScriptObject update] ComponentJS::[create getScriptObject update]
rename_functions = SpriteFrameCache::[addSpriteFramesWithFile=addSpriteFrames getSpriteFrameByName=getSpriteFrame], rename_functions = SpriteFrameCache::[addSpriteFramesWithFile=addSpriteFrames getSpriteFrameByName=getSpriteFrame],
MenuItemFont::[setFontNameObj=setFontName setFontSizeObj=setFontSize getFontSizeObj=getFontSize getFontNameObj=getFontName], MenuItemFont::[setFontNameObj=setFontName setFontSizeObj=setFontSize getFontSizeObj=getFontSize getFontNameObj=getFontName],
@ -186,7 +186,7 @@ base_classes_to_skip = Ref Clonable
# classes that create no constructor # classes that create no constructor
# Set is special and we will use a hand-written constructor # Set is special and we will use a hand-written constructor
abstract_classes = Action FiniteTimeAction ActionInterval ActionEase EaseRateAction EaseElastic EaseBounce ActionInstant GridAction Grid3DAction TiledGrid3DAction Director SpriteFrameCache TransitionEaseScene Set SimpleAudioEngine FileUtils Application GLViewProtocol GLView ComponentContainer SAXParser Configuration EventListener BaseLight AsyncTaskPool abstract_classes = Action FiniteTimeAction ActionInterval ActionEase EaseRateAction EaseElastic EaseBounce ActionInstant GridAction Grid3DAction TiledGrid3DAction Director SpriteFrameCache TransitionEaseScene Set SimpleAudioEngine FileUtils Application GLViewProtocol GLView ComponentContainer SAXParser Configuration EventListener BaseLight AsyncTaskPool ComponentJS
# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'. # Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = no script_control_cpp = no