Line data Source code
1 : /* ✔ */ 2 : 3 : #pragma once 4 : 5 : #include <AH/Settings/Warnings.hpp> 6 : 7 : AH_DIAGNOSTIC_WERROR() // Enable errors on warnings 8 : 9 : #include <AH/Containers/LinkedList.hpp> 10 : #include <AH/Error/Error.hpp> 11 : #include <AH/Settings/SettingsWrapper.hpp> 12 : #include <stddef.h> 13 : 14 : BEGIN_AH_NAMESPACE 15 : 16 : struct NormalUpdatable {}; 17 : 18 : /** 19 : * @brief A super class for object that have to be updated regularly. 20 : * 21 : * All instances of this class are kept in a linked list, so it's easy to 22 : * iterate over all of them to update them. 23 : */ 24 : template <class T = NormalUpdatable> 25 : class Updatable : public DoublyLinkable<Updatable<T>> { 26 : protected: 27 : /// Create an Updatabe and add it to the linked list of instances. 28 90 : Updatable() { updatables.append(this); } 29 : 30 : public: 31 : /// Destructor: remove the updatable from the linked list of instances. 32 90 : virtual ~Updatable() { 33 90 : if (isEnabled()) 34 90 : updatables.remove(this); 35 90 : } 36 : 37 : /// Update this updatable. 38 : virtual void update() = 0; 39 : 40 : /// Initialize this updatable. 41 : virtual void begin() = 0; 42 : 43 : /// Enable this updatable: insert it into the linked list of instances, 44 : /// so it gets updated automatically 45 : void enable() { 46 : if (isEnabled()) { 47 : ERROR(F("Error: This element is already enabled."), 0x1212); 48 : return; 49 : } 50 : updatables.append(this); 51 : } 52 : 53 : /// Disable this updatable: remove it from the linked list of instances, 54 : /// so it no longer gets updated automatically 55 : void disable() { 56 : if (!isEnabled()) { 57 : ERROR(F("Error: This element is already disabled."), 0x1213); 58 : return; 59 : } 60 : updatables.remove(this); 61 : } 62 : 63 : /** 64 : * @brief Check if this updatable is enabled. 65 : * 66 : * @note Assumes that the updatable is not added to a different linked 67 : * list by the user. 68 : */ 69 90 : bool isEnabled() { return updatables.couldContain(this); } 70 : 71 : /// Begin all enabled instances of this class 72 : /// @see begin() 73 8 : static void beginAll() { 74 16 : for (Updatable &el : updatables) 75 8 : el.begin(); 76 8 : } 77 : 78 : /// Update all enabled instances of this class 79 : /// @see update() 80 32 : static void updateAll() { 81 64 : for (Updatable &el : updatables) 82 32 : el.update(); 83 32 : } 84 : 85 : static void enable(Updatable *element) { element->enable(); } 86 : 87 : static void enable(Updatable &element) { element.enable(); } 88 : 89 : template <class U, size_t N> 90 : static void enable(U (&array)[N]) { 91 : for (U &el : array) 92 : enable(el); 93 : } 94 : 95 : static void disable(Updatable<T> *element) { element->disable(); } 96 : 97 : static void disable(Updatable<T> &element) { element.disable(); } 98 : 99 : template <class U, size_t N> 100 : static void disable(U (&array)[N]) { 101 : for (U &el : array) 102 : disable(el); 103 : } 104 : 105 : private: 106 : static DoublyLinkedList<Updatable<T>> updatables; 107 : }; 108 : 109 : template <class T> 110 : DoublyLinkedList<Updatable<T>> Updatable<T>::updatables; 111 : 112 : END_AH_NAMESPACE 113 : 114 : AH_DIAGNOSTIC_POP()