From e974a58d180c29d645293fc9e06af40ed75ef931 Mon Sep 17 00:00:00 2001 From: HarukiToreda <116696711+HarukiToreda@users.noreply.github.com> Date: Sat, 24 May 2025 20:46:33 -0400 Subject: [PATCH] Cannedmessagemodule.h cleanup --- src/modules/CannedMessageModule.h | 183 +++++++++++++++--------------- 1 file changed, 93 insertions(+), 90 deletions(-) diff --git a/src/modules/CannedMessageModule.h b/src/modules/CannedMessageModule.h index dcdeba971..9a3f610c0 100644 --- a/src/modules/CannedMessageModule.h +++ b/src/modules/CannedMessageModule.h @@ -3,6 +3,10 @@ #include "ProtobufModule.h" #include "input/InputBroker.h" +// ============================ +// Enums & Defines +// ============================ + enum cannedMessageModuleRunState { CANNED_MESSAGE_RUN_STATE_DISABLED, CANNED_MESSAGE_RUN_STATE_INACTIVE, @@ -25,6 +29,17 @@ enum cannedMessageDestinationType { enum CannedMessageModuleIconType { shift, backspace, space, enter }; +#define CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT 50 +#define CANNED_MESSAGE_MODULE_MESSAGES_SIZE 800 + +#ifndef CANNED_MESSAGE_MODULE_ENABLE +#define CANNED_MESSAGE_MODULE_ENABLE 0 +#endif + +// ============================ +// Data Structures +// ============================ + struct Letter { String character; float width; @@ -34,90 +49,57 @@ struct Letter { int rectHeight; }; -#define CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT 50 -/** - * Sum of CannedMessageModuleConfig part sizes. - */ -#define CANNED_MESSAGE_MODULE_MESSAGES_SIZE 800 - -#ifndef CANNED_MESSAGE_MODULE_ENABLE -#define CANNED_MESSAGE_MODULE_ENABLE 0 -#endif - struct NodeEntry { meshtastic_NodeInfoLite *node; uint32_t lastHeard; }; -class CannedMessageModule : public SinglePortModule, public Observable, private concurrency::OSThread -{ - CallbackObserver inputObserver = - CallbackObserver(this, &CannedMessageModule::handleInputEvent); - private: - int displayHeight = 64; // Default to a common value, update dynamically - int destIndex = 0; // Tracks currently selected node/channel in selection mode - int scrollIndex = 0; // Tracks scrolling position in node selection grid - int visibleRows = 0; - bool needsUpdate = true; - String searchQuery; - std::vector activeChannelIndices; - bool shouldRedraw = false; - unsigned long lastUpdateMillis = 0; - uint8_t lastAckHopStart = 0; - uint8_t lastAckHopLimit = 0; - public: +// ============================ +// Main Class +// ============================ + +class CannedMessageModule : public SinglePortModule, + public Observable, + private concurrency::OSThread { +public: CannedMessageModule(); + + // === Message navigation === const char *getCurrentMessage(); const char *getPrevMessage(); const char *getNextMessage(); const char *getMessageByIndex(int index); const char *getNodeName(NodeNum node); + + // === State/UI === bool shouldDraw(); bool hasMessages(); - // void eventUp(); - // void eventDown(); - // void eventSelect(); + void showTemporaryMessage(const String &message); + void resetSearch(); + void updateFilteredNodes(); + String drawWithCursor(String text, int cursor); + // === Admin Handlers === void handleGetCannedMessageModuleMessages(const meshtastic_MeshPacket &req, meshtastic_AdminMessage *response); void handleSetCannedMessageModuleMessages(const char *from_msg); - void showTemporaryMessage(const String &message); - void resetSearch(); - void updateFilteredNodes(); - std::vector filteredNodes; - String nodeSelectionInput; - String drawWithCursor(String text, int cursor); - #ifdef RAK14014 cannedMessageModuleRunState getRunState() const { return runState; } #endif - /* - -Override the wantPacket method. We need the Routing Messages to look for ACKs. - */ - virtual bool wantPacket(const meshtastic_MeshPacket *p) override - { - if (p->rx_rssi != 0) { - this->lastRxRssi = p->rx_rssi; - } - - if (p->rx_snr > 0) { - this->lastRxSnr = p->rx_snr; - } - - switch (p->decoded.portnum) { - case meshtastic_PortNum_ROUTING_APP: - return waitingForAck; - default: - return false; - } + // === Packet Interest Filter === + virtual bool wantPacket(const meshtastic_MeshPacket *p) override { + if (p->rx_rssi != 0) lastRxRssi = p->rx_rssi; + if (p->rx_snr > 0) lastRxSnr = p->rx_snr; + return (p->decoded.portnum == meshtastic_PortNum_ROUTING_APP) ? waitingForAck : false; } - protected: +protected: + // === Thread Entry Point === virtual int32_t runOnce() override; + // === Transmission === void sendText(NodeNum dest, ChannelIndex channel, const char *message, bool wantReplies); - int splitConfiguredMessages(); int getNextIndex(); int getPrevIndex(); @@ -125,60 +107,81 @@ class CannedMessageModule : public SinglePortModule, public ObservableshouldDraw(); } + virtual bool wantUIFrame() override { return shouldDraw(); } virtual Observable *getUIFrameObservable() override { return this; } virtual bool interceptingKeyboardInput() override; #if !HAS_TFT virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) override; #endif - virtual AdminMessageHandleResult handleAdminMessageForModule(const meshtastic_MeshPacket &mp, - meshtastic_AdminMessage *request, - meshtastic_AdminMessage *response) override; + virtual AdminMessageHandleResult handleAdminMessageForModule( + const meshtastic_MeshPacket &mp, + meshtastic_AdminMessage *request, + meshtastic_AdminMessage *response) override; - /** Called to handle a particular incoming message - * @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered - * for it - */ virtual ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override; void loadProtoForModule(); bool saveProtoForModule(); - void installDefaultCannedMessageModuleConfig(); - int currentMessageIndex = -1; - cannedMessageModuleRunState runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; - char payload = 0x00; - unsigned int cursor = 0; - String freetext = ""; // Text Buffer for Freetext Editor - NodeNum dest = NODENUM_BROADCAST; - ChannelIndex channel = 0; - cannedMessageDestinationType destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; - uint8_t numChannels = 0; - ChannelIndex indexChannels[MAX_NUM_CHANNELS] = {0}; - NodeNum incoming = NODENUM_BROADCAST; - NodeNum lastSentNode = 0; // Tracks who the message was sent to (for ACK screen) - bool ack = false; // True means ACK, false means NAK (error_reason != NONE) - bool waitingForAck = false; // Are currently interested in routing packets? - bool lastAckWasRelayed = false; - float lastRxSnr = 0; - int32_t lastRxRssi = 0; +private: + // === Input Observers === + CallbackObserver inputObserver = + CallbackObserver(this, &CannedMessageModule::handleInputEvent); + // === Display and UI === + int displayHeight = 64; + int destIndex = 0; + int scrollIndex = 0; + int visibleRows = 0; + bool needsUpdate = true; + bool shouldRedraw = false; + unsigned long lastUpdateMillis = 0; + String searchQuery; + String nodeSelectionInput; + String freetext; + String temporaryMessage; + + // === Message Storage === char messageStore[CANNED_MESSAGE_MODULE_MESSAGES_SIZE + 1]; char *messages[CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT]; int messagesCount = 0; + int currentMessageIndex = -1; + + // === Routing & Acknowledgment === + NodeNum dest = NODENUM_BROADCAST; // Destination node for outgoing messages (default: broadcast) + NodeNum incoming = NODENUM_BROADCAST; // Source node from which last ACK/NACK was received + NodeNum lastSentNode = 0; // Tracks the most recent node we sent a message to (for UI display) + ChannelIndex channel = 0; // Channel index used when sending a message + uint8_t numChannels = 0; // Total number of channels available for selection + ChannelIndex indexChannels[MAX_NUM_CHANNELS] = {0}; // Cached channel indices available for this node + + bool ack = false; // True = ACK received, False = NACK or failed + bool waitingForAck = false; // True if we're expecting an ACK and should monitor routing packets + bool lastAckWasRelayed = false; // True if the ACK was relayed through intermediate nodes + uint8_t lastAckHopStart = 0; // Hop start value from the received ACK packet + uint8_t lastAckHopLimit = 0; // Hop limit value from the received ACK packet + + float lastRxSnr = 0; // SNR from last received ACK (used for diagnostics/UI) + int32_t lastRxRssi = 0; // RSSI from last received ACK (used for diagnostics/UI) + + // === State Tracking === + cannedMessageModuleRunState runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; + cannedMessageDestinationType destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; + char highlight = 0x00; + char payload = 0x00; + unsigned int cursor = 0; unsigned long lastTouchMillis = 0; - String temporaryMessage; + std::vector activeChannelIndices; + std::vector filteredNodes; + #if defined(USE_VIRTUAL_KEYBOARD) Letter keyboard[2][4][10] = {{{{"Q", 20, 0, 0, 0, 0}, @@ -252,4 +255,4 @@ class CannedMessageModule : public SinglePortModule, public Observable