REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
print-multiplexer.h
Go to the documentation of this file.
1// Copyright (c) 2024 anabrid GmbH
2// Contact: https://www.anabrid.com/licensing/
3// SPDX-License-Identifier: MIT OR GPL-2.0-or-later
4
5#pragma once
6
7#include <Arduino.h>
8
9#ifdef ARDUINO
10
11#include <algorithm>
12#include <list>
13#include <vector>
14#include <QNEthernetClient.h>
15
16#include "util/PrintUtils.h" // QNEthernet
17
18namespace utils {
19
20using qindesign::network::EthernetClient;
21
38class PrintMultiplexer : public Print {
39 bool serial = false;
40 std::list<Print *> print_targets;
41 std::list<EthernetClient*> eth_targets;
42
43public:
44 bool optimistic = false;
45
46 void add(Print *target) { print_targets.push_back(target); }
47 void add(EthernetClient *target) { eth_targets.push_back(target); }
48 void add_Serial() { serial = true; }
49
50 void remove(Print *target) { print_targets.remove(target); }
51 void remove(EthernetClient *target) { eth_targets.remove(target); }
52
53 size_t size() const { return print_targets.size() + eth_targets.size(); }
54
56 virtual size_t write(uint8_t b) override {
57 bool success = true;
58 if(serial && Serial.availableForWrite()) success &= Serial.write(b) == 1;
59 for (auto &target : print_targets) if (target) success &= target->write(b) == 1;
60 for (auto &target : eth_targets) if (target) success &= target->writeFully(b) == 1;
61 return success ? 1 : (optimistic ? 1 : 0);
62 }
63
64 size_t write(const uint8_t *buffer, size_t size) override {
65 bool success = true;
66 if(serial && Serial.availableForWrite()) success &= Serial.write(buffer,size) == size; // do not use writeFully
67 for (auto &target : print_targets) if (target) success &= qindesign::network::util::writeFully(*target, buffer, size) == size;
68 for (auto &target : eth_targets) if (target) success &= target->writeFully(buffer, size) == size;
69 // so do all this extra work of print_targets + eth_targets just to exploit that
70 // EthernetClient::write_fully internally does a "still connected" check and if
71 // not, fails. This way we avoid an endless loop if a client disconnects during printout.
72 // Typically, in contrast, print_targets are either Serial or String-Buffers.
73 return success ? size : (optimistic ? size : 0);
74 }
75
76 virtual void flush() override {
77 if(serial && Serial) Serial.flush();
78 for (auto &target : print_targets) if (target) target->flush();
79 for (auto &target : eth_targets) if (target) target->flush();
80 }
81};
82
83} // namespace utils
84
85#endif // ARDUINO
A "multiplexer" for Print targets.
virtual void flush() override
size_t write(const uint8_t *buffer, size_t size) override
void remove(Print *target)
void add(Print *target)
bool optimistic
whether you prefer to send too much or too few
virtual size_t write(uint8_t b) override
Printables which go to all clients.
void remove(EthernetClient *target)
void add(EthernetClient *target)
static constexpr int success
Definition flasher.cpp:275