@@ -908,7 +908,7 @@ bool js_cocos2dx_ext_release(JSContext *cx, uint32_t argc, jsval *vp)
908
908
}
909
909
910
910
911
- __JSDownloaderDelegator::__JSDownloaderDelegator (JSContext *cx, JS::HandleObject obj, const std::string &url, JS::HandleValue callback)
911
+ __JSDownloaderDelegator::__JSDownloaderDelegator (JSContext *cx, JS::HandleObject obj, const std::string &url, JS::HandleObject callback)
912
912
: _cx(cx)
913
913
, _url(url)
914
914
, _buffer(nullptr )
@@ -917,7 +917,27 @@ __JSDownloaderDelegator::__JSDownloaderDelegator(JSContext *cx, JS::HandleObject
917
917
_obj.ref ().set (obj);
918
918
_jsCallback.construct (_cx);
919
919
_jsCallback.ref ().set (callback);
920
-
920
+ }
921
+
922
+ __JSDownloaderDelegator::~__JSDownloaderDelegator ()
923
+ {
924
+ _obj.destroyIfConstructed ();
925
+ _jsCallback.destroyIfConstructed ();
926
+ if (_buffer != nullptr )
927
+ free (_buffer);
928
+ _downloader->setErrorCallback (nullptr );
929
+ _downloader->setSuccessCallback (nullptr );
930
+ }
931
+
932
+ __JSDownloaderDelegator *__JSDownloaderDelegator::create (JSContext *cx, JS::HandleObject obj, const std::string &url, JS::HandleObject callback)
933
+ {
934
+ __JSDownloaderDelegator *delegate = new (std::nothrow) __JSDownloaderDelegator (cx, obj, url, callback);
935
+ delegate->autorelease ();
936
+ return delegate;
937
+ }
938
+
939
+ void __JSDownloaderDelegator::startDownload ()
940
+ {
921
941
if (Director::getInstance ()->getTextureCache ()->getTextureForKey (_url))
922
942
{
923
943
onSuccess (nullptr , nullptr , nullptr );
@@ -929,8 +949,9 @@ __JSDownloaderDelegator::__JSDownloaderDelegator(JSContext *cx, JS::HandleObject
929
949
_downloader->setErrorCallback ( std::bind (&__JSDownloaderDelegator::onError, this , std::placeholders::_1) );
930
950
_downloader->setSuccessCallback ( std::bind (&__JSDownloaderDelegator::onSuccess, this , std::placeholders::_1, std::placeholders::_2, std::placeholders::_3) );
931
951
932
- long contentSize = _downloader->getContentSize (_url);
933
- if (contentSize == -1 ) {
952
+ cocos2d::extension::Downloader::HeaderInfo info = _downloader->getHeader (_url);
953
+ long contentSize = info.contentSize ;
954
+ if (contentSize == -1 || info.responseCode >= 400 ) {
934
955
cocos2d::extension::Downloader::Error err;
935
956
onError (err);
936
957
}
@@ -942,94 +963,101 @@ __JSDownloaderDelegator::__JSDownloaderDelegator(JSContext *cx, JS::HandleObject
942
963
}
943
964
}
944
965
945
- __JSDownloaderDelegator::~__JSDownloaderDelegator ()
966
+ void __JSDownloaderDelegator::download ()
946
967
{
947
- if (_buffer != nullptr )
948
- free (_buffer);
949
- _downloader->setErrorCallback (nullptr );
950
- _downloader->setSuccessCallback (nullptr );
968
+ retain ();
969
+ startDownload ();
970
+ }
971
+
972
+ void __JSDownloaderDelegator::downloadAsync ()
973
+ {
974
+ retain ();
975
+ auto t = std::thread (&__JSDownloaderDelegator::startDownload, this );
976
+ t.detach ();
951
977
}
952
978
953
979
void __JSDownloaderDelegator::onError (const cocos2d::extension::Downloader::Error &error)
954
980
{
955
- if (!_jsCallback.ref ().isNull ()) {
956
- JSContext *cx = ScriptingCore::getInstance ()->getGlobalContext ();
957
- JS::RootedObject global (cx, ScriptingCore::getInstance ()->getGlobalObject ());
958
-
959
- JSAutoCompartment ac (_cx, _obj.ref ());
960
-
961
- jsval succeed = BOOLEAN_TO_JSVAL (false );
962
- JS::RootedValue retval (cx);
963
- JS_CallFunctionValue (cx, global, _jsCallback.ref (), JS::HandleValueArray::fromMarkedLocation (1 , &succeed), &retval);
964
- }
965
- this ->release ();
981
+ Director::getInstance ()->getScheduler ()->performFunctionInCocosThread ([this ]
982
+ {
983
+ JS::RootedValue callback (_cx, OBJECT_TO_JSVAL (_jsCallback.ref ()));
984
+ if (!callback.isNull ()) {
985
+ JS::RootedObject global (_cx, ScriptingCore::getInstance ()->getGlobalObject ());
986
+ JSAutoCompartment ac (_cx, global);
987
+
988
+ jsval succeed = BOOLEAN_TO_JSVAL (false );
989
+ JS::RootedValue retval (_cx);
990
+ JS_CallFunctionValue (_cx, global, callback, JS::HandleValueArray::fromMarkedLocation (1 , &succeed), &retval);
991
+ }
992
+ release ();
993
+ });
966
994
}
967
995
968
996
void __JSDownloaderDelegator::onSuccess (const std::string &srcUrl, const std::string &storagePath, const std::string &customId)
969
997
{
970
998
Image *image = new Image ();
971
- jsval valArr[2 ];
972
- JSContext *cx = ScriptingCore::getInstance ()->getGlobalContext ();
973
- JS::RootedObject global (cx, ScriptingCore::getInstance ()->getGlobalObject ());
974
999
cocos2d::TextureCache *cache = Director::getInstance ()->getTextureCache ();
975
1000
976
- JSAutoCompartment ac (_cx, _obj.ref () ? _obj.ref () : global);
977
-
978
1001
Texture2D *tex = cache->getTextureForKey (_url);
979
- if (tex)
1002
+ if (! tex)
980
1003
{
981
- valArr[0 ] = BOOLEAN_TO_JSVAL (true );
982
- js_proxy_t * p = jsb_get_native_proxy (tex);
983
- valArr[1 ] = OBJECT_TO_JSVAL (p->obj );
1004
+ if (image->initWithImageData (_buffer, _size))
1005
+ {
1006
+ tex = Director::getInstance ()->getTextureCache ()->addImage (image, _url);
1007
+ }
984
1008
}
985
- else if (image->initWithImageData (_buffer, _size))
1009
+ image->release ();
1010
+
1011
+ Director::getInstance ()->getScheduler ()->performFunctionInCocosThread ([this , tex]
986
1012
{
987
- tex = Director ::getInstance ()->getTextureCache ()-> addImage (image, _url );
988
- valArr[ 0 ] = BOOLEAN_TO_JSVAL ( true );
1013
+ JS::RootedObject global (_cx, ScriptingCore ::getInstance ()->getGlobalObject () );
1014
+ JSAutoCompartment ac (_cx, global );
989
1015
990
- JS::RootedObject texProto (cx, jsb_cocos2d_Texture2D_prototype);
991
- JSObject *obj = JS_NewObject (cx, jsb_cocos2d_Texture2D_class, texProto, global);
992
- // link the native object with the javascript object
993
- js_proxy_t * p = jsb_new_proxy (tex, obj);
994
- JS::AddNamedObjectRoot (cx, &p->obj , " cocos2d::Texture2D" );
995
- valArr[1 ] = OBJECT_TO_JSVAL (p->obj );
996
- }
997
- else
998
- {
999
- valArr[0 ] = BOOLEAN_TO_JSVAL (false );
1000
- valArr[1 ] = JSVAL_NULL;
1001
- }
1002
-
1003
- image->release ();
1016
+ jsval valArr[2 ];
1017
+ if (tex)
1018
+ {
1019
+ valArr[0 ] = BOOLEAN_TO_JSVAL (true );
1020
+ js_proxy_t * p = jsb_get_native_proxy (tex);
1021
+ if (!p)
1022
+ {
1023
+ JS::RootedObject texProto (_cx, jsb_cocos2d_Texture2D_prototype);
1024
+ JSObject *obj = JS_NewObject (_cx, jsb_cocos2d_Texture2D_class, texProto, global);
1025
+ // link the native object with the javascript object
1026
+ p = jsb_new_proxy (tex, obj);
1027
+ JS::AddNamedObjectRoot (_cx, &p->obj , " cocos2d::Texture2D" );
1028
+ }
1029
+ valArr[1 ] = OBJECT_TO_JSVAL (p->obj );
1030
+ }
1031
+ else
1032
+ {
1033
+ valArr[0 ] = BOOLEAN_TO_JSVAL (false );
1034
+ valArr[1 ] = JSVAL_NULL;
1035
+ }
1004
1036
1005
- if (!_jsCallback.ref ().isNull ()) {
1006
- JS::RootedValue retval (cx);
1007
- JS_CallFunctionValue (cx, global, _jsCallback.ref (), JS::HandleValueArray::fromMarkedLocation (2 , valArr), &retval);
1008
- }
1009
- this ->release ();
1010
- }
1011
-
1012
- void __JSDownloaderDelegator::download (JSContext *cx, JS::HandleObject obj, const std::string &url, JS::HandleValue callback)
1013
- {
1014
- auto t = std::thread ([cx, obj, url, callback]() {
1015
- new __JSDownloaderDelegator (cx, obj, url, callback);
1037
+ JS::RootedValue callback (_cx, OBJECT_TO_JSVAL (_jsCallback.ref ()));
1038
+ if (!callback.isNull ())
1039
+ {
1040
+ JS::RootedValue retval (_cx);
1041
+ JS_CallFunctionValue (_cx, global, callback, JS::HandleValueArray::fromMarkedLocation (2 , valArr), &retval);
1042
+ }
1043
+ release ();
1016
1044
});
1017
- t.detach ();
1018
1045
}
1019
1046
1020
1047
// jsb.loadRemoteImg(url, function(succeed, result) {})
1021
1048
bool js_load_remote_image (JSContext *cx, uint32_t argc, jsval *vp)
1022
1049
{
1023
1050
JS::CallArgs args = JS::CallArgsFromVp (argc, vp);
1024
1051
JS::RootedObject obj (cx, JS_THIS_OBJECT (cx, vp));
1025
- if (argc == 2 ) {
1052
+ if (argc == 2 )
1053
+ {
1026
1054
std::string url;
1027
1055
bool ok = jsval_to_std_string (cx, args.get (0 ), &url);
1028
- JS::RootedValue callback (cx, args.get (1 ));
1029
-
1030
- __JSDownloaderDelegator::download (cx, obj, url, callback);
1056
+ JSB_PRECONDITION2 (ok, cx, false , " js_load_remote_image : Error processing arguments" );
1057
+ JS::RootedObject callback (cx, args.get (1 ).toObjectOrNull ());
1031
1058
1032
- JSB_PRECONDITION2 (ok, cx, false , " js_console_log : Error processing arguments" );
1059
+ __JSDownloaderDelegator *delegate = __JSDownloaderDelegator::create (cx, obj, url, callback);
1060
+ delegate->downloadAsync ();
1033
1061
1034
1062
args.rval ().setUndefined ();
1035
1063
return true ;
0 commit comments