English 中文(简体)
Custom event loop and UIKit controls. What extra magic Apple s event loop does?
原标题:

Does anyone know or have good links that explain what iPhone s event loop does under the hood?

We are using a custom event loop in our OpenGL-based iPhone game framework. It calls our game rendering system, calls presentRenderbuffer and pumps events using CFRunLoopRunInMode. See the code below for details.

It works well when we are not using UIKit controls (as a proof, try Facetap, our first released game).

However, when using UIKit controls, everything almost works, but not quite. Specifically, scrolling of UIKit controls doesn t work properly.

For example, let s consider following scenario.

  • We show UIImagePickerController on top of our own view.
  • UIImagePickerController covers our custom view
  • We also pause our own rendering, but keep on using the custom event loop.

As said, everything works, except scrolling.

  • Picking photos works.
  • Drilling down to photo albums works and transition animations are smooth.
  • When trying to scroll photo album view, the view follows your finger.

Problem: when scrolling, scrolling stops immediately after you lift your finger. Normally, it continues smoothly based on the speed of your movement, but not when we are using the custom event loop. It seems that iPhone s event loop is doing some magic related to UIKit scrolling that we haven t implemented ourselves.

Now, we can get UIKit controls to work just fine and dandy together with our own system by using Apple s event loop and calling our own rendering via NSTimer callbacks. However, I d still like to understand, what is possibly happening inside iPhone s event loop that is not implemented in our custom event loop.

- (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;
    }
  }
}
最佳回答

If you NSLog [[NSRunLoop currentRunLoop] currentMode] from [UIScrollView setContentOffset:] when [UIScrollView isDecelerating] is true you will see UITrackingRunLoopMode.

In general, the system will use modes besides kCFRunLoopDefaultMode on the main UI thread run loop, only some of which are documented. The only way to get full system behavior is to cooperate with the system run loop on the main thread.

You could try using an NSTimer and letting the system call you instead of calling CFRunLoopRunInMode yourself. An NSTimer is free to run over time, and when no other UI is shown the system run loop would not be doing anything besides calling the timer.

The alternative would be to return from your customEventLoop function while system controls are being displayed, and call it again when resuming your custom UI.

问题回答

暂无回答




相关问题
images sliding continuously with <table> and jQuery

I m trying to write a little test page that circulates images through a window (see image). I have colored boxes inside a table (gray border), with each box being a element. <table id="boxes" ...

WPF 3d rotation animations

I have a few 3d rectangles on my screen that I want to pivot around the Y axis. I want to press down with the mouse, and rotate the 3d object to a max rotation, but when the user moves their mouse, ...

Disable Windows 7 touch animation in WPF

In Windows 7 when you touch the screen there is a short animation that occurs at the touch point. In my WPF app I want to display my own touch points, without showing the one supplied by Windows. ...

jQuery block moving

I wanna move a div block to the top, so I coded like this: CSS part: .movingPart{ margin-top:80px; } jQuery part: $(document).ready(function() { $( #btn ).click(function() { $( .movingPart )....

Direct 2D gnuplot PNG animation?

Can anyone please confirm that yes/no Gnuplot 4.5 (on CVS) can output 2D animated PNG files? I have numerous datasets but one line that I d like to show iteratively in 3 different places in my graph. ...

Visual State Manager VS Animations in WPF

There is a lot of talk about the simplicity of Visual States and the transitions between them in WPF/Silverlight. I have the need to generate animations dynamically at runtime, to animate the ...

Create a ImageIcon that is the mirror of another one

I ll like to know if there is a way to create a ImageIcon that is the mirror of another ImageIcon. Searching on Google, I found how to do it by using many AWT libraries. Is there a way to do it with ...

how to drag in the animation in iphone application?

Iphone application is using the static co-ordinates to reach at some points in the application,which is based on the button event. But what i want is when i drag the item than it should reach at some ...

热门标签