È iOS c'è CADisplayLink, in Mac OS X c'è CVDisplayLink, ma non riesco a trovare un modo per usarlo, tutti gli esempi sono relativi a OpenGL.Alternativa di CADisplayLink per Mac OS X
ho creato questa usanza UIView e voglio tradurlo in una NSView
#import "StarView.h"
#import <QuartzCore/QuartzCore.h>
#define MAX_FPS (100.0)
#define MIN_FPS (MAX_FPS/40.0)
#define FRAME_TIME (1.0/MAX_FPS)
#define MAX_CPF (MAX_FPS/MIN_FPS)
#define aEPS (0.0001f)
@implementation StarView
@synthesize starImage = _starImage;
@synthesize x, y;
- (void)baseInit {
_starImage = nil;
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(runLoop)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self baseInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
[self baseInit];
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
[self.starImage drawAtPoint:CGPointMake(self.x, self.y)];
}
-(void) cycle {
self.x += 5;
if (self.x > 230) {
self.x = 0;
}
}
- (void) runLoop {
//NSLog(@"called");
static CFTimeInterval last_time = 0.0f;
static float cycles_left_over = 0.0f;
static float dt2 = 0.0f;
float dropAnimRate = (2.1f/25.0f);
CFTimeInterval current_time = CACurrentMediaTime();
float dt = current_time - last_time + cycles_left_over;
dt2 += dt;
[self setNeedsDisplay];
if (dt > (MAX_CPF * FRAME_TIME)) {
dt = (MAX_CPF * FRAME_TIME);
}
while (dt > FRAME_TIME) {
if (dt2 > (dropAnimRate - aEPS)){
[self cycle];
dt2 = 0.0f;
}
dt -= FRAME_TIME;
}
cycles_left_over = dt;
last_time = current_time;
}
@end
La parte che non riesco a tradurre è questa
- (void)baseInit {
_starImage = nil;
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(runLoop)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
So che posso utilizzare un NSTimer, ma non ha la stessa accuratezza
'return [(__bridge SPVideoView *) displayLinkContext renderTime: inOutputTime]; 'Non ho capito questa riga, suppongo che invece di SPVideoView dovrei usare MyView, ma non capisco cosa dovrei usare invece di renderTime . Potresti spiegarmi lo scopo di queste funzioni (sia renderCallback che renderTime)? – AR89
@ AR89 - Poiché CVDisplayLink accetta una funzione di callback, non un metodo, sta a te richiamare un metodo appropriato nella tua classe. In quanto sopra, la classe che stavo usando è SPVideoView, e ho un metodo che prende il timestamp inOutputTime. Dovresti utilizzare questo timestamp per determinare se vuoi ancora attivare l'aggiornamento del tuo display. Per inciso, vorrei anche sottolineare che dovresti stare attento con gli aggiornamenti del display usando questo, perché questo callback si verifica su un thread in background, quindi dovrai assicurarti che il tuo disegno si verifichi sul thread principale se usi Core Graphics. –
questa è una buona risposta, ma è importante che si finisca con il callback attivato su un thread diverso da dove verrebbe disegnata una vista? penso che potrebbe essere almeno per il rendering OpenGL. – jheriko