ContinuityRule.h header

#include <ew/core/timeline/ContinuityRule.h>

Namespace ew::core::timeline

ContinuityRule struct

struct ew::core::timeline::ContinuityRule

A user-authored continuity assertion the timeline validator checks (DESIGN 4.5 "user rules"): "at a point in story time, entity E's field F must (or must not) equal V." It complements the built-in checks (two-places-at-once, lifespan, travel time, dangling refs) with truths particular to the writer's world – a monarch's title after a coronation, an artifact's location after it is hidden – evaluated against the entity's state-over-time (Entity::valueAt). A violated rule becomes a conflict in the Conflicts dock.

Rules are a lightweight project-level registry (like the plot-thread and audience registries), not full content objects; ids are stable strings assigned by the UI so the core stays deterministic.

Members

QString ew::core::timeline::ContinuityRule::id

Stable identity of this rule, assigned by the UI when it is created (a UUID).

QString ew::core::timeline::ContinuityRule::name

The writer-facing name of the rule (e.g. "Aragorn is King after the coronation").

ew::core::foundation::ContentId ew::core::timeline::ContinuityRule::entityId

The entity the rule constrains, when its scope names one object.

Kept beside the scope below rather than replaced by it: it is the serialized form every existing project holds, and a rule about one entity is still what most rules are. A rule loaded without a scope gets an Object scope naming this id, so nothing written before scopes existed changes meaning.

RuleScope ew::core::timeline::ContinuityRule::scope

What the rule applies to.

The difference between a rule and a note about one entity. Scoped to a category, "every Item costs at least nothing" is written once and stays true for Items that do not exist yet; without a scope it had to be written per entity, or not written.

QString ew::core::timeline::ContinuityRule::fieldKey

The entity field whose value is asserted (the same key space as Entity::value).

RuleComparison ew::core::timeline::ContinuityRule::comparison =

How the field value is compared against value.

QString ew::core::timeline::ContinuityRule::value

The expected value the comparison is against. For RuleComparison::OneOf it is the set of allowed values joined by '|' (e.g. "King|Queen|Regent"); for is-empty/is-non-empty it is ignored.

QString ew::core::timeline::ContinuityRule::expression

The expression the rule asserts – price >= 0 AND price <= 10000, deathDate > birthDate – instead of the single field/comparison/value above.

When this is non-empty it is what the rule means, and those three are ignored. One field can only ever be compared against one constant, so a truth involving two fields, a range, or a count had to be written as several rules that no longer say anything to each other – or not written. Read over the object being checked and the objects it references (see ew::app::expression::EntityBindings), in the language ew::core::expression::evaluate defines. The rule holds when the expression is true.

std::optional<qint64> ew::core::timeline::ContinuityRule::instant

When to evaluate the field, in minutes since the story epoch; std::nullopt evaluates the entity's base value (Entity::value), otherwise its value at that instant (Entity::valueAt), so a rule can pin a truth to a moment on the timeline.

bool operator==(const ContinuityRule &, const ContinuityRule &)=default

Two rules compare equal when every field matches.

Enumerations

enum class RuleComparison { Equals, NotEquals, Contains, NotContains, LessThan, LessOrEqual, GreaterThan, GreaterOrEqual, IsEmpty, IsNonEmpty, OneOf }

How a continuity rule compares an entity's field value against its expected value. Beyond exact equality, prose-friendly substring and numeric/range checks and set membership let a rule avoid false alarms on wording tweaks and express thresholds ("age must be at least 18").

Functions

bool ew::core::timeline::comparisonUsesValue(RuleComparison comparison)

Whether comparison compares against the rule's expected value (false for is-empty/is-non-empty, which ignore it) – lets a message omit an irrelevant value.

QString ew::core::timeline::requirementPhrase(RuleComparison comparison)

A human phrase for comparison in a rule readout / conflict message ("must be", "must contain", "must be at least", "must be non-empty", "must be one of").

std::optional< RuleComparison > ew::core::timeline::ruleComparisonFromToken(QStringView token)

Parses a comparison token (the toToken forms, plus friendly aliases like "not_equals", "greater_or_equal", "one_of"); nullopt when unrecognized.

QString ew::core::timeline::toToken(RuleComparison comparison)

The stable serialization token for comparison (e.g. "equals", "greaterOrEqual", "oneOf").