diff --git a/examples/cpp/lib/effect.h b/examples/cpp/lib/effect.h index 1d86e91332e659747bd27b3da2c8c4dec23be5aa..9e10dab61c5c2e3e87065c0c9e14f303d421bc5e 100644 --- a/examples/cpp/lib/effect.h +++ b/examples/cpp/lib/effect.h @@ -32,6 +32,9 @@ #include <algorithm> #include <vector> #include <sys/time.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> #include "opcclient.h" @@ -60,15 +63,21 @@ public: void setEffect(Effect* effect); void setMaxFrameRate(float fps); + bool hasLayout(); const rapidjson::Document& getLayout(); Effect* getEffect(); OPCClient& getClient(); + // Main loop body void doFrame(); void doFrame(float timeDelta); + // Minimal main loop void run(); + // Simple argument parsing and main loop + int main(int argc, char **argv); + private: float minTimeDelta; rapidjson::Document layout; @@ -76,6 +85,8 @@ private: Effect *effect; struct timeval lastTime; std::vector<uint8_t> frameBuffer; + + int usage(const char *name); }; @@ -89,6 +100,9 @@ inline EffectRunner::EffectRunner() { lastTime.tv_sec = 0; lastTime.tv_usec = 0; + + // Default server + setServer("localhost"); } inline void EffectRunner::setMaxFrameRate(float fps) @@ -132,6 +146,11 @@ inline const rapidjson::Document& EffectRunner::getLayout() return layout; } +inline bool EffectRunner::hasLayout() +{ + return layout.IsArray(); +} + inline void EffectRunner::setEffect(Effect *effect) { this->effect = effect; @@ -169,7 +188,7 @@ inline void EffectRunner::doFrame() inline void EffectRunner::doFrame(float timeDelta) { - if (!effect || !layout.IsArray()) { + if (!getEffect() || !hasLayout()) { return; } @@ -203,3 +222,51 @@ inline OPCClient& EffectRunner::getClient() { return opc; } + +inline int EffectRunner::main(int argc, char **argv) +{ + for (int i = 1; i < argc; i++) { + + if (!strcmp(argv[i], "-fps") && (i+1 < argc)) { + float rate = atof(argv[++i]); + if (rate <= 0) { + fprintf(stderr, "Invalid frame rate\n"); + return usage(argv[0]); + } + setMaxFrameRate(rate); + continue; + } + + if (!strcmp(argv[i], "-layout") && (i+1 < argc)) { + if (!setLayout(argv[++i])) { + fprintf(stderr, "Can't load layout from %s\n", argv[i]); + return 1; + } + continue; + } + + if (!strcmp(argv[i], "-server") && (i+1 < argc)) { + if (!setServer(argv[++i])) { + fprintf(stderr, "Can't resolve server name %s\n", argv[i]); + return 1; + } + continue; + } + + return usage(argv[0]); + } + + if (!hasLayout()) { + fprintf(stderr, "No layout specified\n"); + return usage(argv[0]); + } + + run(); + return 0; +} + +inline int EffectRunner::usage(const char *name) +{ + fprintf(stderr, "usage: %s [-fps LIMIT] [-layout FILE.json] [-server HOST[:port]]\n", name); + return 1; +} diff --git a/examples/cpp/simple.cpp b/examples/cpp/simple.cpp index bbc880462aa4ead883c816d0ec35bcfb47dda883..bf1314c7eac589b30e372a80d0cc095220559f98 100644 --- a/examples/cpp/simple.cpp +++ b/examples/cpp/simple.cpp @@ -1,5 +1,4 @@ // Simple example effect: -// Uses the grid32x16z layout, connects to a local OPC server. // Draws a noise pattern modulated by an expanding sine wave. #include <math.h> @@ -34,14 +33,16 @@ public: } }; -int main() +int main(int argc, char **argv) { EffectRunner r; + MyEffect e; r.setEffect(&e); + + // Defaults, overridable with command line options r.setMaxFrameRate(100); - r.setServer("localhost"); r.setLayout("../layouts/grid32x16z.json"); - r.run(); - return 0; + + return r.main(argc, argv); } \ No newline at end of file