Creating A Basic C++ PolySync Application Tutorial
In this tutorial, we will examine the different pieces that constitute a C++ PolySync application, what each component means, and how to use them.
### 1. Compiling the source code The default installation directory for PolySync is _/usr/local/polysync_. The relative paths used originate from the default directory. The tutorial source code is located in the _examples/cpp/PolySyncExampleApp_ directory. We will now use the following command sequence to compile the code: ```bash $ cd /usr/local/polysync/examples/cpp/PolySyncExampleApp $ mkdir build $ cd build $ cmake .. $ make ``` ### 1.1 What is happening in the code? This tutorial goes back to using just a single node, but this node gains in complexity as compared to the previous [tutorials](https://help.polysync.io/releases/2.0.7//articles/hello-world-with…-using-the-c-api/). We will implement all of the overloaded callback functions, and will support publishing and subscribing in a single application. Specifically, this application sets the node into different possible states, to demonstrate how the node state machine functions. It also explains what all of the different events are for, and situations where they may be encountered. ### 2. PolySync sample application Open a terminal and run: ```bash $ ./polysync-sample-application-cpp ``` ### 2.1 setConfigurationEvent The first message we see states: **polysync-sample-appliocation-cpp received a configuration event. No configuration parameters to display.** While this is not the only time this message will appear, during the start up of a node, PolySync sends a configuration event to the node to send configuration parameters. We have code to display what the parameters send but, as this is a simple example, we have no parameters to display. The set configuration event handler has the following prototype: ```bash virtual void setConfigurationEvent( int argc, char *argv ) ``` ### 2.2 initStateEvent The next message we see is: ```bash polysync-sample-appliocation-cpp is initializing. ``` In the first tutorial, HelloWorld only implements this function. It demonstrates how PolySync starts the state machine for a given node. In this tutorial, we are doing the extra work of both registering to receive the _'ps_byte_array_msg'_ message and initializing the timer tick to zero (in preparation for incrementing it). The initialization state event has the following prototype: ```bash virtual void initStateEvent() ``` ### 2.3 okStateEvent Below is an example of a series of messages that would display next: ```bash class ByteArrayMessage in->header.type:: 16 in->header.timestamp:: 1456865453973685 in->header.src_guid:: 281479197065652 in->dest_guid:: 0 in->data_type:: 0 in->bytes:: P in->bytes:: o in->bytes:: l in->bytes:: y in->bytes:: S in->bytes:: y in->bytes:: n in->bytes:: c in->bytes:: in->bytes:: S in->bytes:: a in->bytes:: m in->bytes:: p in->bytes:: l in->bytes:: e ``` PolySync rapidly calls the okStateEvent, which is why a sleep function is included at the end of the loop. This slows the function down enough to see what is happening on a second-by-second basis. Inside the function, we can see that a message is being published that contains the information above. We have also subscribed to messages of that type, which is where this printed information is coming from. At the end of this function we increment the timer tick by one. As it exceeds the number of iterations in this state, we use the activate fault function to transition in the **WARN** state. The "OK" state event handler has the following prototype: ```bash virtual void okStateEvent() ``` ### 2.4 messageEvent The information displayed on the console comes from the message event. As part of the initialization, we subscribed to a specific message type that we are now receiving. The complexities associated with the processing of the message event are more related to recognizing the type of message that has now been received. The message class has a specific mechanism in place to allow us to attempt to convert the message pointer into the type of message we want (it uses the C++ dynamic_cast.) This function also allows us to subscribe to multiple messages, and determine which one we receive based on what we can convert it to. The message event has the following prototype: ```bash virtual void messageEvent() ``` ### 2.5 warnStateEvent The next message displays the following: ```bash class ByteArrayMessage in->header.type:: 16 in->header.timestamp:: 1456865459025288 in->header.src_guid:: 281479197065652 in->dest_guid:: 0 in->data_type:: 0 in->bytes:: W in->bytes:: A in->bytes:: R in->bytes:: N in->bytes:: I in->bytes:: N in->bytes:: G in->bytes:: ! ``` The message event receives the message and prints the information. The warning state event sends a few of these messages, and then transitions to the **ERROR** state. The warning state event handler has the following prototype: ```bash virtual void warnStateEvent() ``` ### 2.6 errorStateEvent Next, the applications displays: ```bash polysync-sample-application-cpp is in the error state. ``` Messages can certainly be sent from the error state also, but the intent is to indicate that the node is in an error condition and should do something to fix it. PolySync already contains a specific message (the diagnostics message) that contains the state of a given node. Subscribing to that message allows us to see the state of all of the nodes in the current system. The point of the error state is to allow the system to recognize that the node is in a bad state, and should do something to react or recover from the fault. What that reaction might be is dependent on both the purpose and function of the node, and the criticality of the system. The treatment of the error state is similar to the "OK" state in that it is called as rapidly as possible. The error state event handler contains a sleep function. This is so that it can send a few error messages, and then transition to the **FATAL** state. The error state event handler has the following prototype: ```bash virtual void errorStateEvent() ``` ### 2.7 fatalStateEvent Next, the applications displays: ```bash polysync-sample-application-cpp received a fatal error and will shut down. ``` The fatal state is a last call before the node is shut down. Essentially, an error path for the node to clean itself up if possible. The fatal state event handler has the following prototype: ```bash virtual void fatalStateEvent() ``` ### 2.8 releaseStateEvent Finally, the application displays: ```bash polysync-sample-application-cpp is shutting down. ``` This is an indicator that the shutdown, even through the fatal state, still calls the release state to allow the node to perform any final clean up. This is specifically called here because it is an indicator that the fatal state needs to clean up specific problems. The release will clean up as the nominal exit path for the node. The release state event handler has the following prototype: ```bash virtual void releaseStateEvent() ``` ### Conclusion In this tutorial, we examined the different pieces that constitute a C++ PolySync application, what each component means, and how to use them. #### Next tutorial Ready for more? The [Data Generation Tutorial](https://help.polysync.io/releases/2.0.7//articles/data-generation-tutorial/) expands on filling messages and publishing data to the PolySync bus, as well as working with multiple message types.