#ifndef MONOFORMAT_STRUCTURED_HPP #define MONOFORMAT_STRUCTURED_HPP #include "monoformat_parsehelpers.hpp" #include "monoformat_schema.hpp" #include #include #include #include #include namespace monoformat { struct Section { virtual ~Section() = default; virtual SectionType sectionType() const = 0; virtual std::uint32_t minimumFormatVersion() const = 0; virtual std::size_t serializeTo(std::span target, std::uint32_t formatVersion) const = 0; protected: Section() = default; }; class CustomFontSection; struct Element { virtual ~Element() = default; virtual ElementType elementType() const = 0; virtual std::uint32_t minimumFormatVersion() const = 0; virtual std::size_t serializeTo(std::span target, std::uint32_t formatVersion) const = 0; virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp, std::span customFonts) = 0; protected: Element() = default; }; struct ImageElement : public Element { ImageElement(std::uint16_t x, std::uint16_t y, std::uint16_t width, std::uint16_t height); std::uint16_t x() const noexcept; std::uint16_t y() const noexcept; std::uint16_t width() const noexcept; std::uint16_t height() const noexcept; std::span buffer() noexcept; std::span buffer() const noexcept; MemoryOneBitBuffer image() noexcept; ConstMemoryOneBitBuffer image() const noexcept; void updateBuffer(std::span newBufferData); virtual ~ImageElement() override; virtual ElementType elementType() const override; virtual std::uint32_t minimumFormatVersion() const override; virtual std::size_t serializeTo(std::span target, std::uint32_t formatVersion) const override; virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp, std::span customFonts) override; static std::expected, ParseError> parse(std::span& buffer, std::uint32_t formatVersion); private: std::uint16_t m_x{}; std::uint16_t m_y{}; std::uint16_t m_width{}; std::uint16_t m_height{}; std::vector m_buffer; }; struct AnimationElement : public Element { AnimationElement(std::uint16_t x, std::uint16_t y, std::uint16_t width, std::uint16_t height, std::uint16_t numberOfFrames, std::uint16_t updateInterval); std::uint16_t x() const noexcept; std::uint16_t y() const noexcept; std::uint16_t width() const noexcept; std::uint16_t height() const noexcept; std::uint16_t numberOfFrames() const noexcept; std::uint16_t updateInterval() const noexcept; std::span buffers() noexcept; std::span buffers() const noexcept; std::span buffer(std::uint16_t frameIndex) noexcept; std::span buffer(std::uint16_t frameIndex) const noexcept; MemoryOneBitBuffer image(std::uint16_t frameIndex) noexcept; ConstMemoryOneBitBuffer image(std::uint16_t frameIndex) const noexcept; void updateBuffer(std::span newBufferData); virtual ~AnimationElement() override; virtual ElementType elementType() const override; virtual std::uint32_t minimumFormatVersion() const override; virtual std::size_t serializeTo(std::span target, std::uint32_t formatVersion) const override; virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp, std::span customFonts) override; static std::expected, ParseError> parse(std::span& buffer, std::uint32_t formatVersion); private: std::uint16_t m_x{}; std::uint16_t m_y{}; std::uint16_t m_width{}; std::uint16_t m_height{}; std::uint16_t m_numberOfFrames{}; std::uint16_t m_updateInterval{}; std::vector m_buffer; }; struct HScrollImageElement : public Element { HScrollImageElement(std::uint16_t x, std::uint16_t y, std::uint16_t width, std::uint16_t height, std::uint16_t contentWidth, ScrollFlags flags, std::uint8_t scrollSpeed); std::uint16_t x() const noexcept; std::uint16_t y() const noexcept; std::uint16_t width() const noexcept; std::uint16_t height() const noexcept; std::uint16_t contentWidth() const noexcept; ScrollFlags flags() const noexcept; std::uint8_t scrollSpeed() const noexcept; std::span buffer() noexcept; std::span buffer() const noexcept; MemoryOneBitBuffer image() noexcept; ConstMemoryOneBitBuffer image() const noexcept; void updateBuffer(std::span newBufferData); virtual ~HScrollImageElement() override; virtual ElementType elementType() const override; virtual std::uint32_t minimumFormatVersion() const override; virtual std::size_t serializeTo(std::span target, std::uint32_t formatVersion) const override; virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp, std::span customFonts) override; static std::expected, ParseError> parse(std::span& buffer, std::uint32_t formatVersion); private: std::uint16_t m_x{}; std::uint16_t m_y{}; std::uint16_t m_width{}; std::uint16_t m_height{}; std::uint16_t m_contentWidth{}; ScrollFlags m_flags; std::uint8_t m_scrollSpeed{}; std::vector m_buffer; }; struct VScrollImageElement : public Element { VScrollImageElement(std::uint16_t x, std::uint16_t y, std::uint16_t width, std::uint16_t height, std::uint16_t contentHeight, ScrollFlags flags, std::uint8_t scrollSpeed); std::uint16_t x() const noexcept; std::uint16_t y() const noexcept; std::uint16_t width() const noexcept; std::uint16_t height() const noexcept; std::uint16_t contentHeight() const noexcept; ScrollFlags flags() const noexcept; std::uint8_t scrollSpeed() const noexcept; std::span buffer() noexcept; std::span buffer() const noexcept; MemoryOneBitBuffer image() noexcept; ConstMemoryOneBitBuffer image() const noexcept; void updateBuffer(std::span newBufferData); virtual ~VScrollImageElement() override; virtual ElementType elementType() const override; virtual std::uint32_t minimumFormatVersion() const override; virtual std::size_t serializeTo(std::span target, std::uint32_t formatVersion) const override; virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp, std::span customFonts) override; static std::expected, ParseError> parse(std::span& buffer, std::uint32_t formatVersion); private: std::uint16_t m_x{}; std::uint16_t m_y{}; std::uint16_t m_width{}; std::uint16_t m_height{}; std::uint16_t m_contentHeight{}; ScrollFlags m_flags; std::uint8_t m_scrollSpeed{}; std::vector m_buffer; }; struct LineElement : public Element { LineElement(std::uint16_t originX, std::uint16_t originY, std::uint16_t targetX, std::uint16_t targetY, LineStyle lineStyle, LineFlags flags); std::uint16_t originX() const noexcept; std::uint16_t originY() const noexcept; std::uint16_t targetX() const noexcept; std::uint16_t targetY() const noexcept; LineStyle lineStyle() const noexcept; LineFlags flags() const noexcept; virtual ~LineElement() override; virtual ElementType elementType() const override; virtual std::uint32_t minimumFormatVersion() const override; virtual std::size_t serializeTo(std::span target, std::uint32_t formatVersion) const override; virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp, std::span customFonts) override; static std::expected, ParseError> parse(std::span& buffer, std::uint32_t formatVersion); private: std::uint16_t m_originX{}; std::uint16_t m_originY{}; std::uint16_t m_targetX{}; std::uint16_t m_targetY{}; LineStyle m_lineStyle{}; LineFlags m_flags; }; struct ClippedTextElement : public Element { ClippedTextElement(std::uint16_t x, std::uint16_t y, std::uint16_t width, std::uint16_t height, std::uint16_t fontIndex, std::string text); std::uint16_t x() const noexcept; std::uint16_t y() const noexcept; std::uint16_t width() const noexcept; std::uint16_t height() const noexcept; std::uint16_t fontIndex() const noexcept; std::string text() const; virtual ~ClippedTextElement() override; virtual ElementType elementType() const override; virtual std::uint32_t minimumFormatVersion() const override; virtual std::size_t serializeTo(std::span target, std::uint32_t formatVersion) const override; virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp, std::span customFonts) override; static std::expected, ParseError> parse(std::span& buffer, std::uint32_t formatVersion); private: std::uint16_t m_x{}; std::uint16_t m_y{}; std::uint16_t m_width{}; std::uint16_t m_height{}; std::uint16_t m_fontIndex{}; std::string m_text; }; struct HScrollTextElement : public Element { HScrollTextElement(std::uint16_t x, std::uint16_t y, std::uint16_t width, std::uint16_t height, ScrollFlags flags, std::uint8_t scrollSpeed, std::uint16_t fontIndex, std::string text); std::uint16_t x() const noexcept; std::uint16_t y() const noexcept; std::uint16_t width() const noexcept; std::uint16_t height() const noexcept; ScrollFlags flags() const noexcept; std::uint8_t scrollSpeed() const noexcept; std::uint16_t fontIndex() const noexcept; std::string text() const; virtual ~HScrollTextElement() override; virtual ElementType elementType() const override; virtual std::uint32_t minimumFormatVersion() const override; virtual std::size_t serializeTo(std::span target, std::uint32_t formatVersion) const override; virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp, std::span customFonts) override; static std::expected, ParseError> parse(std::span& buffer, std::uint32_t formatVersion); private: std::uint16_t m_x{}; std::uint16_t m_y{}; std::uint16_t m_width{}; std::uint16_t m_height{}; ScrollFlags m_flags; std::uint8_t m_scrollSpeed{}; std::uint16_t m_fontIndex{}; std::string m_text; }; struct CurrentTimeElement : public Element { CurrentTimeElement(std::uint16_t x, std::uint16_t y, std::uint16_t width, std::uint16_t height, std::uint16_t fontIndex, std::uint16_t utcOffset, TimeDisplayFlags flags); std::uint16_t x() const noexcept; std::uint16_t y() const noexcept; std::uint16_t width() const noexcept; std::uint16_t height() const noexcept; std::uint16_t fontIndex() const noexcept; std::uint16_t utcOffset() const noexcept; TimeDisplayFlags flags() const noexcept; virtual ~CurrentTimeElement() override; virtual ElementType elementType() const override; virtual std::uint32_t minimumFormatVersion() const override; virtual std::size_t serializeTo(std::span target, std::uint32_t formatVersion) const override; virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp, std::span customFonts) override; static std::expected, ParseError> parse(std::span& buffer, std::uint32_t formatVersion); private: std::uint16_t m_x{}; std::uint16_t m_y{}; std::uint16_t m_width{}; std::uint16_t m_height{}; std::uint16_t m_fontIndex{}; std::uint16_t m_utcOffset{}; TimeDisplayFlags m_flags; }; struct AlwaysDrawnSection : public Section { AlwaysDrawnSection() = default; virtual ~AlwaysDrawnSection() override; bool doesDrawOnFront() const noexcept; bool doesDrawOnBack() const noexcept; bool doesClearBeforeDrawing() const noexcept; void setDrawOnFront(bool value) noexcept; void setDrawOnBack(bool value) noexcept; void setClearBeforeDrawing(bool value) noexcept; std::size_t elementCount() const noexcept; Element* elementAt(std::size_t index) const; void appendElement(std::unique_ptr element); void insertElement(std::size_t index, std::unique_ptr element); std::unique_ptr replaceElement(std::size_t index, std::unique_ptr element); std::unique_ptr eraseElement(std::size_t index); virtual SectionType sectionType() const override; virtual std::uint32_t minimumFormatVersion() const override; virtual std::size_t serializeTo(std::span target, std::uint32_t formatVersion) const override; static std::expected, ParseError> parse(std::span& buffer, std::uint32_t formatVersion); private: std::vector> m_elements; bool m_drawOnFront{true}; bool m_drawOnBack{true}; bool m_clearBeforeDrawing{true}; }; struct TimeBasedDrawnSection : public Section { TimeBasedDrawnSection() = default; virtual ~TimeBasedDrawnSection() override; bool doesDrawOnFront() const noexcept; bool doesDrawOnBack() const noexcept; bool doesClearBeforeDrawing() const noexcept; void setDrawOnFront(bool value) noexcept; void setDrawOnBack(bool value) noexcept; void setClearBeforeDrawing(bool value) noexcept; std::size_t elementCount() const noexcept; Element* elementAt(std::size_t index) const; void appendElement(std::unique_ptr element); void insertElement(std::size_t index, std::unique_ptr element); std::unique_ptr replaceElement(std::size_t index, std::unique_ptr element); std::unique_ptr eraseElement(std::size_t index); std::int64_t startTimestamp() const noexcept; std::int64_t endTimestamp() const noexcept; void setStartTimestamp(std::int64_t value); void setEndTimestamp(std::int64_t value); virtual SectionType sectionType() const override; virtual std::uint32_t minimumFormatVersion() const override; virtual std::size_t serializeTo(std::span target, std::uint32_t formatVersion) const override; static std::expected, ParseError> parse(std::span& buffer, std::uint32_t formatVersion); private: std::vector> m_elements; std::int64_t m_startTimestamp{}; std::int64_t m_endTimestamp{}; bool m_drawOnFront{true}; bool m_drawOnBack{true}; bool m_clearBeforeDrawing{true}; }; struct CustomFontSection : public Section { CustomFontSection() = default; virtual ~CustomFontSection() override; std::span fontData() const; void setFontData(std::span fontData); virtual SectionType sectionType() const override; virtual std::uint32_t minimumFormatVersion() const override; virtual std::size_t serializeTo(std::span target, std::uint32_t formatVersion) const override; static std::expected, ParseError> parse(std::span& buffer, std::uint32_t formatVersion); private: std::vector m_fontData; }; struct File { std::vector> sections; }; extern std::size_t serializeFile(std::span& buffer, File const& file); extern std::expected parseFile(std::span data); } // namespace monoformat #endif // MONOFORMAT_STRUCTURED_HPP