threaded-canvas-manipulator.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
  2. // Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation version 2.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program. If not, see <http://gnu.org/licenses/gpl-2.0.txt>
  15. // Utility base class for continuously updating the canvas.
  16. // Note: considering removing this, as real applications likely have something
  17. // similar, but this might not be quite usable.
  18. // Since it is just a few lines of code, it is probably better
  19. // implemented in the application for readability.
  20. //
  21. // So for simplicity of the API, consider ThreadedCanvasManipulator deprecated.
  22. #ifndef RPI_THREADED_CANVAS_MANIPULATOR_H
  23. #define RPI_THREADED_CANVAS_MANIPULATOR_H
  24. #include "thread.h"
  25. #include "canvas.h"
  26. namespace rgb_matrix {
  27. //
  28. // Typically, your programs will crate a canvas and then updating the image
  29. // in a loop. If you want to do stuff in parallel, then this utility class
  30. // helps you doing that. Also a demo for how to use the Thread class.
  31. //
  32. // Extend it, then just implement Run(). Example:
  33. /*
  34. class MyCrazyDemo : public ThreadedCanvasManipulator {
  35. public:
  36. MyCrazyDemo(Canvas *canvas) : ThreadedCanvasManipulator(canvas) {}
  37. virtual void Run() {
  38. unsigned char c;
  39. while (running()) {
  40. // Calculate the next frame.
  41. c++;
  42. for (int x = 0; x < canvas()->width(); ++x) {
  43. for (int y = 0; y < canvas()->height(); ++y) {
  44. canvas()->SetPixel(x, y, c, c, c);
  45. }
  46. }
  47. usleep(15 * 1000);
  48. }
  49. }
  50. };
  51. // Later, in your main method.
  52. RGBMatrix *matrix = RGBMatrix::CreateFromOptions(...);
  53. MyCrazyDemo *demo = new MyCrazyDemo(matrix);
  54. demo->Start(); // Start doing things.
  55. // This now runs in the background, you can do other things here,
  56. // e.g. aquiring new data or simply wait. But for waiting, you wouldn't
  57. // need a thread in the first place.
  58. demo->Stop();
  59. delete demo;
  60. */
  61. class ThreadedCanvasManipulator : public Thread {
  62. public:
  63. ThreadedCanvasManipulator(Canvas *m) : running_(false), canvas_(m) {}
  64. virtual ~ThreadedCanvasManipulator() { Stop(); }
  65. virtual void Start(int realtime_priority=0, uint32_t affinity_mask=0) {
  66. {
  67. MutexLock l(&mutex_);
  68. running_ = true;
  69. }
  70. Thread::Start(realtime_priority, affinity_mask);
  71. }
  72. // Stop the thread at the next possible time Run() checks the running_ flag.
  73. void Stop() {
  74. MutexLock l(&mutex_);
  75. running_ = false;
  76. }
  77. // Implement this and run while running() returns true.
  78. virtual void Run() = 0;
  79. protected:
  80. inline Canvas *canvas() { return canvas_; }
  81. inline bool running() {
  82. MutexLock l(&mutex_);
  83. return running_;
  84. }
  85. private:
  86. Mutex mutex_;
  87. bool running_;
  88. Canvas *const canvas_;
  89. };
  90. } // namespace rgb_matrix
  91. #endif // RPI_THREADED_CANVAS_MANIPULATOR_H