I'm facing with a lot of crash when try to addChild, removeChild inside hardware interrupts, or JAVA callback.
My game has a soft button to call to java, in order to use voice recognition.
The context:
C++: btnRecord pressed -> JAVA: startVoiceRecognition -> C++: return;
JAVA: hasResult -> C++: resultHandler -> C++: addchild, removechild, etc.-> crashed randomly.
I figured out it is crashed because of I tried to change the game data when cocos is doing the samething, in the same area.
Ex: when cocos is rendering layerA, JAVA also tried to remove layerA -> crashed.
Does cocos have any solution for this context ?
May be a callback queue which will be processed in the next game loop ?
I think the need to change the Drawing scene when you press some hard button: back key, volume key, or any hardware interrupt event is very necessary.
yeah, finally I have solved this sh*t.
JNI callback run in seperated thread. This means when JNI occurs a callback, it cannot blocks cocos main thread.
I was afraid that JNI callback will blocks cocos main thread. I should check this first :(
Ok! To solve this, just use std::mutex and scheduleOnce.
like this:
void MyGame::update(float dt)
{
jniMutex.unlock();
// do something
jniMutex.lock();
}
JNI callback()
{
jniMutex.lock();
// scheduleOnce something
jniMutex.unlock();
}
I want to make sure JNI callback run inside MyGame::update(float), therefore I call unlock() from the begining, and call lock() at the end.
Beside that, we should use scheduleOnce instead of try to modify Node structure directly inside update function.
Related
I'm trying to build an application that can spawn a window on a separate thread. Let me explain a simple version. My main creates an object that has a window, let's call this object a menu. From the menu you can select what to do, for example open up an image to a new window. This whole object, or the object's "game loop" needs to be on a separate thread so that I can still keep interacting with the menu. I also need to interact with the image viewer.
My question is, what is the proper way of doing this?
I haven't really used threads a lot before. But from what I understand I need to detach the thread to create a daemon thread.
I tried to play around with the thread to create this but I kept getting these errors:
Failed to activate the window's context
Failed to activate OpenGL context: The requested resource is in use.
I'm not certain what causes this, all objects, like my windows are different instances. The application will still run fine even with these errors.
My application is quite big so here's an extremely simplified version of the code I've tried.
int main()
{
Menu menu; // this spawns a window
menu.run(); // let's say for simplicity this doesn't do anything else other than
// create a new window (the image viewer)
}
...
void caller(Image_view *img_view)
{
img_view->run();
}
void Menu::run()
{
Image_view *img_view = new Image_view(); // This creates the window
this->thread = new std::thread(caller, img_view);
this->thread->detach();
while (1); // This is here to keep the application running,
// in a real application this method would look different.
// This whole thread call would be in an event handler instead,
// but for this example I tried to make it as simple as possible
}
...
void Image_view::run()
{
while (running)
{
update(); // Event handler and whatever
render(); // Renders the image and whatever
}
this->window->close();
}
I mostly want to know if I'm using the thread correctly or not in an application like this. Also if you have any insight as to what the error message means, explaining it would be greatly appreciated. I should also mention that I'm using SFML for rendering and creating the window instance.
The tutorials I found about the threads are always something extremely simple which doesn't involve any window or anything that could for example cause that error message. So I figured someone smarter here might know the proper use of the thread in my case.
Thanks in advance!
I did project in window using wxwidgets then i am trying to run it linux but i am getting some problem with freeze&thaw function.
Will it work with linux? Is there any other option to freeze the window?
Here is mycode:
void *UpdateModeltreeThread::Entry()
{
m_PtrTree->Freeze();
m_PtrTree->ProcessUpdateModelTree();
m_PtrTree->Thaw();
return NULL;
}
Note: i am running above thing using wxThread
ProcessUpdateModelTree() in this function i am adding treeitems to wxtreelistctrl there are number of treeitems are there so i am using freeze&thaw,running at back end using thread function its working in windows but not in linux
Issue:In middle of Freeze() & Thaw() its calling paint event , because ot that its crashing in treelistctrl paint event,but this thing is not happing in window
You absolutely cannot call GUI methods such as Freeze() and Thaw() from worker threads, as you seem to be doing here. You must call them or, better, use safer wxWindowUpdateLocker from the main thread.
I've an application visual c++ written using vs2010,
I have two buttons: "start" and "stop",the first one calls a function that takes a lot of time to process, so in a certain moment I'd like to stop the computation pressing stop button. But in my application the button start seems still clicked (I think it's waiting for the return of the function) and all the other buttons appear to be disabled. Even if I had a wonderful stop function, I could not active because I'm not able to click on button stop. Solutions,ideas,using threads,easy example? Thanks.
You need to run your calculations in another thread. Otherwise your gui freezes until your calculations are done (because only one thing can be done at the moment).
If you are using some modern compiler look at std::thread.
other solutions are boost threads or even microsoft threads.
If your computation is a loop, it may be quite easy to check at each iteration if your User wants to stop the computation.
In the computation thread:
while(compute){
// one loop of computation
}
While your GUI thread can set computationto false through your stop button.
I hope it helps
Note: In c++ as in java Swing etc.., the GUI has it's own thread (not really visible to the developer) and you should never do heavy tasks in it. For instance, every callbacks for buttons should be as small as possible to keep your GUI responsive. This thread's job is just to drive your application.
Button 1 -> onClick =
{
start thread -> { do stuff here }
}
BUtton 2 -> onClick =
{
close thread
}
Be careful when forcibly closing a thread because you can leak memory !
http://msdn.microsoft.com/it-it/library/system.componentmodel.backgroundworker%28v=vs.110%29.aspx
BackgroundWorker is perfect for this use!
First you need to imports the namespace
using System.Threading;
then use the following code :
Thread T=new Thread(Your Code Goes method name);
your method name()
{
// your code goes here
}
T.Start();
then
T.Abort();
Because I´m writting a "generic" application behaving completely different when facing other configurations, I´m forced to show gtk windows even if I dont yet know them at startup. There might also be the requirement that multiple windows need to be visisble (not modal dialogs but standalone windows) at the same time. But, it would be great if one can simply start one gtk event loop at startup.
Is is somehow possible to add windows to that loop after it has been started?
While I found the Gtk::Application class which seems to support exactly the indented behaviour I´m restricted to use the Gtk::Main class.
There's only a single Gtk::Main object allowed. Widgets should be created in the same thread the main event loop is being run in. To work around this limitation you need to develop a way to pass your window creation commands to the gtk thread.
The simplest way is to use Glib::Dispatcher
struct WindowBuilder {
/**/
Glib::Dispatcher* signal_create;
void create_window() {
//From main thread...
signal_create->emit();
}
}
void create_mainWnd() {
new Ui::MainWnd();
}
//From Gtk thread...
builder->signal_create->connect(sigc::ptr_fun(create_mainWnd));
Gtk::Main::run();
Glib::Dispatcher doesn't take any arguments with it, so next step is to figure out how to pass arguments around between threads.
For different types of windows you can just use different disptachers.
boost::asio::io_service can help you pass messages around.
while(!exit) {
io_service.reset();
io_service.poll();
while(Gtk::Main::events_pending())
Gtk::Main::iteration();
Sleep(0);
}
I know that in order to write a GTK application, I write a bunch of code which describes what is put in the main window, then I call:
gtk_main();
Any code statements after this do not get executed.
Now let's suppose I'd like my GTK app to display something I wrote with glut, which itself contains a bunch of statements about what graphics need to be set etc. then ends with the statement:
glutMainLoop();
Anything after this is not executed.
So my problem is that either of these two statements prevents me from calling the other.
Is there a way to execute a glut main loop inside a GTK widget ?
Is there a way to write a code that could somehow simultaneously call both a GTK main loop and a glut main loop (but called from the main program and rendered in a separate X window, not within a widget)? I've got a feeling this could be done with "threads"...
You don't. There's generally no point to it.
GLUT is a library for creating and managing OpenGL windows. GTK already has an OpenGL window in it. If you're using GTK, then there's no point in using GLUT. It's like having two vector math libraries or something.
You are running the main loops. gtk_main() runs until gtk_quit() is called.
gtk_main() at GTK.org
Runs the main loop until gtk_main_quit() is called. You can nest calls to gtk_main(). In that case gtk_main_quit() will make the innermost invocation of the main loop return.
Also, glutMainLoop() works the same way, it processes GL events forever.
glutMainLoop() at OpenGL.org
glutMainLoop() enters the GLUT event processing loop. This routine should be called at most once in a GLUT program. Once called, this routine will never return. It will call as necessary any callbacks that have been registered.
So, you you wan't both of these things to execute at the same time (I think they might interfere with each other so you might get unexpected results) then you will need to call gtk_main_iteration() from inside glut.
gtk_main_iteration() at GTK.org
Runs a single iteration of the mainloop. If no events are waiting to be processed GTK+ will block until the next event is noticed. If you don't want to block look at gtk_main_iteration_do() or check if any events are pending with gtk_events_pending() first.
Now.. GLUT doesn't have an equivalent to gtk_main_iteration() so you are going to need to register GLUT callbacks.
You could register a callback with GLUT that runs gtk_main_iteration() using glutIdleFunc(void (*func)(void)) which will run a callback for every frame - glutIdleFunc()..
Or you could give a callback to glutTimerFunc(unsigned int msecs,
void (*func)(int value), value) to call and check the return value of gtk_main_iteration() every 200msec or so.
I'd probably experiment with both, glutIdleFunc() might not always get called regularly enough for good responsiveness.
It really is worth looking at driving GTK's GL support though.