1 #ifndef ATTRIBUTE_H 2 #define ATTRIBUTE_H 3 4 #include <string> 5 #include <vector> 6 7 #include "entity.h" 8 9 class Object; 10 class Signal; 11 class Completion; 12 13 /* Attributes. 14 * Attributes are members of Objects that expose internal state variables to the 15 * object tree accessible through the 'attr' command. 16 * The class Attribute is abstract and is used to form a common base. 17 * 18 * Attribute_<T> are regular (static) attributes. 19 * They provide static methods for conversion from/to string (parse() and str()). 20 * A validator can be specified that performs checks before accepting external 21 * input. Error messages produced by the validator are propagated back to the user. 22 * The validator is not called when the attribute is set internally. 23 * Static attributes are read-only by default and need to set writable either 24 * explicitely or by setting a validator. 25 * Static attributes provide a signal "changed" that emits whenever the attribute 26 * is altered (internally or externally). 27 * Likewise, they are by-default hookable. For some attributes a hook does not make 28 * sense, so it can be disabled on an individual basis. 29 * 30 * DynAttribute_<T> are shallow attributes and not physically present. 31 * A common reason for having a dynamic attribute is for backwards-compatibility 32 * or to provide some kind of magic in an attribute. 33 * However, for allowing triggers by the user, an Action should be used instead. 34 * Actions are designated properly and can accept multiple arguments. 35 * The can be read-only using a getter callback, or rw with an additional 36 * setter callback. Validation is done within the setter. 37 * Dynamic attributes do not provide a changed signal. They could do it easily in 38 * theory, however it would most-probably be a bad idea to attach to such a signal 39 * instead of to the underlying mechanics. 40 * Note that for similar reasons, dynamic attributes are not hookable. 41 */ 42 43 class Attribute : public Entity, public HasDocumentation { 44 45 public: Attribute(const std::string & name,bool writable)46 Attribute(const std::string &name, 47 bool writable) 48 : Entity(name), writable_(writable) {} 49 ~Attribute() override = default; 50 51 // set the owner after object creation (when pointer is available) setOwner(Object * owner)52 void setOwner(Object *owner) { owner_ = owner; } 53 // make this attribute writable (default is typically read-only) 54 void setWritable(bool writable = true) { writable_ = writable; } 55 // change if attribute can be expected to trigger hooks (rarely used) setHookable(bool hookable)56 void setHookable(bool hookable) { hookable_ = hookable; } 57 writable()58 bool writable() const { return writable_; } hookable()59 bool hookable() const { return hookable_; } 60 virtual Signal& changed() = 0; 61 str()62 virtual std::string str() { return {}; } 63 virtual std::string change(const std::string &payload) = 0; 64 //! suggestions for a new value of the attribute 65 virtual void complete(Completion& complete) = 0; 66 67 // find the current value of the attribute in the given range and then 68 // assign the succeeding value to the attribute (wth wrap around) 69 std::string cycleValue(std::vector<std::string>::const_iterator begin, 70 std::vector<std::string>::const_iterator end); 71 72 //! if the attribute has a default value, reset it, otherwise return false resetValue()73 virtual bool resetValue() { return false; } 74 75 void detachFromOwner(); 76 77 protected: 78 Object *owner_ = nullptr; 79 80 bool writable_ = false, hookable_ = true; 81 }; 82 83 84 #endif // ATTRIBUTE_H 85