original works, reproduced please indicate : http://blog.csdn.net/jackystudio/article/details/15334159
Cocos2d-x and Android,windows are the same, if the main thread to deal with some time-consuming operation, then the main thread will appear blocking phenomenon, performance in the interface is stuck, not responding and so on. To avoid this, we need to open up working threads in the background to process the data, and then use messaging or other forms to notify the main thread of UI changes. The most common situation is the loading before the game enters.
1. Asynchronous loading of images
In the first introduction of multithreading and synchronization to the use of the Pthread library, it is said that because Ccautoreleasepool is not thread-safe, it is not possible to introduce COCOS2D-X-related APIs in worker threads (not all APIs are not available). But Cocos2d-x obviously took this issue into account, so it helped us encapsulate an API, avoiding the embarrassment of manually introducing the Pthread library.
[CPP]View Plaincopy
- void Cctexturecache::addimageasync (const char *path, ccobject *target, Sel_callfunco selector)
Where path is the location of the picture, selector is the callback function when loading is complete. Handy, if you need to load a lot of pictures, do callback processing for each, then update the UI in update.
asynchronous loading of 2.plist
However, due to memory reasons, most of the pieces will be synthesized and packaged and brought into the plist. How to do the asynchronous loading of the picture at this time? At this time, we need to further explore the source code of Addimageasync.
2.1. What is the time-consuming?
The first thing to understand is what the time-consuming action is, and the asynchronous load only makes sense if the time-consuming work is really caught and thrown onto the worker thread. We know that the image in memory is in the form of texture, and the loading of the picture, in layman's terms, is the generation of textures, which is the reason for time-consuming. What did the Cctexurecache AddImage (synchronous loading) and ADDIMAGEAYSNC (asynchronous loading) do separately?
(1) AddImage
It can be seen that AddImage uses synchronization to generate textures, which is a time-consuming load operation in the main thread.
[CPP]View Plaincopy
- ... cocos2d-x maintains a global texture that determines whether a texture already exists
- if (! Texture)
- {
- Do
- {
- //... Determine image format
- Pimage = new Ccimage ();
- cc_break_if (NULL = = pimage);
- bool BRet = Pimage->initwithimagefile (Fullpath.c_str (), Eimageformat);
- Cc_break_if (!bret);
- Texture = new cctexture2d (); //Open texture space
- if (Texture &&
- Texture->initwithimage (pimage)) //Initialize texture with ccimage
- {
- #if Cc_enable_cache_texture_data
- //cache The texture file name
- Volatiletexture::addimagetexture (texture, fullpath.c_str (), Eimageformat);
- #endif
- M_ptextures->setobject (texture, pathkey.c_str ());
- Texture->release ();
- }
- Else
- {
- Cclog ("cocos2d:couldn ' t create texture for file:%s in Cctexturecache", path);
- }
- } while (0);
- }
- //... Releasing resources, returning textures
(2) Addimageasync
The Addimageasync is to load the picture in the worker thread and then transform the texture through the scheduler.
[CPP]View Plaincopy
- Create a worker thread to load a picture in the background
- Pthread_create (&s_loadingthread, NULL, loadimage, NULL);
- Create a schedule queue that is used to transform textures based on loaded pictures
- Ccdirector::shareddirector ()->getscheduler ()->scheduleselector (Schedule_selector (CCTextureCache:: Addimageasynccallback), this , 0, false);
- void Cctexturecache::addimageasynccallback (float DT)
- {
- //...
- Cctexture2d *texture = new Cctexture2d (); //Open texture space
- #if 0//todo: (cc_target_platform = = Cc_platform_ios)
- Texture->initwithimage (Pimage, Kccresolutioniphone);
- #else
- Texture->initwithimage (Pimage); //Use Ccimage to initialize textures
- #endif
- #if Cc_enable_cache_texture_data
- Volatiletexture::addimagetexture (texture, filename, pimageinfo->imagetype);
- #endif
- //... will join Autorelease, make the call of the loaded callback function, release the related resources
- }
the principle of 2.2.plist loading
The previous use of plist is this:
[CPP]View Plaincopy
- void Ccspriteframecache::addspriteframeswithfile (const char *pszplist)//incoming plist files can be
In its implementation, it was discovered that:
[CPP]View Plaincopy
- Cctexture2d *ptexture = Cctexturecache::sharedtexturecache ()->addimage (Texturepath.c_str ());
It turns out that addspriteframeswithfile will look for textures first, otherwise it will look for a picture with the same name in the. plist directory, and then call the synchronized AddImage function to generate the texture. This is why only the plist is loaded, and the texture exists.
2.3. Asynchronous load Plist
Know this, then let Addspriteframeswithfile call asynchronous Addimageasync function can, of course, do not need to change the source, because Ccspriteframecache also provides the following plist loading mode:
[CPP]View Plaincopy
- void Ccspriteframecache::addspriteframeswithfile (const char *pszplist, cctexture2d *pobtexture)
So we can manually generate the texture asynchronously, and in the callback function and. plist into the addspriteframeswithfile, done! Do you remember the first selector? The resulting texture is passed into this callback function as a parameter, perfect!
2.4. Note
One thing to note is that when using a small image in any plist, the engine does not generate a texture for each small image, but instead uses the texture of the large image, specifying the coordinates and the length and width of the small picture.
3. Example
Where Ui_text.png is the big picture, Raffle_b_friend.png and raffle_b_diamond.png are two small pictures.
[CPP]View Plaincopy
- BOOL Ctestlayer::init ()
- {
- bool bret=false;
- Do
- {
- CC_BREAK_IF (! Cclayer::init ());
- create a texture in//addimage or Addimageasync
- Cctexturecache::sharedtexturecache ()->addimageasync ("Ui_text.png",this,callfunco_selector ( Ctestlayer::showsprite));
- Bret=true;
- } while (0);
- return bRet;
- }
- void Ctestlayer::showsprite (ccobject* obj)
- {
- cctexture2d* texture_ui_text= (cctexture2d*) obj; //The incoming obj is an asynchronously generated texture
- Ccspriteframecache::sharedspriteframecache ()->addspriteframeswithfile ("Ui_text.plist", texture_ui_text); Adding Ccspriteframecache through textures and. plist Files
- ccsprite* raffle_b_friend=ccsprite::createwithspriteframename ("raffle_b_friend.png"); Use the small picture.
- Raffle_b_friend->setposition (CCP (100,100));
- This->addchild (raffle_b_friend);
- //error, can only get texture of ui_text.png
- //cctexture2d* Raffle_b_diamond_texture=cctexturecache::sharedtexturecache ()->textureforkey ("Raffle_b_ Diamond.png ");
- //Correct, you can use this to get the sprite frame first, then get the ui_text texture from the sprite frame, and the size, to build the Ccsprite
- ccspriteframe* Raffle_b_diamond_spriteframe=ccspriteframecache::sharedspriteframecache ()->spriteFrameByName ( "Raffle_b_diamond.png");
- cctexture2d* texture=raffle_b_diamond_spriteframe->gettexture ();
- Ccrect Rect=raffle_b_diamond_spriteframe->getrect ();
- ccsprite* raffle_b_diamond=ccsprite::createwithtexture (Texture,rect); //If the texture needs to be rotated, setrotation it
- Raffle_b_diamond->setrotation (false);
- Raffle_b_diamond->setposition (CCP (300,100));
- This->addchild (Raffle_b_diamond);
- }
4. Effectsuse asynchronous load plist to handle:
5. Source code Download
http://download.csdn.net/detail/jackyvincefu/6533293
"Go" "Topsy cocos2d-x 23" multithreading and synchronization 03-picture asynchronous loading