80 lines
2.0 KiB
Objective-C
80 lines
2.0 KiB
Objective-C
// Copyright (c) 2024, 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.
|
|
|
|
#include "protocol.h"
|
|
|
|
#import <Foundation/NSDictionary.h>
|
|
#import <Foundation/NSInvocation.h>
|
|
#import <Foundation/NSValue.h>
|
|
#import <objc/runtime.h>
|
|
|
|
#if !__has_feature(objc_arc)
|
|
#error "This file must be compiled with ARC enabled"
|
|
#endif
|
|
|
|
@implementation DOBJCDartProtocolBuilder {
|
|
@public NSMutableDictionary *methods;
|
|
Class clazz;
|
|
}
|
|
|
|
- (instancetype)initWithClassName: (const char*)name {
|
|
methods = [NSMutableDictionary new];
|
|
clazz = objc_allocateClassPair([DOBJCDartProtocol class], name, 0);
|
|
return self;
|
|
}
|
|
|
|
- (void)implementMethod:(SEL)sel withBlock:(void*)block
|
|
withTrampoline:(void*)trampoline withSignature:(char*)signature {
|
|
class_addMethod(clazz, sel, trampoline, signature);
|
|
NSValue* key = [NSValue valueWithPointer:sel];
|
|
@synchronized(methods) {
|
|
[methods setObject:(__bridge id)block forKey:key];
|
|
}
|
|
}
|
|
|
|
- (void)addProtocol:(Protocol*) protocol {
|
|
class_addProtocol(clazz, protocol);
|
|
}
|
|
|
|
- (void)registerClass {
|
|
objc_registerClassPair(clazz);
|
|
}
|
|
|
|
- (DOBJCDartProtocol*)buildInstance: (Dart_Port)port {
|
|
DOBJCDartProtocol* inst = [clazz alloc];
|
|
return [inst initDOBJCDartProtocolFromDartProtocolBuilder:self
|
|
withDisposePort:port];
|
|
}
|
|
|
|
- (void)dealloc {
|
|
objc_disposeClassPair(clazz);
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation DOBJCDartProtocol {
|
|
DOBJCDartProtocolBuilder* builder;
|
|
Dart_Port dispose_port;
|
|
}
|
|
|
|
- (id)getDOBJCDartProtocolMethodForSelector:(SEL)sel {
|
|
return [builder->methods objectForKey:[NSValue valueWithPointer:sel]];
|
|
}
|
|
|
|
- (instancetype)initDOBJCDartProtocolFromDartProtocolBuilder:
|
|
(DOBJCDartProtocolBuilder*)builder_
|
|
withDisposePort:(Dart_Port)port {
|
|
builder = builder_;
|
|
dispose_port = port;
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc {
|
|
if (dispose_port != ILLEGAL_PORT) {
|
|
Dart_PostInteger_DL(dispose_port, 0);
|
|
}
|
|
}
|
|
|
|
@end
|