// // DSUtilityDefines.h // Shared categories // // Created by David Sinclair on Sat May 07 2005. // Copyright (c) 2002 - 2007 Dejal Systems, LLC. All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // Redistributions of source code must retain this list of conditions and the following disclaimer. // // The name of Dejal Systems, LLC may not be used to endorse or promote products derived from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR // PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THIS SOFTWARE. // // Global function defines: #define sqr(x) pow(x,2) #define DSTestBit(flag, mask) ((flag & mask) == mask) #define DSSetBit(flag, mask, value) flag = value ? flag | mask : flag & ~mask #define DSSmaller(first, second) ((first < second) ? first : second) #define DSBigger(first, second) ((first > second) ? first : second) #define DSClassAvailable(className) (NSClassFromString(className) != nil) #define DSClassSelectorAvailable(className, selector) (NSClassFromString(className) != nil && [NSClassFromString(className) respondsToSelector:selector]) #define DSDoubleClickInterval (GetDblTime() / 60.0) #define DSDoubleClickWithSlopInterval ((GetDblTime() / 60.0) + 0.1) // Convert minutes, hours, days, etc into a NSTimeInterval (seconds): #define DSIntervalFromMinutes(minutes) ((minutes) * 60.0) #define DSIntervalFromHours(hours) ((hours) * 3600.0) #define DSIntervalFromDays(days) ((days) * 86400.0) #define DSIntervalFromWeeks(weeks) ((weeks) * 604800.0) #define DSIntervalFromMonths(months) ((months) * 2628000.0) #define DSIntervalFromYears(years) ((years) * 31536000.0) // Convert a NSTimeInterval (seconds) into minutes, hours, days, etc: #define DSMinutesFromInterval(seconds) ((seconds) / 60.0) #define DSHoursFromInterval(seconds) ((seconds) / 3600.0) #define DSDaysFromInterval(seconds) ((seconds) / 86400.0) #define DSWeeksFromInterval(seconds) ((seconds) / 604800.0) #define DSMonthsFromInterval(seconds) ((seconds) / 2628000.0) #define DSYearsFromInterval(seconds) ((seconds) / 31536000.0) // Seeds the random values. Call this before calling DSRandomRange for the first time (okay to call again, too): static inline void DSRandomSeed() { NSCalendarDate *date = [NSCalendarDate calendarDate]; srandom([date secondOfMinute] * [date minuteOfHour] * [date hourOfDay] * [date dayOfYear]); } // Returns a random number between first and last, inclusive (couldn't do as define, as the compiler gave an error if the divisor was in the same line). Note: should call DSRandomSeed() at least once before this to seed the random values: static inline int DSRandomRange(int first, int last) { int divisor = last - first + 1; return (random() % divisor) + first; } // Check if any object is empty: static inline BOOL IsEmpty(id object) { return (object == nil) || ([object respondsToSelector:@selector(length)] && [(NSData *)object length] == 0) || ([object respondsToSelector:@selector(count)] && [(NSArray *)object count] == 0); } // Check if any object is not empty (similar to the -containsSomething category methods): static inline BOOL ContainsSomething(id object) { return ([object respondsToSelector:@selector(length)] && [(NSData *)object length] > 0) || ([object respondsToSelector:@selector(count)] && [(NSArray *)object count] > 0) || (object != nil); } // Returns YES if this application is an agent, i.e. a menu-less background helper app: static inline BOOL IsAgent() { return ([[[NSBundle mainBundle] infoDictionary] boolForKey:@"NSUIElement"]); } // Global debugging defines; put in the same scope to measure how long a block takes to execute: #define DSProfilerBegin(name) { NSString *__DSProfilerName = name; \ NSDate *__DSProfilerStartDate = [NSDate date]; \ NSLog(@"PROFILER: %@ started", __DSProfilerName); #define DSProfilerEnd NSTimeInterval __DSProfilerInterval = -[__DSProfilerStartDate timeIntervalSinceNow]; \ NSLog(@"PROFILER: %@ ended: total time %.4f seconds", __DSProfilerName, __DSProfilerInterval); } // DSDEBUG should be defined in the OTHER_CFLAGS of the project for the Debug build configuration (set to -DDSDEBUG=1): #ifdef DSDEBUG # define DSLog(...) NSLog(__VA_ARGS__) #else # define DSLog(...) /* */ #endif