diff --git a/src/NoteI2c.hpp b/src/NoteI2c.hpp index 09805ba..a0a9f9e 100644 --- a/src/NoteI2c.hpp +++ b/src/NoteI2c.hpp @@ -7,12 +7,6 @@ class NoteI2c { public: - /**************************************************************************/ - /*! - @brief Type used to abstract specific hardware implementation types. - */ - /**************************************************************************/ - typedef void * param_t; virtual ~NoteI2c(void) {} @@ -94,8 +88,7 @@ class NoteI2c the platform specific I2C implementation. */ /******************************************************************************/ -NoteI2c * make_note_i2c ( - NoteI2c::param_t i2c_parameters -); +template NoteI2c * make_note_i2c (T & i2c_parameters); +NoteI2c * make_note_i2c (nullptr_t); #endif // NOTE_I2C_HPP diff --git a/src/NoteI2c_Arduino.cpp b/src/NoteI2c_Arduino.cpp index 5bb6ec8..b7673c2 100644 --- a/src/NoteI2c_Arduino.cpp +++ b/src/NoteI2c_Arduino.cpp @@ -4,20 +4,37 @@ static const char *i2cerr = "i2c {io}"; #endif +// Singleton instance of the NoteI2c_Arduino class +namespace instance { + inline NoteI2c* & note_i2c (void) { + static NoteI2c* note_i2c = nullptr; + return note_i2c; + } +}; + NoteI2c * make_note_i2c ( - NoteI2c::param_t i2c_parameters_ + nullptr_t +) { + NoteI2c* & note_i2c = instance::note_i2c(); + if (note_i2c) { + delete note_i2c; + note_i2c = nullptr; + } + return note_i2c; +} + +template +NoteI2c * +make_note_i2c ( + T & i2c_parameters_ ) { - static NoteI2c * note_i2c = nullptr; - if (!i2c_parameters_) { - if (note_i2c) { - delete note_i2c; - note_i2c = nullptr; - } - } else if (!note_i2c) { - note_i2c = new NoteI2c_Arduino(*reinterpret_cast(i2c_parameters_)); + NoteI2c* & note_i2c = instance::note_i2c(); + if (!note_i2c) { + note_i2c = new NoteI2c_Arduino(i2c_parameters_); } + return note_i2c; } @@ -182,3 +199,6 @@ NoteI2c_Arduino::transmit ( return result; } + +// Explicitly instantiate the template function for the supported types +template NoteI2c * make_note_i2c(TwoWire &); diff --git a/src/NoteLog.hpp b/src/NoteLog.hpp index 866b662..77db8b8 100644 --- a/src/NoteLog.hpp +++ b/src/NoteLog.hpp @@ -6,12 +6,6 @@ class NoteLog { public: - /**************************************************************************/ - /*! - @brief Type used to abstract specific hardware implementation types. - */ - /**************************************************************************/ - typedef void * param_t; virtual ~NoteLog(void) {} @@ -36,8 +30,7 @@ class NoteLog the platform specific log output implementation. */ /******************************************************************************/ -NoteLog * make_note_log ( - NoteLog::param_t log_parameters -); +template NoteLog * make_note_log (T & log_parameters); +NoteLog * make_note_log (nullptr_t); #endif // NOTE_LOG_HPP diff --git a/src/NoteLog_Arduino.cpp b/src/NoteLog_Arduino.cpp index c23ab0e..c3d3c6a 100644 --- a/src/NoteLog_Arduino.cpp +++ b/src/NoteLog_Arduino.cpp @@ -1,19 +1,35 @@ #include "NoteLog_Arduino.hpp" +// Singleton instance of the NoteLog_Arduino class +namespace instance { + inline NoteLog* & note_log (void) { + static NoteLog* note_log = nullptr; + return note_log; + } +}; + NoteLog * make_note_log ( - NoteLog::param_t log_parameters_ -) -{ - static NoteLog * note_log = nullptr; - if (!log_parameters_) { - if (note_log) { - delete note_log; - note_log = nullptr; - } - } else if (!note_log) { - note_log = new NoteLog_Arduino(reinterpret_cast(log_parameters_)); + nullptr_t +) { + NoteLog* & note_log = instance::note_log(); + if (note_log) { + delete note_log; + note_log = nullptr; + } + return note_log; +} + +template +NoteLog * +make_note_log ( + T & log_parameters_ +) { + NoteLog* & note_log = instance::note_log(); + if (!note_log) { + note_log = new NoteLog_Arduino(reinterpret_cast(&log_parameters_)); } + return note_log; } @@ -35,3 +51,6 @@ NoteLog_Arduino::print ( return result; } + +// Explicitly instantiate the template function for the supported types +template NoteLog * make_note_log(Stream &); diff --git a/src/NoteTxn.hpp b/src/NoteTxn.hpp index 61d27bb..bbb38c2 100644 --- a/src/NoteTxn.hpp +++ b/src/NoteTxn.hpp @@ -7,12 +7,6 @@ class NoteTxn { public: - /**************************************************************************/ - /*! - @brief Type used to abstract specific hardware implementation types. - */ - /**************************************************************************/ - typedef void * param_t; virtual ~NoteTxn(void) {} @@ -44,8 +38,7 @@ class NoteTxn the platform specific transaction implementation. */ /******************************************************************************/ -NoteTxn * make_note_txn ( - NoteTxn::param_t txn_parameters -); +template NoteTxn * make_note_txn (T & txn_parameters); +NoteTxn * make_note_txn (nullptr_t); #endif // NOTE_TXN_HPP diff --git a/src/NoteTxn_Arduino.cpp b/src/NoteTxn_Arduino.cpp index 554e3dc..304687c 100644 --- a/src/NoteTxn_Arduino.cpp +++ b/src/NoteTxn_Arduino.cpp @@ -7,21 +7,43 @@ #include "mock/mock-parameters.hpp" #endif +// Singleton instance of the NoteTxn_Arduino class +namespace instance { + inline NoteTxn* & note_txn (void) { + static NoteTxn* note_txn = nullptr; + return note_txn; + } +}; + NoteTxn * make_note_txn ( - NoteTxn::param_t txn_parameters_ -) -{ - static NoteTxn * note_txn = nullptr; - if (!txn_parameters_) { + nullptr_t +) { + NoteTxn* & note_txn = instance::note_txn(); + if (note_txn) { + delete note_txn; + note_txn = nullptr; + } + return note_txn; +} + +template +NoteTxn * +make_note_txn ( + T & txn_pins_ +) { + NoteTxn* & note_txn = instance::note_txn(); + + if (txn_pins_[0] == txn_pins_[1]) { + // Invalid tuple invokes deletion if (note_txn) { delete note_txn; note_txn = nullptr; } } else if (!note_txn) { - const uint8_t * txn_pins = reinterpret_cast(txn_parameters_); - note_txn = new NoteTxn_Arduino(txn_pins[0], txn_pins[1]); + note_txn = new NoteTxn_Arduino(txn_pins_[0], txn_pins_[1]); } + return note_txn; } @@ -80,3 +102,7 @@ NoteTxn_Arduino::stop ( // Float RTX pin ::pinMode(_rtx_pin, INPUT); } + +// Explicitly instantiate the template function for array types +template NoteTxn * make_note_txn(uint8_t(&)[2]); +template NoteTxn * make_note_txn(const uint8_t(&)[2]); diff --git a/src/Notecard.h b/src/Notecard.h index fdb852c..d2c1736 100644 --- a/src/Notecard.h +++ b/src/Notecard.h @@ -63,7 +63,7 @@ class Notecard inline void begin(uint32_t i2cAddress = NOTE_I2C_ADDR_DEFAULT, uint32_t i2cMax = NOTE_I2C_MAX_DEFAULT, TwoWire &wirePort = Wire) { - begin(make_note_i2c(&wirePort), i2cAddress, i2cMax); + begin(make_note_i2c(wirePort), i2cAddress, i2cMax); } inline void begin(HardwareSerial &serial, uint32_t speed = 9600) { MakeNoteSerial_ArduinoParameters arduino_parameters(serial, speed); @@ -76,7 +76,7 @@ class Notecard } #endif inline void setDebugOutputStream(Stream &dbgserial) { - setDebugOutputStream(make_note_log(&dbgserial)); + setDebugOutputStream(make_note_log(dbgserial)); } inline void setTransactionPins(uint8_t ctx_pin, uint8_t rtx_pin) { uint8_t txn_pins[2] = {ctx_pin, rtx_pin}; diff --git a/test/NoteI2c_Arduino.test.cpp b/test/NoteI2c_Arduino.test.cpp index 7523452..b69ebc7 100644 --- a/test/NoteI2c_Arduino.test.cpp +++ b/test/NoteI2c_Arduino.test.cpp @@ -16,7 +16,7 @@ int test_make_note_i2c_instantiates_notei2c_object() NoteI2c * notei2c = nullptr; // Action - notei2c = make_note_i2c(reinterpret_cast(&Wire)); + notei2c = make_note_i2c(Wire); // Assert if (nullptr != notei2c) @@ -42,10 +42,10 @@ int test_make_note_i2c_enforces_singleton_by_returning_same_notei2c_object_for_a int result; // Arrange - NoteI2c * const notei2c_1 = make_note_i2c(reinterpret_cast(&Wire)); + NoteI2c * const notei2c_1 = make_note_i2c(Wire); // Action - NoteI2c * const notei2c_2 = make_note_i2c(reinterpret_cast(&Wire)); + NoteI2c * const notei2c_2 = make_note_i2c(Wire); // Assert if (notei2c_1 == notei2c_2) @@ -72,7 +72,7 @@ int test_make_note_i2c_deletes_singleton_when_nullptr_is_passed_as_parameter() int result; // Arrange - NoteI2c * notei2c = make_note_i2c(reinterpret_cast(&Wire)); + NoteI2c * notei2c = make_note_i2c(Wire); assert(notei2c); // Action diff --git a/test/NoteLog_Arduino.test.cpp b/test/NoteLog_Arduino.test.cpp index 06e1d25..057e6ba 100644 --- a/test/NoteLog_Arduino.test.cpp +++ b/test/NoteLog_Arduino.test.cpp @@ -14,9 +14,10 @@ int test_make_note_log_instantiates_notelog_object() // Arrange NoteLog * notelog = nullptr; + Stream & serial_stream = Serial; // Action - notelog = make_note_log(reinterpret_cast(&Serial)); + notelog = make_note_log(serial_stream); // Assert if (nullptr != notelog) @@ -42,10 +43,11 @@ int test_make_note_log_enforces_singleton_by_returning_same_notelog_object_for_a int result; // Arrange - NoteLog * const notelog_1 = make_note_log(reinterpret_cast(&Serial)); + Stream & serial_stream = Serial; + NoteLog * const notelog_1 = make_note_log(serial_stream); // Action - NoteLog * const notelog_2 = make_note_log(reinterpret_cast(&Serial)); + NoteLog * const notelog_2 = make_note_log(serial_stream); // Assert if (notelog_1 == notelog_2) @@ -72,7 +74,8 @@ int test_make_note_log_deletes_singleton_when_nullptr_is_passed_as_parameter() int result; // Arrange - NoteLog * notelog = make_note_log(reinterpret_cast(&Serial)); + Stream & serial_stream = Serial; + NoteLog * notelog = make_note_log(serial_stream); assert(notelog); // Action diff --git a/test/NoteTxn_Arduino.test.cpp b/test/NoteTxn_Arduino.test.cpp index 0d349e1..6d45f2f 100644 --- a/test/NoteTxn_Arduino.test.cpp +++ b/test/NoteTxn_Arduino.test.cpp @@ -16,7 +16,7 @@ int test_make_note_txn_instantiates_notetxn_object() uint8_t txn_pins[2] = {19, 79}; // Action - notetxn = make_note_txn(reinterpret_cast(txn_pins)); + notetxn = make_note_txn(txn_pins); // Assert if (nullptr != notetxn) @@ -32,7 +32,8 @@ int test_make_note_txn_instantiates_notetxn_object() } // Clean-up - make_note_txn(nullptr); + uint8_t invalid_pins[2] = {0}; + make_note_txn(invalid_pins); return result; } @@ -43,11 +44,11 @@ int test_make_note_txn_enforces_singleton_by_returning_same_notetxn_object_for_a // Arrange uint8_t txn_pins_1[2] = {19, 79}; - NoteTxn * const notetxn_1 = make_note_txn(reinterpret_cast(txn_pins_1)); + NoteTxn * const notetxn_1 = make_note_txn(txn_pins_1); // Action uint8_t txn_pins_2[2] = {9, 17}; - NoteTxn * const notetxn_2 = make_note_txn(reinterpret_cast(txn_pins_2)); + NoteTxn * const notetxn_2 = make_note_txn(txn_pins_2); // Assert if (notetxn_1 == notetxn_2) @@ -63,23 +64,25 @@ int test_make_note_txn_enforces_singleton_by_returning_same_notetxn_object_for_a } // Clean-up - make_note_txn(nullptr); + uint8_t invalid_pins[2] = {0}; + make_note_txn(invalid_pins); return result; } -//int test_make_note_txn_returns_nullptr_when_nullptr_is_passed_as_parameter() -int test_make_note_txn_deletes_singleton_when_nullptr_is_passed_as_parameter() +//int test_make_note_txn_returns_nullptr_when_same_pins_are_passed_as_parameter() +int test_make_note_txn_deletes_singleton_when_same_pins_are_passed_as_parameter() { int result; // Arrange uint8_t txn_pins[2] = {19, 79}; - NoteTxn * notetxn = make_note_txn(reinterpret_cast(txn_pins)); + NoteTxn * notetxn = make_note_txn(txn_pins); assert(notetxn); // Action - notetxn = make_note_txn(nullptr); + uint8_t invalid_pins[2] = {0}; + notetxn = make_note_txn(invalid_pins); // Assert if (nullptr == notetxn) @@ -605,7 +608,7 @@ int main(void) TestFunction tests[] = { {test_make_note_txn_instantiates_notetxn_object, "test_make_note_txn_instantiates_notetxn_object"}, {test_make_note_txn_enforces_singleton_by_returning_same_notetxn_object_for_all_calls, "test_make_note_txn_enforces_singleton_by_returning_same_notetxn_object_for_all_calls"}, - {test_make_note_txn_deletes_singleton_when_nullptr_is_passed_as_parameter, "test_make_note_txn_deletes_singleton_when_nullptr_is_passed_as_parameter"}, + {test_make_note_txn_deletes_singleton_when_same_pins_are_passed_as_parameter, "test_make_note_txn_deletes_singleton_when_same_pins_are_passed_as_parameter"}, {test_notetxn_arduino_constructor_floats_ctx_pin, "test_notetxn_arduino_constructor_floats_ctx_pin"}, {test_notetxn_arduino_constructor_floats_rtx_pin, "test_notetxn_arduino_constructor_floats_rtx_pin"}, {test_notetxn_arduino_start_initially_configures_ctx_pin_as_input_pullup, "test_notetxn_arduino_start_initially_configures_ctx_pin_as_input_pullup"}, diff --git a/test/Notecard.test.cpp b/test/Notecard.test.cpp index 2dcad31..7c83ae4 100644 --- a/test/Notecard.test.cpp +++ b/test/Notecard.test.cpp @@ -1706,7 +1706,7 @@ int test_notecard_end_provides_nullptr_to_make_note_i2c_to_free_associated_memor Notecard notecard; NoteI2c_Mock mockI2c; // Instantiate NoteI2c (mocked) make_note_i2c_Parameters.reset(); - make_note_i2c_Parameters.i2c_parameters = &mockI2c; + make_note_i2c_Parameters.i2c_parameters = &Wire; notecard.begin(&mockI2c); // Action diff --git a/test/mock/NoteI2c_Mock.cpp b/test/mock/NoteI2c_Mock.cpp index eb5c8a6..ad863bc 100644 --- a/test/mock/NoteI2c_Mock.cpp +++ b/test/mock/NoteI2c_Mock.cpp @@ -1,15 +1,29 @@ #include "mock/NoteI2c_Mock.hpp" -MakeNoteI2c_Parameters make_note_i2c_Parameters; +MakeNoteI2c_Parameters make_note_i2c_Parameters; NoteI2cReceive_Parameters noteI2cReceive_Parameters; NoteI2cReset_Parameters noteI2cReset_Parameters; NoteI2cTransmit_Parameters noteI2cTransmit_Parameters; NoteI2c * make_note_i2c ( - NoteI2c::param_t i2c_parameters_ -) -{ + nullptr_t +) { + // Record invocation(s) + ++make_note_i2c_Parameters.invoked; + + // Stash parameter(s) + make_note_i2c_Parameters.i2c_parameters = nullptr; + + // Return user-supplied result + return make_note_i2c_Parameters.result; +} + +template +NoteI2c * +make_note_i2c ( + T & i2c_parameters_ +) { // Record invocation(s) ++make_note_i2c_Parameters.invoked; diff --git a/test/mock/NoteI2c_Mock.hpp b/test/mock/NoteI2c_Mock.hpp index ca7f7cb..ea96dcc 100644 --- a/test/mock/NoteI2c_Mock.hpp +++ b/test/mock/NoteI2c_Mock.hpp @@ -7,6 +7,7 @@ #include #include "NoteI2c.hpp" +#include "mock/mock-arduino.hpp" class NoteI2c_Mock final : public NoteI2c { @@ -16,6 +17,7 @@ class NoteI2c_Mock final : public NoteI2c const char * transmit(uint16_t device_address, uint8_t * buffer, uint16_t size) override; }; +template struct MakeNoteI2c_Parameters { MakeNoteI2c_Parameters( void @@ -32,7 +34,7 @@ struct MakeNoteI2c_Parameters { result = nullptr; } size_t invoked; - NoteI2c::param_t i2c_parameters; + T * i2c_parameters; NoteI2c * result; }; @@ -115,7 +117,7 @@ struct NoteI2cTransmit_Parameters { const char * result; }; -extern MakeNoteI2c_Parameters make_note_i2c_Parameters; +extern MakeNoteI2c_Parameters make_note_i2c_Parameters; extern NoteI2cReceive_Parameters noteI2cReceive_Parameters; extern NoteI2cReset_Parameters noteI2cReset_Parameters; extern NoteI2cTransmit_Parameters noteI2cTransmit_Parameters; diff --git a/test/mock/NoteLog_Mock.cpp b/test/mock/NoteLog_Mock.cpp index 3f752cc..642acbb 100644 --- a/test/mock/NoteLog_Mock.cpp +++ b/test/mock/NoteLog_Mock.cpp @@ -1,11 +1,26 @@ #include "mock/NoteLog_Mock.hpp" -MakeNoteLog_Parameters make_note_log_Parameters; +MakeNoteLog_Parameters make_note_log_Parameters; NoteLogPrint_Parameters noteLogPrint_Parameters; NoteLog * make_note_log ( - NoteLog::param_t log_parameters_ + nullptr_t +) { + // Record invocation(s) + ++make_note_log_Parameters.invoked; + + // Stash parameter(s) + make_note_log_Parameters.log_parameters = nullptr; + + // Return user-supplied result + return make_note_log_Parameters.result; +} + +template +NoteLog * +make_note_log ( + T & log_parameters_ ) { // Record invocation(s) diff --git a/test/mock/NoteLog_Mock.hpp b/test/mock/NoteLog_Mock.hpp index 5e105a1..13bcbb7 100644 --- a/test/mock/NoteLog_Mock.hpp +++ b/test/mock/NoteLog_Mock.hpp @@ -5,6 +5,7 @@ #include #include "NoteLog.hpp" +#include "mock-arduino.hpp" class NoteLog_Mock final : public NoteLog { @@ -12,6 +13,7 @@ class NoteLog_Mock final : public NoteLog size_t print(const char * message) override; }; +template struct MakeNoteLog_Parameters { MakeNoteLog_Parameters( void @@ -28,7 +30,7 @@ struct MakeNoteLog_Parameters { result = nullptr; } size_t invoked; - NoteLog::param_t log_parameters; + T * log_parameters; NoteLog * result; }; @@ -52,7 +54,7 @@ struct NoteLogPrint_Parameters { size_t result; }; -extern MakeNoteLog_Parameters make_note_log_Parameters; +extern MakeNoteLog_Parameters make_note_log_Parameters; extern NoteLogPrint_Parameters noteLogPrint_Parameters; #endif // MOCK_NOTE_LOG_HPP diff --git a/test/mock/NoteTxn_Mock.cpp b/test/mock/NoteTxn_Mock.cpp index 633d30a..ca5c96f 100644 --- a/test/mock/NoteTxn_Mock.cpp +++ b/test/mock/NoteTxn_Mock.cpp @@ -1,12 +1,26 @@ #include "mock/NoteTxn_Mock.hpp" -MakeNoteTxn_Parameters make_note_txn_Parameters; +MakeNoteTxn_Parameters make_note_txn_Parameters; NoteTxnStart_Parameters noteTxnStart_Parameters; NoteTxnStop_Parameters noteTxnStop_Parameters; NoteTxn * make_note_txn ( - NoteTxn::param_t txn_parameters_ + nullptr_t +) { + // Record invocation(s) + ++make_note_txn_Parameters.invoked; + + // Stash parameter(s) + + // Return user-supplied result + return make_note_txn_Parameters.result; +} + +template +NoteTxn * +make_note_txn ( + T & txn_parameters_ ) { // Record invocation(s) diff --git a/test/mock/NoteTxn_Mock.hpp b/test/mock/NoteTxn_Mock.hpp index f8a4813..25196a4 100644 --- a/test/mock/NoteTxn_Mock.hpp +++ b/test/mock/NoteTxn_Mock.hpp @@ -13,12 +13,13 @@ class NoteTxn_Mock final : public NoteTxn void stop (void) override; }; +template struct MakeNoteTxn_Parameters { MakeNoteTxn_Parameters( void ) : invoked(0), - txn_parameters(nullptr), + txn_parameters{0, 0}, result(nullptr) { } void reset ( @@ -29,7 +30,7 @@ struct MakeNoteTxn_Parameters { result = nullptr; } size_t invoked; - NoteTxn::param_t txn_parameters; + T txn_parameters; NoteTxn * result; }; @@ -67,7 +68,7 @@ struct NoteTxnStop_Parameters { size_t invoked; }; -extern MakeNoteTxn_Parameters make_note_txn_Parameters; +extern MakeNoteTxn_Parameters make_note_txn_Parameters; extern NoteTxnStart_Parameters noteTxnStart_Parameters; extern NoteTxnStop_Parameters noteTxnStop_Parameters;