no message

This commit is contained in:
Peter
2015-09-17 15:01:12 +03:00
parent 3f52eefb17
commit 008ad99279
9 changed files with 152 additions and 3 deletions

View File

@@ -88,6 +88,8 @@
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 */; };
D09FD73E1BA9BAB900FF0A4F /* SVariable.h in Headers */ = {isa = PBXBuildFile; fileRef = D09FD73C1BA9BAB900FF0A4F /* SVariable.h */; settings = {ATTRIBUTES = (Public, ); }; };
D09FD73F1BA9BAB900FF0A4F /* SVariable.m in Sources */ = {isa = PBXBuildFile; fileRef = D09FD73D1BA9BAB900FF0A4F /* SVariable.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -197,6 +199,8 @@
D06F106F1A855E2D00485185 /* DeallocatingObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeallocatingObject.h; sourceTree = "<group>"; };
D06F10701A855E2D00485185 /* DeallocatingObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DeallocatingObject.m; sourceTree = "<group>"; };
D06F10721A85882000485185 /* SSignalPerformanceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSignalPerformanceTests.m; sourceTree = "<group>"; };
D09FD73C1BA9BAB900FF0A4F /* SVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVariable.h; sourceTree = "<group>"; };
D09FD73D1BA9BAB900FF0A4F /* SVariable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVariable.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -365,6 +369,8 @@
D0085AD21B28285400EAF753 /* SSignal+Multicast.m */,
D0085ABA1B28285400EAF753 /* SMulticastSignalManager.h */,
D0085ABB1B28285400EAF753 /* SMulticastSignalManager.m */,
D09FD73C1BA9BAB900FF0A4F /* SVariable.h */,
D09FD73D1BA9BAB900FF0A4F /* SVariable.m */,
D0085AB91B28285400EAF753 /* SSignalKit.h */,
D0445DDB1A7C2CA500267924 /* Supporting Files */,
);
@@ -417,6 +423,7 @@
files = (
D0085AF61B28285400EAF753 /* SSignal+SideEffects.h in Headers */,
D0085AFD1B28285400EAF753 /* SSignal+Meta.h in Headers */,
D09FD73E1BA9BAB900FF0A4F /* SVariable.h in Headers */,
D0085AFE1B28285400EAF753 /* SSignal+Timing.h in Headers */,
D0085B0A1B28285400EAF753 /* SDisposable.h in Headers */,
D0085B111B28285400EAF753 /* SBag.h in Headers */,
@@ -638,6 +645,7 @@
buildActionMask = 2147483647;
files = (
D0085AE91B28285400EAF753 /* SQueue.m in Sources */,
D09FD73F1BA9BAB900FF0A4F /* SVariable.m in Sources */,
D0085B141B28285400EAF753 /* SBlockDisposable.m in Sources */,
D0085B001B28285400EAF753 /* SSignal+Dispatch.m in Sources */,
D0085AE71B28285400EAF753 /* SSignal+Timing.m in Sources */,

View File

@@ -1,7 +1,10 @@
#import <SSignalKit/SDisposable.h>
@class SSignal;
@interface SDisposableSet : NSObject <SDisposable>
- (void)add:(id<SDisposable>)disposable;
- (void)remove:(id<SDisposable>)disposable;
@end

View File

@@ -1,5 +1,7 @@
#import "SDisposableSet.h"
#import "SSignal.h"
#import <libkern/OSAtomic.h>
@interface SDisposableSet ()
@@ -48,6 +50,21 @@
[disposable dispose];
}
- (void)remove:(id<SDisposable>)disposable {
OSSpinLockLock(&_lock);
if (_multipleDisposables != nil)
{
NSMutableArray *multipleDisposables = [[NSMutableArray alloc] initWithArray:_multipleDisposables];
[multipleDisposables removeObject:disposable];
_multipleDisposables = multipleDisposables;
}
else if (_singleDisposable == disposable)
{
_singleDisposable = nil;
}
OSSpinLockUnlock(&_lock);
}
- (void)dispose
{
id<SDisposable> singleDisposable = nil;

View File

@@ -65,7 +65,7 @@
signal = producer();
if (signal != nil)
{
signal = [[signal multicast] onDispose:^
signal = [[signal onDispose:^
{
__strong SMulticastSignalManager *strongSelf = weakSelf;
if (strongSelf != nil)
@@ -74,7 +74,7 @@
[strongSelf->_multicastSignals removeObjectForKey:key];
OSSpinLockUnlock(&strongSelf->_lock);
}
}];
}] multicast];
_multicastSignals[key] = signal;
}
}
@@ -146,7 +146,11 @@
return [[SBlockDisposable alloc] initWithBlock:^
{
OSSpinLockLock(&_lock);
[(SBag *)_pipeListeners[key] removeItem:index];
SBag *bag = _pipeListeners[key];
[bag removeItem:index];
if ([bag isEmpty]) {
[_pipeListeners removeObjectForKey:key];
}
OSSpinLockUnlock(&_lock);
}];
}];

View File

@@ -13,4 +13,6 @@
- (dispatch_queue_t)_dispatch_queue;
- (bool)isCurrentQueue;
@end

View File

@@ -98,4 +98,13 @@ static const void *SQueueSpecificKey = &SQueueSpecificKey;
dispatch_sync(_queue, block);
}
- (bool)isCurrentQueue
{
if (_queueSpecific != NULL && dispatch_get_specific(SQueueSpecificKey) == _queueSpecific)
return true;
else if (_specialIsMainQueue && [NSThread isMainThread])
return true;
return false;
}
@end

View File

@@ -42,3 +42,4 @@ FOUNDATION_EXPORT const unsigned char SSignalKitVersionString[];
#import <SSignalKit/SSignal+Pipe.h>
#import <SSignalKit/SMulticastSignalManager.h>
#import <SSignalKit/STimer.h>
#import <SSignalKit/SVariable.h>

12
SSignalKit/SVariable.h Normal file
View File

@@ -0,0 +1,12 @@
#import <Foundation/Foundation.h>
@class SSignal;
@interface SVariable : NSObject
- (instancetype)init;
- (void)set:(SSignal *)signal;
- (SSignal *)signal;
@end

93
SSignalKit/SVariable.m Normal file
View File

@@ -0,0 +1,93 @@
#import "SVariable.h"
#import <libkern/OSAtomic.h>
#import "SSignal.h"
#import "SBag.h"
#import "SBlockDisposable.h"
#import "SMetaDisposable.h"
@interface SVariable ()
{
OSSpinLock _lock;
id _value;
bool _hasValue;
SBag *_subscribers;
SMetaDisposable *_disposable;
}
@end
@implementation SVariable
- (instancetype)init
{
self = [super init];
if (self != nil)
{
_subscribers = [[SBag alloc] init];
_disposable = [[SMetaDisposable alloc] init];
}
return self;
}
- (void)dealloc
{
[_disposable dispose];
}
- (SSignal *)signal
{
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
{
OSSpinLockLock(&self->_lock);
id currentValue = _value;
bool hasValue = _hasValue;
NSInteger index = [self->_subscribers addItem:[^(id value)
{
[subscriber putNext:value];
} copy]];
OSSpinLockUnlock(&self->_lock);
if (hasValue)
{
[subscriber putNext:currentValue];
}
return [[SBlockDisposable alloc] initWithBlock:^
{
OSSpinLockLock(&self->_lock);
[self->_subscribers removeItem:index];
OSSpinLockUnlock(&self->_lock);
}];
}];
}
- (void)set:(SSignal *)signal
{
OSSpinLockLock(&_lock);
_hasValue = false;
OSSpinLockUnlock(&_lock);
__weak SVariable *weakSelf = self;
[_disposable setDisposable:[signal startWithNext:^(id next)
{
__strong SVariable *strongSelf = weakSelf;
if (strongSelf != nil)
{
NSArray *subscribers = nil;
OSSpinLockLock(&strongSelf->_lock);
strongSelf->_value = next;
strongSelf->_hasValue = true;
subscribers = [strongSelf->_subscribers copyItems];
OSSpinLockUnlock(&strongSelf->_lock);
for (void (^subscriber)(id) in subscribers)
{
subscriber(next);
}
}
}]];
}
@end