Commit 93351681 authored by Aral Balkan's avatar Aral Balkan

Created the Delay library based on the earlier functional version. Renamed...

Created the Delay library based on the earlier functional version. Renamed handle.swift to Handle.swift.
parent ac8f420a
......@@ -37,6 +37,7 @@
A74234171A86477C00493C05 /* MainWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A74234161A86477C00493C05 /* MainWindowController.swift */; };
A74641261A6BD82E0083A0EC /* NodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A74641251A6BD82E0083A0EC /* NodeTests.swift */; };
A7499B171AB4B47000B85BFB /* balloon_512x512@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A7499B161AB4B47000B85BFB /* balloon_512x512@2x.png */; };
A74BB4581AE2477A001CA7BB /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = A74BB4571AE2477A001CA7BB /* Delay.swift */; };
A74C9EE91A65B55C0083B288 /* PreferencesKeyboardShortcutsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A74C9EE81A65B55C0083B288 /* PreferencesKeyboardShortcutsViewController.swift */; };
A74C9EEC1A66889D0083B288 /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = A74C9EEB1A66889D0083B288 /* Node.swift */; };
A74C9EEF1A6688D30083B288 /* Websocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = A74C9EEE1A6688D30083B288 /* Websocket.swift */; };
......@@ -46,7 +47,7 @@
A75AABCA1A5ECFB000B105BA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A75AABC91A5ECFB000B105BA /* AppDelegate.swift */; };
A75AABDD1A5ECFB000B105BA /* HeartbeatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A75AABDC1A5ECFB000B105BA /* HeartbeatTests.swift */; };
A760C9901A75A51100E84890 /* IndieNameFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A760C98F1A75A51100E84890 /* IndieNameFormatter.swift */; };
A77CF7111AE1AAE600D96EF7 /* handle.swift in Sources */ = {isa = PBXBuildFile; fileRef = A77CF7101AE1AAE600D96EF7 /* handle.swift */; };
A77CF7111AE1AAE600D96EF7 /* Handle.swift in Sources */ = {isa = PBXBuildFile; fileRef = A77CF7101AE1AAE600D96EF7 /* Handle.swift */; };
A77D76DF1A99207600F74F00 /* PreloaderWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A77D76DE1A99207600F74F00 /* PreloaderWindow.swift */; };
A77D76E11A99208200F74F00 /* MainWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A77D76E01A99208200F74F00 /* MainWindow.swift */; };
A77D76E41A99213900F74F00 /* PreloaderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A77D76E31A99213900F74F00 /* PreloaderViewController.swift */; };
......@@ -174,6 +175,7 @@
A74234161A86477C00493C05 /* MainWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainWindowController.swift; sourceTree = "<group>"; };
A74641251A6BD82E0083A0EC /* NodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NodeTests.swift; sourceTree = "<group>"; };
A7499B161AB4B47000B85BFB /* balloon_512x512@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "balloon_512x512@2x.png"; sourceTree = "<group>"; };
A74BB4571AE2477A001CA7BB /* Delay.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Delay.swift; sourceTree = "<group>"; };
A74C9EE51A65AB070083B288 /* Credits.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Credits.md; sourceTree = "<group>"; };
A74C9EE81A65B55C0083B288 /* PreferencesKeyboardShortcutsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferencesKeyboardShortcutsViewController.swift; sourceTree = "<group>"; };
A74C9EEB1A66889D0083B288 /* Node.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Node.swift; sourceTree = "<group>"; };
......@@ -189,7 +191,7 @@
A75AABDB1A5ECFB000B105BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A75AABDC1A5ECFB000B105BA /* HeartbeatTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeartbeatTests.swift; sourceTree = "<group>"; };
A760C98F1A75A51100E84890 /* IndieNameFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IndieNameFormatter.swift; sourceTree = "<group>"; };
A77CF7101AE1AAE600D96EF7 /* handle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = handle.swift; sourceTree = "<group>"; };
A77CF7101AE1AAE600D96EF7 /* Handle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Handle.swift; sourceTree = "<group>"; };
A77D76DE1A99207600F74F00 /* PreloaderWindow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreloaderWindow.swift; sourceTree = "<group>"; };
A77D76E01A99208200F74F00 /* MainWindow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainWindow.swift; sourceTree = "<group>"; };
A77D76E31A99213900F74F00 /* PreloaderViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreloaderViewController.swift; sourceTree = "<group>"; };
......@@ -495,7 +497,7 @@
A77CF70F1AE1AA9D00D96EF7 /* Handle (simplified notification handling) */ = {
isa = PBXGroup;
children = (
A77CF7101AE1AAE600D96EF7 /* handle.swift */,
A77CF7101AE1AAE600D96EF7 /* Handle.swift */,
A79C8B891A8CC7F300F1948A /* NSNotificationCenterExtensions.swift */,
);
name = "Handle (simplified notification handling)";
......@@ -577,6 +579,7 @@
A79C8B931A8CDEF600F1948A /* source.ind.ie */ = {
isa = PBXGroup;
children = (
A74BB4571AE2477A001CA7BB /* Delay.swift */,
A77CF70F1AE1AA9D00D96EF7 /* Handle (simplified notification handling) */,
A79C8B941A8CDF3300F1948A /* VoiceOverStatus.swift */,
A7F711611A946763003557FA /* NSImageExtensions.swift */,
......@@ -962,6 +965,7 @@
A78DAE901A8018B5009FDB15 /* NonVibrantImageView.swift in Sources */,
A75AABCA1A5ECFB000B105BA /* AppDelegate.swift in Sources */,
A79C8B8A1A8CC7F300F1948A /* NSNotificationCenterExtensions.swift in Sources */,
A74BB4581AE2477A001CA7BB /* Delay.swift in Sources */,
A70041801AC216A800AE43F1 /* ProfileViewController.swift in Sources */,
A70634B81A63112600A75BC0 /* SetupStepViewController.swift in Sources */,
A74C9EEF1A6688D30083B288 /* Websocket.swift in Sources */,
......@@ -980,7 +984,7 @@
A7FE4E761AD6A3FF00857C35 /* Layout.swift in Sources */,
A7F0320E1A77D67500F3A28E /* SetupMessageViewController.swift in Sources */,
A72F9D951AACFFAF001CF629 /* ISO8601DateFormatter.m in Sources */,
A77CF7111AE1AAE600D96EF7 /* handle.swift in Sources */,
A77CF7111AE1AAE600D96EF7 /* Handle.swift in Sources */,
A7E7D7B31A616B0B003501C1 /* MainInterfaceAndDebugPanelSplitViewController.swift in Sources */,
A7FE4E771AD6A3FF00857C35 /* LayoutProxy.swift in Sources */,
A7F0320C1A76F35A00F3A28E /* SetupProgressIndicatorViewController.swift in Sources */,
......
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// General delay method that uses Grand Central Dispatch to execute a
// block after a specified number of seconds has elapsed.
//
// Basic usage, execute command after N seconds:
//
// delay(N)
// {
// // do something
// }
//
// Idiom for setting up a command that runs every N seconds and resets to N
// seconds if called sooner than that is:
//
// var myCommand:CancellableDelayedCommand
// …
// myCommand = myCommand.reset() ?? delay(N)
// {
// // do something
// }
//
// Credits:
//
// Inspried by the work of Cezary Wojcik, Matt Neuburg, and Evgenii Rtishchev:
//
// * https://stackoverflow.com/a/24034838/253485
// * https://stackoverflow.com/questions/24034544/dispatch-after-gcd-in-swift/24318861#24318861
// * https://github.com/katleta3000/CancelBlocks
//
// Copyright © 2015 Aral Balkan. Released with ♥ by Ind.ie under the MIT License.
//
////////////////////////////////////////////////////////////////////////////////////////////////////
import Foundation
// MARK: Public API
func delay(delay:Double, block:dispatch_block_t) -> CancellableDelayedCommand
{
return CancellableDelayedCommand(delay: delay, block: block)
}
// MARK: - Class
class CancellableDelayedCommand
{
var originalBlock:dispatch_block_t
var delayedBlock:dispatch_block_t?
var cancelled:Bool
var executed:Bool
var delay:Double
init(delay:Double, block:dispatch_block_t)
{
self.delay = delay
self.originalBlock = block
self.executed = false
self.cancelled = false
// println("New CancellableDelayedCommand: \(self)")
if delay < 0.0
{
// Special case. If delay is negative, run the closure on the same stack frame.
// If you want to run the closure on the next stack frame, pass 0.0.
block()
self.executed = true
return
}
// Create a delayed block that checks that the command
// has not been cancelled before it calls it.
self.delayedBlock =
{
dispatch_block_t in
if !self.cancelled
{
// println("\(self): delayed block about to dispatch!")
dispatch_async(dispatch_get_main_queue(), block)
self.executed = true
}
// else
// {
// println("\(self): delayed block NOT dispatching (cancelled).")
// }
self.delayedBlock = nil
}
// Set up the delayed dispatch.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue())
{
dispatch_block_t in
if (self.delayedBlock != nil)
{
self.delayedBlock!()
}
}
}
func cancel()
{
// println("\(self): Cancelling.")
cancelled = true
}
func reset() -> CancellableDelayedCommand?
{
//
// Cancels this command and creates and returns a new one
// with the delay timer reset.
//
// println("\(self): Reset.")
cancel()
return CancellableDelayedCommand(delay: self.delay, block: self.originalBlock)
}
}
......@@ -86,7 +86,7 @@ public func handle(notificationName:String, from object:AnyObject?, with block:N
public func post(notificationName:String, from object:AnyObject?, with userInfo:[NSObject : AnyObject]?)
{
println("About to post: \(notificationName) notification from \(object) with userInfo: \(userInfo)")
// println("About to post: \(notificationName) notification from \(object) with userInfo: \(userInfo)")
📡.post(notificationName, from: object, with: userInfo)
}
......
......@@ -26,69 +26,6 @@ func makeAccessibilityAnnouncement(message:String)
}
//
// General delay method that uses Grand Central Dispatch to execute a
// block after a specified number of seconds has elapsed. A cancellable block
// is returned, that you can cancel by calling and passing true for the cancel parameter.
//
// Based on CancelBlocks by Evgenii Rtishchev (https://github.com/katleta3000/CancelBlocks)
// and http://stackoverflow.com/questions/24034544/dispatch-after-gcd-in-swift
//
typealias dispatch_cancellable_block_t = (cancel:Bool) -> (Void)
func delay(delay:Double, block:dispatch_block_t?) -> dispatch_cancellable_block_t?
{
if (block == nil)
{
return nil
}
if delay < 0.0
{
// Special case. If delay is negative, run the closure on the same stack frame.
// If you want to run the closure on the next stack frame, pass 0.0.
block!()
return nil
}
var originalBlock:dispatch_block_t? = block!
var cancellableBlock:dispatch_cancellable_block_t? = nil
var delayBlock:dispatch_cancellable_block_t =
{
(cancel:Bool) -> Void in
if ((!cancel) && (originalBlock != nil))
{
dispatch_async(dispatch_get_main_queue(), originalBlock!)
}
cancellableBlock = nil
originalBlock = nil
}
cancellableBlock = delayBlock
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue())
{
() -> Void in
if (cancellableBlock != nil)
{
cancellableBlock!(cancel: false)
}
}
return cancellableBlock
}
func dispatch_cancel_block_t(block:dispatch_cancellable_block_t?)
{
if (block != nil)
{
block!(cancel: true)
}
}
//
// Other
//
......
......@@ -65,7 +65,7 @@ class ProfileImageComponentViewController: NSViewController, NSComboBoxDataSourc
var faces:[CIFaceFeature]
var cancellableProfileImageUpdateBlock:dispatch_cancellable_block_t?
var cancellableUpdateProfileImageCommand:CancellableDelayedCommand?
//
// Sets the Profile Image Picker view editable state
......@@ -665,8 +665,7 @@ class ProfileImageComponentViewController: NSViewController, NSComboBoxDataSourc
//
// Update the image whenever its bounds change (after a cancellable delay, so we’re not firing it too quickly).
//
cancellableProfileImageUpdateBlock?(cancel:true)
cancellableProfileImageUpdateBlock = delay(0.3)
cancellableUpdateProfileImageCommand = cancellableUpdateProfileImageCommand?.reset() ?? delay(0.3)
{
self.croppedImage()
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment