Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ NS_SWIFT_SENDABLE
/// Engines work asynchronously so use this block to subscribe to
/// any commands received from the engine.
@property (nullable) void (^ responseHandler)(NSString * _Nonnull response);
@property (nonatomic, strong) NSMutableString *outputBuffer;

/// Initializes an engine with the desired type.
///
Expand Down
34 changes: 25 additions & 9 deletions Sources/ChessKitEngineCore/EngineMessenger/EngineMessenger.mm
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ - (id)initWithEngineType: (EngineType_objc) type {

if (self) {
_lock = [[NSLock alloc] init];
_outputBuffer = [NSMutableString string];
switch (type) {
case EngineTypeStockfish:
_engine = new StockfishEngine();
Expand Down Expand Up @@ -105,15 +106,30 @@ - (void)sendCommand: (NSString*) command {

# pragma mark Private

- (void)readStdout: (NSNotification*) notification {
[_pipeReadHandle readInBackgroundAndNotify];

NSData *data = [[notification userInfo] objectForKey:NSFileHandleNotificationDataItem];
NSArray<NSString *> *output = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] componentsSeparatedByString:@"\n"];

[output enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[self responseHandler](obj);
}];
- (void)readStdout:(NSNotification*)notification {
[_pipeReadHandle readInBackgroundAndNotify];

NSData *data = notification.userInfo[NSFileHandleNotificationDataItem];
if (!data || data.length == 0) return;

NSString *chunk = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (!chunk) return;

[self.outputBuffer appendString:chunk];

NSArray<NSString *> *lines = [self.outputBuffer componentsSeparatedByString:@"\n"];

// Keep the last line in the buffer if it's incomplete
NSUInteger lastIndex = lines.count - 1;
for (NSUInteger i = 0; i < lastIndex; i++) {
NSString *line = lines[i];
if (line.length > 0) {
[self responseHandler](line);
}
}

// Reset the buffer with the last (possibly partial) line
[self.outputBuffer setString:lines[lastIndex]];
}

@end