Skip to content

Commit

Permalink
Lua skin additions (#3667)
Browse files Browse the repository at this point in the history
* pushNSObject: checks for exact class match first

* log*: supports format, args style without NSString stringWithFormat:
  • Loading branch information
asmagill authored Aug 12, 2024
1 parent ec9a8ea commit 45fa356
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 27 deletions.
26 changes: 13 additions & 13 deletions LuaSkin/LuaSkin/Skin.h
Original file line number Diff line number Diff line change
Expand Up @@ -891,49 +891,49 @@ NSString *specMaskToString(int spec);
@discussion This method is equivalent to invoking @link logAtLevel:withMessage: @/link with level @link LS_LOG_VERBOSE @/link
@param theMessage the message to log
*/
- (void)logVerbose:(NSString *)theMessage ;
- (void)logVerbose:(NSString *)theMessage, ... ;

/*!
@abstract Log the specified message with LS_LOG_DEBUG level
@discussion This method is equivalent to invoking @link logAtLevel:withMessage: @/link with level @link LS_LOG_DEBUG @/link
@param theMessage the message to log
*/
- (void)logDebug:(NSString *)theMessage ;
- (void)logDebug:(NSString *)theMessage, ... ;

/*!
@abstract Log the specified message with LS_LOG_INFO level
@discussion This method is equivalent to invoking @link logAtLevel:withMessage: @/link with level @link LS_LOG_INFO @/link
@param theMessage the message to log
*/
- (void)logInfo:(NSString *)theMessage ;
- (void)logInfo:(NSString *)theMessage, ... ;

/*!
@abstract Log the specified message with LS_LOG_WARN level
@discussion This method is equivalent to invoking @link logAtLevel:withMessage: @/link with level @link LS_LOG_WARN @/link
@param theMessage the message to log
*/
- (void)logWarn:(NSString *)theMessage ;
- (void)logWarn:(NSString *)theMessage, ... ;

/*!
@abstract Log the specified message with LS_LOG_ERROR level
@discussion This method is equivalent to invoking @link logAtLevel:withMessage: @/link with level @link LS_LOG_ERROR @/link
@param theMessage the message to log
*/
- (void)logError:(NSString *)theMessage ;
- (void)logError:(NSString *)theMessage, ... ;

/*!
@abstract Log the specified message with LS_LOG_BREADCRUMB level
@discussion This method is equivalent to invoking @link logAtLevel:withMessage: @/link with level @link LS_LOG_BREADCRUMB @/link
@param theMessage the message to log
*/
- (void)logBreadcrumb:(NSString *)theMessage ;
- (void)logBreadcrumb:(NSString *)theMessage, ... ;

/*!
@abstract Log a known, but avoided issue via the log delegate, primarily to ensure it can be recorded in a crash reporting service
@discussion If no delegate has been assigned, the message is logged to the system logs via NSLog.
@param message The message to log
*/
- (void)logKnownBug:(NSString *)message;
- (void)logKnownBug:(NSString *)message, ... ;

// FIXME: Should this be documented? Seems unnecessary to do so, at the moment
+ (void)classLogAtLevel:(int)level withMessage:(NSString *)theMessage;
Expand All @@ -950,47 +950,47 @@ NSString *specMaskToString(int spec);
@discussion This class method is equivalent to invoking @link logAtLevel:withMessage: @/link with level @link LS_LOG_VERBOSE @/link, but is safe to use from any thread, not just the main application thread. If this method is invoked from a thread other than the main thread, it uses dispatch_async to submit the logging message to the main thread for proper handling by the delegate.
@param theMessage the message to log
*/
+ (void)logVerbose:(NSString *)theMessage ;
+ (void)logVerbose:(NSString *)theMessage, ... ;

/*!
@apiuid //apple_ref/doc/classmethodparam/LuaSkin/logDebug:/theMessage
@abstract Log the specified message from any thread with LS_LOG_DEBUG level
@discussion This class method is equivalent to invoking @link logAtLevel:withMessage: @/link with level @link LS_LOG_DEBUG @/link, but is safe to use from any thread, not just the main application thread. If this method is invoked from a thread other than the main thread, it uses dispatch_async to submit the logging message to the main thread for proper handling by the delegate.
@param theMessage the message to log
*/
+ (void)logDebug:(NSString *)theMessage ;
+ (void)logDebug:(NSString *)theMessage, ... ;

/*!
@apiuid //apple_ref/doc/classmethodparam/LuaSkin/logInfo:/theMessage
@abstract Log the specified message from any thread with LS_LOG_INFO level
@discussion This class method is equivalent to invoking @link logAtLevel:withMessage: @/link with level @link LS_LOG_INFO @/link, but is safe to use from any thread, not just the main application thread. If this method is invoked from a thread other than the main thread, it uses dispatch_async to submit the logging message to the main thread for proper handling by the delegate.
@param theMessage the message to log
*/
+ (void)logInfo:(NSString *)theMessage ;
+ (void)logInfo:(NSString *)theMessage, ... ;

/*!
@apiuid //apple_ref/doc/classmethodparam/LuaSkin/logWarn:/theMessage
@abstract Log the specified message from any thread with LS_LOG_WARN level
@discussion This class method is equivalent to invoking @link logAtLevel:withMessage: @/link with level @link LS_LOG_WARN @/link, but is safe to use from any thread, not just the main application thread. If this method is invoked from a thread other than the main thread, it uses dispatch_async to submit the logging message to the main thread for proper handling by the delegate.
@param theMessage the message to log
*/
+ (void)logWarn:(NSString *)theMessage ;
+ (void)logWarn:(NSString *)theMessage, ... ;

/*!
@apiuid //apple_ref/doc/classmethodparam/LuaSkin/logError:/theMessage
@abstract Log the specified message from any thread with LS_LOG_ERROR level
@discussion This class method is equivalent to invoking @link logAtLevel:withMessage: @/link with level @link LS_LOG_ERROR @/link, but is safe to use from any thread, not just the main application thread. If this method is invoked from a thread other than the main thread, it uses dispatch_async to submit the logging message to the main thread for proper handling by the delegate.
@param theMessage the message to log
*/
+ (void)logError:(NSString *)theMessage ;
+ (void)logError:(NSString *)theMessage, ... ;

/*!
@apiuid //apple_ref/doc/classmethodparam/LuaSkin/logBreadcrumb:/theMessage
@abstract Log the specified message from any thread with LS_LOG_BREADCRUMB level
@discussion This class method is equivalent to invoking @link logAtLevel:withMessage: @/link with level @link LS_LOG_BREADCRUMB @/link, but is safe to use from any thread, not just the main application thread. If this method is invoked from a thread other than the main thread, it uses dispatch_async to submit the logging message to the main thread for proper handling by the delegate.
@param theMessage the message to log
*/
+ (void)logBreadcrumb:(NSString *)theMessage ;
+ (void)logBreadcrumb:(NSString *)theMessage, ... ;

#pragma clang diagnostic pop

Expand Down
123 changes: 109 additions & 14 deletions LuaSkin/LuaSkin/Skin.m
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,16 @@ - (int)pushNSObject:(id)obj withOptions:(NSUInteger)options alreadySeenObjects:(

// check for registered helpers

// first check for exact class match
for (id key in self.registeredNSHelperFunctions) {
if ([obj isMemberOfClass: NSClassFromString(key)]) {
pushNSHelperFunction theFunc = (pushNSHelperFunction)[self.registeredNSHelperFunctions[key] pointerValue] ;
int resultAnswer = theFunc(self.L, obj) ;
if (resultAnswer > -1) return resultAnswer ;
}
}

// if we're still here, check for kind of class (i.e. possible superclass of object)
for (id key in self.registeredNSHelperFunctions) {
if ([obj isKindOfClass: NSClassFromString(key)]) {
pushNSHelperFunction theFunc = (pushNSHelperFunction)[self.registeredNSHelperFunctions[key] pointerValue] ;
Expand Down Expand Up @@ -1746,14 +1756,57 @@ - (void) logAtLevel:(int)level withMessage:(NSString *)theMessage {
}

// shorthand
- (void)logVerbose:(NSString *)theMessage { [self logAtLevel:LS_LOG_VERBOSE withMessage:theMessage] ; }
- (void)logDebug:(NSString *)theMessage { [self logAtLevel:LS_LOG_DEBUG withMessage:theMessage] ; }
- (void)logInfo:(NSString *)theMessage { [self logAtLevel:LS_LOG_INFO withMessage:theMessage] ; }
- (void)logWarn:(NSString *)theMessage { [self logAtLevel:LS_LOG_WARN withMessage:theMessage] ; }
- (void)logError:(NSString *)theMessage { [self logAtLevel:LS_LOG_ERROR withMessage:theMessage] ; }
- (void)logBreadcrumb:(NSString *)theMessage { [self logAtLevel:LS_LOG_BREADCRUMB withMessage:theMessage] ; }

- (void)logKnownBug:(NSString *)message {

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"

- (void)logVerbose:(NSString *)format, ... {
va_list args;
va_start(args, format);
NSString *theMessage = [[NSString alloc] initWithFormat:format arguments:args];
[self logAtLevel:LS_LOG_VERBOSE withMessage:theMessage] ;
}

- (void)logDebug:(NSString *)format, ... {
va_list args;
va_start(args, format);
NSString *theMessage = [[NSString alloc] initWithFormat:format arguments:args];
[self logAtLevel:LS_LOG_DEBUG withMessage:theMessage] ;
}

- (void)logInfo:(NSString *)format, ... {
va_list args;
va_start(args, format);
NSString *theMessage = [[NSString alloc] initWithFormat:format arguments:args];
[self logAtLevel:LS_LOG_INFO withMessage:theMessage] ;
}

- (void)logWarn:(NSString *)format, ... {
va_list args;
va_start(args, format);
NSString *theMessage = [[NSString alloc] initWithFormat:format arguments:args];
[self logAtLevel:LS_LOG_WARN withMessage:theMessage] ;
}

- (void)logError:(NSString *)format, ... {
va_list args;
va_start(args, format);
NSString *theMessage = [[NSString alloc] initWithFormat:format arguments:args];
[self logAtLevel:LS_LOG_ERROR withMessage:theMessage] ;
}

- (void)logBreadcrumb:(NSString *)format, ... {
va_list args;
va_start(args, format);
NSString *theMessage = [[NSString alloc] initWithFormat:format arguments:args];
[self logAtLevel:LS_LOG_BREADCRUMB withMessage:theMessage] ;
}

- (void)logKnownBug:(NSString *)format, ... {
va_list args;
va_start(args, format);
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];

id theDelegate = self.delegate;

if (theDelegate && [theDelegate respondsToSelector:@selector(logKnownBug:)]) {
Expand All @@ -1764,6 +1817,8 @@ - (void)logKnownBug:(NSString *)message {

}

#pragma clang diagnostic pop

+ (void)classLogAtLevel:(int)level withMessage:(NSString *)theMessage {
if ([NSThread isMainThread]) {
// the class logging methods *do* use the shared instance, so backup the state/thread in case
Expand All @@ -1783,12 +1838,52 @@ + (void)classLogAtLevel:(int)level withMessage:(NSString *)theMessage {
}
}

+ (void)logVerbose:(NSString *)theMessage { [[self class] classLogAtLevel:LS_LOG_VERBOSE withMessage:theMessage]; }
+ (void)logDebug:(NSString *)theMessage { [[self class] classLogAtLevel:LS_LOG_DEBUG withMessage:theMessage]; }
+ (void)logInfo:(NSString *)theMessage { [[self class] classLogAtLevel:LS_LOG_INFO withMessage:theMessage]; }
+ (void)logWarn:(NSString *)theMessage { [[self class] classLogAtLevel:LS_LOG_WARN withMessage:theMessage]; }
+ (void)logError:(NSString *)theMessage { [[self class] classLogAtLevel:LS_LOG_ERROR withMessage:theMessage]; }
+ (void)logBreadcrumb:(NSString *)theMessage { [[self class] classLogAtLevel:LS_LOG_BREADCRUMB withMessage:theMessage]; }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"

+ (void)logVerbose:(NSString *)format, ... {
va_list args;
va_start(args, format);
NSString *theMessage = [[NSString alloc] initWithFormat:format arguments:args];
[self classLogAtLevel:LS_LOG_VERBOSE withMessage:theMessage] ;
}

+ (void)logDebug:(NSString *)format, ... {
va_list args;
va_start(args, format);
NSString *theMessage = [[NSString alloc] initWithFormat:format arguments:args];
[self classLogAtLevel:LS_LOG_DEBUG withMessage:theMessage] ;
}

+ (void)logInfo:(NSString *)format, ... {
va_list args;
va_start(args, format);
NSString *theMessage = [[NSString alloc] initWithFormat:format arguments:args];
[self classLogAtLevel:LS_LOG_INFO withMessage:theMessage] ;
}

+ (void)logWarn:(NSString *)format, ... {
va_list args;
va_start(args, format);
NSString *theMessage = [[NSString alloc] initWithFormat:format arguments:args];
[self classLogAtLevel:LS_LOG_WARN withMessage:theMessage] ;
}

+ (void)logError:(NSString *)format, ... {
va_list args;
va_start(args, format);
NSString *theMessage = [[NSString alloc] initWithFormat:format arguments:args];
[self classLogAtLevel:LS_LOG_ERROR withMessage:theMessage] ;
}

+ (void)logBreadcrumb:(NSString *)format, ... {
va_list args;
va_start(args, format);
NSString *theMessage = [[NSString alloc] initWithFormat:format arguments:args];
[self classLogAtLevel:LS_LOG_BREADCRUMB withMessage:theMessage] ;
}

#pragma clang diagnostic pop

- (NSString *)tracebackWithTag:(NSString *)theTag fromStackPos:(int)level{
int topIndex = lua_gettop(self.L) ;
Expand Down

0 comments on commit 45fa356

Please sign in to comment.