mirror of
https://github.com/alexhopeoconnor/DFTE.git
synced 2026-10-03 22:21:59 +10:00
Extend DFTE template engine debug API and refine renderer logging.
Add helpers in DeviceFrameworkTemplateEngineDebug and wire clearer instrumentation in DeviceFrameworkTemplateRenderer; update README.
This commit is contained in:
@@ -84,7 +84,7 @@ DFTE is a lightweight C++ template engine tailored for Arduino-class hardware (E
|
||||
- `isComplete(const TemplateContext&)`, `hasError(const TemplateContext&)` – convenience checks.
|
||||
|
||||
- `DeviceFrameworkTemplateEngineDebug`
|
||||
- Optional logging interface; create a `DeviceFrameworkTemplateEngineLogger` subclass and call `deviceFrameworkTemplateEngineEnableLogging(&logger)`.
|
||||
- Optional logging interface; create a `DeviceFrameworkTemplateEngineLogger` subclass and call `deviceFrameworkTemplateEngineEnableLogging(&logger)` (or the two-argument overload with an owner tag, e.g. `this`, for `deviceFrameworkTemplateEngineDisableLoggingForOwner`).
|
||||
|
||||
All public headers are re-exported from `TemplateEngine.h`, so typical sketches only include that file.
|
||||
|
||||
@@ -313,11 +313,11 @@ SerialLogger logger;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
deviceFrameworkTemplateEngineEnableLogging(&logger);
|
||||
deviceFrameworkTemplateEngineEnableLogging(&logger, static_cast<const void*>(&logger));
|
||||
}
|
||||
```
|
||||
|
||||
Use `deviceFrameworkTemplateEngineDisableLogging()` to silence output or `deviceFrameworkTemplateEngineIsLoggingEnabled()` to inspect the current state.
|
||||
Use `deviceFrameworkTemplateEngineDisableLogging()` to silence output, `deviceFrameworkTemplateEngineDisableLoggingForOwner(tag)` to tear down only the registration made with that owner (for example WiFiManager’s server instance), or `deviceFrameworkTemplateEngineIsLoggingEnabled()` to inspect the current state.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -41,6 +41,9 @@ public:
|
||||
// Global logger pointer - set by user or defaults to nullptr (disabled)
|
||||
extern DeviceFrameworkTemplateEngineLogger* deviceFrameworkTemplateEngineLogger;
|
||||
|
||||
/** Opaque owner tag for the active logger (set on enable). Used to disable without clobbering another host. */
|
||||
extern const void* deviceFrameworkTemplateEngineLoggerOwner;
|
||||
|
||||
// ============================================================================
|
||||
// LOGGING MACROS - NO-OPS BY DEFAULT
|
||||
// ============================================================================
|
||||
@@ -86,6 +89,13 @@ extern DeviceFrameworkTemplateEngineLogger* deviceFrameworkTemplateEngineLogger;
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/** Optional verbose trace (compile with -DDFTE_ENABLE_TRACE). Maps to debug() on the active logger. */
|
||||
#if defined(DFTE_ENABLE_TRACE)
|
||||
#define DFTE_LOG_TRACE(msg) DFTE_LOG_DEBUG(String(F("[TRACE] ")) + String(msg))
|
||||
#else
|
||||
#define DFTE_LOG_TRACE(msg) do { (void)0; } while(0)
|
||||
#endif
|
||||
|
||||
// ============================================================================
|
||||
// LOGGING CONFIGURATION FUNCTIONS
|
||||
// ============================================================================
|
||||
@@ -98,12 +108,21 @@ extern DeviceFrameworkTemplateEngineLogger* deviceFrameworkTemplateEngineLogger;
|
||||
*/
|
||||
bool deviceFrameworkTemplateEngineEnableLogging(DeviceFrameworkTemplateEngineLogger* logger);
|
||||
|
||||
/**
|
||||
* Enable logging and record an owner tag (e.g. `this` of WiFiManagerServer).
|
||||
* If ownerTag is nullptr, the logger pointer is used as the tag.
|
||||
*/
|
||||
bool deviceFrameworkTemplateEngineEnableLogging(DeviceFrameworkTemplateEngineLogger* logger, const void* ownerTag);
|
||||
|
||||
/**
|
||||
* Disable all logging
|
||||
* Sets logger to nullptr, making all DFTE_LOG_* macros no-ops
|
||||
*/
|
||||
void deviceFrameworkTemplateEngineDisableLogging();
|
||||
|
||||
/** Disable only if the current logger was registered with this owner tag. Returns true if disabled. */
|
||||
bool deviceFrameworkTemplateEngineDisableLoggingForOwner(const void* ownerTag);
|
||||
|
||||
/**
|
||||
* Check if logging is currently enabled
|
||||
*
|
||||
@@ -118,4 +137,6 @@ bool deviceFrameworkTemplateEngineIsLoggingEnabled();
|
||||
*/
|
||||
DeviceFrameworkTemplateEngineLogger* deviceFrameworkTemplateEngineGetLogger();
|
||||
|
||||
const void* deviceFrameworkTemplateEngineGetLoggerOwner();
|
||||
|
||||
#endif // DEVICEFRAMEWORK_TEMPLATE_ENGINE_DEBUG_H
|
||||
@@ -2,21 +2,39 @@
|
||||
|
||||
// Global logger pointer - starts as nullptr (disabled by default)
|
||||
DeviceFrameworkTemplateEngineLogger* deviceFrameworkTemplateEngineLogger = nullptr;
|
||||
const void* deviceFrameworkTemplateEngineLoggerOwner = nullptr;
|
||||
|
||||
// ============================================================================
|
||||
// LOGGING CONFIGURATION IMPLEMENTATIONS
|
||||
// ============================================================================
|
||||
|
||||
bool deviceFrameworkTemplateEngineEnableLogging(DeviceFrameworkTemplateEngineLogger* logger) {
|
||||
return deviceFrameworkTemplateEngineEnableLogging(logger, nullptr);
|
||||
}
|
||||
|
||||
bool deviceFrameworkTemplateEngineEnableLogging(DeviceFrameworkTemplateEngineLogger* logger, const void* ownerTag) {
|
||||
if (logger == nullptr) {
|
||||
return false;
|
||||
}
|
||||
deviceFrameworkTemplateEngineLogger = logger;
|
||||
deviceFrameworkTemplateEngineLoggerOwner = ownerTag ? ownerTag : static_cast<const void*>(logger);
|
||||
return true;
|
||||
}
|
||||
|
||||
void deviceFrameworkTemplateEngineDisableLogging() {
|
||||
deviceFrameworkTemplateEngineLogger = nullptr;
|
||||
deviceFrameworkTemplateEngineLoggerOwner = nullptr;
|
||||
}
|
||||
|
||||
bool deviceFrameworkTemplateEngineDisableLoggingForOwner(const void* ownerTag) {
|
||||
if (deviceFrameworkTemplateEngineLogger == nullptr || ownerTag == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (deviceFrameworkTemplateEngineLoggerOwner != ownerTag) {
|
||||
return false;
|
||||
}
|
||||
deviceFrameworkTemplateEngineDisableLogging();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool deviceFrameworkTemplateEngineIsLoggingEnabled() {
|
||||
@@ -25,4 +43,8 @@ bool deviceFrameworkTemplateEngineIsLoggingEnabled() {
|
||||
|
||||
DeviceFrameworkTemplateEngineLogger* deviceFrameworkTemplateEngineGetLogger() {
|
||||
return deviceFrameworkTemplateEngineLogger;
|
||||
}
|
||||
|
||||
const void* deviceFrameworkTemplateEngineGetLoggerOwner() {
|
||||
return deviceFrameworkTemplateEngineLoggerOwner;
|
||||
}
|
||||
@@ -261,18 +261,24 @@ static DeviceFrameworkTemplateRenderer::RenderOutcome processIteratorContext(Dev
|
||||
|
||||
} // namespace
|
||||
|
||||
// Helper function to convert RenderingContextType to string
|
||||
static String getContextTypeString(RenderingContextType type) {
|
||||
switch (type) {
|
||||
case RenderingContextType::TEMPLATE: return "TEMPLATE";
|
||||
case RenderingContextType::PLACEHOLDER_DATA: return "PLACEHOLDER_DATA";
|
||||
case RenderingContextType::PLACEHOLDER_TEMPLATE: return "PLACEHOLDER_TEMPLATE";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to log state transitions with stack state
|
||||
static void logStateTransition(DeviceFrameworkTemplateContext& ctx, const String& fromState, const String& toState, const String& reason = "") {
|
||||
#if !defined(DFTE_ENABLE_TRACE)
|
||||
(void)ctx;
|
||||
(void)fromState;
|
||||
(void)toState;
|
||||
(void)reason;
|
||||
return;
|
||||
#else
|
||||
auto getContextTypeString = [](RenderingContextType type) -> String {
|
||||
switch (type) {
|
||||
case RenderingContextType::TEMPLATE: return "TEMPLATE";
|
||||
case RenderingContextType::PLACEHOLDER_DATA: return "PLACEHOLDER_DATA";
|
||||
case RenderingContextType::PLACEHOLDER_TEMPLATE: return "PLACEHOLDER_TEMPLATE";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
};
|
||||
|
||||
if (!deviceFrameworkTemplateEngineLogger) {
|
||||
return;
|
||||
}
|
||||
@@ -287,6 +293,7 @@ static void logStateTransition(DeviceFrameworkTemplateContext& ctx, const String
|
||||
msg += " | Current: " + String(currentCtx->name) + " (type=" + getContextTypeString(currentCtx->type) + ")";
|
||||
}
|
||||
deviceFrameworkTemplateEngineLogger->debug(msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
static String getStateName(TemplateRenderState state) {
|
||||
@@ -887,6 +894,8 @@ void DeviceFrameworkTemplateRenderer::initializeContext(DeviceFrameworkTemplateC
|
||||
|
||||
ctx.state = TemplateRenderState::TEXT;
|
||||
logStateTransition(ctx, "INIT", "TEXT", "Initialized template context");
|
||||
DFTE_LOG_TRACE("initializeContext len=" + String(rootCtx->context.templateCtx.templateLen) + " progmem=" +
|
||||
String(templateInProgmem ? 1 : 0));
|
||||
}
|
||||
|
||||
bool DeviceFrameworkTemplateRenderer::isComplete(const DeviceFrameworkTemplateContext& ctx) {
|
||||
|
||||
Reference in New Issue
Block a user