Node Scaffolding Generator

### 1. Scaffolding The scaffolding generator makes it easy to roll out a functioning C++ software node in PolySync. To generate a new node, open a new terminal and type: ```bash $ polysync-generate node ``` This will create a project called `MyNode`, which can be run with: ```bash $ ./MyNode/build/MyNode ``` By default `MyNode` subscribes to and prints PolySync diagnostic messages - `DiagnosticTraceMessage`. ### 2. Command line options Print the command line options with the help flag. You can specify the node name,output directory and which messages to subscribe to with a few flags. ```bash $ polysync-generate node -h usage: polysync-generate node [-h] [-n NAME] [-o DIR] [-s MESSAGE [MESSAGE ...]] [-l] optional arguments: -h, --help show this help message and exit -n NAME, --name NAME name of the generated PolySync node -o DIR, --output DIR path in which to place generated files -s MESSAGE [MESSAGE ...], --subscribe MESSAGE [MESSAGE ...] messages to which to subscribe -l, --list list valid PolySync messages ``` ### 2.1 About the code `MyNode` contains all of the necessary methods every PolySync C++ node should have. This is the working directory: ```bash MyNode ├── include │ └── MyNode.hpp ├── CMakeLists.txt └── src ├── MyNode.cpp └── main.cpp ``` In `main.cpp`, you can see how PolySync nodes are initialized. The `connectPolySync( )` is a blocking operation, and places the node in the node state machine. If there is a valid license, the node leaves the AUTH state and enters the INIT state, calling the `initStateEvent( )` in `MyNode.cpp`. ### 2.2 main.cpp ```cpp #include < iostream > #include < GetOpt.hpp > #include < PolySyncCore.hpp > #include < PolySyncNode.hpp > #include < PolySyncDataModel.hpp > #include "MyNode.hpp" using namespace std; int main( int argc, char * argv[] ) { MyNode node; node.setNodeName( MyNode::NODE_NAME ); node.setCommandLineOptions( { argc, argv } ); node.connectPolySync(); return 0; } ``` ### 2.3 MyNode.hpp ```cpp #ifndef MYNODE_HPP #define MYNODE_HPP class MyNode : public polysync::Node { public: virtual void messageEvent( std::shared_ptr< polysync::Message > message ); virtual void initStateEvent(); virtual void setConfigurationEvent( const GetOpt & commandLineArgs ); void okStateEvent(); virtual void fatalStateEvent(); virtual void errorStateEvent(); virtual void warnStateEvent(); virtual void releaseStateEvent(); public: static constexpr auto NODE_NAME = "MyNode"; private: ps_msg_type _messageTypeDiagnosticTraceMsg; }; #endif // MYNODE_HPP ``` ### 2.4 MyNode.cpp ```cpp #include #include < GetOpt.hpp > #include < PolySyncCore.hpp > #include < PolySyncNode.hpp > #include < PolySyncDataModel.hpp > #include "MyNode.hpp" using namespace std; void MyNode::messageEvent( std::shared_ptr< polysync::Message > message ) { using namespace polysync::datamodel; if( auto diagnosticTraceMsg = getSubclass< DiagnosticTraceMessage >( message ) ) { diagnosticTraceMsg->print(); } } void MyNode::initStateEvent() { try { _messageTypeDiagnosticTraceMsg = getMessageTypeByName( "ps_diagnostic_trace_msg" ); registerListener( _messageTypeDiagnosticTraceMsg ); } catch (polysync::DTCException e) { polySyncLogDebug( "ps_diagnostic_trace_msg - " + e.getDtcDescription() ); activateFault( e.getDtc(), NODE_STATE_FATAL ); } } void MyNode::setConfigurationEvent( const GetOpt & commandLineArgs ) { commandLineArgs.printAll(); } void MyNode::okStateEvent() { // called continuously while in OK state } void MyNode::fatalStateEvent() { // called once upon entering FATAL state } void MyNode::errorStateEvent() { // called continuously while in ERROR state } void MyNode::warnStateEvent() { // called continuously while in WARN state } void MyNode::releaseStateEvent() { // called at end of node life } ``` The scaffolding generator is a great tool to get you developing custom nodes in PolySync quickly.