"Cocos2d-x Lua" Asynchronous Task Tool class

Source: Internet
Author: User
Tags data structures lua
Ideas


Implementation Ideas
1. Using the Pthread library, encapsulates a class for performing asynchronous tasks that provide a method to accept a LUA function and then execute that function in a child thread. 2. Use the tolua++ tool to bind a C + + custom class to Lua.
Code Ideas (pseudo code)
Defines a C + + class Asyntaskhandler to handle asynchronous tasks that need to be performed in Lua, which has a queue (FIFO) for holding tasks.

Task task = NULL;

Starts a loop in a child thread to process the task in the queue while
(true) {

    //defines whether a bool variable token exits the loop and, at the beginning of the loop, determines whether to exit the loop
    if (need_quit) {	
	break ;
    }

    task = NULL;
    Get tasks from Queue task
    = Task_queue.pop ()
    
    //If the queue is empty if
    (null = = Task) {
        //when the thread is sleeping, wait for the main thread to add tasks and wake the current threads
	thread_sleep ();
	Continues the current loop continue when the thread is awakened
        ;
    }
    
    Perform task Dotask (Task) If the task is successfully acquired
    ;
    Task.release ();    
}

If you exit the cycle
//Cleanup task queue and the resource if
(task_queue) {
    task_queue.clear ();
    Task_queue = NULL;
}
Exit thread
thread_exit ();
Initialize
void Asyntaskhandler::lazyinit ()
{
    //If the task queue is not initialized if
	(taskqueue = = NULL)
	{
		// Create Task queue
        Taskqueue = Queue.create ();
        
		Create thread
		thread_create ();
		Execution thread
		thead_execute ();
		
        Initialize exit marked flase
		Need_quit = false;}	
}


Add Task
void asyntaskhandler::addtask (int task)
{
    //Initialize
	lazyinit ();

	Add to Task Queue	
    Task_queue.add (Task);
	Wakeup worker thread
	thread_wakeup ();
}

Implement
#include "AsynTaskHandler.h" #include "CCLuaEngine.h" #include//#include//single static Asyntaskhandler *s_pasyntask = 
NULL;
Task Queue static ccarray* s_taskqueue = NULL;

Static Std::vector S_taskqueue;

Thread lock static pthread_mutex_t S_taskqueuemutex;
Conditional variable static pthread_mutex_t S_sleepmutex;


Static pthread_cond_t s_sleepcondition;
Thread ID static pthread_t s_workthread;

Task loop flag static BOOL Need_quit = FALSE;
	Worker thread static void* workthread (void *data) {ccinteger* task = NULL;
		while (true) {//If an exit signal is received, exit the loop if (Need_quit) {break;
		} task = NULL; 
		Gets the task Pthread_mutex_lock (&s_taskqueuemutex) in the team header from the task queue;
			if (0! = S_taskqueue->count ()) {task = dynamic_cast (s_taskqueue->objectatindex (0));  			
		S_taskqueue->removeobjectatindex (0);

		} pthread_mutex_unlock (&s_taskqueuemutex); If the queue does not have a task if (NULL = = Task) {//The thread sleeps, waits for the main thread to add the task and wakes the current threads pthread_cond_wait (&s_sleepcondition, &S_SL
			Eepmutex); Continue
		}//If the Get task succeeds, perform task ccluastack* pstack = ccluaengine::d efaultengine ()->getluastack ();
		The first parameter is the integer handle of the function, and the second parameter is the number of function arguments Pstack->executefunctionbyhandler (task->getvalue (), 0);
		Pstack->clean ();
	Task->release ();
	}//If an exit signal is received, Cleanup task queue and release Resources pthread_mutex_lock (&s_taskqueuemutex);
	S_taskqueue->removeallobjects ();

	Pthread_mutex_unlock (&s_taskqueuemutex);
		if (s_taskqueue! = NULL) {Pthread_mutex_destroy (&s_taskqueuemutex);
		Pthread_mutex_destroy (&s_sleepmutex);

		Pthread_cond_destroy (&s_sleepcondition);
		S_taskqueue->release ();
	S_taskqueue = NULL;
	} pthread_exit (NULL);
return 0;
		} void Asyntaskhandler::lazyinit () {if (S_taskqueue = = NULL) {//Create task Queue S_taskqueue = new Ccarray ();

		S_taskqueue->init ();

		Initialization of the thread lock Pthread_mutex_init (&s_taskqueuemutex, NULL);
		Initialize the condition variable pthread_mutex_init (&s_sleepmutex, NULL);

		Pthread_cond_init (&s_sleepcondition, NULL); Create Thread pthread_create (&s_workthread, NULL, workthread, NULL);	

		Execution thread Pthread_detach (s_workthread);
	Need_quit = false;

	}} Asyntaskhandler::asyntaskhandler () {} asyntaskhandler::~asyntaskhandler () {//stop loop Need_quit = true;
	Destroy task queue if (s_taskqueue! = NULL) {//wake thread, clean resource pthread_cond_signal (&s_sleepcondition);
} s_pasyntask = NULL; }/** Return the shared instance **/Asyntaskhandler *asyntaskhandler::getinstance () {if (S_pasyntask = = NULL) {S_pas
	Yntask = new Asyntaskhandler ();
} return s_pasyntask;


}/** relase the shared instance **/void Asyntaskhandler::d Estroy () {s_pasyntask->release ();}

	Add task void Asyntaskhandler::addtask (int task) {lazyinit ();
	Add to Task Queue Pthread_mutex_lock (&s_taskqueuemutex);
	S_taskqueue->addobject (Ccinteger::create (Task));

	Pthread_mutex_unlock (&s_taskqueuemutex);
Wake-up worker thread pthread_cond_signal (&s_sleepcondition);


} #ifndef __asyntaskhandler_h__ #define __ASYNTASKHANDLER_H__ #include "cocos2d.h" USING_NS_CC; Tools for executing asynchronous tasks in LuaClass Asyntaskhandler:public Ccobject {Public:asyntaskhandler ();

	Virtual ~asyntaskhandler ();	

	void AddTask (int task);

	Lazy loading void lazyinit ();

	/** Return the shared instance **/static Asyntaskhandler *getinstance ();
/** relase the shared instance **/static void Destroy ();


};
 #endif//__asyntaskhandler_h__


binding to Lua


Click to see "Using the tolua++ tool to use C + + custom classes in Lua"

The pkg file that you need to use to bind to Lua is the following code:

Class Asyntaskhandler:public Ccobject
{
	asyntaskhandler ();
	~asyntaskhandler ();
	void AddTask (lua_function task);	
	Static Asyntaskhandler *getinstance ();
	static void Destroy ();
};


The code hint files used in the Cocos Code IDE project are placed in the source directory:

--------Asynchronous Task Tool class
---------------------------------
-@module Asyntaskhandler

----------------------- ----------
-@function [parent= #AsynTaskHandler] AddTask 
--@param self--@param #int
Task

------ --------------------------
--@function [parent= #AsynTaskHandler] destory 
--@param self

----------- ----------------------
-@function [parent= #AsynTaskHandler] getinstance- 
-@param self
--@return Asyntaskhandler#asyntaskhandler ret (return value:asyntaskhandler)

return nil

Test


The test code is as follows (LUA code):

    --Test asynchronous execution Task
    asyntaskhandler:getinstance (): AddTask (function ()
        cclog ("Asyn task is running..")
        For I=1, the
            "Child thread num=%s", the i)   
        end
    end) for
    I=1, the
        "main thread Cclog", i) C9/>end


The log output is as follows:
It can be seen in the log that "main thread Num=1" was first output, meaning that the main thread was not blocked.
Note: Cocos2d-x related APIs (such as Cctexturecache) cannot be called in a child thread due to Cocos2d-x's memory management mechanism.
The official note is as follows: Http://www.cocos2d-x.org/wiki/How_to_use_pthread 1.Don ' t call any functions which invokes Ref::retain (), Ref:: Release () or Ref::autorelease (), because Autoreleasepool is not thread-safe. Refer to Reference Count and Autoreleasepool in cocos2d-x for more details. Cocos2d-x use Autoreleasepool every the where in it framework, so my suggestion are that, don ' t invoke any cocos2d-x API in a New thread except Data structures.
Autoreleasepool is not thread-safe.

2.If want to load resources in a new thread, can use Texturecache::addimageasync ()
If you want to load resources asynchronously, you can use Texturecache::addimageasync ().

3.pthread_cond_wait () seems has a bug, it can not wait for the first time, but works properly in subsequence.
Pthread_cond_wait () has a bug. It is not normal at the time of the first call, but the subsequent use will work properly.

about inter-thread communication
You can use Ccnotificationcenter for inter-thread Communication in cocos2d-x2.x (note: Ccnotificationcenter is not thread-safe). In cocos2d-x3.x, you can use Eventcustomelistener for inter-thread communication.
Project git address: Https://coding.net/linchaolong/LuaAsynTaskHandler.git related article: use of "cocos2d-x" Pthread Library

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.