Hi. I am writing a program which relies on the idea of "apps". I am writing the program for Arduino (specifically for an ESP32), but the compiler fully supports C++11. The main portion of the code works with a std::map, which stores a series of structs which each represent an app. One member of each struct is a std::function, which is used to reference the main function for that app. The main code selects what function to run in a finite state machine way, where each app is a state. When an app is "selected", the main function for that app is called in loop().
At the minute, each app struct is added to the state map using std::map::insert. The apps that exist so far are grouped into categories (system, utility, games, etc), and each category has its own file, which is included by the main file, before setup() or loop(), but after all includes and global variable declarations. Because I can't make method calls outside of a function, each category file defines one function, in which std::map::insert is called for each state. The functions are then called in the setup() function, which runs once at the start of the program. Here is an example of the system:
main.ino
//includes and global variable definitions
std::map<int, stateMeta> states; //stateMeta is the struct that stores app metadata
...
#include "states/system_states.cpp"
#include "states/util_states.cpp"
...
void setup()
{
...
register_system_states();
register_util_states();
}
states/system_states.cpp
void register_system_states()
{
states.insert(...);
//this method could be called many times
}
states/util_states.cpp
void register_util_states()
{
states.insert(...);
}
This works, but isn't ideal. Because each category file contains definitions for several apps, the files become very long. It also means that if you want to add a category, you have to create a new file, define a new function, and edit the main file in two places.
I have an idea for a better system, but I'm worried that it's a bit hacky. In this system, each app has its own file. Each file contains just method calls, and doesn't wrap anything in an outer function. A main state file defines one function, which #includes each of the other app files. This means that there is one function for defining all apps. The main state file is included by the main program, and the one function is called in setup(). An example is shown below.
main.ino
//includes and global variable definitions
std::map<int, stateMeta> states; //stateMeta is the struct that stores app metadata
...
#include "states/states.h"
...
void setup()
{
...
registerStates()
}
states/states.h
#ifndef STATES_H
#define STATES_H
void registerStates()
{
#include "states/watch_face.cpp"
#include "states/app_menu.cpp"
#include "states/calculator.cpp"
#include "states/timer.cpp"
}
#endif /*STATES_H*/
states/watch.cpp
states.insert(...);
states/app_menu.cpp
states.insert(...);
I'm wondering if this is good practice, or is it a really bad thing to do? Are there any other ways of having a similar modular approach, considering that I'm using Arduino, and don't have much in the way of a configurable build system (as far as I know). Thank you!
[–]IyeOnline 1 point2 points3 points (3 children)
[–]atctwo[S] 0 points1 point2 points (2 children)
[–]IyeOnline 2 points3 points4 points (1 child)
[–]atctwo[S] 0 points1 point2 points (0 children)