blob: d27a97c82d7967d28f0e7ff361ad800bf4c2141f [file] [log] [blame]
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#import <Foundation/NSObject.h>
#import <Foundation/NSThread.h>
#include "util.h"
typedef struct {
double x;
double y;
double z;
double w;
} Vec4;
@interface DummyObject : NSObject {
int32_t* counter;
}
+ (instancetype)newWithCounter:(int32_t*) _counter;
- (instancetype)initWithCounter:(int32_t*) _counter;
- (void)setCounter:(int32_t*) _counter;
- (void)dealloc;
@end
@implementation DummyObject
+ (instancetype)newWithCounter:(int32_t*) _counter {
return [[DummyObject alloc] initWithCounter: _counter];
}
- (instancetype)initWithCounter:(int32_t*) _counter {
counter = _counter;
++*counter;
return [super init];
}
- (void)setCounter:(int32_t*) _counter {
counter = _counter;
++*counter;
}
- (void)dealloc {
if (counter != nil) --*counter;
[super dealloc];
}
@end
typedef int32_t (^IntBlock)(int32_t);
typedef float (^FloatBlock)(float);
typedef double (^DoubleBlock)(double);
typedef Vec4 (^Vec4Block)(Vec4);
typedef void (^VoidBlock)();
typedef DummyObject* (^ObjectBlock)(DummyObject*);
typedef DummyObject* _Nullable (^NullableObjectBlock)(DummyObject* _Nullable);
typedef IntBlock (^BlockBlock)(IntBlock);
// Wrapper around a block, so that our Dart code can test creating and invoking
// blocks in Objective C code.
@interface BlockTester : NSObject {
IntBlock myBlock;
}
+ (BlockTester*)makeFromBlock:(IntBlock)block;
+ (BlockTester*)makeFromMultiplier:(int32_t)mult;
- (int32_t)call:(int32_t)x;
- (IntBlock)getBlock;
- (void)pokeBlock;
+ (void)callOnSameThread:(VoidBlock)block;
+ (NSThread*)callOnNewThread:(VoidBlock)block;
+ (float)callFloatBlock:(FloatBlock)block;
+ (double)callDoubleBlock:(DoubleBlock)block;
+ (Vec4)callVec4Block:(Vec4Block)block;
+ (DummyObject*)callObjectBlock:(ObjectBlock)block NS_RETURNS_RETAINED;
+ (nullable DummyObject*)callNullableObjectBlock:(NullableObjectBlock)block;
+ (IntBlock)newBlock:(BlockBlock)block withMult:(int)mult;
+ (BlockBlock)newBlockBlock:(int)mult;
@end
@implementation BlockTester
+ (BlockTester*)makeFromBlock:(IntBlock)block {
BlockTester* bt = [BlockTester new];
bt->myBlock = block;
return bt;
}
+ (BlockTester*)makeFromMultiplier:(int32_t)mult {
BlockTester* bt = [BlockTester new];
bt->myBlock = [^int32_t(int32_t x) {
return x * mult;
} copy];
return bt;
}
- (int32_t)call:(int32_t)x {
return myBlock(x);
}
- (IntBlock)getBlock {
return myBlock;
}
- (void)pokeBlock {
// Used to repro https://github.com/dart-lang/ffigen/issues/376
[[myBlock retain] release];
}
+ (void)callOnSameThread:(VoidBlock)block {
block();
}
+ (NSThread*)callOnNewThread:(VoidBlock)block {
return [[NSThread alloc] initWithBlock: block];
}
+ (float)callFloatBlock:(FloatBlock)block {
return block(1.23);
}
+ (double)callDoubleBlock:(DoubleBlock)block {
return block(1.23);
}
+ (Vec4)callVec4Block:(Vec4Block)block {
Vec4 vec4;
vec4.x = 1.2;
vec4.y = 3.4;
vec4.z = 5.6;
vec4.w = 7.8;
return block(vec4);
}
+ (DummyObject*)callObjectBlock:(ObjectBlock)block NS_RETURNS_RETAINED {
return block([DummyObject new]);
}
+ (nullable DummyObject*)callNullableObjectBlock:(NullableObjectBlock)block {
return block(nil);
}
+ (IntBlock)newBlock:(BlockBlock)block withMult:(int)mult {
return block([^int(int x) {
return mult * x;
} copy]);
// ^ copy this stack allocated block to the heap.
}
+ (BlockBlock)newBlockBlock:(int)mult {
return [^IntBlock(IntBlock block) {
return [^int(int x) {
return mult * block(x);
} copy];
} copy];
}
@end