Begin work on core:sys/darwin/Foundation

This commit is contained in:
gingerBill
2022-02-09 00:19:20 +00:00
parent 340838c878
commit b95ade40c0
13 changed files with 414 additions and 0 deletions

View File

@@ -0,0 +1 @@
package objc_Foundation

View File

@@ -0,0 +1,26 @@
package objc_Foundation
import "core:intrinsics"
@(objc_class="NSArray")
Array :: struct($T: typeid) where intrinsics.type_is_pointer(T), intrinsics.type_is_subtype_of(T, ^Object) {using _: Copying(Array(T))}
Array_initWithObjects :: proc(self: ^$A/Array($T), objects: [^]^Object, count: UInteger) -> ^A {
return msgSend(^A, "initWithObjects:count:", objects, count)
}
Array_initWithCoder :: proc(self: ^$A/Array($T), coder: ^Coder) -> ^A {
return msgSend(^A, "initWithCoder:", coder)
}
Array_objectAtIndex :: proc(self: ^Array($T), index: UInteger) -> ^Object {
return msgSend(^Object, self, "objectAtIndex:", index)
}
Array_object :: proc(self: ^Array($T), index: UInteger) -> ^T {
return (^T)(Array_objectAtIndex(self, index))
}
Array_count :: proc(self: ^Array($T)) -> UInteger {
return msgSend(UInteger, self, "count")
}

View File

@@ -0,0 +1,15 @@
package objc_Foundation
@(objc_class="NSAutoreleasePool")
AutoreleasePool :: struct {using _: Object}
AutoreleasePool_drain :: proc(self: ^AutoreleasePool) {
msgSend(nil, self, "drain")
}
AutoreleasePool_addObject :: proc(self: ^AutoreleasePool, obj: ^Object) {
msgSend(nil, self, "addObject:", obj)
}
AutoreleasePool_showPools :: proc(self: ^AutoreleasePool, obj: ^Object) {
msgSend(nil, self, "showPools")
}

View File

@@ -0,0 +1,12 @@
package objc_Foundation
@(objc_class="NSData")
Data :: struct {using _: Copying(Data)}
Data_mutableBytes :: proc(self: ^Data) -> rawptr {
return msgSend(rawptr, self, "mutableBytes")
}
Data_length :: proc(self: ^Data) -> UInteger {
return msgSend(UInteger, self, "length")
}

View File

@@ -0,0 +1,8 @@
package objc_Foundation
@(objc_class="NSDate")
Date :: struct {using _: Copying(Date)}
Date_dateWithTimeIntervalSinceNow :: proc(secs: TimeInterval) -> ^Date {
return msgSend(^Date, Date, "dateWithTimeIntervalSinceNow:", secs)
}

View File

@@ -0,0 +1,27 @@
package objc_Foundation
@(objc_class="NSDictionary")
Dictionary :: struct {using _: Copying(Dictionary)}
Dictionary_dictionary :: proc() -> ^Dictionary {
return msgSend(^Dictionary, Dictionary, "dictionary")
}
Dictionary_dictionaryWithObject :: proc(object: ^Object, forKey: ^Object) -> ^Dictionary {
return msgSend(^Dictionary, Dictionary, "dictionaryWithObject:forKey:", object, forKey)
}
Dictionary_dictionaryWithObjects :: proc(objects: [^]^Object, forKeys: [^]^Object, count: UInteger) -> ^Dictionary {
return msgSend(^Dictionary, Dictionary, "dictionaryWithObjects:forKeys:count", objects, forKeys, count)
}
Dictionary_initWithObjects :: proc(self: ^Dictionary, objects: [^]^Object, forKeys: [^]^Object, count: UInteger) -> ^Dictionary {
return msgSend(^Dictionary, self, "initWithObjects:forKeys:count", objects, forKeys, count)
}
Dictionary_objectForKey :: proc(self: ^Dictionary, key: ^Object) -> ^Object {
return msgSend(^Dictionary, self, "objectForKey:", key)
}
// TODO(bill): enumerator

View File

@@ -0,0 +1,29 @@
package objc_Foundation
Locking :: struct($T: typeid) {using _: Object}
Locking_lock :: proc(self: ^Locking($T)) {
msgSend(nil, self, "lock")
}
Locking_unlock :: proc(self: ^Locking($T)) {
msgSend(nil, self, "unlock")
}
@(objc_class="NSCondition")
Condition :: struct {using _: Locking(Condition) }
Condition_wait :: proc(self: ^Condition) {
msgSend(nil, self, "wait")
}
Condition_waitUntilDate :: proc(self: ^Condition, limit: ^Date) -> BOOL {
return msgSend(BOOL, self, "waitUntilDate:", limit)
}
Condition_signal :: proc(self: ^Condition) {
msgSend(nil, self, "signal")
}
Condition_broadcast :: proc(self: ^Condition) {
msgSend(nil, self, "broadcast")
}

View File

@@ -0,0 +1,16 @@
package objc_Foundation
@(objc_class="NSNotification")
Notification :: struct{using _: Object}
Notification_name :: proc(self: ^Notification) -> ^String {
return msgSend(^String, self, "name")
}
Notification_object :: proc(self: ^Notification) -> ^Object {
return msgSend(^Object, self, "object")
}
Notification_userInfo :: proc(self: ^Notification) -> ^Dictionary {
return msgSend(^Dictionary, self, "userInfo")
}

View File

@@ -0,0 +1,45 @@
package objc_Foundation
@(objc_class="NSValue")
Value :: struct{using _: Copying(Value)}
@(objc_class="NSNumber")
Number :: struct{using _: Copying(Number), using _: Value}
Value_valueWithBytes :: proc(value: rawptr, type: cstring) -> ^Value {
return msgSend(^Value, Value, "valueWithBytes:objCType:", value, type)
}
Value_valueWithPointer :: proc(pointer: rawptr) -> ^Value {
return msgSend(^Value, Value, "valueWithPointer:", pointer)
}
Value_initWithBytes :: proc(value: rawptr, type: cstring) -> ^Value {
return msgSend(^Value, Value, "initWithBytes:objCType:", value, type)
}
Value_initWithCoder :: proc(coder: ^Coder) -> ^Value {
return msgSend(^Value, Value, "initWithCoder:", coder)
}
Value_getValue :: proc(self: ^Value, value: rawptr, size: UInteger) {
msgSend(nil, self, "getValue:size:", value, size)
}
Value_objCType :: proc(self: ^Value) -> cstring {
return msgSend(cstring, self, "objCType")
}
Value_isEqualToValue :: proc(self, other: ^Value) -> BOOL {
return msgSend(BOOL, self, "isEqualToValue:", other)
}
Value_pointerValue :: proc(self: ^Value) -> rawptr {
return msgSend(rawptr, self, "pointerValue")
}
// TODO(bill): Number methods

View File

@@ -0,0 +1,66 @@
package objc_Foundation
import "core:intrinsics"
methodSignatureForSelector :: proc "c" (obj: ^Object, selector: SEL) -> rawptr {
return msgSend(rawptr, obj, "methodSignatureForSelector:", selector)
}
respondsToSelector :: proc "c" (obj: ^Object, selector: SEL) -> BOOL {
return msgSend(BOOL, obj, "respondsToSelector:", selector)
}
msgSendSafeCheck :: proc "c" (obj: ^Object, selector: SEL) -> BOOL {
return respondsToSelector(obj, selector) || methodSignatureForSelector(obj, selector) != nil
}
@(objc_class="NSObject")
Object :: struct {using _: intrinsics.objc_object}
@(objc_class="NSObject")
Copying :: struct($T: typeid) {using _: Object}
alloc :: proc($T: typeid) -> ^T where intrinsics.type_is_subtype_of(T, Object) {
return msgSend(^T, T, "alloc")
}
init :: proc(self: ^$T) -> ^T where intrinsics.type_is_subtype_of(T, Object){
return msgSend(^T, self, "init")
}
retain :: proc(self: ^$T) -> ^T where intrinsics.type_is_subtype_of(T, Object) {
return msgSend(^T, self, "retain")
}
release :: proc(self: ^$T) where intrinsics.type_is_subtype_of(T, Object) {
msgSend(nil, self, "release")
}
retainCount :: proc(self: ^$T) -> UInteger where intrinsics.type_is_subtype_of(T, Object) {
return msgSend(UInteger, self, "retainCount")
}
copy :: proc(self: ^Copying($T)) -> ^T where intrinsics.type_is_subtype_of(T, Object) {
return msgSend(^T, self, "copy")
}
hash :: proc(self: ^Object) -> UInteger {
return msgSend(UInteger, self, "hash")
}
isEqual :: proc(self, pObject: ^Object) -> BOOL {
return msgSend(BOOL, self, "isEqual:", pObject)
}
description :: proc(self: ^Object) -> ^String {
return msgSend(^String, self, "description")
}
debugDescription :: proc(self: ^Object) -> ^String {
if msgSendSafeCheck(self, intrinsics.objc_selector_name("debugDescription")) {
return msgSend(^String, self, "debugDescription")
}
return nil
}
@(objc_class="NSCoder")
Coder :: struct {using _: Object}
// TODO(bill): Implement all the methods for this massive type

View File

@@ -0,0 +1,22 @@
package objc_Foundation
Range :: struct {
location: UInteger,
length: UInteger,
}
Range_Make :: proc(loc, len: UInteger) -> Range {
return Range{loc, len}
}
Range_Equal :: proc(a, b: Range) -> BOOL {
return a == b
}
Range_LocationInRange :: proc(self: Range, loc: UInteger) -> BOOL {
return !((loc < self.location) && ((loc - self.location) < self.length))
}
Range_Max :: proc(self: Range) -> UInteger {
return self.location + self.length
}

View File

@@ -0,0 +1,112 @@
package objc_Foundation
foreign import "system:Foundation.framework"
@(objc_class="NSString")
String :: struct {using _: Copying(String)}
StringEncoding :: enum UInteger {
ASCII = 1,
NEXTSTEP = 2,
JapaneseEUC = 3,
UTF8 = 4,
ISOLatin1 = 5,
Symbol = 6,
NonLossyASCII = 7,
ShiftJIS = 8,
ISOLatin2 = 9,
Unicode = 10,
WindowsCP1251 = 11,
WindowsCP1252 = 12,
WindowsCP1253 = 13,
WindowsCP1254 = 14,
WindowsCP1250 = 15,
ISO2022JP = 21,
MacOSRoman = 30,
UTF16 = Unicode,
UTF16BigEndian = 0x90000100,
UTF16LittleEndian = 0x94000100,
UTF32 = 0x8c000100,
UTF32BigEndian = 0x98000100,
UTF32LittleEndian = 0x9c000100,
}
StringCompareOptions :: distinct bit_set[StringCompareOption; UInteger]
StringCompareOption :: enum UInteger {
CaseInsensitive = 0,
LiteralSearch = 1,
BackwardsSearch = 2,
AnchoredSearch = 3,
NumericSearch = 6,
DiacriticInsensitive = 7,
WidthInsensitive = 8,
ForcedOrdering = 9,
RegularExpression = 10,
}
unichar :: distinct u16
foreign Foundation {
__CFStringMakeConstantString :: proc "c" (c: cstring) -> ^String ---
}
AT :: MakeConstantString
MakeConstantString :: proc "c" (#const c: cstring) -> ^String {
return __CFStringMakeConstantString(c)
}
String_initWithString :: proc(self: ^String, other: ^String) -> ^String {
return msgSend(^String, self, "initWithString:", other)
}
String_initWithCString :: proc(self: ^String, pString: cstring, encoding: StringEncoding) -> ^String {
return msgSend(^String, self, "initWithCstring:encoding:", pString, encoding)
}
String_initWithBytesNoCopy :: proc(self: ^String, pBytes: rawptr, length: UInteger, encoding: StringEncoding, freeWhenDone: bool) -> ^String {
return msgSend(^String, self, "initWithBytesNoCopy:length:encoding:freeWhenDone:", pBytes, length, encoding, freeWhenDone)
}
String_initWithOdinString :: proc(self: ^String, str: string) -> ^String {
return String_initWithBytesNoCopy(self, raw_data(str), UInteger(len(str)), .UTF8, false)
}
String_characterAtIndex :: proc(self: ^String, index: UInteger) -> unichar {
return msgSend(unichar, self, "characterAtIndex:", index)
}
String_length :: proc(self: ^String) -> UInteger {
return msgSend(UInteger, self, "length")
}
String_cStringUsingEncoding :: proc(self: ^String, encoding: StringEncoding) -> cstring {
return msgSend(cstring, self, "cStringUsingEncoding:", encoding)
}
String_UTFString :: proc(self: ^String) -> cstring {
return msgSend(cstring, self, "UTFString")
}
String_OdinString :: proc(self: ^String) -> string {
return string(String_UTFString(self))
}
String_maximumLengthOfBytesUsingEncoding :: proc(self: ^String, encoding: StringEncoding) -> UInteger {
return msgSend(UInteger, self, "maximumLengthOfBytesUsingEncoding:", encoding)
}
String_lengthOfBytesUsingEncoding :: proc(self: ^String, encoding: StringEncoding) -> UInteger {
return msgSend(UInteger, self, "lengthOfBytesUsingEncoding:", encoding)
}
String_isEqualToString :: proc(self, other: ^String) -> BOOL {
return msgSend(BOOL, self, "isEqualToString:", other)
}
String_rangeOfString :: proc(self, other: ^String, options: StringCompareOptions) -> Range {
return msgSend(Range, self, "rangeOfString:options:", other, options)
}

View File

@@ -0,0 +1,35 @@
package objc_Foundation
import "core:intrinsics"
@(private) msgSend :: intrinsics.objc_send
id :: ^intrinsics.objc_object
SEL :: ^intrinsics.objc_selector
Class :: ^intrinsics.objc_class
TimeInterval :: distinct f64
Integer :: distinct int
UInteger :: distinct uint
IntegerMax :: max(Integer)
Integermin :: min(Integer)
UIntegerMax :: max(UInteger)
BOOL :: bool // TODO(bill): should this be `distinct`?
YES :: true
NO :: false
OperatingSystemVersion :: struct #packed {
majorVersion: Integer,
minorVersion: Integer,
patchVersion: Integer,
}
ComparisonResult :: enum Integer {
OrderedAscending = -1,
OrderedSame = 0,
OrderedDescending = 1,
}
NotFound :: IntegerMax