2009-06-12 13 views
6

En un juego OS X llamando a esto, se recomendó como la forma de obtener eventos de teclado y mouse.Alguien sabe por qué nextEventMatchingMask: untilDate: inMode: dequeue: ¿tarda muchos ms para devolver un evento?

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
for(;;) 
{ 
    NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES]; 
    if(!event) break; 
    processevent(event); 
    ... 
} 
[pool release]; 

que se llama en el bucle principal de los juegos (su plataforma cruzada).

Desde las versiones más recientes de OSX 10.5.X, esta llamada toma repentinamente muchos milisegundos por evento cuando hay un evento disponible, y la velocidad de cuadro del juego se ve afectada cada vez que aparece un evento. Si hay varios eventos, puede tardar hasta 10 ms por fotograma en un Mac más lento.

¿Alguien tiene una pista de por qué es esto? ¿O qué puedo hacer alternativamente para obtener eventos sin afectar tanto el juego?

Intenté administrar los eventos del mouse yo mismo obteniendo la posición del mouse manualmente y cuando se acerca al borde de la pantalla, lo deforma hacia el centro, pero eso causa un enganche en el movimiento (solo cuando el cursor está oculto curso).

Otras alternativas pueden ser obtener cosas del administrador de HID, que ya hacemos para joysticks, pero HID no es muy claro.

Cuanto más rápido sea el mac, más se notarán estos enganches de los eventos.

Respuesta

1

Offhand, no sé por qué el método tarda tanto en volver. Vale la pena investigarlo en el cocoa-dev list u otro recurso del foro de Apple. Supongo que gestionar los eventos tú mismo es una mala idea: AppKit está optimizado para eso, y puedes apostar con seguridad que será mucho más rápido que el código personalizado.

Sin embargo, hay algo que puedes hacer para evitar que afecte tu juego: ponlo en un hilo separado. Este es un enfoque sugerido para evitar que su UI se congele durante una llamada larga al método. Apple ha publicado un Introduction to Threading programming guide que puede ayudarlo a ponerse al día con los conceptos críticos que necesitaría.

2

Creo que necesita liberar y volver a asignar el grupo de autorrelease dentro de su ciclo: como tiene el ciclo, todos los elementos liberados automáticamente se están acumulando y nunca se vacían.

1

Creo que tiene que usar un valor real en el argumento untilDate, como [NSDate distantFuture] o [NSDate distantPast]. La función se bloqueará hasta que un evento esté disponible en el primer caso, mientras que volverá inmediatamente con un evento nil en este último caso.

Lo aprendí del código fuente GLFW.

Cuestiones relacionadas