ObjFW  Diff

Differences From Artifact [b99d9d1539]:

To Artifact [692cbbd5b1]:

  • File src/OFRunLoop.m — part of check-in [d16ad96cbd] at 2018-12-07 01:33:47 on branch trunk — OFStream: Use a delegate for async operations

    The target / selector approach had several drawbacks:

    * It was inconvenient to use, as for every read or write, a target,
    selector and context would need to be specified.
    * It lacked any kind of type-safety and would not even warn about using
    a callback method with the wrong number of parameters.
    * It encouraged using a different callback method for each read or
    write call, which results in code that is hard to follow and also
    slower (as it needs to recreate the async operation with a new
    callback every time). (user: js, size: 28736) [annotate] [blame] [check-ins using]


70
71
72
73
74
75
76


77
78
79
80
81
82
83
}
@end

#ifdef OF_HAVE_SOCKETS
@interface OFRunLoop_QueueItem: OFObject
{
@public


	id _target;
	SEL _selector;
	id _context;
}

- (bool)handleObject: (id)object;
@end







>
>







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
}
@end

#ifdef OF_HAVE_SOCKETS
@interface OFRunLoop_QueueItem: OFObject
{
@public
	id _delegate;
	/* TODO: Remove once everything is moved to using delegates */
	id _target;
	SEL _selector;
	id _context;
}

- (bool)handleObject: (id)object;
@end
296
297
298
299
300
301
302

303
304
305
306
307
308
309
- (bool)handleObject: (id)object
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)dealloc
{

	[_target release];
	[_context release];

	[super dealloc];
}
@end








>







298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
- (bool)handleObject: (id)object
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)dealloc
{
	[_delegate release];
	[_target release];
	[_context release];

	[super dealloc];
}
@end

322
323
324
325
326
327
328




329
330



331



332
333
334

335
336
337
338
339
340
341
	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, _buffer, length, exception);
	else {
# endif




		bool (*func)(id, SEL, OFStream *, void *, size_t, id, id) =
		    (bool (*)(id, SEL, OFStream *, void *, size_t, id, id))



		    [_target methodForSelector: _selector];




		return func(_target, _selector, object, _buffer, length,
		    _context, exception);

# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc







>
>
>
>
|
|
>
>
>
|
>
>
>

|
<
>







325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354
	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, _buffer, length, exception);
	else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(stream:didReadIntoBuffer:length:)])
				return false;

			return [_delegate stream: object
			       didReadIntoBuffer: _buffer
					  length: length];
		} else {
			if ([_delegate respondsToSelector:
			    @selector(stream:didFailWithException:)])
				[_delegate	  stream: object
				    didFailWithException: exception];

			return false;

		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
372
373
374
375
376
377
378
379
380
381


382


383
384
385
386
387
388








389
390
391
392
393
394
395
		if (!_block(object, _buffer, _readLength, exception))
			return false;

		_readLength = 0;
		return true;
	} else {
# endif
		bool (*func)(id, SEL, OFStream *, void *, size_t, id, id) =
		    (bool (*)(id, SEL, OFStream *, void *, size_t, id, id))
		    [_target methodForSelector: _selector];





		if (!func(_target, _selector, object, _buffer, _readLength,
		    _context, exception))
			return false;

		_readLength = 0;
		return true;








# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc







|
<
|
>
>

>
>
|
<
|

|
|
>
>
>
>
>
>
>
>







385
386
387
388
389
390
391
392

393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
		if (!_block(object, _buffer, _readLength, exception))
			return false;

		_readLength = 0;
		return true;
	} else {
# endif
		if (exception == nil) {

			if (![_delegate respondsToSelector:
			    @selector(stream:didReadIntoBuffer:length:)])
				return false;

			if (![_delegate stream: object
			     didReadIntoBuffer: _buffer
					length: _readLength])

				return false;

			_readLength = 0;
			return true;
		} else {
			if ([_delegate respondsToSelector:
			    @selector(stream:didFailWithException:)])
				[_delegate	  stream: object
				    didFailWithException: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
418
419
420
421
422
423
424




425
426


427



428
429
430

431
432
433
434
435
436
437
		return true;

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, line, exception);
	else {
# endif




		bool (*func)(id, SEL, OFStream *, OFString *, id, id) =
		    (bool (*)(id, SEL, OFStream *, OFString *, id, id))


		    [_target methodForSelector: _selector];




		return func(_target, _selector, object, line, _context,
		    exception);

# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc







>
>
>
>
|
|
>
>
|
>
>
>

|
<
>







441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469
		return true;

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, line, exception);
	else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(stream:didReadLine:)])
				return false;

			return [_delegate stream: object
				     didReadLine: line];
		} else {
			if ([_delegate respondsToSelector:
			    @selector(stream:didFailWithException:)])
				[_delegate	  stream: object
				    didFailWithException: exception];

			return false;

		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
469
470
471
472
473
474
475
476
477
478

479
480

481
482
483
484
485
486
487








488
489
490
491
492
493
494
		if (_length == 0)
			return false;

		_writtenLength = 0;
		return true;
	} else {
# endif
		bool (*func)(id, SEL, OFStream *, const void *, size_t, id,
		    id) = (bool (*)(id, SEL, OFStream *, const void *, size_t,
		    id, id))[_target methodForSelector: _selector];


		_length = func(_target, _selector, object, &_buffer,

		    _writtenLength, _context, exception);

		if (_length == 0)
			return false;

		_writtenLength = 0;
		return true;








# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc







|
|
|
>

|
>
|

|
|

|
|
>
>
>
>
>
>
>
>







501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
		if (_length == 0)
			return false;

		_writtenLength = 0;
		return true;
	} else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(stream:didWriteBuffer:length:)])
				return false;

			_length = [_delegate stream: object
				     didWriteBuffer: &_buffer
					     length: _length];

			if (_length == 0)
				return false;

			_writtenLength = 0;
			return true;
		} else {
			if ([_delegate respondsToSelector:
			    @selector(stream:didFailWithException:)])
				[_delegate	  stream: object
				    didFailWithException: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
	objc_autoreleasePoolPop(pool);

+ (void)of_addAsyncReadForStream: (OFStream <OFReadyForReadingObserving> *)
				      stream
			  buffer: (void *)buffer
			  length: (size_t)length
			    mode: (of_run_loop_mode_t)mode
			  target: (id)target
			selector: (SEL)selector
			 context: (id)context
{
	ADD_READ(OFRunLoop_ReadQueueItem, stream, mode, {
		queueItem->_target = [target retain];
		queueItem->_selector = selector;
		queueItem->_context = [context retain];
		queueItem->_buffer = buffer;
		queueItem->_length = length;
	})
}

+ (void)of_addAsyncReadForStream: (OFStream <OFReadyForReadingObserving> *)
				      stream
			  buffer: (void *)buffer
		     exactLength: (size_t)exactLength
			    mode: (of_run_loop_mode_t)mode
			  target: (id)target
			selector: (SEL)selector
			 context: (id)context
{
	ADD_READ(OFRunLoop_ExactReadQueueItem, stream, mode, {
		queueItem->_target = [target retain];
		queueItem->_selector = selector;
		queueItem->_context = [context retain];
		queueItem->_buffer = buffer;
		queueItem->_exactLength = exactLength;
	})
}

+ (void)of_addAsyncReadLineForStream: (OFStream <OFReadyForReadingObserving> *)
					  stream
			    encoding: (of_string_encoding_t)encoding
				mode: (of_run_loop_mode_t)mode
			      target: (id)target
			    selector: (SEL)selector
			     context: (id)context
{
	ADD_READ(OFRunLoop_ReadLineQueueItem, stream, mode, {
		queueItem->_target = [target retain];
		queueItem->_selector = selector;
		queueItem->_context = [context retain];
		queueItem->_encoding = encoding;
	})
}

+ (void)of_addAsyncWriteForStream: (OFStream <OFReadyForWritingObserving> *)
				       stream
			   buffer: (const void *)buffer
			   length: (size_t)length
			     mode: (of_run_loop_mode_t)mode
			   target: (id)target
			 selector: (SEL)selector
			  context: (id)context
{
	ADD_WRITE(OFRunLoop_WriteQueueItem, stream, mode, {
		queueItem->_target = [target retain];
		queueItem->_selector = selector;
		queueItem->_context = [context retain];
		queueItem->_buffer = buffer;
		queueItem->_length = length;
	})
}

+ (void)of_addAsyncConnectForTCPSocket: (OFTCPSocket *)stream
				  mode: (of_run_loop_mode_t)mode







|
<
<


<
|
<










|
<
<


<
|
<









|
<
<


<
|
<









|
<
<


<
|
<







766
767
768
769
770
771
772
773


774
775

776

777
778
779
780
781
782
783
784
785
786
787


788
789

790

791
792
793
794
795
796
797
798
799
800


801
802

803

804
805
806
807
808
809
810
811
812
813


814
815

816

817
818
819
820
821
822
823
	objc_autoreleasePoolPop(pool);

+ (void)of_addAsyncReadForStream: (OFStream <OFReadyForReadingObserving> *)
				      stream
			  buffer: (void *)buffer
			  length: (size_t)length
			    mode: (of_run_loop_mode_t)mode
			delegate: (id <OFStreamDelegate>)delegate


{
	ADD_READ(OFRunLoop_ReadQueueItem, stream, mode, {

		queueItem->_delegate = [delegate retain];

		queueItem->_buffer = buffer;
		queueItem->_length = length;
	})
}

+ (void)of_addAsyncReadForStream: (OFStream <OFReadyForReadingObserving> *)
				      stream
			  buffer: (void *)buffer
		     exactLength: (size_t)exactLength
			    mode: (of_run_loop_mode_t)mode
			delegate: (id <OFStreamDelegate>)delegate


{
	ADD_READ(OFRunLoop_ExactReadQueueItem, stream, mode, {

		queueItem->_delegate = [delegate retain];

		queueItem->_buffer = buffer;
		queueItem->_exactLength = exactLength;
	})
}

+ (void)of_addAsyncReadLineForStream: (OFStream <OFReadyForReadingObserving> *)
					  stream
			    encoding: (of_string_encoding_t)encoding
				mode: (of_run_loop_mode_t)mode
			    delegate: (id <OFStreamDelegate>)delegate


{
	ADD_READ(OFRunLoop_ReadLineQueueItem, stream, mode, {

		queueItem->_delegate = [delegate retain];

		queueItem->_encoding = encoding;
	})
}

+ (void)of_addAsyncWriteForStream: (OFStream <OFReadyForWritingObserving> *)
				       stream
			   buffer: (const void *)buffer
			   length: (size_t)length
			     mode: (of_run_loop_mode_t)mode
			 delegate: (id <OFStreamDelegate>)delegate


{
	ADD_WRITE(OFRunLoop_WriteQueueItem, stream, mode, {

		queueItem->_delegate = [delegate retain];

		queueItem->_buffer = buffer;
		queueItem->_length = length;
	})
}

+ (void)of_addAsyncConnectForTCPSocket: (OFTCPSocket *)stream
				  mode: (of_run_loop_mode_t)mode