Advertisement
tarbear123

XOD

Mar 7th, 2019
560
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 169.84 KB | None | 0 0
  1. // The sketch is auto-generated with XOD (https://xod.io).
  2. //
  3. // You can compile and upload it to an Arduino-compatible board with
  4. // Arduino IDE.
  5. //
  6. // Rough code overview:
  7. //
  8. // - Configuration section
  9. // - STL shim
  10. // - Immutable list classes and functions
  11. // - XOD runtime environment
  12. // - Native node implementation
  13. // - Program graph definition
  14. //
  15. // Search for comments fenced with '====' and '----' to navigate through
  16. // the major code blocks.
  17.  
  18. #include <Arduino.h>
  19. #include <inttypes.h>
  20.  
  21.  
  22. /*=============================================================================
  23. *
  24. *
  25. * Configuration
  26. *
  27. *
  28. =============================================================================*/
  29.  
  30. // Uncomment to turn on debug of the program
  31. //#define XOD_DEBUG
  32.  
  33. // Uncomment to trace the program runtime in the Serial Monitor
  34. //#define XOD_DEBUG_ENABLE_TRACE
  35.  
  36.  
  37. // Uncomment to make possible simulation of the program
  38. //#define XOD_SIMULATION
  39.  
  40. #ifdef XOD_SIMULATION
  41. #include <WasmSerial.h>
  42. #define XOD_DEBUG_SERIAL WasmSerial
  43. #else
  44. #define XOD_DEBUG_SERIAL DEBUG_SERIAL
  45. #endif
  46.  
  47. /*=============================================================================
  48. *
  49. *
  50. * STL shim. Provides implementation for vital std::* constructs
  51. *
  52. *
  53. =============================================================================*/
  54.  
  55. namespace xod {
  56. namespace std {
  57.  
  58. template< class T > struct remove_reference {typedef T type;};
  59. template< class T > struct remove_reference<T&> {typedef T type;};
  60. template< class T > struct remove_reference<T&&> {typedef T type;};
  61.  
  62. template <class T>
  63. typename remove_reference<T>::type&& move(T&& a) {
  64. return static_cast<typename remove_reference<T>::type&&>(a);
  65. }
  66.  
  67. } // namespace std
  68. } // namespace xod
  69.  
  70. /*=============================================================================
  71. *
  72. *
  73. * Basic XOD types
  74. *
  75. *
  76. =============================================================================*/
  77. namespace xod {
  78. #if __SIZEOF_FLOAT__ == 4
  79. typedef float Number;
  80. #else
  81. typedef double Number;
  82. #endif
  83. typedef bool Logic;
  84. typedef unsigned long TimeMs;
  85. typedef uint8_t DirtyFlags;
  86. } // namespace xod
  87.  
  88. /*=============================================================================
  89. *
  90. *
  91. * XOD-specific list/array implementations
  92. *
  93. *
  94. =============================================================================*/
  95.  
  96. #ifndef XOD_LIST_H
  97. #define XOD_LIST_H
  98.  
  99. namespace xod {
  100. namespace detail {
  101.  
  102. /*
  103. * Cursors are used internaly by iterators and list views. They are not exposed
  104. * directly to a list consumer.
  105. *
  106. * The base `Cursor` is an interface which provides the bare minimum of methods
  107. * to facilitate a single iteration pass.
  108. */
  109. template<typename T> class Cursor {
  110. public:
  111. virtual ~Cursor() { }
  112. virtual bool isValid() const = 0;
  113. virtual bool value(T* out) const = 0;
  114. virtual void next() = 0;
  115. };
  116.  
  117. template<typename T> class NilCursor : public Cursor<T> {
  118. public:
  119. virtual bool isValid() const { return false; }
  120. virtual bool value(T*) const { return false; }
  121. virtual void next() { }
  122. };
  123.  
  124. } // namespace detail
  125.  
  126. /*
  127. * Iterator is an object used to iterate a list once.
  128. *
  129. * Users create new iterators by calling `someList.iterate()`.
  130. * Iterators are created on stack and are supposed to have a
  131. * short live, e.g. for a duration of `for` loop or node’s
  132. * `evaluate` function. Iterators can’t be copied.
  133. *
  134. * Implemented as a pimpl pattern wrapper over the cursor.
  135. * Once created for a cursor, an iterator owns that cursor
  136. * and will delete the cursor object once destroyed itself.
  137. */
  138. template<typename T>
  139. class Iterator {
  140. public:
  141. static Iterator<T> nil() {
  142. return Iterator<T>(new detail::NilCursor<T>());
  143. }
  144.  
  145. Iterator(detail::Cursor<T>* cursor)
  146. : _cursor(cursor)
  147. { }
  148.  
  149. ~Iterator() {
  150. if (_cursor)
  151. delete _cursor;
  152. }
  153.  
  154. Iterator(const Iterator& that) = delete;
  155. Iterator& operator=(const Iterator& that) = delete;
  156.  
  157. Iterator(Iterator&& it)
  158. : _cursor(it._cursor)
  159. {
  160. it._cursor = nullptr;
  161. }
  162.  
  163. Iterator& operator=(Iterator&& it) {
  164. auto tmp = it._cursor;
  165. it._cursor = _cursor;
  166. _cursor = tmp;
  167. return *this;
  168. }
  169.  
  170. operator bool() const { return _cursor->isValid(); }
  171.  
  172. bool value(T* out) const {
  173. return _cursor->value(out);
  174. }
  175.  
  176. T operator*() const {
  177. T out;
  178. _cursor->value(&out);
  179. return out;
  180. }
  181.  
  182. Iterator& operator++() {
  183. _cursor->next();
  184. return *this;
  185. }
  186.  
  187. private:
  188. detail::Cursor<T>* _cursor;
  189. };
  190.  
  191. /*
  192. * An interface for a list view. A particular list view provides a new
  193. * kind of iteration over existing data. This way we can use list slices,
  194. * list concatenations, list rotations, etc without introducing new data
  195. * buffers. We just change the way already existing data is iterated.
  196. *
  197. * ListView is not exposed to a list user directly, it is used internally
  198. * by the List class. However, deriving a new ListView is necessary if you
  199. * make a new list/string processing node.
  200. */
  201. template<typename T> class ListView {
  202. public:
  203. virtual Iterator<T> iterate() const = 0;
  204. };
  205.  
  206. /*
  207. * The list as it seen by data consumers. Have a single method `iterate`
  208. * to create a new iterator.
  209. *
  210. * Implemented as pimpl pattern wrapper over a list view. Takes pointer
  211. * to a list view in constructor and expects the view will be alive for
  212. * the whole life time of the list.
  213. */
  214. template<typename T> class List {
  215. public:
  216. constexpr List()
  217. : _view(nullptr)
  218. { }
  219.  
  220. List(const ListView<T>* view)
  221. : _view(view)
  222. { }
  223.  
  224. Iterator<T> iterate() const {
  225. return _view ? _view->iterate() : Iterator<T>::nil();
  226. }
  227.  
  228. // pre 0.15.0 backward compatibility
  229. List* operator->() __attribute__ ((deprecated)) { return this; }
  230. const List* operator->() const __attribute__ ((deprecated)) { return this; }
  231.  
  232. private:
  233. const ListView<T>* _view;
  234. };
  235.  
  236. /*
  237. * A list view over an old good plain C array.
  238. *
  239. * Expects the array will be alive for the whole life time of the
  240. * view.
  241. */
  242. template<typename T> class PlainListView : public ListView<T> {
  243. public:
  244. class Cursor : public detail::Cursor<T> {
  245. public:
  246. Cursor(const PlainListView* owner)
  247. : _owner(owner)
  248. , _idx(0)
  249. { }
  250.  
  251. bool isValid() const override {
  252. return _idx < _owner->_len;
  253. }
  254.  
  255. bool value(T* out) const override {
  256. if (!isValid())
  257. return false;
  258. *out = _owner->_data[_idx];
  259. return true;
  260. }
  261.  
  262. void next() override { ++_idx; }
  263.  
  264. private:
  265. const PlainListView* _owner;
  266. size_t _idx;
  267. };
  268.  
  269. public:
  270. PlainListView(const T* data, size_t len)
  271. : _data(data)
  272. , _len(len)
  273. { }
  274.  
  275. virtual Iterator<T> iterate() const override {
  276. return Iterator<T>(new Cursor(this));
  277. }
  278.  
  279. private:
  280. friend class Cursor;
  281. const T* _data;
  282. size_t _len;
  283. };
  284.  
  285. /*
  286. * A list view over a null-terminated C-String.
  287. *
  288. * Expects the char buffer will be alive for the whole life time of the view.
  289. * You can use string literals as a buffer, since they are persistent for
  290. * the program execution time.
  291. */
  292. class CStringView : public ListView<char> {
  293. public:
  294. class Cursor : public detail::Cursor<char> {
  295. public:
  296. Cursor(const char* str)
  297. : _ptr(str)
  298. { }
  299.  
  300. bool isValid() const override {
  301. return (bool)*_ptr;
  302. }
  303.  
  304. bool value(char* out) const override {
  305. *out = *_ptr;
  306. return (bool)*_ptr;
  307. }
  308.  
  309. void next() override { ++_ptr; }
  310.  
  311. private:
  312. const char* _ptr;
  313. };
  314.  
  315. public:
  316. CStringView(const char* str = nullptr)
  317. : _str(str)
  318. { }
  319.  
  320. CStringView& operator=(const CStringView& rhs) {
  321. _str = rhs._str;
  322. return *this;
  323. }
  324.  
  325. virtual Iterator<char> iterate() const override {
  326. return _str ? Iterator<char>(new Cursor(_str)) : Iterator<char>::nil();
  327. }
  328.  
  329. private:
  330. friend class Cursor;
  331. const char* _str;
  332. };
  333.  
  334. /*
  335. * A list view over two other lists (Left and Right) which first iterates the
  336. * left one, and when exhausted, iterates the right one.
  337. *
  338. * Expects both Left and Right to be alive for the whole view life time.
  339. */
  340. template<typename T> class ConcatListView : public ListView<T> {
  341. public:
  342. class Cursor : public detail::Cursor<T> {
  343. public:
  344. Cursor(Iterator<T>&& left, Iterator<T>&& right)
  345. : _left(std::move(left))
  346. , _right(std::move(right))
  347. { }
  348.  
  349. bool isValid() const override {
  350. return _left || _right;
  351. }
  352.  
  353. bool value(T* out) const override {
  354. return _left.value(out) || _right.value(out);
  355. }
  356.  
  357. void next() override {
  358. _left ? ++_left : ++_right;
  359. }
  360.  
  361. private:
  362. Iterator<T> _left;
  363. Iterator<T> _right;
  364. };
  365.  
  366. public:
  367. ConcatListView() { }
  368.  
  369. ConcatListView(List<T> left, List<T> right)
  370. : _left(left)
  371. , _right(right)
  372. { }
  373.  
  374. ConcatListView& operator=(const ConcatListView& rhs) {
  375. _left = rhs._left;
  376. _right = rhs._right;
  377. return *this;
  378. }
  379.  
  380. virtual Iterator<T> iterate() const override {
  381. return Iterator<T>(new Cursor(_left.iterate(), _right.iterate()));
  382. }
  383.  
  384. private:
  385. friend class Cursor;
  386. List<T> _left;
  387. List<T> _right;
  388. };
  389.  
  390. //----------------------------------------------------------------------------
  391. // Text string helpers
  392. //----------------------------------------------------------------------------
  393.  
  394. using XString = List<char>;
  395.  
  396. /*
  397. * List and list view in a single pack. An utility used to define constant
  398. * string literals in XOD.
  399. */
  400. class XStringCString : public XString {
  401. public:
  402. XStringCString(const char* str)
  403. : XString(&_view)
  404. , _view(str)
  405. { }
  406.  
  407. private:
  408. CStringView _view;
  409. };
  410.  
  411. } // namespace xod
  412.  
  413. #endif
  414.  
  415. /*=============================================================================
  416. *
  417. *
  418. * Functions to work with memory
  419. *
  420. *
  421. =============================================================================*/
  422. #ifdef __AVR__
  423. // Placement `new` for Arduino
  424. void* operator new(size_t, void* ptr) {
  425. return ptr;
  426. }
  427. #endif
  428.  
  429. /*=============================================================================
  430. *
  431. *
  432. * UART Classes, that wraps Serials
  433. *
  434. *
  435. =============================================================================*/
  436.  
  437. class HardwareSerial;
  438. class SoftwareSerial;
  439.  
  440. namespace xod {
  441.  
  442. class Uart {
  443. private:
  444. long _baud;
  445.  
  446. protected:
  447. bool _started = false;
  448.  
  449. public:
  450. Uart(long baud) {
  451. _baud = baud;
  452. }
  453.  
  454. virtual void begin() = 0;
  455.  
  456. virtual void end() = 0;
  457.  
  458. virtual void flush() = 0;
  459.  
  460. virtual bool available() = 0;
  461.  
  462. virtual bool writeByte(uint8_t) = 0;
  463.  
  464. virtual bool readByte(uint8_t*) = 0;
  465.  
  466. virtual SoftwareSerial* toSoftwareSerial() {
  467. return nullptr;
  468. }
  469.  
  470. virtual HardwareSerial* toHardwareSerial() {
  471. return nullptr;
  472. }
  473.  
  474. void changeBaudRate(long baud) {
  475. _baud = baud;
  476. if (_started) {
  477. end();
  478. begin();
  479. }
  480. }
  481.  
  482. long getBaudRate() const {
  483. return _baud;
  484. }
  485.  
  486. Stream* toStream() {
  487. Stream* stream = (Stream*) toHardwareSerial();
  488. if (stream) return stream;
  489. return (Stream*) toSoftwareSerial();
  490. }
  491. };
  492.  
  493. class HardwareUart : public Uart {
  494. private:
  495. HardwareSerial* _serial;
  496.  
  497. public:
  498. HardwareUart(HardwareSerial& hserial, uint32_t baud = 115200) : Uart(baud) {
  499. _serial = &hserial;
  500. }
  501.  
  502. void begin();
  503. void end();
  504. void flush();
  505.  
  506. bool available() {
  507. return (bool) _serial->available();
  508. }
  509.  
  510. bool writeByte(uint8_t byte) {
  511. return (bool) _serial->write(byte);
  512. }
  513.  
  514. bool readByte(uint8_t* out) {
  515. int data = _serial->read();
  516. if (data == -1) return false;
  517. *out = data;
  518. return true;
  519. }
  520.  
  521. HardwareSerial* toHardwareSerial() {
  522. return _serial;
  523. }
  524. };
  525.  
  526. void HardwareUart::begin() {
  527. _started = true;
  528. _serial->begin(getBaudRate());
  529. };
  530. void HardwareUart::end() {
  531. _started = false;
  532. _serial->end();
  533. };
  534. void HardwareUart::flush() {
  535. _serial->flush();
  536. };
  537.  
  538. } // namespace xod
  539.  
  540. /*=============================================================================
  541. *
  542. *
  543. * Basic algorithms for XOD lists
  544. *
  545. *
  546. =============================================================================*/
  547.  
  548. #ifndef XOD_LIST_FUNCS_H
  549. #define XOD_LIST_FUNCS_H
  550.  
  551.  
  552.  
  553. namespace xod {
  554.  
  555. /*
  556. * Folds a list from left. Also known as "reduce".
  557. */
  558. template<typename T, typename TR>
  559. TR foldl(List<T> xs, TR (*func)(TR, T), TR acc) {
  560. for (auto it = xs.iterate(); it; ++it)
  561. acc = func(acc, *it);
  562. return acc;
  563. }
  564.  
  565. template<typename T> size_t lengthReducer(size_t len, T) {
  566. return len + 1;
  567. }
  568.  
  569. /*
  570. * Computes length of a list.
  571. */
  572. template<typename T> size_t length(List<T> xs) {
  573. return foldl(xs, lengthReducer<T>, (size_t)0);
  574. }
  575.  
  576. template<typename T> T* dumpReducer(T* buff, T x) {
  577. *buff = x;
  578. return buff + 1;
  579. }
  580.  
  581. /*
  582. * Copies a list content into a memory buffer.
  583. *
  584. * It is expected that `outBuff` has enough size to fit all the data.
  585. */
  586. template<typename T> size_t dump(List<T> xs, T* outBuff) {
  587. T* buffEnd = foldl(xs, dumpReducer, outBuff);
  588. return buffEnd - outBuff;
  589. }
  590.  
  591. /*
  592. * Compares two lists.
  593. */
  594. template<typename T> bool equal(List<T> lhs, List<T> rhs) {
  595. auto lhsIt = lhs.iterate();
  596. auto rhsIt = rhs.iterate();
  597.  
  598. for (; lhsIt && rhsIt; ++lhsIt, ++rhsIt) {
  599. if (*lhsIt != *rhsIt) return false;
  600. }
  601.  
  602. return !lhsIt && !rhsIt;
  603. }
  604.  
  605. template<typename T> bool operator == (List<T> lhs, List<T> rhs) {
  606. return equal(lhs, rhs);
  607. }
  608.  
  609. } // namespace xod
  610.  
  611. #endif
  612.  
  613. /*=============================================================================
  614. *
  615. *
  616. * Format Numbers
  617. *
  618. *
  619. =============================================================================*/
  620.  
  621. /**
  622. * Provide `formatNumber` cross-platform number to string converter function.
  623. *
  624. * Taken from here:
  625. * https://github.com/client9/stringencoders/blob/master/src/modp_numtoa.c
  626. * Original function name: `modp_dtoa2`.
  627. *
  628. * Modified:
  629. * - `isnan` instead of tricky comparing and return "NaN"
  630. * - handle Infinity values and return "Inf" or "-Inf"
  631. * - return `OVF` and `-OVF` for numbers bigger than max possible, instead of using `sprintf`
  632. * - use `Number` instead of double
  633. * - if negative number rounds to zero, return just "0" instead of "-0"
  634. *
  635. * This is a replacement of `dtostrf`.
  636. */
  637.  
  638. #ifndef XOD_FORMAT_NUMBER_H
  639. #define XOD_FORMAT_NUMBER_H
  640.  
  641. namespace xod {
  642.  
  643. /**
  644. * Powers of 10
  645. * 10^0 to 10^9
  646. */
  647. static const Number powers_of_10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000,
  648. 10000000, 100000000, 1000000000 };
  649.  
  650. static void strreverse(char* begin, char* end) {
  651. char aux;
  652. while (end > begin)
  653. aux = *end, *end-- = *begin, *begin++ = aux;
  654. };
  655.  
  656. size_t formatNumber(Number value, int prec, char* str) {
  657. if (isnan(value)) {
  658. strcpy(str, "NaN");
  659. return (size_t)3;
  660. }
  661.  
  662. if (isinf(value)) {
  663. bool isNegative = value < 0;
  664. strcpy(str, isNegative ? "-Inf" : "Inf");
  665. return (size_t)isNegative ? 4 : 3;
  666. }
  667.  
  668. /* if input is larger than thres_max return "OVF" */
  669. const Number thres_max = (Number)(0x7FFFFFFF);
  670.  
  671. Number diff = 0.0;
  672. char* wstr = str;
  673.  
  674. if (prec < 0) {
  675. prec = 0;
  676. } else if (prec > 9) {
  677. /* precision of >= 10 can lead to overflow errors */
  678. prec = 9;
  679. }
  680.  
  681. /* we'll work in positive values and deal with the
  682. negative sign issue later */
  683. int neg = 0;
  684. if (value < 0) {
  685. neg = 1;
  686. value = -value;
  687. }
  688.  
  689. uint32_t whole = (uint32_t)value;
  690. Number tmp = (value - whole) * powers_of_10[prec];
  691. uint32_t frac = (uint32_t)(tmp);
  692. diff = tmp - frac;
  693.  
  694. if (diff > 0.5) {
  695. ++frac;
  696. /* handle rollover, e.g. case 0.99 with prec 1 is 1.0 */
  697. if (frac >= powers_of_10[prec]) {
  698. frac = 0;
  699. ++whole;
  700. }
  701. } else if (diff == 0.5 && prec > 0 && (frac & 1)) {
  702. /* if halfway, round up if odd, OR
  703. if last digit is 0. That last part is strange */
  704. ++frac;
  705. if (frac >= powers_of_10[prec]) {
  706. frac = 0;
  707. ++whole;
  708. }
  709. } else if (diff == 0.5 && prec == 0 && (whole & 1)) {
  710. ++frac;
  711. if (frac >= powers_of_10[prec]) {
  712. frac = 0;
  713. ++whole;
  714. }
  715. }
  716.  
  717. if (value > thres_max) {
  718. if (neg) {
  719. strcpy(str, "-OVF");
  720. return (size_t)4;
  721. }
  722. strcpy(str, "OVF");
  723. return (size_t)3;
  724. }
  725.  
  726. int has_decimal = 0;
  727. int count = prec;
  728. bool notzero = frac > 0;
  729.  
  730. while (count > 0) {
  731. --count;
  732. *wstr++ = (char)(48 + (frac % 10));
  733. frac /= 10;
  734. has_decimal = 1;
  735. }
  736.  
  737. if (frac > 0) {
  738. ++whole;
  739. }
  740.  
  741. /* add decimal */
  742. if (has_decimal) {
  743. *wstr++ = '.';
  744. }
  745.  
  746. notzero = notzero || whole > 0;
  747.  
  748. /* do whole part
  749. * Take care of sign conversion
  750. * Number is reversed.
  751. */
  752. do
  753. *wstr++ = (char)(48 + (whole % 10));
  754. while (whole /= 10);
  755.  
  756. if (neg && notzero) {
  757. *wstr++ = '-';
  758. }
  759. *wstr = '\0';
  760. strreverse(str, wstr - 1);
  761. return (size_t)(wstr - str);
  762. }
  763.  
  764. } // namespace xod
  765. #endif
  766.  
  767.  
  768. /*=============================================================================
  769. *
  770. *
  771. * Runtime
  772. *
  773. *
  774. =============================================================================*/
  775.  
  776. //----------------------------------------------------------------------------
  777. // Debug routines
  778. //----------------------------------------------------------------------------
  779. // #ifndef DEBUG_SERIAL
  780. #if defined(XOD_DEBUG) && !defined(DEBUG_SERIAL)
  781. # define DEBUG_SERIAL Serial
  782. #endif
  783.  
  784. #if defined(XOD_DEBUG) && defined(XOD_DEBUG_ENABLE_TRACE)
  785. # define XOD_TRACE(x) { DEBUG_SERIAL.print(x); DEBUG_SERIAL.flush(); }
  786. # define XOD_TRACE_LN(x) { DEBUG_SERIAL.println(x); DEBUG_SERIAL.flush(); }
  787. # define XOD_TRACE_F(x) XOD_TRACE(F(x))
  788. # define XOD_TRACE_FLN(x) XOD_TRACE_LN(F(x))
  789. #else
  790. # define XOD_TRACE(x)
  791. # define XOD_TRACE_LN(x)
  792. # define XOD_TRACE_F(x)
  793. # define XOD_TRACE_FLN(x)
  794. #endif
  795.  
  796. //----------------------------------------------------------------------------
  797. // PGM space utilities
  798. //----------------------------------------------------------------------------
  799. #define pgm_read_nodeid(address) (pgm_read_word(address))
  800.  
  801. /*
  802. * Workaround for bugs:
  803. * https://github.com/arduino/ArduinoCore-sam/pull/43
  804. * https://github.com/arduino/ArduinoCore-samd/pull/253
  805. * Remove after the PRs merge
  806. */
  807. #if !defined(ARDUINO_ARCH_AVR) && defined(pgm_read_ptr)
  808. # undef pgm_read_ptr
  809. # define pgm_read_ptr(addr) (*(const void **)(addr))
  810. #endif
  811.  
  812. namespace xod {
  813. //----------------------------------------------------------------------------
  814. // Global variables
  815. //----------------------------------------------------------------------------
  816.  
  817. TimeMs g_transactionTime;
  818. bool g_isSettingUp;
  819.  
  820. //----------------------------------------------------------------------------
  821. // Metaprogramming utilities
  822. //----------------------------------------------------------------------------
  823.  
  824. template<typename T> struct always_false {
  825. enum { value = 0 };
  826. };
  827.  
  828. //----------------------------------------------------------------------------
  829. // Forward declarations
  830. //----------------------------------------------------------------------------
  831.  
  832. TimeMs transactionTime();
  833. void runTransaction();
  834.  
  835. //----------------------------------------------------------------------------
  836. // Engine (private API)
  837. //----------------------------------------------------------------------------
  838.  
  839. namespace detail {
  840.  
  841. template<typename NodeT>
  842. bool isTimedOut(const NodeT* node) {
  843. TimeMs t = node->timeoutAt;
  844. // TODO: deal with uint32 overflow
  845. return t && t < transactionTime();
  846. }
  847.  
  848. // Marks timed out node dirty. Do not reset timeoutAt here to give
  849. // a chance for a node to get a reasonable result from `isTimedOut`
  850. // later during its `evaluate`
  851. template<typename NodeT>
  852. void checkTriggerTimeout(NodeT* node) {
  853. node->isNodeDirty |= isTimedOut(node);
  854. }
  855.  
  856. template<typename NodeT>
  857. void clearTimeout(NodeT* node) {
  858. node->timeoutAt = 0;
  859. }
  860.  
  861. template<typename NodeT>
  862. void clearStaleTimeout(NodeT* node) {
  863. if (isTimedOut(node))
  864. clearTimeout(node);
  865. }
  866.  
  867. } // namespace detail
  868.  
  869. //----------------------------------------------------------------------------
  870. // Public API (can be used by native nodes’ `evaluate` functions)
  871. //----------------------------------------------------------------------------
  872.  
  873. TimeMs transactionTime() {
  874. return g_transactionTime;
  875. }
  876.  
  877. bool isSettingUp() {
  878. return g_isSettingUp;
  879. }
  880.  
  881. template<typename ContextT>
  882. void setTimeout(ContextT* ctx, TimeMs timeout) {
  883. ctx->_node->timeoutAt = transactionTime() + timeout;
  884. }
  885.  
  886. template<typename ContextT>
  887. void clearTimeout(ContextT* ctx) {
  888. detail::clearTimeout(ctx->_node);
  889. }
  890.  
  891. template<typename ContextT>
  892. bool isTimedOut(const ContextT* ctx) {
  893. return detail::isTimedOut(ctx->_node);
  894. }
  895.  
  896. bool isValidDigitalPort(uint8_t port) {
  897. #if defined(__AVR__) && defined(NUM_DIGITAL_PINS)
  898. return port < NUM_DIGITAL_PINS;
  899. #else
  900. return true;
  901. #endif
  902. }
  903.  
  904. bool isValidAnalogPort(uint8_t port) {
  905. #if defined(__AVR__) && defined(NUM_ANALOG_INPUTS)
  906. return port >= A0 && port < A0 + NUM_ANALOG_INPUTS;
  907. #else
  908. return true;
  909. #endif
  910. }
  911.  
  912. } // namespace xod
  913.  
  914. //----------------------------------------------------------------------------
  915. // Entry point
  916. //----------------------------------------------------------------------------
  917. void setup() {
  918. // FIXME: looks like there is a rounding bug. Waiting for 100ms fights it
  919. delay(100);
  920.  
  921. #if defined(XOD_DEBUG) || defined(XOD_SIMULATION)
  922. XOD_DEBUG_SERIAL.begin(115200);
  923. XOD_DEBUG_SERIAL.setTimeout(10);
  924. #endif
  925. XOD_TRACE_FLN("\n\nProgram started");
  926.  
  927. xod::g_isSettingUp = true;
  928. xod::runTransaction();
  929. xod::g_isSettingUp = false;
  930. }
  931.  
  932. void loop() {
  933. xod::runTransaction();
  934. }
  935.  
  936. /*=============================================================================
  937. *
  938. *
  939. * Native node implementations
  940. *
  941. *
  942. =============================================================================*/
  943.  
  944. namespace xod {
  945.  
  946. //-----------------------------------------------------------------------------
  947. // bitrex/xod-menu-system/menu-base implementation
  948. //-----------------------------------------------------------------------------
  949. namespace bitrex__xod_menu_system__menu_base {
  950.  
  951. //#pragma XOD dirtiness disable
  952.  
  953. /* Base classes for a BiDirectionalCursor oover a ListView,
  954. this adds the required virtual method "prev" for iterating in
  955. reverse-order, in addition to inheriting "next" */
  956. template <typename T>
  957. class BiDirectionalCursor : public detail::Cursor<T> {
  958. public:
  959. virtual void prev() = 0;
  960. };
  961.  
  962. template <typename T>
  963. class BiDirectionalNilCursor : public BiDirectionalCursor<T> {
  964. bool isValid() const { return false; }
  965. bool value(T*) const { return false; }
  966. void next() {}
  967. void prev() {}
  968. };
  969.  
  970. /* Reverse iterator implementation */
  971.  
  972. template <typename T>
  973. class ReverseIterator {
  974. public:
  975. static Iterator<T> nil() { return Iterator<T>(new detail::NilCursor<T>()); }
  976.  
  977. explicit ReverseIterator(BiDirectionalCursor<T>* cursor) : _cursor(cursor) {}
  978.  
  979. ReverseIterator(const ReverseIterator<T>&) = delete;
  980. ReverseIterator& operator=(const ReverseIterator<T>&) = delete;
  981. ReverseIterator(ReverseIterator<T>&& other) : _cursor(other._cursor) {
  982. other._cursor = nullptr;
  983. }
  984.  
  985. ReverseIterator& operator=(ReverseIterator<T>&& other) {
  986. auto tmp = _cursor;
  987. _cursor = other._cursor;
  988. other._cursor = tmp;
  989. return *this;
  990. }
  991.  
  992. operator bool() const { return _cursor.isValid(); }
  993.  
  994. bool value(T* out) const { return _cursor.value(out); }
  995.  
  996. T operator*() const {
  997. T out;
  998. _cursor->value(&out);
  999. return out;
  1000. }
  1001.  
  1002. ReverseIterator& operator--() {
  1003. _cursor->prev();
  1004. return *this;
  1005. }
  1006.  
  1007. private:
  1008. BiDirectionalCursor<T>* _cursor;
  1009. };
  1010.  
  1011. template <typename T>
  1012. class BiDirectionalIterator;
  1013.  
  1014. /* A ListView which can return a bi-directional iterator
  1015. via the "biterate" method, compare with the XOD library
  1016. class "ListView" and "iterate" method. */
  1017.  
  1018. template <typename T>
  1019. class BiDirectionalListView : public ListView<T> {
  1020. public:
  1021. virtual BiDirectionalIterator<T> biterate() const = 0;
  1022.  
  1023. protected:
  1024. BiDirectionalListView() = default;
  1025. };
  1026.  
  1027. template <typename T>
  1028. class BiDirectionalList : public List<T> {
  1029. public:
  1030. constexpr BiDirectionalList() = default;
  1031.  
  1032. explicit BiDirectionalList(const BiDirectionalListView<T>* view)
  1033. : List<T>(view), _view(view) {}
  1034.  
  1035. BiDirectionalIterator<T> biterate() const {
  1036. return _view ? _view->biterate() : BiDirectionalIterator<T>::nil();
  1037. }
  1038.  
  1039. private:
  1040. const BiDirectionalListView<T>* _view = nullptr;
  1041. };
  1042.  
  1043. /* A bi-directional iterator which functions similar to the XOD
  1044. library class "Iterator" but can be iterated through forwards
  1045. and backwards. Both forward-iterating past the end of the
  1046. underlying container/array and backwards past the starting
  1047. element will invalidate the iterator, and the user-defined
  1048. conversion to bool will return false. */
  1049.  
  1050. template <typename T>
  1051. class BiDirectionalIterator {
  1052. public:
  1053. static BiDirectionalIterator<T> nil() {
  1054. return BiDirectionalIterator<T>(new BiDirectionalNilCursor<T>());
  1055. }
  1056.  
  1057. BiDirectionalIterator(BiDirectionalCursor<T>* cursor)
  1058. : _forward_iterator(cursor), _reverse_iterator(cursor) {}
  1059.  
  1060. operator bool() const { return (bool)_forward_iterator; }
  1061.  
  1062. bool value(T* out) const { return _forward_iterator.value(out); }
  1063.  
  1064. T operator*() const {
  1065. T out;
  1066. _forward_iterator.value(&out);
  1067. return out;
  1068. }
  1069.  
  1070. BiDirectionalIterator& operator++() {
  1071. ++_forward_iterator;
  1072. return *this;
  1073. }
  1074.  
  1075. BiDirectionalIterator& operator--() {
  1076. --_reverse_iterator;
  1077. return *this;
  1078. }
  1079.  
  1080. private:
  1081. Iterator<T> _forward_iterator;
  1082. ReverseIterator<T> _reverse_iterator;
  1083. };
  1084.  
  1085. /* A bi-directional list view over a good ol' C-style array. Compare
  1086. XOD library class "PlainListView" */
  1087.  
  1088. template <typename T>
  1089. class BiDirectionalPlainListView : public BiDirectionalListView<T> {
  1090. class Cursor : public BiDirectionalCursor<T> {
  1091. public:
  1092. explicit Cursor(const BiDirectionalPlainListView* owner) : _owner(owner), _idx(0) {}
  1093.  
  1094. bool isValid() const override { return _valid; }
  1095.  
  1096. bool value(T* out) const override {
  1097. if (!isValid()) return false;
  1098. *out = _owner->_data[_idx];
  1099. return true;
  1100. }
  1101.  
  1102. void next() override {
  1103. if (!(++_idx < _owner->_len)) {
  1104. _valid = false;
  1105. }
  1106. }
  1107.  
  1108. void prev() override { _idx != 0 ? --_idx : _valid = false; }
  1109.  
  1110. private:
  1111. const BiDirectionalPlainListView* _owner;
  1112. size_t _idx;
  1113. bool _valid = true;
  1114. };
  1115.  
  1116. public:
  1117. BiDirectionalPlainListView(const T* data, size_t len)
  1118. : _data(data), _len(len) {}
  1119.  
  1120. Iterator<T> iterate() const override { return Iterator<T>(new Cursor(this)); }
  1121.  
  1122. BiDirectionalIterator<T> biterate() const override {
  1123. return BiDirectionalIterator<T>(new Cursor(this));
  1124. }
  1125.  
  1126. private:
  1127. friend class BiDirectionalCursor<T>;
  1128. const T* _data;
  1129. size_t _len;
  1130. };
  1131.  
  1132. /* Base class tpye for all Menu instances representing a
  1133. particular kind of menu that can be displayed and defines
  1134. a minimal required set of interface methods. All Menu interface
  1135. classes must derive from this base type so these base methods
  1136. may be called polymorphically by the MenuController
  1137.  
  1138. implementation. */
  1139.  
  1140. class MenuBase {
  1141. public:
  1142. virtual ~MenuBase() = default;
  1143.  
  1144. List<XString> text() { return text_(); }
  1145.  
  1146. MenuBase* invoke(Number param) { return invoke_(param); }
  1147.  
  1148. uint8_t internal_id() const { return internal_id_; }
  1149.  
  1150. uint8_t user_id() const { return user_id_; }
  1151.  
  1152. protected:
  1153. explicit MenuBase(uint8_t user_id) : user_id_(user_id),
  1154. internal_id_(id_count()++) {}
  1155.  
  1156. private:
  1157. uint8_t user_id_ = 0;
  1158. uint8_t internal_id_ = 0;
  1159.  
  1160. static uint8_t& id_count() {
  1161. static uint8_t id_count = 0;
  1162. return id_count;
  1163. }
  1164.  
  1165. virtual List<XString> text_() = 0;
  1166. virtual MenuBase* invoke_(Number) = 0;
  1167. };
  1168.  
  1169. /* Base interface class for a menu type, this can be further
  1170. inherited from to define necessary non-virtual method calls
  1171. for various types of menu items. */
  1172.  
  1173. template <typename MenuBase, template <typename> class MenuImpl>
  1174. class MenuInterface {
  1175. public:
  1176. List<XString> text() {
  1177. return static_cast<MenuImpl<MenuBase>*>(this)->text_();
  1178. }
  1179.  
  1180. MenuBase* invoke() {
  1181. return static_cast<MenuImpl<MenuBase>*>(this)->invoke_();
  1182. }
  1183. };
  1184.  
  1185. using Type = MenuBase**;
  1186.  
  1187. /* The state is used to provide storage for a single base-type
  1188. Menu pointer which will be assigned to a Leaf menu instance. */
  1189.  
  1190. struct State {
  1191. MenuBase* leaf_menu_ptr = nullptr;
  1192. };
  1193.  
  1194. struct Node {
  1195. State state;
  1196. bitrex__xod_menu_system__menu_base::Type output_OUT;
  1197.  
  1198. union {
  1199. struct {
  1200. bool isOutputDirty_OUT : 1;
  1201. bool isNodeDirty : 1;
  1202. };
  1203.  
  1204. DirtyFlags dirtyFlags;
  1205. };
  1206. };
  1207.  
  1208. struct output_OUT { };
  1209.  
  1210. template<typename PinT> struct ValueType { using T = void; };
  1211. template<> struct ValueType<output_OUT> { using T = bitrex__xod_menu_system__menu_base::Type; };
  1212.  
  1213. struct ContextObject {
  1214. Node* _node;
  1215.  
  1216. };
  1217.  
  1218. using Context = ContextObject*;
  1219.  
  1220. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  1221. static_assert(always_false<PinT>::value,
  1222. "Invalid pin descriptor. Expected one of:" \
  1223. "" \
  1224. " output_OUT");
  1225. }
  1226.  
  1227. template<> bitrex__xod_menu_system__menu_base::Type getValue<output_OUT>(Context ctx) {
  1228. return ctx->_node->output_OUT;
  1229. }
  1230.  
  1231. template<typename InputT> bool isInputDirty(Context ctx) {
  1232. static_assert(always_false<InputT>::value,
  1233. "Invalid input descriptor. Expected one of:" \
  1234. "");
  1235. return false;
  1236. }
  1237.  
  1238. template<typename OutputT> void emitValue(Context ctx, typename ValueType<OutputT>::T val) {
  1239. static_assert(always_false<OutputT>::value,
  1240. "Invalid output descriptor. Expected one of:" \
  1241. " output_OUT");
  1242. }
  1243.  
  1244. template<> void emitValue<output_OUT>(Context ctx, bitrex__xod_menu_system__menu_base::Type val) {
  1245. ctx->_node->output_OUT = val;
  1246. ctx->_node->isOutputDirty_OUT = true;
  1247. }
  1248.  
  1249. State* getState(Context ctx) {
  1250. return &ctx->_node->state;
  1251. }
  1252.  
  1253. /* An interface to a simp leaf-type menu, which cannot have further sub-menus
  1254. called from it, and generates a pulse output plus a paramter change output
  1255. when it's selected from the MenuController. Particular implementation
  1256. behavior is injected using the CRTP/static polymorphism to avoid runtime
  1257. overhead/program memory bloat. */
  1258.  
  1259. template <typename MenuBase, template <typename> class LeafMenuImpl>
  1260. class LeafMenuInterface : public MenuInterface<MenuBase, LeafMenuImpl> {
  1261. public:
  1262. void set_text(XString line1, XString line2) {
  1263. static_cast<LeafMenuImpl<MenuBase>*>(this)->set_text_(line1, line2);
  1264. }
  1265.  
  1266. bool update(Number* out) {
  1267. return static_cast<LeafMenuImpl<MenuBase>*>(this)->update_(out);
  1268. }
  1269. };
  1270.  
  1271. /* Simple leaf menu implementation example */
  1272.  
  1273. template <typename MenuBase>
  1274. class LeafMenuImpl final : public LeafMenuInterface<MenuBase, LeafMenuImpl>,
  1275. public MenuBase {
  1276. friend class MenuInterface<MenuBase, LeafMenuImpl>;
  1277. friend class LeafMenuInterface<MenuBase, LeafMenuImpl>;
  1278.  
  1279. public:
  1280. LeafMenuImpl() : MenuBase(0), menu_text_lines_view_(nullptr, 0) {}
  1281.  
  1282. LeafMenuImpl(XString line1, XString line2, uint8_t user_id)
  1283. : MenuBase(user_id),
  1284. lines_({line1, line2}),
  1285. menu_text_lines_view_(PlainListView<XString>(lines_, 2)) {}
  1286.  
  1287. protected:
  1288. List<XString> text_() override {
  1289. return List<XString>(&menu_text_lines_view_);
  1290. }
  1291.  
  1292. MenuBase* invoke_(Number param) override {
  1293. invoked_ = true;
  1294. param_ = param;
  1295. return nullptr;
  1296. }
  1297.  
  1298. void set_text_(XString line1, XString line2) {
  1299. lines_[0] = line1;
  1300. lines_[1] = line2;
  1301. menu_text_lines_view_ = PlainListView<XString>(lines_, 2);
  1302. }
  1303.  
  1304. bool update_(Number* out) {
  1305. if (invoked_) {
  1306. *out = param_;
  1307. invoked_ = false;
  1308. return true;
  1309. }
  1310. return false;
  1311. }
  1312.  
  1313. private:
  1314. XString lines_[2];
  1315. PlainListView<XString> menu_text_lines_view_;
  1316. bool invoked_ = false;
  1317. Number param_;
  1318. };
  1319.  
  1320. void evaluate(Context ctx) {
  1321. if (isSettingUp()) {
  1322. auto state = getState(ctx);
  1323. emitValue<output_OUT>(ctx, &state->leaf_menu_ptr);
  1324. }
  1325. }
  1326.  
  1327. } // namespace bitrex__xod_menu_system__menu_base
  1328.  
  1329. //-----------------------------------------------------------------------------
  1330. // bitrex/xod-menu-system/leaf-menu-item-impl implementation
  1331. //-----------------------------------------------------------------------------
  1332. namespace bitrex__xod_menu_system__leaf_menu_item_impl {
  1333.  
  1334. //#pragma XOD dirtiness disable
  1335.  
  1336. namespace menu_base = ____menu_base;
  1337. using menu_base_t = menu_base::MenuBase;
  1338.  
  1339. using Type = menu_base::BiDirectionalList<menu_base_t*>;
  1340.  
  1341. struct State {
  1342. menu_base::LeafMenuImpl<menu_base_t> leaf_menu;
  1343. menu_base::BiDirectionalPlainListView<menu_base_t*> leaf_menu_view =
  1344. menu_base::BiDirectionalPlainListView<menu_base_t*>(nullptr, 0);
  1345. };
  1346.  
  1347. struct Node {
  1348. State state;
  1349. TimeMs timeoutAt;
  1350. bitrex__xod_menu_system__leaf_menu_item_impl::Type output_OUT;
  1351. Number output_PARAM;
  1352. Logic output_INVOKED;
  1353.  
  1354. union {
  1355. struct {
  1356. bool isOutputDirty_OUT : 1;
  1357. bool isOutputDirty_PARAM : 1;
  1358. bool isOutputDirty_INVOKED : 1;
  1359. bool isNodeDirty : 1;
  1360. };
  1361.  
  1362. DirtyFlags dirtyFlags;
  1363. };
  1364. };
  1365.  
  1366. struct input_MENU_PTR { };
  1367. struct input_LINE1 { };
  1368. struct input_LINE2 { };
  1369. struct input_ID { };
  1370. struct output_OUT { };
  1371. struct output_PARAM { };
  1372. struct output_INVOKED { };
  1373.  
  1374. template<typename PinT> struct ValueType { using T = void; };
  1375. template<> struct ValueType<input_MENU_PTR> { using T = bitrex__xod_menu_system__menu_base::Type; };
  1376. template<> struct ValueType<input_LINE1> { using T = XString; };
  1377. template<> struct ValueType<input_LINE2> { using T = XString; };
  1378. template<> struct ValueType<input_ID> { using T = uint8_t; };
  1379. template<> struct ValueType<output_OUT> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  1380. template<> struct ValueType<output_PARAM> { using T = Number; };
  1381. template<> struct ValueType<output_INVOKED> { using T = Logic; };
  1382.  
  1383. struct ContextObject {
  1384. Node* _node;
  1385.  
  1386. bitrex__xod_menu_system__menu_base::Type _input_MENU_PTR;
  1387. XString _input_LINE1;
  1388. XString _input_LINE2;
  1389. uint8_t _input_ID;
  1390.  
  1391. };
  1392.  
  1393. using Context = ContextObject*;
  1394.  
  1395. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  1396. static_assert(always_false<PinT>::value,
  1397. "Invalid pin descriptor. Expected one of:" \
  1398. " input_MENU_PTR input_LINE1 input_LINE2 input_ID" \
  1399. " output_OUT output_PARAM output_INVOKED");
  1400. }
  1401.  
  1402. template<> bitrex__xod_menu_system__menu_base::Type getValue<input_MENU_PTR>(Context ctx) {
  1403. return ctx->_input_MENU_PTR;
  1404. }
  1405. template<> XString getValue<input_LINE1>(Context ctx) {
  1406. return ctx->_input_LINE1;
  1407. }
  1408. template<> XString getValue<input_LINE2>(Context ctx) {
  1409. return ctx->_input_LINE2;
  1410. }
  1411. template<> uint8_t getValue<input_ID>(Context ctx) {
  1412. return ctx->_input_ID;
  1413. }
  1414. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<output_OUT>(Context ctx) {
  1415. return ctx->_node->output_OUT;
  1416. }
  1417. template<> Number getValue<output_PARAM>(Context ctx) {
  1418. return ctx->_node->output_PARAM;
  1419. }
  1420. template<> Logic getValue<output_INVOKED>(Context ctx) {
  1421. return ctx->_node->output_INVOKED;
  1422. }
  1423.  
  1424. template<typename InputT> bool isInputDirty(Context ctx) {
  1425. static_assert(always_false<InputT>::value,
  1426. "Invalid input descriptor. Expected one of:" \
  1427. "");
  1428. return false;
  1429. }
  1430.  
  1431. template<typename OutputT> void emitValue(Context ctx, typename ValueType<OutputT>::T val) {
  1432. static_assert(always_false<OutputT>::value,
  1433. "Invalid output descriptor. Expected one of:" \
  1434. " output_OUT output_PARAM output_INVOKED");
  1435. }
  1436.  
  1437. template<> void emitValue<output_OUT>(Context ctx, bitrex__xod_menu_system__leaf_menu_item_impl::Type val) {
  1438. ctx->_node->output_OUT = val;
  1439. ctx->_node->isOutputDirty_OUT = true;
  1440. }
  1441. template<> void emitValue<output_PARAM>(Context ctx, Number val) {
  1442. ctx->_node->output_PARAM = val;
  1443. ctx->_node->isOutputDirty_PARAM = true;
  1444. }
  1445. template<> void emitValue<output_INVOKED>(Context ctx, Logic val) {
  1446. ctx->_node->output_INVOKED = val;
  1447. ctx->_node->isOutputDirty_INVOKED = true;
  1448. }
  1449.  
  1450. State* getState(Context ctx) {
  1451. return &ctx->_node->state;
  1452. }
  1453.  
  1454. void evaluate(Context ctx) {
  1455. auto state = getState(ctx);
  1456. auto line1 = getValue<input_LINE1>(ctx);
  1457. auto line2 = getValue<input_LINE2>(ctx);
  1458.  
  1459. if (isSettingUp())
  1460. {
  1461. using menu_base::BiDirectionalPlainListView;
  1462. using menu_base::BiDirectionalList;
  1463. using menu_base::LeafMenuImpl;
  1464.  
  1465. const auto user_id = getValue<input_ID>(ctx);
  1466. const auto menu_base_p2p = getValue<input_MENU_PTR>(ctx);
  1467. state->leaf_menu_view = menu_base::BiDirectionalPlainListView<menu_base_t*>(menu_base_p2p, 1);
  1468. state->leaf_menu = LeafMenuImpl<menu_base_t>(line1, line2, user_id);
  1469. *menu_base_p2p = &state->leaf_menu;
  1470. emitValue<output_OUT>(ctx, menu_base::BiDirectionalList<menu_base_t*>(&state->leaf_menu_view));
  1471. setTimeout(ctx, 10);
  1472. }
  1473.  
  1474. if (isTimedOut(ctx)) {
  1475. auto menu_base_ptr = *state->leaf_menu_view.iterate();
  1476. state->leaf_menu.set_text(line1, line2);
  1477. Number out;
  1478. auto invoked = state->leaf_menu.update(&out);
  1479. if (invoked) {
  1480. emitValue<output_INVOKED>(ctx, 1);
  1481. emitValue<output_PARAM>(ctx, out);
  1482. }
  1483. setTimeout(ctx, 10);
  1484. }
  1485. }
  1486.  
  1487. } // namespace bitrex__xod_menu_system__leaf_menu_item_impl
  1488.  
  1489. //-----------------------------------------------------------------------------
  1490. // bitrex/xod-menu-system/flash-string-1 implementation
  1491. //-----------------------------------------------------------------------------
  1492. namespace bitrex__xod_menu_system__flash_string_1 {
  1493.  
  1494. //#pragma XOD dirtiness disable
  1495.  
  1496. class FlashStringView : public ListView<char> {
  1497. public:
  1498. class Cursor : public detail::Cursor<char> {
  1499. public:
  1500. Cursor(const char PROGMEM* str) : _ptr(str) {}
  1501.  
  1502. bool isValid() const override {
  1503. return static_cast<bool>(static_cast<char>(pgm_read_byte(_ptr)));
  1504. }
  1505.  
  1506. bool value(char* out) const override {
  1507. *out = static_cast<char>(pgm_read_byte(_ptr));
  1508. return static_cast<bool>(*out);
  1509. }
  1510.  
  1511. void next() override { ++_ptr; }
  1512.  
  1513. private:
  1514. const char PROGMEM* _ptr;
  1515. };
  1516.  
  1517. public:
  1518. FlashStringView(const char PROGMEM* str = nullptr) : _str(str) {}
  1519. FlashStringView(const __FlashStringHelper* str)
  1520. : _str(reinterpret_cast<const char PROGMEM*>(str)) {}
  1521.  
  1522. FlashStringView& operator=(const FlashStringView& rhs) {
  1523. _str = rhs._str;
  1524. return *this;
  1525. }
  1526.  
  1527. virtual Iterator<char> iterate() const override {
  1528. return _str ? Iterator<char>(new Cursor(_str)) : Iterator<char>::nil();
  1529. }
  1530.  
  1531. private:
  1532. friend class Cursor;
  1533. const char PROGMEM* _str;
  1534. };
  1535.  
  1536. class XStringFlashString : public XString {
  1537. public:
  1538. XStringFlashString(const char PROGMEM* str) : XString(&_view), _view(str) {}
  1539.  
  1540. XStringFlashString(const __FlashStringHelper* str)
  1541. : XString(&_view), _view(str) {}
  1542.  
  1543. private:
  1544. FlashStringView _view;
  1545. };
  1546.  
  1547. struct State {
  1548. };
  1549.  
  1550. struct Node {
  1551. State state;
  1552. XString output_TXT;
  1553.  
  1554. union {
  1555. struct {
  1556. bool isOutputDirty_TXT : 1;
  1557. bool isNodeDirty : 1;
  1558. };
  1559.  
  1560. DirtyFlags dirtyFlags;
  1561. };
  1562. };
  1563.  
  1564. struct output_TXT { };
  1565.  
  1566. template<typename PinT> struct ValueType { using T = void; };
  1567. template<> struct ValueType<output_TXT> { using T = XString; };
  1568.  
  1569. struct ContextObject {
  1570. Node* _node;
  1571.  
  1572. };
  1573.  
  1574. using Context = ContextObject*;
  1575.  
  1576. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  1577. static_assert(always_false<PinT>::value,
  1578. "Invalid pin descriptor. Expected one of:" \
  1579. "" \
  1580. " output_TXT");
  1581. }
  1582.  
  1583. template<> XString getValue<output_TXT>(Context ctx) {
  1584. return ctx->_node->output_TXT;
  1585. }
  1586.  
  1587. template<typename InputT> bool isInputDirty(Context ctx) {
  1588. static_assert(always_false<InputT>::value,
  1589. "Invalid input descriptor. Expected one of:" \
  1590. "");
  1591. return false;
  1592. }
  1593.  
  1594. template<typename OutputT> void emitValue(Context ctx, typename ValueType<OutputT>::T val) {
  1595. static_assert(always_false<OutputT>::value,
  1596. "Invalid output descriptor. Expected one of:" \
  1597. " output_TXT");
  1598. }
  1599.  
  1600. template<> void emitValue<output_TXT>(Context ctx, XString val) {
  1601. ctx->_node->output_TXT = val;
  1602. ctx->_node->isOutputDirty_TXT = true;
  1603. }
  1604.  
  1605. State* getState(Context ctx) {
  1606. return &ctx->_node->state;
  1607. }
  1608.  
  1609. const char text[] PROGMEM = {"Make XOD Menus!"};
  1610. static XStringFlashString out_text = XStringFlashString(text);
  1611.  
  1612. void evaluate(Context ctx) {
  1613. if (isSettingUp()) {
  1614. emitValue<output_TXT>(ctx, out_text);
  1615. }
  1616. }
  1617.  
  1618. } // namespace bitrex__xod_menu_system__flash_string_1
  1619.  
  1620. //-----------------------------------------------------------------------------
  1621. // xod/core/continuously implementation
  1622. //-----------------------------------------------------------------------------
  1623. namespace xod__core__continuously {
  1624.  
  1625. struct State {
  1626. };
  1627.  
  1628. struct Node {
  1629. State state;
  1630. TimeMs timeoutAt;
  1631. Logic output_TICK;
  1632.  
  1633. union {
  1634. struct {
  1635. bool isOutputDirty_TICK : 1;
  1636. bool isNodeDirty : 1;
  1637. };
  1638.  
  1639. DirtyFlags dirtyFlags;
  1640. };
  1641. };
  1642.  
  1643. struct output_TICK { };
  1644.  
  1645. template<typename PinT> struct ValueType { using T = void; };
  1646. template<> struct ValueType<output_TICK> { using T = Logic; };
  1647.  
  1648. struct ContextObject {
  1649. Node* _node;
  1650.  
  1651. };
  1652.  
  1653. using Context = ContextObject*;
  1654.  
  1655. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  1656. static_assert(always_false<PinT>::value,
  1657. "Invalid pin descriptor. Expected one of:" \
  1658. "" \
  1659. " output_TICK");
  1660. }
  1661.  
  1662. template<> Logic getValue<output_TICK>(Context ctx) {
  1663. return ctx->_node->output_TICK;
  1664. }
  1665.  
  1666. template<typename InputT> bool isInputDirty(Context ctx) {
  1667. static_assert(always_false<InputT>::value,
  1668. "Invalid input descriptor. Expected one of:" \
  1669. "");
  1670. return false;
  1671. }
  1672.  
  1673. template<typename OutputT> void emitValue(Context ctx, typename ValueType<OutputT>::T val) {
  1674. static_assert(always_false<OutputT>::value,
  1675. "Invalid output descriptor. Expected one of:" \
  1676. " output_TICK");
  1677. }
  1678.  
  1679. template<> void emitValue<output_TICK>(Context ctx, Logic val) {
  1680. ctx->_node->output_TICK = val;
  1681. ctx->_node->isOutputDirty_TICK = true;
  1682. }
  1683.  
  1684. State* getState(Context ctx) {
  1685. return &ctx->_node->state;
  1686. }
  1687.  
  1688. void evaluate(Context ctx) {
  1689. emitValue<output_TICK>(ctx, 1);
  1690. setTimeout(ctx, 0);
  1691. }
  1692.  
  1693. } // namespace xod__core__continuously
  1694.  
  1695. //-----------------------------------------------------------------------------
  1696. // xod/gpio/analog-read implementation
  1697. //-----------------------------------------------------------------------------
  1698. namespace xod__gpio__analog_read {
  1699.  
  1700. struct State {
  1701. };
  1702.  
  1703. struct Node {
  1704. State state;
  1705. Number output_VAL;
  1706. Logic output_DONE;
  1707. Logic output_ERR;
  1708.  
  1709. union {
  1710. struct {
  1711. bool isOutputDirty_VAL : 1;
  1712. bool isOutputDirty_DONE : 1;
  1713. bool isOutputDirty_ERR : 1;
  1714. bool isNodeDirty : 1;
  1715. };
  1716.  
  1717. DirtyFlags dirtyFlags;
  1718. };
  1719. };
  1720.  
  1721. struct input_PORT { };
  1722. struct input_UPD { };
  1723. struct output_VAL { };
  1724. struct output_DONE { };
  1725. struct output_ERR { };
  1726.  
  1727. template<typename PinT> struct ValueType { using T = void; };
  1728. template<> struct ValueType<input_PORT> { using T = uint8_t; };
  1729. template<> struct ValueType<input_UPD> { using T = Logic; };
  1730. template<> struct ValueType<output_VAL> { using T = Number; };
  1731. template<> struct ValueType<output_DONE> { using T = Logic; };
  1732. template<> struct ValueType<output_ERR> { using T = Logic; };
  1733.  
  1734. struct ContextObject {
  1735. Node* _node;
  1736.  
  1737. uint8_t _input_PORT;
  1738. Logic _input_UPD;
  1739.  
  1740. bool _isInputDirty_UPD;
  1741. };
  1742.  
  1743. using Context = ContextObject*;
  1744.  
  1745. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  1746. static_assert(always_false<PinT>::value,
  1747. "Invalid pin descriptor. Expected one of:" \
  1748. " input_PORT input_UPD" \
  1749. " output_VAL output_DONE output_ERR");
  1750. }
  1751.  
  1752. template<> uint8_t getValue<input_PORT>(Context ctx) {
  1753. return ctx->_input_PORT;
  1754. }
  1755. template<> Logic getValue<input_UPD>(Context ctx) {
  1756. return ctx->_input_UPD;
  1757. }
  1758. template<> Number getValue<output_VAL>(Context ctx) {
  1759. return ctx->_node->output_VAL;
  1760. }
  1761. template<> Logic getValue<output_DONE>(Context ctx) {
  1762. return ctx->_node->output_DONE;
  1763. }
  1764. template<> Logic getValue<output_ERR>(Context ctx) {
  1765. return ctx->_node->output_ERR;
  1766. }
  1767.  
  1768. template<typename InputT> bool isInputDirty(Context ctx) {
  1769. static_assert(always_false<InputT>::value,
  1770. "Invalid input descriptor. Expected one of:" \
  1771. " input_UPD");
  1772. return false;
  1773. }
  1774.  
  1775. template<> bool isInputDirty<input_UPD>(Context ctx) {
  1776. return ctx->_isInputDirty_UPD;
  1777. }
  1778.  
  1779. template<typename OutputT> void emitValue(Context ctx, typename ValueType<OutputT>::T val) {
  1780. static_assert(always_false<OutputT>::value,
  1781. "Invalid output descriptor. Expected one of:" \
  1782. " output_VAL output_DONE output_ERR");
  1783. }
  1784.  
  1785. template<> void emitValue<output_VAL>(Context ctx, Number val) {
  1786. ctx->_node->output_VAL = val;
  1787. ctx->_node->isOutputDirty_VAL = true;
  1788. }
  1789. template<> void emitValue<output_DONE>(Context ctx, Logic val) {
  1790. ctx->_node->output_DONE = val;
  1791. ctx->_node->isOutputDirty_DONE = true;
  1792. }
  1793. template<> void emitValue<output_ERR>(Context ctx, Logic val) {
  1794. ctx->_node->output_ERR = val;
  1795. ctx->_node->isOutputDirty_ERR = true;
  1796. }
  1797.  
  1798. State* getState(Context ctx) {
  1799. return &ctx->_node->state;
  1800. }
  1801.  
  1802. void evaluate(Context ctx) {
  1803. if (!isInputDirty<input_UPD>(ctx))
  1804. return;
  1805.  
  1806. const uint8_t port = getValue<input_PORT>(ctx);
  1807.  
  1808. if (!isValidAnalogPort(port)) {
  1809. emitValue<output_ERR>(ctx, 1);
  1810. return;
  1811. }
  1812.  
  1813. ::pinMode(port, INPUT);
  1814. emitValue<output_VAL>(ctx, ::analogRead(port) / 1023.);
  1815. emitValue<output_DONE>(ctx, 1);
  1816. }
  1817.  
  1818. } // namespace xod__gpio__analog_read
  1819.  
  1820. //-----------------------------------------------------------------------------
  1821. // bitrex/xod-menu-system/text-lcd-16x2-keypad-impl implementation
  1822. //-----------------------------------------------------------------------------
  1823. namespace bitrex__xod_menu_system__text_lcd_16x2_keypad_impl {
  1824.  
  1825. struct State {
  1826. const size_t num_keys = 5;
  1827. const float adc_key_val[5] = {0.05f, 0.15f, 0.35f, 0.55f, 0.75f};
  1828. };
  1829.  
  1830. struct Node {
  1831. State state;
  1832. Logic output_RIGHT;
  1833. Logic output_LEFT;
  1834. Logic output_UP;
  1835. Logic output_DOWN;
  1836. Logic output_SELECT;
  1837.  
  1838. union {
  1839. struct {
  1840. bool isOutputDirty_RIGHT : 1;
  1841. bool isOutputDirty_LEFT : 1;
  1842. bool isOutputDirty_UP : 1;
  1843. bool isOutputDirty_DOWN : 1;
  1844. bool isOutputDirty_SELECT : 1;
  1845. bool isNodeDirty : 1;
  1846. };
  1847.  
  1848. DirtyFlags dirtyFlags;
  1849. };
  1850. };
  1851.  
  1852. struct input_ADC_IN { };
  1853. struct output_RIGHT { };
  1854. struct output_LEFT { };
  1855. struct output_UP { };
  1856. struct output_DOWN { };
  1857. struct output_SELECT { };
  1858.  
  1859. template<typename PinT> struct ValueType { using T = void; };
  1860. template<> struct ValueType<input_ADC_IN> { using T = Number; };
  1861. template<> struct ValueType<output_RIGHT> { using T = Logic; };
  1862. template<> struct ValueType<output_LEFT> { using T = Logic; };
  1863. template<> struct ValueType<output_UP> { using T = Logic; };
  1864. template<> struct ValueType<output_DOWN> { using T = Logic; };
  1865. template<> struct ValueType<output_SELECT> { using T = Logic; };
  1866.  
  1867. struct ContextObject {
  1868. Node* _node;
  1869.  
  1870. Number _input_ADC_IN;
  1871.  
  1872. };
  1873.  
  1874. using Context = ContextObject*;
  1875.  
  1876. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  1877. static_assert(always_false<PinT>::value,
  1878. "Invalid pin descriptor. Expected one of:" \
  1879. " input_ADC_IN" \
  1880. " output_RIGHT output_LEFT output_UP output_DOWN output_SELECT");
  1881. }
  1882.  
  1883. template<> Number getValue<input_ADC_IN>(Context ctx) {
  1884. return ctx->_input_ADC_IN;
  1885. }
  1886. template<> Logic getValue<output_RIGHT>(Context ctx) {
  1887. return ctx->_node->output_RIGHT;
  1888. }
  1889. template<> Logic getValue<output_LEFT>(Context ctx) {
  1890. return ctx->_node->output_LEFT;
  1891. }
  1892. template<> Logic getValue<output_UP>(Context ctx) {
  1893. return ctx->_node->output_UP;
  1894. }
  1895. template<> Logic getValue<output_DOWN>(Context ctx) {
  1896. return ctx->_node->output_DOWN;
  1897. }
  1898. template<> Logic getValue<output_SELECT>(Context ctx) {
  1899. return ctx->_node->output_SELECT;
  1900. }
  1901.  
  1902. template<typename InputT> bool isInputDirty(Context ctx) {
  1903. static_assert(always_false<InputT>::value,
  1904. "Invalid input descriptor. Expected one of:" \
  1905. "");
  1906. return false;
  1907. }
  1908.  
  1909. template<typename OutputT> void emitValue(Context ctx, typename ValueType<OutputT>::T val) {
  1910. static_assert(always_false<OutputT>::value,
  1911. "Invalid output descriptor. Expected one of:" \
  1912. " output_RIGHT output_LEFT output_UP output_DOWN output_SELECT");
  1913. }
  1914.  
  1915. template<> void emitValue<output_RIGHT>(Context ctx, Logic val) {
  1916. ctx->_node->output_RIGHT = val;
  1917. ctx->_node->isOutputDirty_RIGHT = true;
  1918. }
  1919. template<> void emitValue<output_LEFT>(Context ctx, Logic val) {
  1920. ctx->_node->output_LEFT = val;
  1921. ctx->_node->isOutputDirty_LEFT = true;
  1922. }
  1923. template<> void emitValue<output_UP>(Context ctx, Logic val) {
  1924. ctx->_node->output_UP = val;
  1925. ctx->_node->isOutputDirty_UP = true;
  1926. }
  1927. template<> void emitValue<output_DOWN>(Context ctx, Logic val) {
  1928. ctx->_node->output_DOWN = val;
  1929. ctx->_node->isOutputDirty_DOWN = true;
  1930. }
  1931. template<> void emitValue<output_SELECT>(Context ctx, Logic val) {
  1932. ctx->_node->output_SELECT = val;
  1933. ctx->_node->isOutputDirty_SELECT = true;
  1934. }
  1935.  
  1936. State* getState(Context ctx) {
  1937. return &ctx->_node->state;
  1938. }
  1939.  
  1940. void evaluate(Context ctx) {
  1941. auto state = getState(ctx);
  1942. auto input = getValue<input_ADC_IN>(ctx);
  1943. if (input > 0.9) {
  1944. emitValue<output_RIGHT>(ctx, false);
  1945. emitValue<output_UP>(ctx, false);
  1946. emitValue<output_DOWN>(ctx, false);
  1947. emitValue<output_LEFT>(ctx, false);
  1948. emitValue<output_SELECT>(ctx, false);
  1949. return;
  1950. }
  1951.  
  1952. int i = 0;
  1953. for (; i < state->num_keys; ++i) {
  1954. if (input < state->adc_key_val[i]) {
  1955. break;
  1956. }
  1957. }
  1958.  
  1959. if (i >= state->num_keys) {
  1960. i = -1;
  1961. }
  1962.  
  1963. switch (i) {
  1964. case 0:
  1965. emitValue<output_RIGHT>(ctx, true);
  1966. break;
  1967. case 1:
  1968. emitValue<output_UP>(ctx, true);
  1969. break;
  1970. case 2:
  1971. emitValue<output_DOWN>(ctx, true);
  1972. break;
  1973. case 3:
  1974. emitValue<output_LEFT>(ctx, true);
  1975. break;
  1976. case 4:
  1977. emitValue<output_SELECT>(ctx, true);
  1978. break;
  1979. default:
  1980. break;
  1981. }
  1982. }
  1983.  
  1984. } // namespace bitrex__xod_menu_system__text_lcd_16x2_keypad_impl
  1985.  
  1986. //-----------------------------------------------------------------------------
  1987. // bitrex/xod-menu-system/concat-menu implementation
  1988. //-----------------------------------------------------------------------------
  1989. namespace bitrex__xod_menu_system__concat_menu {
  1990.  
  1991. //#pragma XOD dirtiness disable
  1992.  
  1993. namespace menu_base = ____menu_base;
  1994. using menu_base_t = menu_base::MenuBase;
  1995.  
  1996. /* A derived type of BiDirectionalListView, used to concatenate two
  1997. bi-directional lists and iterate forward and backwards over both
  1998. as a single unit. This can also be instantiated recursively. See
  1999. e.g. the XOD standard library class "ConcatListView"*/
  2000.  
  2001. template <typename T>
  2002. class BiDirectionalConcatListView : public menu_base::BiDirectionalListView<T> {
  2003. public:
  2004. class Cursor : public menu_base::BiDirectionalCursor<T> {
  2005. public:
  2006. Cursor(const BiDirectionalConcatListView<T>* owner)
  2007. : _left(std::move(owner->_left.biterate())),
  2008. _right(std::move(owner->_right.biterate())),
  2009. _owner(owner) {}
  2010.  
  2011. bool isValid() const override { return _left && _right; }
  2012.  
  2013. bool value(T* out) const override {
  2014. return _cursor < _owner->_length_left ? _left.value(out) : _right.value(out);
  2015. }
  2016.  
  2017. void next() override {
  2018. const auto total = _owner->_length_left + _owner->_length_right;
  2019. if (_cursor < _owner->_length_left - 1) {
  2020. ++_left;
  2021. } else if (_cursor >= _owner->_length_left - 1 && _cursor < total) {
  2022. if (_cursor != _owner->_length_left - 1) {
  2023. ++_right;
  2024. }
  2025. }
  2026. ++_cursor;
  2027. }
  2028.  
  2029. void prev() override {
  2030. const auto total = _owner->_length_left + _owner->_length_right;
  2031. if (_cursor > _owner->_length_left - 1 && _cursor != total - _owner->_length_right) {
  2032. --_right;
  2033. } else if (_cursor <= _owner->_length_left - 1) {
  2034. --_left;
  2035. }
  2036. if (_cursor) {
  2037. --_cursor;
  2038. }
  2039. }
  2040.  
  2041. private:
  2042. menu_base::BiDirectionalIterator<T> _left;
  2043. menu_base::BiDirectionalIterator<T> _right;
  2044. const BiDirectionalConcatListView<T>* _owner;
  2045. size_t _cursor = 0;
  2046. };
  2047.  
  2048. public:
  2049. BiDirectionalConcatListView() = default;
  2050.  
  2051. BiDirectionalConcatListView(menu_base::BiDirectionalList<T> left,
  2052. menu_base::BiDirectionalList<T> right)
  2053. : _left(left), _right(right), _length_left(length(left)), _length_right(length(right)) {}
  2054.  
  2055. BiDirectionalConcatListView& operator=(
  2056. const BiDirectionalConcatListView& rhs) {
  2057. _left = rhs._left;
  2058. _right = rhs._right;
  2059. _length_left = rhs._length_left;
  2060. _length_right = rhs._length_right;
  2061. return *this;
  2062. }
  2063.  
  2064. Iterator<T> iterate() const override {
  2065. return Iterator<T>(new Cursor(this));
  2066. }
  2067.  
  2068. menu_base::BiDirectionalIterator<T> biterate() const override {
  2069. return menu_base::BiDirectionalIterator<T>(new Cursor(this));
  2070. }
  2071.  
  2072. private:
  2073. friend class Cursor;
  2074. menu_base::BiDirectionalList<T> _left;
  2075. menu_base::BiDirectionalList<T> _right;
  2076. size_t _length_left;
  2077. size_t _length_right;
  2078. };
  2079.  
  2080. /* The state for this node contains a BiDirectionalConcatListView
  2081. of over the two BiDirectionalLists of menu_base_t-type pointers
  2082. it accepts as inputs. This node is employed variadically so there
  2083. will be an additional BiDirectionalConcatListView-containing state
  2084. genearted for each additional input created beyond the first two. */
  2085.  
  2086. struct State {
  2087. BiDirectionalConcatListView<menu_base_t*> menu_ptr_list_view;
  2088. };
  2089.  
  2090. struct Node {
  2091. State state;
  2092. bitrex__xod_menu_system__leaf_menu_item_impl::Type output_OUT;
  2093.  
  2094. union {
  2095. struct {
  2096. bool isOutputDirty_OUT : 1;
  2097. bool isNodeDirty : 1;
  2098. };
  2099.  
  2100. DirtyFlags dirtyFlags;
  2101. };
  2102. };
  2103.  
  2104. struct input_IN1 { };
  2105. struct input_IN2 { };
  2106. struct output_OUT { };
  2107.  
  2108. template<typename PinT> struct ValueType { using T = void; };
  2109. template<> struct ValueType<input_IN1> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  2110. template<> struct ValueType<input_IN2> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  2111. template<> struct ValueType<output_OUT> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  2112.  
  2113. struct ContextObject {
  2114. Node* _node;
  2115.  
  2116. bitrex__xod_menu_system__leaf_menu_item_impl::Type _input_IN1;
  2117. bitrex__xod_menu_system__leaf_menu_item_impl::Type _input_IN2;
  2118.  
  2119. };
  2120.  
  2121. using Context = ContextObject*;
  2122.  
  2123. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  2124. static_assert(always_false<PinT>::value,
  2125. "Invalid pin descriptor. Expected one of:" \
  2126. " input_IN1 input_IN2" \
  2127. " output_OUT");
  2128. }
  2129.  
  2130. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<input_IN1>(Context ctx) {
  2131. return ctx->_input_IN1;
  2132. }
  2133. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<input_IN2>(Context ctx) {
  2134. return ctx->_input_IN2;
  2135. }
  2136. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<output_OUT>(Context ctx) {
  2137. return ctx->_node->output_OUT;
  2138. }
  2139.  
  2140. template<typename InputT> bool isInputDirty(Context ctx) {
  2141. static_assert(always_false<InputT>::value,
  2142. "Invalid input descriptor. Expected one of:" \
  2143. "");
  2144. return false;
  2145. }
  2146.  
  2147. template<typename OutputT> void emitValue(Context ctx, typename ValueType<OutputT>::T val) {
  2148. static_assert(always_false<OutputT>::value,
  2149. "Invalid output descriptor. Expected one of:" \
  2150. " output_OUT");
  2151. }
  2152.  
  2153. template<> void emitValue<output_OUT>(Context ctx, bitrex__xod_menu_system__leaf_menu_item_impl::Type val) {
  2154. ctx->_node->output_OUT = val;
  2155. ctx->_node->isOutputDirty_OUT = true;
  2156. }
  2157.  
  2158. State* getState(Context ctx) {
  2159. return &ctx->_node->state;
  2160. }
  2161.  
  2162. void evaluate(Context ctx) {
  2163. if(isSettingUp()) {
  2164. using menu_base::BiDirectionalList;
  2165. auto state = getState(ctx);
  2166. const auto in1 = getValue<input_IN1>(ctx);
  2167. const auto in2 = getValue<input_IN2>(ctx);
  2168. //create a new concat-view join the incoming lists once on startup,
  2169. //the outputs remain static after that
  2170. state->menu_ptr_list_view = BiDirectionalConcatListView<menu_base_t*>(in1, in2);
  2171. //output is a list that can be further concatenated
  2172. emitValue<output_OUT>(ctx, BiDirectionalList<menu_base_t*>(&state->menu_ptr_list_view));
  2173. }
  2174. }
  2175.  
  2176. } // namespace bitrex__xod_menu_system__concat_menu
  2177.  
  2178. //-----------------------------------------------------------------------------
  2179. // xod/core/debounce(boolean) implementation
  2180. //-----------------------------------------------------------------------------
  2181. namespace xod__core__debounce__boolean {
  2182.  
  2183. struct State {
  2184. bool state = false;
  2185. };
  2186.  
  2187. struct Node {
  2188. State state;
  2189. TimeMs timeoutAt;
  2190. Logic output_OUT;
  2191.  
  2192. union {
  2193. struct {
  2194. bool isOutputDirty_OUT : 1;
  2195. bool isNodeDirty : 1;
  2196. };
  2197.  
  2198. DirtyFlags dirtyFlags;
  2199. };
  2200. };
  2201.  
  2202. struct input_ST { };
  2203. struct input_Ts { };
  2204. struct output_OUT { };
  2205.  
  2206. template<typename PinT> struct ValueType { using T = void; };
  2207. template<> struct ValueType<input_ST> { using T = Logic; };
  2208. template<> struct ValueType<input_Ts> { using T = Number; };
  2209. template<> struct ValueType<output_OUT> { using T = Logic; };
  2210.  
  2211. struct ContextObject {
  2212. Node* _node;
  2213.  
  2214. Logic _input_ST;
  2215. Number _input_Ts;
  2216.  
  2217. };
  2218.  
  2219. using Context = ContextObject*;
  2220.  
  2221. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  2222. static_assert(always_false<PinT>::value,
  2223. "Invalid pin descriptor. Expected one of:" \
  2224. " input_ST input_Ts" \
  2225. " output_OUT");
  2226. }
  2227.  
  2228. template<> Logic getValue<input_ST>(Context ctx) {
  2229. return ctx->_input_ST;
  2230. }
  2231. template<> Number getValue<input_Ts>(Context ctx) {
  2232. return ctx->_input_Ts;
  2233. }
  2234. template<> Logic getValue<output_OUT>(Context ctx) {
  2235. return ctx->_node->output_OUT;
  2236. }
  2237.  
  2238. template<typename InputT> bool isInputDirty(Context ctx) {
  2239. static_assert(always_false<InputT>::value,
  2240. "Invalid input descriptor. Expected one of:" \
  2241. "");
  2242. return false;
  2243. }
  2244.  
  2245. template<typename OutputT> void emitValue(Context ctx, typename ValueType<OutputT>::T val) {
  2246. static_assert(always_false<OutputT>::value,
  2247. "Invalid output descriptor. Expected one of:" \
  2248. " output_OUT");
  2249. }
  2250.  
  2251. template<> void emitValue<output_OUT>(Context ctx, Logic val) {
  2252. ctx->_node->output_OUT = val;
  2253. ctx->_node->isOutputDirty_OUT = true;
  2254. }
  2255.  
  2256. State* getState(Context ctx) {
  2257. return &ctx->_node->state;
  2258. }
  2259.  
  2260. void evaluate(Context ctx) {
  2261. State* state = getState(ctx);
  2262. bool x = getValue<input_ST>(ctx);
  2263.  
  2264. if (x != state->state) {
  2265. state->state = x;
  2266. TimeMs dt = getValue<input_Ts>(ctx) * 1000;
  2267. setTimeout(ctx, dt);
  2268. }
  2269.  
  2270. if (isTimedOut(ctx)) {
  2271. emitValue<output_OUT>(ctx, x);
  2272. }
  2273. }
  2274.  
  2275. } // namespace xod__core__debounce__boolean
  2276.  
  2277. //-----------------------------------------------------------------------------
  2278. // bitrex/xod-menu-system/branch-menu-item implementation
  2279. //-----------------------------------------------------------------------------
  2280. namespace bitrex__xod_menu_system__branch_menu_item {
  2281.  
  2282. //#pragma XOD dirtiness disable
  2283.  
  2284. /* include the base class type of a Menu item */
  2285.  
  2286. namespace menu_base = ____menu_base;
  2287. using menu_base_t = menu_base::MenuBase;
  2288.  
  2289. /* A wrapper for a raw BiDirectionalList that allows a Branch-type
  2290. menu to retain/manage location state when the user is paging thru its
  2291. sub-menus */
  2292.  
  2293. template <typename MenuBase>
  2294. class SubMenuIterator {
  2295. public:
  2296. SubMenuIterator() = default;
  2297.  
  2298. explicit SubMenuIterator(menu_base::BiDirectionalList<MenuBase*> sub_menus) :
  2299. sub_menu_ptr_list_(sub_menus), length_(xod::length(sub_menus)) {}
  2300.  
  2301. menu_base::BiDirectionalList<MenuBase*> menu_ptr_list() const {
  2302. return sub_menu_ptr_list_;
  2303. }
  2304.  
  2305. SubMenuIterator<MenuBase>& operator++() {
  2306. if (cursor_ < length_ - 1) ++cursor_;
  2307. return *this;
  2308. }
  2309.  
  2310. SubMenuIterator<MenuBase>& operator--() {
  2311. if (cursor_ > 0) --cursor_;
  2312. return *this;
  2313. }
  2314.  
  2315. MenuBase* current_menu_ptr() {
  2316. auto it = sub_menu_ptr_list_.iterate();
  2317. for (uint8_t i = 0; i < cursor_; ++i) { ++it; }
  2318. return *it;
  2319. }
  2320.  
  2321. void reset() {
  2322. cursor_ = 0;
  2323. }
  2324.  
  2325. private:
  2326. menu_base::BiDirectionalList<MenuBase*> sub_menu_ptr_list_;
  2327. uint8_t length_ = 0;
  2328. uint8_t cursor_ = 0;
  2329. };
  2330.  
  2331. /* An interface class for a Branch-type menu page which inherits the default
  2332. MenuInterface methods plus additional Branch-type specific methods to allow
  2333.  
  2334. navigation thru its sub-menus. */
  2335.  
  2336. template <typename MenuBase, template <typename> class BranchMenuImpl>
  2337. class BranchMenuInterface : public menu_base::MenuInterface<MenuBase, BranchMenuImpl> {
  2338. public:
  2339. MenuBase* sub_menu_ptr() {
  2340. return static_cast<BranchMenuImpl<MenuBase>*>(this)->sub_menu_ptr_();
  2341. }
  2342.  
  2343. MenuBase* next() {
  2344. return static_cast<BranchMenuImpl<MenuBase>*>(this)->next_();
  2345. }
  2346.  
  2347. MenuBase* prev() {
  2348. return static_cast<BranchMenuImpl<MenuBase>*>(this)->prev_();
  2349. }
  2350.  
  2351. BranchMenuImpl<MenuBase>* parent() {
  2352. return static_cast<BranchMenuImpl<MenuBase>*>(this)->parent_();
  2353. }
  2354.  
  2355. void set_parent(BranchMenuImpl<MenuBase>* parent) {
  2356. static_cast<BranchMenuImpl<MenuBase>*>(this)->set_parent_(parent);
  2357. }
  2358. };
  2359.  
  2360. /* an implementation of a Branch-type menu page satisfying the requirements
  2361. from the above interface. */
  2362.  
  2363. template <typename MenuBase>
  2364. class BranchMenuImpl final
  2365. : public BranchMenuInterface<MenuBase, BranchMenuImpl>,
  2366. public MenuBase {
  2367. friend class menu_base::MenuInterface<MenuBase, BranchMenuImpl>;
  2368. friend class BranchMenuInterface<MenuBase, BranchMenuImpl>;
  2369.  
  2370. public:
  2371. constexpr BranchMenuImpl()
  2372. : MenuBase(0),
  2373. menu_text_lines_view_(PlainListView<XString>(nullptr, 0)) {}
  2374.  
  2375. BranchMenuImpl(menu_base::BiDirectionalList<MenuBase*> sub_menu_ptr_list,
  2376. XString menu_text_1, XString menu_text_2, Number user_id)
  2377. : MenuBase(user_id),
  2378. menu_text_({menu_text_1, menu_text_2}),
  2379. menu_text_lines_view_(PlainListView<XString>(menu_text_, 2)),
  2380. sub_menu_it_(SubMenuIterator<MenuBase>(sub_menu_ptr_list))
  2381. {}
  2382.  
  2383. protected:
  2384. List<XString> text_() override {
  2385. menu_text_lines_view_ = PlainListView<XString>(menu_text_, 2);
  2386. return List<XString>(&menu_text_lines_view_);
  2387. }
  2388.  
  2389. MenuBase* invoke_(Number /* param */) override {
  2390. sub_menu_it_.reset();
  2391. return this;
  2392. }
  2393.  
  2394. MenuBase* sub_menu_ptr_() {
  2395. return sub_menu_it_.current_menu_ptr();
  2396. }
  2397.  
  2398. MenuBase* next_() {
  2399. ++sub_menu_it_;
  2400. return sub_menu_it_.current_menu_ptr();
  2401. }
  2402.  
  2403. MenuBase* prev_() {
  2404. --sub_menu_it_;
  2405. return sub_menu_it_.current_menu_ptr();
  2406. }
  2407.  
  2408. BranchMenuImpl<MenuBase>* parent_() const {
  2409. return parent_ptr_;
  2410. }
  2411.  
  2412. void set_parent_(BranchMenuImpl<MenuBase>* parent) {
  2413. parent_ptr_ = parent;
  2414. }
  2415.  
  2416. private:
  2417. XString menu_text_[2];
  2418. PlainListView<XString> menu_text_lines_view_;
  2419. SubMenuIterator<MenuBase> sub_menu_it_;
  2420. BranchMenuImpl<MenuBase>* parent_ptr_ = nullptr;
  2421. };
  2422.  
  2423. /* The state for this node contains an instance of a Branch-type menu class
  2424. plus a ListView, so that the node can output a List-type wrapper holding its
  2425. pointer, so that its pointer can be appended into further lists of Menu-type
  2426. pointers to allow automatic construction of a tree-like data structure. */
  2427.  
  2428. struct State {
  2429. BranchMenuImpl<menu_base_t> branch_menu;
  2430. menu_base_t* branch_menu_ptr;
  2431. menu_base::BiDirectionalPlainListView<menu_base_t*> branch_menu_ptr_view =
  2432. menu_base::BiDirectionalPlainListView<menu_base_t*>(&branch_menu_ptr, 1);
  2433. };
  2434.  
  2435. struct Node {
  2436. State state;
  2437. bitrex__xod_menu_system__leaf_menu_item_impl::Type output_OUT;
  2438.  
  2439. union {
  2440. struct {
  2441. bool isOutputDirty_OUT : 1;
  2442. bool isNodeDirty : 1;
  2443. };
  2444.  
  2445. DirtyFlags dirtyFlags;
  2446. };
  2447. };
  2448.  
  2449. struct input_IN { };
  2450. struct input_LINE1 { };
  2451. struct input_LINE2 { };
  2452. struct input_ID { };
  2453. struct output_OUT { };
  2454.  
  2455. template<typename PinT> struct ValueType { using T = void; };
  2456. template<> struct ValueType<input_IN> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  2457. template<> struct ValueType<input_LINE1> { using T = XString; };
  2458. template<> struct ValueType<input_LINE2> { using T = XString; };
  2459. template<> struct ValueType<input_ID> { using T = uint8_t; };
  2460. template<> struct ValueType<output_OUT> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  2461.  
  2462. struct ContextObject {
  2463. Node* _node;
  2464.  
  2465. bitrex__xod_menu_system__leaf_menu_item_impl::Type _input_IN;
  2466. XString _input_LINE1;
  2467. XString _input_LINE2;
  2468. uint8_t _input_ID;
  2469.  
  2470. };
  2471.  
  2472. using Context = ContextObject*;
  2473.  
  2474. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  2475. static_assert(always_false<PinT>::value,
  2476. "Invalid pin descriptor. Expected one of:" \
  2477. " input_IN input_LINE1 input_LINE2 input_ID" \
  2478. " output_OUT");
  2479. }
  2480.  
  2481. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<input_IN>(Context ctx) {
  2482. return ctx->_input_IN;
  2483. }
  2484. template<> XString getValue<input_LINE1>(Context ctx) {
  2485. return ctx->_input_LINE1;
  2486. }
  2487. template<> XString getValue<input_LINE2>(Context ctx) {
  2488. return ctx->_input_LINE2;
  2489. }
  2490. template<> uint8_t getValue<input_ID>(Context ctx) {
  2491. return ctx->_input_ID;
  2492. }
  2493. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<output_OUT>(Context ctx) {
  2494. return ctx->_node->output_OUT;
  2495. }
  2496.  
  2497. template<typename InputT> bool isInputDirty(Context ctx) {
  2498. static_assert(always_false<InputT>::value,
  2499. "Invalid input descriptor. Expected one of:" \
  2500. "");
  2501. return false;
  2502. }
  2503.  
  2504. template<typename OutputT> void emitValue(Context ctx, typename ValueType<OutputT>::T val) {
  2505. static_assert(always_false<OutputT>::value,
  2506. "Invalid output descriptor. Expected one of:" \
  2507. " output_OUT");
  2508. }
  2509.  
  2510. template<> void emitValue<output_OUT>(Context ctx, bitrex__xod_menu_system__leaf_menu_item_impl::Type val) {
  2511. ctx->_node->output_OUT = val;
  2512. ctx->_node->isOutputDirty_OUT = true;
  2513. }
  2514.  
  2515. State* getState(Context ctx) {
  2516. return &ctx->_node->state;
  2517. }
  2518.  
  2519. void evaluate(Context ctx) {
  2520. if (isSettingUp()) {
  2521. using menu_base::BiDirectionalList;
  2522. auto state = getState(ctx);
  2523. auto in = getValue<input_IN>(ctx);
  2524. auto text1 = getValue<input_LINE1>(ctx);
  2525. auto text2 = getValue<input_LINE2>(ctx);
  2526. auto id = getValue<input_ID>(ctx);
  2527. state->branch_menu = BranchMenuImpl<menu_base_t>(in, text1, text2, id);
  2528. state->branch_menu_ptr = &state->branch_menu;
  2529. emitValue<output_OUT>(ctx, menu_base::BiDirectionalList<menu_base_t*>(&state->branch_menu_ptr_view));
  2530. }
  2531. }
  2532.  
  2533. } // namespace bitrex__xod_menu_system__branch_menu_item
  2534.  
  2535. //-----------------------------------------------------------------------------
  2536. // xod/core/pulse-on-true implementation
  2537. //-----------------------------------------------------------------------------
  2538. namespace xod__core__pulse_on_true {
  2539.  
  2540. struct State {
  2541. bool state = false;
  2542. };
  2543.  
  2544. struct Node {
  2545. State state;
  2546. Logic output_OUT;
  2547.  
  2548. union {
  2549. struct {
  2550. bool isOutputDirty_OUT : 1;
  2551. bool isNodeDirty : 1;
  2552. };
  2553.  
  2554. DirtyFlags dirtyFlags;
  2555. };
  2556. };
  2557.  
  2558. struct input_IN { };
  2559. struct output_OUT { };
  2560.  
  2561. template<typename PinT> struct ValueType { using T = void; };
  2562. template<> struct ValueType<input_IN> { using T = Logic; };
  2563. template<> struct ValueType<output_OUT> { using T = Logic; };
  2564.  
  2565. struct ContextObject {
  2566. Node* _node;
  2567.  
  2568. Logic _input_IN;
  2569.  
  2570. };
  2571.  
  2572. using Context = ContextObject*;
  2573.  
  2574. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  2575. static_assert(always_false<PinT>::value,
  2576. "Invalid pin descriptor. Expected one of:" \
  2577. " input_IN" \
  2578. " output_OUT");
  2579. }
  2580.  
  2581. template<> Logic getValue<input_IN>(Context ctx) {
  2582. return ctx->_input_IN;
  2583. }
  2584. template<> Logic getValue<output_OUT>(Context ctx) {
  2585. return ctx->_node->output_OUT;
  2586. }
  2587.  
  2588. template<typename InputT> bool isInputDirty(Context ctx) {
  2589. static_assert(always_false<InputT>::value,
  2590. "Invalid input descriptor. Expected one of:" \
  2591. "");
  2592. return false;
  2593. }
  2594.  
  2595. template<typename OutputT> void emitValue(Context ctx, typename ValueType<OutputT>::T val) {
  2596. static_assert(always_false<OutputT>::value,
  2597. "Invalid output descriptor. Expected one of:" \
  2598. " output_OUT");
  2599. }
  2600.  
  2601. template<> void emitValue<output_OUT>(Context ctx, Logic val) {
  2602. ctx->_node->output_OUT = val;
  2603. ctx->_node->isOutputDirty_OUT = true;
  2604. }
  2605.  
  2606. State* getState(Context ctx) {
  2607. return &ctx->_node->state;
  2608. }
  2609.  
  2610. void evaluate(Context ctx) {
  2611. State* state = getState(ctx);
  2612. auto newValue = getValue<input_IN>(ctx);
  2613.  
  2614. if (newValue == true && state->state == false)
  2615. emitValue<output_OUT>(ctx, 1);
  2616.  
  2617. state->state = newValue;
  2618. }
  2619.  
  2620. } // namespace xod__core__pulse_on_true
  2621.  
  2622. //-----------------------------------------------------------------------------
  2623. // bitrex/xod-menu-system/menu-controller implementation
  2624. //-----------------------------------------------------------------------------
  2625. namespace bitrex__xod_menu_system__menu_controller {
  2626.  
  2627. //#pragma XOD dirtiness disable
  2628.  
  2629. namespace menu_base = ____menu_base;
  2630. using menu_base_t = menu_base::MenuBase;
  2631. namespace branch_menu_item = ____branch_menu_item;
  2632.  
  2633. /* a MenuCursor interface, providing an interface from user
  2634.  
  2635. selections on a keypad to navigating thru the menu tree,
  2636.  
  2637. selecting, and invoking menu items */
  2638.  
  2639. template <typename MenuBase>
  2640. class MenuCursor {
  2641. public:
  2642. MenuCursor() = default;
  2643.  
  2644. explicit MenuCursor(branch_menu_item::BranchMenuImpl<MenuBase>* top_menu)
  2645. : top_menu_ptr_(top_menu),
  2646. current_root_menu_ptr_(nullptr),
  2647. current_sub_menu_ptr_(top_menu) {}
  2648.  
  2649. void back() {
  2650. auto parent_ptr = current_root_menu_ptr_->parent();
  2651. if (parent_ptr && current_sub_menu_ptr_!= top_menu_ptr_) {
  2652. current_root_menu_ptr_ = parent_ptr;
  2653. current_sub_menu_ptr_ = current_root_menu_ptr_->sub_menu_ptr();
  2654. } else {
  2655. current_sub_menu_ptr_ = top_menu_ptr_;
  2656. current_root_menu_ptr_ = nullptr;
  2657. }
  2658. }
  2659.  
  2660. void left() {
  2661. if (current_root_menu_ptr_) {
  2662. current_sub_menu_ptr_ = current_root_menu_ptr_->prev();
  2663. }
  2664. }
  2665.  
  2666. void right() {
  2667. if (current_root_menu_ptr_) {
  2668. current_sub_menu_ptr_ = current_root_menu_ptr_->next();
  2669. }
  2670. }
  2671.  
  2672. void invoke(Number param) {
  2673. auto menu_ptr = current_sub_menu_ptr_->invoke(param);
  2674. if (menu_ptr) {
  2675. auto prev_root_menu_ = current_root_menu_ptr_;
  2676. current_root_menu_ptr_ =
  2677. static_cast<branch_menu_item::BranchMenuImpl<MenuBase>*>(
  2678. menu_ptr);
  2679. current_root_menu_ptr_->set_parent(prev_root_menu_);
  2680. current_sub_menu_ptr_ = current_root_menu_ptr_->sub_menu_ptr();
  2681. }
  2682. }
  2683.  
  2684. List<XString> text() const { return current_sub_menu_ptr_->text(); }
  2685.  
  2686. private:
  2687. branch_menu_item::BranchMenuImpl<MenuBase>* top_menu_ptr_ = nullptr;
  2688. branch_menu_item::BranchMenuImpl<MenuBase>* current_root_menu_ptr_ = nullptr;
  2689. MenuBase* current_sub_menu_ptr_ = nullptr;
  2690. };
  2691.  
  2692. /* State for this node holds a branch menu to which the rest of
  2693. the menu structure is connected and derives from */
  2694.  
  2695. struct State {
  2696. MenuCursor<menu_base_t> menu_cursor;
  2697. branch_menu_item::BranchMenuImpl<menu_base_t> root_menu;
  2698. };
  2699.  
  2700. struct Node {
  2701. State state;
  2702. XString output_LINE1;
  2703. XString output_LINE2;
  2704. XString output_LINE3;
  2705. XString output_LINE4;
  2706.  
  2707. union {
  2708. struct {
  2709. bool isOutputDirty_LINE1 : 1;
  2710. bool isOutputDirty_LINE2 : 1;
  2711. bool isOutputDirty_LINE3 : 1;
  2712. bool isOutputDirty_LINE4 : 1;
  2713. bool isNodeDirty : 1;
  2714. };
  2715.  
  2716. DirtyFlags dirtyFlags;
  2717. };
  2718. };
  2719.  
  2720. struct input_MENU_TREE { };
  2721. struct input_TITLE_1 { };
  2722. struct input_TITLE_2 { };
  2723. struct input_RIGHT { };
  2724. struct input_LEFT { };
  2725. struct input_BACK { };
  2726. struct input_INVOKE { };
  2727. struct input_TOP { };
  2728. struct input_PARAM_IN { };
  2729. struct output_LINE1 { };
  2730. struct output_LINE2 { };
  2731. struct output_LINE3 { };
  2732. struct output_LINE4 { };
  2733.  
  2734. template<typename PinT> struct ValueType { using T = void; };
  2735. template<> struct ValueType<input_MENU_TREE> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  2736. template<> struct ValueType<input_TITLE_1> { using T = XString; };
  2737. template<> struct ValueType<input_TITLE_2> { using T = XString; };
  2738. template<> struct ValueType<input_RIGHT> { using T = Logic; };
  2739. template<> struct ValueType<input_LEFT> { using T = Logic; };
  2740. template<> struct ValueType<input_BACK> { using T = Logic; };
  2741. template<> struct ValueType<input_INVOKE> { using T = Logic; };
  2742. template<> struct ValueType<input_TOP> { using T = Logic; };
  2743. template<> struct ValueType<input_PARAM_IN> { using T = Number; };
  2744. template<> struct ValueType<output_LINE1> { using T = XString; };
  2745. template<> struct ValueType<output_LINE2> { using T = XString; };
  2746. template<> struct ValueType<output_LINE3> { using T = XString; };
  2747. template<> struct ValueType<output_LINE4> { using T = XString; };
  2748.  
  2749. struct ContextObject {
  2750. Node* _node;
  2751.  
  2752. bitrex__xod_menu_system__leaf_menu_item_impl::Type _input_MENU_TREE;
  2753. XString _input_TITLE_1;
  2754. XString _input_TITLE_2;
  2755. Logic _input_RIGHT;
  2756. Logic _input_LEFT;
  2757. Logic _input_BACK;
  2758. Logic _input_INVOKE;
  2759. Logic _input_TOP;
  2760. Number _input_PARAM_IN;
  2761.  
  2762. bool _isInputDirty_RIGHT;
  2763. bool _isInputDirty_LEFT;
  2764. bool _isInputDirty_BACK;
  2765. bool _isInputDirty_INVOKE;
  2766. bool _isInputDirty_TOP;
  2767. };
  2768.  
  2769. using Context = ContextObject*;
  2770.  
  2771. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  2772. static_assert(always_false<PinT>::value,
  2773. "Invalid pin descriptor. Expected one of:" \
  2774. " input_MENU_TREE input_TITLE_1 input_TITLE_2 input_RIGHT input_LEFT input_BACK input_INVOKE input_TOP input_PARAM_IN" \
  2775. " output_LINE1 output_LINE2 output_LINE3 output_LINE4");
  2776. }
  2777.  
  2778. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<input_MENU_TREE>(Context ctx) {
  2779. return ctx->_input_MENU_TREE;
  2780. }
  2781. template<> XString getValue<input_TITLE_1>(Context ctx) {
  2782. return ctx->_input_TITLE_1;
  2783. }
  2784. template<> XString getValue<input_TITLE_2>(Context ctx) {
  2785. return ctx->_input_TITLE_2;
  2786. }
  2787. template<> Logic getValue<input_RIGHT>(Context ctx) {
  2788. return ctx->_input_RIGHT;
  2789. }
  2790. template<> Logic getValue<input_LEFT>(Context ctx) {
  2791. return ctx->_input_LEFT;
  2792. }
  2793. template<> Logic getValue<input_BACK>(Context ctx) {
  2794. return ctx->_input_BACK;
  2795. }
  2796. template<> Logic getValue<input_INVOKE>(Context ctx) {
  2797. return ctx->_input_INVOKE;
  2798. }
  2799. template<> Logic getValue<input_TOP>(Context ctx) {
  2800. return ctx->_input_TOP;
  2801. }
  2802. template<> Number getValue<input_PARAM_IN>(Context ctx) {
  2803. return ctx->_input_PARAM_IN;
  2804. }
  2805. template<> XString getValue<output_LINE1>(Context ctx) {
  2806. return ctx->_node->output_LINE1;
  2807. }
  2808. template<> XString getValue<output_LINE2>(Context ctx) {
  2809. return ctx->_node->output_LINE2;
  2810. }
  2811. template<> XString getValue<output_LINE3>(Context ctx) {
  2812. return ctx->_node->output_LINE3;
  2813. }
  2814. template<> XString getValue<output_LINE4>(Context ctx) {
  2815. return ctx->_node->output_LINE4;
  2816. }
  2817.  
  2818. template<typename InputT> bool isInputDirty(Context ctx) {
  2819. static_assert(always_false<InputT>::value,
  2820. "Invalid input descriptor. Expected one of:" \
  2821. " input_RIGHT input_LEFT input_BACK input_INVOKE input_TOP");
  2822. return false;
  2823. }
  2824.  
  2825. template<> bool isInputDirty<input_RIGHT>(Context ctx) {
  2826. return ctx->_isInputDirty_RIGHT;
  2827. }
  2828. template<> bool isInputDirty<input_LEFT>(Context ctx) {
  2829. return ctx->_isInputDirty_LEFT;
  2830. }
  2831. template<> bool isInputDirty<input_BACK>(Context ctx) {
  2832. return ctx->_isInputDirty_BACK;
  2833. }
  2834. template<> bool isInputDirty<input_INVOKE>(Context ctx) {
  2835. return ctx->_isInputDirty_INVOKE;
  2836. }
  2837. template<> bool isInputDirty<input_TOP>(Context ctx) {
  2838. return ctx->_isInputDirty_TOP;
  2839. }
  2840.  
  2841. template<typename OutputT> void emitValue(Context ctx, typename ValueType<OutputT>::T val) {
  2842. static_assert(always_false<OutputT>::value,
  2843. "Invalid output descriptor. Expected one of:" \
  2844. " output_LINE1 output_LINE2 output_LINE3 output_LINE4");
  2845. }
  2846.  
  2847. template<> void emitValue<output_LINE1>(Context ctx, XString val) {
  2848. ctx->_node->output_LINE1 = val;
  2849. ctx->_node->isOutputDirty_LINE1 = true;
  2850. }
  2851. template<> void emitValue<output_LINE2>(Context ctx, XString val) {
  2852. ctx->_node->output_LINE2 = val;
  2853. ctx->_node->isOutputDirty_LINE2 = true;
  2854. }
  2855. template<> void emitValue<output_LINE3>(Context ctx, XString val) {
  2856. ctx->_node->output_LINE3 = val;
  2857. ctx->_node->isOutputDirty_LINE3 = true;
  2858. }
  2859. template<> void emitValue<output_LINE4>(Context ctx, XString val) {
  2860. ctx->_node->output_LINE4 = val;
  2861. ctx->_node->isOutputDirty_LINE4 = true;
  2862. }
  2863.  
  2864. State* getState(Context ctx) {
  2865. return &ctx->_node->state;
  2866. }
  2867.  
  2868. static XStringCString null_string = XStringCString("");
  2869.  
  2870. void evaluate(Context ctx) {
  2871. auto state = getState(ctx);
  2872.  
  2873. if (isSettingUp()) {
  2874. auto title_1 = getValue<input_TITLE_1>(ctx);
  2875. auto title_2 = getValue<input_TITLE_2>(ctx);
  2876. state->root_menu =
  2877. branch_menu_item::BranchMenuImpl<menu_base_t>(getValue<input_MENU_TREE>(ctx), title_1,
  2878. title_2, 0);
  2879. state->root_menu.set_parent(&state->root_menu);
  2880. state->menu_cursor = MenuCursor<menu_base_t>(&state->root_menu);
  2881. }
  2882.  
  2883. /* update all trigger pulse inputs */
  2884.  
  2885. bool back = isInputDirty<input_BACK>(ctx);
  2886. bool left = isInputDirty<input_LEFT>(ctx);
  2887. bool right = isInputDirty<input_RIGHT>(ctx);
  2888. bool invoke = isInputDirty<input_INVOKE>(ctx);
  2889.  
  2890. if (back) {
  2891. state->menu_cursor.back();
  2892. }
  2893. if (left) {
  2894. state->menu_cursor.left();
  2895. }
  2896. if (right) {
  2897. state->menu_cursor.right();
  2898. }
  2899. if (invoke) {
  2900. // if a menu is invoked pass along the input parameter
  2901. // to the appropriate MenuBase class instance
  2902. auto param = getValue<input_PARAM_IN>(ctx);
  2903. state->menu_cursor.invoke(param);
  2904. }
  2905.  
  2906. //Update the menu dispaly text
  2907.  
  2908. auto text_list = state->menu_cursor.text();
  2909. auto text_it = text_list.iterate();
  2910. emitValue<output_LINE1>(ctx, *text_it);
  2911.  
  2912. if (++text_it) {
  2913. emitValue<output_LINE2>(ctx, *text_it);
  2914. } else {
  2915. emitValue<output_LINE2>(ctx, null_string);
  2916. return;
  2917. }
  2918. if (++text_it) {
  2919. emitValue<output_LINE3>(ctx, *text_it);
  2920. } else {
  2921. emitValue<output_LINE3>(ctx, null_string);
  2922. return;
  2923. }
  2924. if (++text_it) {
  2925. emitValue<output_LINE4>(ctx, *text_it);
  2926. } else {
  2927. emitValue<output_LINE4>(ctx, null_string);
  2928. return;
  2929. }
  2930. }
  2931.  
  2932. } // namespace bitrex__xod_menu_system__menu_controller
  2933.  
  2934. //-----------------------------------------------------------------------------
  2935. // xod/common-hardware/text-lcd-16x2 implementation
  2936. //-----------------------------------------------------------------------------
  2937. namespace xod__common_hardware__text_lcd_16x2 {
  2938.  
  2939. // --- Enter global namespace ---
  2940. }}
  2941. #include <LiquidCrystal.h>
  2942.  
  2943. namespace xod {
  2944. namespace xod__common_hardware__text_lcd_16x2 {
  2945. // --- Back to local namespace ---
  2946. struct State {
  2947. LiquidCrystal* lcd;
  2948. };
  2949.  
  2950. struct Node {
  2951. State state;
  2952. Logic output_DONE;
  2953.  
  2954. union {
  2955. struct {
  2956. bool isOutputDirty_DONE : 1;
  2957. bool isNodeDirty : 1;
  2958. };
  2959.  
  2960. DirtyFlags dirtyFlags;
  2961. };
  2962. };
  2963.  
  2964. struct input_RS { };
  2965. struct input_EN { };
  2966. struct input_D4 { };
  2967. struct input_D5 { };
  2968. struct input_D6 { };
  2969. struct input_D7 { };
  2970. struct input_L1 { };
  2971. struct input_L2 { };
  2972. struct input_UPD { };
  2973. struct output_DONE { };
  2974.  
  2975. template<typename PinT> struct ValueType { using T = void; };
  2976. template<> struct ValueType<input_RS> { using T = uint8_t; };
  2977. template<> struct ValueType<input_EN> { using T = uint8_t; };
  2978. template<> struct ValueType<input_D4> { using T = uint8_t; };
  2979. template<> struct ValueType<input_D5> { using T = uint8_t; };
  2980. template<> struct ValueType<input_D6> { using T = uint8_t; };
  2981. template<> struct ValueType<input_D7> { using T = uint8_t; };
  2982. template<> struct ValueType<input_L1> { using T = XString; };
  2983. template<> struct ValueType<input_L2> { using T = XString; };
  2984. template<> struct ValueType<input_UPD> { using T = Logic; };
  2985. template<> struct ValueType<output_DONE> { using T = Logic; };
  2986.  
  2987. struct ContextObject {
  2988. Node* _node;
  2989.  
  2990. uint8_t _input_RS;
  2991. uint8_t _input_EN;
  2992. uint8_t _input_D4;
  2993. uint8_t _input_D5;
  2994. uint8_t _input_D6;
  2995. uint8_t _input_D7;
  2996. XString _input_L1;
  2997. XString _input_L2;
  2998. Logic _input_UPD;
  2999.  
  3000. bool _isInputDirty_UPD;
  3001. };
  3002.  
  3003. using Context = ContextObject*;
  3004.  
  3005. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  3006. static_assert(always_false<PinT>::value,
  3007. "Invalid pin descriptor. Expected one of:" \
  3008. " input_RS input_EN input_D4 input_D5 input_D6 input_D7 input_L1 input_L2 input_UPD" \
  3009. " output_DONE");
  3010. }
  3011.  
  3012. template<> uint8_t getValue<input_RS>(Context ctx) {
  3013. return ctx->_input_RS;
  3014. }
  3015. template<> uint8_t getValue<input_EN>(Context ctx) {
  3016. return ctx->_input_EN;
  3017. }
  3018. template<> uint8_t getValue<input_D4>(Context ctx) {
  3019. return ctx->_input_D4;
  3020. }
  3021. template<> uint8_t getValue<input_D5>(Context ctx) {
  3022. return ctx->_input_D5;
  3023. }
  3024. template<> uint8_t getValue<input_D6>(Context ctx) {
  3025. return ctx->_input_D6;
  3026. }
  3027. template<> uint8_t getValue<input_D7>(Context ctx) {
  3028. return ctx->_input_D7;
  3029. }
  3030. template<> XString getValue<input_L1>(Context ctx) {
  3031. return ctx->_input_L1;
  3032. }
  3033. template<> XString getValue<input_L2>(Context ctx) {
  3034. return ctx->_input_L2;
  3035. }
  3036. template<> Logic getValue<input_UPD>(Context ctx) {
  3037. return ctx->_input_UPD;
  3038. }
  3039. template<> Logic getValue<output_DONE>(Context ctx) {
  3040. return ctx->_node->output_DONE;
  3041. }
  3042.  
  3043. template<typename InputT> bool isInputDirty(Context ctx) {
  3044. static_assert(always_false<InputT>::value,
  3045. "Invalid input descriptor. Expected one of:" \
  3046. " input_UPD");
  3047. return false;
  3048. }
  3049.  
  3050. template<> bool isInputDirty<input_UPD>(Context ctx) {
  3051. return ctx->_isInputDirty_UPD;
  3052. }
  3053.  
  3054. template<typename OutputT> void emitValue(Context ctx, typename ValueType<OutputT>::T val) {
  3055. static_assert(always_false<OutputT>::value,
  3056. "Invalid output descriptor. Expected one of:" \
  3057. " output_DONE");
  3058. }
  3059.  
  3060. template<> void emitValue<output_DONE>(Context ctx, Logic val) {
  3061. ctx->_node->output_DONE = val;
  3062. ctx->_node->isOutputDirty_DONE = true;
  3063. }
  3064.  
  3065. State* getState(Context ctx) {
  3066. return &ctx->_node->state;
  3067. }
  3068.  
  3069. void printLine(LiquidCrystal* lcd, uint8_t lineIndex, XString str) {
  3070. lcd->setCursor(0, lineIndex);
  3071. uint8_t whitespace = 16;
  3072. for (auto it = str->iterate(); it; ++it, --whitespace)
  3073. lcd->write(*it);
  3074.  
  3075. // Clear the rest of the line
  3076. while (whitespace--)
  3077. lcd->write(' ');
  3078. }
  3079.  
  3080. void evaluate(Context ctx) {
  3081. if (!isInputDirty<input_UPD>(ctx))
  3082. return;
  3083.  
  3084. State* state = getState(ctx);
  3085. auto lcd = state->lcd;
  3086. if (!state->lcd) {
  3087. state->lcd = lcd = new LiquidCrystal(
  3088. (int)getValue<input_RS>(ctx),
  3089. (int)getValue<input_EN>(ctx),
  3090. (int)getValue<input_D4>(ctx),
  3091. (int)getValue<input_D5>(ctx),
  3092. (int)getValue<input_D6>(ctx),
  3093. (int)getValue<input_D7>(ctx));
  3094.  
  3095. lcd->begin(16, 2);
  3096. }
  3097.  
  3098. printLine(lcd, 0, getValue<input_L1>(ctx));
  3099. printLine(lcd, 1, getValue<input_L2>(ctx));
  3100.  
  3101. emitValue<output_DONE>(ctx, 1);
  3102. }
  3103.  
  3104. } // namespace xod__common_hardware__text_lcd_16x2
  3105.  
  3106. } // namespace xod
  3107.  
  3108.  
  3109. /*=============================================================================
  3110. *
  3111. *
  3112. * Main loop components
  3113. *
  3114. *
  3115. =============================================================================*/
  3116.  
  3117. namespace xod {
  3118.  
  3119. // Define/allocate persistent storages (state, timeout, output data) for all nodes
  3120. #pragma GCC diagnostic push
  3121. #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
  3122.  
  3123. constexpr XString node_0_output_TXT = XString();
  3124.  
  3125. constexpr XString node_1_output_TXT = XString();
  3126.  
  3127. constexpr XString node_2_output_TXT = XString();
  3128.  
  3129. constexpr bitrex__xod_menu_system__menu_base::Type node_3_output_OUT = { /* bitrex/xod-menu-system/menu-base */ };
  3130.  
  3131. constexpr XString node_4_output_TXT = XString();
  3132.  
  3133. constexpr bitrex__xod_menu_system__menu_base::Type node_5_output_OUT = { /* bitrex/xod-menu-system/menu-base */ };
  3134.  
  3135. constexpr Number node_6_output_VAL = 0;
  3136.  
  3137. constexpr XString node_7_output_VAL = XString();
  3138.  
  3139. constexpr uint8_t node_8_output_VAL = 0x0;
  3140.  
  3141. constexpr uint8_t node_9_output_VAL = A0;
  3142.  
  3143. constexpr Number node_10_output_VAL = 0.03;
  3144.  
  3145. constexpr Number node_11_output_VAL = 0.03;
  3146.  
  3147. constexpr Number node_12_output_VAL = 0.03;
  3148.  
  3149. constexpr Number node_13_output_VAL = 0.03;
  3150.  
  3151. constexpr Number node_14_output_VAL = 0.03;
  3152.  
  3153. constexpr XString node_15_output_VAL = XString();
  3154.  
  3155. constexpr XString node_16_output_VAL = XString();
  3156.  
  3157. constexpr uint8_t node_17_output_VAL = 0x0;
  3158.  
  3159. constexpr uint8_t node_18_output_VAL = 0;
  3160.  
  3161. constexpr uint8_t node_19_output_VAL = 0;
  3162.  
  3163. constexpr uint8_t node_20_output_VAL = 0;
  3164.  
  3165. constexpr uint8_t node_21_output_VAL = 0;
  3166.  
  3167. constexpr uint8_t node_22_output_VAL = 0;
  3168.  
  3169. constexpr uint8_t node_23_output_VAL = 0;
  3170.  
  3171. constexpr XString node_24_output_VAL = XString();
  3172.  
  3173. constexpr uint8_t node_25_output_VAL = 0x0;
  3174.  
  3175. constexpr XString node_26_output_VAL = XString();
  3176.  
  3177. constexpr XString node_27_output_VAL = XString();
  3178.  
  3179. constexpr uint8_t node_28_output_VAL = 0x0;
  3180.  
  3181. constexpr Logic node_29_output_TICK = false;
  3182.  
  3183. constexpr bitrex__xod_menu_system__menu_base::Type node_30_output_OUT = { /* bitrex/xod-menu-system/menu-base */ };
  3184.  
  3185. constexpr XString node_31_output_VAL = XString();
  3186.  
  3187. constexpr XString node_32_output_VAL = XString();
  3188.  
  3189. constexpr uint8_t node_33_output_VAL = 0x0;
  3190.  
  3191. constexpr bitrex__xod_menu_system__menu_base::Type node_34_output_OUT = { /* bitrex/xod-menu-system/menu-base */ };
  3192.  
  3193. constexpr XString node_35_output_VAL = XString();
  3194.  
  3195. constexpr XString node_36_output_VAL = XString();
  3196.  
  3197. constexpr uint8_t node_37_output_VAL = 0x0;
  3198.  
  3199. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_38_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  3200. constexpr Number node_38_output_PARAM = 0;
  3201. constexpr Logic node_38_output_INVOKED = false;
  3202.  
  3203. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_39_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  3204. constexpr Number node_39_output_PARAM = 0;
  3205. constexpr Logic node_39_output_INVOKED = false;
  3206.  
  3207. constexpr Number node_40_output_VAL = 0;
  3208. constexpr Logic node_40_output_DONE = false;
  3209. constexpr Logic node_40_output_ERR = false;
  3210.  
  3211. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_41_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  3212. constexpr Number node_41_output_PARAM = 0;
  3213. constexpr Logic node_41_output_INVOKED = false;
  3214.  
  3215. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_42_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  3216. constexpr Number node_42_output_PARAM = 0;
  3217. constexpr Logic node_42_output_INVOKED = false;
  3218.  
  3219. constexpr Logic node_43_output_RIGHT = false;
  3220. constexpr Logic node_43_output_LEFT = false;
  3221. constexpr Logic node_43_output_UP = false;
  3222. constexpr Logic node_43_output_DOWN = false;
  3223. constexpr Logic node_43_output_SELECT = false;
  3224.  
  3225. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_44_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  3226.  
  3227. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_45_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  3228.  
  3229. constexpr Logic node_46_output_OUT = false;
  3230.  
  3231. constexpr Logic node_47_output_OUT = false;
  3232.  
  3233. constexpr Logic node_48_output_OUT = false;
  3234.  
  3235. constexpr Logic node_49_output_OUT = false;
  3236.  
  3237. constexpr Logic node_50_output_OUT = false;
  3238.  
  3239. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_51_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  3240.  
  3241. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_52_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  3242.  
  3243. constexpr Logic node_53_output_OUT = false;
  3244.  
  3245. constexpr Logic node_54_output_OUT = false;
  3246.  
  3247. constexpr Logic node_55_output_OUT = false;
  3248.  
  3249. constexpr Logic node_56_output_OUT = false;
  3250.  
  3251. constexpr Logic node_57_output_OUT = false;
  3252.  
  3253. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_58_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  3254.  
  3255. constexpr XString node_59_output_LINE1 = XString();
  3256. constexpr XString node_59_output_LINE2 = XString();
  3257. constexpr XString node_59_output_LINE3 = XString();
  3258. constexpr XString node_59_output_LINE4 = XString();
  3259.  
  3260. constexpr Logic node_60_output_DONE = false;
  3261.  
  3262. #pragma GCC diagnostic pop
  3263.  
  3264. bitrex__xod_menu_system__flash_string_1::Node node_0 = {
  3265. bitrex__xod_menu_system__flash_string_1::State(), // state default
  3266. node_0_output_TXT, // output TXT default
  3267. true, // TXT dirty
  3268. true // node itself dirty
  3269. };
  3270. bitrex__xod_menu_system__flash_string_1::Node node_1 = {
  3271. bitrex__xod_menu_system__flash_string_1::State(), // state default
  3272. node_1_output_TXT, // output TXT default
  3273. true, // TXT dirty
  3274. true // node itself dirty
  3275. };
  3276. bitrex__xod_menu_system__flash_string_1::Node node_2 = {
  3277. bitrex__xod_menu_system__flash_string_1::State(), // state default
  3278. node_2_output_TXT, // output TXT default
  3279. true, // TXT dirty
  3280. true // node itself dirty
  3281. };
  3282. bitrex__xod_menu_system__menu_base::Node node_3 = {
  3283. bitrex__xod_menu_system__menu_base::State(), // state default
  3284. node_3_output_OUT, // output OUT default
  3285. true, // OUT dirty
  3286. true // node itself dirty
  3287. };
  3288. bitrex__xod_menu_system__flash_string_1::Node node_4 = {
  3289. bitrex__xod_menu_system__flash_string_1::State(), // state default
  3290. node_4_output_TXT, // output TXT default
  3291. true, // TXT dirty
  3292. true // node itself dirty
  3293. };
  3294. bitrex__xod_menu_system__menu_base::Node node_5 = {
  3295. bitrex__xod_menu_system__menu_base::State(), // state default
  3296. node_5_output_OUT, // output OUT default
  3297. true, // OUT dirty
  3298. true // node itself dirty
  3299. };
  3300. xod__core__continuously::Node node_29 = {
  3301. xod__core__continuously::State(), // state default
  3302. 0, // timeoutAt
  3303. node_29_output_TICK, // output TICK default
  3304. false, // TICK dirty
  3305. true // node itself dirty
  3306. };
  3307. bitrex__xod_menu_system__menu_base::Node node_30 = {
  3308. bitrex__xod_menu_system__menu_base::State(), // state default
  3309. node_30_output_OUT, // output OUT default
  3310. true, // OUT dirty
  3311. true // node itself dirty
  3312. };
  3313. bitrex__xod_menu_system__menu_base::Node node_34 = {
  3314. bitrex__xod_menu_system__menu_base::State(), // state default
  3315. node_34_output_OUT, // output OUT default
  3316. true, // OUT dirty
  3317. true // node itself dirty
  3318. };
  3319. bitrex__xod_menu_system__leaf_menu_item_impl::Node node_38 = {
  3320. bitrex__xod_menu_system__leaf_menu_item_impl::State(), // state default
  3321. 0, // timeoutAt
  3322. node_38_output_OUT, // output OUT default
  3323. node_38_output_PARAM, // output PARAM default
  3324. node_38_output_INVOKED, // output INVOKED default
  3325. true, // OUT dirty
  3326. true, // PARAM dirty
  3327. false, // INVOKED dirty
  3328. true // node itself dirty
  3329. };
  3330. bitrex__xod_menu_system__leaf_menu_item_impl::Node node_39 = {
  3331. bitrex__xod_menu_system__leaf_menu_item_impl::State(), // state default
  3332. 0, // timeoutAt
  3333. node_39_output_OUT, // output OUT default
  3334. node_39_output_PARAM, // output PARAM default
  3335. node_39_output_INVOKED, // output INVOKED default
  3336. true, // OUT dirty
  3337. true, // PARAM dirty
  3338. false, // INVOKED dirty
  3339. true // node itself dirty
  3340. };
  3341. xod__gpio__analog_read::Node node_40 = {
  3342. xod__gpio__analog_read::State(), // state default
  3343. node_40_output_VAL, // output VAL default
  3344. node_40_output_DONE, // output DONE default
  3345. node_40_output_ERR, // output ERR default
  3346. true, // VAL dirty
  3347. false, // DONE dirty
  3348. false, // ERR dirty
  3349. true // node itself dirty
  3350. };
  3351. bitrex__xod_menu_system__leaf_menu_item_impl::Node node_41 = {
  3352. bitrex__xod_menu_system__leaf_menu_item_impl::State(), // state default
  3353. 0, // timeoutAt
  3354. node_41_output_OUT, // output OUT default
  3355. node_41_output_PARAM, // output PARAM default
  3356. node_41_output_INVOKED, // output INVOKED default
  3357. true, // OUT dirty
  3358. true, // PARAM dirty
  3359. false, // INVOKED dirty
  3360. true // node itself dirty
  3361. };
  3362. bitrex__xod_menu_system__leaf_menu_item_impl::Node node_42 = {
  3363. bitrex__xod_menu_system__leaf_menu_item_impl::State(), // state default
  3364. 0, // timeoutAt
  3365. node_42_output_OUT, // output OUT default
  3366. node_42_output_PARAM, // output PARAM default
  3367. node_42_output_INVOKED, // output INVOKED default
  3368. true, // OUT dirty
  3369. true, // PARAM dirty
  3370. false, // INVOKED dirty
  3371. true // node itself dirty
  3372. };
  3373. bitrex__xod_menu_system__text_lcd_16x2_keypad_impl::Node node_43 = {
  3374. bitrex__xod_menu_system__text_lcd_16x2_keypad_impl::State(), // state default
  3375. node_43_output_RIGHT, // output RIGHT default
  3376. node_43_output_LEFT, // output LEFT default
  3377. node_43_output_UP, // output UP default
  3378. node_43_output_DOWN, // output DOWN default
  3379. node_43_output_SELECT, // output SELECT default
  3380. true, // RIGHT dirty
  3381. true, // LEFT dirty
  3382. true, // UP dirty
  3383. true, // DOWN dirty
  3384. true, // SELECT dirty
  3385. true // node itself dirty
  3386. };
  3387. bitrex__xod_menu_system__concat_menu::Node node_44 = {
  3388. bitrex__xod_menu_system__concat_menu::State(), // state default
  3389. node_44_output_OUT, // output OUT default
  3390. true, // OUT dirty
  3391. true // node itself dirty
  3392. };
  3393. bitrex__xod_menu_system__concat_menu::Node node_45 = {
  3394. bitrex__xod_menu_system__concat_menu::State(), // state default
  3395. node_45_output_OUT, // output OUT default
  3396. true, // OUT dirty
  3397. true // node itself dirty
  3398. };
  3399. xod__core__debounce__boolean::Node node_46 = {
  3400. xod__core__debounce__boolean::State(), // state default
  3401. 0, // timeoutAt
  3402. node_46_output_OUT, // output OUT default
  3403. true, // OUT dirty
  3404. true // node itself dirty
  3405. };
  3406. xod__core__debounce__boolean::Node node_47 = {
  3407. xod__core__debounce__boolean::State(), // state default
  3408. 0, // timeoutAt
  3409. node_47_output_OUT, // output OUT default
  3410. true, // OUT dirty
  3411. true // node itself dirty
  3412. };
  3413. xod__core__debounce__boolean::Node node_48 = {
  3414. xod__core__debounce__boolean::State(), // state default
  3415. 0, // timeoutAt
  3416. node_48_output_OUT, // output OUT default
  3417. true, // OUT dirty
  3418. true // node itself dirty
  3419. };
  3420. xod__core__debounce__boolean::Node node_49 = {
  3421. xod__core__debounce__boolean::State(), // state default
  3422. 0, // timeoutAt
  3423. node_49_output_OUT, // output OUT default
  3424. true, // OUT dirty
  3425. true // node itself dirty
  3426. };
  3427. xod__core__debounce__boolean::Node node_50 = {
  3428. xod__core__debounce__boolean::State(), // state default
  3429. 0, // timeoutAt
  3430. node_50_output_OUT, // output OUT default
  3431. true, // OUT dirty
  3432. true // node itself dirty
  3433. };
  3434. bitrex__xod_menu_system__branch_menu_item::Node node_51 = {
  3435. bitrex__xod_menu_system__branch_menu_item::State(), // state default
  3436. node_51_output_OUT, // output OUT default
  3437. true, // OUT dirty
  3438. true // node itself dirty
  3439. };
  3440. bitrex__xod_menu_system__branch_menu_item::Node node_52 = {
  3441. bitrex__xod_menu_system__branch_menu_item::State(), // state default
  3442. node_52_output_OUT, // output OUT default
  3443. true, // OUT dirty
  3444. true // node itself dirty
  3445. };
  3446. xod__core__pulse_on_true::Node node_53 = {
  3447. xod__core__pulse_on_true::State(), // state default
  3448. node_53_output_OUT, // output OUT default
  3449. false, // OUT dirty
  3450. true // node itself dirty
  3451. };
  3452. xod__core__pulse_on_true::Node node_54 = {
  3453. xod__core__pulse_on_true::State(), // state default
  3454. node_54_output_OUT, // output OUT default
  3455. false, // OUT dirty
  3456. true // node itself dirty
  3457. };
  3458. xod__core__pulse_on_true::Node node_55 = {
  3459. xod__core__pulse_on_true::State(), // state default
  3460. node_55_output_OUT, // output OUT default
  3461. false, // OUT dirty
  3462. true // node itself dirty
  3463. };
  3464. xod__core__pulse_on_true::Node node_56 = {
  3465. xod__core__pulse_on_true::State(), // state default
  3466. node_56_output_OUT, // output OUT default
  3467. false, // OUT dirty
  3468. true // node itself dirty
  3469. };
  3470. xod__core__pulse_on_true::Node node_57 = {
  3471. xod__core__pulse_on_true::State(), // state default
  3472. node_57_output_OUT, // output OUT default
  3473. false, // OUT dirty
  3474. true // node itself dirty
  3475. };
  3476. bitrex__xod_menu_system__concat_menu::Node node_58 = {
  3477. bitrex__xod_menu_system__concat_menu::State(), // state default
  3478. node_58_output_OUT, // output OUT default
  3479. true, // OUT dirty
  3480. true // node itself dirty
  3481. };
  3482. bitrex__xod_menu_system__menu_controller::Node node_59 = {
  3483. bitrex__xod_menu_system__menu_controller::State(), // state default
  3484. node_59_output_LINE1, // output LINE1 default
  3485. node_59_output_LINE2, // output LINE2 default
  3486. node_59_output_LINE3, // output LINE3 default
  3487. node_59_output_LINE4, // output LINE4 default
  3488. true, // LINE1 dirty
  3489. true, // LINE2 dirty
  3490. true, // LINE3 dirty
  3491. true, // LINE4 dirty
  3492. true // node itself dirty
  3493. };
  3494. xod__common_hardware__text_lcd_16x2::Node node_60 = {
  3495. xod__common_hardware__text_lcd_16x2::State(), // state default
  3496. node_60_output_DONE, // output DONE default
  3497. false, // DONE dirty
  3498. true // node itself dirty
  3499. };
  3500.  
  3501. #if defined(XOD_DEBUG) || defined(XOD_SIMULATION)
  3502. namespace detail {
  3503. void handleTweaks() {
  3504. if (XOD_DEBUG_SERIAL.available() > 0 && XOD_DEBUG_SERIAL.find("+XOD:", 5)) {
  3505. int tweakedNodeId = XOD_DEBUG_SERIAL.parseInt();
  3506.  
  3507. switch (tweakedNodeId) {
  3508. }
  3509.  
  3510. XOD_DEBUG_SERIAL.find('\n');
  3511. }
  3512. }
  3513. } // namespace detail
  3514. #endif
  3515.  
  3516. void runTransaction() {
  3517. g_transactionTime = millis();
  3518.  
  3519. XOD_TRACE_F("Transaction started, t=");
  3520. XOD_TRACE_LN(g_transactionTime);
  3521.  
  3522. #if defined(XOD_DEBUG) || defined(XOD_SIMULATION)
  3523. detail::handleTweaks();
  3524. #endif
  3525.  
  3526. // Check for timeouts
  3527. detail::checkTriggerTimeout(&node_29);
  3528. detail::checkTriggerTimeout(&node_38);
  3529. detail::checkTriggerTimeout(&node_39);
  3530. detail::checkTriggerTimeout(&node_41);
  3531. detail::checkTriggerTimeout(&node_42);
  3532. detail::checkTriggerTimeout(&node_46);
  3533. detail::checkTriggerTimeout(&node_47);
  3534. detail::checkTriggerTimeout(&node_48);
  3535. detail::checkTriggerTimeout(&node_49);
  3536. detail::checkTriggerTimeout(&node_50);
  3537.  
  3538. // defer-* nodes are always at the very bottom of the graph, so no one will
  3539. // recieve values emitted by them. We must evaluate them before everybody
  3540. // else to give them a chance to emit values.
  3541. //
  3542. // If trigerred, keep only output dirty, not the node itself, so it will
  3543. // evaluate on the regular pass only if it pushed a new value again.
  3544.  
  3545. // Evaluate all dirty nodes
  3546. { // bitrex__xod_menu_system__flash_string_1 #0
  3547. if (node_0.isNodeDirty) {
  3548. XOD_TRACE_F("Eval node #");
  3549. XOD_TRACE_LN(0);
  3550.  
  3551. bitrex__xod_menu_system__flash_string_1::ContextObject ctxObj;
  3552. ctxObj._node = &node_0;
  3553.  
  3554. // copy data from upstream nodes into context
  3555.  
  3556. bitrex__xod_menu_system__flash_string_1::evaluate(&ctxObj);
  3557.  
  3558. // mark downstream nodes dirty
  3559. node_59.isNodeDirty |= node_0.isOutputDirty_TXT;
  3560. }
  3561. }
  3562. { // bitrex__xod_menu_system__flash_string_1 #1
  3563. if (node_1.isNodeDirty) {
  3564. XOD_TRACE_F("Eval node #");
  3565. XOD_TRACE_LN(1);
  3566.  
  3567. bitrex__xod_menu_system__flash_string_1::ContextObject ctxObj;
  3568. ctxObj._node = &node_1;
  3569.  
  3570. // copy data from upstream nodes into context
  3571.  
  3572. bitrex__xod_menu_system__flash_string_1::evaluate(&ctxObj);
  3573.  
  3574. // mark downstream nodes dirty
  3575. node_52.isNodeDirty |= node_1.isOutputDirty_TXT;
  3576. }
  3577. }
  3578. { // bitrex__xod_menu_system__flash_string_1 #2
  3579. if (node_2.isNodeDirty) {
  3580. XOD_TRACE_F("Eval node #");
  3581. XOD_TRACE_LN(2);
  3582.  
  3583. bitrex__xod_menu_system__flash_string_1::ContextObject ctxObj;
  3584. ctxObj._node = &node_2;
  3585.  
  3586. // copy data from upstream nodes into context
  3587.  
  3588. bitrex__xod_menu_system__flash_string_1::evaluate(&ctxObj);
  3589.  
  3590. // mark downstream nodes dirty
  3591. node_59.isNodeDirty |= node_2.isOutputDirty_TXT;
  3592. }
  3593. }
  3594. { // bitrex__xod_menu_system__menu_base #3
  3595. if (node_3.isNodeDirty) {
  3596. XOD_TRACE_F("Eval node #");
  3597. XOD_TRACE_LN(3);
  3598.  
  3599. bitrex__xod_menu_system__menu_base::ContextObject ctxObj;
  3600. ctxObj._node = &node_3;
  3601.  
  3602. // copy data from upstream nodes into context
  3603.  
  3604. bitrex__xod_menu_system__menu_base::evaluate(&ctxObj);
  3605.  
  3606. // mark downstream nodes dirty
  3607. node_38.isNodeDirty |= node_3.isOutputDirty_OUT;
  3608. }
  3609. }
  3610. { // bitrex__xod_menu_system__flash_string_1 #4
  3611. if (node_4.isNodeDirty) {
  3612. XOD_TRACE_F("Eval node #");
  3613. XOD_TRACE_LN(4);
  3614.  
  3615. bitrex__xod_menu_system__flash_string_1::ContextObject ctxObj;
  3616. ctxObj._node = &node_4;
  3617.  
  3618. // copy data from upstream nodes into context
  3619.  
  3620. bitrex__xod_menu_system__flash_string_1::evaluate(&ctxObj);
  3621.  
  3622. // mark downstream nodes dirty
  3623. node_51.isNodeDirty |= node_4.isOutputDirty_TXT;
  3624. }
  3625. }
  3626. { // bitrex__xod_menu_system__menu_base #5
  3627. if (node_5.isNodeDirty) {
  3628. XOD_TRACE_F("Eval node #");
  3629. XOD_TRACE_LN(5);
  3630.  
  3631. bitrex__xod_menu_system__menu_base::ContextObject ctxObj;
  3632. ctxObj._node = &node_5;
  3633.  
  3634. // copy data from upstream nodes into context
  3635.  
  3636. bitrex__xod_menu_system__menu_base::evaluate(&ctxObj);
  3637.  
  3638. // mark downstream nodes dirty
  3639. node_39.isNodeDirty |= node_5.isOutputDirty_OUT;
  3640. }
  3641. }
  3642. { // xod__core__continuously #29
  3643. if (node_29.isNodeDirty) {
  3644. XOD_TRACE_F("Eval node #");
  3645. XOD_TRACE_LN(29);
  3646.  
  3647. xod__core__continuously::ContextObject ctxObj;
  3648. ctxObj._node = &node_29;
  3649.  
  3650. // copy data from upstream nodes into context
  3651.  
  3652. xod__core__continuously::evaluate(&ctxObj);
  3653.  
  3654. // mark downstream nodes dirty
  3655. node_40.isNodeDirty |= node_29.isOutputDirty_TICK;
  3656. node_60.isNodeDirty |= node_29.isOutputDirty_TICK;
  3657. }
  3658. }
  3659. { // bitrex__xod_menu_system__menu_base #30
  3660. if (node_30.isNodeDirty) {
  3661. XOD_TRACE_F("Eval node #");
  3662. XOD_TRACE_LN(30);
  3663.  
  3664. bitrex__xod_menu_system__menu_base::ContextObject ctxObj;
  3665. ctxObj._node = &node_30;
  3666.  
  3667. // copy data from upstream nodes into context
  3668.  
  3669. bitrex__xod_menu_system__menu_base::evaluate(&ctxObj);
  3670.  
  3671. // mark downstream nodes dirty
  3672. node_41.isNodeDirty |= node_30.isOutputDirty_OUT;
  3673. }
  3674. }
  3675. { // bitrex__xod_menu_system__menu_base #34
  3676. if (node_34.isNodeDirty) {
  3677. XOD_TRACE_F("Eval node #");
  3678. XOD_TRACE_LN(34);
  3679.  
  3680. bitrex__xod_menu_system__menu_base::ContextObject ctxObj;
  3681. ctxObj._node = &node_34;
  3682.  
  3683. // copy data from upstream nodes into context
  3684.  
  3685. bitrex__xod_menu_system__menu_base::evaluate(&ctxObj);
  3686.  
  3687. // mark downstream nodes dirty
  3688. node_42.isNodeDirty |= node_34.isOutputDirty_OUT;
  3689. }
  3690. }
  3691. { // bitrex__xod_menu_system__leaf_menu_item_impl #38
  3692. if (node_38.isNodeDirty) {
  3693. XOD_TRACE_F("Eval node #");
  3694. XOD_TRACE_LN(38);
  3695.  
  3696. bitrex__xod_menu_system__leaf_menu_item_impl::ContextObject ctxObj;
  3697. ctxObj._node = &node_38;
  3698.  
  3699. // copy data from upstream nodes into context
  3700. ctxObj._input_MENU_PTR = node_3.output_OUT;
  3701. ctxObj._input_LINE1 = node_15_output_VAL;
  3702. ctxObj._input_LINE2 = node_16_output_VAL;
  3703. ctxObj._input_ID = node_17_output_VAL;
  3704.  
  3705. bitrex__xod_menu_system__leaf_menu_item_impl::evaluate(&ctxObj);
  3706.  
  3707. // mark downstream nodes dirty
  3708. node_45.isNodeDirty |= node_38.isOutputDirty_OUT;
  3709. }
  3710. }
  3711. { // bitrex__xod_menu_system__leaf_menu_item_impl #39
  3712. if (node_39.isNodeDirty) {
  3713. XOD_TRACE_F("Eval node #");
  3714. XOD_TRACE_LN(39);
  3715.  
  3716. bitrex__xod_menu_system__leaf_menu_item_impl::ContextObject ctxObj;
  3717. ctxObj._node = &node_39;
  3718.  
  3719. // copy data from upstream nodes into context
  3720. ctxObj._input_MENU_PTR = node_5.output_OUT;
  3721. ctxObj._input_LINE1 = node_26_output_VAL;
  3722. ctxObj._input_LINE2 = node_27_output_VAL;
  3723. ctxObj._input_ID = node_28_output_VAL;
  3724.  
  3725. bitrex__xod_menu_system__leaf_menu_item_impl::evaluate(&ctxObj);
  3726.  
  3727. // mark downstream nodes dirty
  3728. node_44.isNodeDirty |= node_39.isOutputDirty_OUT;
  3729. }
  3730. }
  3731. { // xod__gpio__analog_read #40
  3732. if (node_40.isNodeDirty) {
  3733. XOD_TRACE_F("Eval node #");
  3734. XOD_TRACE_LN(40);
  3735.  
  3736. xod__gpio__analog_read::ContextObject ctxObj;
  3737. ctxObj._node = &node_40;
  3738.  
  3739. // copy data from upstream nodes into context
  3740. ctxObj._input_PORT = node_9_output_VAL;
  3741. ctxObj._input_UPD = node_29.output_TICK;
  3742.  
  3743. ctxObj._isInputDirty_UPD = node_29.isOutputDirty_TICK;
  3744.  
  3745. xod__gpio__analog_read::evaluate(&ctxObj);
  3746.  
  3747. // mark downstream nodes dirty
  3748. node_43.isNodeDirty |= node_40.isOutputDirty_VAL;
  3749. }
  3750. }
  3751. { // bitrex__xod_menu_system__leaf_menu_item_impl #41
  3752. if (node_41.isNodeDirty) {
  3753. XOD_TRACE_F("Eval node #");
  3754. XOD_TRACE_LN(41);
  3755.  
  3756. bitrex__xod_menu_system__leaf_menu_item_impl::ContextObject ctxObj;
  3757. ctxObj._node = &node_41;
  3758.  
  3759. // copy data from upstream nodes into context
  3760. ctxObj._input_MENU_PTR = node_30.output_OUT;
  3761. ctxObj._input_LINE1 = node_31_output_VAL;
  3762. ctxObj._input_LINE2 = node_32_output_VAL;
  3763. ctxObj._input_ID = node_33_output_VAL;
  3764.  
  3765. bitrex__xod_menu_system__leaf_menu_item_impl::evaluate(&ctxObj);
  3766.  
  3767. // mark downstream nodes dirty
  3768. node_44.isNodeDirty |= node_41.isOutputDirty_OUT;
  3769. }
  3770. }
  3771. { // bitrex__xod_menu_system__leaf_menu_item_impl #42
  3772. if (node_42.isNodeDirty) {
  3773. XOD_TRACE_F("Eval node #");
  3774. XOD_TRACE_LN(42);
  3775.  
  3776. bitrex__xod_menu_system__leaf_menu_item_impl::ContextObject ctxObj;
  3777. ctxObj._node = &node_42;
  3778.  
  3779. // copy data from upstream nodes into context
  3780. ctxObj._input_MENU_PTR = node_34.output_OUT;
  3781. ctxObj._input_LINE1 = node_35_output_VAL;
  3782. ctxObj._input_LINE2 = node_36_output_VAL;
  3783. ctxObj._input_ID = node_37_output_VAL;
  3784.  
  3785. bitrex__xod_menu_system__leaf_menu_item_impl::evaluate(&ctxObj);
  3786.  
  3787. // mark downstream nodes dirty
  3788. node_45.isNodeDirty |= node_42.isOutputDirty_OUT;
  3789. }
  3790. }
  3791. { // bitrex__xod_menu_system__text_lcd_16x2_keypad_impl #43
  3792. if (node_43.isNodeDirty) {
  3793. XOD_TRACE_F("Eval node #");
  3794. XOD_TRACE_LN(43);
  3795.  
  3796. bitrex__xod_menu_system__text_lcd_16x2_keypad_impl::ContextObject ctxObj;
  3797. ctxObj._node = &node_43;
  3798.  
  3799. // copy data from upstream nodes into context
  3800. ctxObj._input_ADC_IN = node_40.output_VAL;
  3801.  
  3802. bitrex__xod_menu_system__text_lcd_16x2_keypad_impl::evaluate(&ctxObj);
  3803.  
  3804. // mark downstream nodes dirty
  3805. node_46.isNodeDirty |= node_43.isOutputDirty_RIGHT;
  3806. node_50.isNodeDirty |= node_43.isOutputDirty_LEFT;
  3807. node_49.isNodeDirty |= node_43.isOutputDirty_UP;
  3808. node_47.isNodeDirty |= node_43.isOutputDirty_DOWN;
  3809. node_48.isNodeDirty |= node_43.isOutputDirty_SELECT;
  3810. }
  3811. }
  3812. { // bitrex__xod_menu_system__concat_menu #44
  3813. if (node_44.isNodeDirty) {
  3814. XOD_TRACE_F("Eval node #");
  3815. XOD_TRACE_LN(44);
  3816.  
  3817. bitrex__xod_menu_system__concat_menu::ContextObject ctxObj;
  3818. ctxObj._node = &node_44;
  3819.  
  3820. // copy data from upstream nodes into context
  3821. ctxObj._input_IN1 = node_39.output_OUT;
  3822. ctxObj._input_IN2 = node_41.output_OUT;
  3823.  
  3824. bitrex__xod_menu_system__concat_menu::evaluate(&ctxObj);
  3825.  
  3826. // mark downstream nodes dirty
  3827. node_51.isNodeDirty |= node_44.isOutputDirty_OUT;
  3828. }
  3829. }
  3830. { // bitrex__xod_menu_system__concat_menu #45
  3831. if (node_45.isNodeDirty) {
  3832. XOD_TRACE_F("Eval node #");
  3833. XOD_TRACE_LN(45);
  3834.  
  3835. bitrex__xod_menu_system__concat_menu::ContextObject ctxObj;
  3836. ctxObj._node = &node_45;
  3837.  
  3838. // copy data from upstream nodes into context
  3839. ctxObj._input_IN1 = node_38.output_OUT;
  3840. ctxObj._input_IN2 = node_42.output_OUT;
  3841.  
  3842. bitrex__xod_menu_system__concat_menu::evaluate(&ctxObj);
  3843.  
  3844. // mark downstream nodes dirty
  3845. node_52.isNodeDirty |= node_45.isOutputDirty_OUT;
  3846. }
  3847. }
  3848. { // xod__core__debounce__boolean #46
  3849. if (node_46.isNodeDirty) {
  3850. XOD_TRACE_F("Eval node #");
  3851. XOD_TRACE_LN(46);
  3852.  
  3853. xod__core__debounce__boolean::ContextObject ctxObj;
  3854. ctxObj._node = &node_46;
  3855.  
  3856. // copy data from upstream nodes into context
  3857. ctxObj._input_ST = node_43.output_RIGHT;
  3858. ctxObj._input_Ts = node_10_output_VAL;
  3859.  
  3860. xod__core__debounce__boolean::evaluate(&ctxObj);
  3861.  
  3862. // mark downstream nodes dirty
  3863. node_53.isNodeDirty |= node_46.isOutputDirty_OUT;
  3864. }
  3865. }
  3866. { // xod__core__debounce__boolean #47
  3867. if (node_47.isNodeDirty) {
  3868. XOD_TRACE_F("Eval node #");
  3869. XOD_TRACE_LN(47);
  3870.  
  3871. xod__core__debounce__boolean::ContextObject ctxObj;
  3872. ctxObj._node = &node_47;
  3873.  
  3874. // copy data from upstream nodes into context
  3875. ctxObj._input_ST = node_43.output_DOWN;
  3876. ctxObj._input_Ts = node_11_output_VAL;
  3877.  
  3878. xod__core__debounce__boolean::evaluate(&ctxObj);
  3879.  
  3880. // mark downstream nodes dirty
  3881. node_54.isNodeDirty |= node_47.isOutputDirty_OUT;
  3882. }
  3883. }
  3884. { // xod__core__debounce__boolean #48
  3885. if (node_48.isNodeDirty) {
  3886. XOD_TRACE_F("Eval node #");
  3887. XOD_TRACE_LN(48);
  3888.  
  3889. xod__core__debounce__boolean::ContextObject ctxObj;
  3890. ctxObj._node = &node_48;
  3891.  
  3892. // copy data from upstream nodes into context
  3893. ctxObj._input_ST = node_43.output_SELECT;
  3894. ctxObj._input_Ts = node_12_output_VAL;
  3895.  
  3896. xod__core__debounce__boolean::evaluate(&ctxObj);
  3897.  
  3898. // mark downstream nodes dirty
  3899. node_55.isNodeDirty |= node_48.isOutputDirty_OUT;
  3900. }
  3901. }
  3902. { // xod__core__debounce__boolean #49
  3903. if (node_49.isNodeDirty) {
  3904. XOD_TRACE_F("Eval node #");
  3905. XOD_TRACE_LN(49);
  3906.  
  3907. xod__core__debounce__boolean::ContextObject ctxObj;
  3908. ctxObj._node = &node_49;
  3909.  
  3910. // copy data from upstream nodes into context
  3911. ctxObj._input_ST = node_43.output_UP;
  3912. ctxObj._input_Ts = node_13_output_VAL;
  3913.  
  3914. xod__core__debounce__boolean::evaluate(&ctxObj);
  3915.  
  3916. // mark downstream nodes dirty
  3917. node_56.isNodeDirty |= node_49.isOutputDirty_OUT;
  3918. }
  3919. }
  3920. { // xod__core__debounce__boolean #50
  3921. if (node_50.isNodeDirty) {
  3922. XOD_TRACE_F("Eval node #");
  3923. XOD_TRACE_LN(50);
  3924.  
  3925. xod__core__debounce__boolean::ContextObject ctxObj;
  3926. ctxObj._node = &node_50;
  3927.  
  3928. // copy data from upstream nodes into context
  3929. ctxObj._input_ST = node_43.output_LEFT;
  3930. ctxObj._input_Ts = node_14_output_VAL;
  3931.  
  3932. xod__core__debounce__boolean::evaluate(&ctxObj);
  3933.  
  3934. // mark downstream nodes dirty
  3935. node_57.isNodeDirty |= node_50.isOutputDirty_OUT;
  3936. }
  3937. }
  3938. { // bitrex__xod_menu_system__branch_menu_item #51
  3939. if (node_51.isNodeDirty) {
  3940. XOD_TRACE_F("Eval node #");
  3941. XOD_TRACE_LN(51);
  3942.  
  3943. bitrex__xod_menu_system__branch_menu_item::ContextObject ctxObj;
  3944. ctxObj._node = &node_51;
  3945.  
  3946. // copy data from upstream nodes into context
  3947. ctxObj._input_IN = node_44.output_OUT;
  3948. ctxObj._input_LINE1 = node_4.output_TXT;
  3949. ctxObj._input_LINE2 = node_7_output_VAL;
  3950. ctxObj._input_ID = node_8_output_VAL;
  3951.  
  3952. bitrex__xod_menu_system__branch_menu_item::evaluate(&ctxObj);
  3953.  
  3954. // mark downstream nodes dirty
  3955. node_58.isNodeDirty |= node_51.isOutputDirty_OUT;
  3956. }
  3957. }
  3958. { // bitrex__xod_menu_system__branch_menu_item #52
  3959. if (node_52.isNodeDirty) {
  3960. XOD_TRACE_F("Eval node #");
  3961. XOD_TRACE_LN(52);
  3962.  
  3963. bitrex__xod_menu_system__branch_menu_item::ContextObject ctxObj;
  3964. ctxObj._node = &node_52;
  3965.  
  3966. // copy data from upstream nodes into context
  3967. ctxObj._input_IN = node_45.output_OUT;
  3968. ctxObj._input_LINE1 = node_1.output_TXT;
  3969. ctxObj._input_LINE2 = node_24_output_VAL;
  3970. ctxObj._input_ID = node_25_output_VAL;
  3971.  
  3972. bitrex__xod_menu_system__branch_menu_item::evaluate(&ctxObj);
  3973.  
  3974. // mark downstream nodes dirty
  3975. node_58.isNodeDirty |= node_52.isOutputDirty_OUT;
  3976. }
  3977. }
  3978. { // xod__core__pulse_on_true #53
  3979. if (node_53.isNodeDirty) {
  3980. XOD_TRACE_F("Eval node #");
  3981. XOD_TRACE_LN(53);
  3982.  
  3983. xod__core__pulse_on_true::ContextObject ctxObj;
  3984. ctxObj._node = &node_53;
  3985.  
  3986. // copy data from upstream nodes into context
  3987. ctxObj._input_IN = node_46.output_OUT;
  3988.  
  3989. xod__core__pulse_on_true::evaluate(&ctxObj);
  3990.  
  3991. // mark downstream nodes dirty
  3992. }
  3993. }
  3994. { // xod__core__pulse_on_true #54
  3995. if (node_54.isNodeDirty) {
  3996. XOD_TRACE_F("Eval node #");
  3997. XOD_TRACE_LN(54);
  3998.  
  3999. xod__core__pulse_on_true::ContextObject ctxObj;
  4000. ctxObj._node = &node_54;
  4001.  
  4002. // copy data from upstream nodes into context
  4003. ctxObj._input_IN = node_47.output_OUT;
  4004.  
  4005. xod__core__pulse_on_true::evaluate(&ctxObj);
  4006.  
  4007. // mark downstream nodes dirty
  4008. }
  4009. }
  4010. { // xod__core__pulse_on_true #55
  4011. if (node_55.isNodeDirty) {
  4012. XOD_TRACE_F("Eval node #");
  4013. XOD_TRACE_LN(55);
  4014.  
  4015. xod__core__pulse_on_true::ContextObject ctxObj;
  4016. ctxObj._node = &node_55;
  4017.  
  4018. // copy data from upstream nodes into context
  4019. ctxObj._input_IN = node_48.output_OUT;
  4020.  
  4021. xod__core__pulse_on_true::evaluate(&ctxObj);
  4022.  
  4023. // mark downstream nodes dirty
  4024. node_59.isNodeDirty |= node_55.isOutputDirty_OUT;
  4025. }
  4026. }
  4027. { // xod__core__pulse_on_true #56
  4028. if (node_56.isNodeDirty) {
  4029. XOD_TRACE_F("Eval node #");
  4030. XOD_TRACE_LN(56);
  4031.  
  4032. xod__core__pulse_on_true::ContextObject ctxObj;
  4033. ctxObj._node = &node_56;
  4034.  
  4035. // copy data from upstream nodes into context
  4036. ctxObj._input_IN = node_49.output_OUT;
  4037.  
  4038. xod__core__pulse_on_true::evaluate(&ctxObj);
  4039.  
  4040. // mark downstream nodes dirty
  4041. }
  4042. }
  4043. { // xod__core__pulse_on_true #57
  4044. if (node_57.isNodeDirty) {
  4045. XOD_TRACE_F("Eval node #");
  4046. XOD_TRACE_LN(57);
  4047.  
  4048. xod__core__pulse_on_true::ContextObject ctxObj;
  4049. ctxObj._node = &node_57;
  4050.  
  4051. // copy data from upstream nodes into context
  4052. ctxObj._input_IN = node_50.output_OUT;
  4053.  
  4054. xod__core__pulse_on_true::evaluate(&ctxObj);
  4055.  
  4056. // mark downstream nodes dirty
  4057. node_59.isNodeDirty |= node_57.isOutputDirty_OUT;
  4058. }
  4059. }
  4060. { // bitrex__xod_menu_system__concat_menu #58
  4061. if (node_58.isNodeDirty) {
  4062. XOD_TRACE_F("Eval node #");
  4063. XOD_TRACE_LN(58);
  4064.  
  4065. bitrex__xod_menu_system__concat_menu::ContextObject ctxObj;
  4066. ctxObj._node = &node_58;
  4067.  
  4068. // copy data from upstream nodes into context
  4069. ctxObj._input_IN1 = node_51.output_OUT;
  4070. ctxObj._input_IN2 = node_52.output_OUT;
  4071.  
  4072. bitrex__xod_menu_system__concat_menu::evaluate(&ctxObj);
  4073.  
  4074. // mark downstream nodes dirty
  4075. node_59.isNodeDirty |= node_58.isOutputDirty_OUT;
  4076. }
  4077. }
  4078. { // bitrex__xod_menu_system__menu_controller #59
  4079. if (node_59.isNodeDirty) {
  4080. XOD_TRACE_F("Eval node #");
  4081. XOD_TRACE_LN(59);
  4082.  
  4083. bitrex__xod_menu_system__menu_controller::ContextObject ctxObj;
  4084. ctxObj._node = &node_59;
  4085.  
  4086. // copy data from upstream nodes into context
  4087. ctxObj._input_MENU_TREE = node_58.output_OUT;
  4088. ctxObj._input_TITLE_1 = node_0.output_TXT;
  4089. ctxObj._input_TITLE_2 = node_2.output_TXT;
  4090. ctxObj._input_BACK = node_57.output_OUT;
  4091. ctxObj._input_INVOKE = node_55.output_OUT;
  4092. ctxObj._input_PARAM_IN = node_6_output_VAL;
  4093.  
  4094. ctxObj._isInputDirty_RIGHT = false;
  4095. ctxObj._isInputDirty_LEFT = false;
  4096. ctxObj._isInputDirty_TOP = false;
  4097. ctxObj._isInputDirty_BACK = node_57.isOutputDirty_OUT;
  4098. ctxObj._isInputDirty_INVOKE = node_55.isOutputDirty_OUT;
  4099.  
  4100. bitrex__xod_menu_system__menu_controller::evaluate(&ctxObj);
  4101.  
  4102. // mark downstream nodes dirty
  4103. node_60.isNodeDirty |= node_59.isOutputDirty_LINE1;
  4104. node_60.isNodeDirty |= node_59.isOutputDirty_LINE2;
  4105. }
  4106. }
  4107. { // xod__common_hardware__text_lcd_16x2 #60
  4108. if (node_60.isNodeDirty) {
  4109. XOD_TRACE_F("Eval node #");
  4110. XOD_TRACE_LN(60);
  4111.  
  4112. xod__common_hardware__text_lcd_16x2::ContextObject ctxObj;
  4113. ctxObj._node = &node_60;
  4114.  
  4115. // copy data from upstream nodes into context
  4116. ctxObj._input_RS = node_18_output_VAL;
  4117. ctxObj._input_EN = node_19_output_VAL;
  4118. ctxObj._input_D4 = node_20_output_VAL;
  4119. ctxObj._input_D5 = node_21_output_VAL;
  4120. ctxObj._input_D6 = node_22_output_VAL;
  4121. ctxObj._input_D7 = node_23_output_VAL;
  4122. ctxObj._input_L1 = node_59.output_LINE1;
  4123. ctxObj._input_L2 = node_59.output_LINE2;
  4124. ctxObj._input_UPD = node_29.output_TICK;
  4125.  
  4126. ctxObj._isInputDirty_UPD = node_29.isOutputDirty_TICK;
  4127.  
  4128. xod__common_hardware__text_lcd_16x2::evaluate(&ctxObj);
  4129.  
  4130. // mark downstream nodes dirty
  4131. }
  4132. }
  4133.  
  4134. // Clear dirtieness and timeouts for all nodes and pins
  4135. node_0.dirtyFlags = 0;
  4136. node_1.dirtyFlags = 0;
  4137. node_2.dirtyFlags = 0;
  4138. node_3.dirtyFlags = 0;
  4139. node_4.dirtyFlags = 0;
  4140. node_5.dirtyFlags = 0;
  4141. node_29.dirtyFlags = 0;
  4142. node_30.dirtyFlags = 0;
  4143. node_34.dirtyFlags = 0;
  4144. node_38.dirtyFlags = 0;
  4145. node_39.dirtyFlags = 0;
  4146. node_40.dirtyFlags = 0;
  4147. node_41.dirtyFlags = 0;
  4148. node_42.dirtyFlags = 0;
  4149. node_43.dirtyFlags = 0;
  4150. node_44.dirtyFlags = 0;
  4151. node_45.dirtyFlags = 0;
  4152. node_46.dirtyFlags = 0;
  4153. node_47.dirtyFlags = 0;
  4154. node_48.dirtyFlags = 0;
  4155. node_49.dirtyFlags = 0;
  4156. node_50.dirtyFlags = 0;
  4157. node_51.dirtyFlags = 0;
  4158. node_52.dirtyFlags = 0;
  4159. node_53.dirtyFlags = 0;
  4160. node_54.dirtyFlags = 0;
  4161. node_55.dirtyFlags = 0;
  4162. node_56.dirtyFlags = 0;
  4163. node_57.dirtyFlags = 0;
  4164. node_58.dirtyFlags = 0;
  4165. node_59.dirtyFlags = 0;
  4166. node_60.dirtyFlags = 0;
  4167. detail::clearStaleTimeout(&node_29);
  4168. detail::clearStaleTimeout(&node_38);
  4169. detail::clearStaleTimeout(&node_39);
  4170. detail::clearStaleTimeout(&node_41);
  4171. detail::clearStaleTimeout(&node_42);
  4172. detail::clearStaleTimeout(&node_46);
  4173. detail::clearStaleTimeout(&node_47);
  4174. detail::clearStaleTimeout(&node_48);
  4175. detail::clearStaleTimeout(&node_49);
  4176. detail::clearStaleTimeout(&node_50);
  4177.  
  4178. XOD_TRACE_F("Transaction completed, t=");
  4179. XOD_TRACE_LN(millis());
  4180. }
  4181.  
  4182. } // namespace xod
  4183.  
  4184.  
  4185. errors:
  4186. Arduino: 1.8.8 (Windows 10), TD: 1.45, Board: "Arduino Nano, ATmega328P"
  4187.  
  4188. sketch_mar07a:1336:23: error: '____menu_base' is not a namespace-name
  4189.  
  4190. namespace menu_base = ____menu_base;
  4191.  
  4192. ^
  4193.  
  4194. sketch_mar07a:1336:36: error: expected namespace-name before ';' token
  4195.  
  4196. namespace menu_base = ____menu_base;
  4197.  
  4198. ^
  4199.  
  4200. sketch_mar07a:1337:21: error: 'menu_base' does not name a type
  4201.  
  4202. using menu_base_t = menu_base::MenuBase;
  4203.  
  4204. ^
  4205.  
  4206. sketch_mar07a:1339:14: error: 'menu_base' does not name a type
  4207.  
  4208. using Type = menu_base::BiDirectionalList<menu_base_t*>;
  4209.  
  4210. ^
  4211.  
  4212. sketch_mar07a:1342:5: error: 'menu_base' does not name a type
  4213.  
  4214. menu_base::LeafMenuImpl<menu_base_t> leaf_menu;
  4215.  
  4216. ^
  4217.  
  4218. sketch_mar07a:1343:5: error: 'menu_base' does not name a type
  4219.  
  4220. menu_base::BiDirectionalPlainListView<menu_base_t*> leaf_menu_view =
  4221.  
  4222. ^
  4223.  
  4224. sketch_mar07a:1350:51: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4225.  
  4226. bitrex__xod_menu_system__leaf_menu_item_impl::Type output_OUT;
  4227.  
  4228. ^
  4229.  
  4230. sketch_mar07a:1379:99: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4231.  
  4232. template<> struct ValueType<output_OUT> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  4233.  
  4234. ^
  4235.  
  4236. sketch_mar07a:1414:58: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4237.  
  4238. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<output_OUT>(Context ctx) {
  4239.  
  4240. ^
  4241.  
  4242. sketch_mar07a:1437:98: error: 'xod::bitrex__xod_menu_system__leaf_menu_item_impl::Type' has not been declared
  4243.  
  4244. template<> void emitValue<output_OUT>(Context ctx, bitrex__xod_menu_system__leaf_menu_item_impl::Type val) {
  4245.  
  4246. ^
  4247.  
  4248. sketch_mar07a:1437:17: error: template-id 'emitValue<xod::bitrex__xod_menu_system__leaf_menu_item_impl::output_OUT>' for 'void xod::bitrex__xod_menu_system__leaf_menu_item_impl::emitValue(xod::bitrex__xod_menu_system__leaf_menu_item_impl::Context, int)' does not match any template declaration
  4249.  
  4250. template<> void emitValue<output_OUT>(Context ctx, bitrex__xod_menu_system__leaf_menu_item_impl::Type val) {
  4251.  
  4252. ^
  4253.  
  4254. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In function 'void xod::bitrex__xod_menu_system__leaf_menu_item_impl::evaluate(xod::bitrex__xod_menu_system__leaf_menu_item_impl::Context)':
  4255.  
  4256. sketch_mar07a:1461:15: error: 'menu_base' has not been declared
  4257.  
  4258. using menu_base::BiDirectionalPlainListView;
  4259.  
  4260. ^
  4261.  
  4262. sketch_mar07a:1462:15: error: 'menu_base' has not been declared
  4263.  
  4264. using menu_base::BiDirectionalList;
  4265.  
  4266. ^
  4267.  
  4268. sketch_mar07a:1463:15: error: 'menu_base' has not been declared
  4269.  
  4270. using menu_base::LeafMenuImpl;
  4271.  
  4272. ^
  4273.  
  4274. sketch_mar07a:1467:16: error: 'struct xod::bitrex__xod_menu_system__leaf_menu_item_impl::State' has no member named 'leaf_menu_view'
  4275.  
  4276. state->leaf_menu_view = menu_base::BiDirectionalPlainListView<menu_base_t*>(menu_base_p2p, 1);
  4277.  
  4278. ^
  4279.  
  4280. sketch_mar07a:1467:33: error: 'menu_base' has not been declared
  4281.  
  4282. state->leaf_menu_view = menu_base::BiDirectionalPlainListView<menu_base_t*>(menu_base_p2p, 1);
  4283.  
  4284. ^
  4285.  
  4286. sketch_mar07a:1467:71: error: 'menu_base_t' was not declared in this scope
  4287.  
  4288. state->leaf_menu_view = menu_base::BiDirectionalPlainListView<menu_base_t*>(menu_base_p2p, 1);
  4289.  
  4290. ^
  4291.  
  4292. sketch_mar07a:1467:83: error: expected primary-expression before '>' token
  4293.  
  4294. state->leaf_menu_view = menu_base::BiDirectionalPlainListView<menu_base_t*>(menu_base_p2p, 1);
  4295.  
  4296. ^
  4297.  
  4298. sketch_mar07a:1468:16: error: 'struct xod::bitrex__xod_menu_system__leaf_menu_item_impl::State' has no member named 'leaf_menu'
  4299.  
  4300. state->leaf_menu = LeafMenuImpl<menu_base_t>(line1, line2, user_id);
  4301.  
  4302. ^
  4303.  
  4304. sketch_mar07a:1468:28: error: 'LeafMenuImpl' was not declared in this scope
  4305.  
  4306. state->leaf_menu = LeafMenuImpl<menu_base_t>(line1, line2, user_id);
  4307.  
  4308. ^
  4309.  
  4310. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:1468:28: note: suggested alternative:
  4311.  
  4312. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:1274:20: note: 'xod::bitrex__xod_menu_system__menu_base::LeafMenuImpl'
  4313.  
  4314. class LeafMenuImpl final : public LeafMenuInterface<MenuBase, LeafMenuImpl>,
  4315.  
  4316. ^
  4317.  
  4318. sketch_mar07a:1469:34: error: 'struct xod::bitrex__xod_menu_system__leaf_menu_item_impl::State' has no member named 'leaf_menu'
  4319.  
  4320. *menu_base_p2p = &state->leaf_menu;
  4321.  
  4322. ^
  4323.  
  4324. sketch_mar07a:1470:37: error: 'menu_base' has not been declared
  4325.  
  4326. emitValue<output_OUT>(ctx, menu_base::BiDirectionalList<menu_base_t*>(&state->leaf_menu_view));
  4327.  
  4328. ^
  4329.  
  4330. sketch_mar07a:1470:78: error: expected primary-expression before '>' token
  4331.  
  4332. emitValue<output_OUT>(ctx, menu_base::BiDirectionalList<menu_base_t*>(&state->leaf_menu_view));
  4333.  
  4334. ^
  4335.  
  4336. sketch_mar07a:1470:88: error: 'struct xod::bitrex__xod_menu_system__leaf_menu_item_impl::State' has no member named 'leaf_menu_view'
  4337.  
  4338. emitValue<output_OUT>(ctx, menu_base::BiDirectionalList<menu_base_t*>(&state->leaf_menu_view));
  4339.  
  4340. ^
  4341.  
  4342. sketch_mar07a:1475:38: error: 'struct xod::bitrex__xod_menu_system__leaf_menu_item_impl::State' has no member named 'leaf_menu_view'
  4343.  
  4344. auto menu_base_ptr = *state->leaf_menu_view.iterate();
  4345.  
  4346. ^
  4347.  
  4348. sketch_mar07a:1476:16: error: 'struct xod::bitrex__xod_menu_system__leaf_menu_item_impl::State' has no member named 'leaf_menu'
  4349.  
  4350. state->leaf_menu.set_text(line1, line2);
  4351.  
  4352. ^
  4353.  
  4354. sketch_mar07a:1478:31: error: 'struct xod::bitrex__xod_menu_system__leaf_menu_item_impl::State' has no member named 'leaf_menu'
  4355.  
  4356. auto invoked = state->leaf_menu.update(&out);
  4357.  
  4358. ^
  4359.  
  4360. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: At global scope:
  4361.  
  4362. sketch_mar07a:1993:23: error: '____menu_base' is not a namespace-name
  4363.  
  4364. namespace menu_base = ____menu_base;
  4365.  
  4366. ^
  4367.  
  4368. sketch_mar07a:1993:36: error: expected namespace-name before ';' token
  4369.  
  4370. namespace menu_base = ____menu_base;
  4371.  
  4372. ^
  4373.  
  4374. sketch_mar07a:1994:21: error: 'menu_base' does not name a type
  4375.  
  4376. using menu_base_t = menu_base::MenuBase;
  4377.  
  4378. ^
  4379.  
  4380. sketch_mar07a:2002:44: error: 'menu_base' has not been declared
  4381.  
  4382. class BiDirectionalConcatListView : public menu_base::BiDirectionalListView<T> {
  4383.  
  4384. ^
  4385.  
  4386. sketch_mar07a:2002:55: error: expected '{' before 'BiDirectionalListView'
  4387.  
  4388. class BiDirectionalConcatListView : public menu_base::BiDirectionalListView<T> {
  4389.  
  4390. ^
  4391.  
  4392. sketch_mar07a:2002:76: error: expected initializer before '<' token
  4393.  
  4394. class BiDirectionalConcatListView : public menu_base::BiDirectionalListView<T> {
  4395.  
  4396. ^
  4397.  
  4398. sketch_mar07a:2087:33: error: 'menu_base_t' was not declared in this scope
  4399.  
  4400. BiDirectionalConcatListView<menu_base_t*> menu_ptr_list_view;
  4401.  
  4402. ^
  4403.  
  4404. sketch_mar07a:2087:45: error: template argument 1 is invalid
  4405.  
  4406. BiDirectionalConcatListView<menu_base_t*> menu_ptr_list_view;
  4407.  
  4408. ^
  4409.  
  4410. sketch_mar07a:2092:51: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4411.  
  4412. bitrex__xod_menu_system__leaf_menu_item_impl::Type output_OUT;
  4413.  
  4414. ^
  4415.  
  4416. sketch_mar07a:2109:98: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4417.  
  4418. template<> struct ValueType<input_IN1> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  4419.  
  4420. ^
  4421.  
  4422. sketch_mar07a:2110:98: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4423.  
  4424. template<> struct ValueType<input_IN2> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  4425.  
  4426. ^
  4427.  
  4428. sketch_mar07a:2111:99: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4429.  
  4430. template<> struct ValueType<output_OUT> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  4431.  
  4432. ^
  4433.  
  4434. sketch_mar07a:2116:51: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4435.  
  4436. bitrex__xod_menu_system__leaf_menu_item_impl::Type _input_IN1;
  4437.  
  4438. ^
  4439.  
  4440. sketch_mar07a:2117:51: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4441.  
  4442. bitrex__xod_menu_system__leaf_menu_item_impl::Type _input_IN2;
  4443.  
  4444. ^
  4445.  
  4446. sketch_mar07a:2130:58: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4447.  
  4448. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<input_IN1>(Context ctx) {
  4449.  
  4450. ^
  4451.  
  4452. sketch_mar07a:2133:58: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4453.  
  4454. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<input_IN2>(Context ctx) {
  4455.  
  4456. ^
  4457.  
  4458. sketch_mar07a:2136:58: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4459.  
  4460. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<output_OUT>(Context ctx) {
  4461.  
  4462. ^
  4463.  
  4464. sketch_mar07a:2153:98: error: 'xod::bitrex__xod_menu_system__leaf_menu_item_impl::Type' has not been declared
  4465.  
  4466. template<> void emitValue<output_OUT>(Context ctx, bitrex__xod_menu_system__leaf_menu_item_impl::Type val) {
  4467.  
  4468. ^
  4469.  
  4470. sketch_mar07a:2153:17: error: template-id 'emitValue<xod::bitrex__xod_menu_system__concat_menu::output_OUT>' for 'void xod::bitrex__xod_menu_system__concat_menu::emitValue(xod::bitrex__xod_menu_system__concat_menu::Context, int)' does not match any template declaration
  4471.  
  4472. template<> void emitValue<output_OUT>(Context ctx, bitrex__xod_menu_system__leaf_menu_item_impl::Type val) {
  4473.  
  4474. ^
  4475.  
  4476. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In function 'void xod::bitrex__xod_menu_system__concat_menu::evaluate(xod::bitrex__xod_menu_system__concat_menu::Context)':
  4477.  
  4478. sketch_mar07a:2164:15: error: 'menu_base' has not been declared
  4479.  
  4480. using menu_base::BiDirectionalList;
  4481.  
  4482. ^
  4483.  
  4484. sketch_mar07a:2166:49: error: no matching function for call to 'getValue(xod::bitrex__xod_menu_system__concat_menu::ContextObject*&)'
  4485.  
  4486. const auto in1 = getValue<input_IN1>(ctx);
  4487.  
  4488. ^
  4489.  
  4490. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2123:53: note: candidate: template<class PinT> typename xod::bitrex__xod_menu_system__concat_menu::ValueType<PinT>::T xod::bitrex__xod_menu_system__concat_menu::getValue(xod::bitrex__xod_menu_system__concat_menu::Context)
  4491.  
  4492. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  4493.  
  4494. ^
  4495.  
  4496. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2123:53: note: template argument deduction/substitution failed:
  4497.  
  4498. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In substitution of 'template<class PinT> typename xod::bitrex__xod_menu_system__concat_menu::ValueType<PinT>::T xod::bitrex__xod_menu_system__concat_menu::getValue(xod::bitrex__xod_menu_system__concat_menu::Context) [with PinT = xod::bitrex__xod_menu_system__concat_menu::input_IN1]':
  4499.  
  4500. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2166:49: required from here
  4501.  
  4502. sketch_mar07a:2123:53: error: no type named 'T' in 'struct xod::bitrex__xod_menu_system__concat_menu::ValueType<xod::bitrex__xod_menu_system__concat_menu::input_IN1>'
  4503.  
  4504. sketch_mar07a:2167:49: error: no matching function for call to 'getValue(xod::bitrex__xod_menu_system__concat_menu::ContextObject*&)'
  4505.  
  4506. const auto in2 = getValue<input_IN2>(ctx);
  4507.  
  4508. ^
  4509.  
  4510. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2123:53: note: candidate: template<class PinT> typename xod::bitrex__xod_menu_system__concat_menu::ValueType<PinT>::T xod::bitrex__xod_menu_system__concat_menu::getValue(xod::bitrex__xod_menu_system__concat_menu::Context)
  4511.  
  4512. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  4513.  
  4514. ^
  4515.  
  4516. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2123:53: note: template argument deduction/substitution failed:
  4517.  
  4518. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In substitution of 'template<class PinT> typename xod::bitrex__xod_menu_system__concat_menu::ValueType<PinT>::T xod::bitrex__xod_menu_system__concat_menu::getValue(xod::bitrex__xod_menu_system__concat_menu::Context) [with PinT = xod::bitrex__xod_menu_system__concat_menu::input_IN2]':
  4519.  
  4520. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2167:49: required from here
  4521.  
  4522. sketch_mar07a:2123:53: error: no type named 'T' in 'struct xod::bitrex__xod_menu_system__concat_menu::ValueType<xod::bitrex__xod_menu_system__concat_menu::input_IN2>'
  4523.  
  4524. sketch_mar07a:2170:65: error: 'menu_base_t' was not declared in this scope
  4525.  
  4526. state->menu_ptr_list_view = BiDirectionalConcatListView<menu_base_t*>(in1, in2);
  4527.  
  4528. ^
  4529.  
  4530. sketch_mar07a:2170:77: error: template argument 1 is invalid
  4531.  
  4532. state->menu_ptr_list_view = BiDirectionalConcatListView<menu_base_t*>(in1, in2);
  4533.  
  4534. ^
  4535.  
  4536. sketch_mar07a:2172:36: error: 'BiDirectionalList' was not declared in this scope
  4537.  
  4538. emitValue<output_OUT>(ctx, BiDirectionalList<menu_base_t*>(&state->menu_ptr_list_view));
  4539.  
  4540. ^
  4541.  
  4542. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2172:36: note: suggested alternative:
  4543.  
  4544. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:1028:7: note: 'xod::bitrex__xod_menu_system__menu_base::BiDirectionalList'
  4545.  
  4546. class BiDirectionalList : public List<T> {
  4547.  
  4548. ^
  4549.  
  4550. sketch_mar07a:2172:66: error: expected primary-expression before '>' token
  4551.  
  4552. emitValue<output_OUT>(ctx, BiDirectionalList<menu_base_t*>(&state->menu_ptr_list_view));
  4553.  
  4554. ^
  4555.  
  4556. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: At global scope:
  4557.  
  4558. sketch_mar07a:2286:23: error: '____menu_base' is not a namespace-name
  4559.  
  4560. namespace menu_base = ____menu_base;
  4561.  
  4562. ^
  4563.  
  4564. sketch_mar07a:2286:36: error: expected namespace-name before ';' token
  4565.  
  4566. namespace menu_base = ____menu_base;
  4567.  
  4568. ^
  4569.  
  4570. sketch_mar07a:2287:21: error: 'menu_base' does not name a type
  4571.  
  4572. using menu_base_t = menu_base::MenuBase;
  4573.  
  4574. ^
  4575.  
  4576. sketch_mar07a:2298:28: error: 'menu_base' has not been declared
  4577.  
  4578. explicit SubMenuIterator(menu_base::BiDirectionalList<MenuBase*> sub_menus) :
  4579.  
  4580. ^
  4581.  
  4582. sketch_mar07a:2298:56: error: expected ')' before '<' token
  4583.  
  4584. explicit SubMenuIterator(menu_base::BiDirectionalList<MenuBase*> sub_menus) :
  4585.  
  4586. ^
  4587.  
  4588. sketch_mar07a:2301:3: error: 'menu_base' does not name a type
  4589.  
  4590. menu_base::BiDirectionalList<MenuBase*> menu_ptr_list() const {
  4591.  
  4592. ^
  4593.  
  4594. sketch_mar07a:2326:5: error: 'menu_base' does not name a type
  4595.  
  4596. menu_base::BiDirectionalList<MenuBase*> sub_menu_ptr_list_;
  4597.  
  4598. ^
  4599.  
  4600. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In member function 'MenuBase* xod::bitrex__xod_menu_system__branch_menu_item::SubMenuIterator<MenuBase>::current_menu_ptr()':
  4601.  
  4602. sketch_mar07a:2316:15: error: 'sub_menu_ptr_list_' was not declared in this scope
  4603.  
  4604. auto it = sub_menu_ptr_list_.iterate();
  4605.  
  4606. ^
  4607.  
  4608. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: At global scope:
  4609.  
  4610. sketch_mar07a:2337:36: error: 'menu_base' has not been declared
  4611.  
  4612. class BranchMenuInterface : public menu_base::MenuInterface<MenuBase, BranchMenuImpl> {
  4613.  
  4614. ^
  4615.  
  4616. sketch_mar07a:2337:47: error: expected '{' before 'MenuInterface'
  4617.  
  4618. class BranchMenuInterface : public menu_base::MenuInterface<MenuBase, BranchMenuImpl> {
  4619.  
  4620. ^
  4621.  
  4622. sketch_mar07a:2337:60: error: expected initializer before '<' token
  4623.  
  4624. class BranchMenuInterface : public menu_base::MenuInterface<MenuBase, BranchMenuImpl> {
  4625.  
  4626. ^
  4627.  
  4628. sketch_mar07a:2367:16: error: 'menu_base' has not been declared
  4629.  
  4630. friend class menu_base::MenuInterface<MenuBase, BranchMenuImpl>;
  4631.  
  4632. ^
  4633.  
  4634. sketch_mar07a:2367:40: error: expected unqualified-id before '<' token
  4635.  
  4636. friend class menu_base::MenuInterface<MenuBase, BranchMenuImpl>;
  4637.  
  4638. ^
  4639.  
  4640. sketch_mar07a:2375:18: error: 'menu_base' has not been declared
  4641.  
  4642. BranchMenuImpl(menu_base::BiDirectionalList<MenuBase*> sub_menu_ptr_list,
  4643.  
  4644. ^
  4645.  
  4646. sketch_mar07a:2375:46: error: expected ')' before '<' token
  4647.  
  4648. BranchMenuImpl(menu_base::BiDirectionalList<MenuBase*> sub_menu_ptr_list,
  4649.  
  4650. ^
  4651.  
  4652. sketch_mar07a:2378:46: error: expected unqualified-id before ')' token
  4653.  
  4654. menu_text_({menu_text_1, menu_text_2}),
  4655.  
  4656. ^
  4657.  
  4658. sketch_mar07a:2429:18: error: 'menu_base_t' was not declared in this scope
  4659.  
  4660. BranchMenuImpl<menu_base_t> branch_menu;
  4661.  
  4662. ^
  4663.  
  4664. sketch_mar07a:2429:29: error: template argument 1 is invalid
  4665.  
  4666. BranchMenuImpl<menu_base_t> branch_menu;
  4667.  
  4668. ^
  4669.  
  4670. sketch_mar07a:2430:3: error: 'menu_base_t' does not name a type
  4671.  
  4672. menu_base_t* branch_menu_ptr;
  4673.  
  4674. ^
  4675.  
  4676. sketch_mar07a:2431:3: error: 'menu_base' does not name a type
  4677.  
  4678. menu_base::BiDirectionalPlainListView<menu_base_t*> branch_menu_ptr_view =
  4679.  
  4680. ^
  4681.  
  4682. sketch_mar07a:2437:51: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4683.  
  4684. bitrex__xod_menu_system__leaf_menu_item_impl::Type output_OUT;
  4685.  
  4686. ^
  4687.  
  4688. sketch_mar07a:2456:97: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4689.  
  4690. template<> struct ValueType<input_IN> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  4691.  
  4692. ^
  4693.  
  4694. sketch_mar07a:2460:99: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4695.  
  4696. template<> struct ValueType<output_OUT> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  4697.  
  4698. ^
  4699.  
  4700. sketch_mar07a:2465:51: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4701.  
  4702. bitrex__xod_menu_system__leaf_menu_item_impl::Type _input_IN;
  4703.  
  4704. ^
  4705.  
  4706. sketch_mar07a:2481:58: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4707.  
  4708. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<input_IN>(Context ctx) {
  4709.  
  4710. ^
  4711.  
  4712. sketch_mar07a:2493:58: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4713.  
  4714. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<output_OUT>(Context ctx) {
  4715.  
  4716. ^
  4717.  
  4718. sketch_mar07a:2510:98: error: 'xod::bitrex__xod_menu_system__leaf_menu_item_impl::Type' has not been declared
  4719.  
  4720. template<> void emitValue<output_OUT>(Context ctx, bitrex__xod_menu_system__leaf_menu_item_impl::Type val) {
  4721.  
  4722. ^
  4723.  
  4724. sketch_mar07a:2510:17: error: template-id 'emitValue<xod::bitrex__xod_menu_system__branch_menu_item::output_OUT>' for 'void xod::bitrex__xod_menu_system__branch_menu_item::emitValue(xod::bitrex__xod_menu_system__branch_menu_item::Context, int)' does not match any template declaration
  4725.  
  4726. template<> void emitValue<output_OUT>(Context ctx, bitrex__xod_menu_system__leaf_menu_item_impl::Type val) {
  4727.  
  4728. ^
  4729.  
  4730. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In function 'void xod::bitrex__xod_menu_system__branch_menu_item::evaluate(xod::bitrex__xod_menu_system__branch_menu_item::Context)':
  4731.  
  4732. sketch_mar07a:2521:11: error: 'menu_base' has not been declared
  4733.  
  4734. using menu_base::BiDirectionalList;
  4735.  
  4736. ^
  4737.  
  4738. sketch_mar07a:2523:37: error: no matching function for call to 'getValue(xod::bitrex__xod_menu_system__branch_menu_item::ContextObject*&)'
  4739.  
  4740. auto in = getValue<input_IN>(ctx);
  4741.  
  4742. ^
  4743.  
  4744. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2474:53: note: candidate: template<class PinT> typename xod::bitrex__xod_menu_system__branch_menu_item::ValueType<PinT>::T xod::bitrex__xod_menu_system__branch_menu_item::getValue(xod::bitrex__xod_menu_system__branch_menu_item::Context)
  4745.  
  4746. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  4747.  
  4748. ^
  4749.  
  4750. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2474:53: note: template argument deduction/substitution failed:
  4751.  
  4752. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In substitution of 'template<class PinT> typename xod::bitrex__xod_menu_system__branch_menu_item::ValueType<PinT>::T xod::bitrex__xod_menu_system__branch_menu_item::getValue(xod::bitrex__xod_menu_system__branch_menu_item::Context) [with PinT = xod::bitrex__xod_menu_system__branch_menu_item::input_IN]':
  4753.  
  4754. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2523:37: required from here
  4755.  
  4756. sketch_mar07a:2474:53: error: no type named 'T' in 'struct xod::bitrex__xod_menu_system__branch_menu_item::ValueType<xod::bitrex__xod_menu_system__branch_menu_item::input_IN>'
  4757.  
  4758. sketch_mar07a:2527:41: error: 'menu_base_t' was not declared in this scope
  4759.  
  4760. state->branch_menu = BranchMenuImpl<menu_base_t>(in, text1, text2, id);
  4761.  
  4762. ^
  4763.  
  4764. sketch_mar07a:2527:52: error: template argument 1 is invalid
  4765.  
  4766. state->branch_menu = BranchMenuImpl<menu_base_t>(in, text1, text2, id);
  4767.  
  4768. ^
  4769.  
  4770. sketch_mar07a:2528:12: error: 'struct xod::bitrex__xod_menu_system__branch_menu_item::State' has no member named 'branch_menu_ptr'
  4771.  
  4772. state->branch_menu_ptr = &state->branch_menu;
  4773.  
  4774. ^
  4775.  
  4776. sketch_mar07a:2529:32: error: 'menu_base' has not been declared
  4777.  
  4778. emitValue<output_OUT>(ctx, menu_base::BiDirectionalList<menu_base_t*>(&state->branch_menu_ptr_view));
  4779.  
  4780. ^
  4781.  
  4782. sketch_mar07a:2529:73: error: expected primary-expression before '>' token
  4783.  
  4784. emitValue<output_OUT>(ctx, menu_base::BiDirectionalList<menu_base_t*>(&state->branch_menu_ptr_view));
  4785.  
  4786. ^
  4787.  
  4788. sketch_mar07a:2529:83: error: 'struct xod::bitrex__xod_menu_system__branch_menu_item::State' has no member named 'branch_menu_ptr_view'
  4789.  
  4790. emitValue<output_OUT>(ctx, menu_base::BiDirectionalList<menu_base_t*>(&state->branch_menu_ptr_view));
  4791.  
  4792. ^
  4793.  
  4794. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: At global scope:
  4795.  
  4796. sketch_mar07a:2629:23: error: '____menu_base' is not a namespace-name
  4797.  
  4798. namespace menu_base = ____menu_base;
  4799.  
  4800. ^
  4801.  
  4802. sketch_mar07a:2629:36: error: expected namespace-name before ';' token
  4803.  
  4804. namespace menu_base = ____menu_base;
  4805.  
  4806. ^
  4807.  
  4808. sketch_mar07a:2630:21: error: 'menu_base' does not name a type
  4809.  
  4810. using menu_base_t = menu_base::MenuBase;
  4811.  
  4812. ^
  4813.  
  4814. sketch_mar07a:2631:30: error: '____branch_menu_item' is not a namespace-name
  4815.  
  4816. namespace branch_menu_item = ____branch_menu_item;
  4817.  
  4818. ^
  4819.  
  4820. sketch_mar07a:2631:50: error: expected namespace-name before ';' token
  4821.  
  4822. namespace branch_menu_item = ____branch_menu_item;
  4823.  
  4824. ^
  4825.  
  4826. sketch_mar07a:2644:23: error: 'branch_menu_item' has not been declared
  4827.  
  4828. explicit MenuCursor(branch_menu_item::BranchMenuImpl<MenuBase>* top_menu)
  4829.  
  4830. ^
  4831.  
  4832. sketch_mar07a:2644:55: error: expected ')' before '<' token
  4833.  
  4834. explicit MenuCursor(branch_menu_item::BranchMenuImpl<MenuBase>* top_menu)
  4835.  
  4836. ^
  4837.  
  4838. sketch_mar07a:2687:3: error: 'branch_menu_item' does not name a type
  4839.  
  4840. branch_menu_item::BranchMenuImpl<MenuBase>* top_menu_ptr_ = nullptr;
  4841.  
  4842. ^
  4843.  
  4844. sketch_mar07a:2688:3: error: 'branch_menu_item' does not name a type
  4845.  
  4846. branch_menu_item::BranchMenuImpl<MenuBase>* current_root_menu_ptr_ = nullptr;
  4847.  
  4848. ^
  4849.  
  4850. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In member function 'void xod::bitrex__xod_menu_system__menu_controller::MenuCursor<MenuBase>::back()':
  4851.  
  4852. sketch_mar07a:2650:23: error: 'current_root_menu_ptr_' was not declared in this scope
  4853.  
  4854. auto parent_ptr = current_root_menu_ptr_->parent();
  4855.  
  4856. ^
  4857.  
  4858. sketch_mar07a:2651:47: error: 'top_menu_ptr_' was not declared in this scope
  4859.  
  4860. if (parent_ptr && current_sub_menu_ptr_!= top_menu_ptr_) {
  4861.  
  4862. ^
  4863.  
  4864. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In member function 'void xod::bitrex__xod_menu_system__menu_controller::MenuCursor<MenuBase>::left()':
  4865.  
  4866. sketch_mar07a:2661:9: error: 'current_root_menu_ptr_' was not declared in this scope
  4867.  
  4868. if (current_root_menu_ptr_) {
  4869.  
  4870. ^
  4871.  
  4872. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In member function 'void xod::bitrex__xod_menu_system__menu_controller::MenuCursor<MenuBase>::right()':
  4873.  
  4874. sketch_mar07a:2667:9: error: 'current_root_menu_ptr_' was not declared in this scope
  4875.  
  4876. if (current_root_menu_ptr_) {
  4877.  
  4878. ^
  4879.  
  4880. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In member function 'void xod::bitrex__xod_menu_system__menu_controller::MenuCursor<MenuBase>::invoke(xod::Number)':
  4881.  
  4882. sketch_mar07a:2675:30: error: 'current_root_menu_ptr_' was not declared in this scope
  4883.  
  4884. auto prev_root_menu_ = current_root_menu_ptr_;
  4885.  
  4886. ^
  4887.  
  4888. sketch_mar07a:2677:23: error: 'branch_menu_item' does not name a type
  4889.  
  4890. static_cast<branch_menu_item::BranchMenuImpl<MenuBase>*>(
  4891.  
  4892. ^
  4893.  
  4894. sketch_mar07a:2677:39: error: expected '>' before '::' token
  4895.  
  4896. static_cast<branch_menu_item::BranchMenuImpl<MenuBase>*>(
  4897.  
  4898. ^
  4899.  
  4900. sketch_mar07a:2677:39: error: expected '(' before '::' token
  4901.  
  4902. sketch_mar07a:2677:39: error: '::BranchMenuImpl' has not been declared
  4903.  
  4904. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2677:39: note: suggested alternative:
  4905.  
  4906. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2364:22: note: 'xod::bitrex__xod_menu_system__branch_menu_item::BranchMenuImpl'
  4907.  
  4908. class BranchMenuImpl final
  4909.  
  4910. ^
  4911.  
  4912. sketch_mar07a:2677:64: error: expected primary-expression before '>' token
  4913.  
  4914. static_cast<branch_menu_item::BranchMenuImpl<MenuBase>*>(
  4915.  
  4916. ^
  4917.  
  4918. sketch_mar07a:2677:66: error: expected primary-expression before '>' token
  4919.  
  4920. static_cast<branch_menu_item::BranchMenuImpl<MenuBase>*>(
  4921.  
  4922. ^
  4923.  
  4924. sketch_mar07a:2678:24: error: expected ')' before ';' token
  4925.  
  4926. menu_ptr);
  4927.  
  4928. ^
  4929.  
  4930. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: At global scope:
  4931.  
  4932. sketch_mar07a:2696:14: error: 'menu_base_t' was not declared in this scope
  4933.  
  4934. MenuCursor<menu_base_t> menu_cursor;
  4935.  
  4936. ^
  4937.  
  4938. sketch_mar07a:2696:25: error: template argument 1 is invalid
  4939.  
  4940. MenuCursor<menu_base_t> menu_cursor;
  4941.  
  4942. ^
  4943.  
  4944. sketch_mar07a:2697:3: error: 'branch_menu_item' does not name a type
  4945.  
  4946. branch_menu_item::BranchMenuImpl<menu_base_t> root_menu;
  4947.  
  4948. ^
  4949.  
  4950. sketch_mar07a:2735:104: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4951.  
  4952. template<> struct ValueType<input_MENU_TREE> { using T = bitrex__xod_menu_system__leaf_menu_item_impl::Type; };
  4953.  
  4954. ^
  4955.  
  4956. sketch_mar07a:2752:51: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4957.  
  4958. bitrex__xod_menu_system__leaf_menu_item_impl::Type _input_MENU_TREE;
  4959.  
  4960. ^
  4961.  
  4962. sketch_mar07a:2778:58: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  4963.  
  4964. template<> bitrex__xod_menu_system__leaf_menu_item_impl::Type getValue<input_MENU_TREE>(Context ctx) {
  4965.  
  4966. ^
  4967.  
  4968. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In function 'void xod::bitrex__xod_menu_system__menu_controller::evaluate(xod::bitrex__xod_menu_system__menu_controller::Context)':
  4969.  
  4970. sketch_mar07a:2876:12: error: 'struct xod::bitrex__xod_menu_system__menu_controller::State' has no member named 'root_menu'
  4971.  
  4972. state->root_menu =
  4973.  
  4974. ^
  4975.  
  4976. sketch_mar07a:2877:5: error: 'branch_menu_item' has not been declared
  4977.  
  4978. branch_menu_item::BranchMenuImpl<menu_base_t>(getValue<input_MENU_TREE>(ctx), title_1,
  4979.  
  4980. ^
  4981.  
  4982. sketch_mar07a:2877:38: error: 'menu_base_t' was not declared in this scope
  4983.  
  4984. branch_menu_item::BranchMenuImpl<menu_base_t>(getValue<input_MENU_TREE>(ctx), title_1,
  4985.  
  4986. ^
  4987.  
  4988. sketch_mar07a:2877:80: error: no matching function for call to 'getValue(xod::bitrex__xod_menu_system__menu_controller::ContextObject*&)'
  4989.  
  4990. branch_menu_item::BranchMenuImpl<menu_base_t>(getValue<input_MENU_TREE>(ctx), title_1,
  4991.  
  4992. ^
  4993.  
  4994. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2771:53: note: candidate: template<class PinT> typename xod::bitrex__xod_menu_system__menu_controller::ValueType<PinT>::T xod::bitrex__xod_menu_system__menu_controller::getValue(xod::bitrex__xod_menu_system__menu_controller::Context)
  4995.  
  4996. template<typename PinT> typename ValueType<PinT>::T getValue(Context ctx) {
  4997.  
  4998. ^
  4999.  
  5000. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2771:53: note: template argument deduction/substitution failed:
  5001.  
  5002. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In substitution of 'template<class PinT> typename xod::bitrex__xod_menu_system__menu_controller::ValueType<PinT>::T xod::bitrex__xod_menu_system__menu_controller::getValue(xod::bitrex__xod_menu_system__menu_controller::Context) [with PinT = xod::bitrex__xod_menu_system__menu_controller::input_MENU_TREE]':
  5003.  
  5004. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2877:80: required from here
  5005.  
  5006. sketch_mar07a:2771:53: error: no type named 'T' in 'struct xod::bitrex__xod_menu_system__menu_controller::ValueType<xod::bitrex__xod_menu_system__menu_controller::input_MENU_TREE>'
  5007.  
  5008. sketch_mar07a:2879:12: error: 'struct xod::bitrex__xod_menu_system__menu_controller::State' has no member named 'root_menu'
  5009.  
  5010. state->root_menu.set_parent(&state->root_menu);
  5011.  
  5012. ^
  5013.  
  5014. sketch_mar07a:2879:41: error: 'struct xod::bitrex__xod_menu_system__menu_controller::State' has no member named 'root_menu'
  5015.  
  5016. state->root_menu.set_parent(&state->root_menu);
  5017.  
  5018. ^
  5019.  
  5020. sketch_mar07a:2880:37: error: the value of 'menu_base_t' is not usable in a constant expression
  5021.  
  5022. state->menu_cursor = MenuCursor<menu_base_t>(&state->root_menu);
  5023.  
  5024. ^
  5025.  
  5026. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2877:38: note: 'menu_base_t' was not declared 'constexpr'
  5027.  
  5028. branch_menu_item::BranchMenuImpl<menu_base_t>(getValue<input_MENU_TREE>(ctx), title_1,
  5029.  
  5030. ^
  5031.  
  5032. sketch_mar07a:2880:48: error: type/value mismatch at argument 1 in template parameter list for 'template<class MenuBase> class xod::bitrex__xod_menu_system__menu_controller::MenuCursor'
  5033.  
  5034. state->menu_cursor = MenuCursor<menu_base_t>(&state->root_menu);
  5035.  
  5036. ^
  5037.  
  5038. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino:2880:48: note: expected a type, got 'menu_base_t'
  5039.  
  5040. sketch_mar07a:2880:58: error: 'struct xod::bitrex__xod_menu_system__menu_controller::State' has no member named 'root_menu'
  5041.  
  5042. state->menu_cursor = MenuCursor<menu_base_t>(&state->root_menu);
  5043.  
  5044. ^
  5045.  
  5046. sketch_mar07a:2891:24: error: request for member 'back' in 'state->xod::bitrex__xod_menu_system__menu_controller::State::menu_cursor', which is of non-class type 'int'
  5047.  
  5048. state->menu_cursor.back();
  5049.  
  5050. ^
  5051.  
  5052. sketch_mar07a:2894:24: error: request for member 'left' in 'state->xod::bitrex__xod_menu_system__menu_controller::State::menu_cursor', which is of non-class type 'int'
  5053.  
  5054. state->menu_cursor.left();
  5055.  
  5056. ^
  5057.  
  5058. sketch_mar07a:2897:24: error: request for member 'right' in 'state->xod::bitrex__xod_menu_system__menu_controller::State::menu_cursor', which is of non-class type 'int'
  5059.  
  5060. state->menu_cursor.right();
  5061.  
  5062. ^
  5063.  
  5064. sketch_mar07a:2903:24: error: request for member 'invoke' in 'state->xod::bitrex__xod_menu_system__menu_controller::State::menu_cursor', which is of non-class type 'int'
  5065.  
  5066. state->menu_cursor.invoke(param);
  5067.  
  5068. ^
  5069.  
  5070. sketch_mar07a:2908:39: error: request for member 'text' in 'state->xod::bitrex__xod_menu_system__menu_controller::State::menu_cursor', which is of non-class type 'int'
  5071.  
  5072. auto text_list = state->menu_cursor.text();
  5073.  
  5074. ^
  5075.  
  5076. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: At global scope:
  5077.  
  5078. sketch_mar07a:3199:57: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  5079.  
  5080. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_38_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  5081.  
  5082. ^
  5083.  
  5084. sketch_mar07a:3203:57: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  5085.  
  5086. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_39_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  5087.  
  5088. ^
  5089.  
  5090. sketch_mar07a:3211:57: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  5091.  
  5092. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_41_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  5093.  
  5094. ^
  5095.  
  5096. sketch_mar07a:3215:57: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  5097.  
  5098. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_42_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  5099.  
  5100. ^
  5101.  
  5102. sketch_mar07a:3225:57: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  5103.  
  5104. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_44_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  5105.  
  5106. ^
  5107.  
  5108. sketch_mar07a:3227:57: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  5109.  
  5110. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_45_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  5111.  
  5112. ^
  5113.  
  5114. sketch_mar07a:3239:57: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  5115.  
  5116. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_51_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  5117.  
  5118. ^
  5119.  
  5120. sketch_mar07a:3241:57: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  5121.  
  5122. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_52_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  5123.  
  5124. ^
  5125.  
  5126. sketch_mar07a:3253:57: error: 'Type' in namespace 'xod::bitrex__xod_menu_system__leaf_menu_item_impl' does not name a type
  5127.  
  5128. constexpr bitrex__xod_menu_system__leaf_menu_item_impl::Type node_58_output_OUT = { /* bitrex/xod-menu-system/leaf-menu-item-impl */ };
  5129.  
  5130. ^
  5131.  
  5132. sketch_mar07a:3322:5: error: 'node_38_output_OUT' was not declared in this scope
  5133.  
  5134. node_38_output_OUT, // output OUT default
  5135.  
  5136. ^
  5137.  
  5138. sketch_mar07a:3333:5: error: 'node_39_output_OUT' was not declared in this scope
  5139.  
  5140. node_39_output_OUT, // output OUT default
  5141.  
  5142. ^
  5143.  
  5144. sketch_mar07a:3354:5: error: 'node_41_output_OUT' was not declared in this scope
  5145.  
  5146. node_41_output_OUT, // output OUT default
  5147.  
  5148. ^
  5149.  
  5150. sketch_mar07a:3365:5: error: 'node_42_output_OUT' was not declared in this scope
  5151.  
  5152. node_42_output_OUT, // output OUT default
  5153.  
  5154. ^
  5155.  
  5156. sketch_mar07a:3389:5: error: 'node_44_output_OUT' was not declared in this scope
  5157.  
  5158. node_44_output_OUT, // output OUT default
  5159.  
  5160. ^
  5161.  
  5162. sketch_mar07a:3395:5: error: 'node_45_output_OUT' was not declared in this scope
  5163.  
  5164. node_45_output_OUT, // output OUT default
  5165.  
  5166. ^
  5167.  
  5168. sketch_mar07a:3436:5: error: 'node_51_output_OUT' was not declared in this scope
  5169.  
  5170. node_51_output_OUT, // output OUT default
  5171.  
  5172. ^
  5173.  
  5174. sketch_mar07a:3442:5: error: 'node_52_output_OUT' was not declared in this scope
  5175.  
  5176. node_52_output_OUT, // output OUT default
  5177.  
  5178. ^
  5179.  
  5180. sketch_mar07a:3478:5: error: 'node_58_output_OUT' was not declared in this scope
  5181.  
  5182. node_58_output_OUT, // output OUT default
  5183.  
  5184. ^
  5185.  
  5186. C:\Users\taran\Documents\Arduino\sketch_mar07a\sketch_mar07a.ino: In function 'void xod::runTransaction()':
  5187.  
  5188. sketch_mar07a:3821:20: error: 'struct xod::bitrex__xod_menu_system__concat_menu::ContextObject' has no member named '_input_IN1'
  5189.  
  5190. ctxObj._input_IN1 = node_39.output_OUT;
  5191.  
  5192. ^
  5193.  
  5194. sketch_mar07a:3821:41: error: 'struct xod::bitrex__xod_menu_system__leaf_menu_item_impl::Node' has no member named 'output_OUT'
  5195.  
  5196. ctxObj._input_IN1 = node_39.output_OUT;
  5197.  
  5198. ^
  5199.  
  5200. sketch_mar07a:3822:20: error: 'struct xod::bitrex__xod_menu_system__concat_menu::ContextObject' has no member named '_input_IN2'
  5201.  
  5202. ctxObj._input_IN2 = node_41.output_OUT;
  5203.  
  5204. ^
  5205.  
  5206. sketch_mar07a:3822:41: error: 'struct xod::bitrex__xod_menu_system__leaf_menu_item_impl::Node' has no member named 'output_OUT'
  5207.  
  5208. ctxObj._input_IN2 = node_41.output_OUT;
  5209.  
  5210. ^
  5211.  
  5212. sketch_mar07a:3839:20: error: 'struct xod::bitrex__xod_menu_system__concat_menu::ContextObject' has no member named '_input_IN1'
  5213.  
  5214. ctxObj._input_IN1 = node_38.output_OUT;
  5215.  
  5216. ^
  5217.  
  5218. sketch_mar07a:3839:41: error: 'struct xod::bitrex__xod_menu_system__leaf_menu_item_impl::Node' has no member named 'output_OUT'
  5219.  
  5220. ctxObj._input_IN1 = node_38.output_OUT;
  5221.  
  5222. ^
  5223.  
  5224. sketch_mar07a:3840:20: error: 'struct xod::bitrex__xod_menu_system__concat_menu::ContextObject' has no member named '_input_IN2'
  5225.  
  5226. ctxObj._input_IN2 = node_42.output_OUT;
  5227.  
  5228. ^
  5229.  
  5230. sketch_mar07a:3840:41: error: 'struct xod::bitrex__xod_menu_system__leaf_menu_item_impl::Node' has no member named 'output_OUT'
  5231.  
  5232. ctxObj._input_IN2 = node_42.output_OUT;
  5233.  
  5234. ^
  5235.  
  5236. sketch_mar07a:3947:20: error: 'struct xod::bitrex__xod_menu_system__branch_menu_item::ContextObject' has no member named '_input_IN'
  5237.  
  5238. ctxObj._input_IN = node_44.output_OUT;
  5239.  
  5240. ^
  5241.  
  5242. sketch_mar07a:3947:40: error: 'struct xod::bitrex__xod_menu_system__concat_menu::Node' has no member named 'output_OUT'
  5243.  
  5244. ctxObj._input_IN = node_44.output_OUT;
  5245.  
  5246. ^
  5247.  
  5248. sketch_mar07a:3967:20: error: 'struct xod::bitrex__xod_menu_system__branch_menu_item::ContextObject' has no member named '_input_IN'
  5249.  
  5250. ctxObj._input_IN = node_45.output_OUT;
  5251.  
  5252. ^
  5253.  
  5254. sketch_mar07a:3967:40: error: 'struct xod::bitrex__xod_menu_system__concat_menu::Node' has no member named 'output_OUT'
  5255.  
  5256. ctxObj._input_IN = node_45.output_OUT;
  5257.  
  5258. ^
  5259.  
  5260. sketch_mar07a:4069:20: error: 'struct xod::bitrex__xod_menu_system__concat_menu::ContextObject' has no member named '_input_IN1'
  5261.  
  5262. ctxObj._input_IN1 = node_51.output_OUT;
  5263.  
  5264. ^
  5265.  
  5266. sketch_mar07a:4069:41: error: 'struct xod::bitrex__xod_menu_system__branch_menu_item::Node' has no member named 'output_OUT'
  5267.  
  5268. ctxObj._input_IN1 = node_51.output_OUT;
  5269.  
  5270. ^
  5271.  
  5272. sketch_mar07a:4070:20: error: 'struct xod::bitrex__xod_menu_system__concat_menu::ContextObject' has no member named '_input_IN2'
  5273.  
  5274. ctxObj._input_IN2 = node_52.output_OUT;
  5275.  
  5276. ^
  5277.  
  5278. sketch_mar07a:4070:41: error: 'struct xod::bitrex__xod_menu_system__branch_menu_item::Node' has no member named 'output_OUT'
  5279.  
  5280. ctxObj._input_IN2 = node_52.output_OUT;
  5281.  
  5282. ^
  5283.  
  5284. sketch_mar07a:4087:20: error: 'struct xod::bitrex__xod_menu_system__menu_controller::ContextObject' has no member named '_input_MENU_TREE'
  5285.  
  5286. ctxObj._input_MENU_TREE = node_58.output_OUT;
  5287.  
  5288. ^
  5289.  
  5290. sketch_mar07a:4087:47: error: 'struct xod::bitrex__xod_menu_system__concat_menu::Node' has no member named 'output_OUT'
  5291.  
  5292. ctxObj._input_MENU_TREE = node_58.output_OUT;
  5293.  
  5294. ^
  5295.  
  5296. exit status 1
  5297. '____menu_base' is not a namespace-name
  5298.  
  5299. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\20180202_vu_meter_update: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\20180202_vu_meter_update
  5300. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\Adafruit: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\Adafruit
  5301. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\BlinkyBall-master: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\BlinkyBall-master
  5302. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\CH341SER: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\CH341SER
  5303. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\keypad_values: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\keypad_values
  5304. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\micropython-ws2812-master: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\micropython-ws2812-master
  5305. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\multiplesketches_master: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\multiplesketches_master
  5306. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\simple_lcd_menu: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\simple_lcd_menu
  5307. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\SmartMatrix3-3.0.1: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\SmartMatrix3-3.0.1
  5308. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\Yahzee: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\Yahzee
  5309. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\20180202_vu_meter_update: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\20180202_vu_meter_update
  5310. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\Adafruit: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\Adafruit
  5311. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\BlinkyBall-master: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\BlinkyBall-master
  5312. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\CH341SER: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\CH341SER
  5313. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\keypad_values: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\keypad_values
  5314. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\micropython-ws2812-master: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\micropython-ws2812-master
  5315. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\multiplesketches_master: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\multiplesketches_master
  5316. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\simple_lcd_menu: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\simple_lcd_menu
  5317. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\SmartMatrix3-3.0.1: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\SmartMatrix3-3.0.1
  5318. Invalid library found in C:\Users\taran\Documents\Arduino\libraries\Yahzee: no headers files (.h) found in C:\Users\taran\Documents\Arduino\libraries\Yahzee
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement