diff --git a/SSignalKit.xcodeproj/project.pbxproj b/SSignalKit.xcodeproj/project.pbxproj index 5e20cfe525..baf70e3b61 100644 --- a/SSignalKit.xcodeproj/project.pbxproj +++ b/SSignalKit.xcodeproj/project.pbxproj @@ -7,93 +7,98 @@ objects = { /* Begin PBXBuildFile section */ - D02AD5CA1B1121010074F9C1 /* SSignal+Pipe.m in Sources */ = {isa = PBXBuildFile; fileRef = D02AD5C81B1121010074F9C1 /* SSignal+Pipe.m */; }; - D02AD5CB1B1121010074F9C1 /* SSignal+Pipe.h in Headers */ = {isa = PBXBuildFile; fileRef = D02AD5C91B1121010074F9C1 /* SSignal+Pipe.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445DDE1A7C2CA500267924 /* SSignalKit.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445DDD1A7C2CA500267924 /* SSignalKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085AE71B28285400EAF753 /* SSignal+Timing.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AB11B28285400EAF753 /* SSignal+Timing.m */; }; + D0085AE81B28285400EAF753 /* SThreadPool.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AB21B28285400EAF753 /* SThreadPool.m */; }; + D0085AE91B28285400EAF753 /* SQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AB31B28285400EAF753 /* SQueue.m */; }; + D0085AEA1B28285400EAF753 /* SSignal+Take.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AB41B28285400EAF753 /* SSignal+Take.m */; }; + D0085AEB1B28285400EAF753 /* SSignal+Meta.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AB51B28285400EAF753 /* SSignal+Meta.m */; }; + D0085AEC1B28285400EAF753 /* SSignal+Accumulate.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AB61B28285400EAF753 /* SSignal+Accumulate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085AED1B28285400EAF753 /* SSignal+Single.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AB71B28285400EAF753 /* SSignal+Single.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085AEE1B28285400EAF753 /* SSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AB81B28285400EAF753 /* SSignal.m */; }; + D0085AEF1B28285400EAF753 /* SSignalKit.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AB91B28285400EAF753 /* SSignalKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085AF01B28285400EAF753 /* SMulticastSignalManager.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085ABA1B28285400EAF753 /* SMulticastSignalManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085AF11B28285400EAF753 /* SMulticastSignalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085ABB1B28285400EAF753 /* SMulticastSignalManager.m */; }; + D0085AF21B28285400EAF753 /* SSignal+Combine.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085ABC1B28285400EAF753 /* SSignal+Combine.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085AF31B28285400EAF753 /* SSignal+Combine.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085ABD1B28285400EAF753 /* SSignal+Combine.m */; }; + D0085AF41B28285400EAF753 /* SSignal+Pipe.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085ABE1B28285400EAF753 /* SSignal+Pipe.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085AF51B28285400EAF753 /* SSignal+Pipe.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085ABF1B28285400EAF753 /* SSignal+Pipe.m */; }; + D0085AF61B28285400EAF753 /* SSignal+SideEffects.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AC01B28285400EAF753 /* SSignal+SideEffects.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085AF71B28285400EAF753 /* SSignal+SideEffects.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AC11B28285400EAF753 /* SSignal+SideEffects.m */; }; + D0085AF81B28285400EAF753 /* SSignal+Catch.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AC21B28285400EAF753 /* SSignal+Catch.m */; }; + D0085AF91B28285400EAF753 /* SSignal+Catch.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AC31B28285400EAF753 /* SSignal+Catch.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085AFA1B28285400EAF753 /* SSignal+Take.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AC41B28285400EAF753 /* SSignal+Take.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085AFB1B28285400EAF753 /* SSignal+Accumulate.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AC51B28285400EAF753 /* SSignal+Accumulate.m */; }; + D0085AFC1B28285400EAF753 /* SQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AC61B28285400EAF753 /* SQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085AFD1B28285400EAF753 /* SSignal+Meta.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AC71B28285400EAF753 /* SSignal+Meta.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085AFE1B28285400EAF753 /* SSignal+Timing.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AC81B28285400EAF753 /* SSignal+Timing.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085AFF1B28285400EAF753 /* SSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AC91B28285400EAF753 /* SSubscriber.m */; }; + D0085B001B28285400EAF753 /* SSignal+Dispatch.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085ACA1B28285400EAF753 /* SSignal+Dispatch.m */; }; + D0085B011B28285400EAF753 /* SThreadPoolTask.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085ACB1B28285400EAF753 /* SThreadPoolTask.m */; }; + D0085B021B28285400EAF753 /* SThreadPoolQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085ACC1B28285400EAF753 /* SThreadPoolQueue.m */; }; + D0085B031B28285400EAF753 /* SThreadPoolQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085ACD1B28285400EAF753 /* SThreadPoolQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B041B28285400EAF753 /* SThreadPool.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085ACE1B28285400EAF753 /* SThreadPool.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B051B28285400EAF753 /* SThreadPoolTask.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085ACF1B28285400EAF753 /* SThreadPoolTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B061B28285400EAF753 /* SDisposableSet.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AD01B28285400EAF753 /* SDisposableSet.m */; }; + D0085B071B28285400EAF753 /* SMetaDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AD11B28285400EAF753 /* SMetaDisposable.m */; }; + D0085B081B28285400EAF753 /* SSignal+Multicast.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AD21B28285400EAF753 /* SSignal+Multicast.m */; }; + D0085B091B28285400EAF753 /* SSubscriber.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AD31B28285400EAF753 /* SSubscriber.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B0A1B28285400EAF753 /* SDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AD41B28285400EAF753 /* SDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B0B1B28285400EAF753 /* SSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AD51B28285400EAF753 /* SSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B0C1B28285400EAF753 /* SSignal+Mapping.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AD61B28285400EAF753 /* SSignal+Mapping.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B0D1B28285400EAF753 /* SSignal+Mapping.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AD71B28285400EAF753 /* SSignal+Mapping.m */; }; + D0085B0E1B28285400EAF753 /* SSignal+Single.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AD81B28285400EAF753 /* SSignal+Single.m */; }; + D0085B0F1B28285400EAF753 /* SAtomic.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AD91B28285400EAF753 /* SAtomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B101B28285400EAF753 /* SAtomic.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085ADA1B28285400EAF753 /* SAtomic.m */; }; + D0085B111B28285400EAF753 /* SBag.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085ADB1B28285400EAF753 /* SBag.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B121B28285400EAF753 /* SBag.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085ADC1B28285400EAF753 /* SBag.m */; }; + D0085B131B28285400EAF753 /* SBlockDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085ADD1B28285400EAF753 /* SBlockDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B141B28285400EAF753 /* SBlockDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085ADE1B28285400EAF753 /* SBlockDisposable.m */; }; + D0085B151B28285400EAF753 /* SDisposableSet.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085ADF1B28285400EAF753 /* SDisposableSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B181B28285400EAF753 /* SMetaDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AE21B28285400EAF753 /* SMetaDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B191B28285400EAF753 /* SSignal+Dispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AE31B28285400EAF753 /* SSignal+Dispatch.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B1A1B28285400EAF753 /* SSignal+Multicast.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AE41B28285400EAF753 /* SSignal+Multicast.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B1B1B28285400EAF753 /* STimer.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085AE51B28285400EAF753 /* STimer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B1C1B28285400EAF753 /* STimer.m in Sources */ = {isa = PBXBuildFile; fileRef = D0085AE61B28285400EAF753 /* STimer.m */; }; + D0085B271B282B9800EAF753 /* SwiftSignalKit.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085B261B282B9800EAF753 /* SwiftSignalKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0085B2D1B282B9800EAF753 /* SwiftSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0085B221B282B9800EAF753 /* SwiftSignalKit.framework */; }; + D0085B4F1B282BEE00EAF753 /* SwiftSignalKit.h in Headers */ = {isa = PBXBuildFile; fileRef = D0085B3B1B282BEE00EAF753 /* SwiftSignalKit.h */; }; + D0085B501B282BEE00EAF753 /* Signal_Timing.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B3C1B282BEE00EAF753 /* Signal_Timing.swift */; }; + D0085B511B282BEE00EAF753 /* Signal_SideEffects.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B3D1B282BEE00EAF753 /* Signal_SideEffects.swift */; }; + D0085B521B282BEE00EAF753 /* Signal_Dispatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B3E1B282BEE00EAF753 /* Signal_Dispatch.swift */; }; + D0085B531B282BEE00EAF753 /* ThreadPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B3F1B282BEE00EAF753 /* ThreadPool.swift */; }; + D0085B541B282BEE00EAF753 /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B401B282BEE00EAF753 /* Timer.swift */; }; + D0085B551B282BEE00EAF753 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B411B282BEE00EAF753 /* Queue.swift */; }; + D0085B561B282BEE00EAF753 /* Pipe.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B421B282BEE00EAF753 /* Pipe.swift */; }; + D0085B571B282BEE00EAF753 /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B431B282BEE00EAF753 /* Bag.swift */; }; + D0085B581B282BEE00EAF753 /* Signal_Take.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B441B282BEE00EAF753 /* Signal_Take.swift */; }; + D0085B591B282BEE00EAF753 /* Signal_Catch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B451B282BEE00EAF753 /* Signal_Catch.swift */; }; + D0085B5A1B282BEE00EAF753 /* Signal_Single.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B461B282BEE00EAF753 /* Signal_Single.swift */; }; + D0085B5B1B282BEE00EAF753 /* Signal_Meta.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B471B282BEE00EAF753 /* Signal_Meta.swift */; }; + D0085B5C1B282BEE00EAF753 /* Signal_Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B481B282BEE00EAF753 /* Signal_Combine.swift */; }; + D0085B5D1B282BEE00EAF753 /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B491B282BEE00EAF753 /* Atomic.swift */; }; + D0085B5E1B282BEE00EAF753 /* Signal_Reduce.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B4A1B282BEE00EAF753 /* Signal_Reduce.swift */; }; + D0085B5F1B282BEE00EAF753 /* Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B4B1B282BEE00EAF753 /* Signal.swift */; }; + D0085B601B282BEE00EAF753 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B4C1B282BEE00EAF753 /* Disposable.swift */; }; + D0085B611B282BEE00EAF753 /* Signal_Mapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B4D1B282BEE00EAF753 /* Signal_Mapping.swift */; }; + D0085B621B282BEE00EAF753 /* Subscriber.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B4E1B282BEE00EAF753 /* Subscriber.swift */; }; + D0085B661B282C2800EAF753 /* SwiftSignalKitFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B631B282C2800EAF753 /* SwiftSignalKitFunctionsTests.swift */; }; + D0085B671B282C2800EAF753 /* DeallocatingObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B641B282C2800EAF753 /* DeallocatingObject.swift */; }; + D0085B681B282C2800EAF753 /* SwiftSignalKitBasicTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0085B651B282C2800EAF753 /* SwiftSignalKitBasicTests.swift */; }; D0445DE41A7C2CA500267924 /* SSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0445DD81A7C2CA500267924 /* SSignalKit.framework */; }; - D0445E221A7C2D7300267924 /* SBlockDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445DF61A7C2D7300267924 /* SBlockDisposable.m */; }; - D0445E231A7C2D7300267924 /* SAtomic.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445DF71A7C2D7300267924 /* SAtomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E241A7C2D7300267924 /* SAtomic.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445DF81A7C2D7300267924 /* SAtomic.m */; }; - D0445E251A7C2D7300267924 /* SBag.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445DF91A7C2D7300267924 /* SBag.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E261A7C2D7300267924 /* SBag.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445DFA1A7C2D7300267924 /* SBag.m */; }; - D0445E271A7C2D7300267924 /* SBlockDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445DFB1A7C2D7300267924 /* SBlockDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E2A1A7C2D7300267924 /* SDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445DFE1A7C2D7300267924 /* SDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E2B1A7C2D7300267924 /* SEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445DFF1A7C2D7300267924 /* SEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E2C1A7C2D7300267924 /* SEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E001A7C2D7300267924 /* SEvent.m */; }; - D0445E2D1A7C2D7300267924 /* SMetaDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E011A7C2D7300267924 /* SMetaDisposable.m */; }; - D0445E2E1A7C2D7300267924 /* SMulticastSignalManager.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E021A7C2D7300267924 /* SMulticastSignalManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E2F1A7C2D7300267924 /* SMulticastSignalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E031A7C2D7300267924 /* SMulticastSignalManager.m */; }; - D0445E301A7C2D7300267924 /* SSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E041A7C2D7300267924 /* SSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E311A7C2D7300267924 /* SSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E051A7C2D7300267924 /* SSignal.m */; }; - D0445E321A7C2D7300267924 /* SSignal+Accumulate.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E061A7C2D7300267924 /* SSignal+Accumulate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E331A7C2D7300267924 /* SSignal+Accumulate.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E071A7C2D7300267924 /* SSignal+Accumulate.m */; }; - D0445E341A7C2D7300267924 /* SSignal+Catch.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E081A7C2D7300267924 /* SSignal+Catch.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E351A7C2D7300267924 /* SSignal+Catch.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E091A7C2D7300267924 /* SSignal+Catch.m */; }; - D0445E361A7C2D7300267924 /* SSignal+Combine.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E0A1A7C2D7300267924 /* SSignal+Combine.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E371A7C2D7300267924 /* SSignal+Combine.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E0B1A7C2D7300267924 /* SSignal+Combine.m */; }; - D0445E3A1A7C2D7300267924 /* SSignal+Dispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E0E1A7C2D7300267924 /* SSignal+Dispatch.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E3B1A7C2D7300267924 /* SSignal+Dispatch.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E0F1A7C2D7300267924 /* SSignal+Dispatch.m */; }; - D0445E3C1A7C2D7300267924 /* SSignal+Mapping.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E101A7C2D7300267924 /* SSignal+Mapping.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E3D1A7C2D7300267924 /* SSignal+Mapping.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E111A7C2D7300267924 /* SSignal+Mapping.m */; }; - D0445E3E1A7C2D7300267924 /* SSignal+Meta.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E121A7C2D7300267924 /* SSignal+Meta.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E3F1A7C2D7300267924 /* SSignal+Meta.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E131A7C2D7300267924 /* SSignal+Meta.m */; }; - D0445E401A7C2D7300267924 /* SSignal+Multicast.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E141A7C2D7300267924 /* SSignal+Multicast.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E411A7C2D7300267924 /* SSignal+Multicast.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E151A7C2D7300267924 /* SSignal+Multicast.m */; }; - D0445E421A7C2D7300267924 /* SSignal+SideEffects.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E161A7C2D7300267924 /* SSignal+SideEffects.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E431A7C2D7300267924 /* SSignal+SideEffects.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E171A7C2D7300267924 /* SSignal+SideEffects.m */; }; - D0445E441A7C2D7300267924 /* SSignal+Single.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E181A7C2D7300267924 /* SSignal+Single.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E451A7C2D7300267924 /* SSignal+Single.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E191A7C2D7300267924 /* SSignal+Single.m */; }; - D0445E461A7C2D7300267924 /* SSignal+Timing.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E1A1A7C2D7300267924 /* SSignal+Timing.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E471A7C2D7300267924 /* SSignal+Timing.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E1B1A7C2D7300267924 /* SSignal+Timing.m */; }; - D0445E481A7C2D7300267924 /* SSubscriber.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E1C1A7C2D7300267924 /* SSubscriber.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E491A7C2D7300267924 /* SSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E1D1A7C2D7300267924 /* SSubscriber.m */; }; - D0445E4A1A7C2D7300267924 /* SThreadPool.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E1E1A7C2D7300267924 /* SThreadPool.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E4B1A7C2D7300267924 /* SThreadPool.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E1F1A7C2D7300267924 /* SThreadPool.m */; }; - D0445E4E1A7C2D8A00267924 /* SQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E4C1A7C2D8A00267924 /* SQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E4F1A7C2D8A00267924 /* SQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E4D1A7C2D8A00267924 /* SQueue.m */; }; - D0445E511A7C2DBF00267924 /* SMetaDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E501A7C2DBF00267924 /* SMetaDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E541A7C2E9D00267924 /* STimer.h in Headers */ = {isa = PBXBuildFile; fileRef = D0445E521A7C2E9D00267924 /* STimer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0445E551A7C2E9D00267924 /* STimer.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E531A7C2E9D00267924 /* STimer.m */; }; D0445E571A7C3FB400267924 /* SDisposableTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E561A7C3FB400267924 /* SDisposableTests.m */; }; - D0445E731A7C447D00267924 /* SBlockDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445DF61A7C2D7300267924 /* SBlockDisposable.m */; }; - D0445E741A7C447D00267924 /* SAtomic.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445DF81A7C2D7300267924 /* SAtomic.m */; }; - D0445E751A7C447D00267924 /* SBag.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445DFA1A7C2D7300267924 /* SBag.m */; }; - D0445E771A7C447D00267924 /* SEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E001A7C2D7300267924 /* SEvent.m */; }; - D0445E781A7C447D00267924 /* SMetaDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E011A7C2D7300267924 /* SMetaDisposable.m */; }; - D0445E791A7C447D00267924 /* SMulticastSignalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E031A7C2D7300267924 /* SMulticastSignalManager.m */; }; - D0445E7A1A7C447D00267924 /* SSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E051A7C2D7300267924 /* SSignal.m */; }; - D0445E7B1A7C447D00267924 /* SSignal+Accumulate.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E071A7C2D7300267924 /* SSignal+Accumulate.m */; }; - D0445E7C1A7C447D00267924 /* SSignal+Catch.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E091A7C2D7300267924 /* SSignal+Catch.m */; }; - D0445E7D1A7C447D00267924 /* SSignal+Combine.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E0B1A7C2D7300267924 /* SSignal+Combine.m */; }; - D0445E7F1A7C447D00267924 /* SSignal+Dispatch.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E0F1A7C2D7300267924 /* SSignal+Dispatch.m */; }; - D0445E801A7C447D00267924 /* SSignal+Mapping.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E111A7C2D7300267924 /* SSignal+Mapping.m */; }; - D0445E811A7C447D00267924 /* SSignal+Meta.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E131A7C2D7300267924 /* SSignal+Meta.m */; }; - D0445E821A7C447D00267924 /* SSignal+Multicast.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E151A7C2D7300267924 /* SSignal+Multicast.m */; }; - D0445E831A7C447D00267924 /* SSignal+SideEffects.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E171A7C2D7300267924 /* SSignal+SideEffects.m */; }; - D0445E841A7C447D00267924 /* SSignal+Single.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E191A7C2D7300267924 /* SSignal+Single.m */; }; - D0445E851A7C447D00267924 /* SSignal+Timing.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E1B1A7C2D7300267924 /* SSignal+Timing.m */; }; - D0445E861A7C447D00267924 /* SSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E1D1A7C2D7300267924 /* SSubscriber.m */; }; - D0445E871A7C447D00267924 /* SThreadPool.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E1F1A7C2D7300267924 /* SThreadPool.m */; }; - D0445E881A7C447D00267924 /* SQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E4D1A7C2D8A00267924 /* SQueue.m */; }; - D0445E891A7C447D00267924 /* STimer.m in Sources */ = {isa = PBXBuildFile; fileRef = D0445E531A7C2E9D00267924 /* STimer.m */; }; D06F106C1A85561E00485185 /* SSignalBasicTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D06F106B1A85561E00485185 /* SSignalBasicTests.m */; }; D06F10711A855E2D00485185 /* DeallocatingObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D06F10701A855E2D00485185 /* DeallocatingObject.m */; }; D06F10731A85882000485185 /* SSignalPerformanceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D06F10721A85882000485185 /* SSignalPerformanceTests.m */; }; - D087632A1A839EDC00632240 /* SDisposableSet.h in Headers */ = {isa = PBXBuildFile; fileRef = D08763281A839EDC00632240 /* SDisposableSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D087632B1A839EDC00632240 /* SDisposableSet.m in Sources */ = {isa = PBXBuildFile; fileRef = D08763291A839EDC00632240 /* SDisposableSet.m */; }; - D087632C1A839EE800632240 /* SDisposableSet.m in Sources */ = {isa = PBXBuildFile; fileRef = D08763291A839EDC00632240 /* SDisposableSet.m */; }; - D089E0311AC48EA7009A744B /* SThreadPoolTask.m in Sources */ = {isa = PBXBuildFile; fileRef = D089E02D1AC48EA7009A744B /* SThreadPoolTask.m */; }; - D089E0321AC48EA7009A744B /* SThreadPoolQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D089E02E1AC48EA7009A744B /* SThreadPoolQueue.m */; }; - D089E0331AC48EA7009A744B /* SThreadPoolQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = D089E02F1AC48EA7009A744B /* SThreadPoolQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D089E0341AC48EA7009A744B /* SThreadPoolTask.h in Headers */ = {isa = PBXBuildFile; fileRef = D089E0301AC48EA7009A744B /* SThreadPoolTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D089E0391AC56981009A744B /* SThreadPoolQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D089E02E1AC48EA7009A744B /* SThreadPoolQueue.m */; }; - D089E03A1AC56981009A744B /* SThreadPoolTask.m in Sources */ = {isa = PBXBuildFile; fileRef = D089E02D1AC48EA7009A744B /* SThreadPoolTask.m */; }; - D0FC5B431AF140E600F353AB /* SSignal+Take.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FC5B411AF140E600F353AB /* SSignal+Take.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0FC5B441AF140E600F353AB /* SSignal+Take.m in Sources */ = {isa = PBXBuildFile; fileRef = D0FC5B421AF140E600F353AB /* SSignal+Take.m */; }; - D0FC5B451AF141F800F353AB /* SSignal+Take.m in Sources */ = {isa = PBXBuildFile; fileRef = D0FC5B421AF140E600F353AB /* SSignal+Take.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + D0085B2E1B282B9800EAF753 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D0445DCF1A7C2CA500267924 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D0085B211B282B9800EAF753; + remoteInfo = SwiftSignalKit; + }; D0445DE51A7C2CA500267924 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D0445DCF1A7C2CA500267924 /* Project object */; @@ -103,86 +108,114 @@ }; /* End PBXContainerItemProxy section */ -/* Begin PBXCopyFilesBuildPhase section */ - D0445E5A1A7C446000267924 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ - D02AD5C81B1121010074F9C1 /* SSignal+Pipe.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Pipe.m"; sourceTree = ""; }; - D02AD5C91B1121010074F9C1 /* SSignal+Pipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Pipe.h"; sourceTree = ""; }; + D0085AB11B28285400EAF753 /* SSignal+Timing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Timing.m"; sourceTree = ""; }; + D0085AB21B28285400EAF753 /* SThreadPool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SThreadPool.m; sourceTree = ""; }; + D0085AB31B28285400EAF753 /* SQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQueue.m; sourceTree = ""; }; + D0085AB41B28285400EAF753 /* SSignal+Take.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Take.m"; sourceTree = ""; }; + D0085AB51B28285400EAF753 /* SSignal+Meta.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Meta.m"; sourceTree = ""; }; + D0085AB61B28285400EAF753 /* SSignal+Accumulate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Accumulate.h"; sourceTree = ""; }; + D0085AB71B28285400EAF753 /* SSignal+Single.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Single.h"; sourceTree = ""; }; + D0085AB81B28285400EAF753 /* SSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSignal.m; sourceTree = ""; }; + D0085AB91B28285400EAF753 /* SSignalKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSignalKit.h; sourceTree = ""; }; + D0085ABA1B28285400EAF753 /* SMulticastSignalManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SMulticastSignalManager.h; sourceTree = ""; }; + D0085ABB1B28285400EAF753 /* SMulticastSignalManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SMulticastSignalManager.m; sourceTree = ""; }; + D0085ABC1B28285400EAF753 /* SSignal+Combine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Combine.h"; sourceTree = ""; }; + D0085ABD1B28285400EAF753 /* SSignal+Combine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Combine.m"; sourceTree = ""; }; + D0085ABE1B28285400EAF753 /* SSignal+Pipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Pipe.h"; sourceTree = ""; }; + D0085ABF1B28285400EAF753 /* SSignal+Pipe.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Pipe.m"; sourceTree = ""; }; + D0085AC01B28285400EAF753 /* SSignal+SideEffects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+SideEffects.h"; sourceTree = ""; }; + D0085AC11B28285400EAF753 /* SSignal+SideEffects.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+SideEffects.m"; sourceTree = ""; }; + D0085AC21B28285400EAF753 /* SSignal+Catch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Catch.m"; sourceTree = ""; }; + D0085AC31B28285400EAF753 /* SSignal+Catch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Catch.h"; sourceTree = ""; }; + D0085AC41B28285400EAF753 /* SSignal+Take.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Take.h"; sourceTree = ""; }; + D0085AC51B28285400EAF753 /* SSignal+Accumulate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Accumulate.m"; sourceTree = ""; }; + D0085AC61B28285400EAF753 /* SQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQueue.h; sourceTree = ""; }; + D0085AC71B28285400EAF753 /* SSignal+Meta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Meta.h"; sourceTree = ""; }; + D0085AC81B28285400EAF753 /* SSignal+Timing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Timing.h"; sourceTree = ""; }; + D0085AC91B28285400EAF753 /* SSubscriber.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSubscriber.m; sourceTree = ""; }; + D0085ACA1B28285400EAF753 /* SSignal+Dispatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Dispatch.m"; sourceTree = ""; }; + D0085ACB1B28285400EAF753 /* SThreadPoolTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SThreadPoolTask.m; sourceTree = ""; }; + D0085ACC1B28285400EAF753 /* SThreadPoolQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SThreadPoolQueue.m; sourceTree = ""; }; + D0085ACD1B28285400EAF753 /* SThreadPoolQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SThreadPoolQueue.h; sourceTree = ""; }; + D0085ACE1B28285400EAF753 /* SThreadPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SThreadPool.h; sourceTree = ""; }; + D0085ACF1B28285400EAF753 /* SThreadPoolTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SThreadPoolTask.h; sourceTree = ""; }; + D0085AD01B28285400EAF753 /* SDisposableSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDisposableSet.m; sourceTree = ""; }; + D0085AD11B28285400EAF753 /* SMetaDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SMetaDisposable.m; sourceTree = ""; }; + D0085AD21B28285400EAF753 /* SSignal+Multicast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Multicast.m"; sourceTree = ""; }; + D0085AD31B28285400EAF753 /* SSubscriber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSubscriber.h; sourceTree = ""; }; + D0085AD41B28285400EAF753 /* SDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDisposable.h; sourceTree = ""; }; + D0085AD51B28285400EAF753 /* SSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSignal.h; sourceTree = ""; }; + D0085AD61B28285400EAF753 /* SSignal+Mapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Mapping.h"; sourceTree = ""; }; + D0085AD71B28285400EAF753 /* SSignal+Mapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Mapping.m"; sourceTree = ""; }; + D0085AD81B28285400EAF753 /* SSignal+Single.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Single.m"; sourceTree = ""; }; + D0085AD91B28285400EAF753 /* SAtomic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAtomic.h; sourceTree = ""; }; + D0085ADA1B28285400EAF753 /* SAtomic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAtomic.m; sourceTree = ""; }; + D0085ADB1B28285400EAF753 /* SBag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBag.h; sourceTree = ""; }; + D0085ADC1B28285400EAF753 /* SBag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBag.m; sourceTree = ""; }; + D0085ADD1B28285400EAF753 /* SBlockDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBlockDisposable.h; sourceTree = ""; }; + D0085ADE1B28285400EAF753 /* SBlockDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBlockDisposable.m; sourceTree = ""; }; + D0085ADF1B28285400EAF753 /* SDisposableSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDisposableSet.h; sourceTree = ""; }; + D0085AE21B28285400EAF753 /* SMetaDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SMetaDisposable.h; sourceTree = ""; }; + D0085AE31B28285400EAF753 /* SSignal+Dispatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Dispatch.h"; sourceTree = ""; }; + D0085AE41B28285400EAF753 /* SSignal+Multicast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Multicast.h"; sourceTree = ""; }; + D0085AE51B28285400EAF753 /* STimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STimer.h; sourceTree = ""; }; + D0085AE61B28285400EAF753 /* STimer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STimer.m; sourceTree = ""; }; + D0085B221B282B9800EAF753 /* SwiftSignalKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftSignalKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0085B251B282B9800EAF753 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D0085B261B282B9800EAF753 /* SwiftSignalKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftSignalKit.h; sourceTree = ""; }; + D0085B2C1B282B9800EAF753 /* SwiftSignalKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftSignalKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + D0085B321B282B9800EAF753 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D0085B3B1B282BEE00EAF753 /* SwiftSignalKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SwiftSignalKit.h; sourceTree = ""; }; + D0085B3C1B282BEE00EAF753 /* Signal_Timing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signal_Timing.swift; sourceTree = ""; }; + D0085B3D1B282BEE00EAF753 /* Signal_SideEffects.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signal_SideEffects.swift; sourceTree = ""; }; + D0085B3E1B282BEE00EAF753 /* Signal_Dispatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signal_Dispatch.swift; sourceTree = ""; }; + D0085B3F1B282BEE00EAF753 /* ThreadPool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThreadPool.swift; sourceTree = ""; }; + D0085B401B282BEE00EAF753 /* Timer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Timer.swift; sourceTree = ""; }; + D0085B411B282BEE00EAF753 /* Queue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Queue.swift; sourceTree = ""; }; + D0085B421B282BEE00EAF753 /* Pipe.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Pipe.swift; sourceTree = ""; }; + D0085B431B282BEE00EAF753 /* Bag.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bag.swift; sourceTree = ""; }; + D0085B441B282BEE00EAF753 /* Signal_Take.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signal_Take.swift; sourceTree = ""; }; + D0085B451B282BEE00EAF753 /* Signal_Catch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signal_Catch.swift; sourceTree = ""; }; + D0085B461B282BEE00EAF753 /* Signal_Single.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signal_Single.swift; sourceTree = ""; }; + D0085B471B282BEE00EAF753 /* Signal_Meta.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signal_Meta.swift; sourceTree = ""; }; + D0085B481B282BEE00EAF753 /* Signal_Combine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signal_Combine.swift; sourceTree = ""; }; + D0085B491B282BEE00EAF753 /* Atomic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = ""; }; + D0085B4A1B282BEE00EAF753 /* Signal_Reduce.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signal_Reduce.swift; sourceTree = ""; }; + D0085B4B1B282BEE00EAF753 /* Signal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signal.swift; sourceTree = ""; }; + D0085B4C1B282BEE00EAF753 /* Disposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Disposable.swift; sourceTree = ""; }; + D0085B4D1B282BEE00EAF753 /* Signal_Mapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signal_Mapping.swift; sourceTree = ""; }; + D0085B4E1B282BEE00EAF753 /* Subscriber.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Subscriber.swift; sourceTree = ""; }; + D0085B631B282C2800EAF753 /* SwiftSignalKitFunctionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftSignalKitFunctionsTests.swift; sourceTree = ""; }; + D0085B641B282C2800EAF753 /* DeallocatingObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeallocatingObject.swift; sourceTree = ""; }; + D0085B651B282C2800EAF753 /* SwiftSignalKitBasicTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftSignalKitBasicTests.swift; sourceTree = ""; }; D0445DD81A7C2CA500267924 /* SSignalKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SSignalKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D0445DDC1A7C2CA500267924 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - D0445DDD1A7C2CA500267924 /* SSignalKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SSignalKit.h; sourceTree = ""; }; D0445DE31A7C2CA500267924 /* SSignalKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SSignalKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; D0445DE91A7C2CA500267924 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - D0445DF61A7C2D7300267924 /* SBlockDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBlockDisposable.m; sourceTree = ""; }; - D0445DF71A7C2D7300267924 /* SAtomic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAtomic.h; sourceTree = ""; }; - D0445DF81A7C2D7300267924 /* SAtomic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAtomic.m; sourceTree = ""; }; - D0445DF91A7C2D7300267924 /* SBag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBag.h; sourceTree = ""; }; - D0445DFA1A7C2D7300267924 /* SBag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBag.m; sourceTree = ""; }; - D0445DFB1A7C2D7300267924 /* SBlockDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBlockDisposable.h; sourceTree = ""; }; - D0445DFE1A7C2D7300267924 /* SDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDisposable.h; sourceTree = ""; }; - D0445DFF1A7C2D7300267924 /* SEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SEvent.h; sourceTree = ""; }; - D0445E001A7C2D7300267924 /* SEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SEvent.m; sourceTree = ""; }; - D0445E011A7C2D7300267924 /* SMetaDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SMetaDisposable.m; sourceTree = ""; }; - D0445E021A7C2D7300267924 /* SMulticastSignalManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SMulticastSignalManager.h; sourceTree = ""; }; - D0445E031A7C2D7300267924 /* SMulticastSignalManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SMulticastSignalManager.m; sourceTree = ""; }; - D0445E041A7C2D7300267924 /* SSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSignal.h; sourceTree = ""; }; - D0445E051A7C2D7300267924 /* SSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSignal.m; sourceTree = ""; }; - D0445E061A7C2D7300267924 /* SSignal+Accumulate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Accumulate.h"; sourceTree = ""; }; - D0445E071A7C2D7300267924 /* SSignal+Accumulate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Accumulate.m"; sourceTree = ""; }; - D0445E081A7C2D7300267924 /* SSignal+Catch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Catch.h"; sourceTree = ""; }; - D0445E091A7C2D7300267924 /* SSignal+Catch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Catch.m"; sourceTree = ""; }; - D0445E0A1A7C2D7300267924 /* SSignal+Combine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Combine.h"; sourceTree = ""; }; - D0445E0B1A7C2D7300267924 /* SSignal+Combine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Combine.m"; sourceTree = ""; }; - D0445E0E1A7C2D7300267924 /* SSignal+Dispatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Dispatch.h"; sourceTree = ""; }; - D0445E0F1A7C2D7300267924 /* SSignal+Dispatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Dispatch.m"; sourceTree = ""; }; - D0445E101A7C2D7300267924 /* SSignal+Mapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Mapping.h"; sourceTree = ""; }; - D0445E111A7C2D7300267924 /* SSignal+Mapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Mapping.m"; sourceTree = ""; }; - D0445E121A7C2D7300267924 /* SSignal+Meta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Meta.h"; sourceTree = ""; }; - D0445E131A7C2D7300267924 /* SSignal+Meta.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Meta.m"; sourceTree = ""; }; - D0445E141A7C2D7300267924 /* SSignal+Multicast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Multicast.h"; sourceTree = ""; }; - D0445E151A7C2D7300267924 /* SSignal+Multicast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Multicast.m"; sourceTree = ""; }; - D0445E161A7C2D7300267924 /* SSignal+SideEffects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+SideEffects.h"; sourceTree = ""; }; - D0445E171A7C2D7300267924 /* SSignal+SideEffects.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+SideEffects.m"; sourceTree = ""; }; - D0445E181A7C2D7300267924 /* SSignal+Single.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Single.h"; sourceTree = ""; }; - D0445E191A7C2D7300267924 /* SSignal+Single.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Single.m"; sourceTree = ""; }; - D0445E1A1A7C2D7300267924 /* SSignal+Timing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Timing.h"; sourceTree = ""; }; - D0445E1B1A7C2D7300267924 /* SSignal+Timing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Timing.m"; sourceTree = ""; }; - D0445E1C1A7C2D7300267924 /* SSubscriber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSubscriber.h; sourceTree = ""; }; - D0445E1D1A7C2D7300267924 /* SSubscriber.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSubscriber.m; sourceTree = ""; }; - D0445E1E1A7C2D7300267924 /* SThreadPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SThreadPool.h; sourceTree = ""; }; - D0445E1F1A7C2D7300267924 /* SThreadPool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SThreadPool.m; sourceTree = ""; }; - D0445E4C1A7C2D8A00267924 /* SQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQueue.h; sourceTree = ""; }; - D0445E4D1A7C2D8A00267924 /* SQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQueue.m; sourceTree = ""; }; - D0445E501A7C2DBF00267924 /* SMetaDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SMetaDisposable.h; sourceTree = ""; }; - D0445E521A7C2E9D00267924 /* STimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STimer.h; sourceTree = ""; }; - D0445E531A7C2E9D00267924 /* STimer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STimer.m; sourceTree = ""; }; D0445E561A7C3FB400267924 /* SDisposableTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDisposableTests.m; sourceTree = ""; }; - D0445E5C1A7C446000267924 /* libSSignalKitStatic.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSSignalKitStatic.a; sourceTree = BUILT_PRODUCTS_DIR; }; D06F106B1A85561E00485185 /* SSignalBasicTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSignalBasicTests.m; sourceTree = ""; }; D06F106F1A855E2D00485185 /* DeallocatingObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeallocatingObject.h; sourceTree = ""; }; D06F10701A855E2D00485185 /* DeallocatingObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DeallocatingObject.m; sourceTree = ""; }; D06F10721A85882000485185 /* SSignalPerformanceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSignalPerformanceTests.m; sourceTree = ""; }; - D08763281A839EDC00632240 /* SDisposableSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDisposableSet.h; sourceTree = ""; }; - D08763291A839EDC00632240 /* SDisposableSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDisposableSet.m; sourceTree = ""; }; - D089E02D1AC48EA7009A744B /* SThreadPoolTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SThreadPoolTask.m; sourceTree = ""; }; - D089E02E1AC48EA7009A744B /* SThreadPoolQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SThreadPoolQueue.m; sourceTree = ""; }; - D089E02F1AC48EA7009A744B /* SThreadPoolQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SThreadPoolQueue.h; sourceTree = ""; }; - D089E0301AC48EA7009A744B /* SThreadPoolTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SThreadPoolTask.h; sourceTree = ""; }; - D0FC5B411AF140E600F353AB /* SSignal+Take.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSignal+Take.h"; sourceTree = ""; }; - D0FC5B421AF140E600F353AB /* SSignal+Take.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SSignal+Take.m"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + D0085B1E1B282B9800EAF753 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D0085B291B282B9800EAF753 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D0085B2D1B282B9800EAF753 /* SwiftSignalKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; D0445DD41A7C2CA500267924 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -198,21 +231,72 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - D0445E591A7C446000267924 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + D0085B231B282B9800EAF753 /* SwiftSignalKit */ = { + isa = PBXGroup; + children = ( + D0085B3B1B282BEE00EAF753 /* SwiftSignalKit.h */, + D0085B3C1B282BEE00EAF753 /* Signal_Timing.swift */, + D0085B3D1B282BEE00EAF753 /* Signal_SideEffects.swift */, + D0085B3E1B282BEE00EAF753 /* Signal_Dispatch.swift */, + D0085B3F1B282BEE00EAF753 /* ThreadPool.swift */, + D0085B401B282BEE00EAF753 /* Timer.swift */, + D0085B411B282BEE00EAF753 /* Queue.swift */, + D0085B421B282BEE00EAF753 /* Pipe.swift */, + D0085B431B282BEE00EAF753 /* Bag.swift */, + D0085B441B282BEE00EAF753 /* Signal_Take.swift */, + D0085B451B282BEE00EAF753 /* Signal_Catch.swift */, + D0085B461B282BEE00EAF753 /* Signal_Single.swift */, + D0085B471B282BEE00EAF753 /* Signal_Meta.swift */, + D0085B481B282BEE00EAF753 /* Signal_Combine.swift */, + D0085B491B282BEE00EAF753 /* Atomic.swift */, + D0085B4A1B282BEE00EAF753 /* Signal_Reduce.swift */, + D0085B4B1B282BEE00EAF753 /* Signal.swift */, + D0085B4C1B282BEE00EAF753 /* Disposable.swift */, + D0085B4D1B282BEE00EAF753 /* Signal_Mapping.swift */, + D0085B4E1B282BEE00EAF753 /* Subscriber.swift */, + D0085B261B282B9800EAF753 /* SwiftSignalKit.h */, + D0085B241B282B9800EAF753 /* Supporting Files */, + ); + path = SwiftSignalKit; + sourceTree = ""; + }; + D0085B241B282B9800EAF753 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + D0085B251B282B9800EAF753 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + D0085B301B282B9800EAF753 /* SwiftSignalKitTests */ = { + isa = PBXGroup; + children = ( + D0085B631B282C2800EAF753 /* SwiftSignalKitFunctionsTests.swift */, + D0085B641B282C2800EAF753 /* DeallocatingObject.swift */, + D0085B651B282C2800EAF753 /* SwiftSignalKitBasicTests.swift */, + D0085B311B282B9800EAF753 /* Supporting Files */, + ); + path = SwiftSignalKitTests; + sourceTree = ""; + }; + D0085B311B282B9800EAF753 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + D0085B321B282B9800EAF753 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; D0445DCE1A7C2CA500267924 = { isa = PBXGroup; children = ( D0445DDA1A7C2CA500267924 /* SSignalKit */, D0445DE71A7C2CA500267924 /* SSignalKitTests */, + D0085B231B282B9800EAF753 /* SwiftSignalKit */, + D0085B301B282B9800EAF753 /* SwiftSignalKitTests */, D0445DD91A7C2CA500267924 /* Products */, ); sourceTree = ""; @@ -222,7 +306,8 @@ children = ( D0445DD81A7C2CA500267924 /* SSignalKit.framework */, D0445DE31A7C2CA500267924 /* SSignalKitTests.xctest */, - D0445E5C1A7C446000267924 /* libSSignalKitStatic.a */, + D0085B221B282B9800EAF753 /* SwiftSignalKit.framework */, + D0085B2C1B282B9800EAF753 /* SwiftSignalKitTests.xctest */, ); name = Products; sourceTree = ""; @@ -230,60 +315,58 @@ D0445DDA1A7C2CA500267924 /* SSignalKit */ = { isa = PBXGroup; children = ( - D02AD5C81B1121010074F9C1 /* SSignal+Pipe.m */, - D02AD5C91B1121010074F9C1 /* SSignal+Pipe.h */, - D0445DF71A7C2D7300267924 /* SAtomic.h */, - D0445DF81A7C2D7300267924 /* SAtomic.m */, - D0445DF91A7C2D7300267924 /* SBag.h */, - D0445DFA1A7C2D7300267924 /* SBag.m */, - D0445DFF1A7C2D7300267924 /* SEvent.h */, - D0445E001A7C2D7300267924 /* SEvent.m */, - D0445DFE1A7C2D7300267924 /* SDisposable.h */, - D0445DFB1A7C2D7300267924 /* SBlockDisposable.h */, - D0445DF61A7C2D7300267924 /* SBlockDisposable.m */, - D0445E501A7C2DBF00267924 /* SMetaDisposable.h */, - D0445E011A7C2D7300267924 /* SMetaDisposable.m */, - D08763281A839EDC00632240 /* SDisposableSet.h */, - D08763291A839EDC00632240 /* SDisposableSet.m */, - D0445E021A7C2D7300267924 /* SMulticastSignalManager.h */, - D0445E031A7C2D7300267924 /* SMulticastSignalManager.m */, - D0445E041A7C2D7300267924 /* SSignal.h */, - D0445E051A7C2D7300267924 /* SSignal.m */, - D0445E061A7C2D7300267924 /* SSignal+Accumulate.h */, - D0445E071A7C2D7300267924 /* SSignal+Accumulate.m */, - D0445E081A7C2D7300267924 /* SSignal+Catch.h */, - D0445E091A7C2D7300267924 /* SSignal+Catch.m */, - D0445E0A1A7C2D7300267924 /* SSignal+Combine.h */, - D0445E0B1A7C2D7300267924 /* SSignal+Combine.m */, - D0445E0E1A7C2D7300267924 /* SSignal+Dispatch.h */, - D0445E0F1A7C2D7300267924 /* SSignal+Dispatch.m */, - D0445E101A7C2D7300267924 /* SSignal+Mapping.h */, - D0445E111A7C2D7300267924 /* SSignal+Mapping.m */, - D0445E121A7C2D7300267924 /* SSignal+Meta.h */, - D0445E131A7C2D7300267924 /* SSignal+Meta.m */, - D0445E141A7C2D7300267924 /* SSignal+Multicast.h */, - D0445E151A7C2D7300267924 /* SSignal+Multicast.m */, - D0445E161A7C2D7300267924 /* SSignal+SideEffects.h */, - D0445E171A7C2D7300267924 /* SSignal+SideEffects.m */, - D0445E181A7C2D7300267924 /* SSignal+Single.h */, - D0445E191A7C2D7300267924 /* SSignal+Single.m */, - D0445E1A1A7C2D7300267924 /* SSignal+Timing.h */, - D0445E1B1A7C2D7300267924 /* SSignal+Timing.m */, - D0FC5B411AF140E600F353AB /* SSignal+Take.h */, - D0FC5B421AF140E600F353AB /* SSignal+Take.m */, - D0445E1C1A7C2D7300267924 /* SSubscriber.h */, - D0445E1D1A7C2D7300267924 /* SSubscriber.m */, - D0445E1E1A7C2D7300267924 /* SThreadPool.h */, - D0445E1F1A7C2D7300267924 /* SThreadPool.m */, - D089E02F1AC48EA7009A744B /* SThreadPoolQueue.h */, - D089E02E1AC48EA7009A744B /* SThreadPoolQueue.m */, - D089E0301AC48EA7009A744B /* SThreadPoolTask.h */, - D089E02D1AC48EA7009A744B /* SThreadPoolTask.m */, - D0445E4C1A7C2D8A00267924 /* SQueue.h */, - D0445E4D1A7C2D8A00267924 /* SQueue.m */, - D0445E521A7C2E9D00267924 /* STimer.h */, - D0445E531A7C2E9D00267924 /* STimer.m */, - D0445DDD1A7C2CA500267924 /* SSignalKit.h */, + D0085AD91B28285400EAF753 /* SAtomic.h */, + D0085ADA1B28285400EAF753 /* SAtomic.m */, + D0085ADB1B28285400EAF753 /* SBag.h */, + D0085ADC1B28285400EAF753 /* SBag.m */, + D0085AD31B28285400EAF753 /* SSubscriber.h */, + D0085AC91B28285400EAF753 /* SSubscriber.m */, + D0085AD41B28285400EAF753 /* SDisposable.h */, + D0085ADF1B28285400EAF753 /* SDisposableSet.h */, + D0085AD01B28285400EAF753 /* SDisposableSet.m */, + D0085AE21B28285400EAF753 /* SMetaDisposable.h */, + D0085AD11B28285400EAF753 /* SMetaDisposable.m */, + D0085ADD1B28285400EAF753 /* SBlockDisposable.h */, + D0085ADE1B28285400EAF753 /* SBlockDisposable.m */, + D0085ACE1B28285400EAF753 /* SThreadPool.h */, + D0085AB21B28285400EAF753 /* SThreadPool.m */, + D0085ACF1B28285400EAF753 /* SThreadPoolTask.h */, + D0085ACB1B28285400EAF753 /* SThreadPoolTask.m */, + D0085ACD1B28285400EAF753 /* SThreadPoolQueue.h */, + D0085ACC1B28285400EAF753 /* SThreadPoolQueue.m */, + D0085AC61B28285400EAF753 /* SQueue.h */, + D0085AB31B28285400EAF753 /* SQueue.m */, + D0085AE51B28285400EAF753 /* STimer.h */, + D0085AE61B28285400EAF753 /* STimer.m */, + D0085AD51B28285400EAF753 /* SSignal.h */, + D0085AB81B28285400EAF753 /* SSignal.m */, + D0085AB71B28285400EAF753 /* SSignal+Single.h */, + D0085AD81B28285400EAF753 /* SSignal+Single.m */, + D0085AD61B28285400EAF753 /* SSignal+Mapping.h */, + D0085AD71B28285400EAF753 /* SSignal+Mapping.m */, + D0085ABC1B28285400EAF753 /* SSignal+Combine.h */, + D0085ABD1B28285400EAF753 /* SSignal+Combine.m */, + D0085AB61B28285400EAF753 /* SSignal+Accumulate.h */, + D0085AC51B28285400EAF753 /* SSignal+Accumulate.m */, + D0085AC01B28285400EAF753 /* SSignal+SideEffects.h */, + D0085AC11B28285400EAF753 /* SSignal+SideEffects.m */, + D0085AC41B28285400EAF753 /* SSignal+Take.h */, + D0085AB41B28285400EAF753 /* SSignal+Take.m */, + D0085AC81B28285400EAF753 /* SSignal+Timing.h */, + D0085AB11B28285400EAF753 /* SSignal+Timing.m */, + D0085AC71B28285400EAF753 /* SSignal+Meta.h */, + D0085AB51B28285400EAF753 /* SSignal+Meta.m */, + D0085ABE1B28285400EAF753 /* SSignal+Pipe.h */, + D0085ABF1B28285400EAF753 /* SSignal+Pipe.m */, + D0085AC31B28285400EAF753 /* SSignal+Catch.h */, + D0085AC21B28285400EAF753 /* SSignal+Catch.m */, + D0085AE31B28285400EAF753 /* SSignal+Dispatch.h */, + D0085ACA1B28285400EAF753 /* SSignal+Dispatch.m */, + D0085AE41B28285400EAF753 /* SSignal+Multicast.h */, + D0085AD21B28285400EAF753 /* SSignal+Multicast.m */, + D0085ABA1B28285400EAF753 /* SMulticastSignalManager.h */, + D0085ABB1B28285400EAF753 /* SMulticastSignalManager.m */, + D0085AB91B28285400EAF753 /* SSignalKit.h */, D0445DDB1A7C2CA500267924 /* Supporting Files */, ); path = SSignalKit; @@ -321,44 +404,88 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ + D0085B1F1B282B9800EAF753 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D0085B271B282B9800EAF753 /* SwiftSignalKit.h in Headers */, + D0085B4F1B282BEE00EAF753 /* SwiftSignalKit.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; D0445DD51A7C2CA500267924 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - D0445E481A7C2D7300267924 /* SSubscriber.h in Headers */, - D0445E2E1A7C2D7300267924 /* SMulticastSignalManager.h in Headers */, - D0445E271A7C2D7300267924 /* SBlockDisposable.h in Headers */, - D089E0331AC48EA7009A744B /* SThreadPoolQueue.h in Headers */, - D0445E4A1A7C2D7300267924 /* SThreadPool.h in Headers */, - D0445E541A7C2E9D00267924 /* STimer.h in Headers */, - D0445E301A7C2D7300267924 /* SSignal.h in Headers */, - D089E0341AC48EA7009A744B /* SThreadPoolTask.h in Headers */, - D0445E321A7C2D7300267924 /* SSignal+Accumulate.h in Headers */, - D0445E361A7C2D7300267924 /* SSignal+Combine.h in Headers */, - D0445E2A1A7C2D7300267924 /* SDisposable.h in Headers */, - D0FC5B431AF140E600F353AB /* SSignal+Take.h in Headers */, - D0445E421A7C2D7300267924 /* SSignal+SideEffects.h in Headers */, - D0445E3E1A7C2D7300267924 /* SSignal+Meta.h in Headers */, - D0445E2B1A7C2D7300267924 /* SEvent.h in Headers */, - D0445E341A7C2D7300267924 /* SSignal+Catch.h in Headers */, - D0445E4E1A7C2D8A00267924 /* SQueue.h in Headers */, - D0445E441A7C2D7300267924 /* SSignal+Single.h in Headers */, - D02AD5CB1B1121010074F9C1 /* SSignal+Pipe.h in Headers */, - D0445E251A7C2D7300267924 /* SBag.h in Headers */, - D0445E3A1A7C2D7300267924 /* SSignal+Dispatch.h in Headers */, - D0445E401A7C2D7300267924 /* SSignal+Multicast.h in Headers */, - D0445E511A7C2DBF00267924 /* SMetaDisposable.h in Headers */, - D0445E231A7C2D7300267924 /* SAtomic.h in Headers */, - D087632A1A839EDC00632240 /* SDisposableSet.h in Headers */, - D0445E461A7C2D7300267924 /* SSignal+Timing.h in Headers */, - D0445DDE1A7C2CA500267924 /* SSignalKit.h in Headers */, - D0445E3C1A7C2D7300267924 /* SSignal+Mapping.h in Headers */, + D0085AF61B28285400EAF753 /* SSignal+SideEffects.h in Headers */, + D0085AFD1B28285400EAF753 /* SSignal+Meta.h in Headers */, + D0085AFE1B28285400EAF753 /* SSignal+Timing.h in Headers */, + D0085B0A1B28285400EAF753 /* SDisposable.h in Headers */, + D0085B111B28285400EAF753 /* SBag.h in Headers */, + D0085AF21B28285400EAF753 /* SSignal+Combine.h in Headers */, + D0085AFA1B28285400EAF753 /* SSignal+Take.h in Headers */, + D0085B0B1B28285400EAF753 /* SSignal.h in Headers */, + D0085AED1B28285400EAF753 /* SSignal+Single.h in Headers */, + D0085AF01B28285400EAF753 /* SMulticastSignalManager.h in Headers */, + D0085AF91B28285400EAF753 /* SSignal+Catch.h in Headers */, + D0085B151B28285400EAF753 /* SDisposableSet.h in Headers */, + D0085B0C1B28285400EAF753 /* SSignal+Mapping.h in Headers */, + D0085AFC1B28285400EAF753 /* SQueue.h in Headers */, + D0085B031B28285400EAF753 /* SThreadPoolQueue.h in Headers */, + D0085B091B28285400EAF753 /* SSubscriber.h in Headers */, + D0085B041B28285400EAF753 /* SThreadPool.h in Headers */, + D0085AEC1B28285400EAF753 /* SSignal+Accumulate.h in Headers */, + D0085B1B1B28285400EAF753 /* STimer.h in Headers */, + D0085AF41B28285400EAF753 /* SSignal+Pipe.h in Headers */, + D0085B181B28285400EAF753 /* SMetaDisposable.h in Headers */, + D0085B051B28285400EAF753 /* SThreadPoolTask.h in Headers */, + D0085B1A1B28285400EAF753 /* SSignal+Multicast.h in Headers */, + D0085B191B28285400EAF753 /* SSignal+Dispatch.h in Headers */, + D0085AEF1B28285400EAF753 /* SSignalKit.h in Headers */, + D0085B131B28285400EAF753 /* SBlockDisposable.h in Headers */, + D0085B0F1B28285400EAF753 /* SAtomic.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + D0085B211B282B9800EAF753 /* SwiftSignalKit */ = { + isa = PBXNativeTarget; + buildConfigurationList = D0085B351B282B9800EAF753 /* Build configuration list for PBXNativeTarget "SwiftSignalKit" */; + buildPhases = ( + D0085B1D1B282B9800EAF753 /* Sources */, + D0085B1E1B282B9800EAF753 /* Frameworks */, + D0085B1F1B282B9800EAF753 /* Headers */, + D0085B201B282B9800EAF753 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SwiftSignalKit; + productName = SwiftSignalKit; + productReference = D0085B221B282B9800EAF753 /* SwiftSignalKit.framework */; + productType = "com.apple.product-type.framework"; + }; + D0085B2B1B282B9800EAF753 /* SwiftSignalKitTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D0085B381B282B9800EAF753 /* Build configuration list for PBXNativeTarget "SwiftSignalKitTests" */; + buildPhases = ( + D0085B281B282B9800EAF753 /* Sources */, + D0085B291B282B9800EAF753 /* Frameworks */, + D0085B2A1B282B9800EAF753 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D0085B2F1B282B9800EAF753 /* PBXTargetDependency */, + ); + name = SwiftSignalKitTests; + productName = SwiftSignalKitTests; + productReference = D0085B2C1B282B9800EAF753 /* SwiftSignalKitTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; D0445DD71A7C2CA500267924 /* SSignalKit */ = { isa = PBXNativeTarget; buildConfigurationList = D0445DEE1A7C2CA500267924 /* Build configuration list for PBXNativeTarget "SSignalKit" */; @@ -395,23 +522,6 @@ productReference = D0445DE31A7C2CA500267924 /* SSignalKitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - D0445E5B1A7C446000267924 /* SSignalKitStatic */ = { - isa = PBXNativeTarget; - buildConfigurationList = D0445E6D1A7C446000267924 /* Build configuration list for PBXNativeTarget "SSignalKitStatic" */; - buildPhases = ( - D0445E581A7C446000267924 /* Sources */, - D0445E591A7C446000267924 /* Frameworks */, - D0445E5A1A7C446000267924 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = SSignalKitStatic; - productName = SSignalKitStatic; - productReference = D0445E5C1A7C446000267924 /* libSSignalKitStatic.a */; - productType = "com.apple.product-type.library.static"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -421,15 +531,18 @@ LastUpgradeCheck = 0610; ORGANIZATIONNAME = Telegram; TargetAttributes = { + D0085B211B282B9800EAF753 = { + CreatedOnToolsVersion = 6.3.1; + }; + D0085B2B1B282B9800EAF753 = { + CreatedOnToolsVersion = 6.3.1; + }; D0445DD71A7C2CA500267924 = { CreatedOnToolsVersion = 6.1.1; }; D0445DE21A7C2CA500267924 = { CreatedOnToolsVersion = 6.1.1; }; - D0445E5B1A7C446000267924 = { - CreatedOnToolsVersion = 6.1.1; - }; }; }; buildConfigurationList = D0445DD21A7C2CA500267924 /* Build configuration list for PBXProject "SSignalKit" */; @@ -445,13 +558,28 @@ projectRoot = ""; targets = ( D0445DD71A7C2CA500267924 /* SSignalKit */, - D0445E5B1A7C446000267924 /* SSignalKitStatic */, D0445DE21A7C2CA500267924 /* SSignalKitTests */, + D0085B211B282B9800EAF753 /* SwiftSignalKit */, + D0085B2B1B282B9800EAF753 /* SwiftSignalKitTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + D0085B201B282B9800EAF753 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D0085B2A1B282B9800EAF753 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; D0445DD61A7C2CA500267924 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -469,36 +597,71 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + D0085B1D1B282B9800EAF753 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D0085B521B282BEE00EAF753 /* Signal_Dispatch.swift in Sources */, + D0085B561B282BEE00EAF753 /* Pipe.swift in Sources */, + D0085B551B282BEE00EAF753 /* Queue.swift in Sources */, + D0085B591B282BEE00EAF753 /* Signal_Catch.swift in Sources */, + D0085B601B282BEE00EAF753 /* Disposable.swift in Sources */, + D0085B531B282BEE00EAF753 /* ThreadPool.swift in Sources */, + D0085B5F1B282BEE00EAF753 /* Signal.swift in Sources */, + D0085B5E1B282BEE00EAF753 /* Signal_Reduce.swift in Sources */, + D0085B621B282BEE00EAF753 /* Subscriber.swift in Sources */, + D0085B581B282BEE00EAF753 /* Signal_Take.swift in Sources */, + D0085B501B282BEE00EAF753 /* Signal_Timing.swift in Sources */, + D0085B541B282BEE00EAF753 /* Timer.swift in Sources */, + D0085B5B1B282BEE00EAF753 /* Signal_Meta.swift in Sources */, + D0085B571B282BEE00EAF753 /* Bag.swift in Sources */, + D0085B5A1B282BEE00EAF753 /* Signal_Single.swift in Sources */, + D0085B611B282BEE00EAF753 /* Signal_Mapping.swift in Sources */, + D0085B5C1B282BEE00EAF753 /* Signal_Combine.swift in Sources */, + D0085B5D1B282BEE00EAF753 /* Atomic.swift in Sources */, + D0085B511B282BEE00EAF753 /* Signal_SideEffects.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D0085B281B282B9800EAF753 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D0085B671B282C2800EAF753 /* DeallocatingObject.swift in Sources */, + D0085B681B282C2800EAF753 /* SwiftSignalKitBasicTests.swift in Sources */, + D0085B661B282C2800EAF753 /* SwiftSignalKitFunctionsTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; D0445DD31A7C2CA500267924 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D0445E451A7C2D7300267924 /* SSignal+Single.m in Sources */, - D0445E2D1A7C2D7300267924 /* SMetaDisposable.m in Sources */, - D0445E3B1A7C2D7300267924 /* SSignal+Dispatch.m in Sources */, - D02AD5CA1B1121010074F9C1 /* SSignal+Pipe.m in Sources */, - D0445E4F1A7C2D8A00267924 /* SQueue.m in Sources */, - D0445E241A7C2D7300267924 /* SAtomic.m in Sources */, - D0445E4B1A7C2D7300267924 /* SThreadPool.m in Sources */, - D0445E551A7C2E9D00267924 /* STimer.m in Sources */, - D089E0321AC48EA7009A744B /* SThreadPoolQueue.m in Sources */, - D0445E3D1A7C2D7300267924 /* SSignal+Mapping.m in Sources */, - D0445E351A7C2D7300267924 /* SSignal+Catch.m in Sources */, - D0445E411A7C2D7300267924 /* SSignal+Multicast.m in Sources */, - D0445E2C1A7C2D7300267924 /* SEvent.m in Sources */, - D0445E261A7C2D7300267924 /* SBag.m in Sources */, - D0445E331A7C2D7300267924 /* SSignal+Accumulate.m in Sources */, - D0445E471A7C2D7300267924 /* SSignal+Timing.m in Sources */, - D0445E311A7C2D7300267924 /* SSignal.m in Sources */, - D087632B1A839EDC00632240 /* SDisposableSet.m in Sources */, - D0FC5B441AF140E600F353AB /* SSignal+Take.m in Sources */, - D089E0311AC48EA7009A744B /* SThreadPoolTask.m in Sources */, - D0445E491A7C2D7300267924 /* SSubscriber.m in Sources */, - D0445E431A7C2D7300267924 /* SSignal+SideEffects.m in Sources */, - D0445E3F1A7C2D7300267924 /* SSignal+Meta.m in Sources */, - D0445E371A7C2D7300267924 /* SSignal+Combine.m in Sources */, - D0445E2F1A7C2D7300267924 /* SMulticastSignalManager.m in Sources */, - D0445E221A7C2D7300267924 /* SBlockDisposable.m in Sources */, + D0085AE91B28285400EAF753 /* SQueue.m in Sources */, + D0085B141B28285400EAF753 /* SBlockDisposable.m in Sources */, + D0085B001B28285400EAF753 /* SSignal+Dispatch.m in Sources */, + D0085AE71B28285400EAF753 /* SSignal+Timing.m in Sources */, + D0085AEB1B28285400EAF753 /* SSignal+Meta.m in Sources */, + D0085B0D1B28285400EAF753 /* SSignal+Mapping.m in Sources */, + D0085AF81B28285400EAF753 /* SSignal+Catch.m in Sources */, + D0085AF11B28285400EAF753 /* SMulticastSignalManager.m in Sources */, + D0085B071B28285400EAF753 /* SMetaDisposable.m in Sources */, + D0085B101B28285400EAF753 /* SAtomic.m in Sources */, + D0085B121B28285400EAF753 /* SBag.m in Sources */, + D0085AEE1B28285400EAF753 /* SSignal.m in Sources */, + D0085B021B28285400EAF753 /* SThreadPoolQueue.m in Sources */, + D0085AFF1B28285400EAF753 /* SSubscriber.m in Sources */, + D0085B081B28285400EAF753 /* SSignal+Multicast.m in Sources */, + D0085B1C1B28285400EAF753 /* STimer.m in Sources */, + D0085AF51B28285400EAF753 /* SSignal+Pipe.m in Sources */, + D0085AF31B28285400EAF753 /* SSignal+Combine.m in Sources */, + D0085AF71B28285400EAF753 /* SSignal+SideEffects.m in Sources */, + D0085AEA1B28285400EAF753 /* SSignal+Take.m in Sources */, + D0085B061B28285400EAF753 /* SDisposableSet.m in Sources */, + D0085AE81B28285400EAF753 /* SThreadPool.m in Sources */, + D0085B011B28285400EAF753 /* SThreadPoolTask.m in Sources */, + D0085B0E1B28285400EAF753 /* SSignal+Single.m in Sources */, + D0085AFB1B28285400EAF753 /* SSignal+Accumulate.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -513,41 +676,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - D0445E581A7C446000267924 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D0445E841A7C447D00267924 /* SSignal+Single.m in Sources */, - D0445E781A7C447D00267924 /* SMetaDisposable.m in Sources */, - D0445E7F1A7C447D00267924 /* SSignal+Dispatch.m in Sources */, - D0445E881A7C447D00267924 /* SQueue.m in Sources */, - D089E03A1AC56981009A744B /* SThreadPoolTask.m in Sources */, - D0445E741A7C447D00267924 /* SAtomic.m in Sources */, - D0445E871A7C447D00267924 /* SThreadPool.m in Sources */, - D0445E891A7C447D00267924 /* STimer.m in Sources */, - D0445E801A7C447D00267924 /* SSignal+Mapping.m in Sources */, - D0445E7C1A7C447D00267924 /* SSignal+Catch.m in Sources */, - D0445E821A7C447D00267924 /* SSignal+Multicast.m in Sources */, - D0445E771A7C447D00267924 /* SEvent.m in Sources */, - D0445E751A7C447D00267924 /* SBag.m in Sources */, - D089E0391AC56981009A744B /* SThreadPoolQueue.m in Sources */, - D0445E7B1A7C447D00267924 /* SSignal+Accumulate.m in Sources */, - D0445E851A7C447D00267924 /* SSignal+Timing.m in Sources */, - D0445E7A1A7C447D00267924 /* SSignal.m in Sources */, - D0FC5B451AF141F800F353AB /* SSignal+Take.m in Sources */, - D087632C1A839EE800632240 /* SDisposableSet.m in Sources */, - D0445E861A7C447D00267924 /* SSubscriber.m in Sources */, - D0445E831A7C447D00267924 /* SSignal+SideEffects.m in Sources */, - D0445E811A7C447D00267924 /* SSignal+Meta.m in Sources */, - D0445E7D1A7C447D00267924 /* SSignal+Combine.m in Sources */, - D0445E791A7C447D00267924 /* SMulticastSignalManager.m in Sources */, - D0445E731A7C447D00267924 /* SBlockDisposable.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + D0085B2F1B282B9800EAF753 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D0085B211B282B9800EAF753 /* SwiftSignalKit */; + targetProxy = D0085B2E1B282B9800EAF753 /* PBXContainerItemProxy */; + }; D0445DE61A7C2CA500267924 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = D0445DD71A7C2CA500267924 /* SSignalKit */; @@ -556,6 +692,85 @@ /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ + D0085B361B282B9800EAF753 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = SwiftSignalKit/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + D0085B371B282B9800EAF753 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = SwiftSignalKit/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Release; + }; + D0085B391B282B9800EAF753 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = SwiftSignalKitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D0085B3A1B282B9800EAF753 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = SwiftSignalKitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; D0445DEC1A7C2CA500267924 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -717,32 +932,25 @@ }; name = Release; }; - D0445E6E1A7C446000267924 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - ONLY_ACTIVE_ARCH = NO; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - D0445E6F1A7C446000267924 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + D0085B351B282B9800EAF753 /* Build configuration list for PBXNativeTarget "SwiftSignalKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0085B361B282B9800EAF753 /* Debug */, + D0085B371B282B9800EAF753 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; + D0085B381B282B9800EAF753 /* Build configuration list for PBXNativeTarget "SwiftSignalKitTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0085B391B282B9800EAF753 /* Debug */, + D0085B3A1B282B9800EAF753 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; D0445DD21A7C2CA500267924 /* Build configuration list for PBXProject "SSignalKit" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -770,15 +978,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - D0445E6D1A7C446000267924 /* Build configuration list for PBXNativeTarget "SSignalKitStatic" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D0445E6E1A7C446000267924 /* Debug */, - D0445E6F1A7C446000267924 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = D0445DCF1A7C2CA500267924 /* Project object */; diff --git a/SSignalKit/SBlockDisposable.h b/SSignalKit/SBlockDisposable.h index 0d130881dd..2914604cba 100644 --- a/SSignalKit/SBlockDisposable.h +++ b/SSignalKit/SBlockDisposable.h @@ -1,4 +1,4 @@ -#import "SDisposable.h" +#import @interface SBlockDisposable : NSObject diff --git a/SSignalKit/SDisposableSet.h b/SSignalKit/SDisposableSet.h index 37924832e6..9cade19504 100644 --- a/SSignalKit/SDisposableSet.h +++ b/SSignalKit/SDisposableSet.h @@ -1,4 +1,4 @@ -#import "SDisposable.h" +#import @interface SDisposableSet : NSObject diff --git a/SSignalKit/SEvent.h b/SSignalKit/SEvent.h deleted file mode 100644 index 7ff523b26b..0000000000 --- a/SSignalKit/SEvent.h +++ /dev/null @@ -1,18 +0,0 @@ -#import - -typedef enum { - SEventTypeNext, - SEventTypeError, - SEventTypeCompleted -} SEventType; - -@interface SEvent : NSObject - -@property (nonatomic, readonly) SEventType type; -@property (nonatomic, strong, readonly) id data; - -- (instancetype)initWithNext:(id)next; -- (instancetype)initWithError:(id)error; -- (instancetype)initWithCompleted; - -@end diff --git a/SSignalKit/SEvent.m b/SSignalKit/SEvent.m deleted file mode 100644 index c3d296633e..0000000000 --- a/SSignalKit/SEvent.m +++ /dev/null @@ -1,37 +0,0 @@ -#import "SEvent.h" - -@implementation SEvent - -- (instancetype)initWithNext:(id)next -{ - self = [super init]; - if (self != nil) - { - _type = SEventTypeNext; - _data = next; - } - return self; -} - -- (instancetype)initWithError:(id)error -{ - self = [super init]; - if (self != nil) - { - _type = SEventTypeError; - _data = error; - } - return self; -} - -- (instancetype)initWithCompleted -{ - self = [super init]; - if (self != nil) - { - _type = SEventTypeCompleted; - } - return self; -} - -@end diff --git a/SSignalKit/SMetaDisposable.h b/SSignalKit/SMetaDisposable.h index b0ce2ce5db..8938f9eacb 100644 --- a/SSignalKit/SMetaDisposable.h +++ b/SSignalKit/SMetaDisposable.h @@ -1,4 +1,4 @@ -#import "SDisposable.h" +#import @interface SMetaDisposable : NSObject diff --git a/SSignalKit/SMulticastSignalManager.h b/SSignalKit/SMulticastSignalManager.h index 7d7391b8f2..243f015a52 100644 --- a/SSignalKit/SMulticastSignalManager.h +++ b/SSignalKit/SMulticastSignalManager.h @@ -1,4 +1,4 @@ -#import "SSignal.h" +#import @interface SMulticastSignalManager : NSObject diff --git a/SSignalKit/SSignal+Accumulate.h b/SSignalKit/SSignal+Accumulate.h index 9b0e8e9d47..1ea8a51ed0 100644 --- a/SSignalKit/SSignal+Accumulate.h +++ b/SSignalKit/SSignal+Accumulate.h @@ -1,4 +1,4 @@ -#import "SSignal.h" +#import @interface SSignal (Accumulate) diff --git a/SSignalKit/SSignal+Catch.h b/SSignalKit/SSignal+Catch.h index ced7b7e1db..5cbdad90c9 100644 --- a/SSignalKit/SSignal+Catch.h +++ b/SSignalKit/SSignal+Catch.h @@ -1,4 +1,4 @@ -#import "SSignal.h" +#import @interface SSignal (Catch) diff --git a/SSignalKit/SSignal+Combine.h b/SSignalKit/SSignal+Combine.h index 95ddb7bd84..d84e065311 100644 --- a/SSignalKit/SSignal+Combine.h +++ b/SSignalKit/SSignal+Combine.h @@ -1,4 +1,4 @@ -#import "SSignal.h" +#import @interface SSignal (Combine) diff --git a/SSignalKit/SSignal+Dispatch.h b/SSignalKit/SSignal+Dispatch.h index 17d74ab452..4b23e0d38a 100644 --- a/SSignalKit/SSignal+Dispatch.h +++ b/SSignalKit/SSignal+Dispatch.h @@ -1,7 +1,7 @@ -#import "SSignal.h" +#import -#import "SQueue.h" -#import "SThreadPool.h" +#import +#import @interface SSignal (Dispatch) diff --git a/SSignalKit/SSignal+Mapping.h b/SSignalKit/SSignal+Mapping.h index 751f72a1e0..d9e810b78a 100644 --- a/SSignalKit/SSignal+Mapping.h +++ b/SSignalKit/SSignal+Mapping.h @@ -1,4 +1,4 @@ -#import "SSignal.h" +#import @interface SSignal (Mapping) diff --git a/SSignalKit/SSignal+Meta.h b/SSignalKit/SSignal+Meta.h index 42c438622d..0aca7db8d7 100644 --- a/SSignalKit/SSignal+Meta.h +++ b/SSignalKit/SSignal+Meta.h @@ -1,4 +1,4 @@ -#import "SSignal.h" +#import @class SQueue; diff --git a/SSignalKit/SSignal+Meta.m b/SSignalKit/SSignal+Meta.m index 76f411817b..2f0ca89633 100644 --- a/SSignalKit/SSignal+Meta.m +++ b/SSignalKit/SSignal+Meta.m @@ -19,7 +19,6 @@ NSMutableArray *_queuedSignals; bool _queueMode; - } @end diff --git a/SSignalKit/SSignal+Multicast.h b/SSignalKit/SSignal+Multicast.h index 3d3c4fc4e5..e0720cc103 100644 --- a/SSignalKit/SSignal+Multicast.h +++ b/SSignalKit/SSignal+Multicast.h @@ -1,4 +1,4 @@ -#import "SSignal.h" +#import @interface SSignal (Multicast) diff --git a/SSignalKit/SSignal+Multicast.m b/SSignalKit/SSignal+Multicast.m index 3fe3a6f789..92976cff4a 100644 --- a/SSignalKit/SSignal+Multicast.m +++ b/SSignalKit/SSignal+Multicast.m @@ -80,29 +80,44 @@ typedef enum { [currentDisposable dispose]; } -- (void)notify:(SEvent *)event +- (void)notifyNext:(id)next { NSArray *currentSubscribers = nil; OSSpinLockLock(&_lock); currentSubscribers = [_subscribers copyItems]; - if (event.type != SEventTypeNext) - _state = SSignalMulticastStateCompleted; OSSpinLockUnlock(&_lock); for (SSubscriber *subscriber in currentSubscribers) { - switch (event.type) - { - case SEventTypeNext: - [subscriber putNext:event.data]; - break; - case SEventTypeError: - [subscriber putError:event.data]; - break; - case SEventTypeCompleted: - [subscriber putCompletion]; - break; - } + [subscriber putNext:next]; + } +} + +- (void)notifyError:(id)error +{ + NSArray *currentSubscribers = nil; + OSSpinLockLock(&_lock); + currentSubscribers = [_subscribers copyItems]; + _state = SSignalMulticastStateCompleted; + OSSpinLockUnlock(&_lock); + + for (SSubscriber *subscriber in currentSubscribers) + { + [subscriber putError:error]; + } +} + +- (void)notifyCompleted +{ + NSArray *currentSubscribers = nil; + OSSpinLockLock(&_lock); + currentSubscribers = [_subscribers copyItems]; + _state = SSignalMulticastStateCompleted; + OSSpinLockUnlock(&_lock); + + for (SSubscriber *subscriber in currentSubscribers) + { + [subscriber putCompletion]; } } @@ -121,13 +136,13 @@ typedef enum { { id disposable = [self startWithNext:^(id next) { - [subscribers notify:[[SEvent alloc] initWithNext:next]]; + [subscribers notifyNext:next]; } error:^(id error) { - [subscribers notify:[[SEvent alloc] initWithError:error]]; + [subscribers notifyError:error]; } completed:^ { - [subscribers notify:[[SEvent alloc] initWithCompleted]]; + [subscribers notifyCompleted]; }]; [subscribers setDisposable:[[SBlockDisposable alloc] initWithBlock:^ diff --git a/SSignalKit/SSignal+SideEffects.h b/SSignalKit/SSignal+SideEffects.h index 7b58754062..0eead9dcd5 100644 --- a/SSignalKit/SSignal+SideEffects.h +++ b/SSignalKit/SSignal+SideEffects.h @@ -1,4 +1,4 @@ -#import "SSignal.h" +#import @interface SSignal (SideEffects) diff --git a/SSignalKit/SSignal+Single.h b/SSignalKit/SSignal+Single.h index 8ce640da5e..75f48ff569 100644 --- a/SSignalKit/SSignal+Single.h +++ b/SSignalKit/SSignal+Single.h @@ -1,4 +1,4 @@ -#import "SSignal.h" +#import @interface SSignal (Single) diff --git a/SSignalKit/SSignal+Timing.h b/SSignalKit/SSignal+Timing.h index 68c0fe6ca8..4b5d50c90e 100644 --- a/SSignalKit/SSignal+Timing.h +++ b/SSignalKit/SSignal+Timing.h @@ -1,6 +1,6 @@ -#import "SSignal.h" +#import -#import "SQueue.h" +#import @interface SSignal (Timing) diff --git a/SSignalKit/SSignal.h b/SSignalKit/SSignal.h index c3e00ad9fb..d85fa9d3ea 100644 --- a/SSignalKit/SSignal.h +++ b/SSignalKit/SSignal.h @@ -1,4 +1,4 @@ -#import "SSubscriber.h" +#import @interface SSignal : NSObject { diff --git a/SSignalKit/SSignalKit.h b/SSignalKit/SSignalKit.h index 142eabd2f0..fd17f141ad 100644 --- a/SSignalKit/SSignalKit.h +++ b/SSignalKit/SSignalKit.h @@ -19,7 +19,6 @@ FOUNDATION_EXPORT const unsigned char SSignalKitVersionString[]; #import #import #import -#import #import #import #import diff --git a/SSignalKit/SSubscriber.h b/SSignalKit/SSubscriber.h index 2689f6c566..37d3368c67 100644 --- a/SSignalKit/SSubscriber.h +++ b/SSignalKit/SSubscriber.h @@ -1,5 +1,4 @@ -#import "SDisposable.h" -#import "SEvent.h" +#import @interface SSubscriber : NSObject { diff --git a/SwiftSignalKit/Atomic.swift b/SwiftSignalKit/Atomic.swift new file mode 100644 index 0000000000..ae7dd94ab4 --- /dev/null +++ b/SwiftSignalKit/Atomic.swift @@ -0,0 +1,36 @@ +import Foundation + +public final class Atomic { + private var lock: OSSpinLock = 0 + private var value: T + + public init(value: T) { + self.value = value + } + + public func with(f: T -> R) -> R { + OSSpinLockLock(&self.lock) + let result = f(self.value) + OSSpinLockUnlock(&self.lock) + + return result + } + + public func modify(f: T -> T) -> T { + OSSpinLockLock(&self.lock) + let result = f(self.value) + self.value = result + OSSpinLockUnlock(&self.lock) + + return result + } + + public func swap(value: T) -> T { + OSSpinLockLock(&self.lock) + let previous = self.value + self.value = value + OSSpinLockUnlock(&self.lock) + + return previous + } +} diff --git a/SwiftSignalKit/Bag.swift b/SwiftSignalKit/Bag.swift new file mode 100644 index 0000000000..b3906960c4 --- /dev/null +++ b/SwiftSignalKit/Bag.swift @@ -0,0 +1,33 @@ +import Foundation + +public final class Bag { + public typealias Index = Int + private var nextIndex: Index = 0 + private var items: [T] = [] + private var itemKeys: [Index] = [] + + public func add(item: T) -> Index { + let key = self.nextIndex + self.nextIndex++ + self.items.append(item) + self.itemKeys.append(key) + + return key + } + + public func remove(index: Index) { + var i = 0 + for key in self.itemKeys { + if key == index { + self.items.removeAtIndex(i) + self.itemKeys.removeAtIndex(i) + break + } + i++ + } + } + + public func copyItems() -> [T] { + return self.items + } +} diff --git a/SwiftSignalKit/Disposable.swift b/SwiftSignalKit/Disposable.swift new file mode 100644 index 0000000000..2efd074979 --- /dev/null +++ b/SwiftSignalKit/Disposable.swift @@ -0,0 +1,129 @@ +import Foundation + +public protocol Disposable +{ + func dispose() +} + +internal struct _EmptyDisposable : Disposable { + internal func dispose() { + } +} + +public let EmptyDisposable: Disposable = _EmptyDisposable() + +public final class ActionDisposable : Disposable +{ + private var action: () -> Void + private var lock: OSSpinLock = 0 + + public init(action: () -> Void) { + self.action = action + } + + public func dispose() { + var action = doNothing + OSSpinLockLock(&self.lock) + action = self.action + self.action = doNothing + OSSpinLockUnlock(&self.lock) + action() + } +} + +public final class MetaDisposable : Disposable +{ + private var lock: OSSpinLock = 0 + private var disposed = false + private var disposable: Disposable! = nil + + public init() { + } + + public func set(disposable: Disposable?) { + var previousDisposable: Disposable! = nil + var disposeImmediately = false + + OSSpinLockLock(&self.lock) + disposeImmediately = self.disposed + if !disposeImmediately { + previousDisposable = self.disposable + if let disposable = disposable { + self.disposable = disposable + } else { + self.disposable = nil + } + } + OSSpinLockUnlock(&self.lock) + + if previousDisposable != nil { + previousDisposable.dispose() + } + + if disposeImmediately { + if let disposable = disposable { + disposable.dispose() + } + } + } + + public func dispose() + { + var disposable: Disposable! = nil + + OSSpinLockLock(&self.lock) + if !self.disposed { + self.disposed = true + disposable = self.disposable + self.disposable = nil + } + OSSpinLockUnlock(&self.lock) + + if disposable != nil { + disposable.dispose() + } + } +} + +public final class DisposableSet : Disposable { + private var lock: OSSpinLock = 0 + private var disposed = false + private var disposables: [Disposable] = [] + + public init() { + + } + + public func add(disposable: Disposable) { + var disposeImmediately = false + + OSSpinLockLock(&self.lock) + if self.disposed { + disposeImmediately = true + } else { + self.disposables.append(disposable) + } + OSSpinLockUnlock(&self.lock) + + if disposeImmediately { + disposable.dispose() + } + } + + public func dispose() { + var disposables: [Disposable] = [] + OSSpinLockLock(&self.lock) + if !self.disposed { + self.disposed = true + disposables = self.disposables + self.disposables = [] + } + OSSpinLockUnlock(&self.lock) + + if disposables.count != 0 { + for disposable in disposables { + disposable.dispose() + } + } + } +} diff --git a/SwiftSignalKit/Info.plist b/SwiftSignalKit/Info.plist new file mode 100644 index 0000000000..f6228f96e7 --- /dev/null +++ b/SwiftSignalKit/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.telegram.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/SwiftSignalKit/Pipe.swift b/SwiftSignalKit/Pipe.swift new file mode 100644 index 0000000000..c5d8d7b376 --- /dev/null +++ b/SwiftSignalKit/Pipe.swift @@ -0,0 +1,40 @@ +import Foundation + +public final class Pipe { + let subscribers = Atomic(value: Bag Void>()) + + public init() { + + } + + public func signal() -> Signal { + return Signal { [weak self] subscriber in + if let strongSelf = self { + var index = strongSelf.subscribers.with { value -> Bag.Index in + return value.add { next in + subscriber.putNext(next) + } + } + + return ActionDisposable { [weak strongSelf] in + if let strongSelf = strongSelf { + strongSelf.subscribers.with { value -> Void in + value.remove(index) + } + } + } + } else { + return EmptyDisposable + } + } + } + + public func putNext(next: T) { + let items = self.subscribers.with { value -> [T -> Void] in + return value.copyItems() + } + for f in items { + f(next) + } + } +} diff --git a/SwiftSignalKit/Queue.swift b/SwiftSignalKit/Queue.swift new file mode 100644 index 0000000000..9245ce58cc --- /dev/null +++ b/SwiftSignalKit/Queue.swift @@ -0,0 +1,69 @@ +import Foundation + +private let _QueueSpecificKey = NSObject() +private let QueueSpecificKey: UnsafePointer = UnsafePointer(Unmanaged.passUnretained(_QueueSpecificKey).toOpaque()) + +public final class Queue { + private let nativeQueue: dispatch_queue_t + private var specific: UnsafeMutablePointer + private let specialIsMainQueue: Bool + + public var queue: dispatch_queue_t { + get { + return self.nativeQueue + } + } + + public class func mainQueue() -> Queue { + return Queue(queue: dispatch_get_main_queue(), specialIsMainQueue: true) + } + + public class func concurrentDefaultQueue() -> Queue { + return Queue(queue: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), specialIsMainQueue: false) + } + + public class func concurrentBackgroundQueue() -> Queue { + return Queue(queue: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), specialIsMainQueue: false) + } + + public init(queue: dispatch_queue_t) { + self.nativeQueue = queue + self.specific = nil + self.specialIsMainQueue = false + } + + private init(queue: dispatch_queue_t, specialIsMainQueue: Bool) { + self.nativeQueue = queue + self.specific = nil + self.specialIsMainQueue = specialIsMainQueue + } + + public init() { + self.nativeQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL) + self.specific = nil + self.specialIsMainQueue = false + + self.specific = UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque()) + dispatch_queue_set_specific(self.nativeQueue, QueueSpecificKey, self.specific, nil) + } + + public func async(f: Void -> Void) { + if self.specific != nil && dispatch_get_specific(QueueSpecificKey) == self.specific { + f() + } else if self.specialIsMainQueue && NSThread.isMainThread() { + f() + } else { + dispatch_async(self.nativeQueue, f) + } + } + + public func dispatch(f: Void -> Void) { + if self.specific != nil && dispatch_get_specific(QueueSpecificKey) == self.specific { + f() + } else if self.specialIsMainQueue && NSThread.isMainThread() { + f() + } else { + dispatch_async(self.nativeQueue, f) + } + } +} diff --git a/SwiftSignalKit/Signal.swift b/SwiftSignalKit/Signal.swift new file mode 100644 index 0000000000..14de82b28e --- /dev/null +++ b/SwiftSignalKit/Signal.swift @@ -0,0 +1,43 @@ +import Foundation + +internal let doNothing: () -> Void = { _ in } + +public func identity(a: A) -> A { + return a; +} + +infix operator |> { associativity left precedence 95 } + +public func |> (value: T, function: (T -> U)) -> U { + return function(value) +} + +private final class SubscriberDisposable : Disposable { + private let subscriber: Subscriber + private let disposable: Disposable + + init(subscriber: Subscriber, disposable: Disposable) { + self.subscriber = subscriber + self.disposable = disposable + } + + func dispose() { + subscriber.markTerminatedWithoutDisposal() + disposable.dispose() + } +} + +public struct Signal { + private let generator: Subscriber -> Disposable + + public init(_ generator: Subscriber -> Disposable) { + self.generator = generator + } + + public func start(next: (T -> Void)! = nil, error: (E -> Void)! = nil, completed: (() -> Void)! = nil) -> Disposable { + let subscriber = Subscriber(next: next, error: error, completed: completed) + let disposable = self.generator(subscriber) + subscriber.assignDisposable(disposable) + return SubscriberDisposable(subscriber: subscriber, disposable: disposable) + } +} diff --git a/SwiftSignalKit/Signal_Catch.swift b/SwiftSignalKit/Signal_Catch.swift new file mode 100644 index 0000000000..3aa10366b7 --- /dev/null +++ b/SwiftSignalKit/Signal_Catch.swift @@ -0,0 +1,61 @@ +import Foundation + +public func catch(f: E -> Signal)(signal: Signal) -> Signal { + return Signal { subscriber in + let disposable = DisposableSet() + + disposable.add(signal.start(next: { next in + subscriber.putNext(next) + }, error: { error in + let anotherSignal = f(error) + + disposable.add(anotherSignal.start(next: { next in + subscriber.putNext(next) + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putCompletion() + })) + }, completed: { + subscriber.putCompletion() + })) + + return disposable + } +} + +private func recursiveFunction(f: (Void -> Void) -> Void) -> (Void -> Void) { + return { + f(recursiveFunction(f)) + } +} + +public func restart(signal: Signal) -> Signal { + return Signal { subscriber in + let shouldRestart = Atomic(value: true) + let currentDisposable = MetaDisposable() + + let start = recursiveFunction { recurse in + let currentShouldRestart = shouldRestart.with { value in + return value + } + if currentShouldRestart { + let disposable = signal.start(next: { next in + subscriber.putNext(next) + }, error: { error in + subscriber.putError(error) + }, completed: { + recurse() + }) + currentDisposable.set(disposable) + } + } + + start() + + return ActionDisposable { + currentDisposable.dispose() + shouldRestart.swap(false) + } + } +} diff --git a/SwiftSignalKit/Signal_Combine.swift b/SwiftSignalKit/Signal_Combine.swift new file mode 100644 index 0000000000..e73d881fdd --- /dev/null +++ b/SwiftSignalKit/Signal_Combine.swift @@ -0,0 +1,91 @@ +import Foundation + +private struct SignalCombineState { + let values: [Int : Any] + let completed: Set + let error: Bool +} + +private func combineLatestAny(signals: [Signal], combine: [Any] -> R) -> Signal { + return Signal { subscriber in + + let state = Atomic(value: SignalCombineState(values: [:], completed: Set(), error: false)) + let disposable = DisposableSet() + + let count = signals.count + for index in 0 ..< count { + let signalDisposable = signals[index].start(next: { next in + let currentState = state.modify { current in + var values = current.values + values[index] = next + return SignalCombineState(values: values, completed: current.completed, error: current.error) + } + if currentState.values.count == count { + var values: [Any] = [] + for i in 0 ..< count { + values.append(currentState.values[i]!) + } + subscriber.putNext(combine(values)) + } + }, error: { error in + var emitError = false + state.modify { current in + if !current.error { + emitError = true + return SignalCombineState(values: current.values, completed: current.completed, error: true) + } else { + return current + } + } + }, completed: { + var emitCompleted = false + state.modify { current in + if !current.completed.contains(index) { + var completed = current.completed + completed.insert(index) + emitCompleted = completed.count == count + return SignalCombineState(values: current.values, completed: completed, error: current.error) + } + return current + } + if emitCompleted { + subscriber.putCompletion() + } + }) + + disposable.add(signalDisposable) + } + + return disposable; + } +} + +private func signalOfAny(signal: Signal) -> Signal { + return Signal { subscriber in + return signal.start(next: { next in + subscriber.putNext(next) + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putCompletion() + }) + } +} + +public func combineLatest(s1: Signal, s2: Signal) -> Signal<(T1, T2), E> { + return combineLatestAny([signalOfAny(s1), signalOfAny(s2)], { values in + return (values[0] as! T1, values[1] as! T2) + }) +} + +public func combineLatest(s1: Signal, s2: Signal, s3: Signal) -> Signal<(T1, T2, T3), E> { + return combineLatestAny([signalOfAny(s1), signalOfAny(s2), signalOfAny(s3)], { values in + return (values[0] as! T1, values[1] as! T2, values[2] as! T3) + }) +} + +public func combineLatest(s1: Signal, s2: Signal, s3: Signal, s4: Signal) -> Signal<(T1, T2, T3, T4), E> { + return combineLatestAny([signalOfAny(s1), signalOfAny(s2), signalOfAny(s3), signalOfAny(s4)], { values in + return (values[0] as! T1, values[1] as! T2, values[2] as! T3, values[3] as! T4) + }) +} diff --git a/SwiftSignalKit/Signal_Dispatch.swift b/SwiftSignalKit/Signal_Dispatch.swift new file mode 100644 index 0000000000..f9cbf2f67a --- /dev/null +++ b/SwiftSignalKit/Signal_Dispatch.swift @@ -0,0 +1,77 @@ +import Foundation + +public func deliverOn(queue: Queue)(signal: Signal) -> Signal { + return Signal { subscriber in + return signal.start(next: { next in + queue.dispatch { + subscriber.putNext(next) + } + }, error: { error in + queue.dispatch { + subscriber.putError(error) + } + }, completed: { + queue.dispatch { + subscriber.putCompletion() + } + }) + } +} + +public func deliverOnMainQueue(signal: Signal) -> Signal { + return signal |> deliverOn(Queue.mainQueue()) +} + +public func deliverOn(threadPool: ThreadPool)(signal: Signal) -> Signal { + return Signal { subscriber in + let queue = threadPool.nextQueue() + return signal.start(next: { next in + queue.addTask(ThreadPoolTask { state in + if !state.cancelled { + subscriber.putNext(next) + } + }) + }, error: { error in + queue.addTask(ThreadPoolTask { state in + if !state.cancelled { + subscriber.putError(error) + } + }) + }, completed: { + queue.addTask(ThreadPoolTask { state in + if !state.cancelled { + subscriber.putCompletion() + } + }) + }) + } +} + +public func runOn(threadPool: ThreadPool)(signal: Signal) -> Signal { + return Signal { subscriber in + var cancelled = false + let disposable = MetaDisposable() + + let task = ThreadPoolTask { state in + if cancelled || state.cancelled { + return + } + + disposable.set(signal.start(next: { next in + subscriber.putNext(next) + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putCompletion() + })) + } + + disposable.set(ActionDisposable { + task.cancel() + }) + + threadPool.addTask(task) + + return disposable + } +} diff --git a/SwiftSignalKit/Signal_Mapping.swift b/SwiftSignalKit/Signal_Mapping.swift new file mode 100644 index 0000000000..abde9df344 --- /dev/null +++ b/SwiftSignalKit/Signal_Mapping.swift @@ -0,0 +1,27 @@ +import Foundation + +public func map(f: T -> R)(signal: Signal) -> Signal { + return Signal { subscriber in + return signal.start(next: { next in + subscriber.putNext(f(next)) + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putCompletion() + }) + } +} + +public func filter(f: T -> Bool)(signal: Signal) -> Signal { + return Signal { subscriber in + return signal.start(next: { next in + if f(next) { + subscriber.putNext(next) + } + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putCompletion() + }) + } +} diff --git a/SwiftSignalKit/Signal_Meta.swift b/SwiftSignalKit/Signal_Meta.swift new file mode 100644 index 0000000000..20ef3a5fde --- /dev/null +++ b/SwiftSignalKit/Signal_Meta.swift @@ -0,0 +1,153 @@ +import Foundation + +private final class SignalQueueState : Disposable { + var lock: OSSpinLock = 0 + var executingSignal = false + var terminated = false + + var disposable: Disposable = EmptyDisposable + let currentDisposable = MetaDisposable() + let subscriber: Subscriber + + var queuedSignals: [Signal] = [] + let queueMode: Bool + + init(subscriber: Subscriber, queueMode: Bool) { + self.subscriber = subscriber + self.queueMode = queueMode + } + + func beginWithDisposable(disposable: Disposable) { + self.disposable = disposable + } + + func enqueueSignal(signal: Signal) { + var startSignal = false + OSSpinLockLock(&self.lock) + if self.queueMode && self.executingSignal { + self.queuedSignals.append(signal) + } else { + self.executingSignal = true + startSignal = true + } + OSSpinLockUnlock(&self.lock) + + if startSignal { + let disposable = signal.start(next: { next in + self.subscriber.putNext(next) + }, error: { error in + self.subscriber.putError(error) + }, completed: { + self.headCompleted() + }) + self.currentDisposable.set(disposable) + } + } + + func headCompleted() { + var nextSignal: Signal! = nil + + var terminated = false + OSSpinLockLock(&self.lock) + self.executingSignal = false + if self.queueMode { + if self.queuedSignals.count != 0 { + nextSignal = self.queuedSignals[0] + self.queuedSignals.removeAtIndex(0) + self.executingSignal = true + } else { + terminated = self.terminated + } + } else { + terminated = self.terminated + } + OSSpinLockUnlock(&self.lock) + + if terminated { + self.subscriber.putCompletion() + } else if nextSignal != nil { + let disposable = nextSignal.start(next: { next in + self.subscriber.putNext(next) + }, error: { error in + self.subscriber.putError(error) + }, completed: { + self.headCompleted() + }) + } + } + + func beginCompletion() { + var executingSignal = false + OSSpinLockLock(&self.lock) + executingSignal = self.executingSignal + self.terminated = true + OSSpinLockUnlock(&self.lock) + + if !executingSignal { + self.subscriber.putCompletion() + } + } + + func dispose() { + self.currentDisposable.dispose() + self.disposable.dispose() + } +} + +public func switchToLatest(signal: Signal, E>) -> Signal { + return Signal { subscriber in + let state = SignalQueueState(subscriber: subscriber, queueMode: false) + state.beginWithDisposable(signal.start(next: { next in + state.enqueueSignal(next) + }, error: { error in + subscriber.putError(error) + }, completed: { + state.beginCompletion() + })) + return state + } +} + +public func queue(signal: Signal, E>) -> Signal { + return Signal { subscriber in + let state = SignalQueueState(subscriber: subscriber, queueMode: true) + state.beginWithDisposable(signal.start(next: { next in + state.enqueueSignal(next) + }, error: { error in + subscriber.putError(error) + }, completed: { + state.beginCompletion() + })) + return state + } +} + +public func mapToSignal(f: T -> Signal)(signal: Signal) -> Signal { + return signal |> map { f($0) } |> switchToLatest +} + +public func mapToQueue(f: T -> Signal)(signal: Signal) -> Signal { + return signal |> map { f($0) } |> queue +} + +public func then(nextSignal: Signal)(signal: Signal) -> Signal { + return Signal { subscriber in + let disposable = DisposableSet() + + disposable.add(signal.start(next: { next in + subscriber.putNext(next) + }, error: { error in + subscriber.putError(error) + }, completed: { + disposable.add(nextSignal.start(next: { next in + subscriber.putNext(next) + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putCompletion() + })) + })) + + return disposable + } +} diff --git a/SwiftSignalKit/Signal_Reduce.swift b/SwiftSignalKit/Signal_Reduce.swift new file mode 100644 index 0000000000..e5a4671b84 --- /dev/null +++ b/SwiftSignalKit/Signal_Reduce.swift @@ -0,0 +1,34 @@ +import Foundation + +public func reduceLeft(value: T, f: (T, T) -> T)(signal: Signal) -> Signal { + return Signal { subscriber in + var currentValue = value + + return signal.start(next: { next in + currentValue = f(currentValue, next) + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putNext(currentValue) + subscriber.putCompletion() + }) + } +} + +public func reduceLeft(value: T, f: (T, T, T -> Void) -> T)(signal: Signal) -> Signal { + return Signal { subscriber in + var currentValue = value + let emit: T -> Void = { next in + subscriber.putNext(next) + } + + return signal.start(next: { next in + currentValue = f(currentValue, next, emit) + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putNext(currentValue) + subscriber.putCompletion() + }) + } +} diff --git a/SwiftSignalKit/Signal_SideEffects.swift b/SwiftSignalKit/Signal_SideEffects.swift new file mode 100644 index 0000000000..53989606ab --- /dev/null +++ b/SwiftSignalKit/Signal_SideEffects.swift @@ -0,0 +1,45 @@ +import Foundation + +public func beforeNext(f: T -> R)(signal: Signal) -> Signal { + return Signal { subscriber in + return signal.start(next: { next in + let unused = f(next) + subscriber.putNext(next) + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putCompletion() + }) + } +} + +public func afterNext(f: T -> R)(signal: Signal) -> Signal { + return Signal { subscriber in + return signal.start(next: { next in + subscriber.putNext(next) + let unused = f(next) + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putCompletion() + }) + } +} + +public func afterDisposed(f: Void -> R)(signal: Signal) -> Signal { + return Signal { subscriber in + let disposable = DisposableSet() + disposable.add(signal.start(next: { next in + subscriber.putNext(next) + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putCompletion() + })) + disposable.add(ActionDisposable { + let unused = f() + }) + + return disposable + } +} \ No newline at end of file diff --git a/SwiftSignalKit/Signal_Single.swift b/SwiftSignalKit/Signal_Single.swift new file mode 100644 index 0000000000..8adc2d8b53 --- /dev/null +++ b/SwiftSignalKit/Signal_Single.swift @@ -0,0 +1,28 @@ +import Foundation + +extension Signal { + public static func single(value: T) -> Signal { + return Signal { subscriber in + subscriber.putNext(value) + subscriber.putCompletion() + + return EmptyDisposable + } + } + + public static func fail(error: E) -> Signal { + return Signal { subscriber in + subscriber.putError(error) + + return EmptyDisposable + } + } + + public static func complete() -> Signal { + return Signal { subscriber in + subscriber.putCompletion() + + return EmptyDisposable + } + } +} diff --git a/SwiftSignalKit/Signal_Take.swift b/SwiftSignalKit/Signal_Take.swift new file mode 100644 index 0000000000..d2e11c1a2f --- /dev/null +++ b/SwiftSignalKit/Signal_Take.swift @@ -0,0 +1,27 @@ +import Foundation + +public func take(count: Int)(signal: Signal) -> Signal { + return Signal { subscriber in + let counter = Atomic(value: 0) + return signal.start(next: { next in + var passthrough = false + var complete = false + counter.modify { value in + let updatedCount = value + 1 + passthrough = updatedCount <= count + complete = updatedCount == count + return updatedCount + } + if passthrough { + subscriber.putNext(next) + } + if complete { + subscriber.putCompletion() + } + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putCompletion() + }) + } +} diff --git a/SwiftSignalKit/Signal_Timing.swift b/SwiftSignalKit/Signal_Timing.swift new file mode 100644 index 0000000000..6d1eb39ede --- /dev/null +++ b/SwiftSignalKit/Signal_Timing.swift @@ -0,0 +1,56 @@ +import Foundation + +public func delay(timeout: NSTimeInterval, queue: Queue)(signal: Signal) -> Signal { + return Signal { subscriber in + let disposable = MetaDisposable() + let timer = Timer(timeout: timeout, repeat: false, completion: { + disposable.set(signal.start(next: { next in + subscriber.putNext(next) + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putCompletion() + })) + }, queue: queue) + disposable.set(ActionDisposable { + timer.invalidate() + }) + timer.start() + return disposable + } +} + +public func timeout(timeout: NSTimeInterval, queue: Queue, alternate: Signal)(signal: Signal) -> Signal { + return Signal { subscriber in + let disposable = MetaDisposable() + let timer = Timer(timeout: timeout, repeat: false, completion: { + disposable.set(alternate.start(next: { next in + subscriber.putNext(next) + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putCompletion() + })) + }, queue: queue) + + disposable.set(signal.start(next: { next in + timer.invalidate() + subscriber.putNext(next) + }, error: { error in + timer.invalidate() + subscriber.putError(error) + }, completed: { + timer.invalidate() + subscriber.putCompletion() + })) + timer.start() + + let disposableSet = DisposableSet() + disposableSet.add(ActionDisposable { + timer.invalidate() + }) + disposableSet.add(disposable) + + return disposableSet + } +} diff --git a/SwiftSignalKit/Subscriber.swift b/SwiftSignalKit/Subscriber.swift new file mode 100644 index 0000000000..2b74e2f57c --- /dev/null +++ b/SwiftSignalKit/Subscriber.swift @@ -0,0 +1,101 @@ +import Foundation + +public final class Subscriber { + private var next: (T -> Void)! + private var error: (E -> Void)! + private var completed: (() -> Void)! + + private var lock: OSSpinLock = 0 + private var terminated = false + internal var disposable: Disposable! + + public init(next: (T -> Void)! = nil, error: (E -> Void)! = nil, completed: (() -> Void)! = nil) { + self.next = next + self.error = error + self.completed = completed + } + + internal func assignDisposable(disposable: Disposable) { + if self.terminated { + disposable.dispose() + } else { + self.disposable = disposable + } + } + + internal func markTerminatedWithoutDisposal() { + OSSpinLockLock(&self.lock) + if !self.terminated { + self.terminated = true + self.next = nil + self.error = nil + self.completed = nil + } + OSSpinLockUnlock(&self.lock) + } + + public func putNext(next: T) { + var action: (T -> Void)! = nil + OSSpinLockLock(&self.lock) + if !self.terminated { + action = self.next + } + OSSpinLockUnlock(&self.lock) + + if action != nil { + action(next) + } + } + + public func putError(error: E) { + var shouldDispose = false + var action: (E -> Void)! = nil + + OSSpinLockLock(&self.lock); + if !self.terminated { + action = self.error + shouldDispose = true; + self.next = nil + self.error = nil + self.completed = nil; + self.terminated = true + } + OSSpinLockUnlock(&self.lock); + + if action != nil { + action(error) + } + + if shouldDispose && self.disposable != nil { + let disposable = self.disposable + disposable.dispose() + self.disposable = nil + } + } + + public func putCompletion() { + var shouldDispose = false + var action: (() -> Void)! = nil + + OSSpinLockLock(&self.lock); + if !self.terminated { + action = self.completed + shouldDispose = true; + self.next = nil + self.error = nil + self.completed = nil; + self.terminated = true + } + OSSpinLockUnlock(&self.lock); + + if action != nil { + action() + } + + if shouldDispose && self.disposable != nil { + let disposable = self.disposable + disposable.dispose() + self.disposable = nil + } + } +} diff --git a/SwiftSignalKit/SwiftSignalKit.h b/SwiftSignalKit/SwiftSignalKit.h new file mode 100644 index 0000000000..e78eb85e84 --- /dev/null +++ b/SwiftSignalKit/SwiftSignalKit.h @@ -0,0 +1,19 @@ +// +// SwiftSignalKit.h +// SwiftSignalKit +// +// Created by Peter on 10/06/15. +// Copyright (c) 2015 Telegram. All rights reserved. +// + +#import + +//! Project version number for SwiftSignalKit. +FOUNDATION_EXPORT double SwiftSignalKitVersionNumber; + +//! Project version string for SwiftSignalKit. +FOUNDATION_EXPORT const unsigned char SwiftSignalKitVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/SwiftSignalKit/ThreadPool.swift b/SwiftSignalKit/ThreadPool.swift new file mode 100644 index 0000000000..295f87c5d1 --- /dev/null +++ b/SwiftSignalKit/ThreadPool.swift @@ -0,0 +1,154 @@ +import Foundation + +public final class ThreadPoolTaskState { + public var cancelled = false +} + +public final class ThreadPoolTask { + private let state = ThreadPoolTaskState() + private let action: ThreadPoolTaskState -> () + + public init(_ action: ThreadPoolTaskState -> ()) { + self.action = action + } + + internal func execute() { + if !state.cancelled { + self.action(self.state) + } + } + + public func cancel() { + self.state.cancelled = true + } +} + +public final class ThreadPoolQueue : Equatable { + private weak var threadPool: ThreadPool? + private var tasks: [ThreadPoolTask] = [] + + public init(threadPool: ThreadPool) { + self.threadPool = threadPool + } + + public func addTask(task: ThreadPoolTask) { + if let threadPool = self.threadPool { + threadPool.workOnQueue(self, action: { + self.tasks.append(task) + }) + } + } + + private func popFirstTask() -> ThreadPoolTask? { + if self.tasks.count != 0 { + let task = self.tasks[0]; + self.tasks.removeAtIndex(0) + return task + } else { + return nil + } + } + + private func hasTasks() -> Bool { + return self.tasks.count != 0 + } +} + +public func ==(lhs: ThreadPoolQueue, rhs: ThreadPoolQueue) -> Bool { + return lhs === rhs +} + +@objc public final class ThreadPool { + private var threads: [NSThread] = [] + private var queues: [ThreadPoolQueue] = [] + private var takenQueues: [ThreadPoolQueue] = [] + private var mutex: pthread_mutex_t + private var condition: pthread_cond_t + + private class func threadEntryPoint(threadPool: ThreadPool) { + var queue: ThreadPoolQueue! + + while (true) { + var task: ThreadPoolTask! + + pthread_mutex_lock(&threadPool.mutex); + + if queue != nil { + if let index = find(threadPool.takenQueues, queue) { + threadPool.takenQueues.removeAtIndex(index) + } + + if queue.hasTasks() { + threadPool.queues.append(queue); + } + } + + while (true) + { + while threadPool.queues.count == 0 { + pthread_cond_wait(&threadPool.condition, &threadPool.mutex); + } + + if threadPool.queues.count != 0 { + queue = threadPool.queues[0] + } + + if queue != nil { + task = queue.popFirstTask() + threadPool.takenQueues.append(queue) + + if let index = find(threadPool.queues, queue) { + threadPool.queues.removeAtIndex(index) + } + + break + } + } + pthread_mutex_unlock(&threadPool.mutex); + + if task != nil { + task.execute() + } + } + } + + public init(threadCount: Int, threadPriority: Double) { + assert(threadCount > 0, "threadCount < 0") + + self.mutex = pthread_mutex_t() + self.condition = pthread_cond_t() + pthread_mutex_init(&self.mutex, nil) + pthread_cond_init(&self.condition, nil) + + for i in 0 ..< threadCount { + var thread = NSThread(target: ThreadPool.self, selector: Selector("threadEntryPoint"), object: self) + thread.threadPriority = threadPriority + self.threads.append(thread) + thread.start() + } + } + + deinit { + pthread_mutex_destroy(&self.mutex) + pthread_cond_destroy(&self.condition) + } + + public func addTask(task: ThreadPoolTask) { + let tempQueue = self.nextQueue() + tempQueue.addTask(task) + } + + private func workOnQueue(queue: ThreadPoolQueue, action: () -> ()) { + pthread_mutex_lock(&self.mutex) + action() + if !contains(self.queues, queue) && !contains(self.takenQueues, queue) { + self.queues.append(queue) + } + pthread_cond_broadcast(&self.condition) + pthread_mutex_unlock(&self.mutex) + } + + public func nextQueue() -> ThreadPoolQueue { + return ThreadPoolQueue(threadPool: self) + } +} \ No newline at end of file diff --git a/SwiftSignalKit/Timer.swift b/SwiftSignalKit/Timer.swift new file mode 100644 index 0000000000..c4acfbcb6b --- /dev/null +++ b/SwiftSignalKit/Timer.swift @@ -0,0 +1,41 @@ +import Foundation + +public final class Timer { + private var timer: dispatch_source_t! + private var timeout: NSTimeInterval + private var repeat: Bool + private var completion: Void -> Void + private var queue: Queue + + public init(timeout: NSTimeInterval, repeat: Bool, completion: Void -> Void, queue: Queue) { + self.timeout = timeout + self.repeat = repeat + self.completion = completion + self.queue = queue + } + + deinit { + self.invalidate() + } + + public func start() { + self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.queue.queue) + dispatch_source_set_timer(self.timer, dispatch_time(DISPATCH_TIME_NOW, Int64(self.timeout * NSTimeInterval(NSEC_PER_SEC))), self.repeat ? UInt64(self.timeout * NSTimeInterval(NSEC_PER_SEC)) : DISPATCH_TIME_FOREVER, 0); + dispatch_source_set_event_handler(self.timer, { [weak self] in + if let strongSelf = self { + strongSelf.completion() + if !strongSelf.repeat { + strongSelf.invalidate() + } + } + }) + dispatch_resume(self.timer) + } + + public func invalidate() { + if self.timer != nil { + dispatch_source_cancel(self.timer) + self.timer = nil + } + } +} diff --git a/SwiftSignalKitTests/DeallocatingObject.swift b/SwiftSignalKitTests/DeallocatingObject.swift new file mode 100644 index 0000000000..c4d12389b2 --- /dev/null +++ b/SwiftSignalKitTests/DeallocatingObject.swift @@ -0,0 +1,19 @@ +import Foundation + +internal class DeallocatingObject : Printable { + private var deallocated: UnsafeMutablePointer + + init(deallocated: UnsafeMutablePointer) { + self.deallocated = deallocated + } + + deinit { + self.deallocated.memory = true + } + + public var description: String { + get { + return "" + } + } +} diff --git a/SwiftSignalKitTests/Info.plist b/SwiftSignalKitTests/Info.plist new file mode 100644 index 0000000000..29dacae6b5 --- /dev/null +++ b/SwiftSignalKitTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.telegram.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/SwiftSignalKitTests/SwiftSignalKitBasicTests.swift b/SwiftSignalKitTests/SwiftSignalKitBasicTests.swift new file mode 100644 index 0000000000..91ed5ac9fa --- /dev/null +++ b/SwiftSignalKitTests/SwiftSignalKitBasicTests.swift @@ -0,0 +1,259 @@ +import UIKit +import XCTest +import SwiftSignalKit + +class SwiftSignalKitTests: XCTestCase { + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func testActionDisposableDisposed() { + var deallocated = false + var disposed = false + if true { + var object: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated) + let disposable = ActionDisposable(action: { [object] () -> Void in + object.debugDescription + disposed = true + }) + object = nil + XCTAssertFalse(deallocated, "deallocated != false") + disposable.dispose() + } + + XCTAssertTrue(deallocated, "deallocated != true") + XCTAssertTrue(disposed, "disposed != true") + } + + func testActionDisposableNotDisposed() { + var deallocated = false + var disposed = false + if true { + var object: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated) + let disposable = ActionDisposable(action: { [object] () -> Void in + object.debugDescription + disposed = true + }) + } + XCTAssertTrue(deallocated, "deallocated != true") + XCTAssertFalse(disposed, "disposed != false") + } + + func testMetaDisposableDisposed() { + var deallocated = false + var disposed = false + if true { + var object: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated) + let disposable = ActionDisposable(action: { [object] () -> Void in + object.debugDescription + disposed = true + }) + + let metaDisposable = MetaDisposable() + metaDisposable.set(disposable) + metaDisposable.dispose() + } + XCTAssertTrue(deallocated, "deallocated != true") + XCTAssertTrue(disposed, "disposed != true") + } + + func testMetaDisposableDisposedMultipleTimes() { + var deallocated1 = false + var disposed1 = false + var deallocated2 = false + var disposed2 = false + if true { + var object1: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated1) + let actionDisposable1 = ActionDisposable(action: { [object1] () -> Void in + object1.debugDescription + disposed1 = true + }) + + var object2: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated2) + let actionDisposable2 = ActionDisposable(action: { [object2] () -> Void in + object2.debugDescription + disposed2 = true + }) + + let metaDisposable = MetaDisposable() + metaDisposable.set(actionDisposable1) + metaDisposable.set(actionDisposable2) + metaDisposable.dispose() + } + XCTAssertTrue(deallocated1, "deallocated1 != true") + XCTAssertTrue(disposed1, "disposed1 != true") + XCTAssertTrue(deallocated2, "deallocated2 != true") + XCTAssertTrue(disposed2, "disposed2 != true") + } + + func testMetaDisposableNotDisposed() { + var deallocated = false + var disposed = false + if true { + var object: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated) + let disposable = ActionDisposable(action: { [object] () -> Void in + object.debugDescription + disposed = true + }) + + let metaDisposable = MetaDisposable() + metaDisposable.set(disposable) + } + XCTAssertTrue(deallocated, "deallocated != true") + XCTAssertFalse(disposed, "disposed != false") + } + + func testDisposableSetSingleDisposed() { + var deallocated = false + var disposed = false + if true { + var object: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated) + let disposable = ActionDisposable(action: { [object] () -> Void in + object.debugDescription + disposed = true + }) + + let disposableSet = DisposableSet() + disposableSet.add(disposable) + disposableSet.dispose() + } + XCTAssertTrue(deallocated, "deallocated != true") + XCTAssertTrue(disposed, "disposed != true") + } + + func testDisposableSetMultipleDisposed() { + var deallocated1 = false + var disposed1 = false + var deallocated2 = false + var disposed2 = false + if true { + var object1: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated1) + let actionDisposable1 = ActionDisposable(action: { [object1] () -> Void in + object1.debugDescription + disposed1 = true + }) + + var object2: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated2) + let actionDisposable2 = ActionDisposable(action: { [object2] () -> Void in + object2.debugDescription + disposed2 = true + }) + + let disposableSet = DisposableSet() + disposableSet.add(actionDisposable1) + disposableSet.add(actionDisposable2) + disposableSet.dispose() + } + XCTAssertTrue(deallocated1, "deallocated1 != true") + XCTAssertTrue(disposed1, "disposed1 != true") + XCTAssertTrue(deallocated2, "deallocated2 != true") + XCTAssertTrue(disposed2, "disposed2 != true") + } + + func testDisposableSetSingleNotDisposed() { + var deallocated = false + var disposed = false + if true { + var object: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated) + let disposable = ActionDisposable(action: { [object] () -> Void in + object.debugDescription + disposed = true + }) + + let disposableSet = DisposableSet() + disposableSet.add(disposable) + } + XCTAssertTrue(deallocated, "deallocated != true") + XCTAssertFalse(disposed, "disposed != false") + } + + func testDisposableSetMultipleNotDisposed() { + var deallocated1 = false + var disposed1 = false + var deallocated2 = false + var disposed2 = false + if true { + var object1: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated1) + let actionDisposable1 = ActionDisposable(action: { [object1] () -> Void in + object1.debugDescription + disposed1 = true + }) + + var object2: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated2) + let actionDisposable2 = ActionDisposable(action: { [object2] () -> Void in + object2.debugDescription + disposed2 = true + }) + + let disposableSet = DisposableSet() + disposableSet.add(actionDisposable1) + disposableSet.add(actionDisposable2) + } + XCTAssertTrue(deallocated1, "deallocated1 != true") + XCTAssertFalse(disposed1, "disposed1 != false") + XCTAssertTrue(deallocated2, "deallocated2 != true") + XCTAssertFalse(disposed2, "disposed2 != false") + } + + func testMetaDisposableAlreadyDisposed() { + var deallocated1 = false + var disposed1 = false + var deallocated2 = false + var disposed2 = false + if true { + var object1: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated1) + let actionDisposable1 = ActionDisposable(action: { [object1] () -> Void in + object1.debugDescription + disposed1 = true + }) + + var object2: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated2) + let actionDisposable2 = ActionDisposable(action: { [object2] () -> Void in + object2.debugDescription + disposed2 = true + }) + + let metaDisposable = MetaDisposable() + metaDisposable.set(actionDisposable1) + metaDisposable.dispose() + metaDisposable.set(actionDisposable2) + } + XCTAssertTrue(deallocated1, "deallocated1 != true") + XCTAssertTrue(disposed1, "disposed1 != true") + XCTAssertTrue(deallocated2, "deallocated2 != true") + XCTAssertTrue(disposed2, "disposed2 != true") + } + + func testDisposableSetAlreadyDisposed() { + var deallocated1 = false + var disposed1 = false + var deallocated2 = false + var disposed2 = false + if true { + var object1: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated1) + let actionDisposable1 = ActionDisposable(action: { [object1] () -> Void in + object1.debugDescription + disposed1 = true + }) + + var object2: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated2) + let actionDisposable2 = ActionDisposable(action: { [object2] () -> Void in + object2.debugDescription + disposed2 = true + }) + + let disposableSet = DisposableSet() + disposableSet.add(actionDisposable1) + disposableSet.dispose() + disposableSet.add(actionDisposable2) + } + XCTAssertTrue(deallocated1, "deallocated1 != true") + XCTAssertTrue(disposed1, "disposed1 != true") + XCTAssertTrue(deallocated2, "deallocated2 != true") + XCTAssertTrue(disposed2, "disposed2 != true") + } +} diff --git a/SwiftSignalKitTests/SwiftSignalKitFunctionsTests.swift b/SwiftSignalKitTests/SwiftSignalKitFunctionsTests.swift new file mode 100644 index 0000000000..80f276cb8c --- /dev/null +++ b/SwiftSignalKitTests/SwiftSignalKitFunctionsTests.swift @@ -0,0 +1,660 @@ +import UIKit +import XCTest +import SwiftSignalKit + +func singleSignalInt(value: Signal) -> Signal, Void> { + return Signal { subscriber in + subscriber.putNext(value) + subscriber.putCompletion() + return EmptyDisposable + } +} + +class SwiftSignalKitFunctionsTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func testSignalGenerated() { + var deallocated = false + var disposed = false + var generated = false + + if true { + var object: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated) + let signal = Signal { [object] subscriber in + subscriber.putNext(1) + return ActionDisposable { + object?.description + disposed = true + } + } + + let disposable = signal.start(next: { [object] next in + generated = true + object?.description + }) + + object = nil + + XCTAssertFalse(deallocated, "deallocated != false") + + disposable.dispose() + } + + XCTAssertTrue(deallocated, "deallocated != true") + XCTAssertTrue(disposed, "disposed != true") + XCTAssertTrue(generated, "generated != true") + } + + func testSignalGeneratedCompleted() { + var deallocated = false + var disposed = false + var generated = false + var completed = false + + if true { + var object: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated) + let signal = Signal { [object] subscriber in + subscriber.putNext(1) + subscriber.putCompletion() + + return ActionDisposable { + object?.description + disposed = true + } + } + + let disposable = signal.start(next: { [object] next in + generated = true + object?.description + }, completed: { [object] + completed = true + object?.description + }) + + object = nil + + XCTAssertFalse(deallocated, "deallocated != false") + + disposable.dispose() + } + + XCTAssertTrue(deallocated, "deallocated != true") + XCTAssertTrue(disposed, "disposed != true") + XCTAssertTrue(generated, "generated != true") + XCTAssertTrue(completed, "completed != true") + } + + func testSignalGeneratedError() { + var deallocated = false + var disposed = false + var generated = false + var completed = false + var error = false + + if true { + var object: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated) + let signal = Signal { [object] subscriber in + subscriber.putError() + subscriber.putNext(1) + + return ActionDisposable { + object?.description + disposed = true + } + } + + let disposable = signal.start(next: { [object] next in + generated = true + object?.description + }, error: { [object] _ in + error = true + object?.description + }, + completed: { [object] + completed = true + object?.description + }) + + object = nil + + XCTAssertFalse(deallocated, "deallocated != false") + + disposable.dispose() + } + + XCTAssertTrue(deallocated, "deallocated != true") + XCTAssertTrue(disposed, "disposed != true") + XCTAssertFalse(generated, "generated != false") + XCTAssertFalse(completed, "completed != false") + XCTAssertTrue(error, "error != true") + } + + func testMap() { + var deallocated = false + var disposed = false + var generated = false + + if true { + var object: DeallocatingObject? = DeallocatingObject(deallocated: &deallocated) + var signal = Signal { [object] subscriber in + subscriber.putNext(1) + + return ActionDisposable { + object?.description + disposed = true + } + } + signal = signal |> map { $0 * 2} + + let disposable = signal.start(next: { [object] next in + generated = next == 2 + object?.description + }) + + object = nil + + XCTAssertFalse(deallocated, "deallocated != false") + + disposable.dispose() + } + + XCTAssertTrue(deallocated, "deallocated != true") + XCTAssertTrue(disposed, "disposed != true") + XCTAssertTrue(generated, "generated != true") + } + + func testCatch() { + let failingSignal = Signal { subscriber in + subscriber.putNext(1) + subscriber.putError(1) + return EmptyDisposable + } + + let catchSignal = failingSignal |> catch { error in + return Signal { subscriber in + subscriber.putNext(error * 2) + return EmptyDisposable + } + } + + var result = 0 + catchSignal.start(next: { next in + result += next + }) + + XCTAssertTrue(result == 3, "result != 2") + } + + func testSubscriberDisposal() { + var disposed = false + var generated = false + var queue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + + if true { + let signal = Signal { subscriber in + dispatch_async(queue, { + usleep(200) + subscriber.putNext(1) + }) + return ActionDisposable { + disposed = true + } + } + + let disposable = signal.start(next: { next in + generated = true + }) + disposable.dispose() + + dispatch_barrier_sync(queue, {}) + + XCTAssertTrue(disposed, "disposed != true") + XCTAssertFalse(generated, "generated != false") + } + } + + func testThen() { + var generatedFirst = false + var disposedFirst = false + var generatedSecond = false + var disposedSecond = false + var result = 0 + + var signal = Signal { subscriber in + generatedFirst = true + subscriber.putNext(1) + subscriber.putCompletion() + return ActionDisposable { + disposedFirst = true + } + } + + signal = signal |> then (Signal { subscriber in + generatedSecond = true + subscriber.putNext(2) + subscriber.putCompletion() + return ActionDisposable { + disposedSecond = true + } + }) + + signal.start(next: { next in + result += next + }) + + XCTAssertTrue(generatedFirst, "generatedFirst != true"); + XCTAssertTrue(disposedFirst, "disposedFirst != true"); + XCTAssertTrue(generatedSecond, "generatedSecond !+ true"); + XCTAssertTrue(disposedSecond, "disposedSecond != true"); + XCTAssertTrue(result == 3, "result != 3"); + } + + func testCombineLatest2() { + let s1 = Signal { subscriber in + subscriber.putNext(1) + subscriber.putCompletion() + return EmptyDisposable + } + let s2 = Signal { subscriber in + subscriber.putNext(2) + subscriber.putCompletion() + return EmptyDisposable + } + + let signal = combineLatest(s1, s2) + + var completed = false + signal.start(next: { next in + XCTAssert(next.0 == 1 && next.1 == 2, "next != (1, 2)") + return + }, completed: { + completed = true + }) + XCTAssert(completed == true, "completed != true") + } + + func testCombineLatest3() { + let s1 = Signal { subscriber in + subscriber.putNext(1) + subscriber.putCompletion() + return EmptyDisposable + } + let s2 = Signal { subscriber in + subscriber.putNext(2) + subscriber.putCompletion() + return EmptyDisposable + } + let s3 = Signal { subscriber in + subscriber.putNext(3) + subscriber.putCompletion() + return EmptyDisposable + } + + let signal = combineLatest(s1, s2, s3) + + var completed = false + signal.start(next: { next in + XCTAssert(next.0 == 1 && next.1 == 2 && next.2 == 3, "next != (1, 2, 3)") + return + }, completed: { + completed = true + }) + XCTAssert(completed == true, "completed != true") + } + + /*func testSingle() { + let s1 = Signal.single(1) + let s2 = Signal.fail(Void()) + let s3 = Signal.complete() + + var singleEmitted = false + s1.start(next: { next in + singleEmitted = next == 1 + }) + XCTAssert(singleEmitted == true, "singleEmitted != true") + + var errorEmitted = false + s2.start(error: { error in + errorEmitted = true + }) + XCTAssert(errorEmitted == true, "errorEmitted != true") + + var completedEmitted = false + s3.start(completed: { + completedEmitted = true + }) + XCTAssert(completedEmitted == true, "errorEmitted != true") + }*/ + + func testSwitchToLatest() { + var result: [Int] = [] + var disposedOne = false + var disposedTwo = false + var disposedThree = false + var completedAll = false + + var deallocatedOne = false + var deallocatedTwo = false + var deallocatedThree = false + + if true { + var objectOne: DeallocatingObject? = DeallocatingObject(deallocated: &deallocatedOne) + var objectTwo: DeallocatingObject? = DeallocatingObject(deallocated: &deallocatedTwo) + var objectThree: DeallocatingObject? = DeallocatingObject(deallocated: &deallocatedThree) + + let one = Signal { subscriber in + subscriber.putNext(1) + subscriber.putCompletion() + return ActionDisposable { [objectOne] in + objectOne?.description + disposedOne = true + } + } + + let two = Signal { subscriber in + subscriber.putNext(2) + subscriber.putCompletion() + return ActionDisposable { [objectTwo] in + objectTwo?.description + disposedTwo = true + } + } + + let three = Signal { subscriber in + subscriber.putNext(3) + subscriber.putCompletion() + return ActionDisposable { [objectThree] in + objectThree?.description + disposedThree = true + } + } + + let signal = singleSignalInt(one) |> then(singleSignalInt(two)) |> then(singleSignalInt(three)) |> switchToLatest + + signal.start(next: { next in + result.append(next) + }, completed: { + completedAll = true + }) + } + + XCTAssert(result.count == 3 && result[0] == 1 && result[1] == 2 && result[2] == 3, "result != [1, 2, 3]"); + XCTAssert(disposedOne == true, "disposedOne != true"); + XCTAssert(disposedTwo == true, "disposedTwo != true"); + XCTAssert(disposedThree == true, "disposedThree != true"); + XCTAssert(deallocatedOne == true, "deallocatedOne != true"); + XCTAssert(deallocatedTwo == true, "deallocatedTwo != true"); + XCTAssert(deallocatedThree == true, "deallocatedThree != true"); + XCTAssert(completedAll == true, "completedAll != true"); + } + + func testSwitchToLatestError() { + var errorGenerated = false + + let one = Signal { subscriber in + subscriber.putError(Void()) + return EmptyDisposable + } + + let signal = singleSignalInt(one) |> switchToLatest + + signal.start(error: { error in + errorGenerated = true + }) + + XCTAssert(errorGenerated == true, "errorGenerated != true") + } + + func testQueue() { + let q = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL) + + var disposedOne = false + var disposedTwo = false + var disposedThree = false + var completedAll = false + var result: [Int] = [] + + let one = Signal { subscriber in + dispatch_async(q, { + subscriber.putNext(1) + subscriber.putCompletion() + }) + return ActionDisposable { + disposedOne = true + } + } + + let two = Signal { subscriber in + dispatch_async(q, { + subscriber.putNext(2) + subscriber.putCompletion() + }) + return ActionDisposable { + disposedTwo = true + } + } + + let three = Signal { subscriber in + dispatch_async(q, { + subscriber.putNext(3) + subscriber.putCompletion() + }) + return ActionDisposable { + disposedThree = true + } + } + + let signal = singleSignalInt(one) |> then(singleSignalInt(two)) |> then(singleSignalInt(three)) |> queue + + signal.start(next: { next in + println("next: \(next)") + result.append(next) + }, completed: { + completedAll = true + }) + + usleep(1000 * 200) + + XCTAssert(result.count == 3 && result[0] == 1 && result[1] == 2 && result[2] == 3, "result != [1, 2, 3]"); + XCTAssert(disposedOne == true, "disposedOne != true"); + XCTAssert(disposedTwo == true, "disposedTwo != true"); + XCTAssert(disposedThree == true, "disposedThree != true"); + XCTAssert(completedAll == true, "completedAll != true"); + } + + func testQueueInterrupted() { + let q = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL) + + var disposedOne = false + var disposedTwo = false + var disposedThree = false + var startedThird = false + var completedAll = false + var result: [Int] = [] + + let one = Signal { subscriber in + dispatch_async(q, { + subscriber.putNext(1) + subscriber.putCompletion() + }) + return ActionDisposable { + disposedOne = true + } + } + + let two = Signal { subscriber in + dispatch_async(q, { + subscriber.putNext(2) + subscriber.putError(Void()) + }) + return ActionDisposable { + disposedTwo = true + } + } + + let three = Signal { subscriber in + startedThird = true + dispatch_async(q, { + subscriber.putNext(3) + subscriber.putCompletion() + }) + return ActionDisposable { + disposedThree = true + } + } + + let signal = singleSignalInt(one) |> then(singleSignalInt(two)) |> then(singleSignalInt(three)) |> queue + + signal.start(next: { next in + result.append(next) + }, completed: { + completedAll = true + }) + + usleep(1000 * 200) + + XCTAssert(result.count == 2 && result[0] == 1 && result[1] == 2, "result != [1, 2]"); + XCTAssert(disposedOne == true, "disposedOne != true"); + XCTAssert(disposedTwo == true, "disposedTwo != true"); + XCTAssert(disposedThree == false, "disposedThree != false"); + XCTAssert(startedThird == false, "startedThird != false"); + XCTAssert(completedAll == false, "completedAll != false"); + } + + func testQueueDisposed() { + let q = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL) + + var disposedOne = false + var disposedTwo = false + var disposedThree = false + var startedFirst = false + var startedSecond = false + var startedThird = false + var result: [Int] = [] + + let one = Signal { subscriber in + startedFirst = true + var cancelled = false + dispatch_async(q, { + if !cancelled { + usleep(100 * 1000) + subscriber.putNext(1) + subscriber.putCompletion() + } + }) + return ActionDisposable { + cancelled = true + disposedOne = true + } + } + + let two = Signal { subscriber in + startedSecond = true + var cancelled = false + dispatch_async(q, { + if !cancelled { + usleep(100 * 1000) + subscriber.putNext(2) + subscriber.putError(Void()) + } + }) + return ActionDisposable { + cancelled = true + disposedTwo = true + } + } + + let three = Signal { subscriber in + startedThird = true + var cancelled = false + dispatch_async(q, { + if !cancelled { + usleep(100 * 1000) + subscriber.putNext(3) + subscriber.putCompletion() + } + }) + return ActionDisposable { + cancelled = true + disposedThree = true + } + } + + let signal = singleSignalInt(one) |> then(singleSignalInt(two)) |> then(singleSignalInt(three)) |> queue + + signal.start(next: { next in + result.append(next) + }).dispose() + + usleep(1000 * 200) + + XCTAssert(result.count == 0, "result != []"); + XCTAssert(disposedOne == true, "disposedOne != true"); + XCTAssert(disposedTwo == false, "disposedTwo != false"); + XCTAssert(disposedThree == false, "disposedThree != false"); + XCTAssert(startedFirst == true, "startedFirst != false"); + XCTAssert(startedSecond == false, "startedSecond != false"); + XCTAssert(startedThird == false, "startedThird != false"); + } + + func testRestart() { + let q = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT) + let signal = Signal { subscriber in + dispatch_async(q, { + subscriber.putNext(1) + subscriber.putCompletion() + }) + return EmptyDisposable + } + + var result = 0 + + (signal |> restart |> take(3)).start(next: { next in + result += next + }) + + usleep(100 * 1000) + + XCTAssert(result == 3, "result != 3") + } + + func testPipe() { + let pipe = Pipe() + + var result1 = 0 + let disposable1 = pipe.signal().start(next: { next in + result1 += next + }) + + var result2 = 0 + let disposable2 = pipe.signal().start(next: { next in + result2 += next + }) + + pipe.putNext(1) + + XCTAssert(result1 == 1, "result1 != 1") + XCTAssert(result2 == 1, "result2 != 1") + + disposable1.dispose() + + pipe.putNext(1) + + XCTAssert(result1 == 1, "result1 != 1") + XCTAssert(result2 == 2, "result2 != 2") + + disposable2.dispose() + + pipe.putNext(1) + + XCTAssert(result1 == 1, "result1 != 1") + XCTAssert(result2 == 2, "result2 != 2") + } +}