summaryrefslogtreecommitdiff
path: root/src/core/model/Node.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/model/Node.hpp')
-rw-r--r--src/core/model/Node.hpp117
1 files changed, 57 insertions, 60 deletions
diff --git a/src/core/model/Node.hpp b/src/core/model/Node.hpp
index 3763395..0523c69 100644
--- a/src/core/model/Node.hpp
+++ b/src/core/model/Node.hpp
@@ -28,6 +28,7 @@
#ifndef _OUSIA_NODE_HPP_
#define _OUSIA_NODE_HPP_
+#include <cstdint>
#include <map>
#include <set>
#include <string>
@@ -47,6 +48,36 @@ template <class T>
class Rtti;
/**
+ * Describes the validity of a node structure.
+ */
+enum class ValidationState : uint8_t {
+ /**
+ * The validity is set to UNKNOWN if the Node has not yet been validated or
+ * the validation state has been reset (because the node was changed).
+ */
+ UNKNOWN,
+
+ /**
+ * The validity is set to validating if the Node has not yet been validated,
+ * but its validation is currently running. This flag is used to prevent
+ * recursion.
+ */
+ VALIDATING,
+
+ /**
+ * The validity is set to VALID if the Node has been validaten and is known
+ * to be valid.
+ */
+ VALID,
+
+ /**
+ * The validity is set to INVALID if the Node has been validated and is
+ * known to be invalid.
+ */
+ INVALID
+};
+
+/**
* Structure describing a single result obtained from the resolution function.
*/
struct ResolutionResult {
@@ -105,11 +136,12 @@ private:
* Reference to a parent node instace.
*/
Owned<Node> parent;
+
/**
- * A "dirty" flag that signifies if this Node has been validated already
+ * A "dirty" flag that signifies if this Node has been already validated
* or not.
*/
- mutable bool validated = false;
+ mutable ValidationState validationState;
/**
* Private version of the "path" function used to construct the path. Calls
@@ -272,9 +304,15 @@ protected:
/**
* This method should be called if the internal state of this Node is
- * changed such that a new validation run has to be made.
+ * changed such that a new validation run has to be made. Also informs the
+ * parent node about the invalidation.
*/
- void invalidate() const { validated = false; }
+ void invalidate();
+
+ /**
+ * This method should be called if a Node finds itself in an invalid state.
+ */
+ void markInvalid();
/**
* The convention for this function is as follows:
@@ -284,44 +322,12 @@ protected:
* If some child returns false this method should return false as well.
* 4.) If all children could be validated this method should return true.
*
- * Note that this implementation does not have to touch the visited set.
- * You can use it for validation purposes, however (e.g. to detect cycles
- * in the graph).
- *
* The default and trivial behaviour of this function is to return true.
*
- * @param logger is a logger for error messages if false is returned.
- * @param visited is a set containing the ManagedUids of all children
- * that already have been visited.
- * @return true if this is a valid node and false if it is not.
+ * @param logger is a logger for error messages if false is returned.
+ * @return true if this is a valid node and false if it is not.
*/
- virtual bool doValidate(Logger &logger, std::set<ManagedUid> &visited) const
- {
- return true;
- }
-
- /**
- * A wrapper for doValidate that takes care of not visiting children twice,
- * and handling the validated flag.
- */
- bool validate(Logger &logger, std::set<ManagedUid> &visited) const {
- if (!visited.insert(getUid()).second) {
- // if we have visited this Node already within this run, return
- // the validated flag.
- return validated;
- }
- if(validated){
- // if this is validated, return true.
- return true;
- }
- if(!doValidate(logger, visited)){
- // if this can not be validated, return false.
- return false;
- }
- // if it could be validated, set the validated flag.
- validated = true;
- return true;
- }
+ virtual bool doValidate(Logger &logger) const;
public:
/**
@@ -330,7 +336,9 @@ public:
* @param mgr is a reference to the Manager instace the node belongs to.
*/
Node(Manager &mgr, Handle<Node> parent = nullptr)
- : Managed(mgr), parent(acquire(parent))
+ : Managed(mgr),
+ parent(acquire(parent)),
+ validationState(ValidationState::UNKNOWN)
{
}
@@ -342,7 +350,10 @@ public:
* @param parent is a handle pointing at the parent node.
*/
Node(Manager &mgr, std::string name, Handle<Node> parent = nullptr)
- : Managed(mgr), name(name), parent(acquire(parent))
+ : Managed(mgr),
+ name(name),
+ parent(acquire(parent)),
+ validationState(ValidationState::UNKNOWN)
{
}
@@ -423,29 +434,15 @@ public:
const RttiType &type);
/**
- * Returns true if this node has been validated. Note that a 'false' return
- * value does _not_ imply that this Node is invalid. It merely says that
- * validity of this node is uncertain. The opposite is true, however: If
- * this node is invalid, the validated flag will be false.
- */
- bool isValidated() const { return validated; }
-
- /**
* Checks whether this node is valid and returns true if it is and false
* if it is not. If the node is invalid further information will be appended
- * to the logger. If this is valid this will also set the "validated" flag
- * to "true".
+ * to the logger.
*
- * @param logger is a logger where errors will be logged if this
- * Node is invalid.
- *
- * @return true if this Node is valid.
+ * @param logger is a logger where errors will be logged if this Node is
+ * invalid.
+ * @return true if this Node is valid.
*/
- bool validate(Logger &logger)
- {
- std::set<ManagedUid> visited;
- return validate(logger, visited);
- }
+ bool validate(Logger &logger) const;
};
/**