RuleScope.h header

#include <ew/core/RuleScope.h>

Namespace ew::core

RuleScope struct

struct ew::core::RuleScope

What a rule applies to: a kind, and whichever of the parameters that kind uses.

One struct with the union of the parameters rather than a variant, because it is SERIALIZED and EDITED: a writer switching a scope from a category to a tag and back should find their category still selected, and a variant would have thrown it away in between.

Members

RuleScopeKind ew::core::timeline::RuleScope::kind =

What the rule applies to.

ew::core::foundation::ContentId ew::core::timeline::RuleScope::objectId

The object, for RuleScopeKind::Object.

ew::core::foundation::CategoryId ew::core::timeline::RuleScope::categoryId

The category, for RuleScopeKind::Category and RuleScopeKind::CategoryTree.

ew::core::content::ContentType ew::core::timeline::RuleScope::contentType =

The content type, for RuleScopeKind::ContentType.

QString ew::core::timeline::RuleScope::tag

The tag, for RuleScopeKind::Tag.

QString ew::core::timeline::RuleScope::plotThread

The plot thread's name, for RuleScopeKind::PlotThread.

QString ew::core::timeline::RuleScope::whereFieldPresent

A field that must be non-empty for the rule to apply, narrowing any scope above.

The work order's "a category plus a predicate", expressed as a narrowing of the scopes rather than as a scope of its own – so "every Item that has a price" and "every Cursed Object that has a curse" are the same idea rather than two. Empty means no narrowing.

Deliberately just "has a value": a scope decides WHICH objects a rule is about, and a scope that could compare values would be a second rule engine sitting in front of the first, with its own answer for what a number means.

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

Two scopes compare equal when every field matches.

Enumerations

enum class RuleScopeKind { Object, Category, CategoryTree, ContentType, Tag, PlotThread, Project }

What a continuity rule applies to.

The difference between a rule and a note. A rule that can only name one object expresses "Aragorn is King after the coronation" and cannot express "every Item costs at least nothing" – so the second had to be written 312 times or not at all, and an Item created tomorrow was covered by neither. A scope makes the second sayable once, and keeps it true for things that do not exist yet.

It is also the PERFORMANCE lever: a rule scoped to a category is evaluated against that category, never against the project.

Functions

RuleScope ew::core::timeline::categoryScope(ew::core::foundation::CategoryId categoryId, bool includeDescendants)

A scope naming a category – that category exactly, or it and everything beneath it.

RuleScope ew::core::timeline::objectScope(ew::core::foundation::ContentId objectId)

A scope naming one object.

These four exist because a RuleScope has seven fields and every construction site names one or two of them – and a partial designated initializer is a warning in this build, so without them every site would spell out five fields it does not care about.

RuleScope ew::core::timeline::projectScope()

A scope naming the whole project.

std::optional< RuleScopeKind > ew::core::timeline::ruleScopeKindFromToken(QStringView token)

Parses a scope kind from its token; nullopt when unrecognized or absent.

RuleScope ew::core::timeline::tagScope(QString tag)

A scope naming everything carrying a tag.

QString ew::core::timeline::toToken(RuleScopeKind kind)

Returns the stable serialization token for kind.