1/*
2 * Copyright (c) 2006-2008, The RubyCocoa Project.
3 * Copyright (c) 2001-2006, FUJIMOTO Hisakuni.
4 * All Rights Reserved.
5 *
6 * RubyCocoa is free software, covered under either the Ruby's license or the
7 * LGPL. See the COPYRIGHT file for more information.
8 */
9
10#ifndef _INTERNAL_MACROS_H_
11#define _INTERNAL_MACROS_H_
12
13#import <Foundation/Foundation.h>
14
15#define RUBYCOCOA_SUPPRESS_EXCEPTION_LOGGING_P \
16  RTEST(rb_gv_get("RUBYCOCOA_SUPPRESS_EXCEPTION_LOGGING"))
17
18extern VALUE rubycocoa_debug;
19
20#define RUBY_DEBUG_P      RTEST(ruby_debug)
21#define RUBYCOCOA_DEBUG_P RTEST(rubycocoa_debug)
22#define DEBUG_P           (RUBY_DEBUG_P || RUBYCOCOA_DEBUG_P)
23
24#define ASSERT_ALLOC(x) do { if (x == NULL) rb_fatal("can't allocate memory"); } while (0)
25
26#define DLOG(mod, fmt, args...)                  \
27  do {                                           \
28    if (DEBUG_P) {                             \
29      NSAutoreleasePool * pool;                  \
30                                                 \
31      pool = [[NSAutoreleasePool alloc] init];   \
32      NSLog(@mod @" : " @fmt, ##args);           \
33      [pool release];                            \
34    }                                            \
35  }                                              \
36  while (0)
37
38/* syntax: POOL_DO(the_pool) { ... } END_POOL(the_pool); */
39#define POOL_DO(POOL)   { id POOL = [[NSAutoreleasePool alloc] init];
40#define END_POOL(POOL)  [(POOL) release]; }
41
42/* flag for calling Init_stack frequently */
43extern int rubycocoa_frequently_init_stack();
44#define FREQUENTLY_INIT_STACK_FLAG rubycocoa_frequently_init_stack()
45
46extern NSThread *rubycocoaThread;
47extern NSRunLoop *rubycocoaRunLoop;
48
49#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
50#import <CoreFoundation/CFRunLoop.h>
51extern CFRunLoopRef CFRunLoopGetMain(void);
52#define DISPATCH_ON_RUBYCOCOA_THREAD(self, sel) \
53  do { \
54    assert(rubycocoaRunLoop != nil); \
55    if ([rubycocoaRunLoop getCFRunLoop] != CFRunLoopGetMain()) \
56      [[NSException exceptionWithName:@"DispatchRubyCocoaThreadError" message:@"cannot forward %s to %@ because RubyCocoa doesn't run in the main thread" userInfo:nil] raise]; \
57    else \
58      [self performSelectorOnMainThread:sel withObject:nil waitUntilDone:YES]; \
59  } \
60  while (0)
61#else
62#define DISPATCH_ON_RUBYCOCOA_THREAD(self, sel) \
63  do { \
64    assert(rubycocoaThread != nil); \
65    [self performSelector:sel onThread:rubycocoaThread withObject:nil waitUntilDone:YES]; \
66  } \
67  while (0)
68#endif
69
70/* invoke-based undo requires some special handling on 10.6 */
71#define IS_UNDOPROXY(obj) (object_getClass(obj) == objc_getClass("NSUndoManagerProxy"))
72
73#endif	// _INTERNAL_MACROS_H_
74