Line data Source code
1 0 : /*
2 :
3 : OOCocoa.h
4 :
5 : Import OpenStep main headers and define some Macisms and other compatibility
6 : stuff.
7 :
8 : Oolite
9 : Copyright (C) 2004-2013 Giles C Williams and contributors
10 :
11 : This program is free software; you can redistribute it and/or
12 : modify it under the terms of the GNU General Public License
13 : as published by the Free Software Foundation; either version 2
14 : of the License, or (at your option) any later version.
15 :
16 : This program is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : GNU General Public License for more details.
20 :
21 : You should have received a copy of the GNU General Public License
22 : along with this program; if not, write to the Free Software
23 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
24 : MA 02110-1301, USA.
25 :
26 : */
27 :
28 : /*
29 : Expressions like #define FOO (1 && !defined(NDEBUG)) are formally invalid,
30 : causing a warning in Clang. This lets us write #define FOO (1 && OOLITE_DEBUG)
31 : instead.
32 : */
33 : #ifdef NDEBUG
34 : #define OOLITE_DEBUG 0
35 : #else
36 0 : #define OOLITE_DEBUG 1
37 : #endif
38 :
39 : #if !OOLITE_DEBUG
40 : #define NS_BLOCK_ASSERTIONS 1
41 : #endif
42 :
43 :
44 : #include <math.h>
45 : #include <stdbool.h>
46 : #import <Foundation/Foundation.h>
47 :
48 : #ifdef GNUSTEP
49 : #define OOLITE_GNUSTEP 1
50 :
51 : #if (GNUSTEP_BASE_MAJOR_VERSION == 1 && GNUSTEP_BASE_MINOR_VERSION >= 20) || (GNUSTEP_BASE_MAJOR_VERSION > 1)
52 : #define OOLITE_GNUSTEP_1_20 1
53 : #else
54 : #error Oolite for non-Mac targets requires GNUstep 1.20.
55 : #endif
56 :
57 : #ifndef NSIntegerMax
58 : // Missing in GNUstep-base prior to 1.23.
59 : #define NSIntegerMax INTPTR_MAX
60 : #define NSIntegerMin INTPTR_MIN
61 : #define NSUIntegerMax UINTPTR_MAX
62 : #endif
63 :
64 : #else
65 : #import <AppKit/AppKit.h>
66 :
67 0 : #define OOLITE_MAC_OS_X 1
68 0 : #define OOLITE_SPEECH_SYNTH 1
69 :
70 : #if __LP64__
71 : #define OOLITE_64_BIT 1
72 : #endif
73 :
74 : /* Useful macro copied from GNUstep.
75 : */
76 : #ifndef DESTROY
77 0 : #define DESTROY(x) do { id x_ = x; x = nil; [x_ release]; } while (0)
78 : #endif
79 :
80 : #if defined MAC_OS_X_VERSION_10_7 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7
81 : #define OOLITE_MAC_OS_X_10_7 1
82 : #endif
83 :
84 : #if defined MAC_OS_X_VERSION_10_8 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8
85 : #define OOLITE_MAC_OS_X_10_8 1
86 : #endif
87 :
88 : #ifndef MAC_OS_X_VERSION_10_12
89 0 : typedef NSUInteger NSWindowStyleMask;
90 : #endif
91 : #endif
92 :
93 :
94 : #ifndef OOLITE_MAC_OS_X_10_7
95 0 : #define OOLITE_MAC_OS_X_10_7 0
96 : #endif
97 :
98 : #ifndef OOLITE_MAC_OS_X_10_8
99 0 : #define OOLITE_MAC_OS_X_10_8 0
100 : #endif
101 :
102 :
103 : #ifdef __clang__
104 : #define OOLITE_HAVE_CLANG 1
105 : #else
106 0 : #define OOLITE_HAVE_CLANG 0
107 : #endif
108 :
109 :
110 : #if defined(__GNUC__) && !OOLITE_HAVE_CLANG
111 : // GCC version; for instance, 40300 for 4.3.0. Deliberately undefined in Clang (which defines fake __GNUC__ macros for compatibility).
112 : #define OOLITE_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
113 : #endif
114 :
115 :
116 : #if OOLITE_GNUSTEP
117 : #include <stdint.h>
118 : #include <limits.h> // to get UINT_MAX
119 :
120 :
121 : #define OOLITE_SDL 1
122 :
123 : #ifdef WIN32
124 : #define OOLITE_WINDOWS 1
125 : #if defined(_WIN64)
126 : #define OOLITE_64_BIT 1
127 : #endif
128 : #endif
129 :
130 : #ifdef LINUX
131 : #define OOLITE_LINUX 1
132 : #endif
133 :
134 :
135 : #define true 1
136 : #define false 0
137 :
138 : #if !defined(MAX)
139 : #define MAX(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a > __b ? __a : __b; })
140 : #endif
141 :
142 : #if !defined(MIN)
143 : #define MIN(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })
144 : #endif
145 :
146 : #ifdef HAVE_LIBESPEAK
147 : #define OOLITE_SPEECH_SYNTH 1
148 : #define OOLITE_ESPEAK 1
149 : #endif
150 :
151 :
152 : // Pseudo-keywords used for AppKit UI bindings.
153 : #define IBOutlet /**/
154 : #define IBAction void
155 :
156 :
157 : #import "Comparison.h"
158 :
159 : /* Define AppKit constants for events */
160 : enum {
161 : NSUpArrowFunctionKey = 0xF700,
162 : NSDownArrowFunctionKey = 0xF701,
163 : NSLeftArrowFunctionKey = 0xF702,
164 : NSRightArrowFunctionKey = 0xF703,
165 : NSF1FunctionKey = 0xF704,
166 : NSF2FunctionKey = 0xF705,
167 : NSF3FunctionKey = 0xF706,
168 : NSF4FunctionKey = 0xF707,
169 : NSF5FunctionKey = 0xF708,
170 : NSF6FunctionKey = 0xF709,
171 : NSF7FunctionKey = 0xF70A,
172 : NSF8FunctionKey = 0xF70B,
173 : NSF9FunctionKey = 0xF70C,
174 : NSF10FunctionKey = 0xF70D,
175 : NSF11FunctionKey = 0xF70E,
176 : NSF12FunctionKey = 0xF70F,
177 : NSF13FunctionKey = 0xF710,
178 : NSF14FunctionKey = 0xF711,
179 : NSF15FunctionKey = 0xF712,
180 : NSF16FunctionKey = 0xF713,
181 : NSF17FunctionKey = 0xF714,
182 : NSF18FunctionKey = 0xF715,
183 : NSF19FunctionKey = 0xF716,
184 : NSF20FunctionKey = 0xF717,
185 : NSF21FunctionKey = 0xF718,
186 : NSF22FunctionKey = 0xF719,
187 : NSF23FunctionKey = 0xF71A,
188 : NSF24FunctionKey = 0xF71B,
189 : NSF25FunctionKey = 0xF71C,
190 : NSF26FunctionKey = 0xF71D,
191 : NSF27FunctionKey = 0xF71E,
192 : NSF28FunctionKey = 0xF71F,
193 : NSF29FunctionKey = 0xF720,
194 : NSF30FunctionKey = 0xF721,
195 : NSF31FunctionKey = 0xF722,
196 : NSF32FunctionKey = 0xF723,
197 : NSF33FunctionKey = 0xF724,
198 : NSF34FunctionKey = 0xF725,
199 : NSF35FunctionKey = 0xF726,
200 : NSInsertFunctionKey = 0xF727,
201 : NSDeleteFunctionKey = 0xF728,
202 : NSHomeFunctionKey = 0xF729,
203 : NSBeginFunctionKey = 0xF72A,
204 : NSEndFunctionKey = 0xF72B,
205 : NSPageUpFunctionKey = 0xF72C,
206 : NSPageDownFunctionKey = 0xF72D,
207 : NSPrintScreenFunctionKey = 0xF72E,
208 : NSScrollLockFunctionKey = 0xF72F,
209 : NSPauseFunctionKey = 0xF730,
210 : NSSysReqFunctionKey = 0xF731,
211 : NSBreakFunctionKey = 0xF732,
212 : NSResetFunctionKey = 0xF733,
213 : NSStopFunctionKey = 0xF734,
214 : NSMenuFunctionKey = 0xF735,
215 : NSUserFunctionKey = 0xF736,
216 : NSSystemFunctionKey = 0xF737,
217 : NSPrintFunctionKey = 0xF738,
218 : NSClearLineFunctionKey = 0xF739,
219 : NSClearDisplayFunctionKey = 0xF73A,
220 : NSInsertLineFunctionKey = 0xF73B,
221 : NSDeleteLineFunctionKey = 0xF73C,
222 : NSInsertCharFunctionKey = 0xF73D,
223 : NSDeleteCharFunctionKey = 0xF73E,
224 : NSPrevFunctionKey = 0xF73F,
225 : NSNextFunctionKey = 0xF740,
226 : NSSelectFunctionKey = 0xF741,
227 : NSExecuteFunctionKey = 0xF742,
228 : NSUndoFunctionKey = 0xF743,
229 : NSRedoFunctionKey = 0xF744,
230 : NSFindFunctionKey = 0xF745,
231 : NSHelpFunctionKey = 0xF746,
232 : NSModeSwitchFunctionKey = 0xF747
233 : };
234 :
235 : #endif
236 :
237 :
238 : #ifndef OOLITE_GNUSTEP
239 0 : #define OOLITE_GNUSTEP 0
240 : #endif
241 :
242 : #ifndef OOLITE_MAC_OS_X
243 : #define OOLITE_MAC_OS_X 0
244 : #endif
245 :
246 : #ifndef OOLITE_WINDOWS
247 0 : #define OOLITE_WINDOWS 0
248 : #endif
249 :
250 : #ifndef OOLITE_LINUX
251 0 : #define OOLITE_LINUX 0
252 : #endif
253 :
254 : #ifndef OOLITE_SDL
255 0 : #define OOLITE_SDL 0
256 : #endif
257 :
258 : #ifndef OOLITE_SPEECH_SYNTH
259 : #define OOLITE_SPEECH_SYNTH 0
260 : #endif
261 :
262 : #ifndef OOLITE_ESPEAK
263 0 : #define OOLITE_ESPEAK 0
264 : #endif
265 :
266 : #ifndef OOLITE_64_BIT
267 0 : #define OOLITE_64_BIT 0
268 : #endif
269 :
270 :
271 0 : #define OOLITE_PROPERTY_SYNTAX (OOLITE_MAC_OS_X || OOLITE_HAVE_CLANG)
272 :
273 :
274 : #import "OOLogging.h"
275 :
276 :
277 : @interface NSObject (OODescriptionComponents)
278 :
279 : /* In order to allow implementations of -description to inherit description
280 : components from superclasses, and to allow implementations of -description
281 : and -oo_jsDescription to share code, both are implemented as wrappers
282 : around -descriptionComponents. -descriptionComponents should provide
283 : information about an object without a class name or surrounding
284 : punctuation. -description will wrap the components like this:
285 : <ClassName 0xnnnnnnnn>{descriptionComponents}
286 : and -oo_jsDescription will wrap them like this:
287 : [oo_jsClassName descriptionComponents]
288 : */
289 0 : - (NSString *)descriptionComponents;
290 :
291 :
292 : /* A lot of Oolite's -description implementations are rather long, and many
293 : embed other descriptions. -shortDescription provides a truncated
294 : alternative, while -shortDescriptionComponents provides a
295 : -descriptionComponents-like mechanism to simplify implementation.
296 : */
297 0 : - (NSString *) shortDescription;
298 0 : - (NSString *) shortDescriptionComponents;
299 :
300 : @end
301 :
302 :
303 : #if OOLITE_MAC_OS_X
304 0 : #define OOLITE_RELEASE_PLIST_ERROR_STRINGS 1
305 : #else
306 : #define OOLITE_RELEASE_PLIST_ERROR_STRINGS 0
307 : #endif
308 :
309 :
310 : /* For some reason, return types for some comparison callbacks are typed
311 : NSInteger/int under OS X but (more sensibly) NSComparisonResult under
312 : GNUstep.
313 : */
314 : #if OOLITE_MAC_OS_X
315 0 : typedef NSInteger OOComparisonResult;
316 : #else
317 : typedef NSComparisonResult OOComparisonResult;
318 : #endif
319 :
320 :
321 : /* Fast enumeration (for (x in y) syntax) is supported in all Mac compilers
322 : when targeting 10.5 or later, and in gcc 4.6 with the GNU libobjc runtime.
323 : At the time of writing, GNUstep stable does not support gcc 4.6, but it
324 : already has support for the fast enumeration protocol in its collection
325 : classes.
326 :
327 : All release versions of clang support fast enumeration, assuming libobjc2
328 : or ObjectiveC2.framework is being used. We shall make that assumption.
329 :
330 : References:
331 : http://lists.gnu.org/archive/html/discuss-gnustep/2011-02/msg00019.html
332 : http://wiki.gnustep.org/index.php/ObjC2_FAQ
333 : -- Ahruman 2011-02-04
334 : */
335 : #if OOLITE_MAC_OS_X
336 0 : #define OOLITE_FAST_ENUMERATION 1
337 : #else
338 : #if __clang__
339 : #define OOLITE_FAST_ENUMERATION 1
340 : #elif defined (OOLITE_GNUSTEP)
341 : #define OOLITE_FAST_ENUMERATION (OOLITE_GCC_VERSION >= 40600)
342 : #endif
343 : #endif
344 :
345 : #ifndef OOLITE_FAST_ENUMERATION
346 : #define OOLITE_FAST_ENUMERATION 0
347 : #endif
348 :
349 :
350 : /* Enumeration macros:
351 : foreach(VAR, COLLECTION) enumerates the members of an array or set, setting
352 : the variable VAR to a member on each pass.
353 : foreachkey(VAR, DICT) enumerates the keys of a dictionary the same way.
354 :
355 : Example:
356 : id element = nil;
357 : foreach (element, array)
358 : {
359 : OOLog(@"element", @"%@", element);
360 : }
361 :
362 : These are based on macros by Jens Alfke.
363 : */
364 : #if OOLITE_FAST_ENUMERATION
365 0 : #define foreach(VAR, COLLECTION) for(VAR in COLLECTION)
366 0 : #define foreachkey(VAR, DICT) for(VAR in DICT)
367 : #else
368 : #define foreach(VAR, COLLECTION) for (NSEnumerator *ooForEachEnum = [(COLLECTION) objectEnumerator]; ((VAR) = [ooForEachEnum nextObject]); )
369 : #define foreachkey(VAR, DICT) for (NSEnumerator *ooForEachEnum = [(DICT) keyEnumerator]; ((VAR) = [ooForEachEnum nextObject]); )
370 : #endif
371 :
372 :
373 : /* Support for foreach() with NSEnumerators in GCC.
374 : It works without this with for (x in y) support, but we leave it defined
375 : to reduce differences between different build environments.
376 : */
377 : @interface NSEnumerator (OOForEachSupport)
378 0 : - (NSEnumerator *) objectEnumerator;
379 : @end
380 :
381 :
382 : /* @optional directive for protocols: added in Objective-C 2.0.
383 :
384 : As a nasty, nasty hack, the OOLITE_OPTIONAL(foo) macro allows an optional
385 : section with or without @optional. If @optional is not available, it
386 : actually ends the protocol and starts an appropriately-named informal
387 : protocol, i.e. a category on NSObject. Since it ends the protocol, there
388 : can only be one and there's no way to switch back to @required.
389 : */
390 : #ifndef OOLITE_HAVE_PROTOCOL_OPTIONAL
391 : #define OOLITE_HAVE_PROTOCOL_OPTIONAL (OOLITE_MAC_OS_X || OOLITE_HAVE_CLANG || OOLITE_GCC_VERSION >= 40700)
392 : #endif
393 :
394 : #if OOLITE_HAVE_PROTOCOL_OPTIONAL
395 0 : #define OOLITE_OPTIONAL(protocolName) @optional
396 : #else
397 : #define OOLITE_OPTIONAL(protocolName) @end @interface NSObject (protocolName ## Optional)
398 : #endif
399 :
400 :
401 : /* instancetype contextual keyword; added in Clang 3.0ish.
402 :
403 : Pseudo-type indicating that the return value of an instance method is an
404 : instance of the same class as the receiver, or for a class mothod, is an
405 : instance of that class.
406 :
407 : For example, given:
408 : @interface Foo: NSObject
409 : + (instancetype) fooWithProperty:(id)property;
410 : @end
411 :
412 : @interface Bar: Foo
413 : @end
414 :
415 : the type of [Bar fooWithProperty] is inferred to be Bar *.
416 :
417 : Clang treats methods of type id as instancetype when their names begin with
418 : +alloc, +new, -init, -autorelease, -retain, or -self.
419 :
420 : For compilers without instancetype support, id is appropriate but less
421 : type-safe.
422 :
423 : NOTE: it is not appropriate to use instancetype for a factory method which
424 : chooses which publicly-visible subclass to instantiate based on parameters.
425 : For instance, calling one of the OOMaterial convenience factory methods on
426 : OOShaderMaterial might return an OOSingleTextureMaterial, so the correct
427 : return type is either OOMaterial or id.
428 : On the other hand, it is appropriate on factory methods which just wrap
429 : the corresponding -init and/or -init + configuration through properties.
430 : (Such factory methods should be implemented in terms of [[self alloc]
431 : init...].)
432 : */
433 : #if __OBJC__ && !__has_feature(objc_instancetype)
434 : typedef id instancetype;
435 : #endif
436 :
437 :
438 : #ifndef OO_DEBUG
439 : // Defined by makefile/Xcode in debug builds.
440 : #define OO_DEBUG 0
441 : #endif
|