Skip to content

Commit

Permalink
Rewrote AEArrayEnumerate to be easier to debug
Browse files Browse the repository at this point in the history
Note that the code block should now follow the AEArrayEnumeratePointers/AEArrayEnumerateObjects call, not be its fourth argument:

    AEArrayEnumeratePointers(array, MyType *, item) {
       foo(item);
    }
  • Loading branch information
michaeltyson committed Jun 15, 2016
1 parent 5c1b675 commit 815978f
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 20 deletions.
10 changes: 10 additions & 0 deletions Tests/AEArrayTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ - (void)testItemLifecycle {
XCTAssertEqualObjects((__bridge id)AEArrayGetItem(token, 1), @(2));
XCTAssertEqualObjects((__bridge id)AEArrayGetItem(token, 2), @(3));

int i=1;
AEArrayEnumerateObjects(array, NSNumber *, number) {
XCTAssertEqualObjects(number, @(i++));
}

i=1;
AEArrayEnumeratePointers(array, void *, number) {
XCTAssertEqualObjects((__bridge NSNumber*)number, @(i++));
}

@autoreleasepool {
[array updateWithContentsOfArray:@[@(4), @(5)]];
}
Expand Down
51 changes: 33 additions & 18 deletions TheAmazingAudioEngine/Core Types/AEArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ typedef void * _Nullable (^AEArrayIndexedCustomMappingBlock)(id _Nonnull item, i
*/
typedef void (^AEArrayReleaseBlock)(id _Nonnull item, void * _Nonnull bytes);

// Some indirection macros required for AEArrayEnumerate
#define __AEArrayVar2(x, y) x ## y
#define __AEArrayVar(x, y) __AEArrayVar2(__ ## x ## _line_, y)

/*!
* Real-time safe array
*
Expand Down Expand Up @@ -228,6 +232,12 @@ void * _Nullable AEArrayGetItem(AEArrayToken _Nonnull token, int index);
* This convenience macro provides the ability to enumerate the objects
* in the array, in a realtime-thread safe fashion.
*
* Use it like:
*
* AEArrayEnumerateObjects(array, MyObjectType *, myVar) {
* // Do stuff with myVar, which is a MyObjectType *
* }
*
* Note: This macro calls AEArrayGetToken to access the array. Consequently, it is not
* recommended for use when you need to access the array in addition to this enumeration.
*
Expand All @@ -236,16 +246,15 @@ void * _Nullable AEArrayGetItem(AEArrayToken _Nonnull token, int index);
* @param array The array
* @param type The object type
* @param varname Name of object variable for inner loop
* @param inner Inner loop implementation
*/
#define AEArrayEnumerateObjects(array, type, varname, inner) { \
AEArrayToken _token = AEArrayGetToken(array); \
int _count = AEArrayGetCount(_token); \
for ( int _i=0; _i < _count; _i++ ) { \
__unsafe_unretained type varname = (__bridge type)AEArrayGetItem(_token, _i); \
{ inner; } \
} \
}
#define AEArrayEnumerateObjects(array, type, varname) \
AEArrayToken __AEArrayVar(token, __LINE__) = AEArrayGetToken(array); \
int __AEArrayVar(count, __LINE__) = AEArrayGetCount(__AEArrayVar(token, __LINE__)); \
int __AEArrayVar(i, __LINE__) = 0; \
for ( __unsafe_unretained type varname = __AEArrayVar(count, __LINE__) > 0 ? (__bridge type)AEArrayGetItem(__AEArrayVar(token, __LINE__), 0) : NULL; \
__AEArrayVar(i, __LINE__) < __AEArrayVar(count, __LINE__); \
__AEArrayVar(i, __LINE__)++, varname = __AEArrayVar(i, __LINE__) < __AEArrayVar(count, __LINE__) ? \
(__bridge type)AEArrayGetItem(__AEArrayVar(token, __LINE__), __AEArrayVar(i, __LINE__)) : NULL )

/*!
* Enumerate pointer types in the array, for use on audio thread
Expand All @@ -254,6 +263,12 @@ void * _Nullable AEArrayGetItem(AEArrayToken _Nonnull token, int index);
* in the array, in a realtime-thread safe fashion. It differs from AEArrayEnumerateObjects
* in that it is designed for use with pointer types, rather than objects.
*
* Use it like:
*
* AEArrayEnumeratePointers(array, MyCType *, myVar) {
* // Do stuff with myVar, which is a MyCType *
* }
*
* Note: This macro calls AEArrayGetToken to access the array. Consequently, it is not
* recommended for use when you need to access the array in addition to this enumeration.
*
Expand All @@ -262,16 +277,16 @@ void * _Nullable AEArrayGetItem(AEArrayToken _Nonnull token, int index);
* @param array The array
* @param type The pointer type (e.g. struct myStruct *)
* @param varname Name of pointer variable for inner loop
* @param inner Inner loop implementation
*/
#define AEArrayEnumeratePointers(array, type, varname, inner) { \
AEArrayToken _token = AEArrayGetToken(array); \
int _count = AEArrayGetCount(_token); \
for ( int _i=0; _i < _count; _i++ ) { \
type varname = (type)AEArrayGetItem(_token, _i); \
{ inner; } \
} \
}
#define AEArrayEnumeratePointers(array, type, varname) \
AEArrayToken __AEArrayVar(token, __LINE__) = AEArrayGetToken(array); \
int __AEArrayVar(count, __LINE__) = AEArrayGetCount(__AEArrayVar(token, __LINE__)); \
int __AEArrayVar(i, __LINE__) = 0; \
for ( type varname = __AEArrayVar(count, __LINE__) > 0 ? (type)AEArrayGetItem(__AEArrayVar(token, __LINE__), 0) : NULL; \
__AEArrayVar(i, __LINE__) < __AEArrayVar(count, __LINE__); \
__AEArrayVar(i, __LINE__)++, varname = __AEArrayVar(i, __LINE__) < __AEArrayVar(count, __LINE__) ? \
(type)AEArrayGetItem(__AEArrayVar(token, __LINE__), __AEArrayVar(i, __LINE__)) : NULL )


//! Number of values in array
@property (nonatomic, readonly) int count;
Expand Down
4 changes: 2 additions & 2 deletions TheAmazingAudioEngine/Modules/Generation/AEMixerModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static void AEMixerModuleProcess(__unsafe_unretained AEMixerModule * self, const
AEAudioBufferListSilence(abl, 0, context->frames);

// Run each module, applying volume/balance then mixing into our output buffer
AEArrayEnumeratePointers(self->_array, AEMixerModuleSubModuleEntry *, entry, {
AEArrayEnumeratePointers(self->_array, AEMixerModuleSubModuleEntry *, entry) {

if ( !AEModuleIsActive(entry->module) ) {
// Module is idle; skip (and skip the volume/balance ramp, too)
Expand Down Expand Up @@ -140,7 +140,7 @@ static void AEMixerModuleProcess(__unsafe_unretained AEMixerModule * self, const
entry->targetVolume, &entry->currentVolume,
entry->targetBalance, &entry->currentBalance);
AEBufferStackMix(context->stack, 2);
});
}
}

- (AEMixerModuleSubModuleEntry *)newEntryForModule:(AEModule *)module volume:(float)volume balance:(float)balance {
Expand Down

0 comments on commit 815978f

Please sign in to comment.