mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-01-15 15:31:08 +00:00
139 lines
4.3 KiB
Mathematica
139 lines
4.3 KiB
Mathematica
|
//
|
||
|
// Copyright (c) 2016-present, Facebook, Inc.
|
||
|
// All rights reserved.
|
||
|
//
|
||
|
// This source code is licensed under the BSD-style license found in the
|
||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||
|
//
|
||
|
|
||
|
#import "SRDelegateController.h"
|
||
|
|
||
|
NS_ASSUME_NONNULL_BEGIN
|
||
|
|
||
|
@interface SRDelegateController ()
|
||
|
|
||
|
@property (nonatomic, strong, readonly) dispatch_queue_t accessQueue;
|
||
|
|
||
|
@property (atomic, assign, readwrite) SRDelegateAvailableMethods availableDelegateMethods;
|
||
|
|
||
|
@end
|
||
|
|
||
|
@implementation SRDelegateController
|
||
|
|
||
|
@synthesize delegate = _delegate;
|
||
|
@synthesize dispatchQueue = _dispatchQueue;
|
||
|
@synthesize operationQueue = _operationQueue;
|
||
|
|
||
|
///--------------------------------------
|
||
|
#pragma mark - Init
|
||
|
///--------------------------------------
|
||
|
|
||
|
- (instancetype)init
|
||
|
{
|
||
|
self = [super init];
|
||
|
if (!self) return self;
|
||
|
|
||
|
_accessQueue = dispatch_queue_create("com.facebook.socketrocket.delegate.access", DISPATCH_QUEUE_CONCURRENT);
|
||
|
_dispatchQueue = dispatch_get_main_queue();
|
||
|
|
||
|
return self;
|
||
|
}
|
||
|
|
||
|
///--------------------------------------
|
||
|
#pragma mark - Accessors
|
||
|
///--------------------------------------
|
||
|
|
||
|
- (void)setDelegate:(id<SRWebSocketDelegate> _Nullable)delegate
|
||
|
{
|
||
|
dispatch_barrier_async(self.accessQueue, ^{
|
||
|
_delegate = delegate;
|
||
|
|
||
|
self.availableDelegateMethods = (SRDelegateAvailableMethods){
|
||
|
.didReceiveMessage = [delegate respondsToSelector:@selector(webSocket:didReceiveMessage:)],
|
||
|
.didReceiveMessageWithString = [delegate respondsToSelector:@selector(webSocket:didReceiveMessageWithString:)],
|
||
|
.didReceiveMessageWithData = [delegate respondsToSelector:@selector(webSocket:didReceiveMessageWithData:)],
|
||
|
.didOpen = [delegate respondsToSelector:@selector(webSocketDidOpen:)],
|
||
|
.didFailWithError = [delegate respondsToSelector:@selector(webSocket:didFailWithError:)],
|
||
|
.didCloseWithCode = [delegate respondsToSelector:@selector(webSocket:didCloseWithCode:reason:wasClean:)],
|
||
|
.didReceivePing = [delegate respondsToSelector:@selector(webSocket:didReceivePingWithData:)],
|
||
|
.didReceivePong = [delegate respondsToSelector:@selector(webSocket:didReceivePong:)],
|
||
|
.shouldConvertTextFrameToString = [delegate respondsToSelector:@selector(webSocketShouldConvertTextFrameToString:)]
|
||
|
};
|
||
|
});
|
||
|
}
|
||
|
|
||
|
- (id<SRWebSocketDelegate> _Nullable)delegate
|
||
|
{
|
||
|
__block id<SRWebSocketDelegate> delegate = nil;
|
||
|
dispatch_sync(self.accessQueue, ^{
|
||
|
delegate = _delegate;
|
||
|
});
|
||
|
return delegate;
|
||
|
}
|
||
|
|
||
|
- (void)setDispatchQueue:(dispatch_queue_t _Nullable)queue
|
||
|
{
|
||
|
dispatch_barrier_async(self.accessQueue, ^{
|
||
|
_dispatchQueue = queue ?: dispatch_get_main_queue();
|
||
|
_operationQueue = nil;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
- (dispatch_queue_t _Nullable)dispatchQueue
|
||
|
{
|
||
|
__block dispatch_queue_t queue = nil;
|
||
|
dispatch_sync(self.accessQueue, ^{
|
||
|
queue = _dispatchQueue;
|
||
|
});
|
||
|
return queue;
|
||
|
}
|
||
|
|
||
|
- (void)setOperationQueue:(NSOperationQueue *_Nullable)queue
|
||
|
{
|
||
|
dispatch_barrier_async(self.accessQueue, ^{
|
||
|
_dispatchQueue = queue ? nil : dispatch_get_main_queue();
|
||
|
_operationQueue = queue;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
- (NSOperationQueue *_Nullable)operationQueue
|
||
|
{
|
||
|
__block NSOperationQueue *queue = nil;
|
||
|
dispatch_sync(self.accessQueue, ^{
|
||
|
queue = _operationQueue;
|
||
|
});
|
||
|
return queue;
|
||
|
}
|
||
|
|
||
|
///--------------------------------------
|
||
|
#pragma mark - Perform
|
||
|
///--------------------------------------
|
||
|
|
||
|
- (void)performDelegateBlock:(SRDelegateBlock)block
|
||
|
{
|
||
|
__block __strong id<SRWebSocketDelegate> delegate = nil;
|
||
|
__block SRDelegateAvailableMethods availableMethods = {};
|
||
|
dispatch_sync(self.accessQueue, ^{
|
||
|
delegate = _delegate; // Not `OK` to go through `self`, since queue sync.
|
||
|
availableMethods = self.availableDelegateMethods; // `OK` to call through `self`, since no queue sync.
|
||
|
});
|
||
|
[self performDelegateQueueBlock:^{
|
||
|
block(delegate, availableMethods);
|
||
|
}];
|
||
|
}
|
||
|
|
||
|
- (void)performDelegateQueueBlock:(dispatch_block_t)block
|
||
|
{
|
||
|
dispatch_queue_t dispatchQueue = self.dispatchQueue;
|
||
|
if (dispatchQueue) {
|
||
|
dispatch_async(dispatchQueue, block);
|
||
|
} else {
|
||
|
[self.operationQueue addOperationWithBlock:block];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@end
|
||
|
|
||
|
NS_ASSUME_NONNULL_END
|