Files
DFTE/include/DeviceFrameworkTemplateRenderer.h
T
2026-08-24 22:02:41 +10:00

103 lines
3.7 KiB
C++

#ifndef DEVICEFRAMEWORK_TEMPLATE_RENDERER_H
#define DEVICEFRAMEWORK_TEMPLATE_RENDERER_H
#include <Arduino.h>
#include "DeviceFrameworkTemplateContext.h"
#include "DeviceFrameworkPlaceholderRegistry.h"
// Fallback defaults when DeviceFrameworkConfig is not available (standalone usage)
#ifndef DFTE_MAX_ITERATIONS_DEFAULT
#define DFTE_MAX_ITERATIONS_DEFAULT 50
#endif
// Renderer settings are build-wide DFTE_* flags.
#ifndef DFTE_MAX_ITERATIONS
#define DFTE_MAX_ITERATIONS DFTE_MAX_ITERATIONS_DEFAULT
#endif
/**
* DeviceFramework Template Renderer
* Core rendering engine for streaming template output with chunked processing
*/
class DeviceFrameworkTemplateRenderer {
public:
struct RenderOutcome {
size_t bytesWritten;
TemplateRenderState nextState;
bool repeat;
bool finished;
bool errored;
uint8_t popCount;
struct {
bool active;
RenderingContextType type;
const PlaceholderEntry* entry;
} pushContext;
};
/**
* Render next chunk of template
* Call repeatedly until returns 0
*
* @param ctx Rendering context (maintains state between calls)
* @param buffer Output buffer to write to
* @param maxLen Maximum bytes to write to buffer
* @return Number of bytes written (0 = complete or error)
*/
static size_t renderNextChunk(DeviceFrameworkTemplateContext& ctx, uint8_t* buffer, size_t maxLen);
/**
* Initialize rendering context with template stored in PROGMEM
* Call once before rendering begins
*
* @param ctx Context to initialize
* @param templateData Pointer to PROGMEM template string
*/
static void initializeContext(DeviceFrameworkTemplateContext& ctx, const char* templateData);
/**
* Initialize rendering context with template stored in RAM or PROGMEM
*
* @param ctx Context to initialize
* @param templateData Pointer to template string
* @param templateInProgmem True if template is stored in PROGMEM, false if in RAM
*/
static void initializeContext(DeviceFrameworkTemplateContext& ctx, const char* templateData, bool templateInProgmem);
/**
* Check if rendering is complete
*/
static bool isComplete(const DeviceFrameworkTemplateContext& ctx);
/**
* Check if rendering encountered an error
*/
static bool hasError(const DeviceFrameworkTemplateContext& ctx);
/**
* Helper constructors for RenderOutcome
*/
static RenderOutcome makeWritten(size_t bytes, TemplateRenderState state, bool repeat = false);
static RenderOutcome makeState(TemplateRenderState nextState, bool repeat = true);
static RenderOutcome makeComplete();
static RenderOutcome makeError();
private:
static RenderOutcome renderChunk(DeviceFrameworkTemplateContext& ctx, uint8_t* buffer, size_t maxLen);
static bool applyStackCommands(DeviceFrameworkTemplateContext& ctx, const RenderOutcome& outcome);
// Core processing methods
static RenderOutcome consumeTemplateText(DeviceFrameworkTemplateContext& ctx, uint8_t* buffer, size_t maxLen);
static RenderOutcome buildPlaceholderToken(DeviceFrameworkTemplateContext& ctx);
static RenderOutcome resolvePlaceholder(DeviceFrameworkTemplateContext& ctx);
static RenderOutcome emitActiveContext(DeviceFrameworkTemplateContext& ctx, uint8_t* buffer, size_t maxLen);
static RenderOutcome streamPlaceholderData(DeviceFrameworkTemplateContext& ctx, RenderingContext* context, uint8_t* buffer, size_t maxLen);
static RenderOutcome handleTemplateCompletion(DeviceFrameworkTemplateContext& ctx);
// Constants
static constexpr size_t MAX_ITERATIONS = DFTE_MAX_ITERATIONS;
};
#endif // DEVICEFRAMEWORK_TEMPLATE_RENDERER_H