@@ -1822,93 +1822,53 @@ - (void)flagsChanged:(NSEvent *)event
1822
1822
1823
1823
typedef struct {
1824
1824
PyObject_HEAD
1825
- CFRunLoopTimerRef timer;
1825
+ NSTimer * timer;
1826
+
1826
1827
} Timer;
1827
1828
1828
1829
static PyObject*
1829
1830
Timer_new (PyTypeObject* type, PyObject *args, PyObject *kwds)
1830
1831
{
1831
1832
lazy_init ();
1832
1833
Timer* self = (Timer*)type->tp_alloc (type, 0 );
1833
- if (!self) { return NULL ; }
1834
+ if (!self) {
1835
+ return NULL ;
1836
+ }
1834
1837
self->timer = NULL ;
1835
1838
return (PyObject*) self;
1836
1839
}
1837
1840
1838
1841
static PyObject*
1839
1842
Timer_repr (Timer* self)
1840
1843
{
1841
- return PyUnicode_FromFormat (" Timer object %p wrapping CFRunLoopTimerRef %p " ,
1844
+ return PyUnicode_FromFormat (" Timer object %p wrapping NSTimer %p " ,
1842
1845
(void *) self, (void *)(self->timer ));
1843
1846
}
1844
1847
1845
- static void timer_callback (CFRunLoopTimerRef timer, void * info)
1846
- {
1847
- gil_call_method (info, " _on_timer" );
1848
- }
1849
-
1850
- static void context_cleanup (const void * info)
1851
- {
1852
- Py_DECREF ((PyObject*)info);
1853
- }
1854
-
1855
1848
static PyObject*
1856
1849
Timer__timer_start (Timer* self, PyObject* args)
1857
1850
{
1858
- CFRunLoopRef runloop;
1859
- CFRunLoopTimerRef timer;
1860
- CFRunLoopTimerContext context;
1861
- CFAbsoluteTime firstFire;
1862
- CFTimeInterval interval;
1851
+ NSTimeInterval interval;
1863
1852
PyObject* py_interval = NULL , * py_single = NULL , * py_on_timer = NULL ;
1864
1853
int single;
1865
- runloop = CFRunLoopGetMain ();
1866
- if (!runloop) {
1867
- PyErr_SetString (PyExc_RuntimeError, " Failed to obtain run loop" );
1868
- return NULL ;
1869
- }
1870
1854
if (!(py_interval = PyObject_GetAttrString ((PyObject*)self, " _interval" ))
1871
1855
|| ((interval = PyFloat_AsDouble (py_interval) / 1000 .), PyErr_Occurred ())
1872
1856
|| !(py_single = PyObject_GetAttrString ((PyObject*)self, " _single" ))
1873
1857
|| ((single = PyObject_IsTrue (py_single)) == -1 )
1874
1858
|| !(py_on_timer = PyObject_GetAttrString ((PyObject*)self, " _on_timer" ))) {
1875
1859
goto exit;
1876
1860
}
1877
- // (current time + interval) is time of first fire.
1878
- firstFire = CFAbsoluteTimeGetCurrent () + interval;
1879
- if (single) {
1880
- interval = 0 ;
1881
- }
1882
1861
if (!PyMethod_Check (py_on_timer)) {
1883
1862
PyErr_SetString (PyExc_RuntimeError, " _on_timer should be a Python method" );
1884
1863
goto exit;
1885
1864
}
1886
- Py_INCREF (self);
1887
- context.version = 0 ;
1888
- context.retain = NULL ;
1889
- context.release = context_cleanup;
1890
- context.copyDescription = NULL ;
1891
- context.inf
10000
o = self;
1892
- timer = CFRunLoopTimerCreate (kCFAllocatorDefault ,
1893
- firstFire,
1894
- interval,
1895
- 0 ,
1896
- 0 ,
1897
- timer_callback,
1898
- &context);
1899
- if (!timer) {
1900
- PyErr_SetString (PyExc_RuntimeError, " Failed to create timer" );
1901
- goto exit;
1902
- }
1903
- if (self->timer ) {
1904
- CFRunLoopTimerInvalidate (self->timer );
1905
- CFRelease (self->timer );
1906
- }
1907
- CFRunLoopAddTimer (runloop, timer, kCFRunLoopCommonModes );
1908
- /* Don't release the timer here, since the run loop may be destroyed and
1909
- * the timer lost before we have a chance to decrease the reference count
1910
- * of the attribute */
1911
- self->timer = timer;
1865
+
1866
+ // hold a reference to the timer so we can invalidate/stop it later
1867
+ self->timer = [NSTimer scheduledTimerWithTimeInterval: interval
1868
+ repeats: !single
1869
+ block: ^(NSTimer *timer) {
1870
+ gil_call_method ((PyObject*)self, " _on_timer" );
1871
+ }];
1912
1872
exit:
1913
1873
Py_XDECREF (py_interval);
1914
1874
Py_XDECREF (py_single);
@@ -1924,8 +1884,7 @@ static void context_cleanup(const void* info)
1924
1884
Timer__timer_stop (Timer* self)
1925
1885
{
1926
1886
if (self->timer ) {
1927
- CFRunLoopTimerInvalidate (self->timer );
1928
- CFRelease (self->timer );
1887
+ [self ->timer invalidate ];
1929
1888
self->timer = NULL ;
1930
1889
}
1931
1890
Py_RETURN_NONE;
@@ -1946,7 +1905,7 @@ static void context_cleanup(const void* info)
1946
1905
.tp_repr = (reprfunc)Timer_repr,
1947
1906
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
1948
1907
.tp_new = (newfunc)Timer_new,
1949
- .tp_doc = " A Timer object wraps a CFRunLoopTimerRef and can add it to the event loop." ,
1908
+ .tp_doc = " A Timer object that contains an NSTimer that gets added to the event loop when started ." ,
1950
1909
.tp_methods = (PyMethodDef[]){ // All docstrings are inherited.
1951
1910
{" _timer_start" ,
1952
1911
(PyCFunction)Timer__timer_start,
0 commit comments