Skip to content

Commit e048b47

Browse files
committed
Add logging API functions and callbacks
1 parent b5616e9 commit e048b47

File tree

5 files changed

+136
-2
lines changed

5 files changed

+136
-2
lines changed

src/api/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ set(PROJECTM_PUBLIC_HEADERS
1818
include/projectM-4/callbacks.h
1919
include/projectM-4/core.h
2020
include/projectM-4/debug.h
21+
include/projectM-4/logging.h
2122
include/projectM-4/memory.h
2223
include/projectM-4/projectM.h
2324
include/projectM-4/render_opengl.h

src/api/include/projectM-4/callbacks.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,3 @@ PROJECTM_EXPORT void projectm_set_preset_switch_failed_event_callback(projectm_h
9191
#ifdef __cplusplus
9292
} // extern "C"
9393
#endif
94-
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* @file logging.h
3+
* @copyright 2003-2025 projectM Team
4+
* @brief Functions for registering log callbacks and setting log levels.
5+
* @since 4.2.0
6+
*
7+
* projectM -- Milkdrop-esque visualisation SDK
8+
* Copyright (C)2003-2024 projectM Team
9+
*
10+
* This library is free software; you can redistribute it and/or
11+
* modify it under the terms of the GNU Lesser General Public
12+
* License as published by the Free Software Foundation; either
13+
* version 2.1 of the License, or (at your option) any later version.
14+
*
15+
* This library is distributed in the hope that it will be useful,
16+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18+
* Lesser General Public License for more details.
19+
*
20+
* You should have received a copy of the GNU Lesser General Public
21+
* License along with this library; if not, write to the Free Software
22+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23+
* See 'LICENSE.txt' included within this release
24+
*
25+
*/
26+
27+
#pragma once
28+
29+
#include "projectM-4/types.h"
30+
31+
32+
#ifdef __cplusplus
33+
extern "C" {
34+
#endif
35+
36+
/**
37+
* @brief Callback function that is executed if projectM wants to log a message.
38+
*
39+
* The message pointer is only valid inside the callback. Make a copy of the string inside the
40+
* function to use it after the callback returns. Applications must not free the message pointer.
41+
*
42+
* @param message The message to be logged.
43+
* @param log_level The log level this message was created for.
44+
* @param user_data A user-defined data pointer that was provided when registering the callback,
45+
* e.g. context information.
46+
* @since 4.2.0
47+
*/
48+
typedef void (*projectm_log_callback)(const char* message, projectm_log_level log_level, void* user_data);
49+
50+
51+
/**
52+
* @brief Sets a callback function that will be called for each message to be logged by projectM.
53+
*
54+
* The logging callback is independent of any projectM instance. Applications can set the callback
55+
* globally, or only for a single thread, or both. If both a global and a thread-specific callback
56+
* are set, the thread-specific callback takes precedence and the global callback will not be called.
57+
*
58+
* Since log messages will only be emitted by projectM when within an API call and the callback runs
59+
* in the same thread as the projectM instance, applications can keep track of the instance making
60+
* the call.
61+
*
62+
* If the application runs multiple projectM instances in separate threads, a global log callback
63+
* (or the same thread callback registered in multiple threads) may be called in parallel from each
64+
* thread, so the application has to take care about any possible race conditions in its own
65+
* logging code and make sure it's thread-safe.
66+
*
67+
* To remove a callback, pass NULL as the callback argument. Thread-specific callbacks are removed
68+
* automatically when the thread is terminated, though it is good practice to reset the callback at
69+
* the end of a thread.
70+
*
71+
* @param callback A pointer to the callback function.
72+
* @param current_thread_only If true, the callback is only set for the thread calling the function.
73+
* @param user_data A pointer to any data that will be sent back in the callback, e.g. context
74+
* information.
75+
* @since 4.2.0
76+
* @note Log messages can contain line breaks.
77+
*/
78+
PROJECTM_EXPORT void projectm_set_log_callback(projectm_log_callback callback,
79+
bool current_thread_only,
80+
void* user_data);
81+
82+
/**
83+
* Sets the minimum log level for which the callback should be called.
84+
* @param instance The projectM instance handle.
85+
* @param log_level The new log level to set. If set to PROJECTM_LOG_LEVEL_NOTSET, the global or default setting will be used.
86+
* @param current_thread_only If true, the log level is only set for the thread calling the function.
87+
* @since 4.2.0
88+
*/
89+
PROJECTM_EXPORT void projectm_set_log_level(projectm_log_level log_level,
90+
bool current_thread_only);
91+
92+
#ifdef __cplusplus
93+
} // extern "C"
94+
#endif

src/api/include/projectM-4/types.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,21 @@ typedef enum
7878
PROJECTM_TOUCH_TYPE_DOUBLE_LINE //!< Draws a double-line waveform.
7979
} projectm_touch_type;
8080

81+
/**
82+
* Log level constants for use with the logging API functions.
83+
* @since 4.2.0
84+
*/
85+
typedef enum
86+
{
87+
PROJECTM_LOG_LEVEL_NOTSET = 0, //!< No specific log level, use default (INFO).
88+
PROJECTM_LOG_LEVEL_TRACE = 1, //!< Verbose trace logging. Only enabled in debug builds by default.
89+
PROJECTM_LOG_LEVEL_DEBUG = 2, //!< Development-related debug logging. Only enabled in debug builds by default.
90+
PROJECTM_LOG_LEVEL_INFO = 3, //!< Informational messages.
91+
PROJECTM_LOG_LEVEL_WARN = 4, //!< Warnings about non-critical issues.
92+
PROJECTM_LOG_LEVEL_ERROR = 5, //!< Recoverable errors, e.g. shader compilation or I/O errors.
93+
PROJECTM_LOG_LEVEL_FATAL = 6 //!< Irrecoverable errors preventing projectM from working.
94+
} projectm_log_level;
95+
8196
#ifdef __cplusplus
8297
} // extern "C"
8398
#endif
84-

src/libprojectM/ProjectMCWrapper.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include <projectM-4/projectM.h>
44

5+
#include <Logging.hpp>
6+
57
#include <Audio/AudioConstants.hpp>
68

79
#include <cstring>
@@ -461,4 +463,28 @@ uint32_t projectm_sprite_get_max_sprites(projectm_handle instance)
461463
auto* projectMInstance = handle_to_instance(instance);
462464

463465
return projectMInstance->UserSpriteLimit();
466+
}
467+
468+
void projectm_set_log_callback(projectm_log_callback callback, bool current_thread_only, void* user_data)
469+
{
470+
if (current_thread_only)
471+
{
472+
libprojectM::Logging::SetThreadCallback({reinterpret_cast<libprojectM::Logging::CallbackFunction>(callback), user_data});
473+
}
474+
else
475+
{
476+
libprojectM::Logging::SetGlobalCallback({reinterpret_cast<libprojectM::Logging::CallbackFunction>(callback), user_data});
477+
}
478+
}
479+
480+
void projectm_set_log_level(projectm_log_level log_level, bool current_thread_only)
481+
{
482+
if (current_thread_only)
483+
{
484+
libprojectM::Logging::SetThreadLogLevel(static_cast<libprojectM::Logging::LogLevel>(log_level));
485+
}
486+
else
487+
{
488+
libprojectM::Logging::SetGlobalLogLevel(static_cast<libprojectM::Logging::LogLevel>(log_level));
489+
}
464490
}

0 commit comments

Comments
 (0)