Skip to content

Commit b17d2b4

Browse files
committed
chore: Template NoteSerial
Allows for SoftwareSerial
1 parent 4f1a24e commit b17d2b4

11 files changed

+355
-69
lines changed

src/NoteSerial.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ class NoteSerial
6565
the platform specific UART implementation.
6666
*/
6767
/******************************************************************************/
68-
NoteSerial * make_note_serial (
69-
NoteSerial::param_t serial_parameters
70-
);
68+
template<typename T> NoteSerial * make_note_serial (T & serial_parameters);
69+
NoteSerial * make_note_serial (nullptr_t);
7170

7271
#endif // NOTE_SERIAL_HPP

src/NoteSerial_Arduino.cpp

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,61 @@
11
#include "NoteSerial_Arduino.hpp"
22

3+
#ifndef NOTE_MOCK
4+
#ifdef NOTE_ARDUINO_SOFTWARE_SERIAL_SUPPORT
5+
#include <SoftwareSerial.h>
6+
#endif
7+
#else
8+
#include "mock/mock-arduino.hpp"
9+
#endif
10+
11+
// Template Meta-Programming (TMP) to extract the nested template type
12+
template <typename nested_type>
13+
struct ExtractNestedTemplateType {
14+
// Default case: no extraction
15+
};
16+
template <typename nested_type>
17+
struct ExtractNestedTemplateType<MakeNoteSerial_ArduinoParameters<nested_type>> {
18+
using type = nested_type;
19+
};
20+
21+
// Singleton instance of the NoteSerial_Arduino class
22+
namespace instance {
23+
inline NoteSerial* & note_serial (void) {
24+
static NoteSerial* note_serial = nullptr;
25+
return note_serial;
26+
}
27+
};
28+
329
NoteSerial *
430
make_note_serial (
5-
NoteSerial::param_t serial_parameters_
6-
)
7-
{
8-
static NoteSerial * note_serial = nullptr;
9-
if (!serial_parameters_) {
10-
if (note_serial) {
11-
delete note_serial;
12-
note_serial = nullptr;
13-
}
14-
} else if (!note_serial) {
15-
MakeNoteSerial_ArduinoParameters * arduino_parameters = reinterpret_cast<MakeNoteSerial_ArduinoParameters *>(serial_parameters_);
16-
note_serial = new NoteSerial_Arduino(arduino_parameters->hw_serial, arduino_parameters->baud_rate);
31+
nullptr_t
32+
) {
33+
NoteSerial* & note_serial = instance::note_serial();
34+
if (note_serial) {
35+
delete note_serial;
36+
note_serial = nullptr;
1737
}
1838
return note_serial;
1939
}
2040

21-
NoteSerial_Arduino::NoteSerial_Arduino
41+
template <typename T>
42+
NoteSerial *
43+
make_note_serial (
44+
T & serial_parameters_
45+
) {
46+
NoteSerial* & note_serial = instance::note_serial();
47+
if (!note_serial) {
48+
using serial_type = typename ExtractNestedTemplateType<T>::type;
49+
note_serial = new NoteSerial_Arduino<serial_type>(serial_parameters_.hw_serial, serial_parameters_.baud_rate);
50+
}
51+
52+
return note_serial;
53+
}
54+
55+
template <typename T>
56+
NoteSerial_Arduino<T>::NoteSerial_Arduino
2257
(
23-
HardwareSerial & hw_serial_,
58+
T & hw_serial_,
2459
size_t baud_rate_
2560
) :
2661
_notecardSerial(hw_serial_),
@@ -29,31 +64,35 @@ NoteSerial_Arduino::NoteSerial_Arduino
2964
_notecardSerial.begin(_notecardSerialSpeed);
3065
}
3166

32-
NoteSerial_Arduino::~NoteSerial_Arduino (
67+
template <typename T>
68+
NoteSerial_Arduino<T>::~NoteSerial_Arduino (
3369
void
3470
)
3571
{
3672
_notecardSerial.end();
3773
}
3874

75+
template <typename T>
3976
size_t
40-
NoteSerial_Arduino::available (
77+
NoteSerial_Arduino<T>::available (
4178
void
4279
)
4380
{
4481
return _notecardSerial.available();
4582
}
4683

84+
template <typename T>
4785
char
48-
NoteSerial_Arduino::receive (
86+
NoteSerial_Arduino<T>::receive (
4987
void
5088
)
5189
{
5290
return _notecardSerial.read();
5391
}
5492

93+
template <typename T>
5594
bool
56-
NoteSerial_Arduino::reset (
95+
NoteSerial_Arduino<T>::reset (
5796
void
5897
)
5998
{
@@ -63,8 +102,9 @@ NoteSerial_Arduino::reset (
63102
return true;
64103
}
65104

105+
template <typename T>
66106
size_t
67-
NoteSerial_Arduino::transmit (
107+
NoteSerial_Arduino<T>::transmit (
68108
uint8_t *buffer,
69109
size_t size,
70110
bool flush
@@ -77,3 +117,12 @@ NoteSerial_Arduino::transmit (
77117
}
78118
return result;
79119
}
120+
121+
// Explicitly instantiate the classes and methods for the supported types
122+
template class NoteSerial_Arduino<HardwareSerial>;
123+
template NoteSerial * make_note_serial<MakeNoteSerial_ArduinoParameters<HardwareSerial>>(MakeNoteSerial_ArduinoParameters<HardwareSerial> &);
124+
125+
#ifdef NOTE_ARDUINO_SOFTWARE_SERIAL_SUPPORT
126+
template class NoteSerial_Arduino<SoftwareSerial>;
127+
template NoteSerial * make_note_serial<MakeNoteSerial_ArduinoParameters<SoftwareSerial>>(MakeNoteSerial_ArduinoParameters<SoftwareSerial> &);
128+
#endif

src/NoteSerial_Arduino.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,32 @@
99
#include "mock/mock-arduino.hpp"
1010
#endif
1111

12+
template <typename T>
1213
struct MakeNoteSerial_ArduinoParameters {
1314
MakeNoteSerial_ArduinoParameters (
14-
HardwareSerial & hw_serial_,
15+
T & hw_serial_,
1516
size_t baud_rate_
1617
) :
1718
hw_serial(hw_serial_),
1819
baud_rate(baud_rate_)
1920
{ }
20-
HardwareSerial & hw_serial;
21+
T & hw_serial;
2122
size_t baud_rate;
2223
};
2324

25+
template <typename T>
2426
class NoteSerial_Arduino final : public NoteSerial
2527
{
2628
public:
27-
NoteSerial_Arduino(HardwareSerial & hw_serial_, size_t baud_rate_);
29+
NoteSerial_Arduino(T & hw_serial_, size_t baud_rate_);
2830
~NoteSerial_Arduino(void);
2931
size_t available(void) override;
3032
char receive(void) override;
3133
bool reset(void) override;
3234
size_t transmit(uint8_t * buffer, size_t size, bool flush) override;
3335

3436
private:
35-
HardwareSerial & _notecardSerial;
37+
T & _notecardSerial;
3638
const int _notecardSerialSpeed;
3739
};
3840

src/NoteTxn.hpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,7 @@ class NoteTxn
3838
the platform specific transaction implementation.
3939
*/
4040
/******************************************************************************/
41-
template <typename T>
42-
NoteTxn * make_note_txn (
43-
T & txn_parameters
44-
);
45-
46-
NoteTxn * make_note_txn (
47-
nullptr_t
48-
);
41+
template<typename T> NoteTxn * make_note_txn (T & txn_parameters);
42+
NoteTxn * make_note_txn (nullptr_t);
4943

5044
#endif // NOTE_TXN_HPP

src/NoteTxn_Arduino.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,32 @@
77
#include "mock/mock-parameters.hpp"
88
#endif
99

10+
// Singleton instance of the NoteSerial_Arduino class
11+
namespace instance {
12+
inline NoteTxn* & note_txn (void) {
13+
static NoteTxn* note_txn = nullptr;
14+
return note_txn;
15+
}
16+
};
17+
1018
NoteTxn *
1119
make_note_txn (
1220
nullptr_t
1321
) {
14-
const uint8_t invoke_deletion[2] = {0, 0}; // Invalid tuple invokes deletion
15-
return make_note_txn(invoke_deletion);
22+
NoteTxn* & note_txn = instance::note_txn();
23+
if (note_txn) {
24+
delete note_txn;
25+
note_txn = nullptr;
26+
}
27+
return note_txn;
1628
}
1729

1830
template <typename T>
1931
NoteTxn *
2032
make_note_txn (
2133
T & txn_pins_
2234
) {
23-
// Singleton
24-
static NoteTxn * note_txn = nullptr;
35+
NoteTxn* & note_txn = instance::note_txn();
2536

2637
if (txn_pins_[0] == txn_pins_[1]) {
2738
// Invalid tuple invokes deletion

src/Notecard.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
#ifndef Notecard_h
2525
#define Notecard_h
2626

27+
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR) || defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_NRF52) || defined(ARDUINO_ARCH_RP2040)
28+
#define NOTE_ARDUINO_SOFTWARE_SERIAL_SUPPORT
29+
#endif
30+
2731
#include <stddef.h>
2832
#include <stdint.h>
2933

@@ -34,6 +38,9 @@
3438

3539
#ifdef ARDUINO
3640
#include <Arduino.h>
41+
#ifdef NOTE_ARDUINO_SOFTWARE_SERIAL_SUPPORT
42+
#include <SoftwareSerial.h>
43+
#endif
3744
#include <Wire.h>
3845
#include "NoteSerial_Arduino.hpp"
3946
#endif
@@ -77,9 +84,15 @@ class Notecard
7784
begin(make_note_i2c(&wirePort), i2cAddress, i2cMax);
7885
}
7986
inline void begin(HardwareSerial &serial, uint32_t speed = 9600) {
80-
MakeNoteSerial_ArduinoParameters arduino_parameters(serial, speed);
81-
begin(make_note_serial(&arduino_parameters));
87+
MakeNoteSerial_ArduinoParameters<HardwareSerial> arduino_parameters(serial, speed);
88+
begin(make_note_serial<MakeNoteSerial_ArduinoParameters<HardwareSerial>>(arduino_parameters));
8289
}
90+
#ifdef NOTE_ARDUINO_SOFTWARE_SERIAL_SUPPORT
91+
inline void begin(SoftwareSerial &serial, uint32_t speed = 9600) {
92+
MakeNoteSerial_ArduinoParameters<SoftwareSerial> arduino_parameters(serial, speed);
93+
begin(make_note_serial<MakeNoteSerial_ArduinoParameters<SoftwareSerial>>(arduino_parameters));
94+
}
95+
#endif
8396
inline void setDebugOutputStream(Stream &dbgserial) {
8497
setDebugOutputStream(make_note_log(&dbgserial));
8598
}
@@ -96,8 +109,7 @@ class Notecard
96109
setDebugOutputStream(nullptr);
97110
}
98111
inline void clearTransactionPins(void) {
99-
uint8_t txn_pins[2] = {0};
100-
setTransactionPins(make_note_txn(txn_pins));
112+
setTransactionPins(make_note_txn(nullptr));
101113
}
102114
bool debugSyncStatus (int pollFrequencyMs, int maxLevel);
103115
void deleteResponse(J *rsp) const;

0 commit comments

Comments
 (0)