UNPKG

nodobjc-x

Version:

The Node.js ⇆ Objective-C bridge

108 lines (90 loc) 2.94 kB
// Test inspired by ./nstimer.js, but using node-friendly deconstructed event loop var $ = require('../') , assert = require('assert') , util = require('util') , events = require('events') $.import('Foundation') $.import('Cocoa') function EventLoop(start) { events.EventEmitter.call(this) assert.equal($.NSDefaultRunLoopMode, 'kCFRunLoopDefaultMode') if (start) this.start(); return this } util.inherits(EventLoop, events.EventEmitter) EventLoop.prototype.start = function() { this.emit('start') return this.schedule(true) } EventLoop.prototype.stop = function() { this._is_running = false this.emit('stop') return this } EventLoop.prototype._schedule = setTimeout EventLoop.prototype.schedule = function(runRecurring) { if (runRecurring !== undefined) this._is_running = runRecurring var memento = this._schedule(this.eventLoop.bind(this)) this.emit('scheduled', memento, this._is_running) return this } EventLoop.prototype.eventLoop = function(runRecurring) { this.eventLoopCore() if (this._is_running || runRecurring) this.schedule(runRecurring) return this } EventLoop.prototype.eventLoopCore = function(block) { var untilDate = block ? $.NSDate('distantFuture') : null; // or $.NSDate('distantPast') to not block var event, app = $.NSApplication('sharedApplication') var runLoopPool = $.NSAutoreleasePool('alloc')('init') var count = 0; try { this.emit('eventLoop-enter') do { this.emit('event-next', count) event = app('nextEventMatchingMask', $.NSAnyEventMask.toString(), // …grumble… uint64 as string …grumble… 'untilDate', untilDate, 'inMode', $.NSDefaultRunLoopMode, 'dequeue', 1) this.emit('event-match', event, app, count) if (event) { app('sendEvent', event) this.emit('event-sent', event, app, count) } ++count; } while (event) this.emit('eventLoop-exit', count) } catch (err) { this.emit('error', err) throw err } finally { runLoopPool('drain') } return this; } var pool = $.NSAutoreleasePool('alloc')('init') var Obj = $.NSObject.extend('Obj') , invokeCount = 0 , eventLoopCount = 0 var evtLoop = new EventLoop() evtLoop.on('eventLoop-exit', function(count) { eventLoopCount += count }) Obj.addMethod('sel:', 'v@:@', function (self, _cmd, timer) { assert.equal('Info', timer('userInfo').toString()) if (++invokeCount == 5) { timer('invalidate'); evtLoop.stop() } }).register() var timer = $.NSTimer('scheduledTimerWithTimeInterval', 0.1 ,'target', Obj('alloc')('init') ,'selector', 'sel:' ,'userInfo', $('Info') ,'repeats', 1) process.on('exit', function () { assert.equal(invokeCount, 5) assert(eventLoopCount > invokeCount, eventLoopCount+' evts > '+invokeCount+' timers') }) evtLoop.start()