@lucent-lang/lucent 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app.plugin.js +92 -0
- package/bin/lucent.cjs +16 -0
- package/core/index.cjs +11 -0
- package/dist/bench-CR3E7e2e.js +304 -0
- package/dist/build-CAIrRSYA.js +7 -0
- package/dist/build-check-QozuNJm5.js +92 -0
- package/dist/check-1SCmYlqA.js +7 -0
- package/dist/clean-BVwpbJ5K.js +35 -0
- package/dist/cli.js +406 -0
- package/dist/codes-CIuwXt1S.js +260 -0
- package/dist/compiler.js +4 -0
- package/dist/confirm-BYF5eY3q.js +34 -0
- package/dist/dashboard-B-NzjjaN.js +91 -0
- package/dist/dev-BYWMP7oC.js +221 -0
- package/dist/diagnostic-BM9sXmwl.js +30 -0
- package/dist/diff-BTDo3Sro.js +44 -0
- package/dist/doctor-C0PrfWT6.js +230 -0
- package/dist/doctor-DdR4JnVc.js +30 -0
- package/dist/explain--vV1oaRl.js +35 -0
- package/dist/format-D9fnIMEx.js +53 -0
- package/dist/init-gIabu1S_.js +207 -0
- package/dist/live-steps-BGcWFM9M.js +79 -0
- package/dist/new-module-C2mtb0op.js +66 -0
- package/dist/package-manager-BnxwCySi.js +30 -0
- package/dist/package.json +3 -0
- package/dist/packages-HyskKIsY.js +150 -0
- package/dist/pipeline-CH7-2cxu.js +232 -0
- package/dist/project-D8tEet0k.js +150 -0
- package/dist/sdk-coverage-BoW_3Efd.js +64 -0
- package/dist/sdk-prefetch-mo04JDZV.js +89 -0
- package/dist/sdk-search-Iv4K3-8a.js +124 -0
- package/dist/sdk-show-CkrdlqlP.js +74 -0
- package/dist/sdks-Xoyiy2E4.js +28 -0
- package/dist/src-BD7f1_aZ.js +11493 -0
- package/dist/steps--_h-FFS7.js +24 -0
- package/dist/theme-uv5bc0aK.js +134 -0
- package/dist/tsconfig-S4uyLNzf.js +59 -0
- package/dist/version-bqpIO5sP.js +26 -0
- package/gradle/lucent-classpath.gradle +38 -0
- package/gradle/lucent-classpath.init.gradle +6 -0
- package/gradle/lucent.gradle +24 -0
- package/lib/core.cjs +106 -0
- package/lib/globals.d.ts +36 -0
- package/lib/sdk/android.d.ts +8 -0
- package/lib/sdk/core.d.ts +23 -0
- package/lib/sdk/ios.d.ts +33 -0
- package/lib/sdk/platform.d.ts +8 -0
- package/lib/sdk/thread.d.ts +8 -0
- package/metro/index.cjs +72 -0
- package/metro/index.d.ts +6 -0
- package/metro/transformer.cjs +70 -0
- package/package.json +61 -0
- package/runtime/cpp/lucent/abort.cpp +61 -0
- package/runtime/cpp/lucent/abort.h +54 -0
- package/runtime/cpp/lucent/array.h +442 -0
- package/runtime/cpp/lucent/async.h +236 -0
- package/runtime/cpp/lucent/builtins.cpp +163 -0
- package/runtime/cpp/lucent/bytes.h +129 -0
- package/runtime/cpp/lucent/console.h +17 -0
- package/runtime/cpp/lucent/core.h +129 -0
- package/runtime/cpp/lucent/date.cpp +441 -0
- package/runtime/cpp/lucent/date.h +82 -0
- package/runtime/cpp/lucent/equality.h +87 -0
- package/runtime/cpp/lucent/function.h +61 -0
- package/runtime/cpp/lucent/generator.h +244 -0
- package/runtime/cpp/lucent/helpers.h +226 -0
- package/runtime/cpp/lucent/jserror.cpp +51 -0
- package/runtime/cpp/lucent/jserror.h +66 -0
- package/runtime/cpp/lucent/jsi/convert.cpp +202 -0
- package/runtime/cpp/lucent/jsi/convert.h +612 -0
- package/runtime/cpp/lucent/jsi/host.cpp +322 -0
- package/runtime/cpp/lucent/jsi/host.h +166 -0
- package/runtime/cpp/lucent/json.cpp +243 -0
- package/runtime/cpp/lucent/json.h +164 -0
- package/runtime/cpp/lucent/json_parse.h +138 -0
- package/runtime/cpp/lucent/jsstring.cpp +874 -0
- package/runtime/cpp/lucent/jsstring.h +152 -0
- package/runtime/cpp/lucent/lucent.h +24 -0
- package/runtime/cpp/lucent/map.h +344 -0
- package/runtime/cpp/lucent/native.cpp +76 -0
- package/runtime/cpp/lucent/native.h +116 -0
- package/runtime/cpp/lucent/number.cpp +545 -0
- package/runtime/cpp/lucent/number.h +190 -0
- package/runtime/cpp/lucent/ops.h +165 -0
- package/runtime/cpp/lucent/platform/android.cpp +437 -0
- package/runtime/cpp/lucent/platform/android.h +117 -0
- package/runtime/cpp/lucent/platform/ios.h +297 -0
- package/runtime/cpp/lucent/platform/ios.mm +31 -0
- package/runtime/cpp/lucent/regexp.cpp +440 -0
- package/runtime/cpp/lucent/regexp.h +107 -0
- package/runtime/cpp/lucent/scheduler.cpp +153 -0
- package/runtime/cpp/lucent/scheduler.h +160 -0
- package/runtime/cpp/lucent/unicode_data.inc +4051 -0
- package/runtime/cpp/rn/LucentModule.cpp +35 -0
- package/runtime/cpp/rn/LucentModule.h +37 -0
- package/runtime/cpp/third_party/quickjs/LICENSE +22 -0
- package/runtime/cpp/third_party/quickjs/README.md +11 -0
- package/runtime/cpp/third_party/quickjs/cutils.c +641 -0
- package/runtime/cpp/third_party/quickjs/cutils.h +457 -0
- package/runtime/cpp/third_party/quickjs/libregexp-opcode.h +73 -0
- package/runtime/cpp/third_party/quickjs/libregexp.c +3448 -0
- package/runtime/cpp/third_party/quickjs/libregexp.h +65 -0
- package/runtime/cpp/third_party/quickjs/libunicode-table.h +5206 -0
- package/runtime/cpp/third_party/quickjs/libunicode.c +2124 -0
- package/runtime/cpp/third_party/quickjs/libunicode.h +196 -0
- package/runtime/js/index.d.ts +7 -0
- package/runtime/js/index.js +60 -0
- package/runtime/native/LucentNative.podspec +28 -0
- package/runtime/native/android/CMakeLists.txt +51 -0
- package/runtime/native/android/build.gradle +22 -0
- package/runtime/native/android/include/lucentnative.h +16 -0
- package/runtime/native/android/src/main/java/dev/lucent/LucentPackage.java +25 -0
- package/runtime/native/android/src/main/java/dev/lucent/NativeProxy.java +132 -0
- package/runtime/native/ios/LucentRegistration.mm +23 -0
- package/runtime/native/package.json +6 -0
- package/runtime/native/react-native.config.js +19 -0
- package/runtime/test/jsi/harness.cpp +181 -0
- package/schemas/build.schema.json +152 -0
- package/schemas/check.schema.json +74 -0
- package/schemas/doctor.schema.json +40 -0
- package/schemas/lucent.schema.json +43 -0
- package/schemas/sdk-prefetch.schema.json +37 -0
- package/schemas/sdk-search.schema.json +54 -0
- package/ts-plugin/index.d.ts +4 -0
- package/ts-plugin/index.js +99 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
// Lucent runtime — Objective-C glue helpers for *.ios.lucent.ts units
|
|
2
|
+
// (compiled as Objective-C++ with ARC).
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#import <objc/runtime.h>
|
|
6
|
+
#import <Foundation/Foundation.h>
|
|
7
|
+
|
|
8
|
+
#include <variant>
|
|
9
|
+
|
|
10
|
+
#include "../array.h"
|
|
11
|
+
#include "../bytes.h"
|
|
12
|
+
#include "../date.h"
|
|
13
|
+
#include "../jsstring.h"
|
|
14
|
+
#include "../map.h"
|
|
15
|
+
#include "../native.h"
|
|
16
|
+
|
|
17
|
+
namespace lucent::objc {
|
|
18
|
+
|
|
19
|
+
void releaseOnMain(void* retained);
|
|
20
|
+
|
|
21
|
+
/// A Lucent reference to `obj` (retained). Throws TypeError for nil.
|
|
22
|
+
inline NativeRef wrap(id obj, const char* what) {
|
|
23
|
+
if (!obj) throw Exception(makeError(String::fromLatin1("TypeError"), String::fromUtf8(std::string(what) + " returned nil")));
|
|
24
|
+
return NativeRef((__bridge_retained void*)obj, releaseOnMain, nullptr);
|
|
25
|
+
}
|
|
26
|
+
inline Opt<NativeRef> wrapOpt(id obj) {
|
|
27
|
+
if (!obj) return Opt<NativeRef>(null);
|
|
28
|
+
return NativeRef((__bridge_retained void*)obj, releaseOnMain, nullptr);
|
|
29
|
+
}
|
|
30
|
+
inline id unwrap(const NativeRef& r) { return (__bridge id)r.get(); }
|
|
31
|
+
inline id unwrap(const Opt<NativeRef>& r) { return r.has() ? (__bridge id)r.get().get() : nil; }
|
|
32
|
+
|
|
33
|
+
inline NSString* toNSString(const String& s) {
|
|
34
|
+
std::u16string units = s.toUtf16();
|
|
35
|
+
return [NSString stringWithCharacters:reinterpret_cast<const unichar*>(units.data()) length:units.size()];
|
|
36
|
+
}
|
|
37
|
+
inline String fromNSString(NSString* s, const char* what) {
|
|
38
|
+
if (!s) throw Exception(makeError(String::fromLatin1("TypeError"), String::fromUtf8(std::string(what) + " returned nil")));
|
|
39
|
+
NSUInteger n = s.length;
|
|
40
|
+
std::u16string units(n, u'\0');
|
|
41
|
+
[s getCharacters:reinterpret_cast<unichar*>(units.data()) range:NSMakeRange(0, n)];
|
|
42
|
+
return String::fromUtf16(units);
|
|
43
|
+
}
|
|
44
|
+
inline Opt<String> fromNSStringOpt(NSString* s) {
|
|
45
|
+
if (!s) return Opt<String>(null);
|
|
46
|
+
return fromNSString(s, "");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
inline NSString* toNSStringOpt(const Opt<String>& s) { return s.has() ? toNSString(s.get()) : nil; }
|
|
50
|
+
|
|
51
|
+
[[noreturn]] inline void returnedNil(const char* what) {
|
|
52
|
+
throw Exception(makeError(String::fromLatin1("TypeError"), String::fromUtf8(std::string(what) + " returned nil")));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// --- values copied at the boundary ---------------------------------------------------
|
|
56
|
+
|
|
57
|
+
inline NSData* toNSData(const Bytes& b) { return [NSData dataWithBytes:b.data() length:b.size()]; }
|
|
58
|
+
inline Bytes fromNSData(NSData* d, const char* what) {
|
|
59
|
+
if (!d) returnedNil(what);
|
|
60
|
+
return Bytes::copy(static_cast<const uint8_t*>(d.bytes), d.length);
|
|
61
|
+
}
|
|
62
|
+
inline Opt<Bytes> fromNSDataOpt(NSData* d) { return d ? Opt<Bytes>(fromNSData(d, "")) : Opt<Bytes>(null); }
|
|
63
|
+
|
|
64
|
+
inline NSDate* toNSDate(const Date& d) { return [NSDate dateWithTimeIntervalSince1970:d->getTime() / 1000.0]; }
|
|
65
|
+
inline Date fromNSDate(NSDate* d, const char* what) {
|
|
66
|
+
if (!d) returnedNil(what);
|
|
67
|
+
return makeDate(d.timeIntervalSince1970 * 1000.0);
|
|
68
|
+
}
|
|
69
|
+
inline Opt<Date> fromNSDateOpt(NSDate* d) { return d ? Opt<Date>(fromNSDate(d, "")) : Opt<Date>(null); }
|
|
70
|
+
|
|
71
|
+
template <class T, class F>
|
|
72
|
+
NSArray* toNSArray(const Array<T>& a, F toObject) {
|
|
73
|
+
NSMutableArray* out = [NSMutableArray arrayWithCapacity:a.size()];
|
|
74
|
+
for (size_t i = 0; i < a.size(); i++) {
|
|
75
|
+
id v = toObject(a.at(i));
|
|
76
|
+
[out addObject:v ?: [NSNull null]];
|
|
77
|
+
}
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
template <class T, class F>
|
|
81
|
+
Array<T> fromNSArray(NSArray* a, F fromObject, const char* what) {
|
|
82
|
+
if (!a) returnedNil(what);
|
|
83
|
+
Array<T> out;
|
|
84
|
+
for (id v in a) out.push(fromObject(v));
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
template <class T, class F>
|
|
88
|
+
Opt<Array<T>> fromNSArrayOpt(NSArray* a, F fromObject) {
|
|
89
|
+
return a ? Opt<Array<T>>(fromNSArray<T>(a, fromObject, "")) : Opt<Array<T>>(null);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
template <class T, class F>
|
|
93
|
+
NSSet* toNSSet(const Set<T>& s, F toObject) {
|
|
94
|
+
NSMutableSet* out = [NSMutableSet setWithCapacity:static_cast<NSUInteger>(s.size())];
|
|
95
|
+
Array<T> items = s.values();
|
|
96
|
+
for (size_t i = 0; i < items.size(); i++) {
|
|
97
|
+
id v = toObject(items.at(i));
|
|
98
|
+
[out addObject:v ?: [NSNull null]];
|
|
99
|
+
}
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
102
|
+
template <class T, class F>
|
|
103
|
+
Set<T> fromNSSet(NSSet* s, F fromObject, const char* what) {
|
|
104
|
+
if (!s) returnedNil(what);
|
|
105
|
+
Set<T> out;
|
|
106
|
+
for (id v in s) out.add(fromObject(v));
|
|
107
|
+
return out;
|
|
108
|
+
}
|
|
109
|
+
template <class T, class F>
|
|
110
|
+
Opt<Set<T>> fromNSSetOpt(NSSet* s, F fromObject) {
|
|
111
|
+
return s ? Opt<Set<T>>(fromNSSet<T>(s, fromObject, "")) : Opt<Set<T>>(null);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
template <class V, class F>
|
|
115
|
+
NSDictionary* toNSDictionary(const Dict<V>& d, F toObject) {
|
|
116
|
+
NSMutableDictionary* out = [NSMutableDictionary dictionary];
|
|
117
|
+
Array<String> keys = d.keys();
|
|
118
|
+
for (size_t i = 0; i < keys.size(); i++) {
|
|
119
|
+
id v = toObject(d.get(keys.at(i)).get());
|
|
120
|
+
out[toNSString(keys.at(i))] = v ?: [NSNull null];
|
|
121
|
+
}
|
|
122
|
+
return out;
|
|
123
|
+
}
|
|
124
|
+
/// Entries with keys that are not strings are left out.
|
|
125
|
+
template <class V, class F>
|
|
126
|
+
Dict<V> fromNSDictionary(NSDictionary* d, F fromObject, const char* what) {
|
|
127
|
+
if (!d) returnedNil(what);
|
|
128
|
+
Dict<V> out;
|
|
129
|
+
for (id k in d) {
|
|
130
|
+
if (![k isKindOfClass:[NSString class]]) continue;
|
|
131
|
+
out.set(fromNSString(k, what), fromObject(d[k]));
|
|
132
|
+
}
|
|
133
|
+
return out;
|
|
134
|
+
}
|
|
135
|
+
template <class V, class F>
|
|
136
|
+
Opt<Dict<V>> fromNSDictionaryOpt(NSDictionary* d, F fromObject) {
|
|
137
|
+
return d ? Opt<Dict<V>>(fromNSDictionary<V>(d, fromObject, "")) : Opt<Dict<V>>(null);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/// Applies `f` to a value that may be absent; absent gives a null pointer.
|
|
141
|
+
template <class T, class F>
|
|
142
|
+
auto ifPresent(const Opt<T>& v, F f) -> decltype(f(v.get())) {
|
|
143
|
+
return v.has() ? f(v.get()) : nullptr;
|
|
144
|
+
}
|
|
145
|
+
template <class T, class F>
|
|
146
|
+
requires(!IsOpt<T>::value)
|
|
147
|
+
auto ifPresent(const T& v, F f) {
|
|
148
|
+
return f(v);
|
|
149
|
+
}
|
|
150
|
+
template <class F>
|
|
151
|
+
std::nullptr_t ifPresent(const Null&, F) {
|
|
152
|
+
return nullptr;
|
|
153
|
+
}
|
|
154
|
+
template <class F>
|
|
155
|
+
std::nullptr_t ifPresent(const Undefined&, F) {
|
|
156
|
+
return nullptr;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// --- Any (id) --------------------------------------------------------------------------
|
|
160
|
+
|
|
161
|
+
inline id toId(const String& s) { return toNSString(s); }
|
|
162
|
+
inline id toId(double v) { return @(v); }
|
|
163
|
+
inline id toId(bool v) { return @(v); }
|
|
164
|
+
inline id toId(const Bytes& b) { return toNSData(b); }
|
|
165
|
+
inline id toId(const Date& d) { return toNSDate(d); }
|
|
166
|
+
inline id toId(const NativeRef& r) { return unwrap(r); }
|
|
167
|
+
inline id toId(const Null&) { return nil; }
|
|
168
|
+
inline id toId(const Undefined&) { return nil; }
|
|
169
|
+
template <class... Ts>
|
|
170
|
+
id toId(const std::variant<Ts...>& v) {
|
|
171
|
+
return std::visit([](const auto& x) -> id { return toId(x); }, v);
|
|
172
|
+
}
|
|
173
|
+
template <class T>
|
|
174
|
+
id toId(const Opt<T>& v) {
|
|
175
|
+
return v.has() ? toId(v.get()) : nil;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/// `asString(value)` and friends from lucent:ios: Swift's `as? String`.
|
|
179
|
+
inline Opt<String> asString(const Opt<NativeRef>& o) {
|
|
180
|
+
id x = unwrap(o);
|
|
181
|
+
return [x isKindOfClass:[NSString class]] ? Opt<String>(fromNSString(x, "")) : Opt<String>(null);
|
|
182
|
+
}
|
|
183
|
+
inline Opt<double> asNumber(const Opt<NativeRef>& o) {
|
|
184
|
+
id x = unwrap(o);
|
|
185
|
+
return [x isKindOfClass:[NSNumber class]] ? Opt<double>([(NSNumber*)x doubleValue]) : Opt<double>(null);
|
|
186
|
+
}
|
|
187
|
+
inline Opt<bool> asBoolean(const Opt<NativeRef>& o) {
|
|
188
|
+
id x = unwrap(o);
|
|
189
|
+
return [x isKindOfClass:[NSNumber class]] ? Opt<bool>(static_cast<bool>([(NSNumber*)x boolValue])) : Opt<bool>(null);
|
|
190
|
+
}
|
|
191
|
+
inline Opt<Bytes> asData(const Opt<NativeRef>& o) {
|
|
192
|
+
id x = unwrap(o);
|
|
193
|
+
return [x isKindOfClass:[NSData class]] ? Opt<Bytes>(fromNSData(x, "")) : Opt<Bytes>(null);
|
|
194
|
+
}
|
|
195
|
+
inline Opt<Date> asDate(const Opt<NativeRef>& o) {
|
|
196
|
+
id x = unwrap(o);
|
|
197
|
+
return [x isKindOfClass:[NSDate class]] ? Opt<Date>(fromNSDate(x, "")) : Opt<Date>(null);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// --- errors ----------------------------------------------------------------------------
|
|
201
|
+
|
|
202
|
+
/// An NSError as a Lucent error: code "<domain>:<code>".
|
|
203
|
+
inline Error fromNSError(NSError* e, const char* what) {
|
|
204
|
+
if (!e) throw Exception(makeError(String::fromLatin1("TypeError"), String::fromUtf8(std::string(what) + " got no error")));
|
|
205
|
+
Error err = makeError(String::fromLatin1("Error"), fromNSString(e.localizedDescription ?: @"", ""));
|
|
206
|
+
err->code = fromNSString([NSString stringWithFormat:@"%@:%ld", e.domain, (long)e.code], "");
|
|
207
|
+
return err;
|
|
208
|
+
}
|
|
209
|
+
inline Opt<Error> fromNSErrorOpt(NSError* e) { return e ? Opt<Error>(fromNSError(e, "")) : Opt<Error>(null); }
|
|
210
|
+
|
|
211
|
+
/// A method's NSError** result as a thrown Lucent error.
|
|
212
|
+
inline void throwIfError(NSError* e) {
|
|
213
|
+
if (e) throw Exception(fromNSError(e, ""));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// --- blocks ----------------------------------------------------------------------------
|
|
217
|
+
|
|
218
|
+
/// One Objective-C object per `key` (a Lucent object) while the object is
|
|
219
|
+
/// alive: `make` creates it. Callers hold the Lucent lock.
|
|
220
|
+
inline id cachedObject(const void* key, id (^make)(void)) {
|
|
221
|
+
static NSMapTable* objects = [NSMapTable strongToWeakObjectsMapTable];
|
|
222
|
+
NSValue* k = [NSValue valueWithPointer:key];
|
|
223
|
+
id o = [objects objectForKey:k];
|
|
224
|
+
if (!o) {
|
|
225
|
+
o = make();
|
|
226
|
+
[objects setObject:o forKey:k];
|
|
227
|
+
}
|
|
228
|
+
return o;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/// A C++ callable as a heap block of type `Block` (the platform may keep it).
|
|
232
|
+
template <class Block, class F>
|
|
233
|
+
Block block(F f) {
|
|
234
|
+
Block b = std::move(f);
|
|
235
|
+
return b;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// --- out-parameters --------------------------------------------------------------------
|
|
239
|
+
|
|
240
|
+
/// `new Out()` from lucent:ios: a CFTypeRef a C function writes into.
|
|
241
|
+
struct OutSlot {
|
|
242
|
+
CFTypeRef value = nullptr;
|
|
243
|
+
bool owned = false;
|
|
244
|
+
~OutSlot() {
|
|
245
|
+
if (value && owned) CFRelease(value);
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
inline NativeRef makeOut() {
|
|
249
|
+
return NativeRef(new OutSlot(), [](void* p) { delete static_cast<OutSlot*>(p); }, nullptr);
|
|
250
|
+
}
|
|
251
|
+
/// The slot for a call; `owned` per CoreFoundation's Create/Copy rule.
|
|
252
|
+
inline CFTypeRef* outSlot(const NativeRef& r, bool owned) {
|
|
253
|
+
auto* s = static_cast<OutSlot*>(r.get());
|
|
254
|
+
if (s->value && s->owned) CFRelease(s->value);
|
|
255
|
+
s->value = nullptr;
|
|
256
|
+
s->owned = owned;
|
|
257
|
+
return &s->value;
|
|
258
|
+
}
|
|
259
|
+
inline CFTypeRef* outSlot(const Opt<NativeRef>& r, bool owned) { return r.has() ? outSlot(r.get(), owned) : nullptr; }
|
|
260
|
+
inline Opt<NativeRef> outValue(const NativeRef& r) { return wrapOpt((__bridge id) static_cast<OutSlot*>(r.get())->value); }
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* An NSError** argument writing into an Out<Error>: the method writes an
|
|
264
|
+
* autoreleased error, which the slot retains when the call's full
|
|
265
|
+
* expression ends (before any autorelease pool drains).
|
|
266
|
+
*/
|
|
267
|
+
class ErrorOut {
|
|
268
|
+
public:
|
|
269
|
+
explicit ErrorOut(const NativeRef& out) : slot_(static_cast<OutSlot*>(out.get())) {}
|
|
270
|
+
explicit ErrorOut(const Opt<NativeRef>& out) : slot_(out.has() ? static_cast<OutSlot*>(out.get().get()) : nullptr) {}
|
|
271
|
+
~ErrorOut() {
|
|
272
|
+
if (!slot_) return;
|
|
273
|
+
if (slot_->value && slot_->owned) CFRelease(slot_->value);
|
|
274
|
+
slot_->value = error_ ? CFBridgingRetain(error_) : nullptr;
|
|
275
|
+
slot_->owned = true;
|
|
276
|
+
}
|
|
277
|
+
ErrorOut(const ErrorOut&) = delete;
|
|
278
|
+
ErrorOut& operator=(const ErrorOut&) = delete;
|
|
279
|
+
NSError* __autoreleasing* ptr() { return slot_ ? reinterpret_cast<NSError* __autoreleasing*>(&error_) : nullptr; }
|
|
280
|
+
|
|
281
|
+
private:
|
|
282
|
+
OutSlot* slot_;
|
|
283
|
+
NSError* __unsafe_unretained error_ = nil;
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
inline Opt<Error> outError(const NativeRef& r) { return fromNSErrorOpt((__bridge NSError*) static_cast<OutSlot*>(r.get())->value); }
|
|
287
|
+
|
|
288
|
+
/// `mainQueue()` from lucent:ios: the main dispatch queue (an OS object).
|
|
289
|
+
inline NativeRef mainQueue() { return wrap(dispatch_get_main_queue(), "mainQueue"); }
|
|
290
|
+
|
|
291
|
+
/// `available("ios", major, minor)`.
|
|
292
|
+
inline bool available(double major, double minor = 0) {
|
|
293
|
+
NSOperatingSystemVersion v = {static_cast<NSInteger>(major), static_cast<NSInteger>(minor), 0};
|
|
294
|
+
return [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:v];
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
} // namespace lucent::objc
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Lucent runtime — iOS: the main queue, and releasing objects there.
|
|
2
|
+
#include "ios.h"
|
|
3
|
+
|
|
4
|
+
#import <dispatch/dispatch.h>
|
|
5
|
+
|
|
6
|
+
namespace lucent {
|
|
7
|
+
|
|
8
|
+
void postToMain(std::function<void()> job) {
|
|
9
|
+
auto* heap = new std::function<void()>(std::move(job));
|
|
10
|
+
dispatch_async_f(dispatch_get_main_queue(), heap, [](void* p) {
|
|
11
|
+
std::unique_ptr<std::function<void()>> j(static_cast<std::function<void()>*>(p));
|
|
12
|
+
(*j)();
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
bool onMainThread() { return [NSThread isMainThread]; }
|
|
17
|
+
|
|
18
|
+
namespace objc {
|
|
19
|
+
|
|
20
|
+
// UIKit objects must be deallocated on the main thread; the last Lucent
|
|
21
|
+
// reference can go on any thread.
|
|
22
|
+
void releaseOnMain(void* retained) {
|
|
23
|
+
if ([NSThread isMainThread]) {
|
|
24
|
+
CFRelease(retained);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
dispatch_async_f(dispatch_get_main_queue(), retained, [](void* p) { CFRelease(p); });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
} // namespace objc
|
|
31
|
+
} // namespace lucent
|