Multithread, Window, Event, Runloop, ... => Headache
Multithread, Window, Event, Runloop, ... => Headache
- Subject: Multithread, Window, Event, Runloop, ... => Headache
- From: Marco Antognini <email@hidden>
- Date: Thu, 17 Feb 2011 15:48:44 +0100
Hello,
This is my first time on any mailing list so please advise me if I'm doing something wrong.
For some reason (I'm porting a low level C++ window management library on mac) I cannot use NSApplicationMain nor NSApplication -run method. So I create a function to dispatch NSEvent working like this :
loop begin (non infinite)
[NSApp nextEventMatchingMask:blabla..]
[NSApp sendEvent:..]
loop end
And I call it periodically. Until now it worked pretty well (the window is displayed, key/mouse event are dispatched, ...) – I was only using main thread.
But now I'm stuck with a problem : is there any way to create/destroy window/view, make them live (e.g. rendering process) and get event notification; all that only in a worker thread (like we can do on Linux or Windows) ?
From what I've read in the doc the NSWindow can be created/destroyed in any thread but this is not true for NSView. So I though of using NSObject -performSelectorOnMainThread:..-like methods. But, again, the documentation is against me :
> This method queues the message on the run loop of the main thread using the default run loop modes—that is, the modes associated with the NSRunLoopCommonModes constant. As part of its normal run loop processing, the main thread dequeues the message (assuming it is running in one of the default run loop modes) and invokes the desired method.
And I tested : if I call some dummy function like this in a worker thread nothing happen (as expected) :
-(void)dummy:(NSString *)msg
{
NSLog(@"Hello %@", msg);
}
-(id)initWithStuff:...
{
if ((self = [super init])) {
[self performSelectorOnMainThread:@selector(dummy:)
withObject:@"World"
waitUntilDone:YES];
:
:
}
It get stuck forever in performSelectorOnMainThread:.. because the selector is never executed. Of course, I could set waitUntilDone to NO but later I will require to wait for my view to be initialized.
So have any of you an idea of how to make it work ? Or is it really impossible ? One idea that crossed my mind was to call some method in the main thread periodically but that would require to change the public API of the library... which is not an option for me. The only thing I can do is play in some GetEvent and Display functions called by the user in the worker thread. You can see below what should the lib-user be able to do.
#include <SFML/Window.hpp>
sf::Window App;
void threadProc() {
App.Create(sf::VideoMode(800, 600, 32), "SFML Threads");
// Create the main window // Start main loop
while (App.IsOpened()) {
// Process events
sf::Event Event;
while (App.GetEvent(Event)) {
// Close window : exit
if (Event.Type == sf::Event::Closed)
App.Close();
// Escape key : exit
if (Event.Type == sf::Event::KeyPressed && Event.Key.Code == sf::Key::Escape)
App.Close();
}
// Display window on screen
App.Display();
}
}
int main(int, char**)
{
sf::Thread Thread(threadProc);
Thread.Launch();
Thread.Wait();
return 0;
}
This C++ code display a window with white titlebar and a spinning wheel.
The only thing that is working is rendering stuff from a worker thread works! (Also as expected by the documentation.)
And if it can be done to work so I'll have some other trouble with event dispatching... arg!
If you need any other information please tell me.
Thank you very much for your time =)
Marco
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden