I couldn’t resist playing with the new C+±based task manager from the CVS trunk. Although, I couldn’t entirely get it to work. This somewhat resembles my code:
// The global task manager
PT(AsyncTaskManager) taskMgr = AsyncTaskManager::get_global_ptr();
struct World {
PT(AsyncTask) main_loop;
World() : main_loop(NULL) {
//Create the movement task, but first make sure it is not already running
if(main_loop != NULL) taskMgr->remove(main_loop);
main_loop = new rollTask();
taskMgr->add(main_loop);
}
struct rollTask : AsyncTask {
DoneStatus do_frame() {
cout << "frame" << endl;
return DS_cont;
}
};
};
main() {
World w;
Thread *current_thread = Thread::get_current_thread();
while (framework.do_frame(current_thread)) {
cerr << taskMgr->get_num_tasks() << endl;
taskMgr->poll();
}
}
Although, “frame” never gets printed out. Am I missing some essential step?
Also, since AsyncTask inherits from TypedObject, do I really need to declare all that typehandle and virtual functions etc stuff in my class definition? That would kind of make my tasks, very big. Or, is there a different, better way to add tasks in C++?
No, you can omit this if you like. It means that you won’t be able to use run-time typing on your task objects, but if you don’t care about that, there’s no reason to insist you use it.
You may also choose to use GenericAsyncTask, which allows you to specify a plain function pointer, C-style, instead of using inheritance. To use this, you can’t pass in a pointer to an ordinary member function, because of C++'s wacky definition of member functions; it has to be either a static member function, or a global non-member function.
I still haven’t looked at this, where is it located on CVS ?
1 more question :
in Python, it’s possible to attach some data to task object as attributes. How is it implemented in C++ task ? Just like python tag as in nodepath ?
It’s located in panda/src/event/. You can find an example of how it works in direct/src/task/TaskNew.py.
IMHO, if you want to have your own data attached to a task, you should create your own class that inherits from AsyncTask, and override the do_task() function for the actual task code. You can then add data members to the class for additional data. (I’m not an expert on it though.)
Right, subclassing is the way to attach data in C++ code.
Unfortunately, subclassing is not an option in Python, because of the whole C++ pointer storage (this is similar to the Actor/NodePath conundrum). This is the first I’ve heard of anyone wanting to subclass Task objects, though. Instead of subclassing, you’ll have to store a pointer onto your Task object.
You mean as an argument to the do_task function? If that’s what you mean, no. If you add parameters to your do_task function, you’re actually overloading the function, not overriding, and thus the function will not get called.
Umm, are we talking about C++ or Python? It’s true you can’t add new arguments to the parameter list in C++, but in Python you can add anything you like to the extraArgs list.
Of course, in Python you can also assign a back pointer on the Task object itself. Either way is similar to the functionality you get via subclassing.
Yes, unless you’re doing something exotic like accessing private members, or subclassing the Task object, the Python interface should be the same between the original task manager and the new task manager. Why don’t you download it and try it out?