Qualcuno sa o ha dei buoni link che spiegano cosa fa il ciclo degli eventi di iPhone sotto il cofano?Ciclo evento personalizzato e controlli UIKit. Che extra magica fa il ciclo degli eventi di Apple?
Stiamo utilizzando un ciclo di eventi personalizzato nel nostro framework di giochi per iPhone basato su OpenGL. Chiama il nostro sistema di rendering del gioco, chiama presentRenderbuffer e pompa gli eventi utilizzando CFRunLoopRunInMode. Vedi il codice qui sotto per i dettagli.
Funziona bene quando non utilizziamo i controlli UIKit (come prova, prova Facetap, il nostro primo gioco rilasciato).
Tuttavia, quando si utilizzano i controlli UIKit, tutto quasi funziona, ma non del tutto. Nello specifico, lo scorrimento dei controlli di UIKit non funziona correttamente.
Ad esempio, consideriamo lo scenario seguente.
- Mostriamo UIImagePickerController in cima alla nostra vista.
- UIImagePickerController copre la nostra vista personalizzata
- Mettiamo anche in pausa il nostro rendering, ma continuiamo ad usare il ciclo di eventi personalizzato.
Come detto, tutto funziona, tranne lo scorrimento.
- Il prelievo delle foto funziona.
- Drill in giù per lavori di album di foto e animazioni di transizione sono liscio.
- Quando si tenta di scorrere la visualizzazione dell'album fotografico, la vista segue il dito.
Problema: quando si scorre, lo scorrimento si interrompe immediatamente dopo aver sollevato il dito. Normalmente, continua senza intoppi in base alla velocità del movimento, ma non quando si utilizza il ciclo di eventi personalizzato. Sembra che il ciclo degli eventi di iPhone stia facendo qualche magia legata allo scrolling UIKit che non abbiamo implementato noi stessi.
Ora, possiamo far sì che i controlli UIKit funzionino perfettamente e dandy insieme al nostro sistema utilizzando il ciclo degli eventi di Apple e chiamando il nostro rendering tramite i callback NSTimer. Tuttavia, mi piacerebbe ancora capire, che cosa potrebbe accadere all'interno del ciclo degli eventi di iPhone che non è implementato nel nostro ciclo di eventi personalizzati.
- (void)customEventLoop { OBJC_METHOD;
float excess = 0.0f;
while(isRunning) {
animationInterval = 1.0f/openGLapp->ticks_per_second();
// Calculate the target time to be used in this run of loop
float wait = max(0.0, animationInterval - excess);
Systemtime target = Systemtime::now().after_seconds(wait);
Scope("event loop");
NSAutoreleasePool* pool = [[ NSAutoreleasePool alloc] init];
// Call our own render system and present render buffer
[self drawView];
// Pump system events
[self handleSystemEvents:target];
[pool release];
excess = target.seconds_to_now();
}
}
- (void)drawView { OBJC_METHOD;
// call our own custom rendering
bool bind = openGLapp->app_render();
// bind the buffer to be THE renderbuffer and present its contents
if (bind) {
opengl::bind_renderbuffer(renderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
}
- (void) handleSystemEvents:(Systemtime)target { OBJC_METHOD;
SInt32 reason = 0;
double time_left = target.seconds_since_now();
if (time_left <= 0.0) {
while((reason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE)) == kCFRunLoopRunHandledSource) {}
} else {
float dt = time_left;
while((reason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, dt, FALSE)) == kCFRunLoopRunHandledSource) {
double time_left = target.seconds_since_now();
if (time_left <= 0.0) break;
dt = (float) time_left;
}
}
}
Ho usato i timer per un gioco OpenGL e, nonostante quello che si potrebbe pensare, ho ottenuto i framerate più alti usando questo metodo. Sembra giocare molto meglio con il ciclo degli eventi principale. –
drawnonward, grazie, le modalità ciclo continuo spiegano tutto. Abbiamo anche utilizzato l'approccio basato su NSTimer e ha avuto alcune anomalie con animazioni veloci. In iPhone OS 3.1 c'è CADisplayLink che può aiutare con il problema. –
disegnato, per qualche motivo, non posso contrassegnare la tua risposta come accettata. Questa domanda ha avuto un premio in precedenza, ma hai risposto dopo che la caccia alla taglia si era chiusa e sembra che StackOverflow mi impedisca di contrassegnare la risposta accettata dopo. Strano. –