From b95ade40c075ed23525f28d571b0175040194ed2 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 9 Feb 2022 00:19:20 +0000 Subject: [PATCH] Begin work on `core:sys/darwin/Foundation` --- core/sys/darwin/Foundation/Foundation.odin | 1 + core/sys/darwin/Foundation/NSArray.odin | 26 ++++ .../darwin/Foundation/NSAutoreleasePool.odin | 15 +++ core/sys/darwin/Foundation/NSData.odin | 12 ++ core/sys/darwin/Foundation/NSDate.odin | 8 ++ core/sys/darwin/Foundation/NSDictionary.odin | 27 +++++ core/sys/darwin/Foundation/NSLock.odin | 29 +++++ .../sys/darwin/Foundation/NSNotification.odin | 16 +++ core/sys/darwin/Foundation/NSNumber.odin | 45 +++++++ core/sys/darwin/Foundation/NSObject.odin | 66 +++++++++++ core/sys/darwin/Foundation/NSRange.odin | 22 ++++ core/sys/darwin/Foundation/NSString.odin | 112 ++++++++++++++++++ core/sys/darwin/Foundation/NSTypes.odin | 35 ++++++ 13 files changed, 414 insertions(+) create mode 100644 core/sys/darwin/Foundation/Foundation.odin create mode 100644 core/sys/darwin/Foundation/NSArray.odin create mode 100644 core/sys/darwin/Foundation/NSAutoreleasePool.odin create mode 100644 core/sys/darwin/Foundation/NSData.odin create mode 100644 core/sys/darwin/Foundation/NSDate.odin create mode 100644 core/sys/darwin/Foundation/NSDictionary.odin create mode 100644 core/sys/darwin/Foundation/NSLock.odin create mode 100644 core/sys/darwin/Foundation/NSNotification.odin create mode 100644 core/sys/darwin/Foundation/NSNumber.odin create mode 100644 core/sys/darwin/Foundation/NSObject.odin create mode 100644 core/sys/darwin/Foundation/NSRange.odin create mode 100644 core/sys/darwin/Foundation/NSString.odin create mode 100644 core/sys/darwin/Foundation/NSTypes.odin diff --git a/core/sys/darwin/Foundation/Foundation.odin b/core/sys/darwin/Foundation/Foundation.odin new file mode 100644 index 000000000..c69b10ddb --- /dev/null +++ b/core/sys/darwin/Foundation/Foundation.odin @@ -0,0 +1 @@ +package objc_Foundation diff --git a/core/sys/darwin/Foundation/NSArray.odin b/core/sys/darwin/Foundation/NSArray.odin new file mode 100644 index 000000000..7544c278c --- /dev/null +++ b/core/sys/darwin/Foundation/NSArray.odin @@ -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") +} diff --git a/core/sys/darwin/Foundation/NSAutoreleasePool.odin b/core/sys/darwin/Foundation/NSAutoreleasePool.odin new file mode 100644 index 000000000..5ff2a6f1d --- /dev/null +++ b/core/sys/darwin/Foundation/NSAutoreleasePool.odin @@ -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") +} + diff --git a/core/sys/darwin/Foundation/NSData.odin b/core/sys/darwin/Foundation/NSData.odin new file mode 100644 index 000000000..93bb3ae0e --- /dev/null +++ b/core/sys/darwin/Foundation/NSData.odin @@ -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") +} \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSDate.odin b/core/sys/darwin/Foundation/NSDate.odin new file mode 100644 index 000000000..4b298ee24 --- /dev/null +++ b/core/sys/darwin/Foundation/NSDate.odin @@ -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) +} \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSDictionary.odin b/core/sys/darwin/Foundation/NSDictionary.odin new file mode 100644 index 000000000..19ea8a491 --- /dev/null +++ b/core/sys/darwin/Foundation/NSDictionary.odin @@ -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 \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSLock.odin b/core/sys/darwin/Foundation/NSLock.odin new file mode 100644 index 000000000..0e76dfc62 --- /dev/null +++ b/core/sys/darwin/Foundation/NSLock.odin @@ -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") +} \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSNotification.odin b/core/sys/darwin/Foundation/NSNotification.odin new file mode 100644 index 000000000..fa9160cc8 --- /dev/null +++ b/core/sys/darwin/Foundation/NSNotification.odin @@ -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") +} \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSNumber.odin b/core/sys/darwin/Foundation/NSNumber.odin new file mode 100644 index 000000000..d41f1e6d2 --- /dev/null +++ b/core/sys/darwin/Foundation/NSNumber.odin @@ -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 \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSObject.odin b/core/sys/darwin/Foundation/NSObject.odin new file mode 100644 index 000000000..cf15dd68d --- /dev/null +++ b/core/sys/darwin/Foundation/NSObject.odin @@ -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 \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSRange.odin b/core/sys/darwin/Foundation/NSRange.odin new file mode 100644 index 000000000..74ce595a3 --- /dev/null +++ b/core/sys/darwin/Foundation/NSRange.odin @@ -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 +} \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSString.odin b/core/sys/darwin/Foundation/NSString.odin new file mode 100644 index 000000000..857e27f12 --- /dev/null +++ b/core/sys/darwin/Foundation/NSString.odin @@ -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) +} \ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSTypes.odin b/core/sys/darwin/Foundation/NSTypes.odin new file mode 100644 index 000000000..47f75630f --- /dev/null +++ b/core/sys/darwin/Foundation/NSTypes.odin @@ -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