forked from mapsme/omim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathios_video_timer.mm
109 lines (87 loc) · 2.08 KB
/
ios_video_timer.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "platform/video_timer.hpp"
#include "std/target_os.hpp"
#import <QuartzCore/CADisplayLink.h>
#import <Foundation/NSRunLoop.h>
class IOSVideoTimer;
@interface VideoTimerWrapper : NSObject {
@private
IOSVideoTimer * m_timer;
}
- (id)initWithTimer:(IOSVideoTimer *) timer;
- (void)perform;
@end
class IOSVideoTimer : public VideoTimer
{
VideoTimerWrapper * m_objCppWrapper;
CADisplayLink * m_displayLink;
public:
IOSVideoTimer(VideoTimer::TFrameFn frameFn) : VideoTimer(frameFn), m_objCppWrapper(0), m_displayLink(0)
{}
~IOSVideoTimer()
{
stop();
}
void start()
{
if (m_displayLink == 0)
{
m_objCppWrapper = [[VideoTimerWrapper alloc] initWithTimer:this];
m_displayLink = [CADisplayLink displayLinkWithTarget:m_objCppWrapper selector:@selector(perform)];
m_displayLink.frameInterval = 1;
m_displayLink.paused = true;
[m_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
resume();
}
}
void stop()
{
if (m_displayLink)
{
// Set EStopped flag first. It seems like 'CADisplayLink::invalidate' can invoke pending 'perform'.
// So we should check EStopped flag in 'perform' to skip pending call.
m_state = EStopped;
[m_displayLink invalidate];
[m_objCppWrapper release];
m_displayLink = 0;
}
}
void pause()
{
m_displayLink.paused = true;
m_state = EPaused;
}
void resume()
{
m_displayLink.paused = false;
m_state = ERunning;
}
void perform()
{
// In case when we stopped and have pending perform at the same time.
// It's not allowed to call m_frameFn after stopping (see WindowHandle::~WindowHandle).
if (m_state != EStopped)
m_frameFn();
}
};
@implementation VideoTimerWrapper
- (id)initWithTimer:(IOSVideoTimer*) timer
{
self = [super init];
if (self) {
m_timer = timer;
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (void)perform
{
m_timer->perform();
}
@end
VideoTimer * CreateIOSVideoTimer(VideoTimer::TFrameFn frameFn)
{
return new IOSVideoTimer(frameFn);
}